Merge pull request #811 from dbuchwald/main
Added missing RTS/DTR management feature to serialupdi programmer
This commit is contained in:
commit
b99687f33c
|
@ -1186,6 +1186,17 @@ line, and the XBee DIN pin (pin 3) must be connected to the MCU's
|
||||||
.Ql TXD
|
.Ql TXD
|
||||||
line.
|
line.
|
||||||
.El
|
.El
|
||||||
|
.It Ar serialupdi
|
||||||
|
Extended parameters:
|
||||||
|
.Bl -tag -offset indent -width indent
|
||||||
|
.It Ar rtsdtr=low|high
|
||||||
|
Forces RTS/DTR lines to assume low or high state during the whole
|
||||||
|
programming session. Some programmers might use this signal to
|
||||||
|
indicate UPDI programming state, but this is strictly hardware
|
||||||
|
specific.
|
||||||
|
.Pp
|
||||||
|
When not provided, driver/OS default value will be used.
|
||||||
|
.El
|
||||||
.El
|
.El
|
||||||
.Sh FILES
|
.Sh FILES
|
||||||
.Bl -tag -offset indent -width /dev/ppi0XXX
|
.Bl -tag -offset indent -width /dev/ppi0XXX
|
||||||
|
|
|
@ -1067,6 +1067,18 @@ The remaining two necessary XBee-to-MCU connections are not selectable
|
||||||
the MCU's ‘TXD’ line.
|
the MCU's ‘TXD’ line.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
@item serialupdi
|
||||||
|
Extended parameters:
|
||||||
|
@table @code
|
||||||
|
@item @samp{rtsdtr=low|high}
|
||||||
|
Forces RTS/DTR lines to assume low or high state during the whole
|
||||||
|
programming session. Some programmers might use this signal to
|
||||||
|
indicate UPDI programming state, but this is strictly hardware
|
||||||
|
specific.
|
||||||
|
|
||||||
|
When not provided, driver/OS default value will be used.
|
||||||
|
@end table
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@page
|
@page
|
||||||
|
|
|
@ -55,6 +55,7 @@ static void serialupdi_setup(PROGRAMMER * pgm)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
memset(pgm->cookie, 0, sizeof(updi_state));
|
memset(pgm->cookie, 0, sizeof(updi_state));
|
||||||
|
updi_set_rts_mode(pgm, RTS_MODE_DEFAULT);
|
||||||
updi_set_datalink_mode(pgm, UPDI_LINK_MODE_16BIT);
|
updi_set_datalink_mode(pgm, UPDI_LINK_MODE_16BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,6 +185,10 @@ static void serialupdi_close(PROGRAMMER * pgm)
|
||||||
if (serialupdi_leave_progmode(pgm) < 0) {
|
if (serialupdi_leave_progmode(pgm) < 0) {
|
||||||
avrdude_message(MSG_INFO, "%s: Unable to leave NVM programming mode\n", progname);
|
avrdude_message(MSG_INFO, "%s: Unable to leave NVM programming mode\n", progname);
|
||||||
}
|
}
|
||||||
|
if (updi_get_rts_mode(pgm) != RTS_MODE_DEFAULT) {
|
||||||
|
avrdude_message(MSG_INFO, "%s: Releasing DTR/RTS handshake lines\n", progname);
|
||||||
|
}
|
||||||
|
|
||||||
updi_link_close(pgm);
|
updi_link_close(pgm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -582,6 +587,10 @@ static int serialupdi_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||||
}
|
}
|
||||||
avrdude_message(MSG_INFO, "%s: UPDI link initialization OK\n", progname);
|
avrdude_message(MSG_INFO, "%s: UPDI link initialization OK\n", progname);
|
||||||
|
|
||||||
|
if (updi_get_rts_mode(pgm) != RTS_MODE_DEFAULT) {
|
||||||
|
avrdude_message(MSG_INFO, "%s: Forcing serial DTR/RTS handshake lines %s\n", progname, updi_get_rts_mode(pgm) == RTS_MODE_LOW ? "LOW" : "HIGH");
|
||||||
|
}
|
||||||
|
|
||||||
if (updi_read_cs(pgm, UPDI_ASI_SYS_STATUS, &value)<0) {
|
if (updi_read_cs(pgm, UPDI_ASI_SYS_STATUS, &value)<0) {
|
||||||
|
|
||||||
/* let's try reset the connection */
|
/* let's try reset the connection */
|
||||||
|
@ -926,6 +935,35 @@ static int serialupdi_read_sib(PROGRAMMER * pgm, AVRPART *p, char *sib) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int serialupdi_parseextparms(PROGRAMMER * pgm, LISTID extparms)
|
||||||
|
{
|
||||||
|
LNODEID ln;
|
||||||
|
const char *extended_param;
|
||||||
|
char rts_mode[5];
|
||||||
|
int rv = 0;
|
||||||
|
|
||||||
|
for (ln = lfirst(extparms); ln; ln = lnext(ln)) {
|
||||||
|
extended_param = ldata(ln);
|
||||||
|
|
||||||
|
if (sscanf(extended_param, "rtsdtr=%4s", rts_mode) == 1) {
|
||||||
|
if (strcasecmp(rts_mode, "low") == 0) {
|
||||||
|
updi_set_rts_mode(pgm, RTS_MODE_LOW);
|
||||||
|
} else if (strcasecmp(rts_mode, "high") == 0) {
|
||||||
|
updi_set_rts_mode(pgm, RTS_MODE_HIGH);
|
||||||
|
} else {
|
||||||
|
avrdude_message(MSG_INFO, "%s: RTS/DTR mode must be LOW or HIGH\n", progname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
avrdude_message(MSG_INFO, "%s: serialupdi_parseextparms(): invalid extended parameter '%s'\n",
|
||||||
|
progname, extended_param);
|
||||||
|
rv = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
void serialupdi_initpgm(PROGRAMMER * pgm)
|
void serialupdi_initpgm(PROGRAMMER * pgm)
|
||||||
{
|
{
|
||||||
|
@ -936,6 +974,7 @@ void serialupdi_initpgm(PROGRAMMER * pgm)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pgm->initialize = serialupdi_initialize;
|
pgm->initialize = serialupdi_initialize;
|
||||||
|
pgm->parseextparams = serialupdi_parseextparms;
|
||||||
pgm->display = serialupdi_display;
|
pgm->display = serialupdi_display;
|
||||||
pgm->enable = serialupdi_enable;
|
pgm->enable = serialupdi_enable;
|
||||||
pgm->disable = serialupdi_disable;
|
pgm->disable = serialupdi_disable;
|
||||||
|
|
|
@ -39,9 +39,16 @@
|
||||||
#include "updi_constants.h"
|
#include "updi_constants.h"
|
||||||
#include "updi_state.h"
|
#include "updi_state.h"
|
||||||
|
|
||||||
static void msleep(int tms)
|
static void updi_set_rtsdtr_mode(PROGRAMMER* pgm)
|
||||||
{
|
{
|
||||||
usleep(tms * 1000);
|
updi_rts_mode rts_mode = updi_get_rts_mode(pgm);
|
||||||
|
|
||||||
|
if (rts_mode == RTS_MODE_DEFAULT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
serial_set_dtr_rts(&pgm->fd, 0);
|
||||||
|
serial_set_dtr_rts(&pgm->fd, rts_mode == RTS_MODE_LOW ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int updi_physical_open(PROGRAMMER* pgm, int baudrate, unsigned long cflags)
|
static int updi_physical_open(PROGRAMMER* pgm, int baudrate, unsigned long cflags)
|
||||||
|
@ -65,11 +72,17 @@ static int updi_physical_open(PROGRAMMER* pgm, int baudrate, unsigned long cflag
|
||||||
*/
|
*/
|
||||||
serial_drain(&pgm->fd, 0);
|
serial_drain(&pgm->fd, 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* set RTS/DTR mode if needed
|
||||||
|
*/
|
||||||
|
updi_set_rtsdtr_mode(pgm);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void updi_physical_close(PROGRAMMER* pgm)
|
static void updi_physical_close(PROGRAMMER* pgm)
|
||||||
{
|
{
|
||||||
|
serial_set_dtr_rts(&pgm->fd, 0);
|
||||||
serial_close(&pgm->fd);
|
serial_close(&pgm->fd);
|
||||||
pgm->fd.ifd = -1;
|
pgm->fd.ifd = -1;
|
||||||
}
|
}
|
||||||
|
@ -124,28 +137,31 @@ static int updi_physical_send_double_break(PROGRAMMER * pgm)
|
||||||
|
|
||||||
avrdude_message(MSG_DEBUG, "%s: Sending double break\n", progname);
|
avrdude_message(MSG_DEBUG, "%s: Sending double break\n", progname);
|
||||||
|
|
||||||
updi_physical_close(pgm);
|
if (serial_setparams(&pgm->fd, 300, SERIAL_8E1) < 0) {
|
||||||
|
|
||||||
if (updi_physical_open(pgm, 300, SERIAL_8E1)==-1) {
|
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer[0] = UPDI_BREAK;
|
updi_set_rtsdtr_mode(pgm);
|
||||||
|
|
||||||
serial_send(&pgm->fd, buffer, 1);
|
|
||||||
serial_recv(&pgm->fd, buffer, 1);
|
|
||||||
|
|
||||||
msleep(100);
|
|
||||||
|
|
||||||
buffer[0] = UPDI_BREAK;
|
buffer[0] = UPDI_BREAK;
|
||||||
|
|
||||||
serial_send(&pgm->fd, buffer, 1);
|
serial_send(&pgm->fd, buffer, 1);
|
||||||
serial_recv(&pgm->fd, buffer, 1);
|
serial_recv(&pgm->fd, buffer, 1);
|
||||||
|
|
||||||
updi_physical_close(pgm);
|
usleep(100*1000);
|
||||||
|
|
||||||
return updi_physical_open(pgm, pgm->baudrate? pgm->baudrate: 115200, SERIAL_8E2);
|
buffer[0] = UPDI_BREAK;
|
||||||
|
|
||||||
|
serial_send(&pgm->fd, buffer, 1);
|
||||||
|
serial_recv(&pgm->fd, buffer, 1);
|
||||||
|
|
||||||
|
if (serial_setparams(&pgm->fd, pgm->baudrate? pgm->baudrate: 115200, SERIAL_8E2) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
updi_set_rtsdtr_mode(pgm);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int updi_physical_sib(PROGRAMMER * pgm, unsigned char * buffer, uint8_t size)
|
int updi_physical_sib(PROGRAMMER * pgm, unsigned char * buffer, uint8_t size)
|
||||||
|
|
|
@ -53,3 +53,13 @@ void updi_set_nvm_mode(PROGRAMMER * pgm, updi_nvm_mode mode)
|
||||||
{
|
{
|
||||||
((updi_state *)(pgm->cookie))->nvm_mode = mode;
|
((updi_state *)(pgm->cookie))->nvm_mode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updi_rts_mode updi_get_rts_mode(PROGRAMMER * pgm)
|
||||||
|
{
|
||||||
|
return ((updi_state *)(pgm->cookie))->rts_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updi_set_rts_mode(PROGRAMMER * pgm, updi_rts_mode mode)
|
||||||
|
{
|
||||||
|
((updi_state *)(pgm->cookie))->rts_mode = mode;
|
||||||
|
}
|
||||||
|
|
|
@ -61,11 +61,19 @@ typedef struct
|
||||||
char debug_version;
|
char debug_version;
|
||||||
} updi_sib_info;
|
} updi_sib_info;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
RTS_MODE_DEFAULT,
|
||||||
|
RTS_MODE_LOW,
|
||||||
|
RTS_MODE_HIGH
|
||||||
|
} updi_rts_mode;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
updi_sib_info sib_info;
|
updi_sib_info sib_info;
|
||||||
updi_datalink_mode datalink_mode;
|
updi_datalink_mode datalink_mode;
|
||||||
updi_nvm_mode nvm_mode;
|
updi_nvm_mode nvm_mode;
|
||||||
|
updi_rts_mode rts_mode;
|
||||||
} updi_state;
|
} updi_state;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -77,6 +85,8 @@ updi_datalink_mode updi_get_datalink_mode(PROGRAMMER * pgm);
|
||||||
void updi_set_datalink_mode(PROGRAMMER * pgm, updi_datalink_mode mode);
|
void updi_set_datalink_mode(PROGRAMMER * pgm, updi_datalink_mode mode);
|
||||||
updi_nvm_mode updi_get_nvm_mode(PROGRAMMER * pgm);
|
updi_nvm_mode updi_get_nvm_mode(PROGRAMMER * pgm);
|
||||||
void updi_set_nvm_mode(PROGRAMMER * pgm, updi_nvm_mode mode);
|
void updi_set_nvm_mode(PROGRAMMER * pgm, updi_nvm_mode mode);
|
||||||
|
updi_rts_mode updi_get_rts_mode(PROGRAMMER * pgm);
|
||||||
|
void updi_set_rts_mode(PROGRAMMER * pgm, updi_rts_mode mode);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue