diff --git a/NEWS b/NEWS index 84fdeae3..880cc66c 100644 --- a/NEWS +++ b/NEWS @@ -12,13 +12,16 @@ Changes since version 7.1: - libgpiod support for linuxgpio #1299 - Support jtag2updi -U UPDI EEPROM write #1318 - avrdude.conf reconciled with ATDFs #1343 + - avrdude -p part/s now also shows part variants #1343 - New programmer dryrun for testing #1347 - New -T cmd to mix terminal with -U commands #1373 + - Run -t interactive terminals in CLI option order #1402 - Terminal + Command config (mnemonic fuse setting) #1365 + Write to memory from files #1358 + Command save memory to file #1396 + Subshell command ! #1397 + + Command include file #1429 * New devices supported: @@ -73,6 +76,7 @@ Changes since version 7.1: - CH341A - Kanda AVRISP-U - arduino_as_isp + - scratchmonkey, scratchmonkey_pp, scratchmonkey_hvsp * Issues fixed: @@ -99,6 +103,13 @@ Changes since version 7.1: - Some SPI read/write commands incompatible with .ATDF #1370 - Avrdude can segfault writing ihex or srec files #1390 - Avrdude srec format too lax when writing #1391 + - Avrdude fails with AT90S8515 #433 + - AT90S8515 STK500v2: only odd bytes are programmed #500 + - STK500v2 ATtiny15 problem #509 + - Downgrade missing USB device warning #1398 + - Avrdude can not write usersig in terminal mode #1361 + - avr109 atmega2564rfr2 erase timeout too short #336 + - Add ScratchMonkey #989 * Pull requests: @@ -156,6 +167,31 @@ Changes since version 7.1: - Add more documentation for programmers #1393, #1394, #1395 - Provide terminal save command #1396 - Provide terminal subshell command ! #1397 + - Fix stk500v2.c's write_byte() for old parts #1386 + - Document terminal comments #1399 + - Expand authorship of documentation #1400 + - Fix memory leak in avrcache.c #1401 + - Run -t interactive terminals when it is their turn with + respect to -t/-T/-U command line option order #1402 + - Mute missing USB device warning for lower verbosity #1403 + - Implement bytewise cache for usersig #1404 + - Relax checks before executing the -T/-U operations #1405 + - Define usersig memory for ATmega*RF[AR]* parts #1406 + - Increase timeout for emulated butterfly chip erase #1411 + - Update reference to AT90S4433 datasheet #1415 + - Update alf programmer info and URL #1416 + - Update URLs for 89isp programmer #1417 + - Update ft2232h programmer info and URLs #1418 + - Update butterfly_mk info #1419 + - Remove outdated web URLs for O-Link #1420 + - Update URLs for the ttl232r programmer #1421 + - Update usbasp programmer info #1422 + - Remove comment and URL for arduino-ft232r programmer #1423 + - Enable -c programmers to access -c string #1424 + - Add scratchmonkey programmers #1429 + - Use pgm->id list for alias names of a programmer #1430 + - Fix writing of empty flash memory #1438 + - Provide terminal include command #1439 * Internals: diff --git a/src/avr910.c b/src/avr910.c index 792e2667..a7c78e95 100644 --- a/src/avr910.c +++ b/src/avr910.c @@ -333,8 +333,7 @@ static int avr910_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { continue; } if (str_eq(extended_param, "help")) { - char *prg = (char *)ldata(lfirst(pgm->id)); - msg_error("%s -c %s extended options:\n", progname, prg); + msg_error("%s -c %s extended options:\n", progname, pgmid); msg_error(" -xdevcode= Override device code\n"); msg_error(" -xno_blockmode Disable default checking for block transfer capability\n"); msg_error(" -xhelp Show this help menu and exit\n"); diff --git a/src/avrdude.1 b/src/avrdude.1 index 7d425eb8..4c66ff37 100644 --- a/src/avrdude.1 +++ b/src/avrdude.1 @@ -1070,7 +1070,7 @@ items is ignored to facilitate copy & paste of lists. The start address .Ar addr may be omitted if the size of the memory being written to is -1 byte in size. +one byte. .It Ar write memory addr len data[,] {data[,]} ... The ellipsis ... form writes the data to the entire memory intervall addressed by .Ar addr len @@ -1150,6 +1150,11 @@ can be uniquely resolved. It is quite possible, as is with direct writing to the underlying fuses and lock bits, to brick a part, i.e., make it unresponsive to further programming with the chosen programmer: here be dragons. +.It Ar include [] +Include contents of the named file as if it was typed. This is useful for +batch scripts, eg, recurring initialisation code for fuses. The include +option -e prints the lines of the file as comments before processing them; +on a non-zero verbosity level the line numbers are printed, too. .It Ar sig Display the device signature bytes. .It Ar part diff --git a/src/avrdude.conf.in b/src/avrdude.conf.in index 6f5980f9..c5325f75 100644 --- a/src/avrdude.conf.in +++ b/src/avrdude.conf.in @@ -236,7 +236,7 @@ # This flag was added to work around a problem with the # at90s4433/2333's; see the at90s4433 errata at: # -# http://www.atmel.com/dyn/resources/prod_documents/doc1280.pdf +# https://www.microchip.com/content/dam/mchp/documents/OTH/ProductDocuments/DataSheets/doc1042.pdf # # INSTRUCTION FORMATS # @@ -502,9 +502,12 @@ programmer parent "dt006" # alf #------------------------------------------------------------ +# PC Parallel Port Programmer +# https://web.archive.org/web/20050928233713fw_/http://nightshade.homeip.net/ALF-PgmAVR.htm + programmer id = "alf"; - desc = "Nightshade ALF-PgmAVR, http://nightshade.homeip.net/"; + desc = "Nightshade ALF-PgmAVR via PC parallel port"; type = "par"; prog_modes = PM_TPI | PM_ISP; vcc = 2, 3, 4, 5; @@ -625,9 +628,11 @@ programmer # atisp #------------------------------------------------------------ +# https://micro-research.co.th + programmer id = "atisp"; - desc = "AT-ISP v1.1 programming cable for AVR-SDK1 from "; + desc = "AT-ISP v1.1 programming cable for AVR-SDK1"; type = "par"; prog_modes = PM_TPI | PM_ISP; reset = ~6; @@ -640,9 +645,11 @@ programmer # ere-isp-avr #------------------------------------------------------------ +# No longer exists: http://www.ere.co.th/download/sch050713.pdf + programmer id = "ere-isp-avr"; - desc = "ERE ISP-AVR "; + desc = "ERE ISP-AVR"; type = "par"; prog_modes = PM_TPI | PM_ISP; reset = ~4; @@ -672,7 +679,7 @@ programmer #------------------------------------------------------------ # It is almost same as pony-stk200, except vcc on pin 5 to auto -# disconnect port (download on http://electropol.free.fr/spip/spip.php?article27) +# disconnect port, see http://electropol.free.fr/spip/spip.php?article27 programmer parent "pony-stk200" id = "frank-stk200"; @@ -685,8 +692,10 @@ programmer parent "pony-stk200" # 89isp #------------------------------------------------------------ -# The AT98ISP Cable is a simple parallel dongle for AT89 family. -# http://www.atmel.com/dyn/products/tools_card.asp?tool_id=2877 +# The AT89ISP Cable is a simple parallel dongle for AT89 family +# https://www.microchip.com/en-us/development-tool/AT89ISP +# https://ww1.microchip.com/downloads/en/appnotes/doc3310.pdf +# https://ww1.microchip.com/downloads/en/DeviceDoc/AT89ISP_Update3.3.zip programmer id = "89isp"; @@ -876,29 +885,31 @@ programmer # ft2232h #------------------------------------------------------------ -# this will interface with the chips on these programmers: +# Interfaces with the chips on these programmers: +# - http://real.kiev.ua/old/avreal/en/adapters +# - http://www.amontec.com/jtagkey.shtml and .../jtagkey-tiny.shtml +# - http://www.olimex.com/dev/arm-usb-ocd.html, arm-usb-tiny.html +# - http://www.ethernut.de/en/hardware/turtelizer/index.html +# - https://web.archive.org/web/20161221220118/http://elk.informatik.fh-augsburg.de/hhweb/doc/openocd/usbjtag/usbjtag.html +# - http://dangerousprototypes.com/docs/FT2232_breakout_board +# - http://flashrom.org/FT2232SPI_Programmer # -# http://real.kiev.ua/old/avreal/en/adapters -# http://www.amontec.com/jtagkey.shtml, jtagkey-tiny.shtml -# http://www.olimex.com/dev/arm-usb-ocd.html, arm-usb-tiny.html -# http://www.ethernut.de/en/hardware/turtelizer/index.html -# http://elk.informatik.fh-augsburg.de/hhweb/doc/openocd/usbjtag/usbjtag.html -# http://dangerousprototypes.com/docs/FT2232_breakout_board -# http://www.ftdichip.com/Products/Modules/DLPModules.htm,DLP-2232*,DLP-USB1232H -# http://flashrom.org/FT2232SPI_Programmer -# -# The drivers will look for a specific device and use the first one found. -# If you have mulitple devices, then look for unique information (like SN) -# And fill that in here. +# 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 = "..."; +# field added to distinguish between them. # # Note that the pin numbers for the main ISP signals (reset, sck, # sdo, sdi) are fixed and cannot be changed, since they must match # the way the Multi-Protocol Synchronous Serial Engine (MPSSE) of # these FTDI ICs has been designed. +# +# See also https://ftdichip.com/wp-content/uploads/2020/07/DS_FT2232H.pdf programmer - id = "ft2232h"; - desc = "FT2232H based generic programmer"; + id = "ft2232h", "avrftdi", "2232h"; + desc = "FT2232H/D based generic programmer"; type = "avrftdi"; prog_modes = PM_TPI | PM_ISP; connection_type = usb; @@ -912,15 +923,6 @@ programmer sdi = 2; # AD2 (TDO) ; -#------------------------------------------------------------ -# avrftdi -#------------------------------------------------------------ - -programmer parent "ft2232h" - id = "avrftdi"; - desc = "FT2232D based generic programmer"; -; - #------------------------------------------------------------ # 2232HIO #------------------------------------------------------------ @@ -975,23 +977,15 @@ programmer parent "ft2232h" # ft4232h #------------------------------------------------------------ -#The FT4232H can be treated as FT2232H, but it has a different USB -#device ID of 0x6011. +# The FT4232H can be treated as FT2232H but with a different USB +# device ID of 0x6011 programmer parent "ft2232h" - id = "ft4232h"; + id = "ft4232h", "4232h"; desc = "FT4232H based generic programmer"; usbpid = 0x6011; ; -#------------------------------------------------------------ -# 4232h -#------------------------------------------------------------ - -programmer parent "ft4232h" - id = "4232h"; -; - #------------------------------------------------------------ # jtagkey #------------------------------------------------------------ @@ -1075,23 +1069,15 @@ programmer parent "ft232h" # o-link #------------------------------------------------------------ -# On the adapter you can read "O-Link". On the PCB is printed "OpenJTAG v3.1" -# You can find it as "OpenJTAG ARM JTAG USB" in the internet. -# (But there are also several projects called Open JTAG, eg. -# http://www.openjtag.org, which are completely different.) -# http://www.100ask.net/shop/english.html (website seems to be outdated) -# http://item.taobao.com/item.htm?id=1559277013 -# http://www.micro4you.com/store/openjtag-arm-jtag-usb.html (schematics!) -# some other sources which call it O-Link -# http://www.andahammer.com/olink/ -# http://www.developmentboard.net/31-o-link-debugger.html -# http://armwerks.com/catalog/o-link-debugger-copy/ -# or just have a look at ebay ... -# It is basically the same entry as jtagkey with different usb ids. +# On the adapter you can read "O-Link". On the PCB is printed "OpenJTAG v3.1". +# You can find it as "OpenJTAG ARM JTAG USB" in the internet. Note there are also +# several projects called Open JTAG, which are completely different. Some other +# sources call it O-Link or just have a look at ebay ... It is basically the same +# entry as jtagkey with different usb ids. See www.100ask.net programmer parent "jtagkey" id = "o-link"; - desc = "O-Link, OpenJTAG from www.100ask.net"; + desc = "O-Link, OpenJTAG ARM JTAG USB"; usbvid = 0x1457; usbpid = 0x5118; usbvendor = "www.100ask.net"; @@ -1174,14 +1160,18 @@ programmer # Kristech KT-LINK FT2232H interface with IO switching and voltage buffers. # Created on 20220410 by CeDeROM Tomasz CEDRO (www.cederom.io). # Interface DataSheet: https://kristech.pl/files/KT-LINK-UM-ENG.pdf +# # AVRDUDE FT2232H PIN NUMBER DECODE: # | 0 | 1 | .. | 7 | 8 | 9 | .. | 15 | # | ADBUS0 | ADBUS1 | .. | ADBUS7 | ACBUS0 | ACBUS1 | .. | ACBUS7 | +# # KT-LINK JTAG CONN: # 1=Vsense(->EXT13), 19=5V(EXT1->EXT3), 20=GND, 3=TPIRST, 9=TPICLK, 7=TPIDATA. +# # INTERNALS CONFIGURATION ("~" MEANS ACTIVE LOW): # ~TRST_EN=10(ACBUS2), ~CLK_EN=14(ACBUS6), ~SDO_EN=13(ACBUS5), # TMS_SEL=5(ADBUS5), ~TMS_EN=12(ACBUS4), LED=~15(ACBUS7). +# # CONNECTION NOTES: # * Connect EXT connector pin 1 with 3 to get 5V on JTAG connector pin 19. # * Connect JTAG connector pin 1 to 5V (i.e. EXT pin 13 or JTAG pin 19). @@ -1190,7 +1180,7 @@ programmer programmer id = "ktlink"; - desc = "KT-LINK FT2232H interface with IO switching and voltage buffers."; + desc = "KT-LINK FT2232H interface with IO switching and voltage buffers"; type = "avrftdi"; prog_modes = PM_TPI | PM_ISP; connection_type = usb; @@ -1297,7 +1287,7 @@ programmer #------------------------------------------------------------ programmer - id = "avrispmkII"; + id = "avrispmkII", "avrisp2"; desc = "Atmel AVR ISP mkII"; type = "stk500v2"; prog_modes = PM_TPI | PM_ISP | PM_PDI; @@ -1305,14 +1295,6 @@ programmer connection_type = usb; ; -#------------------------------------------------------------ -# avrisp2 -#------------------------------------------------------------ - -programmer parent "avrispmkII" - id = "avrisp2"; -; - #------------------------------------------------------------ # buspirate #------------------------------------------------------------ @@ -1407,7 +1389,7 @@ programmer #------------------------------------------------------------ programmer - id = "stk500v2"; + id = "stk500v2", "scratchmonkey"; desc = "Atmel STK500 version 2.x firmware"; type = "stk500v2"; prog_modes = PM_TPI | PM_ISP; @@ -1420,7 +1402,7 @@ programmer #------------------------------------------------------------ programmer - id = "stk500pp"; + id = "stk500pp", "scratchmonkey_pp"; desc = "Atmel STK500 v2 in parallel programming mode"; type = "stk500pp"; prog_modes = PM_HVPP; @@ -1433,7 +1415,7 @@ programmer #------------------------------------------------------------ programmer - id = "stk500hvsp"; + id = "stk500hvsp", "scratchmonkey_hvsp"; desc = "Atmel STK500 v2 in high-voltage serial programming mode"; type = "stk500hvsp"; prog_modes = PM_HVSP; @@ -1546,11 +1528,15 @@ programmer # arduino-ft232r #------------------------------------------------------------ -# see http://www.geocities.jp/arduino_diecimila/bootloader/index_en.html -# Note: pins are numbered from 1! +# This programmer helps programming the Arduino Diecimila, NG and +# Duemilanove (but not the Uno) without bootloader or external +# programmer using the on-board FT232RL chip. Instructions here: +# https://make.kosakalab.com/arduino/bootloader/index_en.html +# Note that the -c diecimila avrdude.conf entry mentioned in above post +# is the same as the -c arduino-ft232r entry here. programmer - id = "arduino-ft232r"; + id = "arduino-ft232r", "diecimila"; desc = "Arduino: FT232R connected to ISP"; type = "ftdi_syncbb"; prog_modes = PM_TPI | PM_ISP; @@ -1578,17 +1564,6 @@ programmer sdi = 1; # RxD = D1 (wire to TPIDATA directly) ; -#------------------------------------------------------------ -# diecimila -#------------------------------------------------------------ - -# website mentioned above uses this id - -programmer parent "arduino-ft232r" - id = "diecimila"; - desc = "alias for arduino-ft232r"; -; - #------------------------------------------------------------ # uncompatino #------------------------------------------------------------ @@ -1617,9 +1592,10 @@ programmer #------------------------------------------------------------ # FTDI USB to serial cable TTL-232R-5V with a custom adapter for ICSP -# http://www.ftdichip.com/Products/Cables/USBTTLSerial.htm -# http://www.ftdichip.com/Support/Documents/DataSheets/Cables/DS_TTL-232R_CABLES.pdf -# For ICSP pinout see for example http://www.atmel.com/images/doc2562.pdf +# - https://ftdichip.com/product-category/products/cables/usb-ttl-serial-cable-series/ +# - http://www.ftdichip.com/Support/Documents/DataSheets/Cables/DS_TTL-232R_CABLES.pdf +# +# For ICSP pinout see, e.g., http://ww1.microchip.com/downloads/en/DeviceDoc/doc2562.pdf # (Figure 1. ISP6PIN header pinout and Table 1. Connections required for ISP ...) # TTL-232R GND 1 Black -> ICPS GND (pin 6) # TTL-232R CTS 2 Brown -> ICPS SDO (pin 4) @@ -1627,8 +1603,9 @@ programmer # TTL-232R TXD 4 Orange -> ICPS RESET (pin 5) # TTL-232R RXD 5 Yellow -> ICPS SCK (pin 3) # TTL-232R RTS 6 Green -> ICPS SDI (pin 1) -# Except for VCC and GND, you can connect arbitual pairs as long as -# the following table is adjusted. +# +# Except for VCC and GND, you can connect arbitrary pairs as long as the +# following table is adjusted. programmer id = "ttl232r"; @@ -1646,9 +1623,33 @@ programmer # usbasp #------------------------------------------------------------ +# From http://www.fischl.de/usbasp +# USBasp is a USB in-circuit programmer for Atmel AVR controllers. It +# simply consists of an ATmega88 or an ATmega8 and a couple of passive +# components. The programmer uses a firmware-only USB driver, no +# special USB controller is needed. +# +# Firmware, schematics and drivers are available under above URL, too. +# +# Alternative firmware for the external programmer: +# +# - https://github.com/mariusgreuel/USBasp +# Windows OS descriptor to load WinUSB driver automatically +# +# - https://github.com/nerdralph/usbasp +# WCID compliant, meaning it should work on Windows without any +# driver or .inf install; default SCK clock of 1.5 MHz and automatic +# SCK slowing if target does not respond; PORTD is left as input, so +# this firmware also works with USBISP modules, eg, +# https://www.sciencetronics.com/greenphotons/?p=938 +# +# - https://github.com/dioannidis/usbasp +# As above plus HID UART support, setting unique serial number and +# AT89S51/AT89S52 support + programmer id = "usbasp"; - desc = "USBasp, http://www.fischl.de/usbasp/"; + desc = "USBasp ISP and TPI programmer"; type = "usbasp"; prog_modes = PM_TPI | PM_ISP; connection_type = usb; @@ -1656,25 +1657,20 @@ programmer usbpid = 0x05dc; # Obdev's free shared PID usbvendor = "www.fischl.de"; usbproduct = "USBasp"; - # following variants are autodetected for id "usbasp" - # original usbasp from fischl.de - # see above "usbasp" - - # old usbasp from fischl.de + # Old usbasp from fischl.de: # usbvid = 0x03EB; # ATMEL # usbpid = 0xC7B4; # (unoffical) USBasp # usbvendor = "www.fischl.de"; # usbproduct = "USBasp"; - - # NIBObee (only if -P nibobee is given on command line) - # see below "nibobee" ; #------------------------------------------------------------ # nibobee #------------------------------------------------------------ +# http://www.nicai-systems.com/en/nibobee + programmer id = "nibobee"; desc = "NIBObee"; @@ -1705,14 +1701,16 @@ programmer # usbtiny #------------------------------------------------------------ -# USBtiny can also be used for TPI programming. +# https://learn.adafruit.com/usbtinyisp +# +# The ISP USBtiny programmer can also be used for TPI programming. # In that case, a resistor of 1 kOhm is needed between SDI and SDO # pins of the connector, and SDI (pin 1 of the 6-pin connector) # connects to TPIDATA. programmer id = "usbtiny"; - desc = "USBtiny simple USB programmer, https://learn.adafruit.com/usbtinyisp"; + desc = "USBtiny simple USB programmer"; type = "usbtiny"; prog_modes = PM_TPI | PM_ISP; connection_type = usb; @@ -1784,11 +1782,12 @@ programmer # ehajo-isp #------------------------------------------------------------ -# commercial version of USBtiny, using a separate VID/PID +# Commercial version of USBtiny using a separate VID/PID from +# http://www.eHaJo.de (closed from end of 2023) programmer id = "ehajo-isp"; - desc = "avr-isp-programmer from eHaJo, http://www.eHaJo.de"; + desc = "AVR ISP programmer from eHaJo.de"; type = "usbtiny"; prog_modes = PM_TPI | PM_ISP; connection_type = usb; @@ -1800,12 +1799,14 @@ programmer # iseavrprog #------------------------------------------------------------ -# commercial version of USBtiny, using a separate VID/PID +# Commercial version of USBtiny using a separate VID/PID from +# https://iascaled.com +# # https://github.com/IowaScaledEngineering/ckt-avrprogrammer programmer id = "iseavrprog"; - desc = "USBtiny-based programmer, https://iascaled.com"; + desc = "AVR ISP programmer from iascaled.com"; type = "usbtiny"; prog_modes = PM_TPI | PM_ISP; connection_type = usb; @@ -1910,33 +1911,25 @@ programmer ; #------------------------------------------------------------ -# mkbutterfly +# butterfly_mk and mkbutterfly #------------------------------------------------------------ -# suggested in http://forum.mikrokopter.de/topic-post48317.html +# http://forum.mikrokopter.de programmer - id = "mkbutterfly"; + id = "butterfly_mk", "mkbutterfly"; desc = "Mikrokopter.de Butterfly for bootloader"; type = "butterfly_mk"; prog_modes = PM_SPM; connection_type = serial; ; -#------------------------------------------------------------ -# butterfly_mk -#------------------------------------------------------------ - -programmer parent "mkbutterfly" - id = "butterfly_mk"; -; - #------------------------------------------------------------ # jtagmkI #------------------------------------------------------------ programmer - id = "jtagmkI"; + id = "jtagmkI", "jtag1"; desc = "Atmel JTAG ICE (mkI)"; type = "jtagmki"; prog_modes = PM_JTAGmkI; @@ -1945,22 +1938,10 @@ programmer baudrate = 115200; # default is 115200 ; -#------------------------------------------------------------ -# jtag1 -#------------------------------------------------------------ - -# easier to type - -programmer parent "jtagmkI" - id = "jtag1"; -; - #------------------------------------------------------------ # jtag1slow #------------------------------------------------------------ -# easier to type - programmer parent "jtag1" id = "jtag1slow"; baudrate = 19200; @@ -1989,8 +1970,6 @@ programmer # jtag2slow #------------------------------------------------------------ -# easier to type - programmer parent "jtagmkII" id = "jtag2slow"; ; @@ -1999,23 +1978,13 @@ programmer parent "jtagmkII" # jtag2fast #------------------------------------------------------------ -# JTAG ICE mkII @ 115200 Bd +# JTAG ICE mkII @ 115200 Bd (and alias jtag2 the fast version) programmer parent "jtag2slow" - id = "jtag2fast"; + id = "jtag2fast", "jtag2"; baudrate = 115200; ; -#------------------------------------------------------------ -# jtag2 -#------------------------------------------------------------ - -# make the fast one the default, people will love that - -programmer parent "jtag2fast" - id = "jtag2"; -; - #------------------------------------------------------------ # jtag2isp #------------------------------------------------------------ @@ -2055,7 +2024,7 @@ programmer # JTAG ICE mkII in AVR32 mode programmer - id = "jtagmkII_avr32"; + id = "jtagmkII_avr32", "jtag2avr32"; desc = "Atmel JTAG ICE mkII in AVR32 mode"; type = "jtagmkii_avr32"; prog_modes = PM_aWire; @@ -2064,16 +2033,6 @@ programmer baudrate = 115200; ; -#------------------------------------------------------------ -# jtag2avr32 -#------------------------------------------------------------ - -# JTAG ICE mkII in AVR32 mode - -programmer parent "jtagmkII_avr32" - id = "jtag2avr32"; -; - #------------------------------------------------------------ # jtag2pdi #------------------------------------------------------------ @@ -2769,12 +2728,12 @@ programmer # siprog #------------------------------------------------------------ +# Serial port adapter http://www.lancos.com/siprogsch.html # Same as above, different name -# reset=!txd sck=rts sdo=dtr sdi=cts programmer parent "ponyser" id = "siprog"; - desc = "Lancos SI-Prog "; + desc = "Lancos SI-Prog (same as ponyser)"; ; #------------------------------------------------------------ @@ -4424,8 +4383,8 @@ part memory "lfuse" size = 1; initval = 0xe1; - min_write_delay = 9000; - max_write_delay = 9000; + min_write_delay = 4500; + max_write_delay = 4500; read = "0101.0000--0000.0000--xxxx.xxxx--oooo.oooo"; write = "1010.1100--1010.0000--xxxx.xxxx--iiii.iiii"; ; @@ -4433,8 +4392,8 @@ part memory "hfuse" size = 1; initval = 0x99; - min_write_delay = 9000; - max_write_delay = 9000; + min_write_delay = 4500; + max_write_delay = 4500; read = "0101.1000--0000.1000--xxxx.xxxx--oooo.oooo"; write = "1010.1100--1010.1000--xxxx.xxxx--iiii.iiii"; ; @@ -4443,8 +4402,8 @@ part size = 1; initval = 0xfd; bitmask = 0x03; - min_write_delay = 9000; - max_write_delay = 9000; + min_write_delay = 4500; + max_write_delay = 4500; read = "0101.0000--0000.1000--xxxx.xxxx--oooo.oooo"; write = "1010.1100--1010.0100--xxxx.xxxx--xxxx.xxii"; ; @@ -4453,8 +4412,8 @@ part size = 1; initval = 0xff; bitmask = 0x3f; - min_write_delay = 9000; - max_write_delay = 9000; + min_write_delay = 4500; + max_write_delay = 4500; read = "0101.1000--0000.0000--xxxx.xxxx--oooo.oooo"; write = "1010.1100--111x.xxxx--xxxx.xxxx--11ii.iiii"; ; @@ -4519,7 +4478,7 @@ part boot_section_size = 1024; stk500_devcode = 0xb2; avr910_devcode = 0x43; - chip_erase_delay = 9000; + chip_erase_delay = 10000; pagel = 0xd7; bs2 = 0xa0; signature = 0x1e 0x97 0x02; @@ -4556,8 +4515,8 @@ part memory "eeprom" size = 4096; page_size = 8; - min_write_delay = 9000; - max_write_delay = 9000; + min_write_delay = 10000; + max_write_delay = 10000; readback = 0xff 0xff; mode = 0x04; delay = 20; @@ -4572,8 +4531,8 @@ part size = 0x20000; page_size = 256; num_pages = 512; - min_write_delay = 4500; - max_write_delay = 4500; + min_write_delay = 5000; + max_write_delay = 5000; readback = 0xff 0x00; mode = 0x21; delay = 10; @@ -4589,8 +4548,8 @@ part memory "lfuse" size = 1; initval = 0xe1; - min_write_delay = 9000; - max_write_delay = 9000; + min_write_delay = 4500; + max_write_delay = 4500; read = "0101.0000--0000.0000--xxxx.xxxx--oooo.oooo"; write = "1010.1100--1010.0000--xxxx.xxxx--iiii.iiii"; ; @@ -4598,8 +4557,8 @@ part memory "hfuse" size = 1; initval = 0x99; - min_write_delay = 9000; - max_write_delay = 9000; + min_write_delay = 4500; + max_write_delay = 4500; read = "0101.1000--0000.1000--xxxx.xxxx--oooo.oooo"; write = "1010.1100--1010.1000--xxxx.xxxx--iiii.iiii"; ; @@ -4608,8 +4567,8 @@ part size = 1; initval = 0xfd; bitmask = 0x03; - min_write_delay = 9000; - max_write_delay = 9000; + min_write_delay = 4500; + max_write_delay = 4500; read = "0101.0000--0000.1000--xxxx.xxxx--oooo.oooo"; write = "1010.1100--1010.0100--xxxx.xxxx--xxxx.xxii"; ; @@ -4618,8 +4577,8 @@ part size = 1; initval = 0xff; bitmask = 0x3f; - min_write_delay = 9000; - max_write_delay = 9000; + min_write_delay = 4500; + max_write_delay = 4500; read = "0101.1000--0000.0000--xxxx.xxxx--oooo.oooo"; write = "1010.1100--111x.xxxx--xxxx.xxxx--11ii.iiii"; ; @@ -5169,8 +5128,8 @@ part memory "lfuse" size = 1; initval = 0xe1; - min_write_delay = 9000; - max_write_delay = 9000; + min_write_delay = 4500; + max_write_delay = 4500; read = "0101.0000--0000.0000--xxxx.xxxx--oooo.oooo"; write = "1010.1100--1010.0000--xxxx.xxxx--iiii.iiii"; ; @@ -5178,8 +5137,8 @@ part memory "hfuse" size = 1; initval = 0x99; - min_write_delay = 9000; - max_write_delay = 9000; + min_write_delay = 4500; + max_write_delay = 4500; read = "0101.1000--0000.1000--xxxx.xxxx--oooo.oooo"; write = "1010.1100--1010.1000--xxxx.xxxx--iiii.iiii"; ; @@ -5188,8 +5147,8 @@ part size = 1; initval = 0xff; bitmask = 0x3f; - min_write_delay = 9000; - max_write_delay = 9000; + min_write_delay = 4500; + max_write_delay = 4500; read = "0101.1000--0000.0000--xxxx.xxxx--oooo.oooo"; write = "1010.1100--111x.xxxx--xxxx.xxxx--11ii.iiii"; ; @@ -7059,8 +7018,8 @@ part memory "lfuse" size = 1; initval = 0xe1; - min_write_delay = 2000; - max_write_delay = 2000; + min_write_delay = 4500; + max_write_delay = 4500; read = "0101.0000--0000.0000--xxxx.xxxx--oooo.oooo"; write = "1010.1100--1010.0000--xxxx.xxxx--iiii.iiii"; ; @@ -7068,8 +7027,8 @@ part memory "hfuse" size = 1; initval = 0x99; - min_write_delay = 2000; - max_write_delay = 2000; + min_write_delay = 4500; + max_write_delay = 4500; read = "0101.1000--0000.1000--xxxx.xxxx--oooo.oooo"; write = "1010.1100--1010.1000--xxxx.xxxx--iiii.iiii"; ; @@ -7078,8 +7037,8 @@ part size = 1; initval = 0xff; bitmask = 0x3f; - min_write_delay = 2000; - max_write_delay = 2000; + min_write_delay = 4500; + max_write_delay = 4500; read = "0101.1000--0000.0000--xxxx.xxxx--oooo.oooo"; write = "1010.1100--111x.xxxx--xxxx.xxxx--11ii.iiii"; ; @@ -7254,7 +7213,7 @@ part boot_section_size = 256; stk500_devcode = 0x70; avr910_devcode = 0x76; - chip_erase_delay = 10000; + chip_erase_delay = 9000; pagel = 0xd7; bs2 = 0xc2; signature = 0x1e 0x93 0x07; @@ -7321,8 +7280,8 @@ part memory "lfuse" size = 1; initval = 0xe1; - min_write_delay = 2000; - max_write_delay = 2000; + min_write_delay = 4500; + max_write_delay = 4500; read = "0101.0000--0000.0000--xxxx.xxxx--oooo.oooo"; write = "1010.1100--1010.0000--xxxx.xxxx--iiii.iiii"; ; @@ -7330,8 +7289,8 @@ part memory "hfuse" size = 1; initval = 0xd9; - min_write_delay = 2000; - max_write_delay = 2000; + min_write_delay = 4500; + max_write_delay = 4500; read = "0101.1000--0000.1000--xxxx.xxxx--oooo.oooo"; write = "1010.1100--1010.1000--xxxx.xxxx--iiii.iiii"; ; @@ -7340,8 +7299,8 @@ part size = 1; initval = 0xff; bitmask = 0x3f; - min_write_delay = 2000; - max_write_delay = 2000; + min_write_delay = 4500; + max_write_delay = 4500; read = "0101.1000--0000.0000--xxxx.xxxx--oooo.oooo"; write = "1010.1100--111x.xxxx--xxxx.xxxx--11ii.iiii"; ; @@ -9348,7 +9307,8 @@ part read = "0101.1000--0000.0000--0000.0000--oooo.oooo"; write = "1010.1100--111x.xxxx--xxxx.xxxx--xxxx.xxii"; ; -# ATtiny87 has Signature Bytes: 0x1E 0x93 0x87. + + # ATtiny87 has signature bytes 0x1E 0x93 0x87 memory "signature" size = 3; read = "0011.0000--000x.xxxx--xxxx.xxaa--oooo.oooo"; @@ -9496,7 +9456,8 @@ part read = "0101.1000--0000.0000--0000.0000--oooo.oooo"; write = "1010.1100--111x.xxxx--xxxx.xxxx--xxxx.xxii"; ; -# ATtiny167 has Signature Bytes: 0x1E 0x94 0x87. + + # ATtiny167 has signature bytes 0x1E 0x94 0x87 memory "signature" size = 3; read = "0011.0000--000x.xxxx--xxxx.xxaa--oooo.oooo"; @@ -11142,11 +11103,13 @@ part read = "0101.1000--0000.0000--xxxx.xxxx--oooo.oooo"; write = "1010.1100--111x.xxxx--xxxx.xxxx--11ii.iiii"; ; -# ATtiny2313 has Signature Bytes: 0x1E 0x91 0x0A. + + # ATtiny2313 has signature bytes 0x1E 0x91 0x0A memory "signature" size = 3; read = "0011.0000--000x.xxxx--xxxx.xxaa--oooo.oooo"; ; + # The Tiny2313 has calibration data for both 4 MHz and 8 MHz. # The information in the data sheet of April/2004 is wrong, this works: @@ -11314,7 +11277,8 @@ part read = "0101.1000--0000.0000--xxxx.xxxx--oooo.oooo"; write = "1010.1100--111x.xxxx--xxxx.xxxx--11ii.iiii"; ; -# ATtiny4313 has Signature Bytes: 0x1E 0x92 0x0D. + + # ATtiny4313 has signature bytes 0x1E 0x92 0x0D memory "signature" size = 3; read = "0011.0000--000x.xxxx--xxxx.xxaa--oooo.oooo"; @@ -11594,7 +11558,8 @@ part read = "0101.1000--0000.0000--xxxx.xxxx--oooo.oooo"; write = "1010.1100--111x.xxxx--xxxx.xxxx--11ii.iiii"; ; -# AT90PWM2 has Signature Bytes: 0x1E 0x93 0x81. + + # AT90PWM2 has signature bytes 0x1E 0x93 0x81 memory "signature" size = 3; read = "0011.0000--00xx.xxxx--xxxx.xxaa--oooo.oooo"; @@ -12059,7 +12024,8 @@ part read = "0101.1000--0000.0000--0000.0000--oooo.oooo"; write = "1010.1100--111x.xxxx--xxxx.xxxx--11ii.iiii"; ; -# ATtiny25 has Signature Bytes: 0x1E 0x91 0x08. + + # ATtiny25 has signature bytes 0x1E 0x91 0x08 memory "signature" size = 3; read = "0011.0000--000x.xxxx--xxxx.xxaa--oooo.oooo"; @@ -12218,7 +12184,8 @@ part read = "0101.1000--0000.0000--0000.0000--oooo.oooo"; write = "1010.1100--111x.xxxx--xxxx.xxxx--11ii.iiii"; ; -# ATtiny45 has Signature Bytes: 0x1E 0x92 0x08. (Data sheet 2586C-AVR-06/05 (doc2586.pdf) indicates otherwise!) + + # ATtiny45 has signature bytes 0x1E 0x92 0x08 (data sheet 2586C-AVR-06/05 doc2586.pdf indicates otherwise) memory "signature" size = 3; read = "0011.0000--000x.xxxx--xxxx.xxaa--oooo.oooo"; @@ -12374,7 +12341,8 @@ part read = "0101.1000--0000.0000--0000.0000--oooo.oooo"; write = "1010.1100--111x.xxxx--xxxx.xxxx--11ii.iiii"; ; -# ATtiny85 has Signature Bytes: 0x1E 0x93 0x08. + + # ATtiny85 has signature bytes 0x1E 0x93 0x08 memory "signature" size = 3; read = "0011.0000--000x.xxxx--xxxx.xxaa--oooo.oooo"; @@ -12874,7 +12842,7 @@ part parent "m2561" "ATmega128RFA1-ZUR00: VFQFN64, Fmax=N/A, T=[-40 C, 85 C], Vcc=[1.8 V, 3.6 V]"; mcuid = 87; n_interrupts = 72; - chip_erase_delay = 55000; + chip_erase_delay = 18500; bs2 = 0xe2; signature = 0x1e 0xa7 0x01; pp_controlstack = @@ -12886,24 +12854,66 @@ part parent "m2561" ocdrev = 3; memory "eeprom" + min_write_delay = 13000; + max_write_delay = 13000; delay = 50; ; memory "flash" size = 0x20000; num_pages = 512; - min_write_delay = 50000; - max_write_delay = 50000; delay = 50; load_ext_addr = NULL; ; + + memory "lfuse" + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "hfuse" + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "efuse" + min_write_delay = 4500; + max_write_delay = 4500; + ; + + memory "lock" + min_write_delay = 4500; + max_write_delay = 4500; + ; + + ##### + # Three separate flash pages + # - Offset 0x100 in signature row + # - Only programmable with JTAG or HVPP + # - Readable from an application + # - Cannot be read using ISP + # - Not erased by chip erase + # + memory "usersig" + paged = yes; + size = 768; + page_size = 256; + num_pages = 3; + offset = 0x100; + min_write_delay = 4500; + max_write_delay = 4500; + mode = 0x41; + delay = 50; + blocksize = 256; + readsize = 256; + ; ; #------------------------------------------------------------ # ATmega256RFR2 #------------------------------------------------------------ -part parent "m2561" +part parent "m128rfa1" desc = "ATmega256RFR2"; id = "m256rfr2"; variants = @@ -12913,29 +12923,21 @@ part parent "m2561" "ATmega256RFR2-ZUR: VFQFN64, Fmax=16 MHz, T=[-40 C, 85 C], Vcc=[1.8 V, 3.6 V]"; mcuid = 108; n_interrupts = 77; - chip_erase_delay = 18500; - bs2 = 0xe2; signature = 0x1e 0xa8 0x02; - pp_controlstack = - 0x0e, 0x1e, 0x0f, 0x1f, 0x2e, 0x3e, 0x2f, 0x3f, - 0x4e, 0x5e, 0x4f, 0x5f, 0x6e, 0x7e, 0x6f, 0x7f, - 0x66, 0x76, 0x67, 0x77, 0x6a, 0x7a, 0x6b, 0x7b, - 0xbe, 0xfd, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00; - latchcycles = 5; chiperasepolltimeout = 20; + ocdrev = 4; memory "eeprom" size = 8192; - min_write_delay = 13000; - max_write_delay = 13000; - delay = 50; read = "1010.0000--xxxa.aaaa--aaaa.aaaa--oooo.oooo"; write = "1100.0000--xxxa.aaaa--aaaa.aaaa--iiii.iiii"; writepage = "1100.0010--00xa.aaaa--aaaa.a000--xxxx.xxxx"; ; memory "flash" - delay = 50; + size = 0x40000; + num_pages = 1024; + load_ext_addr = "0100.1101--0000.0000--0000.000a--0000.0000"; ; memory "efuse" @@ -12984,8 +12986,6 @@ part parent "m128rfa1" memory "eeprom" size = 2048; - min_write_delay = 13000; - max_write_delay = 13000; read = "1010.0000--xxxx.xaaa--aaaa.aaaa--oooo.oooo"; write = "1100.0000--xxxx.xaaa--aaaa.aaaa--iiii.iiii"; writepage = "1100.0010--00xx.xaaa--aaaa.a000--xxxx.xxxx"; @@ -13190,7 +13190,8 @@ part read = "0101.1000--0000.0000--0000.0000--oooo.oooo"; write = "1010.1100--111x.xxxx--xxxx.xxxx--xxxx.xxii"; ; -# ATtiny24 has Signature Bytes: 0x1E 0x91 0x0B. + + # ATtiny24 has signature bytes 0x1E 0x91 0x0B memory "signature" size = 3; read = "0011.0000--000x.xxxx--xxxx.xxaa--oooo.oooo"; @@ -13369,7 +13370,8 @@ part read = "0101.1000--0000.0000--0000.0000--oooo.oooo"; write = "1010.1100--111x.xxxx--xxxx.xxxx--xxxx.xxii"; ; -# ATtiny44 has Signature Bytes: 0x1E 0x92 0x07. + + # ATtiny44 has signature bytes 0x1E 0x92 0x07 memory "signature" size = 3; read = "0011.0000--000x.xxxx--xxxx.xxaa--oooo.oooo"; @@ -13547,7 +13549,8 @@ part read = "0101.1000--0000.0000--0000.0000--oooo.oooo"; write = "1010.1100--111x.xxxx--xxxx.xxxx--xxxx.xxii"; ; -# ATtiny84 has Signature Bytes: 0x1E 0x93 0x0C. + + # ATtiny84 has signature bytes 0x1E 0x93 0x0C memory "signature" size = 3; read = "0011.0000--000x.xxxx--xxxx.xxaa--oooo.oooo"; @@ -17084,6 +17087,7 @@ part parent ".xmega" n_interrupts = 127; boot_section_size = 8192; signature = 0x1e 0x97 0x51; + # usbpid = 0x2f??; memory "eeprom" diff --git a/src/avrdude.h b/src/avrdude.h index 8219252a..3ab85e5a 100644 --- a/src/avrdude.h +++ b/src/avrdude.h @@ -37,7 +37,8 @@ extern char progbuf[]; // Spaces same length as progname extern int ovsigck; // Override signature check (-F) extern int verbose; // Verbosity level (-v, -vv, ...) extern int quell_progress; // Quell progress report -q, reduce effective verbosity level (-qq, -qqq) -extern const char *partdesc; // Part id +extern const char *partdesc; // Part -p string +extern const char *pgmid; // Programmer -c string int avrdude_message(int msglvl, const char *format, ...); int avrdude_message2(FILE *fp, int lno, const char *file, const char *func, int msgmode, int msglvl, const char *format, ...); diff --git a/src/buspirate.c b/src/buspirate.c index 4792ae43..3708722b 100644 --- a/src/buspirate.c +++ b/src/buspirate.c @@ -378,8 +378,7 @@ buspirate_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { } if (str_eq(extended_param, "help")) { - char *prg = (char *)ldata(lfirst(pgm->id)); - msg_error("%s -c %s extended options:\n", progname, prg); + msg_error("%s -c %s extended options:\n", progname, pgmid); msg_error(" -xreset=cs,aux,aux2 Override default reset pin\n"); msg_error(" -xspifreq=<0..7> Set binary SPI mode speed\n"); msg_error(" -xrawfreq=<0..3> Set \"raw-wire\" SPI mode speed\n"); diff --git a/src/butterfly.c b/src/butterfly.c index a71d55e6..7fc773aa 100644 --- a/src/butterfly.c +++ b/src/butterfly.c @@ -140,11 +140,21 @@ static int butterfly_vfy_led(const PROGRAMMER *pgm, int value) { * issue the 'chip erase' command to the butterfly board */ static int butterfly_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { - butterfly_send(pgm, "e", 1); - if (butterfly_vfy_cmd_sent(pgm, "chip erase") < 0) - return -1; + long bak_timeout = serial_recv_timeout; + AVRMEM *fl = avr_locate_mem(p, "flash"); + int ret = 0; - return 0; + // Estimated time it takes to erase all pages in bootloader + long new_timeout = p->chip_erase_delay * (fl? fl->num_pages: 999); + if(serial_recv_timeout < new_timeout) + serial_recv_timeout = new_timeout; + + butterfly_send(pgm, "e", 1); + if(butterfly_vfy_cmd_sent(pgm, "chip erase") < 0) + ret = -1; + + serial_recv_timeout = bak_timeout; + return ret; } diff --git a/src/config_gram.y b/src/config_gram.y index d862e204..df8c7cf0 100644 --- a/src/config_gram.y +++ b/src/config_gram.y @@ -250,7 +250,6 @@ prog_def : prog_decl prog_parms { PROGRAMMER * existing_prog; - char * id; if (lsize(current_prog->id) == 0) { yyerror("required parameter id not specified"); YYABORT; @@ -259,17 +258,17 @@ prog_def : yyerror("programmer type not specified"); YYABORT; } - id = ldata(lfirst(current_prog->id)); - existing_prog = locate_programmer(programmers, id); - if (existing_prog) { - { /* temporarily set lineno to lineno of programmer start */ + for(LNODEID ln = lfirst(current_prog->id); ln; ln = lnext(ln)) { + char *id = ldata(ln); + if((existing_prog = locate_programmer(programmers, id))) { + // Temporarily set lineno to lineno of programmer start int temp = cfg_lineno; cfg_lineno = current_prog->lineno; yywarning("programmer %s overwrites previous definition %s:%d.", - id, existing_prog->config_file, existing_prog->lineno); + id, existing_prog->config_file, existing_prog->lineno); cfg_lineno = temp; + lrmv_d(programmers, existing_prog); + pgm_free(existing_prog); } - lrmv_d(programmers, existing_prog); - pgm_free(existing_prog); } current_prog->comments = cfg_move_comments(); LISTADD(programmers, current_prog); diff --git a/src/developer_opts.c b/src/developer_opts.c index 2c60b320..5bed3ebc 100644 --- a/src/developer_opts.c +++ b/src/developer_opts.c @@ -361,9 +361,11 @@ void dev_print_comment(const LISTID comms) { static void dev_cout(const LISTID comms, const char *name, int rhs, int elself) { COMMENT *cp; + if(elself == 2) + dev_info("\n"); if((cp = locate_comment(comms, name, rhs))) dev_print_comment(cp->comms); - else if(elself) + else if(elself == 1) dev_info("\n"); } @@ -813,13 +815,13 @@ static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base, bool int haveinjct = 0; if(injct) for(size_t i=0; idesc) && str_match(meminj[i].mem, m->desc)) + if(meminj[i].mcu && str_casematch(meminj[i].mcu, p->desc) && str_match(meminj[i].mem, m->desc)) haveinjct = 1; if(!haveinjct) continue; } - dev_cout(m->comments, "*", 0, 1); + dev_cout(m->comments, "*", 0, 2); dev_info(" memory \"%s\"\n", m->desc); } @@ -848,7 +850,7 @@ static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base, bool if(injct) for(size_t i=0; idesc) && str_match(meminj[i].mem, m->desc)) + if(str_casematch(meminj[i].mcu, p->desc) && str_match(meminj[i].mem, m->desc)) dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, meminj[i].var, cfg_strdup("meminj", meminj[i].value), NULL); @@ -882,7 +884,7 @@ static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base, bool if(injct) for(size_t i=0; idesc)) + if(str_casematch(ptinj[i].mcu, p->desc)) dev_part_strct_entry(tsv, ".pt", p->desc, NULL, ptinj[i].var, cfg_strdup("ptinj", ptinj[i].value), NULL); @@ -1426,7 +1428,7 @@ static void dev_pgm_strct(const PROGRAMMER *pgm, bool tsv, const PROGRAMMER *bas for(size_t i=0; iid); ln; ln=lnext(ln)) - if(str_match(pgminj[i].pgmid, ldata(ln))) + if(str_casematch(pgminj[i].pgmid, ldata(ln))) dev_part_strct_entry(tsv, ".prog", ldata(ln), NULL, pgminj[i].var, cfg_strdup("pgminj", pgminj[i].value), NULL); @@ -1438,16 +1440,16 @@ static void dev_pgm_strct(const PROGRAMMER *pgm, bool tsv, const PROGRAMMER *bas // -c */[ASsrti] -void dev_output_pgm_defs(char *pgmid) { +void dev_output_pgm_defs(char *pgmidcp) { bool astrc, strct, cmpst, raw, tsv, injct; char *flags; int nprinted; PROGRAMMER *nullpgm = pgm_new(); - if((flags = strchr(pgmid, '/'))) + if((flags = strchr(pgmidcp, '/'))) *flags++ = 0; - if(!flags && str_eq(pgmid, "*")) // Treat -c * as if it was -c */s + if(!flags && str_eq(pgmidcp, "*")) // Treat -c * as if it was -c */s flags = "s"; if(!*flags || !strchr("ASsrti", *flags)) { @@ -1494,7 +1496,7 @@ void dev_output_pgm_defs(char *pgmid) { PROGRAMMER *pgm = ldata(ln1); int matched = 0; for(ln2=lfirst(pgm->id); ln2; ln2=lnext(ln2)) { - if(str_casematch(pgmid, ldata(ln2))) { + if(str_casematch(pgmidcp, ldata(ln2))) { matched = 1; break; } diff --git a/src/doc/avrdude.texi b/src/doc/avrdude.texi index a5bee79b..48811d5c 100644 --- a/src/doc/avrdude.texi +++ b/src/doc/avrdude.texi @@ -2184,7 +2184,7 @@ and paste of lists. @item write @var{memory} @var{addr} @var{data} The start address @code{addr} may be omitted if the size of the memory -being written to is 1 byte in size. +being written to is one byte. @item write @var{memory} @var{addr} @var{len} @var{data[,]} @var{@{data[,]@}} @dots{} The ellipsis @dots{} form writes the data to the entire memory intervall @@ -2269,6 +2269,13 @@ It is quite possible, as is with direct writing to the underlying fuses and lock bits, to brick a part, i.e., make it unresponsive to further programming with the chosen programmer: here be dragons. +@item include [@var{opts}] @var{file} +Include contents of the named file @var{file} as if it was typed. This is +useful for batch scripts, eg, recurring initialisation code for fuses. The +include option @code{-e} prints the lines of the file as comments before +processing them; on a non-zero verbosity level the line numbers are +printed, too. + @item sig Display the device signature bytes. @@ -3098,7 +3105,7 @@ defined for the programmer, a message indicating that the device needs a power-cycle is printed out. This flag was added to work around a problem with the at90s4433/2333's; see the at90s4433 errata at: - @url{http://www.atmel.com/dyn/resources/prod_documents/doc1280.pdf} + @url{https://www.microchip.com/content/dam/mchp/documents/OTH/ProductDocuments/DataSheets/doc1042.pdf} @item The boot loader from application note AVR109 (and thus also the AVR diff --git a/src/dryrun.c b/src/dryrun.c index ee50eadd..313501f2 100644 --- a/src/dryrun.c +++ b/src/dryrun.c @@ -164,11 +164,10 @@ static int dryrun_initialize(const PROGRAMMER *pgm, const AVRPART *p) { int pm = pgm->prog_modes & p->prog_modes; if(!pm) - Return("programmer %s and part %s have no common programming mode", - (char *) ldata(lfirst(pgm->id)), p->desc); + Return("programmer %s and part %s have no common programming mode", pgmid, p->desc); if(pm & (pm-1)) Return("%s and %s share multiple programming modes (%s)", - (char *) ldata(lfirst(pgm->id)), p->desc, avr_prog_modes(pm)); + pgmid, p->desc, avr_prog_modes(pm)); */ return pgm->program_enable(pgm, p); diff --git a/src/fileio.c b/src/fileio.c index d3b2f4a2..cddff602 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -521,7 +521,7 @@ static int b2srec(const AVRMEM *mem, const Segment_t *segp, Segorder_t where, // Add S5/6 record count record and S7/8/9 end of data record if(where & LAST_SEG) { - if(reccount > 0 && reccount <= 0xffffff) { + if(reccount >= 0 && reccount <= 0xffffff) { int wd = reccount <= 0xffff? 2: 3; fprintf(outf, "S%c%02X%0*X%02X\n", '5' + (wd == 3), wd + 1, 2*wd, reccount, cksum_srec(NULL, 0, reccount, wd)); @@ -1227,7 +1227,7 @@ static int b2num(const char *filename, FILE *f, const AVRMEM *mem, const Segment if (putc('\n', f) == EOF) goto writeerr; - return segp->addr + segp->len-1; + return segp->addr + segp->len; writeerr: pmsg_ext_error("unable to write to %s: %s\n", filename, strerror(errno)); @@ -1457,8 +1457,8 @@ int segment_normalise(const AVRMEM *mem, Segment_t *segp) { addr = maxsize + addr; if(addr < 0 || addr >= maxsize) { - pmsg_error("%s address %s is out of range [-0x%0*x, 0x%0*x]\n", - mem->desc, segp->addr, digits, maxsize, digits, maxsize-1); + pmsg_error("%s address 0x%0*x is out of range [-0x%0*x, 0x%0*x]\n", + mem->desc, digits, segp->addr, digits, maxsize, digits, maxsize-1); return -1; } @@ -1555,7 +1555,7 @@ static int fileio_segments_normalise(int oprwv, const char *filename, FILEFMT fo for(int i=0; iflag & PGM_FL_IS_EDBG) && - !str_starts(ldata(lfirst(pgm->id)), "xplainedmini")) { + !str_starts(pgmid, "xplainedmini")) { if (jtag3_edbg_prepare(pgm) < 0) { return -1; } @@ -1583,13 +1583,12 @@ static int jtag3_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { } else if (str_eq(extended_param, "help")) { - char *prg = (char *)ldata(lfirst(pgm->id)); - msg_error("%s -c %s extended options:\n", progname, prg); + msg_error("%s -c %s extended options:\n", progname, pgmid); if (str_eq(pgm->type, "JTAGICE3")) msg_error(" -xjtagchain=UB,UA,BB,BA Setup the JTAG scan chain order\n"); - if (str_eq(prg, "powerdebugger_updi") || str_eq(prg, "pickit4_updi")) + if (str_eq(pgmid, "powerdebugger_updi") || str_eq(pgmid, "pickit4_updi")) msg_error(" -xhvupdi Enable high-voltage UPDI initialization\n"); - if (str_starts(prg, "xplainedmini") && !str_eq(prg, "xplainedmini_tpi")) { + if (str_starts(pgmid, "xplainedmini") && !str_eq(pgmid, "xplainedmini_tpi")) { msg_error(" -xsuffer Read SUFFER register value\n"); msg_error(" -xsuffer= Set SUFFER register value\n"); msg_error(" -xvtarg_switch Read on-board target voltage switch state\n"); @@ -1820,7 +1819,7 @@ void jtag3_close(PROGRAMMER * pgm) { /* XplainedMini boards do not need this, and early revisions had a * firmware bug where they complained about it. */ if ((pgm->flag & PGM_FL_IS_EDBG) && - !str_starts(ldata(lfirst(pgm->id)), "xplainedmini")) { + !str_starts(pgmid, "xplainedmini")) { jtag3_edbg_signoff(pgm); } diff --git a/src/jtagmkII.c b/src/jtagmkII.c index c7cc0477..2338adfa 100644 --- a/src/jtagmkII.c +++ b/src/jtagmkII.c @@ -1225,10 +1225,9 @@ static int jtagmkII_initialize(const PROGRAMMER *pgm, const AVRPART *p) { } /* Abort and print error if programmer does not support the target microcontroller */ - if ((strncmp(pgm->type, "JTAGMKII_UPDI", strlen("JTAGMKII_UPDI")) == 0 && !(p->prog_modes & PM_UPDI)) || - (strncmp(ldata(lfirst(pgm->id)), "jtagmkII", strlen("jtagmkII")) == 0 && (p->prog_modes & PM_UPDI))) { - msg_error("programmer %s does not support target %s\n\n", - (char *) ldata(lfirst(pgm->id)), p->desc); + if((str_starts(pgm->type, "JTAGMKII_UPDI") && !(p->prog_modes & PM_UPDI)) || + (str_starts(pgmid, "jtagmkII") && (p->prog_modes & PM_UPDI))) { + msg_error("programmer %s does not support target %s\n\n", pgmid, p->desc); return -1; } @@ -1298,9 +1297,8 @@ static int jtagmkII_initialize(const PROGRAMMER *pgm, const AVRPART *p) { AVRMEM *bootmem = avr_locate_mem(p, "boot"); AVRMEM *flashmem = avr_locate_mem(p, "flash"); if (bootmem == NULL || flashmem == NULL) { - if (strncmp(ldata(lfirst(pgm->id)), "jtagmkII", strlen("jtagmkII")) == 0) { + if(str_starts(pgmid, "jtagmkII")) pmsg_error("cannot locate flash or boot memories in description\n"); - } } else { if (PDATA(pgm)->fwver < 0x700) { /* V7+ firmware does not need this anymore */ @@ -1427,8 +1425,7 @@ static int jtagmkII_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) } if (str_eq(extended_param, "help")) { - char *prg = (char *)ldata(lfirst(pgm->id)); - msg_error("%s -c %s extended options:\n", progname, prg); + msg_error("%s -c %s extended options:\n", progname, pgmid); if (pgm->flag & PGM_FL_IS_JTAG) msg_error(" -xjtagchain=UB,UA,BB,BA Setup the JTAG scan chain order\n"); if (pgm->flag & PGM_FL_IS_PDI) diff --git a/src/libavrdude.h b/src/libavrdude.h index d5acb2f7..a0b54005 100644 --- a/src/libavrdude.h +++ b/src/libavrdude.h @@ -336,7 +336,7 @@ typedef struct avrmem { int pwroff_after_write; /* after this memory type is written to, the device must be powered off and back on, see errata - http://www.atmel.com/dyn/resources/prod_documents/doc1280.pdf */ + https://www.microchip.com/content/dam/mchp/documents/OTH/ProductDocuments/DataSheets/doc1042.pdf */ unsigned char readback[2]; /* polled read-back values */ int mode; /* stk500 v2 xml file parameter */ @@ -864,6 +864,8 @@ void programmer_display(PROGRAMMER * pgm, const char * p); void pgm_display_generic_mask(const PROGRAMMER *pgm, const char *p, unsigned int show); void pgm_display_generic(const PROGRAMMER *pgm, const char *p); +PROGRAMMER *locate_programmer_set(const LISTID programmers, const char *id, const char **setid); + PROGRAMMER *locate_programmer(const LISTID programmers, const char *configid); typedef void (*walk_programmers_cb)(const char *name, const char *desc, diff --git a/src/linuxspi.c b/src/linuxspi.c index 00e6650d..15a8abb0 100644 --- a/src/linuxspi.c +++ b/src/linuxspi.c @@ -414,8 +414,7 @@ static int linuxspi_parseextparams(const PROGRAMMER *pgm, const LISTID extparms) continue; } if (str_eq(extended_param, "help")) { - char *prg = (char *)ldata(lfirst(pgm->id)); - msg_error("%s -c %s extended options:\n", progname, prg); + msg_error("%s -c %s extended options:\n", progname, pgmid); msg_error(" -xdisable_no_cs Do not use the SPI_NO_CS bit for the SPI driver\n"); msg_error(" -xhelp Show this help menu and exit\n"); exit(0); diff --git a/src/main.c b/src/main.c index 9ccd73b7..37edb936 100644 --- a/src/main.c +++ b/src/main.c @@ -213,8 +213,8 @@ static PROGRAMMER * pgm; int verbose; // Verbose output int quell_progress; // Quell progress report and un-verbose output int ovsigck; // 1 = override sig check, 0 = don't -const char *partdesc; // Part id - +const char *partdesc; // Part -p string +const char *pgmid; // Programmer -c string /* * usage message @@ -280,7 +280,7 @@ static void pmshorten(char *desc, const char *modes) { for(size_t i=0; i elen && strcasecmp(desc+len-elen, pairs[i].end) == 0 && strcmp(modes, pairs[i].mode) == 0) { + if(len > elen && str_caseeq(desc+len-elen, pairs[i].end) && str_eq(modes, pairs[i].mode)) { desc[len-elen] = 0; break; } @@ -431,7 +431,7 @@ static void replace_backslashes(char *s) static int dev_opt(const char *str) { return !str? 0: - !strcmp(str, "*") || !strncmp(str, "*/", 2)? 2: + str_eq(str, "*") || str_starts(str, "*/")? 2: !!strchr(str, '/'); } @@ -511,7 +511,6 @@ int main(int argc, char * argv []) int calibrate; /* 1=calibrate RC oscillator, 0=don't */ char * port; /* device port (/dev/xxx) */ const char *exitspecs; /* exit specs string from command line */ - const char *programmer; /* programmer id */ int explicit_c; /* 1=explicit -c on command line, 0=not specified there */ int explicit_e; /* 1=explicit -e on command line, 0=not specified there */ char sys_config[PATH_MAX]; /* system wide config file */ @@ -560,7 +559,7 @@ int main(int argc, char * argv []) progname = argv[0]; // Remove trailing .exe - if(strlen(progname) > 4 && strcmp(progname+strlen(progname)-4, ".exe") == 0) { + if(str_ends(progname, ".exe")) { progname = cfg_strdup("main()", progname); // Don't write to argv[0] progname[strlen(progname)-4] = 0; } @@ -604,7 +603,7 @@ int main(int argc, char * argv []) quell_progress = 0; exitspecs = NULL; pgm = NULL; - programmer = ""; + pgmid = ""; explicit_c = 0; explicit_e = 0; verbose = 0; @@ -704,7 +703,7 @@ int main(int argc, char * argv []) break; case 'c': /* programmer id */ - programmer = optarg; + pgmid = optarg; explicit_c = 1; break; @@ -1003,15 +1002,15 @@ int main(int argc, char * argv []) bitclock = default_bitclock; } - if(!(programmer && *programmer) && *default_programmer) - programmer = cache_string(default_programmer); + if(!(pgmid && *pgmid) && *default_programmer) + pgmid = cache_string(default_programmer); // Developer options to print parts and/or programmer entries of avrdude.conf - int dev_opt_c = dev_opt(programmer); // -c /[sSArt] - int dev_opt_p = dev_opt(partdesc); // -p /[dsSArcow*t] + int dev_opt_c = dev_opt(pgmid); // -c /[sSArt] + int dev_opt_p = dev_opt(partdesc); // -p /[dsSArcow*t] if(dev_opt_c || dev_opt_p) { // See -c/h and or -p/h - dev_output_pgm_part(dev_opt_c, programmer, dev_opt_p, partdesc); + dev_output_pgm_part(dev_opt_c, pgmid, dev_opt_p, partdesc); exit(0); } @@ -1026,15 +1025,15 @@ int main(int argc, char * argv []) } } - if (partdesc) { - if (strcmp(partdesc, "?") == 0) { - if(programmer && *programmer && explicit_c) { - PROGRAMMER *pgm = locate_programmer(programmers, programmer); + if(partdesc) { + if(str_eq(partdesc, "?")) { + if(pgmid && *pgmid && explicit_c) { + PROGRAMMER *pgm = locate_programmer_set(programmers, pgmid, &pgmid); if(!pgm) { - programmer_not_found(programmer); + programmer_not_found(pgmid); exit(1); } - msg_error("\nValid parts for programmer %s are:\n", programmer); + msg_error("\nValid parts for programmer %s are:\n", pgmid); list_parts(stderr, " ", part_list, pgm->prog_modes); } else { msg_error("\nValid parts are:\n"); @@ -1045,8 +1044,8 @@ int main(int argc, char * argv []) } } - if (programmer) { - if (strcmp(programmer, "?") == 0) { + if(pgmid) { + if(str_eq(pgmid, "?")) { if(partdesc && *partdesc) { AVRPART *p = locate_part(part_list, partdesc); if(!p) { @@ -1063,7 +1062,7 @@ int main(int argc, char * argv []) exit(1); } - if (strcmp(programmer, "?type") == 0) { + if(str_eq(pgmid, "?type")) { msg_error("\nValid programmer types are:\n"); list_programmer_types(stderr, " "); msg_error("\n"); @@ -1073,14 +1072,14 @@ int main(int argc, char * argv []) msg_notice("\n"); - if (!programmer || !*programmer) { + if(!pgmid || !*pgmid) { programmer_not_found(NULL); exit(1); } - pgm = locate_programmer(programmers, programmer); + pgm = locate_programmer_set(programmers, pgmid, &pgmid); if (pgm == NULL) { - programmer_not_found(programmer); + programmer_not_found(pgmid); exit(1); } @@ -1104,8 +1103,7 @@ int main(int argc, char * argv []) for (LNODEID ln = lfirst(extended_params); ln; ln = lnext(ln)) { const char *extended_param = ldata(ln); if (str_eq(extended_param, "help")) { - char *prg = (char *)ldata(lfirst(pgm->id)); - msg_error("%s -c %s extended options:\n", progname, prg); + msg_error("%s -c %s extended options:\n", progname, pgmid); msg_error(" -xhelp Show this help menu and exit\n"); exit(0); } @@ -1160,7 +1158,7 @@ int main(int argc, char * argv []) if (verbose > 0) { imsg_notice("Using Port : %s\n", port); - imsg_notice("Using Programmer : %s\n", programmer); + imsg_notice("Using Programmer : %s\n", pgmid); } if (baudrate != 0) { @@ -1180,7 +1178,7 @@ int main(int argc, char * argv []) rc = pgm->open(pgm, port); if (rc < 0) { - pmsg_error("unable to open programmer %s on port %s\n", programmer, port); + pmsg_error("unable to open programmer %s on port %s\n", pgmid, port); exitrc = 1; pgm->ppidata = 0; /* clear all bits at exit */ goto main_exit; @@ -1220,7 +1218,7 @@ int main(int argc, char * argv []) } if(verbose > 0) { - if ((strcmp(pgm->type, "avr910") == 0)) { + if((str_eq(pgm->type, "avr910"))) { imsg_notice("avr910_devcode (avrdude.conf) : "); if(p->avr910_devcode) msg_notice("0x%02x\n", (uint8_t) p->avr910_devcode); @@ -1306,7 +1304,7 @@ int main(int argc, char * argv []) else imsg_error("- double check the connections and try again\n"); - if (strcmp(pgm->type, "serialupdi") == 0 || strcmp(pgm->type, "SERBB") == 0) + if(str_eq(pgm->type, "serialupdi") || str_eq(pgm->type, "SERBB")) imsg_error("- use -b to set lower baud rate, e.g. -b %d\n", baudrate? baudrate/2: 57600); else imsg_error("- use -B to set lower the bit clock frequency, e.g. -B 125kHz\n"); @@ -1453,7 +1451,7 @@ int main(int argc, char * argv []) m = avr_locate_mem(p, upd->memtype); if (m == NULL) continue; - if ((strcmp(m->desc, memname) == 0) && (upd->op == DEVICE_WRITE)) { + if(str_eq(m->desc, memname) && upd->op == DEVICE_WRITE) { erase = 1; pmsg_info("Note: %s memory has been specified, an erase cycle will be performed.\n", memname); imsg_info("To disable this feature, specify the -D option.\n"); diff --git a/src/micronucleus.c b/src/micronucleus.c index e322f9dc..11e8fec6 100644 --- a/src/micronucleus.c +++ b/src/micronucleus.c @@ -922,8 +922,7 @@ static int micronucleus_parseextparams(const PROGRAMMER *pgm, const LISTID xpara } else if (str_eq(param, "help")) { - char *prg = (char *)ldata(lfirst(pgm->id)); - msg_error("%s -c %s extended options:\n", progname, prg); + msg_error("%s -c %s extended options:\n", progname, pgmid); msg_error(" -xwait Wait for the device to be plugged in if not connected\n"); msg_error(" -xwait= Wait [s] for the device to be plugged in if not connected\n"); msg_error(" -xhelp Show this help menu and exit\n"); diff --git a/src/pgm.c b/src/pgm.c index 5eb321ad..e7d9576f 100644 --- a/src/pgm.c +++ b/src/pgm.c @@ -291,18 +291,24 @@ void pgm_display_generic(const PROGRAMMER *pgm, const char *p) { pgm_display_generic_mask(pgm, p, SHOW_ALL_PINS); } -PROGRAMMER *locate_programmer(const LISTID programmers, const char *configid) { - PROGRAMMER *p = NULL; - int found = 0; - - for(LNODEID ln1=lfirst(programmers); ln1 && !found; ln1=lnext(ln1)) { - p = ldata(ln1); - for(LNODEID ln2=lfirst(p->id); ln2 && !found; ln2=lnext(ln2)) - if(strcasecmp(configid, (const char *) ldata(ln2)) == 0) - found = 1; +PROGRAMMER *locate_programmer_set(const LISTID programmers, const char *configid, const char **setid) { + for(LNODEID ln1=lfirst(programmers); ln1; ln1=lnext(ln1)) { + PROGRAMMER *p = ldata(ln1); + for(LNODEID ln2=lfirst(p->id); ln2; ln2=lnext(ln2)) { + const char *id = (const char *) ldata(ln2); + if(str_caseeq(configid, id)) { + if(setid) + *setid = id; + return p; + } + } } - return found? p: NULL; + return NULL; +} + +PROGRAMMER *locate_programmer(const LISTID programmers, const char *configid) { + return locate_programmer_set(programmers, configid, NULL); } /* diff --git a/src/pickit2.c b/src/pickit2.c index e3b70819..caa87256 100644 --- a/src/pickit2.c +++ b/src/pickit2.c @@ -1212,8 +1212,7 @@ static int pickit2_parseextparams(const PROGRAMMER *pgm, const LISTID extparms) continue; } if (str_eq(extended_param, "help")) { - char *prg = (char *)ldata(lfirst(pgm->id)); - msg_error("%s -c %s extended options:\n", progname, prg); + msg_error("%s -c %s extended options:\n", progname, pgmid); msg_error(" -xclockrate= Set the SPI clocking rate in [Hz]\n"); msg_error(" -xtimeout= Set the timeout for USB read/write to [ms]\n"); msg_error(" -xhelp Show this help menu and exit\n"); diff --git a/src/serialupdi.c b/src/serialupdi.c index d287c6c6..794e4daf 100644 --- a/src/serialupdi.c +++ b/src/serialupdi.c @@ -944,8 +944,7 @@ static int serialupdi_parseextparms(const PROGRAMMER *pgm, const LISTID extparms continue; } if (str_eq(extended_param, "help")) { - char *prg = (char *)ldata(lfirst(pgm->id)); - msg_error("%s -c %s extended options:\n", progname, prg); + msg_error("%s -c %s extended options:\n", progname, pgmid); msg_error(" -xrtsdtr=low,high Force RTS/DTR lines low or high state during programming\n"); msg_error(" -xhelp Show this help menu and exit\n"); exit(0); diff --git a/src/stk500.c b/src/stk500.c index ccbb5004..ddc7fc84 100644 --- a/src/stk500.c +++ b/src/stk500.c @@ -403,7 +403,7 @@ static int stk500_initialize(const PROGRAMMER *pgm, const AVRPART *p) { stk500_getparm(pgm, Parm_STK_SW_MINOR, &min); // MIB510 does not need extparams - if (str_eq(ldata(lfirst(pgm->id)), "mib510")) + if (str_eq(pgmid, "mib510")) n_extparms = 0; else if ((maj > 1) || ((maj == 1) && (min > 10))) n_extparms = 4; @@ -749,8 +749,7 @@ static int stk500_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) } else if (str_eq(extended_param, "help")) { - char *prg = (char *)ldata(lfirst(pgm->id)); - msg_error("%s -c %s extended options:\n", progname, prg); + msg_error("%s -c %s extended options:\n", progname, pgmid); msg_error(" -xattempts= Specify no. connection retry attempts\n"); if (pgm->extra_features & HAS_VTARG_ADJ) { msg_error(" -xvtarg Read target supply voltage\n"); @@ -844,7 +843,7 @@ static int stk500_open(PROGRAMMER *pgm, const char *port) { stk500_drain(pgm, 0); // MIB510 init - if (str_eq(ldata(lfirst(pgm->id)), "mib510") && mib510_isp(pgm, 1) != 0) + if (str_eq(pgmid, "mib510") && mib510_isp(pgm, 1) != 0) return -1; if (stk500_getsync(pgm) < 0) @@ -857,7 +856,7 @@ static int stk500_open(PROGRAMMER *pgm, const char *port) { static void stk500_close(PROGRAMMER * pgm) { // MIB510 close - if (str_eq(ldata(lfirst(pgm->id)), "mib510")) + if (str_eq(pgmid, "mib510")) (void)mib510_isp(pgm, 0); serial_close(&pgm->fd); @@ -967,7 +966,7 @@ static int set_memtype_a_div(const PROGRAMMER *pgm, const AVRPART *p, const AVRM if(avr_mem_is_eeprom_type(m)) { *memtypep = 'E'; // Word addr for bootloaders or Arduino as ISP if part is a "classic" part, byte addr otherwise - *a_divp = ((pgm->prog_modes & PM_SPM) || str_caseeq(ldata(lfirst(pgm->id)), "arduino_as_isp")) \ + *a_divp = ((pgm->prog_modes & PM_SPM) || str_caseeq(pgmid, "arduino_as_isp")) \ && !(p->prog_modes & (PM_UPDI | PM_PDI))? 2: 1; return 0; } @@ -1003,7 +1002,7 @@ static int stk500_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVR for (; addr < n; addr += block_size) { // MIB510 uses fixed blocks size of 256 bytes - if (str_eq(ldata(lfirst(pgm->id)), "mib510")) { + if (str_eq(pgmid, "mib510")) { block_size = 256; } else { if (n - addr < page_size) @@ -1075,7 +1074,7 @@ static int stk500_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRM n = addr + n_bytes; for (; addr < n; addr += block_size) { // MIB510 uses fixed blocks size of 256 bytes - if (str_eq(ldata(lfirst(pgm->id)), "mib510")) { + if(str_eq(pgmid, "mib510")) { block_size = 256; } else { if (n - addr < page_size) @@ -1119,7 +1118,7 @@ static int stk500_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRM if (stk500_recv(pgm, buf, 1) < 0) return -1; - if(str_eq(ldata(lfirst(pgm->id)), "mib510")) { + if(str_eq(pgmid, "mib510")) { if (buf[0] != Resp_STK_INSYNC) { msg_error("\n"); pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]); diff --git a/src/stk500v2.c b/src/stk500v2.c index a95af29c..03410f4a 100644 --- a/src/stk500v2.c +++ b/src/stk500v2.c @@ -755,6 +755,9 @@ retry: if (siglen >= strlen("STK500_2") && memcmp(resp + 3, "STK500_2", strlen("STK500_2")) == 0) { PDATA(pgm)->pgmtype = PGMTYPE_STK500; + } else if (siglen >= strlen("SCRATCHMONKEY") && + memcmp(resp + 3, "SCRATCHMONKEY", strlen("SCRATCHMONKEY")) == 0) { + PDATA(pgm)->pgmtype = PGMTYPE_STK500; } else if (siglen >= strlen("AVRISP_2") && memcmp(resp + 3, "AVRISP_2", strlen("AVRISP_2")) == 0) { PDATA(pgm)->pgmtype = PGMTYPE_AVRISP; @@ -1932,8 +1935,7 @@ static int stk500v2_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) } else if (str_eq(extended_param, "help")) { - char *prg = (char *)ldata(lfirst(pgm->id)); - msg_error("%s -c %s extended options:\n", progname, prg); + msg_error("%s -c %s extended options:\n", progname, pgmid); if (pgm->extra_features & HAS_VTARG_ADJ) { msg_error(" -xvtarg Read target supply voltage\n"); msg_error(" -xvtarg= Set target supply voltage\n"); @@ -2046,9 +2048,8 @@ static int stk500v2_jtag3_parseextparms(const PROGRAMMER *pgm, const LISTID extp } else if (str_eq(extended_param, "help")) { - char *prg = (char *)ldata(lfirst(pgm->id)); - msg_error("%s -c %s extended options:\n", progname, prg); - if (str_starts(prg, "xplainedmini")) { + msg_error("%s -c %s extended options:\n", progname, pgmid); + if(str_starts(pgmid, "xplainedmini")) { msg_error(" -xsuffer Read SUFFER register value\n"); msg_error(" -xsuffer= Set SUFFER register value\n"); msg_error(" -xvtarg_switch Read on-board target voltage switch state\n"); diff --git a/src/teensy.c b/src/teensy.c index 67cc0e09..2c4d35f4 100644 --- a/src/teensy.c +++ b/src/teensy.c @@ -569,8 +569,7 @@ static int teensy_parseextparams(const PROGRAMMER *pgm, const LISTID xparams) { } else if (str_eq(param, "help")) { - char *prg = (char *)ldata(lfirst(pgm->id)); - msg_error("%s -c %s extended options:\n", progname, prg); + msg_error("%s -c %s extended options:\n", progname, pgmid); msg_error(" -xwait Wait for the device to be plugged in if not connected\n"); msg_error(" -xwait= Wait [s] for the device to be plugged in if not connected\n"); msg_error(" -xhelp Show this help menu and exit\n"); diff --git a/src/term.c b/src/term.c index 46a3721f..9f88b22d 100644 --- a/src/term.c +++ b/src/term.c @@ -73,6 +73,7 @@ static int cmd_abort (const PROGRAMMER *pgm, const AVRPART *p, int argc, char * static int cmd_erase (const PROGRAMMER *pgm, const AVRPART *p, int argc, char *argv[]); static int cmd_pgerase(const PROGRAMMER *pgm, const AVRPART *p, int argc, char *argv[]); static int cmd_config (const PROGRAMMER *pgm, const AVRPART *p, int argc, char *argv[]); +static int cmd_include(const PROGRAMMER *pgm, const AVRPART *p, int argc, char *argv[]); static int cmd_sig (const PROGRAMMER *pgm, const AVRPART *p, int argc, char *argv[]); static int cmd_part (const PROGRAMMER *pgm, const AVRPART *p, int argc, char *argv[]); static int cmd_help (const PROGRAMMER *pgm, const AVRPART *p, int argc, char *argv[]); @@ -100,6 +101,7 @@ struct command cmd[] = { { "erase", cmd_erase, _fo(chip_erase_cached), "perform a chip or memory erase" }, { "pgerase", cmd_pgerase, _fo(page_erase), "erase one page of flash or EEPROM memory" }, { "config", cmd_config, _fo(open), "change or show configuration properties of the part" }, + { "include", cmd_include, _fo(open), "include contents of named file as if it was typed" }, { "sig", cmd_sig, _fo(open), "display device signature bytes" }, { "part", cmd_part, _fo(open), "display the current part information" }, { "send", cmd_send, _fo(cmd), "send a raw command to the programmer" }, @@ -895,7 +897,7 @@ static int cmd_erase(const PROGRAMMER *pgm, const AVRPART *p, int argc, char *ar } if(rc) { - pmsg_error("(erase) programmer %s failed erasing the chip\n", (char *) ldata(lfirst(pgm->id))); + pmsg_error("(erase) programmer %s failed erasing the chip\n", pgmid); return -1; } @@ -919,7 +921,7 @@ static int cmd_pgerase(const PROGRAMMER *pgm, const AVRPART *p, int argc, char * return -1; } if(!avr_has_paged_access(pgm, mem)) { - pmsg_error("(pgerase) %s memory cannot be paged addressed by %s\n", memtype, (char *) ldata(lfirst(pgm->id))); + pmsg_error("(pgerase) %s memory cannot be paged addressed by %s\n", memtype, pgmid); return -1; } @@ -2207,6 +2209,75 @@ int terminal_mode(const PROGRAMMER *pgm, const AVRPART *p) { return terminal_mode_noninteractive(pgm, p); } + +static int cmd_include(const PROGRAMMER *pgm, const AVRPART *p, int argc, char *argv[]) { + int help = 0, invalid = 0, echo = 0, itemac=1; + + for(int ai = 0; --argc > 0; ) { // Simple option parsing + const char *q; + if(*(q=argv[++ai]) != '-' || !q[1]) + argv[itemac++] = argv[ai]; + else { + while(*++q) { + switch(*q) { + case '?': + case 'h': + help++; + break; + case 'e': + echo++; + break; + default: + if(!invalid++) + pmsg_error("(config) invalid option %c, see usage:\n", *q); + q = "x"; + } + } + } + } + argc = itemac; // (arg,c argv) still valid but options have been removed + + if(argc != 2 || help || invalid) { + msg_error( + "Syntax: include [opts] \n" + "Function: include contents of named file as if it was typed\n" + "Option:\n" + " -e echo lines as they are processed\n" + ); + return !help || invalid? -1: 0; + } + + int lineno = 0, rc = 0; + const char *errstr; + FILE *fp = fopen(argv[1], "r"); + if(fp == NULL) { + pmsg_ext_error("(include) cannot open file %s: %s\n", argv[1], strerror(errno)); + return -1; + } + + for(char *buffer; (buffer = str_fgets(fp, &errstr)); free(buffer)) { + lineno++; + if(echo) { + term_out("# "); + if(verbose > 0) + term_out("%d: ", lineno); + term_out("%s", buffer); + term_out("\v"); + } + if(process_line(buffer, pgm, p) < 0) + rc = -1; + term_out("\v"); + } + if(errstr) { + pmsg_error("(include) read error in file %s: %s\n", argv[1], errstr); + return -1; + } + + fclose(fp); + return rc; +} + + static void update_progress_tty(int percent, double etime, const char *hdr, int finish) { static char *header; static int last, done = 1; diff --git a/src/urclock.c b/src/urclock.c index f686bf85..8afe2c13 100644 --- a/src/urclock.c +++ b/src/urclock.c @@ -1757,7 +1757,7 @@ static int ur_readEF(const PROGRAMMER *pgm, const AVRPART *p, uint8_t *buf, uint int classic = !(p->prog_modes & (PM_UPDI | PM_PDI | PM_aWire)); pmsg_debug("ur_readEF(%s, %s, %s, %p, 0x%06x, %d, %c)\n", - (char *) ldata(lfirst(pgm->id)), p->desc, mchr=='F'? "flash": "eeprom", buf, badd, len, mchr); + pgmid, p->desc, mchr=='F'? "flash": "eeprom", buf, badd, len, mchr); if(mchr == 'F' && ur.urprotocol && !(ur.urfeatures & UB_READ_FLASH)) Return("bootloader does not have flash read capability"); @@ -2105,16 +2105,16 @@ static int urclock_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { buf[0] = Cmnd_STK_CHIP_ERASE; buf[1] = Sync_CRC_EOP; - if(urclock_send(pgm, buf, 2) < 0) + if(urclock_send(pgm, buf, 2) < 0 || urclock_res_check(pgm, __func__, 0, NULL, 0) < 0) { + serial_recv_timeout = bak_timeout; return -1; - if(urclock_res_check(pgm, __func__, 0, NULL, 0) < 0) - return -1; - + } } else { // Legacy bootloaders use universal extension pmsg_notice2("chip erase via universal STK500v1 command\n"); - if (pgm->cmd == NULL) { // Should not happen + if(pgm->cmd == NULL) { // Should not happen pmsg_error("%s programmer does not provide a cmd() method\n", pgm->type); + serial_recv_timeout = bak_timeout; return -1; } @@ -2125,8 +2125,10 @@ static int urclock_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { buf[2] = (uint8_t) (Subc_STK_UNIVERSAL_CE>>8); buf[3] = (uint8_t) (Subc_STK_UNIVERSAL_CE); - if(urclock_cmd(pgm, buf, buf+4) < 0) + if(urclock_cmd(pgm, buf, buf+4) < 0) { + serial_recv_timeout = bak_timeout; return -1; + } } serial_recv_timeout = bak_timeout; @@ -2498,7 +2500,7 @@ static int urclock_parseextparms(const PROGRAMMER *pgm, LISTID extparms) { } if(help || rc < 0) { - msg_error("%s -c %s extended options:\n", progname, (char *) ldata(lfirst(pgm->id))); + msg_error("%s -c %s extended options:\n", progname, pgmid); for(size_t i=0; i": "", urmax(0, 16-(int) strlen(options[i].name)-(options[i].assign? 6: 0)), "", options[i].help); diff --git a/src/usbasp.c b/src/usbasp.c index 19dfbe3c..fe8d36fa 100644 --- a/src/usbasp.c +++ b/src/usbasp.c @@ -290,8 +290,7 @@ static int usbasp_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { continue; } if (str_eq(extended_param, "help")) { - char *prg = (char *)ldata(lfirst(pgm->id)); - msg_error("%s -c %s extended options:\n", progname, prg); + msg_error("%s -c %s extended options:\n", progname, pgmid); msg_error(" -xsection_config Erase configuration section only with -e (TPI only)\n"); msg_error(" -xhelp Show this help menu and exit\n"); exit(0); @@ -560,7 +559,7 @@ static int usbasp_open(PROGRAMMER *pgm, const char *port) { vid = pgm->usbvid? pgm->usbvid: USBASP_SHARED_VID; if (usbOpenDevice(&PDATA(pgm)->usbhandle, vid, pgm->usbvendor, pid, pgm->usbproduct) != 0) { /* try alternatives */ - if(strcasecmp(ldata(lfirst(pgm->id)), "usbasp") == 0) { + if(str_eq(pgmid, "usbasp")) { /* for id usbasp autodetect some variants */ if(strcasecmp(port, "nibobee") == 0) { pmsg_error("using -C usbasp -P nibobee is deprecated, use -C nibobee instead\n"); diff --git a/src/wiring.c b/src/wiring.c index 2a6c1bed..ae99b304 100644 --- a/src/wiring.c +++ b/src/wiring.c @@ -131,8 +131,7 @@ static int wiring_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { continue; } if (str_eq(extended_param, "help")) { - char *prg = (char *)ldata(lfirst(pgm->id)); - msg_error("%s -c %s extended options:\n", progname, prg); + msg_error("%s -c %s extended options:\n", progname, pgmid); msg_error(" -xsnooze= Wait [ms] before protocol sync after port open\n"); msg_error(" -xhelp Show this help menu and exit\n"); exit(0); diff --git a/src/xbee.c b/src/xbee.c index ee454162..0aaf0469 100644 --- a/src/xbee.c +++ b/src/xbee.c @@ -1652,8 +1652,7 @@ static int xbee_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { continue; } if (str_eq(extended_param, "help")) { - char *prg = (char *)ldata(lfirst(pgm->id)); - msg_error("%s -c %s extended options:\n", progname, prg); + msg_error("%s -c %s extended options:\n", progname, pgmid); msg_error(" -xxbeeresetpin=<1..7> Set XBee pin DIO<1..7> as reset pin\n"); msg_error(" -xhelp Show this help menu and exit\n"); exit(0);