mirror of
https://github.com/avrdudes/avrdude.git
synced 2026-09-23 09:36:24 +03:00
Provide serialadapter entity in avrdude.conf
This commit is contained in:
@@ -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
|
||||
@@ -286,6 +287,7 @@ target_link_libraries(libavrdude
|
||||
${LIB_LIBFTDI}
|
||||
${LIB_LIBFTDI1}
|
||||
${LIB_LIBREADLINE}
|
||||
${LIB_LIBSERIALPORT}
|
||||
${LIB_NCURSES}
|
||||
${LIB_LIBGPIOD}
|
||||
${EXTRA_WINDOWS_LIBRARIES}
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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
|
||||
@@ -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,
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
#
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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
|
||||
|
||||
10
src/main.c
10
src/main.c
@@ -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);
|
||||
@@ -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)) {
|
||||
@@ -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"))
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user