Implemented extended parameter for RTS/DTR lines management

This commit is contained in:
Dawid Buchwald 2022-01-08 10:04:25 +01:00
parent c71fab0889
commit 1631fc4dd8
5 changed files with 93 additions and 14 deletions

View File

@ -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

View File

@ -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);
} }
@ -926,6 +927,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 +966,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;

View File

@ -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)

View File

@ -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;
}

View File

@ -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
} }