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
|
||||
line.
|
||||
.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
|
||||
.Sh FILES
|
||||
.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.
|
||||
@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
|
||||
|
||||
@page
|
||||
|
|
|
@ -55,6 +55,7 @@ static void serialupdi_setup(PROGRAMMER * pgm)
|
|||
exit(1);
|
||||
}
|
||||
memset(pgm->cookie, 0, sizeof(updi_state));
|
||||
updi_set_rts_mode(pgm, RTS_MODE_DEFAULT);
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -582,6 +587,10 @@ static int serialupdi_initialize(PROGRAMMER * pgm, AVRPART * p)
|
|||
}
|
||||
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) {
|
||||
|
||||
/* let's try reset the connection */
|
||||
|
@ -926,6 +935,35 @@ static int serialupdi_read_sib(PROGRAMMER * pgm, AVRPART *p, char *sib) {
|
|||
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)
|
||||
{
|
||||
|
@ -936,6 +974,7 @@ void serialupdi_initpgm(PROGRAMMER * pgm)
|
|||
*/
|
||||
|
||||
pgm->initialize = serialupdi_initialize;
|
||||
pgm->parseextparams = serialupdi_parseextparms;
|
||||
pgm->display = serialupdi_display;
|
||||
pgm->enable = serialupdi_enable;
|
||||
pgm->disable = serialupdi_disable;
|
||||
|
|
|
@ -39,9 +39,16 @@
|
|||
#include "updi_constants.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)
|
||||
|
@ -65,11 +72,17 @@ static int updi_physical_open(PROGRAMMER* pgm, int baudrate, unsigned long cflag
|
|||
*/
|
||||
serial_drain(&pgm->fd, 0);
|
||||
|
||||
/*
|
||||
* set RTS/DTR mode if needed
|
||||
*/
|
||||
updi_set_rtsdtr_mode(pgm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void updi_physical_close(PROGRAMMER* pgm)
|
||||
{
|
||||
serial_set_dtr_rts(&pgm->fd, 0);
|
||||
serial_close(&pgm->fd);
|
||||
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);
|
||||
|
||||
updi_physical_close(pgm);
|
||||
|
||||
if (updi_physical_open(pgm, 300, SERIAL_8E1)==-1) {
|
||||
|
||||
if (serial_setparams(&pgm->fd, 300, SERIAL_8E1) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
buffer[0] = UPDI_BREAK;
|
||||
|
||||
serial_send(&pgm->fd, buffer, 1);
|
||||
serial_recv(&pgm->fd, buffer, 1);
|
||||
|
||||
msleep(100);
|
||||
updi_set_rtsdtr_mode(pgm);
|
||||
|
||||
buffer[0] = UPDI_BREAK;
|
||||
|
||||
serial_send(&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)
|
||||
|
|
|
@ -53,3 +53,13 @@ void updi_set_nvm_mode(PROGRAMMER * pgm, updi_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;
|
||||
} updi_sib_info;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RTS_MODE_DEFAULT,
|
||||
RTS_MODE_LOW,
|
||||
RTS_MODE_HIGH
|
||||
} updi_rts_mode;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
updi_sib_info sib_info;
|
||||
updi_datalink_mode datalink_mode;
|
||||
updi_nvm_mode nvm_mode;
|
||||
updi_rts_mode rts_mode;
|
||||
} updi_state;
|
||||
|
||||
#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);
|
||||
updi_nvm_mode updi_get_nvm_mode(PROGRAMMER * pgm);
|
||||
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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue