Skip to content

Commit

Permalink
Provide serialadapter entity in avrdude.conf
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanrueger committed Aug 28, 2023
1 parent b8c47f3 commit 91ffab5
Show file tree
Hide file tree
Showing 10 changed files with 69 additions and 9 deletions.
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ add_library(libavrdude
ser_avrdoper.c
ser_posix.c
ser_win32.c
serialadapter.c
serialupdi.c
serialupdi.h
solaris_ecpp.h
Expand Down Expand Up @@ -286,6 +287,7 @@ target_link_libraries(libavrdude
${LIB_LIBFTDI}
${LIB_LIBFTDI1}
${LIB_LIBREADLINE}
${LIB_LIBSERIALPORT}
${LIB_NCURSES}
${LIB_LIBGPIOD}
${EXTRA_WINDOWS_LIBRARIES}
Expand Down
1 change: 1 addition & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ libavrdude_a_SOURCES = \
ser_avrdoper.c \
ser_posix.c \
ser_win32.c \
serialadapter.c \
solaris_ecpp.h \
stk500.c \
stk500.h \
Expand Down
39 changes: 37 additions & 2 deletions src/avrdude.conf.in
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,16 @@
# #
# # (3) Not all programmer types can process a list of PIDs
#
# serialadapter # same as programmer albeit only for usb parameters
# parent <id> # optional serialadapter or programmer parent
# id = <id1> [, <id2> ... ] ; # <idN> are quoted strings
# desc = <description> ; # quoted string
# baudrate = <num> ; # optional default baudrate
# usbvid = <hexnum> ; # USB vendor ID
# usbpid = <hexnum> [, <hexnum> ...] ; # list of USB product IDs
# usbsn = <serialno> ; # USB Serial Number in private .avrduderc files
# ;
#
# part
# desc = <description> ; # quoted string, the long part name, eg, "ATmega328p"
# id = <id> ; # quoted string, normally an abbreviated part name
Expand Down Expand Up @@ -924,7 +934,7 @@ programmer
# The drivers will look for a specific device and use the first one
# found. If you have mulitple devices, and they give out serial
# numbers, a different entry for each of them can be created in a
# persnonal ~/.avrduderc or avrdude.rc entry and the usbsn = "...";
# personal ~/.avrduderc or avrdude.rc entry and the usbsn = "...";
# field added to distinguish between them.
#
# Note that the pin numbers for the main ISP signals (reset, sck,
Expand Down Expand Up @@ -1583,6 +1593,9 @@ programmer
type = "ftdi_syncbb";
prog_modes = PM_TPI | PM_ISP;
connection_type = usb;
baudrate = 250000; # For use as serial adapter
usbvid = 0x0403; # "
usbpid = 0x6001; # "
reset = 4; # DTR
sck = 0; # TxD
sdo = 2; # RTS
Expand Down Expand Up @@ -1740,7 +1753,6 @@ programmer
usbpid = 0x05dc; # Obdev's free shared PID
usbvendor = "www.fischl.de";
usbproduct = "USBasp";

# Old usbasp from fischl.de:
# usbvid = 0x03EB; # ATMEL
# usbpid = 0xC7B4; # (unoffical) USBasp
Expand Down Expand Up @@ -2896,6 +2908,29 @@ programmer
hvupdi_support = 1;
;

#------------------------------------------------------------
# ch340
#------------------------------------------------------------

# A serialadapter is a programmer that has only USB parameters defined;
# they can be used for a -P <serialadapter|programmer>[:<serial number>]
# port specification instead of the serial port that the serial adapter
# creates, eg, instead of /dev/ttyUSB3. Personal serialadapter definitions
# in the ~/.avrduderc or avrdude.rc files can add a serial number using
# the definition usbsn = "012345679"; to give a particular board a
# specific unique name (id). This is particularly useful when uploading
# directly to a board with a bootloader as it allows to assign boards
# unique names rather than having to figure out which a varying serial
# port name the Operating System has assigned at runtime.

serialadapter
id = "ch340";
desc = "WCH CH340 USB to serial adapter";
baudrate = 250000;
usbvid = 0x1a86;
usbpid = 0x7523;
;

#
# PART DEFINITIONS
#
Expand Down
2 changes: 1 addition & 1 deletion src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ void capture_lvalue_kw(const char *kw, int lineno) {
}
}

if(str_eq(kw, "programmer") || str_eq(kw, "part") || str_eq(kw, "memory"))
if(str_eq(kw, "programmer") || str_eq(kw, "serialadapter") || str_eq(kw, "part") || str_eq(kw, "memory"))
kw = "*"; // Show comment before programmer/part/memory

if(lkw)
Expand Down
2 changes: 1 addition & 1 deletion src/config_gram.y
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ prog_def :
yyerror("required parameter id not specified");
YYABORT;
}
if (current_prog->initpgm == NULL) {
if (current_prog->initpgm == NULL && current_prog->prog_modes) {
yyerror("programmer type not specified");
YYABORT;
}
Expand Down
5 changes: 3 additions & 2 deletions src/developer_opts.c
Original file line number Diff line number Diff line change
Expand Up @@ -1359,10 +1359,11 @@ static void dev_pgm_strct(const PROGRAMMER *pgm, bool tsv, const PROGRAMMER *bas
if(cp)
dev_print_comment(cp->comms);

const char *prog_sea = is_programmer(pgm)? "programmer": is_serialadapter(pgm)? "serialadapter": "programmer";
if(pgm->parent_id && *pgm->parent_id)
dev_info("programmer parent \"%s\"\n", pgm->parent_id);
dev_info("%s parent \"%s\"\n", prog_sea, pgm->parent_id);
else
dev_info("programmer\n");
dev_info("%s\n", prog_sea);
}

if(tsv)
Expand Down
2 changes: 1 addition & 1 deletion src/lexer.l
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ part { yylval=NULL; ccap(); current_strct = COMP_AVRPART; return K_P
pgm_enable { yylval=new_token(K_PGM_ENABLE); ccap(); return K_PGM_ENABLE; }
pgmled { yylval=NULL; ccap(); return K_PGMLED; }
pp_controlstack { yylval=NULL; ccap(); return K_PP_CONTROLSTACK; }
programmer { yylval=NULL; ccap(); current_strct = COMP_PROGRAMMER; return K_PROGRAMMER; }
(programmer|serialadapter) { yylval=NULL; ccap(); current_strct = COMP_PROGRAMMER; return K_PROGRAMMER; }
rdyled { yylval=NULL; ccap(); return K_RDYLED; }
read { yylval=new_token(K_READ); ccap(); return K_READ; }
read_hi { yylval=new_token(K_READ_HI); ccap(); return K_READ_HI; }
Expand Down
6 changes: 6 additions & 0 deletions src/libavrdude.h
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,12 @@ typedef struct programmer_t {
char flag; // For use by pgm->initpgm()
} PROGRAMMER;

typedef PROGRAMMER SERIALADAPTER; // Only a subset is needed for serial adapters
int is_programmer(const PROGRAMMER *p);
int is_serialadapter(const SERIALADAPTER *p);
void list_serialadapters(FILE *f, const char *prefix, LISTID programmers);
void serialadapter_not_found(const char *sea_id);

#define NO_PIN (PIN_MAX + 1U) // Magic pinno[] value for unused pins

#ifdef __cplusplus
Expand Down
10 changes: 8 additions & 2 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,8 @@ static void list_programmers(FILE *f, const char *prefix, LISTID programmers, in
// Compute max length of programmer names
for(ln1 = lfirst(programmers); ln1; ln1 = lnext(ln1)) {
pgm = ldata(ln1);
if(!is_programmer(pgm))
continue;
for(ln2=lfirst(pgm->id); ln2; ln2=lnext(ln2))
if(!pm || !pgm->prog_modes || (pm & pgm->prog_modes)) {
const char *id = ldata(ln2);
Expand All @@ -310,6 +312,8 @@ static void list_programmers(FILE *f, const char *prefix, LISTID programmers, in

for(ln1 = lfirst(programmers); ln1; ln1 = lnext(ln1)) {
pgm = ldata(ln1);
if(!is_programmer(pgm))
continue;
for(ln2=lfirst(pgm->id); ln2; ln2=lnext(ln2)) {
// List programmer if pm or prog_modes uninitialised or if they are compatible otherwise
if(!pm || !pgm->prog_modes || (pm & pgm->prog_modes)) {
Expand Down Expand Up @@ -1018,6 +1022,8 @@ int main(int argc, char * argv [])
AVRPART *p = ldata(ln1);
for(LNODEID ln2 = lfirst(programmers); ln2; ln2 = lnext(ln2)) {
PROGRAMMER *pgm = ldata(ln2);
if(!is_programmer(pgm))
continue;
const char *pnam = pgm->id? ldata(lfirst(pgm->id)): "???";
int pm = pgm->prog_modes & p->prog_modes;
if((pm & (pm-1)) && !str_eq(pnam, "dryrun"))
Expand All @@ -1029,7 +1035,7 @@ int main(int argc, char * argv [])
if(str_eq(partdesc, "?")) {
if(pgmid && *pgmid && explicit_c) {
PROGRAMMER *pgm = locate_programmer_set(programmers, pgmid, &pgmid);
if(!pgm) {
if(!pgm || !is_programmer(pgm)) {
programmer_not_found(pgmid);
exit(1);
}
Expand Down Expand Up @@ -1078,7 +1084,7 @@ int main(int argc, char * argv [])
}

pgm = locate_programmer_set(programmers, pgmid, &pgmid);
if (pgm == NULL) {
if (pgm == NULL || !is_programmer(pgm)) {
programmer_not_found(pgmid);
exit(1);
}
Expand Down
9 changes: 9 additions & 0 deletions src/pgm.c
Original file line number Diff line number Diff line change
Expand Up @@ -364,3 +364,12 @@ void sort_programmers(LISTID programmers)
lsort(programmers,(int (*)(void*, void*)) sort_programmer_compare);
}


// Soft assignment: some struct programmer_t entries can be both programmers and serial adapters
int is_programmer(const PROGRAMMER *p) {
return p->id && lsize(p->id) && p->prog_modes && p->initpgm;
}

int is_serialadapter(const SERIALADAPTER *p) {
return p->id && lsize(p->id) && p->usbpid && lsize(p->usbpid);
}

0 comments on commit 91ffab5

Please sign in to comment.