mirror of
https://github.com/mariusgreuel/avrdude.git
synced 2025-12-15 02:01:07 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
595c92288d |
5
AUTHORS
5
AUTHORS
@@ -10,7 +10,7 @@ Contributors:
|
||||
Alex Shepherd <maillists@ajsystems.co.nz>
|
||||
Martin Thomas <mthomas@rhrk.uni-kl.de>
|
||||
Theodore A. Roth <troth@openavr.org>
|
||||
Juliane Holzt <avrdude@juliane.holzt.de>
|
||||
Michael Holzt <kju-avr@fqdn.org>
|
||||
Colin O'Flynn <coflynn@newae.com>
|
||||
Thomas Fischl <tfischl@gmx.de>
|
||||
David Hoerl <dhoerl@mac.com>
|
||||
@@ -23,9 +23,6 @@ Contributors:
|
||||
Brett Hagman <bhagman@roguerobotics.com>
|
||||
Rene Liebscher <r.liebscher@gmx.de>
|
||||
Jim Paris <jim@jtan.com>
|
||||
Jan Egil Ruud <janegil.ruud@microchip.com>
|
||||
David Mosberger <davidm@egauge.net>
|
||||
David Sainty
|
||||
|
||||
For minor contributions, please see the ChangeLog files.
|
||||
|
||||
|
||||
331
ChangeLog
331
ChangeLog
@@ -1,320 +1,39 @@
|
||||
2021-12-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
2015-11-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (AC_INIT): Bump version to 6.4
|
||||
* main.c: Remove unmaintained year numbers from Copyright
|
||||
* configure.ac: Released version 6.2.
|
||||
|
||||
2021-12-06 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #57338: if safemode has to change fuses avrdude should exit with non-zero exit code
|
||||
* main.c (main): drop unused variable `fuses_specified'
|
||||
|
||||
2021-12-06 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Dmitrii Chernukhin:
|
||||
bug #58994: VPP PWM still enabled at the end of programming process
|
||||
* pickit2.c (pickit2_disable): turn off VPP before shutting down
|
||||
|
||||
2021-12-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (AC_INIT): Bump version date
|
||||
* configure.ac (enabled_parport): Default to "no"
|
||||
|
||||
2021-12-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Alex Sverdlin:
|
||||
patch #10153: linuxspi: Support "-E reset" and "-E noreset"
|
||||
* linuxspi.c (linuxspi_parseexitspecs): New function
|
||||
|
||||
2021-11-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #58440: linuxgpio PIN limit too low
|
||||
* libavrdude.h (PIN_MAX): bump (for HAVE_LINUXGPIO) to 400
|
||||
|
||||
2021-11-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by David Mosberger-Tang:
|
||||
patch #8923: Enable TPI for linuxgpio
|
||||
* linuxgpio.c (linuxgpio_initpgm): add cmd_tpi entry
|
||||
|
||||
2021-11-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by: Milan Kupcevic <milan@debian.org>
|
||||
patch #8996: Remove lock byte read mask (bug#21954, bug#46759)
|
||||
* avrdude.conf.in (ATmega48, ATmega88, ATmega168, ATmega328)
|
||||
(ATmega32U4, ATmega640, ATmega1280, ATmega1281, ATmega2560)
|
||||
(ATmega2561, ATmega8, ATtiny13, ATmega64, ATmega128, ATmega16)
|
||||
(AT90CAN32, AT90CAN64, AT90CAN128, ATmega324, ATmega644)
|
||||
(ATmega1284, ATmega161, ATmega162, ATmega163, ATmega169, ATmega32)
|
||||
(ATmega329, ATmega649, ATmega8515, ATmega8535, ATtiny2313, ATtiny4313)
|
||||
(AT90PWM2, AT90USB646, AT90USB1286, AT90USB162, AT90USB82, ATmega32U2)
|
||||
(ATmega16U2, ATmega8U2, ATmega325, ATmega645, ATtiny1634): Remove
|
||||
lock byte read mask (bug#46759).
|
||||
|
||||
2021-11-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Christopher Cooper:
|
||||
patch #9304: [Bug #48767] Implemented WinSock variation of "ser_drain(...)" functionality
|
||||
* ser_win32.c (ser_drain): Implement a network drain
|
||||
function.
|
||||
|
||||
2021-11-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Lars Ollén:
|
||||
* linux_spi.c (linuxspi_open): ensure correct SPI mode is
|
||||
set (submitted in the audit trail of patch #9816).
|
||||
|
||||
2021-11-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* linuxspi.c: Use -B <bitclock> rather than -b <baudrate>
|
||||
to specify the clock rate
|
||||
|
||||
2021-11-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Improve defaults and documentation of linuxspi
|
||||
* avrdude.conf.in: use @HAVE_LINUXGPIO_BEGIN/END@ and
|
||||
@HAVE_LINUXSPI_BEGIN/END@ brackets around respective config
|
||||
snippets; values were already set in configure.ac.
|
||||
* linuxspi.c (linuxspi_open): Provide a reasonable (for the
|
||||
Raspberry Pi) default for the -P option
|
||||
* avrdude.1: Extend linuxspi documentation
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2021-11-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Alex Sverdlin:
|
||||
patch #10031: linuxspi: Support GPIO uAPI v2
|
||||
* linuxspi.c (linuxspi_reset_mcu, linuxspi_open): Since Linux
|
||||
v5.10 GPIO ABI Version 1 is optional and depends on
|
||||
CONFIG_GPIO_CDEV_V1.
|
||||
|
||||
2021-11-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Alex Sverdlin:
|
||||
patch #10030: linuxspi: Support inverted GPIO pin
|
||||
* linuxspi.c (linuxspi_open): Clear the inversion mask on request
|
||||
and set default state to avoid short glitches on the GPIO line.
|
||||
|
||||
2021-11-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Alex Sverdlin:
|
||||
patch #10029: linuxspi: Report GPIO_GET_LINEHANDLE_IOCTL errors
|
||||
* linuxspi.c (linuxspi_open): Report ioctl error
|
||||
|
||||
2021-11-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Alex Sverdlin:
|
||||
patch #10028: linuxspi: close() only when necessary
|
||||
* linuxspi.c: unify descriptor closing
|
||||
|
||||
2021-11-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Alex Sverdlin:
|
||||
patch #10027: linuxspi: Add reset pulse, according to AVR programming algorithm
|
||||
* linuxspi.c (linuxspi_open, linuxspi_program_enable):
|
||||
movw out reset code into linuxspi_reset_mcu()
|
||||
|
||||
2021-11-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by David Mosberger-Tang:
|
||||
patch #9328: ft245r.c: add TPI support (patches 5-7)
|
||||
* ft245r.c (ft245r_set_bitclock): add workaround for
|
||||
FT245 hardware bugs in bitclock setting
|
||||
|
||||
2021-11-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by David Mosberger-Tang:
|
||||
patch #9328: ft245r.c: add TPI support (patches 5-7)
|
||||
* ft245r.c: Remove the reader thread (also removes
|
||||
patch #9079)
|
||||
|
||||
2021-11-24 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by David Mosberger-Tang:
|
||||
patch #9327: ft245r.c: add TPI support (patches 1-4)
|
||||
* ft245r.c (set_pin, ft245r_open): use
|
||||
ft245r_send_and_discard() so ft245r_in can go away
|
||||
|
||||
2021-11-24 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by David Mosberger-Tang:
|
||||
patch #9327: ft245r.c: add TPI support (patches 1-4)
|
||||
* ft245r.c (ft245r_recv): Optimize TPI programming
|
||||
speed by reducing number of USB reads.
|
||||
|
||||
2021-11-24 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by David Mosberger-Tang:
|
||||
patch #9327: ft245r.c: add TPI support (patches 1-4)
|
||||
* ft245r.c (ft245r_open): add call to
|
||||
ftdi_set_latency_timer() to improve timing
|
||||
|
||||
2021-11-24 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by David Mosberger-Tang:
|
||||
patch #9327: ft245r.c: add TPI support (patches 1-4)
|
||||
* ft245r.c: add TPI support
|
||||
* avrdude.conf.in (tc2030): New programmer
|
||||
|
||||
2021-11-24 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* ft245r.c (ft245r_open): allow for picking a default
|
||||
device if none has been provided by -P
|
||||
|
||||
2021-11-24 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c (jtag3_edbg_recv_frame): Better handling for
|
||||
fragment_info == 0x00 (no response available)
|
||||
|
||||
2021-11-23 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c: Use matches() instead of strncmp()
|
||||
|
||||
2021-11-23 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #9757: Fix ATtiny817 Xplained Mini programmer
|
||||
* jtag3.c (jtag3_getsync, jtag3_close): correctly extract
|
||||
programmer name from list of names
|
||||
|
||||
2021-11-22 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by David Sainty:
|
||||
patch #8719: Support Over-the-Air bootloading with XBeeBoot
|
||||
* xbee.c: New programmer
|
||||
* xbee.h: (Dito.)
|
||||
* pgm_type.c: Add xbee.h
|
||||
* avrdude.conf.in (xbee): New programmer
|
||||
* Makefile.am (libavrdude_a_SOURCES): add xbee.c, xbee.h
|
||||
* avrdude.1: document the new programmer
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2021-11-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Ivan Frederiks:
|
||||
patch #9079: Fix ftdi_syncbb teardown (supersedes #9893)
|
||||
patch #9122: Fixed MISO sampling in ftdi_syncbb
|
||||
patch #9123: ftdi_syncbb: use FT245R_CYCLES in ft245r_set_bitclock()
|
||||
* ft245r.c: Various fixes for FT245-bitbang programmers
|
||||
|
||||
2021-11-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by David Mosberger-Tang:
|
||||
patch #9320: fix TPI RESET in bitbang.c
|
||||
* bitbang.c (bitbang_initialize): wait for 128 ms after deasserting
|
||||
/RESET (per datasheet), and keep /RESET low during MOSI/MISO link check
|
||||
|
||||
2021-11-12 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Jon Thacker:
|
||||
patch #9253: Fix for giving terminal_mode commands more than 20 arguments
|
||||
* term.c (tokenize): fix realloc usage, pointer returned not necessarily
|
||||
the same as pointer passed
|
||||
|
||||
2021-11-12 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
2015-10-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Martino Facchin:
|
||||
patch #9110: Let reserved fuse bits to be read as *don't care*
|
||||
* avr.c (compare_memory_masked): New function
|
||||
* libavrdude.h: declare compare_memory_masked(); also, insist on C99
|
||||
so <stdint.h> is required now
|
||||
* main.c: Use compare_memory_masked() in safemode comparisons
|
||||
bug #45727: Wrong atmega8u2 flash parameters
|
||||
* avrdude.conf.in (ATmega8U2): correct page and block size
|
||||
|
||||
2021-11-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
2015-10-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Joseph Coffland:
|
||||
patch #8957: Allow reading prodsig memory from stk500v2 on xmega devices
|
||||
* stk500v2.c (stk600_xprog_read_byte, stk600_xprog_paged_load):
|
||||
treat "prodsig" memory space as equivalent to "calibration"
|
||||
Submitted by Pasquale Cocchini:
|
||||
bug #46020: Add TIAO TUMPA to the conf file.
|
||||
* avrdude.conf.in (tumpa): New entry.
|
||||
|
||||
2021-11-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
2015-10-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Martin Thierer:
|
||||
patch #10017: uspasp / tpi: Automatically clear configuration byte (fuse) before writing it
|
||||
* usbasp.c (usbasp_tpi_paged_write): clear fuse region before writing it
|
||||
Submitted by Pasquale Cocchini:
|
||||
bug #46021: Please add read in the memory lock section of ATtiny85
|
||||
* avrdude.conf.in (ATtiny25/45/85): add read pattern for lock bits
|
||||
|
||||
2021-11-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
2015-10-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Michael Petersen:
|
||||
patch #9697: Add iseavrprog support
|
||||
* avrdude.conf.in (iseavrprog): New programmer
|
||||
* Makefile.am (libavrdude_a_SOURCES): reflect recent changes
|
||||
(pgm.h is gone, config.h is new).
|
||||
|
||||
2021-11-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
2015-04-09 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #50630: Erase Cycle Counter options ( -y -Y n ) should be removed from usage Message
|
||||
* main.c (usage): remove -y / -Y descriptions
|
||||
bug #44717: avrdude creates empty flash dump
|
||||
* update.c (do_op): When about to write an empty flash dump file,
|
||||
warn about this to avoid surprises.
|
||||
* avrdude.1: Document the truncation of trailing 0xFF bytes for
|
||||
flash memory areas.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2021-11-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
2015-04-09 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in (ATmega8A): new device (alias for ATmega8)
|
||||
|
||||
2021-11-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #50517: Reading fails if "immediate mode" for output file format is selected - fileio: invalid operation=1
|
||||
* update.c (do_op): refuse to write to "immediate format" argument
|
||||
|
||||
2021-11-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Martin Thierer:
|
||||
bug #60863: avrftdi programming error probably caused by multiple, consecutive empty pages
|
||||
* avrftdi.c (avrftdi_flash_write): Skip empty pages
|
||||
|
||||
2021-11-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Matwey V. Kornilov:
|
||||
bug #58495: Add atmega324pb support to avrdude.conf.in
|
||||
* avrdude.conf.in (ATmega324PB): new entry
|
||||
|
||||
2021-11-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #55734: USBtiny programming of ATmega328p broken by Patch #9278
|
||||
* usbtiny.c (usbtiny_initialize): undo change from patch #9728
|
||||
|
||||
2021-11-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #55009: no efuses for m164a/pa
|
||||
* avrdude.conf.in (ATmega164P): derive from ATmega324P
|
||||
|
||||
2021-11-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by evan Venn:
|
||||
bug #59227: Add new part. How does one get a part added to the CONF file?
|
||||
* avrdude.conf.in (LGT8FX88P, LGT8FX168P, LGT8FX328P): new parts
|
||||
|
||||
2021-11-06 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Britton Kerin:
|
||||
bug #57453: [PATCH] fix reference to nonexistant -m option by changing to -U
|
||||
* avrdude.1: replace -m option by -U
|
||||
|
||||
2021-11-06 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Andrew D'Addesio:
|
||||
bug #58078: [PATCH] buspirate: remove compound literals (fixes GCC>=9)
|
||||
* buspirate.c (buspirate_start_mode_bin):
|
||||
avoid propagating local scope compound literals
|
||||
|
||||
2021-11-06 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Jan Egil Ruud:
|
||||
patch #10000: Add support for extended UPDI device context
|
||||
* avrdude.conf.in (pickit4_updi, snap_updi, pkobn_updi):
|
||||
new programmers
|
||||
* avrdude.conf.in (ATmega808, ATmega809, ATmega1608, ATmega1609)
|
||||
(AVR DA, AVR DB): new devices
|
||||
* jtag3.c: Add support for extended UPDI device context
|
||||
* jtag3_private.h: (Dito.)
|
||||
* tools/atdf-to-avrdude.xslt: Bug fixes
|
||||
* usbdevs.h: Bump USBDEV_MAX_XFER_3 to 912
|
||||
* doc/avrdude.texi: Document changes
|
||||
* avrdude.1: (Dito)
|
||||
|
||||
2021-06-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #60753: Patch #1436 breaks multiple programmer/device combinations on MacOS BigSur
|
||||
* avr.c: compare page_size > 1 instead of != 0
|
||||
* stk500v2.c: (Ditto.)
|
||||
|
||||
2021-06-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by gerardoallende:
|
||||
bug #59525: Bogus error message because Copy/Paste typo in stk500.c
|
||||
* stk500.c (stk500_getparm): Fix bogus ID in error message
|
||||
Annual ChangeLog rotation.
|
||||
|
||||
@@ -1080,7 +1080,7 @@
|
||||
|
||||
2005-09-18 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Add the serial bit-bang driver, contributed by Juliane Holzt.
|
||||
Add the serial bit-bang driver, contributed by Michael Holzt.
|
||||
* bitbang.h: New file.
|
||||
* bitbang.c: New file.
|
||||
* serbb.h: New file.
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
2015-12-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.1 (-C): Do not suggest users might change the
|
||||
default config file. It will be overwritten by updates.
|
||||
|
||||
2015-12-09 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #46610: Floating point exception (core dumped) arch linux rpi2
|
||||
bug #46483: version 6.2. ser_open(): can't set attributes for device
|
||||
* ser_posix.c: Back out change from patch #8380
|
||||
|
||||
2015-11-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Bump for post-release 6.2.
|
||||
|
||||
2015-11-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Released version 6.2.
|
||||
|
||||
2015-10-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Martino Facchin:
|
||||
bug #45727: Wrong atmega8u2 flash parameters
|
||||
* avrdude.conf.in (ATmega8U2): correct page and block size
|
||||
|
||||
2015-10-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Pasquale Cocchini:
|
||||
bug #46020: Add TIAO TUMPA to the conf file.
|
||||
* avrdude.conf.in (tumpa): New entry.
|
||||
|
||||
2015-10-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Pasquale Cocchini:
|
||||
bug #46021: Please add read in the memory lock section of ATtiny85
|
||||
* avrdude.conf.in (ATtiny25/45/85): add read pattern for lock bits
|
||||
|
||||
2015-10-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* Makefile.am (libavrdude_a_SOURCES): reflect recent changes
|
||||
(pgm.h is gone, config.h is new).
|
||||
|
||||
2015-04-09 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #44717: avrdude creates empty flash dump
|
||||
* update.c (do_op): When about to write an empty flash dump file,
|
||||
warn about this to avoid surprises.
|
||||
* avrdude.1: Document the truncation of trailing 0xFF bytes for
|
||||
flash memory areas.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2015-04-09 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Annual ChangeLog rotation.
|
||||
@@ -1,95 +0,0 @@
|
||||
2016-09-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c (DEBUG, DEBUGRECV): define these unconditionally,
|
||||
as MSG_TRACE2 messages.
|
||||
|
||||
2016-05-10 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Hannes Jochriem:
|
||||
* avrdude.conf.in (ehajo-isp): New programmer.
|
||||
|
||||
2016-04-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (libftdi1): Rather than hardcoding the library
|
||||
providing the libusb-1.0 API, use the result from the previous
|
||||
probe. This helps detecting libftdi1 on FreeBSD where the
|
||||
libusb-1.0 API is provided by the system's libusb.
|
||||
|
||||
2016-04-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usb_hidapi.c (usbhid_open): Correctly calculate the
|
||||
offset for serial number matching
|
||||
|
||||
2016-03-28 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #47550: Linux GPIO broken
|
||||
* linuxgpio.c: Replace %ud by %u in snprintf calls.
|
||||
|
||||
2016-03-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usb_hidapi.c (usbhid_recv): Bump read timeout to 300 ms.
|
||||
|
||||
2016-02-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c: add support for libhidapi as (optional) transport for
|
||||
CMSIS-DAP compliant debuggers (JTAGICE3 with firmware 3+,
|
||||
AtmelICE, EDBG, mEDBG)
|
||||
* usb_hidapi.c: (New file)
|
||||
* libavrdude.h: Mention usbhid_serdev
|
||||
* configure.ac: Bump version date
|
||||
|
||||
2016-02-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
(Obtained from patch #8717: pattch for mcprog and libhidapi support)
|
||||
* configure.ac: Probe for libhidapi
|
||||
* Makefile.am: Add @LIBHIDAPI@
|
||||
|
||||
2016-02-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* doc/avrdude.texi: Bump copyright year.
|
||||
|
||||
2016-02-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Bump for post-release 6.3.
|
||||
|
||||
2016-02-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Released version 6.3.
|
||||
|
||||
2016-02-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #8894: Spelling in 6.2 doc
|
||||
* doc/avrdude.texi: Various spelling fixes.
|
||||
|
||||
2016-02-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #8895: Spelling in 6.2 code
|
||||
* avrftdi.c (avrftdi_open): Spell fix.
|
||||
|
||||
2016-02-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #8896: Silence cppcheck warnings in 6.2 code
|
||||
* linuxgpio.c: Use %ud to print GPIO values.
|
||||
|
||||
2016-02-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #8735: ATtiny28 support in avrdude.conf
|
||||
* avrdude.conf.in (ATtiny28): New device.
|
||||
|
||||
2016-02-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in (ATmega48PB, ATmega88PB, ATmega168PB): New
|
||||
devices.
|
||||
|
||||
2016-02-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #8435: Implementing mEDBG CMSIS-DAP protocol
|
||||
* usb_libusb.c: Add endpoint IDs for Xplained Mini, correctly
|
||||
transfer trailing ZLP when needed
|
||||
* avrdude.conf.in (xplainedmini, xplainedmini_dw): New entries.
|
||||
* jtag3.c (jtag3_edbg_send, jtag3_edbg_recv_frame): Implement
|
||||
fragmentation needed for the 64-byte EP size of the Xplained Mini
|
||||
* avrdude.1: Document the change
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
2017-12-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Jan Egil Ruud <janegil.ruud@microchip.com>
|
||||
patch #9507: Fix UPDI chip erase
|
||||
* jtag3.c (jtag3_chip_erase_updi): New function
|
||||
* jtag3_private.h: More constants
|
||||
|
||||
2017-12-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Jan Egil Ruud <janegil.ruud@microchip.com>
|
||||
patch #9508: Add PowerDebugger and XPlained Mini in UPDI mode
|
||||
* avrdude.conf.in (xplainedmini_updi, powerdebugger,
|
||||
powerdebugger_pdi, powerdebugger_updi, powerdebugger_dw,
|
||||
powerdebugger_isp): New programmers
|
||||
|
||||
2017-12-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* bootstrap: Detect whether libtoolize is named
|
||||
`glibtoolize' (MacOS)
|
||||
|
||||
2017-11-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Bump version date, due to UPDI addition
|
||||
|
||||
2017-11-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Jan Egil Ruud <janegil.ruud@microchip.com>
|
||||
patch #9482: Add support for UPDI and AVR8X
|
||||
* avrdude.conf.in (xplainedpro_updi): New programmer
|
||||
* avrdude.conf.in (.avr8x, ATtiny1617, ATtiny817): New device
|
||||
family and devices
|
||||
* config_gram.y: add K_OCD_BASE and K_HAS_UPDI
|
||||
* lexer.l: (Ditto.)
|
||||
* doc/avrdude.texi: Document "has_updi" flag
|
||||
* jtag3.c: Implement UPDI
|
||||
* jtag3.h: (Ditto.)
|
||||
* jtag3_private.h: (Ditto.)
|
||||
* libavrdude.h: Add ocd_base value and AVRPART_HAS_UPDI flag
|
||||
* pgm_type.c: Add jtagice3_updi
|
||||
|
||||
2017-11-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Jan Egil Ruud <janegil.ruud@microchip.com>
|
||||
* avrdude.conf.in (ATmega328PB): New part
|
||||
|
||||
2017-11-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #48084: Avoid compiled-in timestamp for reproducible release builds
|
||||
* main.c: Remove "compiled on/at" string
|
||||
|
||||
2017-03-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #47718: "lfuse reads as" not displayed in verbose mode - SOLUTION
|
||||
Reported by Roger A. Krupski:
|
||||
* safemode.c: Display lfuse at correct MSG level
|
||||
|
||||
148
ChangeLog-2018
148
ChangeLog-2018
@@ -1,148 +0,0 @@
|
||||
2018-01-21 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #8444: Proposal for modifications in -B and -U command options managment
|
||||
* update.c (parse_op): Default -U filename to RBIN for output
|
||||
files
|
||||
|
||||
2018-01-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Simone:
|
||||
patch #8128: Added new option to configure.ac script
|
||||
* configure.ac (disable-libusb_1_0): New option
|
||||
|
||||
2018-01-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Jan Egil Ruud:
|
||||
patch #9542: Correct "usersig" on avr8x devices
|
||||
* avrdude.conf.in (.avr8x_tiny, .avr8x_mega): rename "userrow" to
|
||||
"usersig", and fix its page size for .avr8x_mega
|
||||
* jtag3.c: Remove all "userrow" handling
|
||||
|
||||
2018-01-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Reinhard Max
|
||||
patch #8311: Add IPv6 support to the -Pnet:host:port option
|
||||
* ser_posix.c (net_open): Rewrite to use getaddrinfo()
|
||||
rather than gethostbyname()
|
||||
* avrdude.1: Document IPv6 feature
|
||||
* doc/avrdude.texi: (Dito)
|
||||
|
||||
2018-01-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Maciej:
|
||||
patch #9185: Add extended_param to usbasp.c - erasing
|
||||
configuration section in ATtiny 4...40 (TPI)
|
||||
* usbasp.c: Implement extended parameter parsing, and modify
|
||||
usbasp_tpi_chip_erase() appropriately
|
||||
* avrdude.1: Document USBasp extended parameters
|
||||
* doc/avrdude.texi: (Dito)
|
||||
|
||||
2018-01-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Tom Carney:
|
||||
patch #8219: Fix boot_start for xmega devices on jtagmkII
|
||||
* jtagmkII.c (jtagmkII_initialize): Determine boarder between
|
||||
application and boot area correctly.
|
||||
|
||||
2018-01-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Jan Egil Ruud <janegil.ruud@microchip.com>
|
||||
patch #9507: Fix UPDI chip erase
|
||||
* libavrdude.h (PROGRAMMER): add unlock method
|
||||
* avr.c (avr_unlock): Generic unlock function
|
||||
* jtag3.c: Implement unlock feature; avoid calling
|
||||
jtag3_edbg_prepare() and jtag3_edbg_signoff() on XplainedMini
|
||||
boards to work around a bug in early firmware versions;
|
||||
implement "userrow" memory region
|
||||
* main.c: Call avr_unlock() rather than avr_chip_erase() when
|
||||
encountering a locked UPDI chip
|
||||
|
||||
2018-01-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Nicolas BRULEZ
|
||||
patch #8910: ATxmega32c4 and ATxmega16c4 have wrong signatures
|
||||
bug #41388: ATxmega32c4 and ATxmega16c4 have wrong signatures
|
||||
* avrdude.conf.in (ATxmega16C4, ATxmega32C4): Fix signatures
|
||||
|
||||
2018-01-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Dennis Reimers:
|
||||
patch #8580: FT245r support to select device by serial number
|
||||
* ft245r.c (ft245r_open): Add serial number parsing.
|
||||
|
||||
2018-01-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Axel Simon:
|
||||
patch #9033: avrdoper backend uses libhidapi instead of libusb
|
||||
* ser_avrdoper: Add libhidapi implementation
|
||||
* stk500v2.c: Adapt #ifdefs for LIBHIDAPI
|
||||
* avrdude.1: Document change
|
||||
* doc/avrdude.texi: (Dito)
|
||||
|
||||
2018-01-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by David Mosberger-Tang
|
||||
patch #8924: Enable TPI for usbtiny
|
||||
* usbtiny.c: Extend to handle TPI targets
|
||||
* configure.ac: Probe for <netinet/in.h>
|
||||
|
||||
2018-01-12 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Yegor Yefremov:
|
||||
patch #9222: Enable silent build
|
||||
* configure.ac: Add AM_SILENT_RULES
|
||||
* Makefile.am: Document how to run "make" to get verbose
|
||||
build messages
|
||||
|
||||
2018-01-12 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by: Kjetil Kjeka:
|
||||
patch #9317: Support atmega64m1 as part
|
||||
* avrdue.conf.in (ATmega64M1): New entry.
|
||||
|
||||
2018-01-12 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Submitted David Griffith:
|
||||
patch #9530: Update URL to Ladyada's USBtinyISP page.
|
||||
* avrdude.conf.in (usbtiny): Update URL
|
||||
|
||||
2018-01-12 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Milan Kupcevic:
|
||||
patch #9423: Support ATtiny841 and ATtiny441
|
||||
bug #47376: ATtiny841 description missing in configuration file
|
||||
bug #49455: support for tiny441
|
||||
* avrdude.conf.in (ATtiny841, ATtiny441): New entries
|
||||
|
||||
2018-01-10 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Morten Engelhardt Olsen
|
||||
patch #9506: Script to create device configuration stub from Atmel ATDF files
|
||||
* tools/atdf-to-avrdude.xslt: New script
|
||||
|
||||
2018-01-10 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Jan Egil Ruud <janegil.ruud@microchip.com>
|
||||
patch #9507: Fix UPDI chip erase
|
||||
* lexer.l (family_id): New keyword.
|
||||
* config_gram.y: (Ditto)
|
||||
* doc/avrdude.texi: Document new keyword
|
||||
* avrdude.conf.in: Add family_id for avr8x devices
|
||||
* avr.c: Pass error code up.
|
||||
* jtag3.c: Pass error code from memory read up; implement
|
||||
jtag3_read_sib()
|
||||
* libavrdude.h: Add new items.
|
||||
* main.c: Implement different chip erase handling required
|
||||
for UPDI devices.
|
||||
|
||||
2018-01-10 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Jan Egil Ruud <janegil.ruud@microchip.com>
|
||||
patch #9506: Script to create device configuration stub from Atmel ATDF files
|
||||
* avrdude.conf.in (ATtiny202, ATtiny204, ATtiny402, ATtiny404)
|
||||
(ATtiny406, ATtiny804, ATtiny806, ATtiny807, ATtiny1604)
|
||||
(ATtiny1606, ATtiny1607, ATtiny212, ATtiny214, ATtiny412)
|
||||
(ATTiny414, ATtiny416, ATtiny417, ATtiny814, ATtiny816)
|
||||
(ATtiny1614, ATtiny1616, ATtiny3214, ATtiny3216, ATtiny3217)
|
||||
(ATmega3208, ATmega3209, ATmega4808, ATmega4809): New devices
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
2019-12-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Britton Kerin:
|
||||
bug #57428: [PATCH] document when 'arduino' or 'wiring' should be used, and -D requirement of latter
|
||||
* avrdude.1: Clarify
|
||||
* doc/avrdude.texi: (dito)
|
||||
|
||||
2019-01-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Milan Kupcevic:
|
||||
patch #9735: spelling error fix: psuedo -> pseudo
|
||||
* avrpart.c (avr_display): Spelling fix
|
||||
|
||||
2019-01-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Martino Facchin:
|
||||
patch #9728: Fix UsbTiny programmer
|
||||
* usbtiny.c (usbtiny_initialize): Only consider
|
||||
pgm->program_enable successful if returning 0
|
||||
|
||||
104
ChangeLog-2020
104
ChangeLog-2020
@@ -1,104 +0,0 @@
|
||||
2020-09-22 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Reported by Hannes Wallnöfer:
|
||||
* avrdude.conf.in (m32m1): add "size" parameter in "efuse"
|
||||
section
|
||||
|
||||
2020-09-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Björn Mellström
|
||||
patch #9744: Patch for ATMega324A support
|
||||
* avrdude.conf.in (m324a): New entry.
|
||||
|
||||
2020-09-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Ronald Sutherland
|
||||
patch #9811: ATmega328pb has efuse bit 3
|
||||
* avrdude.conf.in (m328pb): Add own efuse definition
|
||||
|
||||
2020-09-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Ralf Ramsauer
|
||||
patch #9816: Implement new programmer type: linuxspi
|
||||
* linuxspi.c: (New file.)
|
||||
* linuxspi.h: (New file.)
|
||||
* Makefile.am: Add new files
|
||||
* configure.ac: Add "linuxspi" --enable option
|
||||
* avrdude.conf.in: Add "linuxspi" programmer template
|
||||
* pgm_type.c: Include linuxspi programmer
|
||||
* doc/avrdude.texi: Document new programmer
|
||||
* avrdude.1: (Dito.)
|
||||
|
||||
2020-09-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Marcin Miskiewic
|
||||
patch #9963: UsbAsp 3 MHz patch for UsbAsp-flash firmware
|
||||
* usbasp.c: Implement 3 MHz clock option including capability check
|
||||
* usbasp.h: (Dito.)
|
||||
|
||||
2020-09-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Sven Schwermer:
|
||||
patch #9966: Add JTAGICE3 in UPDI mode
|
||||
* avrdude.conf (jtag3updi): New entry.
|
||||
|
||||
2020-09-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Joel Ray Holveck
|
||||
patch #9732: usbtiny_paged_load overflows buffer e.g. when reading EEPROM
|
||||
* usbtiny.c (usbtiny_paged_load, usbtiny_paged_write): ensure chunk
|
||||
does not overflow memory area
|
||||
|
||||
2020-09-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Adrian Klieber:
|
||||
patch #9818: correct typos in SVN rev 1429
|
||||
* buspirate.c: Fix typos.
|
||||
* fileio.c: Fix typos.
|
||||
* jtagmkII.c: Fix typos.
|
||||
* main.c: Fix typos.
|
||||
* term.c: Fix typos.
|
||||
* usbasp.c: Fix typos.
|
||||
* usbtiny.h: Fix typos.
|
||||
|
||||
2020-09-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Adrian Klieber:
|
||||
patch #9820: Fix some out-of-bounds/uninitialized issues
|
||||
* stk500v2.c (stk500v2_display): fix uninitialized variables
|
||||
* stk500v2.c (stk500v2_set_sck_period_mk2): fix loop limits
|
||||
* pickit2.c (pickit2_open): Use pgm->desc to store description (WIN32 only)
|
||||
* config_gram.y (K_PAGE_SIZE): ensure page_size is > 0
|
||||
* avrpart.c (avr_new_memtype): initialize page_size to 1
|
||||
|
||||
2020-09-10 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* config_gram.y (K_DESC): Enforce correct length in strncpy()
|
||||
* config_gram.y (K_MEMORY): (Dito.)
|
||||
|
||||
2020-09-10 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrpart.c (avr_new_memtype): ensure page_size is at least 1
|
||||
* config_gram.y (K_PAGE_SIZE): (Dito.)
|
||||
|
||||
2020-03-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Adrian Klieber:
|
||||
patch #9819: Address several leaks in SVN rev 1429
|
||||
* config.c: Fix potential memory leak
|
||||
* jtagmkII.c: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
* update.c: (Dito.)
|
||||
* windows/loaddrv.c: Fix file descriptor leak.
|
||||
|
||||
2020-03-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by: kautism
|
||||
patch #9893: [PATCH] Reader reads ftdi handle after main thread close it
|
||||
* ft245r.c: Wait until reader thread has been stopped before closing FTDI
|
||||
|
||||
2020-03-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Fix compiler warnings
|
||||
* avr.c: misleading indentation after spin loop
|
||||
* fileio.c: EM_AVR32 might be defined in system <libelf.h>
|
||||
57
INSTALL
57
INSTALL
@@ -1,57 +0,0 @@
|
||||
Installation Instructions
|
||||
*************************
|
||||
|
||||
Use `./configure; make all; sudo make install' for Unix-like systems.
|
||||
|
||||
Depending on your requirements, the following prerequisites are
|
||||
needed:
|
||||
|
||||
* libelf including header files (for directly reading ELF files)
|
||||
* libusb 0.1 or 1.0 (or compatible), including header files
|
||||
* libftdi or libftdi1 (for direct access to FTDI devices)
|
||||
* libhidapi or libhid (for access to recent Atmel/Microchip dongles)
|
||||
|
||||
If the header and/or library files for one of those are found in
|
||||
non-default locations, you can add them to configure, e.g.
|
||||
|
||||
`./configure CPPFLAGS=-I/opt/local/include LDFLAGS=-L/opt/local/lib'
|
||||
|
||||
as an example for MacOS using Macports. MacOS Brew requires
|
||||
|
||||
`./configure CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/Cellar'
|
||||
|
||||
instead. (LDFLAGS and CPPFLAGS can also be supplied as environment
|
||||
variables to configure.)
|
||||
|
||||
At the end of the configure script, a configuration summary is issued,
|
||||
like this:
|
||||
|
||||
Configuration summary:
|
||||
----------------------
|
||||
DO HAVE libelf
|
||||
DO HAVE libusb
|
||||
DO HAVE libusb_1_0
|
||||
DO HAVE libftdi1
|
||||
DON'T HAVE libftdi
|
||||
DON'T HAVE libhid
|
||||
DO HAVE libhidapi
|
||||
DO HAVE pthread
|
||||
DISABLED doc
|
||||
DISABLED parport
|
||||
DISABLED linuxgpio
|
||||
DISABLED linuxspi
|
||||
|
||||
Make sure all the features you are interested in have been found.
|
||||
|
||||
For BSD-like systems, using GNU make (gmake) is not mandatory but
|
||||
appears to cause less troubles with the quite complex dependency graph
|
||||
that might be produced by autoconf/automake.
|
||||
|
||||
For Windows, right now, a toolset like MinGW is required to compile
|
||||
AVRDUDE.
|
||||
|
||||
Obviously, a working C compiler is needed. Tested compilers so far
|
||||
include GCC (in various versions) and Clang. The compiler needs to
|
||||
support (at least) C99 language level. For MacOS, either Xcode or the
|
||||
(smaller) Xcode Command Line tools are needed, for Windows, some port
|
||||
of GCC that supports generating native Windows executables.
|
||||
22
Makefile.am
22
Makefile.am
@@ -16,15 +16,6 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
# In order to get verbose build messages rather than a summary line
|
||||
# only, either use
|
||||
#
|
||||
# ./configure --disable-silent-rules
|
||||
#
|
||||
# or run make like
|
||||
#
|
||||
# make V=1
|
||||
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
@@ -42,10 +33,6 @@ EXTRA_DIST = \
|
||||
ChangeLog-2011 \
|
||||
ChangeLog-2012 \
|
||||
ChangeLog-2013 \
|
||||
ChangeLog-2014 \
|
||||
ChangeLog-2015 \
|
||||
ChangeLog-2016 \
|
||||
ChangeLog-2017 \
|
||||
avrdude.1 \
|
||||
avrdude.spec \
|
||||
bootstrap
|
||||
@@ -79,7 +66,7 @@ avrdude_CFLAGS = @ENABLE_WARNINGS@
|
||||
libavrdude_a_CFLAGS = @ENABLE_WARNINGS@
|
||||
libavrdude_la_CFLAGS = $(libavrdude_a_CFLAGS)
|
||||
|
||||
avrdude_LDADD = $(top_builddir)/$(noinst_LIBRARIES) @LIBUSB_1_0@ @LIBHIDAPI@ @LIBUSB@ @LIBFTDI1@ @LIBFTDI@ @LIBHID@ @LIBELF@ @LIBPTHREAD@ -lm
|
||||
avrdude_LDADD = $(top_builddir)/$(noinst_LIBRARIES) @LIBUSB_1_0@ @LIBUSB@ @LIBFTDI1@ @LIBFTDI@ @LIBHID@ @LIBELF@ @LIBPTHREAD@ -lm
|
||||
|
||||
bin_PROGRAMS = avrdude
|
||||
|
||||
@@ -149,8 +136,6 @@ libavrdude_a_SOURCES = \
|
||||
libavrdude.h \
|
||||
linuxgpio.c \
|
||||
linuxgpio.h \
|
||||
linuxspi.c \
|
||||
linuxspi.h \
|
||||
linux_ppdev.h \
|
||||
lists.c \
|
||||
my_ddk_hidsdi.h \
|
||||
@@ -184,15 +169,12 @@ libavrdude_a_SOURCES = \
|
||||
usbasp.c \
|
||||
usbasp.h \
|
||||
usbdevs.h \
|
||||
usb_hidapi.c \
|
||||
usb_libusb.c \
|
||||
usbtiny.h \
|
||||
usbtiny.c \
|
||||
update.c \
|
||||
wiring.h \
|
||||
wiring.c \
|
||||
xbee.h \
|
||||
xbee.c
|
||||
wiring.c
|
||||
libavrdude_la_SOURCES = $(libavrdude_a_SOURCES)
|
||||
libavrdude_la_LDFLAGS = -version-info 1:0
|
||||
|
||||
|
||||
171
NEWS
171
NEWS
@@ -5,176 +5,6 @@ Approximate change log for AVRDUDE by version.
|
||||
(For more detailed changes, see the ChangeLog file.)
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Version 6.4:
|
||||
|
||||
* Major changes compared to the previous version:
|
||||
|
||||
- libhidapi support (part of patch #8717)
|
||||
- use libhidapi as (optional) transport for CMSIS-DAP compliant
|
||||
debuggers (JTAGICE3 with firmware 3+, AtmelICE, EDBG, mEDBG)
|
||||
- UPDI support added (AVR8X family)
|
||||
- TPI support for USBtinyISP
|
||||
- TPI support for ft245r
|
||||
- TPI support for linuxgpio
|
||||
- AVR Doper uses libhidapi rather than raw libusb (patch #9033)
|
||||
- -P net:host:port can use IPv6 now (Posix systems only)
|
||||
- New configure option: -disable-libusb_1_0
|
||||
- extended UPDI device context (> 64 Ki flash)
|
||||
- major overhaul of ft245r driver (patch #9327/#9328)
|
||||
- some improvements in linuxspi driver
|
||||
- Use -B <bitclock> rather than -b <baudrate> for linuxspi driver
|
||||
- unused lock byte bits are not masked on read anymore
|
||||
- parport support disabled by default; configure with
|
||||
--enable-parport to explicitly enable it
|
||||
|
||||
* New devices supported:
|
||||
|
||||
- ATmega328PB
|
||||
- AVR8X family, ATtiny1617, ATtiny817, ATtiny202, ATtiny204,
|
||||
ATtiny402, ATtiny404, ATtiny406, ATtiny804, ATtiny806,
|
||||
ATtiny807, ATtiny1604, ATtiny1606, ATtiny1607, ATtiny212,
|
||||
ATtiny214, ATtiny412, ATTiny414, ATtiny416, ATtiny417,
|
||||
ATtiny814, ATtiny816, ATtiny1614, ATtiny1616, ATtiny3214,
|
||||
ATtiny3216, ATtiny3217, ATmega3208, ATmega3209, ATmega4808,
|
||||
ATmega4809
|
||||
- ATtiny841, ATtiny441
|
||||
- ATmega64M1
|
||||
- ATmega324A
|
||||
- ATmega808, ATmega809, ATmega1608, ATmega1609, AVR DA, AVR DB
|
||||
- LGT8FX88P, LGT8FX168P, LGT8FX328P
|
||||
- ATmega324PB
|
||||
- ATmega8A
|
||||
|
||||
* New programmers supported:
|
||||
|
||||
- ehajo-isp (commercial version of USBtiny)
|
||||
- XplainedPro in UPDI mode
|
||||
- XplainedMini in UPDI mode
|
||||
- JTAGICE3 in UPDI mode
|
||||
- Atmel Powerdebugger in all modes (JTAG, PDI, UPDI, debugWIRE, ISP)
|
||||
- linuxspi (direct SPI bus e.g. on Raspberry Pi devices)
|
||||
- PICkit4, Snap, PKoB
|
||||
- iseavrprog
|
||||
- XBeeBoot
|
||||
|
||||
* Bugfixes:
|
||||
bug #47550: Linux GPIO broken
|
||||
bug #47718: "lfuse reads as" not displayed in verbose mode - SOLUTION
|
||||
bug #48084: Avoid compiled-in timestamp for reproducible release builds
|
||||
bug #47376: ATtiny841 description missing in configuration file
|
||||
bug #49455: support for tiny441
|
||||
bug #57428: document when 'arduino' or 'wiring' should be used, and -D requirement of latter
|
||||
bug #58095: error setting efuse on atmega328pb variant
|
||||
bug #51409: Can't program EFUSE on ATmega32M1
|
||||
bug #60753: Patch #1436 breaks multiple programmer/device combinations on MacOS BigSur
|
||||
bug #59525: Bogus error message because Copy/Paste typo in stk500.c
|
||||
bug #58078: [PATCH] buspirate: remove compound literals (fixes GCC>=9)
|
||||
bug #57453: [PATCH] fix reference to nonexistant -m option by changing to -U
|
||||
bug #59227: Add new part. How does one get a part added to the CONF file?
|
||||
bug #55009: no efuses for m164a/pa
|
||||
bug #55734: USBtiny programming of ATmega328p broken by Patch #9278
|
||||
bug #58495: Add atmega324pb support to avrdude.conf.in
|
||||
bug #60863: avrftdi programming error probably caused by multiple, consecutive empty pages
|
||||
bug #50517: Reading fails if "immediate mode" for output file format is selected - fileio: invalid operation=1
|
||||
bug #50630: Erase Cycle Counter options ( -y -Y n ) should be removed from usage Message
|
||||
bug #48767: ser_drain() for TCP on Windows doesn't work
|
||||
bug #46759: avrdude 6.1 -> 6.2 regression: lock byte verification error
|
||||
bug #58440: linuxgpio PIN limit too low
|
||||
bug #55462: wrong programmer id check in jtag3_getsync() and jtag3_close()
|
||||
bug #58994: VPP PWM still enabled at the end of programming process
|
||||
bug #57338: if safemode has to change fuses avrdude should exit with non-zero exit code
|
||||
bug #60575: Permission denied on macOS Big Sur
|
||||
|
||||
* Patches:
|
||||
patch #9482: Add support for UPDI and AVR8X
|
||||
patch #9508: Add PowerDebugger and XPlained Mini in UPDI mode
|
||||
patch #9507: Fix UPDI chip erase
|
||||
patch #9506: Script to create device configuration stub from Atmel
|
||||
ATDF files
|
||||
patch #9423: Support ATtiny841 and ATtiny441
|
||||
patch #9530: Update URL to Ladyada's USBtinyISP page.
|
||||
patch #9317: Support atmega64m1 as part
|
||||
patch #9222: Enable silent build
|
||||
patch #8924: Enable TPI for usbtiny
|
||||
patch #9033: avrdoper backend uses libhidapi instead of libusb
|
||||
patch #8580: FT245r support to select device by serial number
|
||||
patch #8910: ATxmega32c4 and ATxmega16c4 have wrong signatures
|
||||
patch #8219: Fix boot_start for xmega devices on jtagmkII
|
||||
patch #9185: Add extended_param to usbasp.c - erasing
|
||||
patch #8311: Add IPv6 support to the -Pnet:host:port option
|
||||
patch #9542: Correct "usersig" on avr8x devices
|
||||
patch #8128: Added new option to configure.ac script
|
||||
patch #8444: Proposal for modifications in -B and -U command options managment (partially)
|
||||
patch #9735: spelling error fix: psuedo -> pseudo
|
||||
patch #9893: [PATCH] Reader reads ftdi handle after main thread close it
|
||||
patch #9819: Address several leaks in SVN rev 1429
|
||||
patch #9820: Fix some out-of-bounds/uninitialized issues
|
||||
patch #9818: correct typos in SVN rev 1429
|
||||
patch #9732: usbtiny_paged_load overflows buffer e.g. when reading EEPROM
|
||||
patch #9966: Add JTAGICE3 in UPDI mode
|
||||
patch #9963: UsbAsp 3 MHz patch for UsbAsp-flash firmware
|
||||
patch #9816: Implement new programmer type: linuxspi
|
||||
patch #9811: ATmega328pb has efuse bit 3
|
||||
patch #9744: Patch for ATMega324A support
|
||||
patch #10000: Add support for extended UPDI device context
|
||||
patch #9697: Add iseavrprog support
|
||||
patch #10017: uspasp / tpi: Automatically clear configuration byte (fuse) before writing it
|
||||
patch #8957: Allow reading prodsig memory from stk500v2 on xmega devices
|
||||
patch #9110: Let reserved fuse bits to be read as *don't care*
|
||||
patch #9253: Fix for giving terminal_mode commands more than 20 arguments
|
||||
patch #9320: fix TPI RESET in bitbang.c
|
||||
patch #9079: Fix ftdi_syncbb teardown (supersedes #9893, superseded by #9328)
|
||||
patch #9122: Fixed MISO sampling in ftdi_syncbb
|
||||
patch #9123: ftdi_syncbb: use FT245R_CYCLES in ft245r_set_bitclock()
|
||||
patch #8719: Support Over-the-Air bootloading with XBeeBoot
|
||||
patch #9757: Fix ATtiny817 Xplained Mini programmer
|
||||
patch #9327: ft245r.c: add TPI support (patches 1-4)
|
||||
patch #9328: ft245r.c: add TPI support (patches 5-7)
|
||||
patch #10027: linuxspi: Add reset pulse, according to AVR programming algorithm
|
||||
patch #10028: linuxspi: close() only when necessary
|
||||
patch #10029: linuxspi: Report GPIO_GET_LINEHANDLE_IOCTL errors
|
||||
patch #10030: linuxspi: Support inverted GPIO pin
|
||||
patch #10031: linuxspi: Support GPIO uAPI v2
|
||||
(no-id): Improve documentation of linuxspi driver, provide portname default
|
||||
(no-id): Use -B <bitclock> rather than -b <baudrate> for linuxspi driver
|
||||
patch #9304: [Bug #48767] Implemented WinSock variation of "ser_drain(...)" functionality
|
||||
patch #8996: Remove lock byte read mask (bug#21954, bug#46759)
|
||||
patch #8923: Enable TPI for linuxgpio
|
||||
patch #10153: linuxspi: Support "-E reset" and "-E noreset"
|
||||
|
||||
* Internals:
|
||||
- New avrdude.conf keyword "family_id", used to verify SIB attributes
|
||||
on AVR8X architecture if device is locked.
|
||||
|
||||
|
||||
Version 6.3:
|
||||
|
||||
* Major changes compared to the previous version:
|
||||
|
||||
- Backout of
|
||||
patch #8380: adds 500k 1M 2M baud to ser_posix.c
|
||||
It broke the functionality in too many situations
|
||||
(bug #46610/46483)
|
||||
|
||||
* New devices supported:
|
||||
|
||||
- ATmega48PB, ATmega88PB, ATmega168PB
|
||||
- ATtiny28 (HVPP-only device)
|
||||
|
||||
* New programmers supported:
|
||||
|
||||
- Atmel mEDBG: xplainedmini, xplainedmini_dw
|
||||
|
||||
* Bugfixes
|
||||
|
||||
- bug #46610: Floating point exception (core dumped) arch linux rpi2
|
||||
- bug #46483: version 6.2. ser_open(): can't set attributes for device
|
||||
- patch #8435: Implementing mEDBG CMSIS-DAP protocol
|
||||
- patch #8735: ATtiny28 support in avrdude.conf
|
||||
- patch #8896: Silence cppcheck warnings in 6.2 code
|
||||
- patch #8895: Spelling in 6.2 code
|
||||
|
||||
|
||||
Version 6.2:
|
||||
|
||||
* Major changes compared to the previous version:
|
||||
@@ -233,6 +63,7 @@ Version 6.2:
|
||||
- bug #40870: config nitpick: ATtiny25/45/85 have 1 calibration byte not 2
|
||||
- bug #42908: no external reset at JTAGICE3
|
||||
- patch #8437: [PATCH] Serial-over-ethernet for Win32
|
||||
- patch #8380: adds 500k 1M 2M baud to ser_posix.c
|
||||
- bug #44717: avrdude creates empty flash dump
|
||||
|
||||
* Internals:
|
||||
|
||||
94
avr.c
94
avr.c
@@ -80,12 +80,11 @@ int avr_tpi_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
||||
0xFF
|
||||
};
|
||||
|
||||
while (avr_tpi_poll_nvmbsy(pgm))
|
||||
;
|
||||
while (avr_tpi_poll_nvmbsy(pgm));
|
||||
|
||||
err = pgm->cmd_tpi(pgm, cmd, sizeof(cmd), NULL, 0);
|
||||
if(err)
|
||||
return err;
|
||||
err = pgm->cmd_tpi(pgm, cmd, sizeof(cmd), NULL, 0);
|
||||
if(err)
|
||||
return err;
|
||||
|
||||
while (avr_tpi_poll_nvmbsy(pgm));
|
||||
|
||||
@@ -330,7 +329,7 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype,
|
||||
memset(mem->buf, 0xff, mem->size);
|
||||
|
||||
/* supports "paged load" thru post-increment */
|
||||
if ((p->flags & AVRPART_HAS_TPI) && mem->page_size > 1 &&
|
||||
if ((p->flags & AVRPART_HAS_TPI) && mem->page_size != 0 &&
|
||||
pgm->cmd_tpi != NULL) {
|
||||
|
||||
while (avr_tpi_poll_nvmbsy(pgm));
|
||||
@@ -361,7 +360,7 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype,
|
||||
return avr_mem_hiaddr(mem);
|
||||
}
|
||||
|
||||
if (pgm->paged_load != NULL && mem->page_size > 1) {
|
||||
if (pgm->paged_load != NULL && mem->page_size != 0) {
|
||||
/*
|
||||
* the programmer supports a paged mode read
|
||||
*/
|
||||
@@ -439,15 +438,11 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype,
|
||||
{
|
||||
rc = pgm->read_byte(pgm, p, mem, i, mem->buf + i);
|
||||
if (rc != 0) {
|
||||
avrdude_message(MSG_INFO, "avr_read(): error reading address 0x%04lx\n", i);
|
||||
if (rc == -1) {
|
||||
avrdude_message(MSG_INFO, " read operation not supported for memory \"%s\"\n",
|
||||
avrdude_message(MSG_INFO, "avr_read(): error reading address 0x%04lx\n", i);
|
||||
if (rc == -1)
|
||||
avrdude_message(MSG_INFO, " read operation not supported for memory \"%s\"\n",
|
||||
memtype);
|
||||
return -2;
|
||||
}
|
||||
avrdude_message(MSG_INFO, " read operation failed for memory \"%s\"\n",
|
||||
memtype);
|
||||
return rc;
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
report_progress(i, mem->size, NULL);
|
||||
@@ -863,7 +858,7 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
||||
}
|
||||
|
||||
|
||||
if ((p->flags & AVRPART_HAS_TPI) && m->page_size > 1 &&
|
||||
if ((p->flags & AVRPART_HAS_TPI) && m->page_size != 0 &&
|
||||
pgm->cmd_tpi != NULL) {
|
||||
|
||||
while (avr_tpi_poll_nvmbsy(pgm));
|
||||
@@ -903,7 +898,7 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
||||
return i;
|
||||
}
|
||||
|
||||
if (pgm->paged_write != NULL && m->page_size > 1) {
|
||||
if (pgm->paged_write != NULL && m->page_size != 0) {
|
||||
/*
|
||||
* the programmer supports a paged mode write
|
||||
*/
|
||||
@@ -1056,37 +1051,13 @@ int avr_signature(PROGRAMMER * pgm, AVRPART * p)
|
||||
if (rc < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: error reading signature data for part \"%s\", rc=%d\n",
|
||||
progname, p->desc, rc);
|
||||
return rc;
|
||||
return -1;
|
||||
}
|
||||
report_progress (1,1,NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t get_fuse_bitmask(AVRMEM * m) {
|
||||
uint8_t bitmask_r = 0;
|
||||
uint8_t bitmask_w = 0;
|
||||
int i;
|
||||
|
||||
if (!m || m->size > 1) {
|
||||
// not a fuse, compare bytes directly
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
// For fuses, only compare bytes that are actually written *and* read.
|
||||
for (i = 0; i < 32; i++) {
|
||||
if (m->op[AVR_OP_WRITE]->bit[i].type == AVR_CMDBIT_INPUT)
|
||||
bitmask_w |= (1 << m->op[AVR_OP_WRITE]->bit[i].bitno);
|
||||
if (m->op[AVR_OP_READ]->bit[i].type == AVR_CMDBIT_OUTPUT)
|
||||
bitmask_r |= (1 << m->op[AVR_OP_READ]->bit[i].bitno);
|
||||
}
|
||||
return bitmask_r & bitmask_w;
|
||||
}
|
||||
|
||||
int compare_memory_masked(AVRMEM * m, uint8_t b1, uint8_t b2) {
|
||||
uint8_t bitmask = get_fuse_bitmask(m);
|
||||
return (b1 & bitmask) != (b2 & bitmask);
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify the memory buffer of p with that of v. The byte range of v,
|
||||
@@ -1133,30 +1104,11 @@ int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size)
|
||||
for (i=0; i<size; i++) {
|
||||
if ((b->tags[i] & TAG_ALLOCATED) != 0 &&
|
||||
buf1[i] != buf2[i]) {
|
||||
uint8_t bitmask = get_fuse_bitmask(a);
|
||||
if((buf1[i] & bitmask) != (buf2[i] & bitmask)) {
|
||||
// Mismatch is not just in unused bits
|
||||
avrdude_message(MSG_INFO, "%s: verification error, first mismatch at byte 0x%04x\n"
|
||||
"%s0x%02x != 0x%02x\n",
|
||||
progname, i,
|
||||
progbuf, buf1[i], buf2[i]);
|
||||
return -1;
|
||||
} else {
|
||||
// Mismatch is only in unused bits
|
||||
if ((buf1[i] | bitmask) != 0xff) {
|
||||
// Programmer returned unused bits as 0, must be the part/programmer
|
||||
avrdude_message(MSG_INFO, "%s: WARNING: ignoring mismatch in unused bits of \"%s\"\n"
|
||||
"%s(0x%02x != 0x%02x). To prevent this warning fix the part\n"
|
||||
"%sor programmer definition in the config file.\n",
|
||||
progname, memtype, progbuf, buf1[i], buf2[i], progbuf);
|
||||
} else {
|
||||
// Programmer returned unused bits as 1, must be the user
|
||||
avrdude_message(MSG_INFO, "%s: WARNING: ignoring mismatch in unused bits of \"%s\"\n"
|
||||
"%s(0x%02x != 0x%02x). To prevent this warning set unused bits\n"
|
||||
"%sto 1 when writing (double check with your datasheet first).\n",
|
||||
progname, memtype, progbuf, buf1[i], buf2[i], progbuf);
|
||||
}
|
||||
}
|
||||
avrdude_message(MSG_INFO, "%s: verification error, first mismatch at byte 0x%04x\n"
|
||||
"%s0x%02x != 0x%02x\n",
|
||||
progname, i,
|
||||
progbuf, buf1[i], buf2[i]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1239,16 +1191,6 @@ int avr_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
||||
return rc;
|
||||
}
|
||||
|
||||
int avr_unlock(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
int rc = -1;
|
||||
|
||||
if (pgm->unlock)
|
||||
rc = pgm->unlock(pgm, p);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Report the progress of a read or write operation from/to the
|
||||
* device.
|
||||
|
||||
109
avrdude.1
109
avrdude.1
@@ -1,6 +1,6 @@
|
||||
.\"
|
||||
.\" avrdude - A Downloader/Uploader for AVR device programmers
|
||||
.\" Copyright (C) 2001, 2002, 2003, 2005 - 2020 Joerg Wunsch
|
||||
.\" Copyright (C) 2001, 2002, 2003, 2005 - 2014 Joerg Wunsch
|
||||
.\"
|
||||
.\" This program is free software; you can redistribute it and/or modify
|
||||
.\" it under the terms of the GNU General Public License as published by
|
||||
@@ -18,7 +18,7 @@
|
||||
.\"
|
||||
.\" $Id$
|
||||
.\"
|
||||
.Dd DATE November 22, 2021
|
||||
.Dd DATE November 23, 2014
|
||||
.Os
|
||||
.Dt AVRDUDE 1
|
||||
.Sh NAME
|
||||
@@ -109,31 +109,6 @@ some resistors in series or better yet use a 3-state buffer driver like
|
||||
the 74HC244. Have a look at http://kolev.info/avrdude-linuxgpio for a more
|
||||
detailed tutorial about using this programmer type.
|
||||
.Pp
|
||||
Under a Linux installation with direct access to the SPI bus and GPIO
|
||||
pins, such as would be found on a Raspberry Pi, the ``linuxspi''
|
||||
programmer type can be used to directly connect to and program a chip
|
||||
using the built in interfaces on the computer. The requirements to use
|
||||
this type are that an SPI interface is exposed along with one GPIO
|
||||
pin. The GPIO serves as the reset output since the Linux SPI drivers
|
||||
do not hold slave select down when a transfer is not occuring and thus
|
||||
it cannot be used as the reset pin. A readily available level
|
||||
translator should be used between the SPI bus/reset GPIO and the chip
|
||||
to avoid potentially damaging the computer's SPI controller in the
|
||||
event that the chip is running at 5V and the SPI runs at 3.3V. The
|
||||
GPIO chosen for reset can be configured in the avrdude configuration
|
||||
file using the
|
||||
.Li reset
|
||||
entry under the linuxspi programmer, or
|
||||
directly in the port specification. An external pull-up resistor
|
||||
should be connected between the AVR's reset pin and Vcc. If Vcc is not
|
||||
the same as the SPI voltage, this should be done on the AVR side of
|
||||
the level translator to protect the hardware from damage.
|
||||
.Pp
|
||||
The
|
||||
.Fl P Ar portname
|
||||
option for this programmer defaults to
|
||||
.Li /dev/spidev0.0:/dev/gpiochip0 .
|
||||
.Pp
|
||||
Atmel's STK500 programmer is also supported and connects to a serial
|
||||
port.
|
||||
Both, firmware versions 1.x and 2.x can be handled, but require a
|
||||
@@ -142,15 +117,12 @@ Using firmware version 2, high-voltage programming is also supported,
|
||||
both parallel and serial
|
||||
(programmer types stk500pp and stk500hvsp).
|
||||
.Pp
|
||||
Wiring boards (e.g. Arduino Mega 2560 Rev3) are supported, utilizing STK500
|
||||
V2.x protocol, but a simple DTR/RTS toggle is used to set the boards into
|
||||
programming mode. The programmer type is ``wiring''. Note that the -D option
|
||||
will likely be required in this case, because the bootloader will rewrite the
|
||||
program memory, but no true chip erase can be performed.
|
||||
Wiring boards are supported, utilizing STK500 V2.x protocol, but
|
||||
a simple DTR/RTS toggle is used to set the boards into programming mode.
|
||||
The programmer type is ``wiring''.
|
||||
.Pp
|
||||
The Arduino (which is very similar to the STK500 1.x) is supported via
|
||||
its own programmer type specification ``arduino''. This programmer works for
|
||||
the Arduino Uno Rev3.
|
||||
its own programmer type specification ``arduino''.
|
||||
.Pp
|
||||
The BusPirate is a versatile tool that can also be used as an AVR programmer.
|
||||
A single BusPirate can be connected to up to 3 independent AVRs. See
|
||||
@@ -184,9 +156,6 @@ ISP).
|
||||
Atmel's XplainedPro boards, using the EDBG protocol (CMSIS-DAP compatible),
|
||||
are supported using the "jtag3" programmer type.
|
||||
.Pp
|
||||
Atmel's XplainedMini boards, using the mEDBG protocol,
|
||||
are also supported using the "jtag3" programmer type.
|
||||
.Pp
|
||||
The AVR Dragon is supported in all modes (ISP, JTAG, HVSP, PP, debugWire).
|
||||
When used in JTAG and debugWire mode, the AVR Dragon behaves similar to a
|
||||
JTAG ICE mkII, so all device-specific comments for that device
|
||||
@@ -216,12 +185,6 @@ The Atmel DFU bootloader is supported in both, FLIP protocol version 1
|
||||
(AT90USB* and ATmega*U* devices), as well as version 2 (Xmega devices).
|
||||
See below for some hints about FLIP version 1 protocol behaviour.
|
||||
.Pp
|
||||
The MPLAB(R) PICkit 4, MPLAB(R) SNAP, and Curiosity Nano boards are
|
||||
supported in UPDI mode. The Curiosity Nano board is dubbed
|
||||
.Dq PICkit on Board ,
|
||||
thus the name
|
||||
.Pa pkobn_updi .
|
||||
.Pp
|
||||
Input files can be provided, and output files can be written in
|
||||
different file formats, such as raw binary files containing the data
|
||||
to download to the chip, Intel hex format, or Motorola S-record
|
||||
@@ -247,7 +210,7 @@ lock bits can be programmed as well. These are implemented within
|
||||
.Nm
|
||||
as separate memory types and can be programmed using data from a file
|
||||
(see the
|
||||
.Fl U
|
||||
.Fl m
|
||||
option) or from terminal mode (see the
|
||||
.Ar dump
|
||||
and
|
||||
@@ -326,8 +289,11 @@ by using ? as programmer-id.
|
||||
Use the specified config file to load configuration data. This file
|
||||
contains all programmer and part definitions that
|
||||
.Nm avrdude
|
||||
knows about.
|
||||
See the config file, located at
|
||||
knows about. If you have a programmer or part that
|
||||
.Nm avrdude
|
||||
does not know about, you can add it to the config file (be sure and
|
||||
submit a patch back to the author so that it can be incorporated for
|
||||
the next version). See the config file, located at
|
||||
.Pa ${PREFIX}/etc/avrdude.conf ,
|
||||
which contains a description of the format.
|
||||
.Pp
|
||||
@@ -519,7 +485,7 @@ same method of specifying the port is required there.
|
||||
For the USB programmer "AVR-Doper" running in HID mode, the port must
|
||||
be specified as
|
||||
.Ar avrdoper.
|
||||
Libhidapi support is required on Unix and Mac OS but not on Windows. For more
|
||||
Libusb support is required on Unix but not on Windows. For more
|
||||
information about AVR-Doper see http://www.obdev.at/avrusb/avrdoper.html.
|
||||
.Pp
|
||||
For the USBtinyISP, which is a simplicistic device not implementing
|
||||
@@ -528,22 +494,6 @@ location in the USB hierarchy. See the the respective
|
||||
.Em Troubleshooting
|
||||
entry in the detailed documentation for examples.
|
||||
.Pp
|
||||
For the XBee programmer the target MCU is to be programmed wirelessly over a
|
||||
ZigBee mesh using the XBeeBoot bootloader. The ZigBee 64-bit address for the
|
||||
target MCU's own XBee device must be supplied as a 16-character hexadecimal
|
||||
value as a
|
||||
.Ar port
|
||||
prefix, followed by the
|
||||
.Ql @
|
||||
character, and the serial device to connect to a second directly contactable
|
||||
XBee device associated with the same mesh (with a default baud rate of 9600).
|
||||
This may look similar to:
|
||||
.Pa 0013a20000000001@/dev/tty.serial .
|
||||
.Pp
|
||||
For diagnostic purposes, if the target MCU with an XBeeBoot bootloader is
|
||||
connected directly to the serial port, the 64-bit address field can be
|
||||
omitted. In this mode the default baud rate will be 19200.
|
||||
.Pp
|
||||
For programmers that attach to a serial port using some kind of
|
||||
higher level protocol (as opposed to bit-bang style programmers),
|
||||
.Ar port
|
||||
@@ -555,19 +505,12 @@ network connection to (TCP)
|
||||
on
|
||||
.Ar host
|
||||
is established.
|
||||
Square brackets may be placed around
|
||||
.Ar host
|
||||
to improve readability, for numeric IPv6 addresses (e.g.
|
||||
.Li net:[2001:db8::42]:1337 ) .
|
||||
The remote endpoint is assumed to be a terminal or console server
|
||||
that connects the network stream to a local serial port where the
|
||||
actual programmer has been attached to.
|
||||
The port is assumed to be properly configured, for example using a
|
||||
transparent 8-bit data connection without parity at 115200 Baud
|
||||
for a STK500.
|
||||
.Pp
|
||||
Note: The ability to handle IPv6 hostnames and addresses is limited to
|
||||
Posix systems (by now).
|
||||
.It Fl q
|
||||
Disable (or quell) output of the progress bar while reading or writing
|
||||
to the device. Specify it a second time for even quieter operation.
|
||||
@@ -1104,32 +1047,6 @@ Sets the SPI clocking rate in Hz (default is 100kHz). Alternately the -B or -i o
|
||||
.It Ar timeout=<usb-transaction-timeout>
|
||||
Sets the timeout for USB reads and writes in milliseconds (default is 1500 ms).
|
||||
.El
|
||||
.It Ar USBasp
|
||||
Extended parameters:
|
||||
.Bl -tag -offset indent -width indent
|
||||
.It Ar section_config
|
||||
Programmer will erase configuration section with option
|
||||
.Fl e
|
||||
(chip erase), rather than entire chip.
|
||||
Only applicable to TPI devices (ATtiny 4/5/9/10/20/40).
|
||||
.El
|
||||
.It Ar xbee
|
||||
Extended parameters:
|
||||
.Bl -tag -offset indent -width indent
|
||||
.It Ar xbeeresetpin=<1..7>
|
||||
Select the XBee pin DIO<1..7> that is connected to the MCU's
|
||||
.Ql /RESET
|
||||
line. The programmer needs to know which DIO pin to use to reset into the
|
||||
bootloader. The default (3) is the DIO3 pin (XBee pin 17), but some
|
||||
commercial products use a different XBee pin.
|
||||
.Pp
|
||||
The remaining two necessary XBee-to-MCU connections are not selectable - the
|
||||
XBee DOUT pin (pin 2) must be connected to the MCU's
|
||||
.Ql RXD
|
||||
line, and the XBee DIN pin (pin 3) must be connected to the MCU's
|
||||
.Ql TXD
|
||||
line.
|
||||
.El
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -offset indent -width /dev/ppi0XXX
|
||||
|
||||
2394
avrdude.conf.in
2394
avrdude.conf.in
File diff suppressed because it is too large
Load Diff
27
avrftdi.c
27
avrftdi.c
@@ -703,7 +703,7 @@ static int avrftdi_open(PROGRAMMER * pgm, char *port)
|
||||
|
||||
err = ftdi_usb_open_desc_index(pdata->ftdic, vid, pid, desc, serial, index);
|
||||
if(err) {
|
||||
log_err("Error %d occurred: %s\n", err, ftdi_get_error_string(pdata->ftdic));
|
||||
log_err("Error %d occured: %s\n", err, ftdi_get_error_string(pdata->ftdic));
|
||||
//stupid hack, because avrdude calls pgm->close() even when pgm->open() fails
|
||||
//and usb_dev is intialized to the last usb device from probing
|
||||
pdata->ftdic->usb_dev = NULL;
|
||||
@@ -1045,6 +1045,16 @@ static int avrftdi_flash_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
bufptr += 4;
|
||||
}
|
||||
|
||||
buf_size = bufptr - buf;
|
||||
|
||||
if(verbose > TRACE)
|
||||
buf_dump(buf, buf_size, "command buffer", 0, 16*2);
|
||||
|
||||
log_info("Transmitting buffer of size: %d\n", buf_size);
|
||||
if (0 > avrftdi_transmit(pgm, MPSSE_DO_WRITE, buf, buf, buf_size))
|
||||
return -1;
|
||||
|
||||
bufptr = buf;
|
||||
/* find a poll byte. we cannot poll a value of 0xff, so look
|
||||
* for a value != 0xff
|
||||
*/
|
||||
@@ -1054,17 +1064,6 @@ static int avrftdi_flash_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
|
||||
if((poll_index < addr + len) && m->buf[poll_index] != 0xff)
|
||||
{
|
||||
buf_size = bufptr - buf;
|
||||
|
||||
if(verbose > TRACE)
|
||||
buf_dump(buf, buf_size, "command buffer", 0, 16*2);
|
||||
|
||||
log_info("Transmitting buffer of size: %d\n", buf_size);
|
||||
if (0 > avrftdi_transmit(pgm, MPSSE_DO_WRITE, buf, buf, buf_size))
|
||||
return -1;
|
||||
|
||||
bufptr = buf;
|
||||
|
||||
log_info("Using m->buf[%d] = 0x%02x as polling value ", poll_index,
|
||||
m->buf[poll_index]);
|
||||
/* poll page write ready */
|
||||
@@ -1078,7 +1077,9 @@ static int avrftdi_flash_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
}
|
||||
else
|
||||
{
|
||||
log_warn("Skipping empty page (containing only 0xff bytes)\n");
|
||||
log_warn("No suitable byte (!=0xff) for polling found.\n");
|
||||
log_warn("Trying to sleep instead, but programming errors may occur.\n");
|
||||
log_warn("Be sure to verify programmed memory (no -V option)\n");
|
||||
/* TODO sync write */
|
||||
/* sleep */
|
||||
usleep((m->max_write_delay));
|
||||
|
||||
@@ -254,7 +254,6 @@ AVRMEM * avr_new_memtype(void)
|
||||
}
|
||||
|
||||
memset(m, 0, sizeof(*m));
|
||||
m->page_size = 1; // ensure not 0
|
||||
|
||||
return m;
|
||||
}
|
||||
@@ -646,7 +645,7 @@ void avr_display(FILE * f, AVRPART * p, const char * prefix, int verbose)
|
||||
prefix, avr_pin_name(p->retry_pulse),
|
||||
prefix, (p->flags & AVRPART_SERIALOK) ? "yes" : "no",
|
||||
prefix, (p->flags & AVRPART_PARALLELOK) ?
|
||||
((p->flags & AVRPART_PSEUDOPARALLEL) ? "pseudo" : "yes") : "no",
|
||||
((p->flags & AVRPART_PSEUDOPARALLEL) ? "psuedo" : "yes") : "no",
|
||||
prefix, p->timeout,
|
||||
prefix, p->stabdelay,
|
||||
prefix, p->cmdexedelay,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2005 Juliane Holzt <avrdude@juliane.holzt.de>
|
||||
* Copyright (C) 2005 Michael Holzt <kju-avr@fqdn.org>
|
||||
* Copyright (C) 2011 Darell Tan <darell.tan@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -542,10 +542,7 @@ int bitbang_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
|
||||
/* bring RESET high first */
|
||||
pgm->setpin(pgm, PIN_AVR_RESET, 1);
|
||||
usleep(128000); /* wait t_TOUT (32-128ms) */
|
||||
|
||||
/* RESET must be LOW in case the existing code is driving the TPI pins: */
|
||||
pgm->setpin(pgm, PIN_AVR_RESET, 0);
|
||||
usleep(1000);
|
||||
|
||||
avrdude_message(MSG_NOTICE2, "doing MOSI-MISO link check\n");
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2005 Juliane Holzt <avrdude@juliane.holzt.de>
|
||||
* Copyright (C) 2005 Michael Holzt <kju-avr@fqdn.org>
|
||||
* Copyright (C) 2011 Darell Tan <darell.tan@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
@@ -13,11 +13,7 @@ set -x
|
||||
|
||||
rm -rf autom4te.cache
|
||||
|
||||
# MacOS calls it "glibtoolize", everyone else "libtoolize"
|
||||
# probe for that
|
||||
LIBTOOLIZE=libtoolize
|
||||
glibtoolize --version > /dev/null 2>&1 && LIBTOOLIZE=glibtoolize
|
||||
${LIBTOOLIZE}
|
||||
libtoolize
|
||||
|
||||
${ACLOCAL}
|
||||
${AUTOHEADER}
|
||||
|
||||
48
buspirate.c
48
buspirate.c
@@ -493,31 +493,35 @@ static void buspirate_reset_from_binmode(struct programmer_t *pgm)
|
||||
|
||||
static int buspirate_start_mode_bin(struct programmer_t *pgm)
|
||||
{
|
||||
struct submode {
|
||||
const struct submode {
|
||||
const char *name; /* Name of mode for user messages */
|
||||
char enter; /* Command to enter from base binary mode */
|
||||
const char *entered_format; /* Response, for "scanf" */
|
||||
char config; /* Command to setup submode parameters */
|
||||
} submode;
|
||||
} *submode;
|
||||
|
||||
if (pgm->flag & BP_FLAG_XPARM_RAWFREQ) {
|
||||
submode.name = "Raw-wire";
|
||||
submode.enter = 0x05;
|
||||
submode.entered_format = "RAW%1d";
|
||||
submode.config = 0x8C;
|
||||
submode = &(const struct submode){
|
||||
.name = "Raw-wire",
|
||||
.enter = 0x05,
|
||||
.entered_format = "RAW%1d",
|
||||
.config = 0x8C,
|
||||
};
|
||||
pgm->flag |= BP_FLAG_NOPAGEDWRITE;
|
||||
pgm->flag |= BP_FLAG_NOPAGEDREAD;
|
||||
} else {
|
||||
submode.name = "SPI";
|
||||
submode.enter = 0x01;
|
||||
submode.entered_format = "SPI%1d";
|
||||
|
||||
/* 1000wxyz - SPI config, w=HiZ(0)/3.3v(1), x=CLK idle, y=CLK edge, z=SMP sample
|
||||
* we want: 3.3V(1), idle low(0), data change on
|
||||
* trailing edge (1), sample in the middle
|
||||
* of the pulse (0)
|
||||
* => 0b10001010 = 0x8a */
|
||||
submode.config = 0x8A;
|
||||
submode = &(const struct submode){
|
||||
.name = "SPI",
|
||||
.enter = 0x01,
|
||||
.entered_format = "SPI%1d",
|
||||
|
||||
/* 1000wxyz - SPI config, w=HiZ(0)/3.3v(1), x=CLK idle, y=CLK edge, z=SMP sample
|
||||
* we want: 3.3V(1), idle low(0), data change on
|
||||
* trailing edge (1), sample in the middle
|
||||
* of the pulse (0)
|
||||
* => 0b10001010 = 0x8a */
|
||||
.config = 0x8A,
|
||||
};
|
||||
}
|
||||
|
||||
unsigned char buf[20] = { '\0' };
|
||||
@@ -562,18 +566,18 @@ static int buspirate_start_mode_bin(struct programmer_t *pgm)
|
||||
}
|
||||
|
||||
/* == Set protocol sub-mode of binary mode == */
|
||||
buf[0] = submode.enter;
|
||||
buf[0] = submode->enter;
|
||||
buspirate_send_bin(pgm, buf, 1);
|
||||
memset(buf, 0, sizeof(buf));
|
||||
buspirate_recv_bin(pgm, buf, 4);
|
||||
if (sscanf((const char*)buf, submode.entered_format, &PDATA(pgm)->submode_version) != 1) {
|
||||
if (sscanf((const char*)buf, submode->entered_format, &PDATA(pgm)->submode_version) != 1) {
|
||||
avrdude_message(MSG_INFO, "%s mode not confirmed: '%s'\n",
|
||||
submode.name, buf);
|
||||
submode->name, buf);
|
||||
buspirate_reset_from_binmode(pgm);
|
||||
return -1;
|
||||
}
|
||||
avrdude_message(MSG_NOTICE, "BusPirate %s version: %d\n",
|
||||
submode.name, PDATA(pgm)->submode_version);
|
||||
submode->name, PDATA(pgm)->submode_version);
|
||||
|
||||
if (pgm->flag & BP_FLAG_NOPAGEDWRITE) {
|
||||
avrdude_message(MSG_NOTICE, "%s: Paged flash write disabled.\n", progname);
|
||||
@@ -614,7 +618,7 @@ static int buspirate_start_mode_bin(struct programmer_t *pgm)
|
||||
return -1;
|
||||
|
||||
/* Submode config */
|
||||
if (buspirate_expect_bin_byte(pgm, submode.config, 0x01) < 0)
|
||||
if (buspirate_expect_bin_byte(pgm, submode->config, 0x01) < 0)
|
||||
return -1;
|
||||
|
||||
/* AVR Extended Commands - test for existence */
|
||||
@@ -797,7 +801,7 @@ static void buspirate_powerup(struct programmer_t *pgm)
|
||||
char buf[25];
|
||||
int ok = 0;
|
||||
snprintf(buf, sizeof(buf), "%d\n", PDATA(pgm)->cpufreq);
|
||||
if (buspirate_expect(pgm, "g\n", "Frequency in kHz", 1)) {
|
||||
if (buspirate_expect(pgm, "g\n", "Frequency in KHz", 1)) {
|
||||
if (buspirate_expect(pgm, buf, "Duty cycle in %", 1)) {
|
||||
if (buspirate_expect(pgm, "50\n", "PWM active", 1)) {
|
||||
ok = 1;
|
||||
|
||||
2
config.c
2
config.c
@@ -217,7 +217,6 @@ TOKEN * hexnumber(char * text)
|
||||
tkn->value.number = strtoul(text, &e, 16);
|
||||
if ((e == text) || (*e != 0)) {
|
||||
yyerror("can't scan hex number \"%s\"", text);
|
||||
free_token(tkn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -245,7 +244,6 @@ TOKEN * string(char * text)
|
||||
tkn->value.string = (char *) malloc(len+1);
|
||||
if (tkn->value.string == NULL) {
|
||||
yyerror("string(): out of memory");
|
||||
free_token(tkn);
|
||||
return NULL;
|
||||
}
|
||||
strcpy(tkn->value.string, text);
|
||||
|
||||
@@ -80,7 +80,6 @@ static int pin_name;
|
||||
%token K_DEFAULT_SAFEMODE
|
||||
%token K_DEFAULT_SERIAL
|
||||
%token K_DESC
|
||||
%token K_FAMILY_ID
|
||||
%token K_DEVICECODE
|
||||
%token K_STK500_DEVCODE
|
||||
%token K_AVR910_DEVCODE
|
||||
@@ -97,7 +96,6 @@ static int pin_name;
|
||||
%token K_MOSI
|
||||
%token K_NUM_PAGES
|
||||
%token K_NVM_BASE
|
||||
%token K_OCD_BASE
|
||||
%token K_OCDREV
|
||||
%token K_OFFSET
|
||||
%token K_PAGEL
|
||||
@@ -185,7 +183,6 @@ static int pin_name;
|
||||
%token K_HAS_JTAG /* MCU has JTAG i/f. */
|
||||
%token K_HAS_DW /* MCU has debugWire i/f. */
|
||||
%token K_HAS_PDI /* MCU has PDI i/f rather than ISP (ATxmega). */
|
||||
%token K_HAS_UPDI /* MCU has UPDI i/f (AVR8X). */
|
||||
%token K_HAS_TPI /* MCU has TPI i/f rather than ISP (ATtiny4/5/9/10). */
|
||||
%token K_IDR /* address of OCD register in IO space */
|
||||
%token K_IS_AT90S1200 /* chip is an AT90S1200 (needs special treatment) */
|
||||
@@ -672,18 +669,11 @@ part_parm :
|
||||
|
||||
K_DESC TKN_EQUAL TKN_STRING
|
||||
{
|
||||
strncpy(current_part->desc, $3->value.string, AVR_DESCLEN - 1);
|
||||
strncpy(current_part->desc, $3->value.string, AVR_DESCLEN);
|
||||
current_part->desc[AVR_DESCLEN-1] = 0;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_FAMILY_ID TKN_EQUAL TKN_STRING
|
||||
{
|
||||
strncpy(current_part->family_id, $3->value.string, AVR_FAMILYIDLEN);
|
||||
current_part->family_id[AVR_FAMILYIDLEN] = 0;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_DEVICECODE TKN_EQUAL TKN_NUMBER {
|
||||
{
|
||||
yyerror("devicecode is deprecated, use "
|
||||
@@ -1072,16 +1062,6 @@ part_parm :
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_HAS_UPDI TKN_EQUAL yesno
|
||||
{
|
||||
if ($3->primary == K_YES)
|
||||
current_part->flags |= AVRPART_HAS_UPDI;
|
||||
else if ($3->primary == K_NO)
|
||||
current_part->flags &= ~AVRPART_HAS_UPDI;
|
||||
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_HAS_TPI TKN_EQUAL yesno
|
||||
{
|
||||
if ($3->primary == K_YES)
|
||||
@@ -1168,12 +1148,6 @@ part_parm :
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_OCD_BASE TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->ocd_base = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_OCDREV TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->ocdrev = $3->value.number;
|
||||
@@ -1240,7 +1214,7 @@ part_parm :
|
||||
free_token($2);
|
||||
YYABORT;
|
||||
}
|
||||
strncpy(current_mem->desc, $2->value.string, AVR_MEMDESCLEN - 1);
|
||||
strncpy(current_mem->desc, $2->value.string, AVR_MEMDESCLEN);
|
||||
current_mem->desc[AVR_MEMDESCLEN-1] = 0;
|
||||
free_token($2);
|
||||
}
|
||||
@@ -1310,13 +1284,7 @@ mem_spec :
|
||||
|
||||
K_PAGE_SIZE TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
int ps = $3->value.number;
|
||||
if (ps <= 0)
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s, line %d: invalid page size %d, ignored\n",
|
||||
infile, lineno, ps);
|
||||
else
|
||||
current_mem->page_size = ps;
|
||||
current_mem->page_size = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
|
||||
85
configure.ac
85
configure.ac
@@ -23,7 +23,7 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.60)
|
||||
AC_INIT(avrdude, 6.4, avrdude-dev@nongnu.org)
|
||||
AC_INIT(avrdude, 6.2, avrdude-dev@nongnu.org)
|
||||
|
||||
AC_CANONICAL_BUILD
|
||||
AC_CANONICAL_HOST
|
||||
@@ -36,8 +36,6 @@ AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
LT_INIT()
|
||||
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
@@ -115,22 +113,10 @@ if test x$have_libusb = xyes; then
|
||||
fi
|
||||
AC_SUBST(LIBUSB, $LIBUSB)
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
[libusb_1_0],
|
||||
AC_HELP_STRING(
|
||||
[--disable-libusb_1_0],
|
||||
[Allow to build with libusb instead of libusb_1_0 if both are present]),
|
||||
[case "${enableval}" in
|
||||
yes) enabled_libusb_1_0=yes ;;
|
||||
no) enabled_libusb_1_0=no ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for enable-libusb_1_0 option) ;;
|
||||
esac],
|
||||
[enabled_libusb_1_0=yes])
|
||||
|
||||
AH_TEMPLATE([HAVE_LIBUSB_1_0],
|
||||
[Define if USB support is enabled via libusb 1.0])
|
||||
AC_CHECK_LIB([usb-1.0], [libusb_init], [have_libusb_1_0=yes])
|
||||
if test x$have_libusb_1_0 = xyes && test x$enabled_libusb_1_0 = xyes; then
|
||||
if test x$have_libusb_1_0 = xyes; then
|
||||
case $target in
|
||||
*-*-darwin*)
|
||||
LIBUSB_1_0="-lusb-1.0 -framework CoreFoundation -framework IOKit"
|
||||
@@ -146,7 +132,7 @@ fi
|
||||
AH_TEMPLATE([HAVE_LIBUSB_1_0],
|
||||
[Define if USB support is enabled via a libusb-1.0 compatible libusb])
|
||||
AC_CHECK_LIB([usb], [libusb_init], [have_libusb_1_0=yes])
|
||||
if test x$have_libusb_1_0 = xyes && test x$enabled_libusb_1_0 = xyes; then
|
||||
if test x$have_libusb_1_0 = xyes; then
|
||||
case $target in
|
||||
*-*-freebsd*)
|
||||
# FreeBSD 8+ has a native libusb-1.0 API compatible
|
||||
@@ -164,32 +150,13 @@ if test x$have_libusb_1_0 = xyes && test x$enabled_libusb_1_0 = xyes; then
|
||||
AC_CHECK_HEADERS([libusb.h])
|
||||
fi
|
||||
AC_SUBST(LIBUSB_1_0, $LIBUSB_1_0)
|
||||
|
||||
AH_TEMPLATE([HAVE_LIBHIDAPI],
|
||||
[Define if HID support is enabled via libhidapi])
|
||||
AC_SEARCH_LIBS([hid_init], [hidapi hidapi-libusb hidapi-hidraw], [have_libhidapi=yes])
|
||||
if test x$have_libhidapi = xyes; then
|
||||
case $target in
|
||||
*-*-darwin*)
|
||||
LIBHIDAPI="-lhidapi -iframework CoreFoundation -framework IOKit"
|
||||
;;
|
||||
*)
|
||||
LIBHIDAPI="$ac_cv_lib_hid_init"
|
||||
;;
|
||||
esac
|
||||
AC_DEFINE([HAVE_LIBHIDAPI])
|
||||
AC_CHECK_HEADERS([hidapi/hidapi.h])
|
||||
fi
|
||||
AC_SUBST(LIBHIDAPI, $LIBHIDAPI)
|
||||
|
||||
|
||||
AH_TEMPLATE([HAVE_LIBFTDI1],
|
||||
[Define if FTDI support is enabled via libftdi1])
|
||||
AH_TEMPLATE([HAVE_LIBFTDI],
|
||||
[Define if FTDI support is enabled via libftdi])
|
||||
AH_TEMPLATE([HAVE_LIBFTDI_TYPE_232H],
|
||||
[Define if libftdi supports FT232H, libftdi version >= 0.20])
|
||||
AC_CHECK_LIB([ftdi1], [ftdi_new], [have_libftdi1=yes], [], [$LIBUSB_1_0])
|
||||
AC_CHECK_LIB([ftdi1], [ftdi_new], [have_libftdi1=yes], [], [-lusb-1.0])
|
||||
AC_CHECK_LIB([ftdi], [ftdi_usb_get_strings], [have_libftdi=yes], [], [-lusb])
|
||||
if test x$have_libftdi1 = xyes; then
|
||||
LIBFTDI1="-lftdi1"
|
||||
@@ -224,13 +191,11 @@ AC_CHECK_HEADERS([ddk/hidsdi.h],,,[#include <windows.h>
|
||||
AC_C_CONST
|
||||
AC_HEADER_TIME
|
||||
|
||||
AC_CHECK_HEADERS([netinet/in.h])
|
||||
|
||||
# WinSock2
|
||||
AC_CHECK_LIB([ws2_32], [puts])
|
||||
|
||||
# Checks for library functions.
|
||||
AC_CHECK_FUNCS([memset select strcasecmp strdup strerror strncasecmp strtol strtoul gettimeofday usleep getaddrinfo])
|
||||
AC_CHECK_FUNCS([memset select strcasecmp strdup strerror strncasecmp strtol strtoul gettimeofday usleep])
|
||||
|
||||
AC_MSG_CHECKING([for a Win32 HID libray])
|
||||
SAVED_LIBS="${LIBS}"
|
||||
@@ -322,7 +287,7 @@ AC_ARG_ENABLE(
|
||||
no) enabled_parport=no ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for enable-parport option) ;;
|
||||
esac],
|
||||
[enabled_parport=no])
|
||||
[enabled_parport=yes])
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
[linuxgpio],
|
||||
@@ -336,18 +301,6 @@ AC_ARG_ENABLE(
|
||||
esac],
|
||||
[enabled_linuxgpio=no])
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
[linuxspi],
|
||||
AC_HELP_STRING(
|
||||
[--enable-linuxspi],
|
||||
[Enable the Linux SPIDEV interface programmer type]),
|
||||
[case "${enableval}" in
|
||||
yes) enabled_linuxspi=yes ;;
|
||||
no) enabled_linuxspi=no ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for enable-linuxspi option) ;;
|
||||
esac],
|
||||
[enabled_linuxspi=no])
|
||||
|
||||
DIST_SUBDIRS_AC='doc windows'
|
||||
|
||||
if test "$enabled_doc" = "yes"; then
|
||||
@@ -425,14 +378,6 @@ else
|
||||
fi
|
||||
|
||||
|
||||
if test "$enabled_linuxspi" = "yes"; then
|
||||
AC_DEFINE(HAVE_LINUXSPI, 1, [Linux SPI support enabled])
|
||||
confsubst="$confsubst -e /^@HAVE_LINUXSPI_/d"
|
||||
else
|
||||
confsubst="$confsubst -e /^@HAVE_LINUXSPI_BEGIN@/,/^@HAVE_LINUXSPI_END@/d"
|
||||
fi
|
||||
|
||||
|
||||
# If we are compiling with gcc, enable all warning and make warnings errors.
|
||||
if test "$GCC" = yes; then
|
||||
ENABLE_WARNINGS="-Wall"
|
||||
@@ -549,11 +494,7 @@ else
|
||||
fi
|
||||
|
||||
if test x$have_libusb_1_0 = xyes; then
|
||||
if test x$enabled_libusb_1_0 = xyes; then
|
||||
echo "DO HAVE libusb_1_0"
|
||||
else
|
||||
echo "DISABLED libusb_1_0"
|
||||
fi
|
||||
echo "DO HAVE libusb_1_0"
|
||||
else
|
||||
echo "DON'T HAVE libusb_1_0"
|
||||
fi
|
||||
@@ -580,12 +521,6 @@ else
|
||||
echo "DON'T HAVE libhid"
|
||||
fi
|
||||
|
||||
if test x$have_libhidapi = xyes; then
|
||||
echo "DO HAVE libhidapi"
|
||||
else
|
||||
echo "DON'T HAVE libhidapi"
|
||||
fi
|
||||
|
||||
if test x$have_pthread = xyes; then
|
||||
echo "DO HAVE pthread"
|
||||
else
|
||||
@@ -610,9 +545,3 @@ else
|
||||
echo "DISABLED linuxgpio"
|
||||
fi
|
||||
|
||||
if test x$enabled_linuxspi = xyes; then
|
||||
echo "ENABLED linuxspi"
|
||||
else
|
||||
echo "DISABLED linuxspi"
|
||||
fi
|
||||
|
||||
|
||||
142
doc/avrdude.texi
142
doc/avrdude.texi
@@ -30,7 +30,7 @@ For avrdude version @value{VERSION}, @value{UPDATED}.
|
||||
|
||||
Copyright @copyright{} 2003, 2005 Brian Dean
|
||||
|
||||
Copyright @copyright{} 2006 - 2021 J@"org Wunsch
|
||||
Copyright @copyright{} 2006 - 2011 J@"org Wunsch
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
@@ -154,7 +154,7 @@ serial bit-bang adapters,
|
||||
and the PPI (parallel port interface). PPI represents a class
|
||||
of simple programmers where the programming lines are directly
|
||||
connected to the PC parallel port. Several pin configurations exist
|
||||
for several variations of the PPI programmers, and AVRDUDE can be
|
||||
for several variations of the PPI programmers, and AVRDUDE can be be
|
||||
configured to work with them by either specifying the appropriate
|
||||
programmer on the command line or by creating a new entry in its
|
||||
configuration file. All that's usually required for a new entry is to
|
||||
@@ -173,58 +173,15 @@ available (like almost all embedded Linux boards) you can do without
|
||||
any additional hardware - just connect them to the MOSI, MISO, RESET
|
||||
and SCK pins on the AVR and use the linuxgpio programmer type. It bitbangs
|
||||
the lines using the Linux sysfs GPIO interface. Of course, care should
|
||||
be taken about voltage level compatibility. Also, although not strictly
|
||||
be taken about voltage level compatibility. Also, although not strictrly
|
||||
required, it is strongly advisable to protect the GPIO pins from
|
||||
overcurrent situations in some way. The simplest would be to just put
|
||||
some resistors in series or better yet use a 3-state buffer driver like
|
||||
the 74HC244. Have a look at http://kolev.info/avrdude-linuxgpio for a more
|
||||
detailed tutorial about using this programmer type.
|
||||
|
||||
Under a Linux installation with direct access to the SPI bus and GPIO
|
||||
pins, such as would be found on a Raspberry Pi, the ``linuxspi''
|
||||
programmer type can be used to directly connect to and program a chip
|
||||
using the built in interfaces on the computer. The requirements to use
|
||||
this type are that an SPI interface is exposed along with one GPIO
|
||||
pin. The GPIO serves as the reset output since the Linux SPI drivers
|
||||
do not hold slave select down when a transfer is not occuring and thus
|
||||
it cannot be used as the reset pin. A readily available level
|
||||
translator should be used between the SPI bus/reset GPIO and the chip
|
||||
to avoid potentially damaging the computer's SPI controller in the
|
||||
event that the chip is running at 5V and the SPI runs at 3.3V. The
|
||||
GPIO chosen for reset can be configured in the avrdude configuration
|
||||
file using the @code{reset} entry under the linuxspi programmer, or
|
||||
directly in the port specification. An external pull-up resistor
|
||||
should be connected between the AVR's reset pin and Vcc. If Vcc is not
|
||||
the same as the SPI voltage, this should be done on the AVR side of
|
||||
the level translator to protect the hardware from damage.
|
||||
|
||||
On a Raspberry Pi, header J8 provides access to the SPI and GPIO
|
||||
lines.
|
||||
|
||||
Typically, pins 19, 21, and 23 are SPI MOSI, MISO, and SCK, while
|
||||
pins 24 and 26 would serve as CE outputs. So, close to these pins
|
||||
is pin 22 as GPIO25 which can be used as /RESET, and pin 25 can
|
||||
be used as GND.
|
||||
|
||||
A typical programming cable would then look like:
|
||||
|
||||
@multitable @columnfractions .15 .15 .3
|
||||
@item @code{J8 pin} @tab @code{ISP pin} @tab @code{Name}
|
||||
@item @code{21} @tab @code{1} @tab @code{MISO}
|
||||
@item @code{-} @tab @code{2} @tab @code{Vcc - leave open}
|
||||
@item @code{23} @tab @code{3} @tab @code{SCK}
|
||||
@item @code{19} @tab @code{4} @tab @code{MOSI}
|
||||
@item @code{22} @tab @code{5} @tab @code{/RESET}
|
||||
@item @code{25} @tab @code{6} @tab @code{GND}
|
||||
@end multitable
|
||||
|
||||
(Mind the 3.3 V voltage level of the Raspberry Pi!)
|
||||
|
||||
The @code{-P @var{portname}} option defaults to
|
||||
@code{/dev/spidev0.0:/dev/gpiochip0} for this programmer.
|
||||
|
||||
The STK500, JTAG ICE, avr910, and avr109/butterfly use the serial port to communicate with the PC.
|
||||
The STK600, JTAG ICE mkII/3, AVRISP mkII, USBasp, avrftdi (and derivatives), and USBtinyISP
|
||||
The STK600, JTAG ICE mkII/3, AVRISP mkII, USBasp, avrftdi (and derivitives), and USBtinyISP
|
||||
programmers communicate through the USB, using @code{libusb} as a
|
||||
platform abstraction layer.
|
||||
The avrftdi adds support for the FT2232C/D, FT2232H, and FT4232H devices. These all use
|
||||
@@ -259,10 +216,7 @@ has a revision 1 hardware and firmware version of at least 5.37 (decimal).
|
||||
The Atmel-ICE (ARM/AVR) is supported (JTAG, PDI for Xmega, debugWIRE, ISP modes).
|
||||
|
||||
Atmel's XplainedPro boards, using EDBG protocol (CMSIS-DAP compliant), are
|
||||
supported by the ``jtag3'' programmer type.
|
||||
|
||||
Atmel's XplainedMini boards, using mEDBG protocol, are also
|
||||
supported by the ``jtag3'' programmer type.
|
||||
supported by teh ``jtag3'' programmer type.
|
||||
|
||||
The AVR Dragon is supported in all modes (ISP, JTAG, PDI, HVSP, PP, debugWire).
|
||||
When used in JTAG and debugWire mode, the AVR Dragon behaves similar to a
|
||||
@@ -277,16 +231,12 @@ option might be required to achieve a stable ISP communication.
|
||||
For ATxmega devices, the AVR Dragon is supported in PDI mode, provided it
|
||||
has a firmware version of at least 6.11 (decimal).
|
||||
|
||||
Wiring boards (e.g. Arduino Mega 2560 Rev3) are supported, utilizing
|
||||
STK500 V2.x protocol, but a simple DTR/RTS toggle to set the boards
|
||||
into programming mode. The programmer type is ``wiring''. Note that
|
||||
the -D option will likely be required in this case, because the
|
||||
bootloader will rewrite the program memory, but no true chip erase can
|
||||
be performed.
|
||||
Wiring boards are supported, utilizing STK500 V2.x protocol, but
|
||||
a simple DTR/RTS toggle to set the boards into programming mode.
|
||||
The programmer type is ``wiring''.
|
||||
|
||||
The Arduino (which is very similar to the STK500 1.x) is supported via
|
||||
its own programmer type specification ``arduino''. This programmer works for
|
||||
the Arduino Uno Rev3.
|
||||
its own programmer type specification ``arduino''.
|
||||
|
||||
The BusPirate is a versatile tool that can also be used as an AVR programmer.
|
||||
A single BusPirate can be connected to up to 3 independent AVRs. See
|
||||
@@ -303,10 +253,6 @@ The Atmel DFU bootloader is supported in both, FLIP protocol version 1
|
||||
(AT90USB* and ATmega*U* devices), as well as version 2 (Xmega devices).
|
||||
See below for some hints about FLIP version 1 protocol behaviour.
|
||||
|
||||
The MPLAB(R) PICkit 4, MPLAB(R) SNAP, and Curiosity Nano boards are
|
||||
supported in UPDI mode. The Curiosity Nano board is dubbed ``PICkit on
|
||||
Board'', thus the name @code{pkobn_updi}.
|
||||
|
||||
|
||||
@menu
|
||||
* History::
|
||||
@@ -593,29 +539,14 @@ As the AVRISP mkII device can only be talked to over USB, the very
|
||||
same method of specifying the port is required there.
|
||||
|
||||
For the USB programmer "AVR-Doper" running in HID mode, the port must
|
||||
be specified as @var{avrdoper}. Libhidapi support is required on Unix
|
||||
and Mac OS but not on Windows. For more information about AVR-Doper see
|
||||
be specified as @var{avrdoper}. Libusb support is required on Unix
|
||||
but not on Windows. For more information about AVR-Doper see
|
||||
@url{http://www.obdev.at/avrusb/avrdoper.html}.
|
||||
|
||||
For the USBtinyISP, which is a simplistic device not implementing
|
||||
For the USBtinyISP, which is a simplicistic device not implementing
|
||||
serial numbers, multiple devices can be distinguished by their
|
||||
location in the USB hierarchy.
|
||||
See the respective
|
||||
@xref{Troubleshooting} entry for examples.
|
||||
|
||||
For the XBee programmer the target MCU is to be programmed wirelessly
|
||||
over a ZigBee mesh using the XBeeBoot bootloader. The ZigBee 64-bit
|
||||
address for the target MCU's own XBee device must be supplied as a
|
||||
16-character hexadecimal value as a port prefix, followed by the
|
||||
@code{@@} character, and the serial device to connect to a second
|
||||
directly contactable XBee device associated with the same mesh (with
|
||||
a default baud rate of 9600). This may look similar to:
|
||||
@code{0013a20000000001@/dev/tty.serial}.
|
||||
|
||||
For diagnostic purposes, if the target MCU with an XBeeBoot
|
||||
bootloader is connected directly to the serial port, the
|
||||
64-bit address field can be omitted. In this mode the
|
||||
default baud rate will be 19200.
|
||||
@xref{Troubleshooting}, for examples.
|
||||
|
||||
For programmers that attach to a serial port using some kind of
|
||||
higher level protocol (as opposed to bit-bang style programmers),
|
||||
@@ -623,9 +554,6 @@ higher level protocol (as opposed to bit-bang style programmers),
|
||||
In this case, instead of trying to open a local device, a TCP
|
||||
network connection to (TCP) @var{port} on @var{host}
|
||||
is established.
|
||||
Square brackets may be placed around @var{host} to improve
|
||||
readability for numeric IPv6 addresses (e.g.
|
||||
@code{net:[2001:db8::42]:1337}).
|
||||
The remote endpoint is assumed to be a terminal or console server
|
||||
that connects the network stream to a local serial port where the
|
||||
actual programmer has been attached to.
|
||||
@@ -633,8 +561,6 @@ The port is assumed to be properly configured, for example using a
|
||||
transparent 8-bit data connection without parity at 115200 Baud
|
||||
for a STK500.
|
||||
|
||||
Note: The ability to handle IPv6 hostnames and addresses is limited to
|
||||
Posix systems (by now).
|
||||
|
||||
@item -q
|
||||
Disable (or quell) output of the progress bar while reading or writing
|
||||
@@ -972,7 +898,7 @@ Connection to the PICkit2 programmer:
|
||||
@item @code{OSI} @tab @code{AUX (6) }
|
||||
@end multitable
|
||||
|
||||
Extended command line parameters:
|
||||
Extended commandline parameters:
|
||||
@table @code
|
||||
@item @samp{clockrate=@var{rate}}
|
||||
Sets the SPI clocking rate in Hz (default is 100kHz). Alternately the -B or -i options can be used to set the period.
|
||||
@@ -980,32 +906,6 @@ Sets the SPI clocking rate in Hz (default is 100kHz). Alternately the -B or -i o
|
||||
Sets the timeout for USB reads and writes in milliseconds (default is 1500 ms).
|
||||
@end table
|
||||
|
||||
@item USBasp
|
||||
Extended parameters:
|
||||
@table @code
|
||||
@item @samp{section_config}
|
||||
Programmer will erase
|
||||
configuration section with option '-e' (chip erase),
|
||||
rather than entire chip.
|
||||
Only applicable to TPI devices (ATtiny 4/5/9/10/20/40).
|
||||
@end table
|
||||
|
||||
@item xbee
|
||||
Extended parameters:
|
||||
@table @code
|
||||
@item @samp{xbeeresetpin=@var{1..7}}
|
||||
Select the XBee pin @code{DIO<1..7>} that is connected to the MCU's
|
||||
‘/RESET’ line. The programmer needs to know which DIO pin to use to
|
||||
reset into the bootloader. The default (3) is the @code{DIO3} pin
|
||||
(XBee pin 17), but some commercial products use a different XBee
|
||||
pin.
|
||||
|
||||
The remaining two necessary XBee-to-MCU connections are not selectable
|
||||
- the XBee @code{DOUT} pin (pin 2) must be connected to the MCU's
|
||||
‘RXD’ line, and the XBee @code{DIN} pin (pin 3) must be connected to
|
||||
the MCU's ‘TXD’ line.
|
||||
@end table
|
||||
|
||||
@end table
|
||||
|
||||
@page
|
||||
@@ -1250,7 +1150,7 @@ Return to programming mode (from direct SPI mode).
|
||||
Change (when @var{level} is provided), or display the verbosity
|
||||
level.
|
||||
The initial verbosity level is controlled by the number of @code{-v} options
|
||||
given on the command line.
|
||||
given on the commandline.
|
||||
|
||||
@item ?
|
||||
@itemx help
|
||||
@@ -1429,7 +1329,7 @@ programmer work with AVRDUDE.
|
||||
|
||||
AVRDUDE first looks for a system wide configuration file in a platform
|
||||
dependent location. On Unix, this is usually
|
||||
@code{/usr/local/etc/avrdude.conf}, while on Windows it is usually in the
|
||||
@code{/usr/local/etc/avrdude.conf}, while on Windows it is usally in the
|
||||
same location as the executable file. The name of this file can be
|
||||
changed using the @option{-C} command line option. After the system wide
|
||||
configuration file is parsed, AVRDUDE looks for a per-user configuration
|
||||
@@ -1534,11 +1434,9 @@ Following programmer types are currently implemented:
|
||||
part
|
||||
id = <id> ; # quoted string
|
||||
desc = <description> ; # quoted string
|
||||
family_id = <description> ; # quoted string
|
||||
has_jtag = <yes/no> ; # part has JTAG i/f
|
||||
has_debugwire = <yes/no> ; # part has debugWire i/f
|
||||
has_pdi = <yes/no> ; # part has PDI i/f
|
||||
has_updi = <yes/no> ; # part has UPDI i/f
|
||||
has_tpi = <yes/no> ; # part has TPI i/f
|
||||
devicecode = <num> ; # numeric
|
||||
stk500_devcode = <num> ; # numeric
|
||||
@@ -1759,7 +1657,7 @@ flash pages of the application section.
|
||||
|
||||
Reading fuse and lock bits is fully supported.
|
||||
|
||||
Note that due to the inability to write the fuse bits, the safemode
|
||||
Note that due to the unability to write the fuse bits, the safemode
|
||||
functionality does not make sense for these boot loaders.
|
||||
|
||||
@end itemize
|
||||
@@ -1944,7 +1842,7 @@ The default location of the install is into @code{/usr/local} so you
|
||||
will need to be sure that @code{/usr/local/bin} is in your @code{PATH}
|
||||
environment variable.
|
||||
|
||||
If you do not have root access to your system, you can do the
|
||||
If you do not have root access to your system, you can do the the
|
||||
following instead:
|
||||
|
||||
@example
|
||||
@@ -1994,7 +1892,7 @@ obtained.
|
||||
@subsubsection Linux Installation
|
||||
|
||||
@noindent
|
||||
On rpm based Linux systems (such as RedHat, SUSE, Mandrake, etc.), you
|
||||
On rpm based Linux systems (such as RedHat, SUSE, Mandrake, etc), you
|
||||
can build and install the rpm binaries directly from the tarball:
|
||||
|
||||
@example
|
||||
@@ -2488,7 +2386,7 @@ be added to the @var{-P usb} option, similar to adding a serial number
|
||||
on other USB-based programmers.
|
||||
|
||||
The actual naming convention for the bus and device names is
|
||||
operating-system dependent; AVRDUDE will print out what it found
|
||||
operating-system dependant; AVRDUDE will print out what it found
|
||||
on the bus when running it with (at least) one @var{-v} option.
|
||||
By specifying a string that cannot match any existing device
|
||||
(for example, @var{-P usb:xxx}), the scan will list all possible
|
||||
|
||||
6
fileio.c
6
fileio.c
@@ -34,9 +34,7 @@
|
||||
#elif defined(HAVE_LIBELF_LIBELF_H)
|
||||
#include <libelf/libelf.h>
|
||||
#endif
|
||||
#ifndef EM_AVR32
|
||||
# define EM_AVR32 0x18ad /* inofficial */
|
||||
#endif
|
||||
#define EM_AVR32 0x18ad /* inofficial */
|
||||
#endif
|
||||
|
||||
#include "avrdude.h"
|
||||
@@ -1172,7 +1170,7 @@ static int fileio_ihex(struct fioparms * fio,
|
||||
break;
|
||||
|
||||
default:
|
||||
avrdude_message(MSG_INFO, "%s: invalid Intel Hex file I/O operation=%d\n",
|
||||
avrdude_message(MSG_INFO, "%s: invalid Intex Hex file I/O operation=%d\n",
|
||||
progname, fio->op);
|
||||
return -1;
|
||||
break;
|
||||
|
||||
583
ft245r.c
583
ft245r.c
@@ -59,7 +59,6 @@
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "libavrdude.h"
|
||||
@@ -68,11 +67,6 @@
|
||||
#include "ft245r.h"
|
||||
#include "usbdevs.h"
|
||||
|
||||
#include "tpi.h"
|
||||
|
||||
#define TPIPCR_GT_0b 0x07
|
||||
#define TPI_STOP_BITS 0x03
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
@@ -92,7 +86,25 @@
|
||||
#define DO_NOT_BUILD_FT245R
|
||||
#endif
|
||||
|
||||
#if defined(DO_NOT_BUILD_FT245R)
|
||||
#ifndef HAVE_PTHREAD_H
|
||||
|
||||
static int ft245r_nopthread_open (struct programmer_t *pgm, char * name) {
|
||||
avrdude_message(MSG_INFO, "%s: error: no pthread support. Please compile again with pthread installed."
|
||||
#if defined(_WIN32)
|
||||
" See http://sourceware.org/pthreads-win32/."
|
||||
#endif
|
||||
"\n",
|
||||
progname);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ft245r_initpgm(PROGRAMMER * pgm) {
|
||||
strcpy(pgm->type, "ftdi_syncbb");
|
||||
pgm->open = ft245r_nopthread_open;
|
||||
}
|
||||
|
||||
#elif defined(DO_NOT_BUILD_FT245R)
|
||||
|
||||
static int ft245r_noftdi_open (struct programmer_t *pgm, char * name) {
|
||||
avrdude_message(MSG_INFO, "%s: error: no libftdi or libusb support. Install libftdi1/libusb-1.0 or libftdi/libusb and run configure/make again.\n",
|
||||
@@ -108,183 +120,102 @@ void ft245r_initpgm(PROGRAMMER * pgm) {
|
||||
|
||||
#else
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
/* Mac OS X defines sem_init but actually does not implement them */
|
||||
#include <dispatch/dispatch.h>
|
||||
|
||||
typedef dispatch_semaphore_t sem_t;
|
||||
|
||||
#define sem_init(psem,x,val) *psem = dispatch_semaphore_create(val)
|
||||
#define sem_post(psem) dispatch_semaphore_signal(*psem)
|
||||
#define sem_wait(psem) dispatch_semaphore_wait(*psem, DISPATCH_TIME_FOREVER)
|
||||
#else
|
||||
#include <semaphore.h>
|
||||
#endif
|
||||
|
||||
#define FT245R_CYCLES 2
|
||||
#define FT245R_FRAGMENT_SIZE 512
|
||||
#define REQ_OUTSTANDINGS 10
|
||||
//#define USE_INLINE_WRITE_PAGE
|
||||
|
||||
#define FT245R_DEBUG 0
|
||||
/*
|
||||
Some revisions of the FTDI chips mess up the timing in bitbang mode
|
||||
unless the bitclock is set to the max (3MHz). For example, see:
|
||||
|
||||
http://www.ftdichip.com/Support/Documents/TechnicalNotes/TN_120_FT232R%20Errata%20Technical%20Note.pdf
|
||||
|
||||
To work around this problem, set the macro below to 1 to always set
|
||||
the bitclock to 3MHz and then issue the same byte repeatedly to get
|
||||
the desired timing.
|
||||
|
||||
*/
|
||||
#define FT245R_BITBANG_VARIABLE_PULSE_WIDTH_WORKAROUND 0
|
||||
|
||||
static struct ftdi_context *handle;
|
||||
|
||||
#if FT245R_BITBANG_VARIABLE_PULSE_WIDTH_WORKAROUND
|
||||
static unsigned int baud_multiplier;
|
||||
#else
|
||||
# define baud_multiplier 1 // this let's C compiler optimize
|
||||
#endif
|
||||
static unsigned char ft245r_ddr;
|
||||
static unsigned char ft245r_out;
|
||||
static unsigned char ft245r_in;
|
||||
|
||||
#define FT245R_BUFSIZE 0x2000 // receive buffer size
|
||||
#define FT245R_MIN_FIFO_SIZE 128 // min of FTDI RX/TX FIFO size
|
||||
#define BUFSIZE 0x2000
|
||||
|
||||
static struct {
|
||||
int len; // # of bytes in transmit buffer
|
||||
uint8_t buf[FT245R_MIN_FIFO_SIZE]; // transmit buffer
|
||||
} tx;
|
||||
// libftdi / libftd2xx compatibility functions.
|
||||
|
||||
static struct {
|
||||
int discard; // # of bytes to discard during read
|
||||
int pending; // # of bytes that have been written since last read
|
||||
int wr; // write pointer
|
||||
int rd; // read pointer
|
||||
uint8_t buf[FT245R_BUFSIZE]; // receive ring buffer
|
||||
} rx;
|
||||
static pthread_t readerthread;
|
||||
static sem_t buf_data, buf_space;
|
||||
static unsigned char buffer[BUFSIZE];
|
||||
static int head, tail;
|
||||
|
||||
static int ft245r_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
|
||||
unsigned char *res);
|
||||
static int ft245r_tpi_tx(PROGRAMMER * pgm, uint8_t byte);
|
||||
static int ft245r_tpi_rx(PROGRAMMER * pgm, uint8_t *bytep);
|
||||
static void add_to_buf (unsigned char c) {
|
||||
int nh;
|
||||
|
||||
// Discard all data from the receive buffer.
|
||||
static void ft245r_rx_buf_purge(PROGRAMMER * pgm) {
|
||||
rx.rd = rx.wr = 0;
|
||||
}
|
||||
sem_wait (&buf_space);
|
||||
if (head == (BUFSIZE -1)) nh = 0;
|
||||
else nh = head + 1;
|
||||
|
||||
static void ft245r_rx_buf_put(PROGRAMMER * pgm, uint8_t byte) {
|
||||
rx.buf[rx.wr++] = byte;
|
||||
if (rx.wr >= sizeof(rx.buf))
|
||||
rx.wr = 0;
|
||||
}
|
||||
|
||||
static uint8_t ft245r_rx_buf_get(PROGRAMMER * pgm) {
|
||||
uint8_t byte = rx.buf[rx.rd++];
|
||||
if (rx.rd >= sizeof(rx.buf))
|
||||
rx.rd = 0;
|
||||
return byte;
|
||||
}
|
||||
|
||||
/* Fill receive buffer with data from the FTDI receive FIFO. */
|
||||
static int ft245r_fill(PROGRAMMER * pgm) {
|
||||
uint8_t raw[FT245R_MIN_FIFO_SIZE];
|
||||
int i, nread;
|
||||
|
||||
nread = ftdi_read_data(handle, raw, rx.pending);
|
||||
if (nread < 0)
|
||||
return -1;
|
||||
rx.pending -= nread;
|
||||
#if FT245R_DEBUG
|
||||
avrdude_message(MSG_INFO, "%s: read %d bytes (pending=%d)\n",
|
||||
__func__, nread, rx.pending);
|
||||
#endif
|
||||
for (i = 0; i < nread; ++i)
|
||||
ft245r_rx_buf_put(pgm, raw[i]);
|
||||
return nread;
|
||||
}
|
||||
|
||||
/* Flush pending TX data to the FTDI send FIFO. */
|
||||
static int ft245r_flush(PROGRAMMER * pgm) {
|
||||
int rv, len = tx.len, avail;
|
||||
uint8_t *src = tx.buf;
|
||||
|
||||
if (!len)
|
||||
return 0;
|
||||
|
||||
while (len > 0) {
|
||||
avail = FT245R_MIN_FIFO_SIZE - rx.pending;
|
||||
if (avail <= 0) {
|
||||
avail = ft245r_fill(pgm);
|
||||
if (avail < 0) {
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: fill returned %d: %s\n",
|
||||
__func__, avail, ftdi_get_error_string(handle));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (avail > len)
|
||||
avail = len;
|
||||
|
||||
#if FT245R_DEBUG
|
||||
avrdude_message(MSG_INFO, "%s: writing %d bytes\n", __func__, avail);
|
||||
#endif
|
||||
rv = ftdi_write_data(handle, src, avail);
|
||||
if (rv != avail) {
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: write returned %d (expected %d): %s\n",
|
||||
__func__, rv, avail, ftdi_get_error_string(handle));
|
||||
return -1;
|
||||
}
|
||||
src += avail;
|
||||
len -= avail;
|
||||
rx.pending += avail;
|
||||
if (nh == tail) {
|
||||
avrdude_message(MSG_INFO, "buffer overflow. Cannot happen!\n");
|
||||
}
|
||||
tx.len = 0;
|
||||
return 0;
|
||||
buffer[head] = c;
|
||||
head = nh;
|
||||
sem_post (&buf_data);
|
||||
}
|
||||
|
||||
static int ft245r_send2(PROGRAMMER * pgm, unsigned char * buf, size_t len,
|
||||
bool discard_rx_data) {
|
||||
int i, j;
|
||||
static void *reader (void *arg) {
|
||||
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
|
||||
struct ftdi_context *handle = (struct ftdi_context *)(arg);
|
||||
unsigned char buf[0x1000];
|
||||
int br, i;
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
for (j = 0; j < baud_multiplier; ++j) {
|
||||
if (discard_rx_data)
|
||||
++rx.discard;
|
||||
tx.buf[tx.len++] = buf[i];
|
||||
if (tx.len >= FT245R_MIN_FIFO_SIZE)
|
||||
ft245r_flush(pgm);
|
||||
}
|
||||
while (1) {
|
||||
pthread_testcancel();
|
||||
br = ftdi_read_data (handle, buf, sizeof(buf));
|
||||
for (i=0; i<br; i++)
|
||||
add_to_buf (buf[i]);
|
||||
}
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int ft245r_send(PROGRAMMER * pgm, unsigned char * buf, size_t len) {
|
||||
return ft245r_send2(pgm, buf, len, false);
|
||||
}
|
||||
int rv;
|
||||
|
||||
static int ft245r_send_and_discard(PROGRAMMER * pgm, unsigned char * buf,
|
||||
size_t len) {
|
||||
return ft245r_send2(pgm, buf, len, true);
|
||||
rv = ftdi_write_data(handle, buf, len);
|
||||
if (len != rv) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ft245r_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len) {
|
||||
int i, j;
|
||||
int i;
|
||||
|
||||
ft245r_flush(pgm);
|
||||
ft245r_fill(pgm);
|
||||
|
||||
#if FT245R_DEBUG
|
||||
avrdude_message(MSG_INFO, "%s: discarding %d, consuming %zu bytes\n",
|
||||
__func__, rx.discard, len);
|
||||
#endif
|
||||
while (rx.discard > 0) {
|
||||
ft245r_rx_buf_get(pgm);
|
||||
--rx.discard;
|
||||
// Copy over data from the circular buffer..
|
||||
// XXX This should timeout, and return error if there isn't enough
|
||||
// data.
|
||||
for (i=0; i<len; i++) {
|
||||
sem_wait (&buf_data);
|
||||
buf[i] = buffer[tail];
|
||||
if (tail == (BUFSIZE -1)) tail = 0;
|
||||
else tail++;
|
||||
sem_post (&buf_space);
|
||||
}
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
buf[i] = ft245r_rx_buf_get(pgm);
|
||||
for (j = 1; j < baud_multiplier; ++j)
|
||||
ft245r_rx_buf_get(pgm);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ft245r_drain(PROGRAMMER * pgm, int display) {
|
||||
int r;
|
||||
unsigned char t;
|
||||
|
||||
// flush the buffer in the chip by changing the mode.....
|
||||
r = ftdi_set_bitmode(handle, 0, BITMODE_RESET); // reset
|
||||
@@ -293,25 +224,17 @@ static int ft245r_drain(PROGRAMMER * pgm, int display) {
|
||||
if (r) return -1;
|
||||
|
||||
// drain our buffer.
|
||||
ft245r_rx_buf_purge(pgm);
|
||||
while (head != tail) {
|
||||
ft245r_recv (pgm, &t, 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Ensure any pending writes are sent to the FTDI chip before sleeping. */
|
||||
static void ft245r_usleep(PROGRAMMER * pgm, useconds_t usec) {
|
||||
ft245r_flush(pgm);
|
||||
usleep(usec);
|
||||
}
|
||||
|
||||
|
||||
static int ft245r_chip_erase(PROGRAMMER * pgm, AVRPART * p) {
|
||||
unsigned char cmd[4] = {0,0,0,0};
|
||||
unsigned char res[4];
|
||||
|
||||
if (p->flags & AVRPART_HAS_TPI)
|
||||
return avr_tpi_chip_erase(pgm, p);
|
||||
|
||||
if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
|
||||
avrdude_message(MSG_INFO, "chip erase instruction not defined for part \"%s\"\n",
|
||||
p->desc);
|
||||
@@ -320,38 +243,29 @@ static int ft245r_chip_erase(PROGRAMMER * pgm, AVRPART * p) {
|
||||
|
||||
avr_set_bits(p->op[AVR_OP_CHIP_ERASE], cmd);
|
||||
pgm->cmd(pgm, cmd, res);
|
||||
ft245r_usleep(pgm, p->chip_erase_delay);
|
||||
usleep(p->chip_erase_delay);
|
||||
return pgm->initialize(pgm, p);
|
||||
}
|
||||
|
||||
|
||||
static int ft245r_set_bitclock(PROGRAMMER * pgm) {
|
||||
// libftdi1 multiplies bitbang baudrate by 4:
|
||||
int r, rate = 0, ftdi_rate = 3000000 / 4;
|
||||
int r;
|
||||
int rate = 0;
|
||||
|
||||
/* bitclock is second. 1us = 0.000001. Max rate for ft232r 750000 */
|
||||
if(pgm->bitclock) {
|
||||
rate = (uint32_t)(1.0/pgm->bitclock);
|
||||
rate = (uint32_t)(1.0/pgm->bitclock) * 2;
|
||||
} else if (pgm->baudrate) {
|
||||
rate = pgm->baudrate;
|
||||
rate = pgm->baudrate * 2;
|
||||
} else {
|
||||
rate = 150000; /* should work for all ftdi chips and the avr default internal clock of 1MHz */
|
||||
}
|
||||
|
||||
#if FT245R_BITBANG_VARIABLE_PULSE_WIDTH_WORKAROUND
|
||||
if (rate > 0 && rate < ftdi_rate)
|
||||
baud_multiplier = round((ftdi_rate + rate - 1) / rate);
|
||||
else
|
||||
baud_multiplier = 1;
|
||||
#else
|
||||
ftdi_rate = rate;
|
||||
#endif
|
||||
|
||||
avrdude_message(MSG_NOTICE2,
|
||||
"%s: bitclk %d -> FTDI rate %d, baud multiplier %d\n",
|
||||
__func__, rate, ftdi_rate, baud_multiplier);
|
||||
|
||||
r = ftdi_set_baudrate(handle, ftdi_rate);
|
||||
if (FT245R_DEBUG) {
|
||||
avrdude_message(MSG_NOTICE2, " ft245r: spi bitclk %d -> ft baudrate %d\n",
|
||||
rate / 2, rate);
|
||||
}
|
||||
r = ftdi_set_baudrate(handle, rate);
|
||||
if (r) {
|
||||
avrdude_message(MSG_INFO, "Set baudrate (%d) failed with error '%s'.\n",
|
||||
rate, ftdi_get_error_string (handle));
|
||||
@@ -360,18 +274,6 @@ static int ft245r_set_bitclock(PROGRAMMER * pgm) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_pin(PROGRAMMER *pgm, int pinname) {
|
||||
uint8_t byte;
|
||||
|
||||
ft245r_flush(pgm);
|
||||
|
||||
if (ftdi_read_pins(handle, &byte) != 0)
|
||||
return -1;
|
||||
if (FT245R_DEBUG)
|
||||
avrdude_message(MSG_INFO, "%s: in 0x%02x\n", __func__, byte);
|
||||
return GET_BITS_0(byte, pgm, pinname) != 0;
|
||||
}
|
||||
|
||||
static int set_pin(PROGRAMMER * pgm, int pinname, int val) {
|
||||
unsigned char buf[1];
|
||||
|
||||
@@ -383,7 +285,10 @@ static int set_pin(PROGRAMMER * pgm, int pinname, int val) {
|
||||
ft245r_out = SET_BITS_0(ft245r_out,pgm,pinname,val);
|
||||
buf[0] = ft245r_out;
|
||||
|
||||
ft245r_send_and_discard(pgm, buf, 1);
|
||||
ft245r_send (pgm, buf, 1);
|
||||
ft245r_recv (pgm, buf, 1);
|
||||
|
||||
ft245r_in = buf[0];
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -428,7 +333,7 @@ static int set_led_vfy(struct programmer_t * pgm, int value) {
|
||||
static void ft245r_powerup(PROGRAMMER * pgm)
|
||||
{
|
||||
set_vcc(pgm, ON); /* power up */
|
||||
ft245r_usleep(pgm, 100);
|
||||
usleep(100);
|
||||
}
|
||||
|
||||
|
||||
@@ -458,10 +363,12 @@ static void ft245r_enable(PROGRAMMER * pgm) {
|
||||
* and not via the buffer chip.
|
||||
*/
|
||||
set_reset(pgm, OFF);
|
||||
ft245r_usleep(pgm, 1);
|
||||
usleep(1);
|
||||
set_buff(pgm, ON);
|
||||
}
|
||||
|
||||
static int ft245r_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
|
||||
unsigned char *res);
|
||||
/*
|
||||
* issue the 'program enable' command to the AVR device
|
||||
*/
|
||||
@@ -470,9 +377,6 @@ static int ft245r_program_enable(PROGRAMMER * pgm, AVRPART * p) {
|
||||
unsigned char res[4];
|
||||
int i;
|
||||
|
||||
if (p->flags & AVRPART_HAS_TPI)
|
||||
return avr_tpi_program_enable(pgm, p, TPIPCR_GT_0b);
|
||||
|
||||
if (p->op[AVR_OP_PGM_ENABLE] == NULL) {
|
||||
avrdude_message(MSG_INFO, "%s: AVR_OP_PGM_ENABLE command not defined for %s\n",
|
||||
progname, p->desc);
|
||||
@@ -493,12 +397,12 @@ static int ft245r_program_enable(PROGRAMMER * pgm, AVRPART * p) {
|
||||
fflush(stderr);
|
||||
}
|
||||
set_pin(pgm, PIN_AVR_RESET, ON);
|
||||
ft245r_usleep(pgm, 20);
|
||||
usleep(20);
|
||||
set_pin(pgm, PIN_AVR_RESET, OFF);
|
||||
|
||||
if (i == 3) {
|
||||
ft245r_drain(pgm, 0);
|
||||
ft245r_rx_buf_purge(pgm);
|
||||
tail = head;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -523,83 +427,35 @@ static int ft245r_initialize(PROGRAMMER * pgm, AVRPART * p) {
|
||||
ft245r_powerup(pgm);
|
||||
|
||||
set_reset(pgm, OFF);
|
||||
ft245r_usleep(pgm, 5000); // 5ms
|
||||
usleep(5000); // 5ms
|
||||
set_reset(pgm, ON);
|
||||
ft245r_usleep(pgm, 5000); // 5ms
|
||||
usleep(5000); // 5ms
|
||||
set_reset(pgm, OFF);
|
||||
|
||||
/* Wait for at least 20 ms and enable serial programming by sending the Programming
|
||||
* Enable serial instruction to pin MOSI.
|
||||
*/
|
||||
ft245r_usleep(pgm, 20000); // 20ms
|
||||
usleep(20000); // 20ms
|
||||
|
||||
if (p->flags & AVRPART_HAS_TPI) {
|
||||
bool io_link_ok = true;
|
||||
uint8_t byte;
|
||||
int i;
|
||||
|
||||
/* Since there is a single TPIDATA line, MOSI and MISO must be
|
||||
linked together through a 1kOhm resistor. Verify that
|
||||
everything we send on MOSI gets mirrored back on MISO. */
|
||||
set_pin(pgm, PIN_AVR_MOSI, 0);
|
||||
if (get_pin(pgm, PIN_AVR_MISO) != 0) {
|
||||
io_link_ok = false;
|
||||
avrdude_message(MSG_INFO, "MOSI->MISO 0 failed\n");
|
||||
if (!ovsigck)
|
||||
return -1;
|
||||
}
|
||||
set_pin(pgm, PIN_AVR_MOSI, 1);
|
||||
if (get_pin(pgm, PIN_AVR_MISO) != 1) {
|
||||
io_link_ok = false;
|
||||
avrdude_message(MSG_INFO, "MOSI->MISO 1 failed\n");
|
||||
if (!ovsigck)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (io_link_ok)
|
||||
avrdude_message(MSG_NOTICE2, "MOSI-MISO link present\n");
|
||||
|
||||
/* keep TPIDATA high for 16 clock cycles */
|
||||
set_pin(pgm, PIN_AVR_MOSI, 1);
|
||||
for (i = 0; i < 16; i++) {
|
||||
set_sck(pgm, 1);
|
||||
set_sck(pgm, 0);
|
||||
}
|
||||
|
||||
/* remove extra guard timing bits */
|
||||
ft245r_tpi_tx(pgm, TPI_CMD_SSTCS | TPI_REG_TPIPCR);
|
||||
ft245r_tpi_tx(pgm, 0x7);
|
||||
|
||||
/* read TPI ident reg */
|
||||
ft245r_tpi_tx(pgm, TPI_CMD_SLDCS | TPI_REG_TPIIR);
|
||||
ft245r_tpi_rx(pgm, &byte);
|
||||
if (byte != 0x80) {
|
||||
avrdude_message(MSG_INFO, "TPIIR 0x%02x not correct\n", byte);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return ft245r_program_enable(pgm, p);
|
||||
}
|
||||
|
||||
static inline void add_bit(PROGRAMMER * pgm, unsigned char *buf, int *buf_pos,
|
||||
uint8_t bit) {
|
||||
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_MOSI, bit);
|
||||
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,0);
|
||||
buf[*buf_pos] = ft245r_out;
|
||||
(*buf_pos)++;
|
||||
|
||||
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,1);
|
||||
buf[*buf_pos] = ft245r_out;
|
||||
(*buf_pos)++;
|
||||
}
|
||||
|
||||
static inline int set_data(PROGRAMMER * pgm, unsigned char *buf, unsigned char data) {
|
||||
int j;
|
||||
int buf_pos = 0;
|
||||
unsigned char bit = 0x80;
|
||||
|
||||
for (j=0; j<8; j++) {
|
||||
add_bit(pgm, buf, &buf_pos, (data & bit) != 0);
|
||||
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_MOSI,data & bit);
|
||||
|
||||
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,0);
|
||||
buf[buf_pos] = ft245r_out;
|
||||
buf_pos++;
|
||||
|
||||
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,1);
|
||||
buf[buf_pos] = ft245r_out;
|
||||
buf_pos++;
|
||||
|
||||
bit >>= 1;
|
||||
}
|
||||
return buf_pos;
|
||||
@@ -607,8 +463,7 @@ static inline int set_data(PROGRAMMER * pgm, unsigned char *buf, unsigned char d
|
||||
|
||||
static inline unsigned char extract_data(PROGRAMMER * pgm, unsigned char *buf, int offset) {
|
||||
int j;
|
||||
int buf_pos = FT245R_CYCLES; /* MISO data is valid AFTER rising SCK edge,
|
||||
i.e. in next clock cycle */
|
||||
int buf_pos = 1;
|
||||
unsigned char bit = 0x80;
|
||||
unsigned char r = 0;
|
||||
|
||||
@@ -624,7 +479,6 @@ static inline unsigned char extract_data(PROGRAMMER * pgm, unsigned char *buf, i
|
||||
}
|
||||
|
||||
/* to check data */
|
||||
#if 0
|
||||
static inline unsigned char extract_data_out(PROGRAMMER * pgm, unsigned char *buf, int offset) {
|
||||
int j;
|
||||
int buf_pos = 1;
|
||||
@@ -641,7 +495,6 @@ static inline unsigned char extract_data_out(PROGRAMMER * pgm, unsigned char *bu
|
||||
}
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
@@ -670,122 +523,6 @@ static int ft245r_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline uint8_t extract_tpi_data(PROGRAMMER * pgm, unsigned char *buf,
|
||||
int *buf_pos) {
|
||||
uint8_t bit = 0x1, byte = 0;
|
||||
int j;
|
||||
|
||||
for (j = 0; j < 8; j++) {
|
||||
(*buf_pos)++; // skip over falling clock edge
|
||||
if (GET_BITS_0(buf[(*buf_pos)++], pgm, PIN_AVR_MISO))
|
||||
byte |= bit;
|
||||
bit <<= 1;
|
||||
}
|
||||
return byte;
|
||||
}
|
||||
|
||||
static inline int set_tpi_data(PROGRAMMER * pgm, unsigned char *buf,
|
||||
uint8_t byte) {
|
||||
uint8_t bit = 0x1, parity = 0;
|
||||
int j, buf_pos = 0;
|
||||
|
||||
// start bit:
|
||||
add_bit(pgm, buf, &buf_pos, 0);
|
||||
|
||||
// 8 data bits:
|
||||
for (j = 0; j < 8; j++) {
|
||||
add_bit(pgm, buf, &buf_pos, (byte & bit) != 0);
|
||||
parity ^= (byte & bit) != 0;
|
||||
bit <<= 1;
|
||||
}
|
||||
|
||||
// parity bit:
|
||||
add_bit(pgm, buf, &buf_pos, parity);
|
||||
// stop bits:
|
||||
add_bit(pgm, buf, &buf_pos, 1);
|
||||
add_bit(pgm, buf, &buf_pos, 1);
|
||||
return buf_pos;
|
||||
}
|
||||
|
||||
static int ft245r_tpi_tx(PROGRAMMER * pgm, uint8_t byte) {
|
||||
uint8_t buf[128];
|
||||
int len;
|
||||
|
||||
len = set_tpi_data(pgm, buf, byte);
|
||||
ft245r_send_and_discard(pgm, buf, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ft245r_tpi_rx(PROGRAMMER * pgm, uint8_t *bytep) {
|
||||
uint8_t buf[128], bit, parity;
|
||||
int i, buf_pos = 0, len = 0;
|
||||
uint32_t res, m, byte;
|
||||
|
||||
/* Allow for up to 4 bits before we must see start bit; during
|
||||
that time, we must keep the MOSI line high. */
|
||||
for (i = 0; i < 2; ++i)
|
||||
len += set_data(pgm, &buf[len], 0xff);
|
||||
|
||||
ft245r_send(pgm, buf, len);
|
||||
ft245r_recv(pgm, buf, len);
|
||||
|
||||
res = (extract_tpi_data(pgm, buf, &buf_pos)
|
||||
| ((uint32_t) extract_tpi_data(pgm, buf, &buf_pos) << 8));
|
||||
|
||||
/* Look for start bit: */
|
||||
m = 0x1;
|
||||
while (m & res)
|
||||
m <<= 1;
|
||||
if (m >= 0x10) {
|
||||
avrdude_message(MSG_INFO, "%s: start bit missing (res=0x%04x)\n",
|
||||
__func__, res);
|
||||
return -1;
|
||||
}
|
||||
byte = parity = 0;
|
||||
for (i = 0; i < 8; ++i) {
|
||||
m <<= 1;
|
||||
bit = (res & m) != 0;
|
||||
parity ^= bit;
|
||||
byte |= bit << i;
|
||||
}
|
||||
m <<= 1;
|
||||
if (((res & m) != 0) != parity) {
|
||||
avrdude_message(MSG_INFO, "%s: parity bit wrong\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
if (((res & (m << 1)) == 0) || ((res & (m << 2))) == 0) {
|
||||
avrdude_message(MSG_INFO, "%s: stop bits wrong\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
*bytep = (uint8_t) byte;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ft245r_cmd_tpi(PROGRAMMER * pgm, const unsigned char *cmd,
|
||||
int cmd_len, unsigned char *res, int res_len) {
|
||||
int i, ret = 0;
|
||||
|
||||
pgm->pgm_led(pgm, ON);
|
||||
|
||||
for (i = 0; i < cmd_len; ++i)
|
||||
ft245r_tpi_tx(pgm, cmd[i]);
|
||||
for (i = 0; i < res_len; ++i)
|
||||
if ((ret = ft245r_tpi_rx(pgm, &res[i])) < 0)
|
||||
break;
|
||||
if (verbose >= 2) {
|
||||
avrdude_message(MSG_NOTICE2, "%s: [ ", __func__);
|
||||
for (i = 0; i < cmd_len; i++)
|
||||
avrdude_message(MSG_NOTICE2, "%02X ", cmd[i]);
|
||||
avrdude_message(MSG_NOTICE2, "] [ ");
|
||||
for(i = 0; i < res_len; i++)
|
||||
avrdude_message(MSG_NOTICE2, "%02X ", res[i]);
|
||||
avrdude_message(MSG_NOTICE2, "]\n");
|
||||
}
|
||||
|
||||
pgm->pgm_led(pgm, OFF);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* lower 8 pins are accepted, they might be also inverted */
|
||||
static const struct pindef_t valid_pins = {{0xff},{0xff}} ;
|
||||
|
||||
@@ -800,10 +537,8 @@ static const struct pin_checklist_t pin_checklist[] = {
|
||||
static int ft245r_open(PROGRAMMER * pgm, char * port) {
|
||||
int rv;
|
||||
int devnum = -1;
|
||||
char device[9] = "";
|
||||
|
||||
rv = pins_check(pgm,pin_checklist,sizeof(pin_checklist)/sizeof(pin_checklist[0]), true);
|
||||
|
||||
if(rv) {
|
||||
pgm->display(pgm, progbuf);
|
||||
return rv;
|
||||
@@ -811,47 +546,22 @@ static int ft245r_open(PROGRAMMER * pgm, char * port) {
|
||||
|
||||
strcpy(pgm->port, port);
|
||||
|
||||
// read device string cut after 8 chars (max. length of serial number)
|
||||
if ((sscanf(port, "usb:%8s", device) != 1)) {
|
||||
avrdude_message(MSG_NOTICE,
|
||||
"%s: ft245r_open(): no device identifier in portname, using default\n",
|
||||
progname);
|
||||
pgm->usbsn[0] = 0;
|
||||
devnum = 0;
|
||||
if (strcmp(port,DEFAULT_USB) != 0) {
|
||||
if (strncasecmp("ft", port, 2) == 0) {
|
||||
char *startptr = port + 2;
|
||||
char *endptr = NULL;
|
||||
devnum = strtol(startptr,&endptr,10);
|
||||
if ((startptr==endptr) || (*endptr != '\0')) {
|
||||
devnum = -1;
|
||||
}
|
||||
}
|
||||
if (devnum < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: invalid portname '%s': use 'ft[0-9]+'\n",
|
||||
progname,port);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (strlen(device) == 8 ){ // serial number
|
||||
if (verbose >= 2) {
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: ft245r_open(): serial number parsed as: "
|
||||
"%s\n",
|
||||
progname,
|
||||
device);
|
||||
}
|
||||
// copy serial number to pgm struct
|
||||
strcpy(pgm->usbsn, device);
|
||||
// and use first device with matching serial (should be unique)
|
||||
devnum = 0;
|
||||
}
|
||||
else if (strncmp("ft", device, 2) || strlen(device) <= 8) { // classic device number
|
||||
char *startptr = device + 2;
|
||||
char *endptr = NULL;
|
||||
devnum = strtol(startptr,&endptr,10);
|
||||
if ((startptr==endptr) || (*endptr != '\0')) {
|
||||
devnum = -1;
|
||||
}
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: ft245r_open(): device number parsed as: "
|
||||
"%d\n",
|
||||
progname,
|
||||
devnum);
|
||||
}
|
||||
}
|
||||
|
||||
// if something went wrong before abort with helpful message
|
||||
if (devnum < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: ft245r_open(): invalid portname '%s': use^ 'ft[0-9]+' or serial number\n",
|
||||
progname,port);
|
||||
return -1;
|
||||
}
|
||||
|
||||
handle = malloc (sizeof (struct ftdi_context));
|
||||
@@ -873,8 +583,7 @@ static int ft245r_open(PROGRAMMER * pgm, char * port) {
|
||||
pgm->usbsn[0]?pgm->usbsn:NULL,
|
||||
devnum);
|
||||
if (rv) {
|
||||
avrdude_message(MSG_INFO, "%s: can't open ftdi device: %s\n",
|
||||
progname, ftdi_get_error_string(handle));
|
||||
avrdude_message(MSG_INFO, "can't open ftdi device %d. (%s)\n", devnum, ftdi_get_error_string(handle));
|
||||
goto cleanup_no_usb;
|
||||
}
|
||||
|
||||
@@ -902,13 +611,6 @@ static int ft245r_open(PROGRAMMER * pgm, char * port) {
|
||||
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_LED_VFY,0);
|
||||
|
||||
|
||||
rv = ftdi_set_latency_timer(handle, 1);
|
||||
if (rv) {
|
||||
avrdude_message(MSG_INFO, "%s: unable to set latency timer to 1 (%s)\n",
|
||||
progname, ftdi_get_error_string(handle));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
rv = ftdi_set_bitmode(handle, ft245r_ddr, BITMODE_SYNCBB); // set Synchronous BitBang
|
||||
if (rv) {
|
||||
avrdude_message(MSG_INFO, "%s: Synchronous BitBangMode is not supported (%s)\n",
|
||||
@@ -921,12 +623,22 @@ static int ft245r_open(PROGRAMMER * pgm, char * port) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* We start a new thread to read the output from the FTDI. This is
|
||||
* necessary because otherwise we'll deadlock. We cannot finish
|
||||
* writing because the ftdi cannot send the results because we
|
||||
* haven't provided a read buffer yet. */
|
||||
|
||||
sem_init (&buf_data, 0, 0);
|
||||
sem_init (&buf_space, 0, BUFSIZE);
|
||||
pthread_create (&readerthread, NULL, reader, handle);
|
||||
|
||||
/*
|
||||
* drain any extraneous input
|
||||
*/
|
||||
ft245r_drain (pgm, 0);
|
||||
|
||||
ft245r_send_and_discard(pgm, &ft245r_out, 1);
|
||||
ft245r_send (pgm, &ft245r_out, 1);
|
||||
ft245r_recv (pgm, &ft245r_in, 1);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -947,6 +659,8 @@ static void ft245r_close(PROGRAMMER * pgm) {
|
||||
ftdi_set_bitmode(handle, 0, BITMODE_RESET); // disable Synchronous BitBang
|
||||
ftdi_usb_close(handle);
|
||||
ftdi_deinit (handle);
|
||||
pthread_cancel(readerthread);
|
||||
pthread_join(readerthread, NULL);
|
||||
free(handle);
|
||||
handle = NULL;
|
||||
}
|
||||
@@ -1096,11 +810,6 @@ static int ft245r_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,0); // sck down
|
||||
buf[buf_pos++] = ft245r_out;
|
||||
}
|
||||
else {
|
||||
/* stretch sequence to allow correct readout, see extract_data() */
|
||||
buf[buf_pos] = buf[buf_pos - 1];
|
||||
buf_pos++;
|
||||
}
|
||||
ft245r_send(pgm, buf, buf_pos);
|
||||
put_request(addr_save, buf_pos, 0);
|
||||
//ft245r_sync(pgm);
|
||||
@@ -1118,7 +827,7 @@ static int ft245r_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
#if defined(USE_INLINE_WRITE_PAGE)
|
||||
while (do_request(pgm, m))
|
||||
;
|
||||
ft245r_usleep(pgm, m->max_write_delay);
|
||||
usleep(m->max_write_delay);
|
||||
#else
|
||||
int addr_wk = addr_save - (addr_save % m->page_size);
|
||||
int rc;
|
||||
@@ -1190,11 +899,6 @@ static int ft245r_paged_load_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,0); // sck down
|
||||
buf[buf_pos++] = ft245r_out;
|
||||
}
|
||||
else {
|
||||
/* stretch sequence to allow correct readout, see extract_data() */
|
||||
buf[buf_pos] = buf[buf_pos - 1];
|
||||
buf_pos++;
|
||||
}
|
||||
n = j;
|
||||
ft245r_send(pgm, buf, buf_pos);
|
||||
put_request(addr_save, buf_pos, n);
|
||||
@@ -1233,7 +937,6 @@ void ft245r_initpgm(PROGRAMMER * pgm) {
|
||||
pgm->program_enable = ft245r_program_enable;
|
||||
pgm->chip_erase = ft245r_chip_erase;
|
||||
pgm->cmd = ft245r_cmd;
|
||||
pgm->cmd_tpi = ft245r_cmd_tpi;
|
||||
pgm->open = ft245r_open;
|
||||
pgm->close = ft245r_close;
|
||||
pgm->read_byte = avr_read_byte_default;
|
||||
|
||||
625
jtag3.c
625
jtag3.c
@@ -30,7 +30,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
@@ -85,7 +84,6 @@ struct pdata
|
||||
#define PGM_FL_IS_PDI (0x0002)
|
||||
#define PGM_FL_IS_JTAG (0x0004)
|
||||
#define PGM_FL_IS_EDBG (0x0008)
|
||||
#define PGM_FL_IS_UPDI (0x0010)
|
||||
|
||||
static int jtag3_open(PROGRAMMER * pgm, char * port);
|
||||
static int jtag3_edbg_prepare(PROGRAMMER * pgm);
|
||||
@@ -162,11 +160,6 @@ u16_to_b2(unsigned char *b, unsigned short l)
|
||||
b[1] = (l >> 8) & 0xff;
|
||||
}
|
||||
|
||||
static bool matches(const char *s, const char *pat)
|
||||
{
|
||||
return strncmp(s, pat, strlen(pat)) == 0;
|
||||
}
|
||||
|
||||
static void jtag3_print_data(unsigned char *b, size_t s)
|
||||
{
|
||||
int i;
|
||||
@@ -453,66 +446,39 @@ static int jtag3_edbg_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
|
||||
avrdude_message(MSG_DEBUG, "\n%s: jtag3_edbg_send(): sending %lu bytes\n",
|
||||
progname, (unsigned long)len);
|
||||
|
||||
/* 4 bytes overhead for CMD, fragment #, and length info */
|
||||
int max_xfer = pgm->fd.usb.max_xfer;
|
||||
int nfragments = (len + max_xfer - 1) / max_xfer;
|
||||
if (nfragments > 1)
|
||||
if (len + 8 > USBDEV_MAX_XFER_3)
|
||||
{
|
||||
avrdude_message(MSG_DEBUG, "%s: jtag3_edbg_send(): fragmenting into %d packets\n",
|
||||
progname, nfragments);
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_send(): Fragmentation not (yet) implemented!\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
int frag;
|
||||
for (frag = 0; frag < nfragments; frag++)
|
||||
buf[0] = EDBG_VENDOR_AVR_CMD;
|
||||
buf[1] = (1 << 4) | 1; /* first out of a total of 1 fragments */
|
||||
buf[2] = (len + 4) >> 8;
|
||||
buf[3] = (len + 4) & 0xff;
|
||||
buf[4] = TOKEN;
|
||||
buf[5] = 0; /* dummy */
|
||||
u16_to_b2(buf + 6, PDATA(pgm)->command_sequence);
|
||||
memcpy(buf + 8, data, len);
|
||||
|
||||
if (serial_send(&pgm->fd, buf, USBDEV_MAX_XFER_3) != 0) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_send(): failed to send command to serial port\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
rv = serial_recv(&pgm->fd, status, USBDEV_MAX_XFER_3);
|
||||
|
||||
if (rv < 0) {
|
||||
/* timeout in receive */
|
||||
avrdude_message(MSG_NOTICE2, "%s: jtag3_edbg_send(): Timeout receiving packet\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
if (status[0] != EDBG_VENDOR_AVR_CMD || status[1] != 0x01)
|
||||
{
|
||||
int this_len;
|
||||
|
||||
/* All fragments have the (CMSIS-DAP layer) CMD, the fragment
|
||||
* identifier, and the length field. */
|
||||
buf[0] = EDBG_VENDOR_AVR_CMD;
|
||||
buf[1] = ((frag + 1) << 4) | nfragments;
|
||||
|
||||
if (frag == 0)
|
||||
{
|
||||
/* Only first fragment has TOKEN and seq#, thus four bytes
|
||||
* less payload than subsequent fragments. */
|
||||
this_len = len < max_xfer - 8? len: max_xfer - 8;
|
||||
buf[2] = (this_len + 4) >> 8;
|
||||
buf[3] = (this_len + 4) & 0xff;
|
||||
buf[4] = TOKEN;
|
||||
buf[5] = 0; /* dummy */
|
||||
u16_to_b2(buf + 6, PDATA(pgm)->command_sequence);
|
||||
memcpy(buf + 8, data, this_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
this_len = len < max_xfer - 4? len: max_xfer - 4;
|
||||
buf[2] = (this_len) >> 8;
|
||||
buf[3] = (this_len) & 0xff;
|
||||
memcpy(buf + 4, data, this_len);
|
||||
}
|
||||
|
||||
if (serial_send(&pgm->fd, buf, max_xfer) != 0) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_send(): failed to send command to serial port\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
rv = serial_recv(&pgm->fd, status, max_xfer);
|
||||
|
||||
if (rv < 0) {
|
||||
/* timeout in receive */
|
||||
avrdude_message(MSG_NOTICE2, "%s: jtag3_edbg_send(): Timeout receiving packet\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
if (status[0] != EDBG_VENDOR_AVR_CMD ||
|
||||
(frag == nfragments - 1 && status[1] != 0x01))
|
||||
{
|
||||
/* what to do in this case? */
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_send(): Unexpected response 0x%02x, 0x%02x\n",
|
||||
progname, status[0], status[1]);
|
||||
}
|
||||
data += this_len;
|
||||
len -= this_len;
|
||||
/* what to do in this case? */
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_send(): Unexpected response 0x%02x, 0x%02x\n",
|
||||
progname, status[0], status[1]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -535,13 +501,13 @@ static int jtag3_edbg_prepare(PROGRAMMER * pgm)
|
||||
|
||||
buf[0] = CMSISDAP_CMD_CONNECT;
|
||||
buf[1] = CMSISDAP_CONN_SWD;
|
||||
if (serial_send(&pgm->fd, buf, pgm->fd.usb.max_xfer) != 0) {
|
||||
if (serial_send(&pgm->fd, buf, USBDEV_MAX_XFER_3) != 0) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_prepare(): failed to send command to serial port\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
rv = serial_recv(&pgm->fd, status, pgm->fd.usb.max_xfer);
|
||||
if (rv != pgm->fd.usb.max_xfer) {
|
||||
rv = serial_recv(&pgm->fd, status, USBDEV_MAX_XFER_3);
|
||||
if (rv != USBDEV_MAX_XFER_3) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_prepare(): failed to read from serial port (%d)\n",
|
||||
progname, rv);
|
||||
return -1;
|
||||
@@ -556,13 +522,13 @@ static int jtag3_edbg_prepare(PROGRAMMER * pgm)
|
||||
buf[0] = CMSISDAP_CMD_LED;
|
||||
buf[1] = CMSISDAP_LED_CONNECT;
|
||||
buf[2] = 1;
|
||||
if (serial_send(&pgm->fd, buf, pgm->fd.usb.max_xfer) != 0) {
|
||||
if (serial_send(&pgm->fd, buf, USBDEV_MAX_XFER_3) != 0) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_prepare(): failed to send command to serial port\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
rv = serial_recv(&pgm->fd, status, pgm->fd.usb.max_xfer);
|
||||
if (rv != pgm->fd.usb.max_xfer) {
|
||||
rv = serial_recv(&pgm->fd, status, USBDEV_MAX_XFER_3);
|
||||
if (rv != USBDEV_MAX_XFER_3) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_prepare(): failed to read from serial port (%d)\n",
|
||||
progname, rv);
|
||||
return -1;
|
||||
@@ -594,13 +560,13 @@ static int jtag3_edbg_signoff(PROGRAMMER * pgm)
|
||||
buf[0] = CMSISDAP_CMD_LED;
|
||||
buf[1] = CMSISDAP_LED_CONNECT;
|
||||
buf[2] = 0;
|
||||
if (serial_send(&pgm->fd, buf, pgm->fd.usb.max_xfer) != 0) {
|
||||
if (serial_send(&pgm->fd, buf, USBDEV_MAX_XFER_3) != 0) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_signoff(): failed to send command to serial port\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
rv = serial_recv(&pgm->fd, status, pgm->fd.usb.max_xfer);
|
||||
if (rv != pgm->fd.usb.max_xfer) {
|
||||
rv = serial_recv(&pgm->fd, status, USBDEV_MAX_XFER_3);
|
||||
if (rv != USBDEV_MAX_XFER_3) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_signoff(): failed to read from serial port (%d)\n",
|
||||
progname, rv);
|
||||
return -1;
|
||||
@@ -611,13 +577,13 @@ static int jtag3_edbg_signoff(PROGRAMMER * pgm)
|
||||
progname, status[0], status[1]);
|
||||
|
||||
buf[0] = CMSISDAP_CMD_DISCONNECT;
|
||||
if (serial_send(&pgm->fd, buf, pgm->fd.usb.max_xfer) != 0) {
|
||||
if (serial_send(&pgm->fd, buf, USBDEV_MAX_XFER_3) != 0) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_signoff(): failed to send command to serial port\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
rv = serial_recv(&pgm->fd, status, pgm->fd.usb.max_xfer);
|
||||
if (rv != pgm->fd.usb.max_xfer) {
|
||||
rv = serial_recv(&pgm->fd, status, USBDEV_MAX_XFER_3);
|
||||
if (rv != USBDEV_MAX_XFER_3) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_signoff(): failed to read from serial port (%d)\n",
|
||||
progname, rv);
|
||||
return -1;
|
||||
@@ -678,9 +644,8 @@ static int jtag3_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
|
||||
}
|
||||
|
||||
static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
|
||||
int rv, len = 0;
|
||||
int rv, len;
|
||||
unsigned char *buf = NULL;
|
||||
unsigned char *request;
|
||||
|
||||
avrdude_message(MSG_TRACE, "%s: jtag3_edbg_recv():\n", progname);
|
||||
|
||||
@@ -689,105 +654,42 @@ static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
if ((request = malloc(pgm->fd.usb.max_xfer)) == NULL) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): out of memory\n",
|
||||
progname);
|
||||
|
||||
buf[0] = EDBG_VENDOR_AVR_RSP;
|
||||
|
||||
if (serial_send(&pgm->fd, buf, USBDEV_MAX_XFER_3) != 0) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): error sending CMSIS-DAP vendor command\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rv = serial_recv(&pgm->fd, buf, USBDEV_MAX_XFER_3);
|
||||
|
||||
if (rv < 0) {
|
||||
/* timeout in receive */
|
||||
avrdude_message(MSG_NOTICE2, "%s: jtag3_edbg_recv(): Timeout receiving packet\n",
|
||||
progname);
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buf[0] != EDBG_VENDOR_AVR_RSP ||
|
||||
buf[1] != ((1 << 4) | 1)) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): Unexpected response 0x%02x, 0x%02x\n",
|
||||
progname, buf[0], buf[1]);
|
||||
return -1;
|
||||
}
|
||||
/* calculate length from response; CMSIS-DAP response might be larger */
|
||||
len = (buf[2] << 8) | buf[3];
|
||||
if (len > rv + 4) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): Unexpected length value (%d > %d)\n",
|
||||
progname, len, rv + 4);
|
||||
len = rv + 4;
|
||||
}
|
||||
memmove(buf, buf + 4, len);
|
||||
|
||||
*msg = buf;
|
||||
|
||||
int nfrags = 0;
|
||||
int thisfrag = 0;
|
||||
|
||||
do {
|
||||
request[0] = EDBG_VENDOR_AVR_RSP;
|
||||
|
||||
if (serial_send(&pgm->fd, request, pgm->fd.usb.max_xfer) != 0) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): error sending CMSIS-DAP vendor command\n",
|
||||
progname);
|
||||
free(request);
|
||||
free(*msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rv = serial_recv(&pgm->fd, buf, pgm->fd.usb.max_xfer);
|
||||
|
||||
if (rv < 0) {
|
||||
/* timeout in receive */
|
||||
avrdude_message(MSG_NOTICE2, "%s: jtag3_edbg_recv(): Timeout receiving packet\n",
|
||||
progname);
|
||||
free(*msg);
|
||||
free(request);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buf[0] != EDBG_VENDOR_AVR_RSP) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): Unexpected response 0x%02x\n",
|
||||
progname, buf[0]);
|
||||
free(*msg);
|
||||
free(request);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buf[1] == 0) {
|
||||
// Documentation says:
|
||||
// "FragmentInfo 0x00 indicates that no response data is
|
||||
// available, and the rest of the packet is ignored."
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: jtag3_edbg_recv(): "
|
||||
"No response available\n",
|
||||
progname);
|
||||
free(*msg);
|
||||
free(request);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* calculate fragment information */
|
||||
if (thisfrag == 0) {
|
||||
/* first fragment */
|
||||
nfrags = buf[1] & 0x0F;
|
||||
thisfrag = 1;
|
||||
} else {
|
||||
if (nfrags != (buf[1] & 0x0F)) {
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: jtag3_edbg_recv(): "
|
||||
"Inconsistent # of fragments; had %d, now %d\n",
|
||||
progname, nfrags, (buf[1] & 0x0F));
|
||||
free(*msg);
|
||||
free(request);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (thisfrag != ((buf[1] >> 4) & 0x0F)) {
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: jtag3_edbg_recv(): "
|
||||
"Inconsistent fragment number; expect %d, got %d\n",
|
||||
progname, thisfrag, ((buf[1] >> 4) & 0x0F));
|
||||
free(*msg);
|
||||
free(request);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int thislen = (buf[2] << 8) | buf[3];
|
||||
if (thislen > rv + 4) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): Unexpected length value (%d > %d)\n",
|
||||
progname, thislen, rv + 4);
|
||||
thislen = rv + 4;
|
||||
}
|
||||
if (len + thislen > USBDEV_MAX_XFER_3) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): Length exceeds max size (%d > %d)\n",
|
||||
progname, len + thislen, USBDEV_MAX_XFER_3);
|
||||
thislen = USBDEV_MAX_XFER_3 - len;
|
||||
}
|
||||
memmove(buf, buf + 4, thislen);
|
||||
thisfrag++;
|
||||
len += thislen;
|
||||
buf += thislen;
|
||||
} while (thisfrag <= nfrags);
|
||||
|
||||
free(request);
|
||||
return len;
|
||||
}
|
||||
|
||||
@@ -859,18 +761,11 @@ int jtag3_recv(PROGRAMMER * pgm, unsigned char **msg) {
|
||||
|
||||
c = (*resp)[1];
|
||||
if ((c & RSP3_STATUS_MASK) != RSP3_OK) {
|
||||
if ((c == RSP3_FAILED) && ((*resp)[3] == RSP3_FAIL_OCD_LOCKED)) {
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: Device is locked! Chip erase required to unlock.\n",
|
||||
progname);
|
||||
} else {
|
||||
avrdude_message(MSG_INFO, "%s: bad response to %s command: 0x%02x\n",
|
||||
progname, descr, c);
|
||||
}
|
||||
status = (*resp)[3];
|
||||
avrdude_message(MSG_INFO, "%s: bad response to %s command: 0x%02x\n",
|
||||
progname, descr, c);
|
||||
free(*resp);
|
||||
resp = 0;
|
||||
return -status;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return status;
|
||||
@@ -883,13 +778,9 @@ int jtag3_getsync(PROGRAMMER * pgm, int mode) {
|
||||
|
||||
avrdude_message(MSG_DEBUG, "%s: jtag3_getsync()\n", progname);
|
||||
|
||||
/* 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) &&
|
||||
!matches(ldata(lfirst(pgm->id)), "xplainedmini")) {
|
||||
if (jtag3_edbg_prepare(pgm) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (pgm->flag & PGM_FL_IS_EDBG) {
|
||||
if (jtag3_edbg_prepare(pgm) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Get the sign-on information. */
|
||||
@@ -925,34 +816,6 @@ static int jtag3_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* UPDI 'unlock' -> 'enter progmode' with chip erase key
|
||||
*/
|
||||
static int jtag3_unlock_erase_key(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
unsigned char buf[8], *resp;
|
||||
|
||||
buf[0] = 1; /* Enable */
|
||||
if (jtag3_setparm(pgm, SCOPE_AVR, SET_GET_CTXT_OPTIONS, PARM3_OPT_CHIP_ERASE_TO_ENTER, buf, 1) < 0)
|
||||
return -1;
|
||||
|
||||
buf[0] = SCOPE_AVR;
|
||||
buf[1] = CMD3_ENTER_PROGMODE;
|
||||
buf[2] = 0;
|
||||
|
||||
if (jtag3_command(pgm, buf, 3, &resp, "enter progmode") < 0)
|
||||
return -1;
|
||||
PDATA(pgm)->prog_enabled = 1;
|
||||
|
||||
buf[0] = 0; /* Disable */
|
||||
if (jtag3_setparm(pgm, SCOPE_AVR, SET_GET_CTXT_OPTIONS, PARM3_OPT_CHIP_ERASE_TO_ENTER, buf, 1) < 0)
|
||||
return -1;
|
||||
|
||||
free(resp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* There is no chip erase functionality in debugWire mode.
|
||||
*/
|
||||
@@ -973,7 +836,6 @@ static int jtag3_program_enable_dummy(PROGRAMMER * pgm, AVRPART * p)
|
||||
static int jtag3_program_enable(PROGRAMMER * pgm)
|
||||
{
|
||||
unsigned char buf[3], *resp;
|
||||
int status;
|
||||
|
||||
if (PDATA(pgm)->prog_enabled)
|
||||
return 0;
|
||||
@@ -982,14 +844,14 @@ static int jtag3_program_enable(PROGRAMMER * pgm)
|
||||
buf[1] = CMD3_ENTER_PROGMODE;
|
||||
buf[2] = 0;
|
||||
|
||||
if ((status = jtag3_command(pgm, buf, 3, &resp, "enter progmode")) >= 0) {
|
||||
if (jtag3_command(pgm, buf, 3, &resp, "enter progmode") >= 0) {
|
||||
free(resp);
|
||||
PDATA(pgm)->prog_enabled = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return status;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int jtag3_program_disable(PROGRAMMER * pgm)
|
||||
@@ -1074,10 +936,6 @@ static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
ifname = "PDI";
|
||||
if (p->flags & AVRPART_HAS_PDI)
|
||||
conn = PARM3_CONN_PDI;
|
||||
} else if (pgm->flag & PGM_FL_IS_UPDI) {
|
||||
ifname = "UPDI";
|
||||
if (p->flags & AVRPART_HAS_UPDI)
|
||||
conn = PARM3_CONN_UPDI;
|
||||
} else {
|
||||
ifname = "JTAG";
|
||||
if (p->flags & AVRPART_HAS_JTAG)
|
||||
@@ -1092,8 +950,6 @@ static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
|
||||
if (p->flags & AVRPART_HAS_PDI)
|
||||
parm[0] = PARM3_ARCH_XMEGA;
|
||||
else if (p->flags & AVRPART_HAS_UPDI)
|
||||
parm[0] = PARM3_ARCH_UPDI;
|
||||
else if (p->flags & AVRPART_HAS_DW)
|
||||
parm[0] = PARM3_ARCH_TINY;
|
||||
else
|
||||
@@ -1109,7 +965,7 @@ static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
if (jtag3_setparm(pgm, SCOPE_AVR, 1, PARM3_CONNECTION, parm, 1) < 0)
|
||||
return -1;
|
||||
|
||||
if (conn == PARM3_CONN_PDI || conn == PARM3_CONN_UPDI)
|
||||
if (conn == PARM3_CONN_PDI)
|
||||
PDATA(pgm)->set_sck = jtag3_set_sck_xmega_pdi;
|
||||
else if (conn == PARM3_CONN_JTAG) {
|
||||
if (p->flags & AVRPART_HAS_PDI)
|
||||
@@ -1171,7 +1027,7 @@ static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
u32_to_b4(xd.nvm_boot_offset, m->offset);
|
||||
} else if (strcmp(m->desc, "fuse1") == 0) {
|
||||
u32_to_b4(xd.nvm_fuse_offset, m->offset & ~7);
|
||||
} else if (matches(m->desc, "lock")) {
|
||||
} else if (strncmp(m->desc, "lock", 4) == 0) {
|
||||
u32_to_b4(xd.nvm_lock_offset, m->offset);
|
||||
} else if (strcmp(m->desc, "usersig") == 0) {
|
||||
u32_to_b4(xd.nvm_user_sig_offset, m->offset);
|
||||
@@ -1185,99 +1041,6 @@ static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
if (jtag3_setparm(pgm, SCOPE_AVR, 2, PARM3_DEVICEDESC, (unsigned char *)&xd, sizeof xd) < 0)
|
||||
return -1;
|
||||
}
|
||||
else if ((p->flags & AVRPART_HAS_UPDI))
|
||||
{
|
||||
struct updi_device_desc xd;
|
||||
LNODEID ln;
|
||||
AVRMEM *m;
|
||||
|
||||
u16_to_b2(xd.nvm_base_addr, p->nvm_base);
|
||||
u16_to_b2(xd.ocd_base_addr, p->ocd_base);
|
||||
|
||||
for (ln = lfirst(p->mem); ln; ln = lnext(ln))
|
||||
{
|
||||
m = ldata(ln);
|
||||
if (strcmp(m->desc, "flash") == 0)
|
||||
{
|
||||
u16_to_b2(xd.prog_base, m->offset&0xFFFF);
|
||||
xd.prog_base_msb = m->offset>>16;
|
||||
|
||||
if (m->readsize != 0 && m->readsize < m->page_size)
|
||||
PDATA(pgm)->flash_pagesize = m->readsize;
|
||||
else
|
||||
PDATA(pgm)->flash_pagesize = m->page_size;
|
||||
xd.flash_page_size = m->page_size & 0xFF;
|
||||
xd.flash_page_size_msb = (m->page_size)>>8;
|
||||
|
||||
u32_to_b4(xd.flash_bytes, m->size);
|
||||
|
||||
if (m->offset > 0xFFFF)
|
||||
xd.address_mode = UPDI_ADDRESS_MODE_24BIT;
|
||||
else
|
||||
xd.address_mode = UPDI_ADDRESS_MODE_16BIT;
|
||||
}
|
||||
else if (strcmp(m->desc, "eeprom") == 0)
|
||||
{
|
||||
PDATA(pgm)->eeprom_pagesize = m->page_size;
|
||||
xd.eeprom_page_size = m->page_size;
|
||||
|
||||
u16_to_b2(xd.eeprom_bytes, m->size);
|
||||
u16_to_b2(xd.eeprom_base, m->offset);
|
||||
}
|
||||
else if (strcmp(m->desc, "usersig") == 0)
|
||||
{
|
||||
u16_to_b2(xd.user_sig_bytes, m->size);
|
||||
u16_to_b2(xd.user_sig_base, m->offset);
|
||||
}
|
||||
else if (strcmp(m->desc, "signature") == 0)
|
||||
{
|
||||
u16_to_b2(xd.signature_base, m->offset);
|
||||
xd.device_id[0] = p->signature[1];
|
||||
xd.device_id[1] = p->signature[2];
|
||||
}
|
||||
else if (strcmp(m->desc, "fuses") == 0)
|
||||
{
|
||||
xd.fuses_bytes = m->size;
|
||||
u16_to_b2(xd.fuses_base, m->offset);
|
||||
}
|
||||
else if (strcmp(m->desc, "lock") == 0)
|
||||
{
|
||||
u16_to_b2(xd.lockbits_base, m->offset);
|
||||
}
|
||||
}
|
||||
|
||||
u16_to_b2(xd.default_min_div1_voltage, DEFAULT_MINIMUM_CHARACTERISED_DIV1_VOLTAGE_MV);
|
||||
u16_to_b2(xd.default_min_div2_voltage, DEFAULT_MINIMUM_CHARACTERISED_DIV2_VOLTAGE_MV);
|
||||
u16_to_b2(xd.default_min_div4_voltage, DEFAULT_MINIMUM_CHARACTERISED_DIV4_VOLTAGE_MV);
|
||||
u16_to_b2(xd.default_min_div8_voltage, DEFAULT_MINIMUM_CHARACTERISED_DIV8_VOLTAGE_MV);
|
||||
u16_to_b2(xd.pdi_pad_fmax, MAX_FREQUENCY_SHARED_UPDI_PIN);
|
||||
xd.syscfg_offset = FUSES_SYSCFG0_OFFSET;
|
||||
xd.syscfg_write_mask_and = 0xFF;
|
||||
xd.syscfg_write_mask_or = 0x00;
|
||||
xd.syscfg_erase_mask_and = 0xFF;
|
||||
xd.syscfg_erase_mask_or = 0x00;
|
||||
|
||||
avrdude_message(MSG_NOTICE2, "UPDI SET: \n\t"
|
||||
"xd->prog_base_msb=%x\n\t"
|
||||
"xd->prog_base=%x %x\n\t"
|
||||
"xd->flash_page_size_msb=%x\n\t"
|
||||
"xd->flash_page_size=%x\n\t"
|
||||
"xd->eeprom_page_size=%x\n\t"
|
||||
"xd->nvmctrl=%x %x\n\t"
|
||||
"xd->ocd=%x %x\n\t",
|
||||
"xd->address_mode=%x\n",
|
||||
xd.prog_base_msb,
|
||||
xd.prog_base[0], xd.prog_base[1],
|
||||
xd.flash_page_size_msb,
|
||||
xd.flash_page_size,
|
||||
xd.eeprom_page_size,
|
||||
xd.nvm_base_addr[0], xd.nvm_base_addr[1],
|
||||
xd.ocd_base_addr[0], xd.ocd_base_addr[1],
|
||||
xd.address_mode);
|
||||
|
||||
if (jtag3_setparm(pgm, SCOPE_AVR, 2, PARM3_DEVICEDESC, (unsigned char *)&xd, sizeof xd) < 0)
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct mega_device_desc md;
|
||||
@@ -1360,28 +1123,17 @@ static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
}
|
||||
|
||||
/*
|
||||
* Depending on the target connection, there are three different
|
||||
* Depending on the target connection, there are two different
|
||||
* possible replies of the ICE. For a JTAG connection, the reply
|
||||
* format is RSP3_DATA, followed by 4 bytes of the JTAG ID read from
|
||||
* the device (followed by a trailing 0).
|
||||
* For a UPDI connection the reply format is RSP3_DATA, followed by
|
||||
* 4 bytes of the SIB Family_ID read from the device (followed by a
|
||||
* trailing 0).
|
||||
* For all other connections
|
||||
* the device (followed by a trailing 0). For all other connections
|
||||
* (except ISP which is handled completely differently, but that
|
||||
* doesn't apply here anyway), the response is just RSP_OK.
|
||||
*/
|
||||
if (resp[1] == RSP3_DATA && status >= 7) {
|
||||
if (p->flags & AVRPART_HAS_UPDI) {
|
||||
/* Partial Family_ID has been returned */
|
||||
avrdude_message(MSG_NOTICE, "%s: Partial Family_ID returned: \"%c%c%c%c\"\n",
|
||||
progname, resp[3], resp[4], resp[5], resp[6]);
|
||||
}
|
||||
else
|
||||
/* JTAG ID has been returned */
|
||||
avrdude_message(MSG_NOTICE, "%s: JTAG ID returned: 0x%02x 0x%02x 0x%02x 0x%02x\n",
|
||||
progname, resp[3], resp[4], resp[5], resp[6]);
|
||||
}
|
||||
if (resp[1] == RSP3_DATA && status >= 7)
|
||||
/* JTAG ID has been returned */
|
||||
avrdude_message(MSG_NOTICE, "%s: JTAG ID returned: 0x%02x 0x%02x 0x%02x 0x%02x\n",
|
||||
progname, resp[3], resp[4], resp[5], resp[6]);
|
||||
|
||||
free(resp);
|
||||
|
||||
@@ -1449,7 +1201,7 @@ static int jtag3_parseextparms(PROGRAMMER * pgm, LISTID extparms)
|
||||
for (ln = lfirst(extparms); ln; ln = lnext(ln)) {
|
||||
extended_param = ldata(ln);
|
||||
|
||||
if (matches(extended_param, "jtagchain=")) {
|
||||
if (strncmp(extended_param, "jtagchain=", strlen("jtagchain=")) == 0) {
|
||||
unsigned int ub, ua, bb, ba;
|
||||
if (sscanf(extended_param, "jtagchain=%u,%u,%u,%u", &ub, &ua, &bb, &ba)
|
||||
!= 4) {
|
||||
@@ -1484,17 +1236,18 @@ int jtag3_open_common(PROGRAMMER * pgm, char * port)
|
||||
LNODEID usbpid;
|
||||
int rv = -1;
|
||||
|
||||
#if !defined(HAVE_LIBUSB) && !defined(HAVE_LIBHIDAPI)
|
||||
avrdude_message(MSG_INFO, "avrdude was compiled without USB or HIDAPI support.\n");
|
||||
#if !defined(HAVE_LIBUSB)
|
||||
avrdude_message(MSG_INFO, "avrdude was compiled without usb support.\n");
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
if (!matches(port, "usb")) {
|
||||
if (strncmp(port, "usb", 3) != 0) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_open_common(): JTAGICE3/EDBG port names must start with \"usb\"\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
serdev = &usb_serdev_frame;
|
||||
if (pgm->usbvid)
|
||||
pinfo.usbinfo.vid = pgm->usbvid;
|
||||
else
|
||||
@@ -1504,42 +1257,17 @@ int jtag3_open_common(PROGRAMMER * pgm, char * port)
|
||||
if (lfirst(pgm->usbpid) == NULL)
|
||||
ladd(pgm->usbpid, (void *)USB_DEVICE_JTAGICE3);
|
||||
|
||||
#if defined(HAVE_LIBHIDAPI)
|
||||
/*
|
||||
* Try HIDAPI first. LibUSB is more generic, but might then cause
|
||||
* troubles for HID-class devices in some OSes (like Windows).
|
||||
*/
|
||||
serdev = &usbhid_serdev;
|
||||
for (usbpid = lfirst(pgm->usbpid); rv < 0 && usbpid != NULL; usbpid = lnext(usbpid)) {
|
||||
pinfo.usbinfo.flags = PINFO_FL_SILENT;
|
||||
pinfo.usbinfo.pid = *(int *)(ldata(usbpid));
|
||||
pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_3;
|
||||
pgm->fd.usb.rep = USBDEV_BULK_EP_READ_3;
|
||||
pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_3;
|
||||
pgm->fd.usb.eep = 0;
|
||||
pgm->fd.usb.eep = USBDEV_EVT_EP_READ_3;
|
||||
|
||||
strcpy(pgm->port, port);
|
||||
rv = serial_open(port, pinfo, &pgm->fd);
|
||||
}
|
||||
if (rv < 0) {
|
||||
#endif /* HAVE_LIBHIDAPI */
|
||||
#if defined(HAVE_LIBUSB)
|
||||
serdev = &usb_serdev_frame;
|
||||
for (usbpid = lfirst(pgm->usbpid); rv < 0 && usbpid != NULL; usbpid = lnext(usbpid)) {
|
||||
pinfo.usbinfo.flags = PINFO_FL_SILENT;
|
||||
pinfo.usbinfo.pid = *(int *)(ldata(usbpid));
|
||||
pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_3;
|
||||
pgm->fd.usb.rep = USBDEV_BULK_EP_READ_3;
|
||||
pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_3;
|
||||
pgm->fd.usb.eep = USBDEV_EVT_EP_READ_3;
|
||||
|
||||
strcpy(pgm->port, port);
|
||||
rv = serial_open(port, pinfo, &pgm->fd);
|
||||
}
|
||||
#endif /* HAVE_LIBUSB */
|
||||
#if defined(HAVE_LIBHIDAPI)
|
||||
}
|
||||
#endif
|
||||
if (rv < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_open_common(): Did not find any device matching VID 0x%04x and PID list: ",
|
||||
progname, (unsigned)pinfo.usbinfo.vid);
|
||||
@@ -1613,18 +1341,6 @@ static int jtag3_open_pdi(PROGRAMMER * pgm, char * port)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int jtag3_open_updi(PROGRAMMER * pgm, char * port)
|
||||
{
|
||||
avrdude_message(MSG_NOTICE2, "%s: jtag3_open_updi()\n", progname);
|
||||
|
||||
if (jtag3_open_common(pgm, port) < 0)
|
||||
return -1;
|
||||
|
||||
if (jtag3_getsync(pgm, PARM3_CONN_UPDI) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void jtag3_close(PROGRAMMER * pgm)
|
||||
{
|
||||
@@ -1645,12 +1361,8 @@ void jtag3_close(PROGRAMMER * pgm)
|
||||
if (jtag3_command(pgm, buf, 4, &resp, "sign-off") >= 0)
|
||||
free(resp);
|
||||
|
||||
/* 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) &&
|
||||
!matches(ldata(lfirst(pgm->id)), "xplainedmini")) {
|
||||
jtag3_edbg_signoff(pgm);
|
||||
}
|
||||
if (pgm->flag & PGM_FL_IS_EDBG)
|
||||
jtag3_edbg_signoff(pgm);
|
||||
|
||||
serial_close(&pgm->fd);
|
||||
pgm->fd.ifd = -1;
|
||||
@@ -1712,13 +1424,8 @@ static int jtag3_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
int status, dynamic_memtype = 0;
|
||||
long otimeout = serial_recv_timeout;
|
||||
|
||||
avrdude_message(MSG_NOTICE2, "%s: jtag3_paged_write(.., %s, %d, 0x%lx, %d)\n",
|
||||
progname, m->desc, page_size, addr, n_bytes);
|
||||
|
||||
block_size = jtag3_memaddr(pgm, p, m, addr);
|
||||
if(block_size != addr)
|
||||
avrdude_message(MSG_NOTICE2, " mapped to address: 0x%lx\n", block_size);
|
||||
block_size = 0;
|
||||
avrdude_message(MSG_NOTICE2, "%s: jtag3_paged_write(.., %s, %d, %d)\n",
|
||||
progname, m->desc, page_size, n_bytes);
|
||||
|
||||
if (!(pgm->flag & PGM_FL_IS_DW) && jtag3_program_enable(pgm) < 0)
|
||||
return -1;
|
||||
@@ -1762,7 +1469,7 @@ static int jtag3_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
cmd[3] = MTYPE_USERSIG;
|
||||
} else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
|
||||
cmd[3] = MTYPE_BOOT_FLASH;
|
||||
} else if ( p->flags & AVRPART_HAS_PDI || p->flags & AVRPART_HAS_UPDI ) {
|
||||
} else if ( p->flags & AVRPART_HAS_PDI ) {
|
||||
cmd[3] = MTYPE_FLASH;
|
||||
} else {
|
||||
cmd[3] = MTYPE_SPM;
|
||||
@@ -1821,13 +1528,8 @@ static int jtag3_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
int status, dynamic_memtype = 0;
|
||||
long otimeout = serial_recv_timeout;
|
||||
|
||||
avrdude_message(MSG_NOTICE2, "%s: jtag3_paged_load(.., %s, %d, 0x%lx, %d)\n",
|
||||
progname, m->desc, page_size, addr, n_bytes);
|
||||
|
||||
block_size = jtag3_memaddr(pgm, p, m, addr);
|
||||
if(block_size != addr)
|
||||
avrdude_message(MSG_NOTICE2, " mapped to address: 0x%lx\n", block_size);
|
||||
block_size = 0;
|
||||
avrdude_message(MSG_NOTICE2, "%s: jtag3_paged_load(.., %s, %d, %d)\n",
|
||||
progname, m->desc, page_size, n_bytes);
|
||||
|
||||
if (!(pgm->flag & PGM_FL_IS_DW) && jtag3_program_enable(pgm) < 0)
|
||||
return -1;
|
||||
@@ -1844,7 +1546,7 @@ static int jtag3_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
/* dynamically decide between flash/boot memtype */
|
||||
dynamic_memtype = 1;
|
||||
} else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
cmd[3] = ( p->flags & AVRPART_HAS_PDI || p->flags & AVRPART_HAS_UPDI ) ? MTYPE_EEPROM : MTYPE_EEPROM_PAGE;
|
||||
cmd[3] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_EEPROM : MTYPE_EEPROM_PAGE;
|
||||
if (pgm->flag & PGM_FL_IS_DW)
|
||||
return -1;
|
||||
} else if ( ( strcmp(m->desc, "prodsig") == 0 ) ) {
|
||||
@@ -1855,8 +1557,6 @@ static int jtag3_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
cmd[3] = MTYPE_BOOT_FLASH;
|
||||
} else if ( p->flags & AVRPART_HAS_PDI ) {
|
||||
cmd[3] = MTYPE_FLASH;
|
||||
} else if ( p->flags & AVRPART_HAS_UPDI ) {
|
||||
cmd[3] = MTYPE_SRAM;
|
||||
} else {
|
||||
cmd[3] = MTYPE_SPM;
|
||||
}
|
||||
@@ -1907,20 +1607,14 @@ static int jtag3_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
avrdude_message(MSG_NOTICE2, "%s: jtag3_read_byte(.., %s, 0x%lx, ...)\n",
|
||||
progname, mem->desc, addr);
|
||||
|
||||
paddr = jtag3_memaddr(pgm, p, mem, addr);
|
||||
if(paddr != addr)
|
||||
avrdude_message(MSG_NOTICE2, " mapped to address: 0x%lx\n", paddr);
|
||||
paddr = 0;
|
||||
|
||||
if (!(pgm->flag & PGM_FL_IS_DW))
|
||||
if ((status = jtag3_program_enable(pgm)) < 0)
|
||||
return status;
|
||||
if (!(pgm->flag & PGM_FL_IS_DW) && jtag3_program_enable(pgm) < 0)
|
||||
return -1;
|
||||
|
||||
cmd[0] = SCOPE_AVR;
|
||||
cmd[1] = CMD3_READ_MEMORY;
|
||||
cmd[2] = 0;
|
||||
|
||||
cmd[3] = ( p->flags & AVRPART_HAS_PDI || p->flags & AVRPART_HAS_UPDI ) ? MTYPE_FLASH : MTYPE_FLASH_PAGE;
|
||||
cmd[3] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_FLASH : MTYPE_FLASH_PAGE;
|
||||
if (strcmp(mem->desc, "flash") == 0 ||
|
||||
strcmp(mem->desc, "application") == 0 ||
|
||||
strcmp(mem->desc, "apptable") == 0 ||
|
||||
@@ -1931,7 +1625,7 @@ static int jtag3_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
paddr_ptr = &PDATA(pgm)->flash_pageaddr;
|
||||
cache_ptr = PDATA(pgm)->flash_pagecache;
|
||||
} else if (strcmp(mem->desc, "eeprom") == 0) {
|
||||
if ( (pgm->flag & PGM_FL_IS_DW) || ( p->flags & AVRPART_HAS_PDI ) || ( p->flags & AVRPART_HAS_UPDI ) ) {
|
||||
if ( (pgm->flag & PGM_FL_IS_DW) || ( p->flags & AVRPART_HAS_PDI ) ) {
|
||||
cmd[3] = MTYPE_EEPROM;
|
||||
} else {
|
||||
cmd[3] = MTYPE_EEPROM_PAGE;
|
||||
@@ -1955,14 +1649,13 @@ static int jtag3_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
addr = 2;
|
||||
if (pgm->flag & PGM_FL_IS_DW)
|
||||
unsupp = 1;
|
||||
} else if (matches(mem->desc, "lock")) {
|
||||
} else if (strncmp(mem->desc, "lock", 4) == 0) {
|
||||
cmd[3] = MTYPE_LOCK_BITS;
|
||||
if (pgm->flag & PGM_FL_IS_DW)
|
||||
unsupp = 1;
|
||||
} else if (matches(mem->desc, "fuse")) {
|
||||
} else if (strncmp(mem->desc, "fuse", strlen("fuse")) == 0) {
|
||||
cmd[3] = MTYPE_FUSE_BITS;
|
||||
if (!(p->flags & AVRPART_HAS_UPDI))
|
||||
addr = mem->offset & 7;
|
||||
addr = mem->offset & 7;
|
||||
} else if (strcmp(mem->desc, "usersig") == 0) {
|
||||
cmd[3] = MTYPE_USERSIG;
|
||||
} else if (strcmp(mem->desc, "prodsig") == 0) {
|
||||
@@ -1983,11 +1676,11 @@ static int jtag3_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
* harm for other connection types either.
|
||||
*/
|
||||
u32_to_b4(cmd + 8, 3);
|
||||
u32_to_b4(cmd + 4, jtag3_memaddr(pgm, p, mem, addr));
|
||||
u32_to_b4(cmd + 4, 0);
|
||||
|
||||
if (addr == 0) {
|
||||
if ((status = jtag3_command(pgm, cmd, 12, &resp, "read memory")) < 0)
|
||||
return status;
|
||||
return -1;
|
||||
|
||||
signature_cache[0] = resp[4];
|
||||
signature_cache[1] = resp[5];
|
||||
@@ -2029,15 +1722,14 @@ static int jtag3_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
|
||||
if (pagesize) {
|
||||
u32_to_b4(cmd + 8, pagesize);
|
||||
u32_to_b4(cmd + 4, jtag3_memaddr(pgm, p, mem, paddr));
|
||||
|
||||
u32_to_b4(cmd + 4, paddr);
|
||||
} else {
|
||||
u32_to_b4(cmd + 8, 1);
|
||||
u32_to_b4(cmd + 4, jtag3_memaddr(pgm, p, mem, addr));
|
||||
u32_to_b4(cmd + 4, addr);
|
||||
}
|
||||
|
||||
if ((status = jtag3_command(pgm, cmd, 12, &resp, "read memory")) < 0)
|
||||
return status;
|
||||
return -1;
|
||||
|
||||
if (resp[1] != RSP3_DATA ||
|
||||
status < (pagesize? pagesize: 1) + 4) {
|
||||
@@ -2066,19 +1758,14 @@ static int jtag3_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned char *cache_ptr = 0;
|
||||
int status, unsupp = 0;
|
||||
unsigned int pagesize = 0;
|
||||
unsigned long mapped_addr;
|
||||
|
||||
avrdude_message(MSG_NOTICE2, "%s: jtag3_write_byte(.., %s, 0x%lx, ...)\n",
|
||||
progname, mem->desc, addr);
|
||||
|
||||
mapped_addr = jtag3_memaddr(pgm, p, mem, addr);
|
||||
if(mapped_addr != addr)
|
||||
avrdude_message(MSG_NOTICE2, " mapped to address: 0x%lx\n", mapped_addr);
|
||||
|
||||
cmd[0] = SCOPE_AVR;
|
||||
cmd[1] = CMD3_WRITE_MEMORY;
|
||||
cmd[2] = 0;
|
||||
cmd[3] = ( p->flags & AVRPART_HAS_PDI || p->flags & AVRPART_HAS_UPDI ) ? MTYPE_FLASH : MTYPE_SPM;
|
||||
cmd[3] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_FLASH : MTYPE_SPM;
|
||||
if (strcmp(mem->desc, "flash") == 0) {
|
||||
cache_ptr = PDATA(pgm)->flash_pagecache;
|
||||
pagesize = PDATA(pgm)->flash_pagesize;
|
||||
@@ -2108,15 +1795,14 @@ static int jtag3_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
addr = 2;
|
||||
if (pgm->flag & PGM_FL_IS_DW)
|
||||
unsupp = 1;
|
||||
} else if (matches(mem->desc, "fuse")) {
|
||||
} else if (strncmp(mem->desc, "fuse", strlen("fuse")) == 0) {
|
||||
cmd[3] = MTYPE_FUSE_BITS;
|
||||
if (!(p->flags & AVRPART_HAS_UPDI))
|
||||
addr = mem->offset & 7;
|
||||
addr = mem->offset & 7;
|
||||
} else if (strcmp(mem->desc, "usersig") == 0) {
|
||||
cmd[3] = MTYPE_USERSIG;
|
||||
} else if (strcmp(mem->desc, "prodsig") == 0) {
|
||||
cmd[3] = MTYPE_PRODSIG;
|
||||
} else if (matches(mem->desc, "lock")) {
|
||||
} else if (strncmp(mem->desc, "lock", 4) == 0) {
|
||||
cmd[3] = MTYPE_LOCK_BITS;
|
||||
if (pgm->flag & PGM_FL_IS_DW)
|
||||
unsupp = 1;
|
||||
@@ -2159,12 +1845,12 @@ static int jtag3_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
return -1;
|
||||
|
||||
u32_to_b4(cmd + 8, 1);
|
||||
u32_to_b4(cmd + 4, jtag3_memaddr(pgm, p, mem, addr));
|
||||
u32_to_b4(cmd + 4, addr);
|
||||
cmd[12] = 0;
|
||||
cmd[13] = data;
|
||||
|
||||
if ((status = jtag3_command(pgm, cmd, 14, &resp, "write memory")) < 0)
|
||||
return status;
|
||||
return -1;
|
||||
|
||||
free(resp);
|
||||
|
||||
@@ -2281,28 +1967,6 @@ int jtag3_setparm(PROGRAMMER * pgm, unsigned char scope,
|
||||
return status;
|
||||
}
|
||||
|
||||
int jtag3_read_sib(PROGRAMMER * pgm, AVRPART * p, char * sib)
|
||||
{
|
||||
int status;
|
||||
unsigned char cmd[12];
|
||||
unsigned char *resp = NULL;
|
||||
|
||||
cmd[0] = SCOPE_AVR;
|
||||
cmd[1] = CMD3_READ_MEMORY;
|
||||
cmd[2] = 0;
|
||||
cmd[3] = MTYPE_SIB;
|
||||
u32_to_b4(cmd + 4, 0);
|
||||
u32_to_b4(cmd + 8, AVR_SIBLEN);
|
||||
|
||||
if ((status = jtag3_command(pgm, cmd, 12, &resp, "read SIB")) < 0)
|
||||
return status;
|
||||
|
||||
memcpy(sib, resp+3, AVR_SIBLEN);
|
||||
sib[AVR_SIBLEN] = 0; // Zero terminate string
|
||||
avrdude_message(MSG_DEBUG, "%s: jtag3_read_sib(): Received SIB: \"%s\"\n", progname, sib);
|
||||
free(resp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void jtag3_display(PROGRAMMER * pgm, const char * p)
|
||||
{
|
||||
@@ -2413,17 +2077,6 @@ static unsigned int jtag3_memaddr(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, uns
|
||||
/*
|
||||
* Non-Xmega device.
|
||||
*/
|
||||
if (p->flags & AVRPART_HAS_UPDI) {
|
||||
if (strcmp(m->desc, "fuses") == 0) {
|
||||
addr += m->offset;
|
||||
}
|
||||
else if (matches(m->desc, "fuse")) {
|
||||
addr = m->offset;
|
||||
}
|
||||
else if (strcmp(m->desc, "flash") != 0) {
|
||||
addr += m->offset;
|
||||
}
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
@@ -2529,39 +2182,3 @@ void jtag3_pdi_initpgm(PROGRAMMER * pgm)
|
||||
pgm->flag = PGM_FL_IS_PDI;
|
||||
}
|
||||
|
||||
const char jtag3_updi_desc[] = "Atmel JTAGICE3 in UPDI mode";
|
||||
|
||||
void jtag3_updi_initpgm(PROGRAMMER * pgm)
|
||||
{
|
||||
strcpy(pgm->type, "JTAGICE3_UPDI");
|
||||
|
||||
/*
|
||||
* mandatory functions
|
||||
*/
|
||||
pgm->initialize = jtag3_initialize;
|
||||
pgm->display = jtag3_display;
|
||||
pgm->enable = jtag3_enable;
|
||||
pgm->disable = jtag3_disable;
|
||||
pgm->program_enable = jtag3_program_enable_dummy;
|
||||
pgm->chip_erase = jtag3_chip_erase;
|
||||
pgm->open = jtag3_open_updi;
|
||||
pgm->close = jtag3_close;
|
||||
pgm->read_byte = jtag3_read_byte;
|
||||
pgm->write_byte = jtag3_write_byte;
|
||||
|
||||
/*
|
||||
* optional functions
|
||||
*/
|
||||
pgm->paged_write = jtag3_paged_write;
|
||||
pgm->paged_load = jtag3_paged_load;
|
||||
pgm->page_erase = jtag3_page_erase;
|
||||
pgm->print_parms = jtag3_print_parms;
|
||||
pgm->set_sck_period = jtag3_set_sck_period;
|
||||
pgm->setup = jtag3_setup;
|
||||
pgm->teardown = jtag3_teardown;
|
||||
pgm->page_size = 256;
|
||||
pgm->flag = PGM_FL_IS_UPDI;
|
||||
pgm->unlock = jtag3_unlock_erase_key;
|
||||
pgm->read_sib = jtag3_read_sib;
|
||||
}
|
||||
|
||||
|
||||
2
jtag3.h
2
jtag3.h
@@ -41,11 +41,9 @@ int jtag3_command(PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen,
|
||||
extern const char jtag3_desc[];
|
||||
extern const char jtag3_dw_desc[];
|
||||
extern const char jtag3_pdi_desc[];
|
||||
extern const char jtag3_updi_desc[];
|
||||
void jtag3_initpgm (PROGRAMMER * pgm);
|
||||
void jtag3_dw_initpgm (PROGRAMMER * pgm);
|
||||
void jtag3_pdi_initpgm (PROGRAMMER * pgm);
|
||||
void jtag3_updi_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
/*
|
||||
* These functions are referenced from stk500v2.c for JTAGICE3 in
|
||||
|
||||
@@ -109,7 +109,6 @@
|
||||
#define CMD3_GET_PARAMETER 0x02
|
||||
#define CMD3_SIGN_ON 0x10
|
||||
#define CMD3_SIGN_OFF 0x11 /* takes one parameter? */
|
||||
#define CMD3_GET_ID 0x12
|
||||
#define CMD3_START_DW_DEBUG 0x13
|
||||
#define CMD3_MONCON_DISABLE 0x17
|
||||
|
||||
@@ -144,7 +143,6 @@
|
||||
# define RSP3_FAIL_WRONG_MODE 0x32 /* progmode vs. non-prog */
|
||||
# define RSP3_FAIL_UNSUPP_MEMORY 0x34 /* unsupported memory type */
|
||||
# define RSP3_FAIL_WRONG_LENGTH 0x35 /* wrong lenth for mem access */
|
||||
# define RSP3_FAIL_OCD_LOCKED 0x44 /* device is locked */
|
||||
# define RSP3_FAIL_NOT_UNDERSTOOD 0x91
|
||||
|
||||
/* ICE events */
|
||||
@@ -167,16 +165,6 @@
|
||||
#define MTYPE_EEPROM_XMEGA 0xc4 /* xmega EEPROM in debug mode - undocumented in AVR067 */
|
||||
#define MTYPE_USERSIG 0xc5 /* xmega user signature - undocumented in AVR067 */
|
||||
#define MTYPE_PRODSIG 0xc6 /* xmega production signature - undocumented in AVR067 */
|
||||
#define MTYPE_SIB 0xD3 /* AVR8X System Information Block */
|
||||
|
||||
/*
|
||||
* SET and GET context definitions
|
||||
*/
|
||||
#define SET_GET_CTXT_CONFIG 0x00 /* Configuration */
|
||||
#define SET_GET_CTXT_PHYSICAL 0x01 /* Physical interface related */
|
||||
#define SET_GET_CTXT_DEVICE 0x02 /* Device specific settings */
|
||||
#define SET_GET_CTXT_OPTIONS 0x03 /* Option-related settings */
|
||||
#define SET_GET_CTXT_SESSION 0x04 /* Session-related settings */
|
||||
|
||||
/*
|
||||
* Parameters are divided into sections, where the section number
|
||||
@@ -201,7 +189,6 @@
|
||||
# define PARM3_ARCH_TINY 1 /* also small megaAVR with ISP/DW only */
|
||||
# define PARM3_ARCH_MEGA 2
|
||||
# define PARM3_ARCH_XMEGA 3
|
||||
# define PARM3_ARCH_UPDI 5 /* AVR devices with UPDI i/f */
|
||||
|
||||
#define PARM3_SESS_PURPOSE 0x01 /* section 0, AVR scope, 1 byte */
|
||||
# define PARM3_SESS_PROGRAMMING 1
|
||||
@@ -212,26 +199,18 @@
|
||||
# define PARM3_CONN_JTAG 4
|
||||
# define PARM3_CONN_DW 5
|
||||
# define PARM3_CONN_PDI 6
|
||||
# define PARM3_CONN_UPDI 8
|
||||
|
||||
|
||||
#define PARM3_JTAGCHAIN 0x01 /* JTAG chain info, AVR scope (units
|
||||
* before/after, bits before/after), 4
|
||||
* bytes */
|
||||
|
||||
/*
|
||||
* Physical context parameters
|
||||
*/
|
||||
#define PARM3_CLK_MEGA_PROG 0x20 /* section 1, AVR scope, 2 bytes (kHz) */
|
||||
#define PARM3_CLK_MEGA_DEBUG 0x21 /* section 1, AVR scope, 2 bytes (kHz) */
|
||||
#define PARM3_CLK_XMEGA_JTAG 0x30 /* section 1, AVR scope, 2 bytes (kHz) */
|
||||
#define PARM3_CLK_XMEGA_PDI 0x31 /* section 1, AVR scope, 2 bytes (kHz) */
|
||||
|
||||
/*
|
||||
* Options context parameters
|
||||
*/
|
||||
#define PARM3_OPT_12V_UPDI_ENABLE 0x06
|
||||
#define PARM3_OPT_CHIP_ERASE_TO_ENTER 0x07
|
||||
|
||||
|
||||
/* Xmega erase memory types, for CMND_XMEGA_ERASE */
|
||||
#define XMEGA_ERASE_CHIP 0x00
|
||||
@@ -284,16 +263,6 @@
|
||||
|
||||
#define CMSISDAP_CMD_SWD_CONFIGURE 0x13 /* configure SWD protocol; (byte) */
|
||||
|
||||
#define DEFAULT_MINIMUM_CHARACTERISED_DIV1_VOLTAGE_MV 4500 // Default minimum voltage for 32M => 4.5V
|
||||
#define DEFAULT_MINIMUM_CHARACTERISED_DIV2_VOLTAGE_MV 2700 // Default minimum voltage for 16M => 2.7V
|
||||
#define DEFAULT_MINIMUM_CHARACTERISED_DIV4_VOLTAGE_MV 2200 // Default minimum voltage for 8M => 2.2V
|
||||
#define DEFAULT_MINIMUM_CHARACTERISED_DIV8_VOLTAGE_MV 1500 // Default minimum voltage for 4M => 1.5V
|
||||
#define MAX_FREQUENCY_DEDICATED_UPDI_PIN 1500
|
||||
#define MAX_FREQUENCY_SHARED_UPDI_PIN 750
|
||||
#define UPDI_ADDRESS_MODE_16BIT 0
|
||||
#define UPDI_ADDRESS_MODE_24BIT 1
|
||||
#define FUSES_SYSCFG0_OFFSET 5
|
||||
|
||||
#if !defined(JTAG3_PRIVATE_EXPORTED)
|
||||
|
||||
struct mega_device_desc {
|
||||
@@ -347,47 +316,4 @@ struct xmega_device_desc {
|
||||
unsigned char nvm_base_addr[2]; // IO space base address of NVM controller
|
||||
unsigned char mcu_base_addr[2]; // IO space base address of MCU control
|
||||
};
|
||||
|
||||
/* UPDI device descriptor */
|
||||
struct updi_device_desc {
|
||||
unsigned char prog_base[2];
|
||||
unsigned char flash_page_size;
|
||||
unsigned char eeprom_page_size;
|
||||
unsigned char nvm_base_addr[2];
|
||||
unsigned char ocd_base_addr[2];
|
||||
|
||||
// Configuration below, except for "Extended memory support", is only used by kits with
|
||||
// embedded debuggers (XPlained, Curiosity, ...).
|
||||
unsigned char default_min_div1_voltage[2]; // Default minimum voltage for 32M => 4.5V -> 4500
|
||||
unsigned char default_min_div2_voltage[2]; // Default minimum voltage for 16M => 2.7V -> 2700
|
||||
unsigned char default_min_div4_voltage[2]; // Default minimum voltage for 8M => 2.2V -> 2200
|
||||
unsigned char default_min_div8_voltage[2]; // Default minimum voltage for 4M => 1.5V -> 1500
|
||||
|
||||
unsigned char pdi_pad_fmax[2]; // 750
|
||||
|
||||
unsigned char flash_bytes[4]; // Flash size in bytes
|
||||
unsigned char eeprom_bytes[2]; // EEPROM size in bytes
|
||||
unsigned char user_sig_bytes[2]; // UserSignture size in bytes
|
||||
unsigned char fuses_bytes; // Fuses size in bytes
|
||||
|
||||
unsigned char syscfg_offset; // Offset of SYSCFG0 within FUSE space
|
||||
unsigned char syscfg_write_mask_and; // AND mask to apply to SYSCFG0 when writing
|
||||
unsigned char syscfg_write_mask_or; // OR mask to apply to SYSCFG0 when writing
|
||||
unsigned char syscfg_erase_mask_and; // AND mask to apply to SYSCFG0 after erase
|
||||
unsigned char syscfg_erase_mask_or; // OR mask to apply to SYSCFG0 after erase
|
||||
|
||||
unsigned char eeprom_base[2]; // Base address for EEPROM memory
|
||||
unsigned char user_sig_base[2]; // Base address for UserSignature memory
|
||||
unsigned char signature_base[2]; // Base address for Signature memory
|
||||
unsigned char fuses_base[2]; // Base address for Fuses memory
|
||||
unsigned char lockbits_base[2]; // Base address for Lockbits memory
|
||||
|
||||
unsigned char device_id[2]; // Two last bytes of the device ID
|
||||
|
||||
// Extended memory support. Needed for flash >= 64kb
|
||||
unsigned char prog_base_msb; // Extends prog_base, used in 24-bit mode
|
||||
unsigned char flash_page_size_msb; // Extends flash_page_size, used in 24-bit mode
|
||||
|
||||
unsigned char address_mode; // 0x00 = 16-bit mode, 0x01 = 24-bit mode
|
||||
};
|
||||
#endif /* JTAG3_PRIVATE_EXPORTED */
|
||||
|
||||
13
jtagmkII.c
13
jtagmkII.c
@@ -604,7 +604,6 @@ static int jtagmkII_recv_frame(PROGRAMMER * pgm, unsigned char **msg,
|
||||
if (tnow - tstart > timeoutval) {
|
||||
avrdude_message(MSG_INFO, "%s: jtagmkII_recv_frame(): timeout\n",
|
||||
progname);
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -742,7 +741,6 @@ int jtagmkII_getsync(PROGRAMMER * pgm, int mode) {
|
||||
avrdude_message(MSG_NOTICE, "Device ID: %s\n",
|
||||
resp + 16);
|
||||
}
|
||||
free(resp);
|
||||
break;
|
||||
}
|
||||
free(resp);
|
||||
@@ -1348,7 +1346,12 @@ static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
jtagmkII_set_devdescr(pgm, p);
|
||||
|
||||
PDATA(pgm)->boot_start = ULONG_MAX;
|
||||
if ((p->flags & AVRPART_HAS_PDI)) {
|
||||
/*
|
||||
* If this is an ATxmega device in JTAG mode, change the emulator
|
||||
* mode from JTAG to JTAG_XMEGA.
|
||||
*/
|
||||
if ((pgm->flag & PGM_FL_IS_JTAG) &&
|
||||
(p->flags & AVRPART_HAS_PDI)) {
|
||||
/*
|
||||
* Find out where the border between application and boot area
|
||||
* is.
|
||||
@@ -1916,7 +1919,7 @@ static int jtagmkII_page_erase(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
|
||||
retry:
|
||||
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_page_erase(): "
|
||||
"Sending Xmega erase command: ",
|
||||
"Sending xmega erase command: ",
|
||||
progname);
|
||||
jtagmkII_send(pgm, cmd, sizeof cmd);
|
||||
|
||||
@@ -3636,12 +3639,12 @@ static int jtagmkII_paged_write32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
status = jtagmkII_flash_write_page32(pgm, pageNum);
|
||||
if(status < 0) {lineno = __LINE__; goto eRR;}
|
||||
}
|
||||
free(cmd);
|
||||
serial_recv_timeout = otimeout;
|
||||
|
||||
status = jtagmkII_reset32(pgm, AVR32_SET4RUNNING); // AVR32_SET4RUNNING | AVR32_RELEASE_JTAG
|
||||
if(status < 0) {lineno = __LINE__; goto eRR;}
|
||||
|
||||
free(cmd);
|
||||
return addr;
|
||||
|
||||
eRR:
|
||||
|
||||
3
lexer.l
3
lexer.l
@@ -140,7 +140,6 @@ default_safemode { yylval=NULL; return K_DEFAULT_SAFEMODE; }
|
||||
default_serial { yylval=NULL; return K_DEFAULT_SERIAL; }
|
||||
delay { yylval=NULL; return K_DELAY; }
|
||||
desc { yylval=NULL; return K_DESC; }
|
||||
family_id { yylval=NULL; return K_FAMILY_ID; }
|
||||
devicecode { yylval=NULL; return K_DEVICECODE; }
|
||||
eecr { yylval=NULL; return K_EECR; }
|
||||
eeprom { yylval=NULL; return K_EEPROM; }
|
||||
@@ -153,7 +152,6 @@ has_debugwire { yylval=NULL; return K_HAS_DW; }
|
||||
has_jtag { yylval=NULL; return K_HAS_JTAG; }
|
||||
has_pdi { yylval=NULL; return K_HAS_PDI; }
|
||||
has_tpi { yylval=NULL; return K_HAS_TPI; }
|
||||
has_updi { yylval=NULL; return K_HAS_UPDI; }
|
||||
hventerstabdelay { yylval=NULL; return K_HVENTERSTABDELAY; }
|
||||
hvleavestabdelay { yylval=NULL; return K_HVLEAVESTABDELAY; }
|
||||
hvsp_controlstack { yylval=NULL; return K_HVSP_CONTROLSTACK; }
|
||||
@@ -178,7 +176,6 @@ no { yylval=new_token(K_NO); return K_NO; }
|
||||
num_banks { yylval=NULL; return K_NUM_PAGES; }
|
||||
num_pages { yylval=NULL; return K_NUM_PAGES; }
|
||||
nvm_base { yylval=NULL; return K_NVM_BASE; }
|
||||
ocd_base { yylval=NULL; return K_OCD_BASE; }
|
||||
ocdrev { yylval=NULL; return K_OCDREV; }
|
||||
offset { yylval=NULL; return K_OFFSET; }
|
||||
page_size { yylval=NULL; return K_PAGE_SIZE; }
|
||||
|
||||
21
libavrdude.h
21
libavrdude.h
@@ -33,7 +33,11 @@
|
||||
#include <stdint.h>
|
||||
typedef uint32_t pinmask_t;
|
||||
#else
|
||||
#error Need a C99 capable compiler
|
||||
#if UINT_MAX >= 0xFFFFFFFF
|
||||
typedef unsigned int pinmask_t;
|
||||
#else
|
||||
typedef unsigned long pinmask_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -195,12 +199,9 @@ typedef struct opcode {
|
||||
#define AVRPART_WRITE 0x0400 /* at least one write operation specified */
|
||||
#define AVRPART_HAS_TPI 0x0800 /* part has TPI i/f rather than ISP (ATtiny4/5/9/10) */
|
||||
#define AVRPART_IS_AT90S1200 0x1000 /* part is an AT90S1200 (needs special treatment) */
|
||||
#define AVRPART_HAS_UPDI 0x2000 /* part has UPDI i/f (AVR8X) */
|
||||
|
||||
#define AVR_DESCLEN 64
|
||||
#define AVR_IDLEN 32
|
||||
#define AVR_FAMILYIDLEN 7
|
||||
#define AVR_SIBLEN 16
|
||||
#define CTL_STACK_SIZE 32
|
||||
#define FLASH_INSTR_SIZE 3
|
||||
#define EEPROM_INSTR_SIZE 20
|
||||
@@ -210,7 +211,6 @@ typedef struct opcode {
|
||||
typedef struct avrpart {
|
||||
char desc[AVR_DESCLEN]; /* long part name */
|
||||
char id[AVR_IDLEN]; /* short part name */
|
||||
char family_id[AVR_FAMILYIDLEN+1]; /* family id in the SIB (avr8x) */
|
||||
int stk500_devcode; /* stk500 device code */
|
||||
int avr910_devcode; /* avr910 device code */
|
||||
int chip_erase_delay; /* microseconds */
|
||||
@@ -264,7 +264,6 @@ typedef struct avrpart {
|
||||
unsigned short eecr; /* JTAC ICE mkII XML file parameter */
|
||||
unsigned int mcu_base; /* Base address of MCU control block in ATxmega devices */
|
||||
unsigned int nvm_base; /* Base address of NVM controller in ATxmega devices */
|
||||
unsigned int ocd_base; /* Base address of OCD module in AVR8X/UPDI devices */
|
||||
int ocdrev; /* OCD revision (JTAGICE3 parameter, from AS6 XML files) */
|
||||
|
||||
OPCODE * op[AVR_OP_MAX]; /* opcodes */
|
||||
@@ -338,9 +337,6 @@ typedef void (*walk_avrparts_cb)(const char *name, const char *desc,
|
||||
void *cookie);
|
||||
void walk_avrparts(LISTID avrparts, walk_avrparts_cb cb, void *cookie);
|
||||
void sort_avrparts(LISTID avrparts);
|
||||
|
||||
int compare_memory_masked(AVRMEM * m, uint8_t buf1, uint8_t buf2);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -369,7 +365,7 @@ enum {
|
||||
#ifdef HAVE_LINUXGPIO
|
||||
/* Embedded systems might have a lot more gpio than only 0-31 */
|
||||
#undef PIN_MAX
|
||||
#define PIN_MAX 400 /* largest allowed pin number */
|
||||
#define PIN_MAX 255 /* largest allowed pin number */
|
||||
#endif
|
||||
|
||||
/** Number of pins in each element of the bitfield */
|
||||
@@ -567,7 +563,6 @@ extern struct serial_device serial_serdev;
|
||||
extern struct serial_device usb_serdev;
|
||||
extern struct serial_device usb_serdev_frame;
|
||||
extern struct serial_device avrdoper_serdev;
|
||||
extern struct serial_device usbhid_serdev;
|
||||
|
||||
#define serial_open (serdev->open)
|
||||
#define serial_setspeed (serdev->setspeed)
|
||||
@@ -646,7 +641,6 @@ typedef struct programmer_t {
|
||||
void (*powerdown) (struct programmer_t * pgm);
|
||||
int (*program_enable) (struct programmer_t * pgm, AVRPART * p);
|
||||
int (*chip_erase) (struct programmer_t * pgm, AVRPART * p);
|
||||
int (*unlock) (struct programmer_t * pgm, AVRPART * p);
|
||||
int (*cmd) (struct programmer_t * pgm, const unsigned char *cmd,
|
||||
unsigned char *res);
|
||||
int (*cmd_tpi) (struct programmer_t * pgm, const unsigned char *cmd,
|
||||
@@ -669,7 +663,6 @@ typedef struct programmer_t {
|
||||
int (*read_byte) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned long addr, unsigned char * value);
|
||||
int (*read_sig_bytes) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m);
|
||||
int (*read_sib) (struct programmer_t * pgm, AVRPART * p, char *sib);
|
||||
void (*print_parms) (struct programmer_t * pgm);
|
||||
int (*set_vtarget) (struct programmer_t * pgm, double v);
|
||||
int (*set_varef) (struct programmer_t * pgm, unsigned int chan, double v);
|
||||
@@ -764,8 +757,6 @@ int avr_mem_hiaddr(AVRMEM * mem);
|
||||
|
||||
int avr_chip_erase(PROGRAMMER * pgm, AVRPART * p);
|
||||
|
||||
int avr_unlock(PROGRAMMER * pgm, AVRPART * p);
|
||||
|
||||
void report_progress (int completed, int total, char *hdr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -66,7 +66,7 @@ static int linuxgpio_export(unsigned int gpio)
|
||||
return fd;
|
||||
}
|
||||
|
||||
len = snprintf(buf, sizeof(buf), "%u", gpio);
|
||||
len = snprintf(buf, sizeof(buf), "%d", gpio);
|
||||
r = write(fd, buf, len);
|
||||
close(fd);
|
||||
|
||||
@@ -84,7 +84,7 @@ static int linuxgpio_unexport(unsigned int gpio)
|
||||
return fd;
|
||||
}
|
||||
|
||||
len = snprintf(buf, sizeof(buf), "%u", gpio);
|
||||
len = snprintf(buf, sizeof(buf), "%d", gpio);
|
||||
r = write(fd, buf, len);
|
||||
close(fd);
|
||||
|
||||
@@ -95,7 +95,7 @@ static int linuxgpio_openfd(unsigned int gpio)
|
||||
{
|
||||
char filepath[60];
|
||||
|
||||
snprintf(filepath, sizeof(filepath), "/sys/class/gpio/gpio%u/value", gpio);
|
||||
snprintf(filepath, sizeof(filepath), "/sys/class/gpio/gpio%d/value", gpio);
|
||||
return (open(filepath, O_RDWR));
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ static int linuxgpio_dir(unsigned int gpio, unsigned int dir)
|
||||
int fd, r;
|
||||
char buf[60];
|
||||
|
||||
snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%u/direction", gpio);
|
||||
snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction", gpio);
|
||||
|
||||
fd = open(buf, O_WRONLY);
|
||||
if (fd < 0) {
|
||||
@@ -330,7 +330,6 @@ void linuxgpio_initpgm(PROGRAMMER *pgm)
|
||||
pgm->program_enable = bitbang_program_enable;
|
||||
pgm->chip_erase = bitbang_chip_erase;
|
||||
pgm->cmd = bitbang_cmd;
|
||||
pgm->cmd_tpi = bitbang_cmd_tpi;
|
||||
pgm->open = linuxgpio_open;
|
||||
pgm->close = linuxgpio_close;
|
||||
pgm->setpin = linuxgpio_setpin;
|
||||
|
||||
427
linuxspi.c
427
linuxspi.c
@@ -1,427 +0,0 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Support for using spidev userspace drivers to communicate directly over SPI
|
||||
*
|
||||
* Copyright (C) 2013 Kevin Cuzner <kevin@kevincuzner.com>
|
||||
* Copyright (C) 2018 Ralf Ramsauer <ralf@vmexit.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Support for inversion of reset pin, Tim Chilton 02/05/2014
|
||||
* Review code, rebase to latest trunk, add linux/gpio.h support, Ralf Ramsauer 2018-09-07
|
||||
*/
|
||||
|
||||
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "libavrdude.h"
|
||||
|
||||
#include "linuxspi.h"
|
||||
|
||||
#if HAVE_LINUXSPI
|
||||
|
||||
/**
|
||||
* Linux Kernel SPI Drivers
|
||||
*
|
||||
* Copyright (C) 2006 SWAPP
|
||||
* Andrea Paterniani <a.paterniani@swapp-eng.it>
|
||||
* Copyright (C) 2007 David Brownell (simplification, cleanup)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/spi/spidev.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#define LINUXSPI "linuxspi"
|
||||
|
||||
static int fd_spidev, fd_gpiochip, fd_linehandle;
|
||||
|
||||
/**
|
||||
* @brief Sends/receives a message in full duplex mode
|
||||
* @return -1 on failure, otherwise number of bytes sent/recieved
|
||||
*/
|
||||
static int linuxspi_spi_duplex(PROGRAMMER *pgm, const unsigned char *tx, unsigned char *rx, int len)
|
||||
{
|
||||
struct spi_ioc_transfer tr;
|
||||
int ret;
|
||||
|
||||
tr = (struct spi_ioc_transfer) {
|
||||
.tx_buf = (unsigned long)tx,
|
||||
.rx_buf = (unsigned long)rx,
|
||||
.len = len,
|
||||
.delay_usecs = 1,
|
||||
.speed_hz = 1.0 / pgm->bitclock, // seconds to Hz
|
||||
.bits_per_word = 8,
|
||||
};
|
||||
|
||||
ret = ioctl(fd_spidev, SPI_IOC_MESSAGE(1), &tr);
|
||||
if (ret != len)
|
||||
avrdude_message(MSG_INFO, "\n%s: error: Unable to send SPI message\n", progname);
|
||||
|
||||
return (ret == -1) ? -1 : 0;
|
||||
}
|
||||
|
||||
static void linuxspi_setup(PROGRAMMER *pgm)
|
||||
{
|
||||
}
|
||||
|
||||
static void linuxspi_teardown(PROGRAMMER* pgm)
|
||||
{
|
||||
}
|
||||
|
||||
static int linuxspi_reset_mcu(PROGRAMMER *pgm, bool active)
|
||||
{
|
||||
struct gpiohandle_data data;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Set the reset state and keep it. The pin will be released and set back to
|
||||
* its initial value, once the fd_gpiochip is closed.
|
||||
*/
|
||||
data.values[0] = active ^ !(pgm->pinno[PIN_AVR_RESET] & PIN_INVERSE);
|
||||
ret = ioctl(fd_linehandle, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
|
||||
#ifdef GPIO_V2_LINE_SET_VALUES_IOCTL
|
||||
if (ret == -1) {
|
||||
struct gpio_v2_line_values val;
|
||||
|
||||
val.mask = 1;
|
||||
val.bits = active ^ !(pgm->pinno[PIN_AVR_RESET] & PIN_INVERSE);
|
||||
|
||||
ret = ioctl(fd_linehandle, GPIO_V2_LINE_SET_VALUES_IOCTL, &val);
|
||||
}
|
||||
#endif
|
||||
if (ret == -1) {
|
||||
ret = -errno;
|
||||
avrdude_message(MSG_INFO, "%s error: Unable to set GPIO line %d value\n",
|
||||
progname, pgm->pinno[PIN_AVR_RESET] & ~PIN_INVERSE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int linuxspi_open(PROGRAMMER *pgm, char *port)
|
||||
{
|
||||
const char *port_error =
|
||||
"%s: error: Unknown port specification. "
|
||||
"Please use the format /dev/spidev:/dev/gpiochip[:resetno]\n";
|
||||
char port_default[] = "/dev/spidev0.0:/dev/gpiochip0";
|
||||
char *spidev, *gpiochip, *reset_pin;
|
||||
struct gpiohandle_request req;
|
||||
int ret;
|
||||
|
||||
if (!strcmp(port, "unknown")) {
|
||||
port = port_default;
|
||||
}
|
||||
|
||||
spidev = strtok(port, ":");
|
||||
if (!spidev) {
|
||||
avrdude_message(MSG_INFO, port_error, progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
gpiochip = strtok(NULL, ":");
|
||||
if (!gpiochip) {
|
||||
avrdude_message(MSG_INFO, port_error, progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* optional: override reset pin in configuration */
|
||||
reset_pin = strtok(NULL, ":");
|
||||
if (reset_pin)
|
||||
pgm->pinno[PIN_AVR_RESET] = strtoul(reset_pin, NULL, 0);
|
||||
|
||||
strcpy(pgm->port, port);
|
||||
fd_spidev = open(pgm->port, O_RDWR);
|
||||
if (fd_spidev < 0) {
|
||||
avrdude_message(MSG_INFO, "\n%s: error: Unable to open the spidev device %s", progname, pgm->port);
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t mode = SPI_MODE_0 | SPI_NO_CS;
|
||||
ret = ioctl(fd_spidev, SPI_IOC_WR_MODE32, &mode);
|
||||
if (ret == -1) {
|
||||
avrdude_message(MSG_INFO, "%s: error: Unable to set SPI mode %0X on %s\n",
|
||||
progname, mode, spidev);
|
||||
goto close_spidev;
|
||||
}
|
||||
fd_gpiochip = open(gpiochip, 0);
|
||||
if (fd_gpiochip < 0) {
|
||||
avrdude_message(MSG_INFO, "\n%s error: Unable to open the gpiochip %s", progname, gpiochip);
|
||||
ret = -1;
|
||||
goto close_spidev;
|
||||
}
|
||||
|
||||
strcpy(req.consumer_label, progname);
|
||||
req.lines = 1;
|
||||
req.lineoffsets[0] = pgm->pinno[PIN_AVR_RESET] & ~PIN_INVERSE;
|
||||
req.default_values[0] = !!(pgm->pinno[PIN_AVR_RESET] & PIN_INVERSE);
|
||||
req.flags = GPIOHANDLE_REQUEST_OUTPUT;
|
||||
|
||||
ret = ioctl(fd_gpiochip, GPIO_GET_LINEHANDLE_IOCTL, &req);
|
||||
if (ret != -1)
|
||||
fd_linehandle = req.fd;
|
||||
#ifdef GPIO_V2_GET_LINE_IOCTL
|
||||
if (ret == -1) {
|
||||
struct gpio_v2_line_request reqv2;
|
||||
|
||||
memset(&reqv2, 0, sizeof(reqv2));
|
||||
reqv2.offsets[0] = pgm->pinno[PIN_AVR_RESET] & ~PIN_INVERSE;
|
||||
strncpy(reqv2.consumer, progname, sizeof(reqv2.consumer) - 1);
|
||||
reqv2.config.flags = GPIO_V2_LINE_FLAG_OUTPUT;
|
||||
reqv2.config.num_attrs = 1;
|
||||
reqv2.config.attrs[0].attr.id = GPIO_V2_LINE_ATTR_ID_OUTPUT_VALUES;
|
||||
reqv2.config.attrs[0].attr.values = !!(pgm->pinno[PIN_AVR_RESET] & PIN_INVERSE);
|
||||
reqv2.config.attrs[0].mask = 1;
|
||||
reqv2.num_lines = 1;
|
||||
|
||||
ret = ioctl(fd_gpiochip, GPIO_V2_GET_LINE_IOCTL, &reqv2);
|
||||
if (ret != -1)
|
||||
fd_linehandle = reqv2.fd;
|
||||
}
|
||||
#endif
|
||||
if (ret == -1) {
|
||||
ret = -errno;
|
||||
avrdude_message(MSG_INFO, "%s error: Unable to get GPIO line %d\n",
|
||||
progname, pgm->pinno[PIN_AVR_RESET] & ~PIN_INVERSE);
|
||||
goto close_gpiochip;
|
||||
}
|
||||
|
||||
ret = linuxspi_reset_mcu(pgm, true);
|
||||
if (ret)
|
||||
goto close_out;
|
||||
|
||||
if (pgm->baudrate != 0) {
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: obsolete use of -b <clock> option for bit clock; use -B <clock>\n",
|
||||
progname);
|
||||
pgm->bitclock = 1E6 / pgm->baudrate;
|
||||
}
|
||||
if (pgm->bitclock == 0) {
|
||||
avrdude_message(MSG_NOTICE,
|
||||
"%s: defaulting bit clock to 200 kHz\n",
|
||||
progname);
|
||||
pgm->bitclock = 5E-6; // 200 kHz - 5 µs
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
close_out:
|
||||
close(fd_linehandle);
|
||||
close_gpiochip:
|
||||
close(fd_gpiochip);
|
||||
close_spidev:
|
||||
close(fd_spidev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void linuxspi_close(PROGRAMMER *pgm)
|
||||
{
|
||||
switch (pgm->exit_reset) {
|
||||
case EXIT_RESET_ENABLED:
|
||||
linuxspi_reset_mcu(pgm, true);
|
||||
break;
|
||||
|
||||
case EXIT_RESET_DISABLED:
|
||||
linuxspi_reset_mcu(pgm, false);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
close(fd_linehandle);
|
||||
close(fd_spidev);
|
||||
close(fd_gpiochip);
|
||||
}
|
||||
|
||||
static void linuxspi_disable(PROGRAMMER* pgm)
|
||||
{
|
||||
}
|
||||
|
||||
static void linuxspi_enable(PROGRAMMER* pgm)
|
||||
{
|
||||
}
|
||||
|
||||
static void linuxspi_display(PROGRAMMER* pgm, const char* p)
|
||||
{
|
||||
}
|
||||
|
||||
static int linuxspi_initialize(PROGRAMMER *pgm, AVRPART *p)
|
||||
{
|
||||
int tries, ret;
|
||||
|
||||
if (p->flags & AVRPART_HAS_TPI) {
|
||||
/* We do not support tpi. This is a dedicated SPI thing */
|
||||
avrdude_message(MSG_INFO, "%s: error: Programmer " LINUXSPI " does not support TPI\n", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//enable programming on the part
|
||||
tries = 0;
|
||||
do
|
||||
{
|
||||
ret = pgm->program_enable(pgm, p);
|
||||
if (ret == 0 || ret == -1)
|
||||
break;
|
||||
} while(tries++ < 65);
|
||||
|
||||
if (ret)
|
||||
avrdude_message(MSG_INFO, "%s: error: AVR device not responding\n", progname);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int linuxspi_cmd(PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res)
|
||||
{
|
||||
return linuxspi_spi_duplex(pgm, cmd, res, 4);
|
||||
}
|
||||
|
||||
static int linuxspi_program_enable(PROGRAMMER *pgm, AVRPART *p)
|
||||
{
|
||||
unsigned char cmd[4], res[4];
|
||||
|
||||
if (!p->op[AVR_OP_PGM_ENABLE]) {
|
||||
avrdude_message(MSG_INFO, "%s: error: program enable instruction not defined for part \"%s\"\n", progname, p->desc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(cmd, 0, sizeof(cmd));
|
||||
avr_set_bits(p->op[AVR_OP_PGM_ENABLE], cmd); //set the cmd
|
||||
pgm->cmd(pgm, cmd, res);
|
||||
|
||||
if (res[2] != cmd[1]) {
|
||||
/*
|
||||
* From ATtiny441 datasheet:
|
||||
*
|
||||
* In some systems, the programmer can not guarantee that SCK is held low
|
||||
* during power-up. In this case, RESET must be given a positive pulse after
|
||||
* SCK has been set to '0'. The duration of the pulse must be at least t RST
|
||||
* plus two CPU clock cycles. See Table 25-5 on page 240 for definition of
|
||||
* minimum pulse width on RESET pin, t RST
|
||||
* 2. Wait for at least 20 ms and then enable serial programming by sending
|
||||
* the Programming Enable serial instruction to the MOSI pin
|
||||
* 3. The serial programming instructions will not work if the communication
|
||||
* is out of synchronization. When in sync, the second byte (0x53) will echo
|
||||
* back when issuing the third byte of the Programming Enable instruction
|
||||
* ...
|
||||
* If the 0x53 did not echo back, give RESET a positive pulse and issue a
|
||||
* new Programming Enable command
|
||||
*/
|
||||
if (linuxspi_reset_mcu(pgm, false))
|
||||
return -1;
|
||||
usleep(5);
|
||||
if (linuxspi_reset_mcu(pgm, true))
|
||||
return -1;
|
||||
usleep(20000);
|
||||
|
||||
return -2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int linuxspi_chip_erase(PROGRAMMER *pgm, AVRPART *p)
|
||||
{
|
||||
unsigned char cmd[4], res[4];
|
||||
|
||||
if (!p->op[AVR_OP_CHIP_ERASE]) {
|
||||
avrdude_message(MSG_INFO, "%s: error: chip erase instruction not defined for part \"%s\"\n", progname, p->desc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(cmd, 0, sizeof(cmd));
|
||||
avr_set_bits(p->op[AVR_OP_CHIP_ERASE], cmd);
|
||||
pgm->cmd(pgm, cmd, res);
|
||||
usleep(p->chip_erase_delay);
|
||||
pgm->initialize(pgm, p);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int linuxspi_parseexitspecs(PROGRAMMER *pgm, char *s)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
while ((cp = strtok(s, ","))) {
|
||||
s = 0;
|
||||
if (!strcmp(cp, "reset")) {
|
||||
pgm->exit_reset = EXIT_RESET_ENABLED;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(cp, "noreset")) {
|
||||
pgm->exit_reset = EXIT_RESET_DISABLED;
|
||||
continue;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void linuxspi_initpgm(PROGRAMMER *pgm)
|
||||
{
|
||||
strcpy(pgm->type, LINUXSPI);
|
||||
|
||||
pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed
|
||||
|
||||
/* mandatory functions */
|
||||
pgm->initialize = linuxspi_initialize;
|
||||
pgm->display = linuxspi_display;
|
||||
pgm->enable = linuxspi_enable;
|
||||
pgm->disable = linuxspi_disable;
|
||||
pgm->program_enable = linuxspi_program_enable;
|
||||
pgm->chip_erase = linuxspi_chip_erase;
|
||||
pgm->cmd = linuxspi_cmd;
|
||||
pgm->open = linuxspi_open;
|
||||
pgm->close = linuxspi_close;
|
||||
pgm->read_byte = avr_read_byte_default;
|
||||
pgm->write_byte = avr_write_byte_default;
|
||||
|
||||
/* optional functions */
|
||||
pgm->setup = linuxspi_setup;
|
||||
pgm->teardown = linuxspi_teardown;
|
||||
pgm->parseexitspecs = linuxspi_parseexitspecs;
|
||||
}
|
||||
|
||||
const char linuxspi_desc[] = "SPI using Linux spidev driver";
|
||||
|
||||
#else /* !HAVE_LINUXSPI */
|
||||
|
||||
void linuxspi_initpgm(PROGRAMMER * pgm)
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: Linux SPI driver not available in this configuration\n",
|
||||
progname);
|
||||
}
|
||||
|
||||
const char linuxspi_desc[] = "SPI using Linux spidev driver (not available)";
|
||||
|
||||
#endif /* HAVE_LINUXSPI */
|
||||
35
linuxspi.h
35
linuxspi.h
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2013 Kevin Cuzner <kevin@kevincuner.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef linuxspi_h
|
||||
#define linuxspi_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const char linuxspi_desc[];
|
||||
void linuxspi_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //linuxspi_h
|
||||
|
||||
73
main.c
73
main.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2000-2005 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
* Copyright 2007-2014 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -127,6 +127,8 @@ static void usage(void)
|
||||
" -t Enter terminal mode.\n"
|
||||
" -E <exitspec>[,<exitspec>] List programmer exit specifications.\n"
|
||||
" -x <extended_param> Pass <extended_param> to programmer.\n"
|
||||
" -y Count # erase cycles in EEPROM.\n"
|
||||
" -Y <number> Initialize erase cycle # in EEPROM.\n"
|
||||
" -v Verbose output. -v -v for more.\n"
|
||||
" -q Quell progress output. -q -q for less.\n"
|
||||
" -l logfile Use logfile rather than stderr for diagnostics.\n"
|
||||
@@ -345,6 +347,7 @@ int main(int argc, char * argv [])
|
||||
unsigned char safemode_fuse = 0xff;
|
||||
|
||||
char * safemode_response;
|
||||
int fuses_specified = 0;
|
||||
int fuses_updated = 0;
|
||||
#if !defined(WIN32NATIVE)
|
||||
char * homedir;
|
||||
@@ -676,10 +679,10 @@ int main(int argc, char * argv [])
|
||||
* Print out an identifying string so folks can tell what version
|
||||
* they are running
|
||||
*/
|
||||
avrdude_message(MSG_NOTICE, "\n%s: Version %s\n"
|
||||
"%sCopyright (c) Brian Dean, http://www.bdmicro.com/\n"
|
||||
"%sCopyright (c) Joerg Wunsch\n\n",
|
||||
progname, version, progbuf, progbuf);
|
||||
avrdude_message(MSG_NOTICE, "\n%s: Version %s, compiled on %s at %s\n"
|
||||
"%sCopyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/\n"
|
||||
"%sCopyright (c) 2007-2014 Joerg Wunsch\n\n",
|
||||
progname, version, __DATE__, __TIME__, progbuf, progbuf);
|
||||
avrdude_message(MSG_NOTICE, "%sSystem wide configuration file is \"%s\"\n",
|
||||
progbuf, sys_config);
|
||||
|
||||
@@ -918,7 +921,7 @@ int main(int argc, char * argv [])
|
||||
*/
|
||||
if (port[0] == 0) {
|
||||
avrdude_message(MSG_INFO, "\n%s: no port has been specified on the command line "
|
||||
"or in the config file\n",
|
||||
"or the config file\n",
|
||||
progname);
|
||||
avrdude_message(MSG_INFO, "%sSpecify a port using the -P option and try again\n\n",
|
||||
progbuf);
|
||||
@@ -1042,44 +1045,6 @@ int main(int argc, char * argv [])
|
||||
if (init_ok) {
|
||||
rc = avr_signature(pgm, p);
|
||||
if (rc != 0) {
|
||||
// -68 == -(0x44) == -(RSP3_FAIL_OCD_LOCKED)
|
||||
if ((rc == -68) && (p->flags & AVRPART_HAS_UPDI) && (attempt < 1)) {
|
||||
attempt++;
|
||||
if (pgm->read_sib) {
|
||||
// Read SIB and compare FamilyID
|
||||
char sib[AVR_SIBLEN + 1];
|
||||
pgm->read_sib(pgm, p, sib);
|
||||
avrdude_message(MSG_NOTICE, "%s: System Information Block: \"%s\"\n",
|
||||
progname, sib);
|
||||
if (quell_progress < 2) {
|
||||
avrdude_message(MSG_INFO, "%s: Received FamilyID: \"%.*s\"\n", progname, AVR_FAMILYIDLEN, sib);
|
||||
}
|
||||
if (strncmp(p->family_id, sib, AVR_FAMILYIDLEN)) {
|
||||
avrdude_message(MSG_INFO, "%s: Expected FamilyID: \"%s\"\n", progname, p->family_id);
|
||||
if (!ovsigck) {
|
||||
avrdude_message(MSG_INFO, "%sDouble check chip, "
|
||||
"or use -F to override this check.\n",
|
||||
progbuf);
|
||||
exitrc = 1;
|
||||
goto main_exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(erase) {
|
||||
erase = 0;
|
||||
if (uflags & UF_NOWRITE) {
|
||||
avrdude_message(MSG_INFO, "%s: conflicting -e and -n options specified, NOT erasing chip\n",
|
||||
progname);
|
||||
} else {
|
||||
if (quell_progress < 2) {
|
||||
avrdude_message(MSG_INFO, "%s: erasing chip\n", progname);
|
||||
}
|
||||
exitrc = avr_unlock(pgm, p);
|
||||
if(exitrc) goto main_exit;
|
||||
goto sig_again;
|
||||
}
|
||||
}
|
||||
}
|
||||
avrdude_message(MSG_INFO, "%s: error reading signature data, rc=%d\n",
|
||||
progname, rc);
|
||||
exitrc = 1;
|
||||
@@ -1173,7 +1138,7 @@ int main(int argc, char * argv [])
|
||||
//Check if the programmer just doesn't support reading
|
||||
if (rc == -5)
|
||||
{
|
||||
avrdude_message(MSG_NOTICE, "%s: safemode: Fuse reading not supported by programmer.\n"
|
||||
avrdude_message(MSG_NOTICE, "%s: safemode: Fuse reading not support by programmer.\n"
|
||||
" Safemode disabled.\n", progname);
|
||||
}
|
||||
else
|
||||
@@ -1299,11 +1264,8 @@ int main(int argc, char * argv [])
|
||||
}
|
||||
}
|
||||
|
||||
AVRMEM * m;
|
||||
|
||||
/* Now check what fuses are against what they should be */
|
||||
m = avr_locate_mem(p, "fuse");
|
||||
if (compare_memory_masked(m, safemodeafter_fuse, safemode_fuse)) {
|
||||
if (safemodeafter_fuse != safemode_fuse) {
|
||||
fuses_updated = 1;
|
||||
avrdude_message(MSG_INFO, "%s: safemode: fuse changed! Was %x, and is now %x\n",
|
||||
progname, safemode_fuse, safemodeafter_fuse);
|
||||
@@ -1331,8 +1293,7 @@ int main(int argc, char * argv [])
|
||||
}
|
||||
|
||||
/* Now check what fuses are against what they should be */
|
||||
m = avr_locate_mem(p, "lfuse");
|
||||
if (compare_memory_masked(m, safemodeafter_lfuse, safemode_lfuse)) {
|
||||
if (safemodeafter_lfuse != safemode_lfuse) {
|
||||
fuses_updated = 1;
|
||||
avrdude_message(MSG_INFO, "%s: safemode: lfuse changed! Was %x, and is now %x\n",
|
||||
progname, safemode_lfuse, safemodeafter_lfuse);
|
||||
@@ -1360,8 +1321,7 @@ int main(int argc, char * argv [])
|
||||
}
|
||||
|
||||
/* Now check what fuses are against what they should be */
|
||||
m = avr_locate_mem(p, "hfuse");
|
||||
if (compare_memory_masked(m, safemodeafter_hfuse, safemode_hfuse)) {
|
||||
if (safemodeafter_hfuse != safemode_hfuse) {
|
||||
fuses_updated = 1;
|
||||
avrdude_message(MSG_INFO, "%s: safemode: hfuse changed! Was %x, and is now %x\n",
|
||||
progname, safemode_hfuse, safemodeafter_hfuse);
|
||||
@@ -1386,8 +1346,7 @@ int main(int argc, char * argv [])
|
||||
}
|
||||
|
||||
/* Now check what fuses are against what they should be */
|
||||
m = avr_locate_mem(p, "efuse");
|
||||
if (compare_memory_masked(m, safemodeafter_efuse, safemode_efuse)) {
|
||||
if (safemodeafter_efuse != safemode_efuse) {
|
||||
fuses_updated = 1;
|
||||
avrdude_message(MSG_INFO, "%s: safemode: efuse changed! Was %x, and is now %x\n",
|
||||
progname, safemode_efuse, safemodeafter_efuse);
|
||||
@@ -1415,14 +1374,14 @@ int main(int argc, char * argv [])
|
||||
avrdude_message(MSG_INFO, "%s: safemode: ", progname);
|
||||
if (failures == 0) {
|
||||
avrdude_message(MSG_INFO, "Fuses OK (E:%02X, H:%02X, L:%02X)\n",
|
||||
safemodeafter_efuse, safemodeafter_hfuse, safemodeafter_lfuse);
|
||||
safemode_efuse, safemode_hfuse, safemode_lfuse);
|
||||
}
|
||||
else {
|
||||
avrdude_message(MSG_INFO, "Fuses not recovered, sorry\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (fuses_updated) {
|
||||
if (fuses_updated && fuses_specified) {
|
||||
exitrc = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
#include "jtagmkII.h"
|
||||
#include "jtag3.h"
|
||||
#include "linuxgpio.h"
|
||||
#include "linuxspi.h"
|
||||
#include "par.h"
|
||||
#include "pickit2.h"
|
||||
#include "ppi.h"
|
||||
@@ -51,7 +50,6 @@
|
||||
#include "usbasp.h"
|
||||
#include "usbtiny.h"
|
||||
#include "wiring.h"
|
||||
#include "xbee.h"
|
||||
|
||||
|
||||
const PROGRAMMER_TYPE programmers_types[] = {
|
||||
@@ -79,11 +77,9 @@ const PROGRAMMER_TYPE programmers_types[] = {
|
||||
{"jtagmkii_pdi", jtagmkII_pdi_initpgm, jtagmkII_pdi_desc},
|
||||
{"jtagice3", jtag3_initpgm, jtag3_desc},
|
||||
{"jtagice3_pdi", jtag3_pdi_initpgm, jtag3_pdi_desc},
|
||||
{"jtagice3_updi", jtag3_updi_initpgm, jtag3_updi_desc},
|
||||
{"jtagice3_dw", jtag3_dw_initpgm, jtag3_dw_desc},
|
||||
{"jtagice3_isp", stk500v2_jtag3_initpgm, stk500v2_jtag3_desc},
|
||||
{"linuxgpio", linuxgpio_initpgm, linuxgpio_desc},
|
||||
{"linuxspi", linuxspi_initpgm, linuxspi_desc},
|
||||
{"par", par_initpgm, par_desc},
|
||||
{"pickit2", pickit2_initpgm, pickit2_desc},
|
||||
{"serbb", serbb_initpgm, serbb_desc},
|
||||
@@ -98,7 +94,6 @@ const PROGRAMMER_TYPE programmers_types[] = {
|
||||
{"usbasp", usbasp_initpgm, usbasp_desc},
|
||||
{"usbtiny", usbtiny_initpgm, usbtiny_desc},
|
||||
{"wiring", wiring_initpgm, wiring_desc},
|
||||
{"xbee", xbee_initpgm, xbee_desc},
|
||||
};
|
||||
|
||||
const PROGRAMMER_TYPE * locate_programmer_type(const char * id)
|
||||
|
||||
@@ -202,10 +202,10 @@ static int pickit2_open(PROGRAMMER * pgm, char * port)
|
||||
HidD_GetProductString(PDATA(pgm)->usb_handle, buff, PGM_DESCLEN-1);
|
||||
|
||||
// convert from wide chars, but do not overwrite trailing '\0'
|
||||
memset(&(pgm->desc), 0, PGM_DESCLEN);
|
||||
memset(&(pgm->type), 0, PGM_DESCLEN);
|
||||
for (i = 0; i < (PGM_DESCLEN-1) && buff[i]; i++)
|
||||
{
|
||||
pgm->desc[i] = (char)buff[i]; // TODO what about little/big endian???
|
||||
pgm->type[i] = (char)buff[i]; // TODO what about little/big endian???
|
||||
}
|
||||
}
|
||||
#else
|
||||
@@ -330,8 +330,6 @@ static void pickit2_disable(PROGRAMMER * pgm)
|
||||
SCR_MCLR_GND_OFF,
|
||||
SCR_VPP_OFF,
|
||||
SCR_VDD_OFF,
|
||||
SCR_VPP_PWM_OFF,
|
||||
SCR_DELAY_2(.01),
|
||||
SCR_BUSY_LED_OFF,
|
||||
CMD_END_OF_BUFFER
|
||||
};
|
||||
|
||||
@@ -180,7 +180,7 @@ int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
|
||||
return -1;
|
||||
}
|
||||
else if (fusegood == 1) {
|
||||
avrdude_message(MSG_NOTICE, "%s: safemode: lfuse reads as %X\n", progname, safemode_lfuse);
|
||||
avrdude_message(MSG_DEBUG, "%s: safemode: lfuse reads as %X\n", progname, safemode_lfuse);
|
||||
}
|
||||
|
||||
/* Read hfuse three times */
|
||||
|
||||
299
ser_avrdoper.c
299
ser_avrdoper.c
@@ -26,7 +26,7 @@
|
||||
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#if defined(HAVE_LIBHIDAPI) || (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
|
||||
#if defined(HAVE_LIBUSB) || (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -64,102 +64,7 @@ static int avrdoperRxPosition = 0; /* amount of bytes already consu
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#if defined(HAVE_LIBHIDAPI)
|
||||
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static int usbOpenDevice(union filedescriptor *fdp, int vendor, char *vendorName,
|
||||
int product, char *productName, int doReportIDs)
|
||||
{
|
||||
hid_device *dev;
|
||||
|
||||
dev = hid_open(vendor, product, NULL);
|
||||
if (dev == NULL)
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: usbOpenDevice(): No device found\n",
|
||||
progname);
|
||||
return USB_ERROR_NOTFOUND;
|
||||
}
|
||||
fdp->usb.handle = dev;
|
||||
return USB_ERROR_NONE;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static void usbCloseDevice(union filedescriptor *fdp)
|
||||
{
|
||||
hid_device *udev = (hid_device *)fdp->usb.handle;
|
||||
fdp->usb.handle = NULL;
|
||||
|
||||
if (udev == NULL)
|
||||
return;
|
||||
|
||||
hid_close(udev);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static int usbSetReport(union filedescriptor *fdp, int reportType, char *buffer, int len)
|
||||
{
|
||||
hid_device *udev = (hid_device *)fdp->usb.handle;
|
||||
int bytesSent = -1;
|
||||
|
||||
switch(reportType){
|
||||
case USB_HID_REPORT_TYPE_INPUT:
|
||||
break;
|
||||
case USB_HID_REPORT_TYPE_OUTPUT:
|
||||
bytesSent = hid_write(udev, (unsigned char*) buffer, len);
|
||||
break;
|
||||
case USB_HID_REPORT_TYPE_FEATURE:
|
||||
bytesSent = hid_send_feature_report(udev, (unsigned char*) buffer, len);
|
||||
break;
|
||||
}
|
||||
|
||||
if(bytesSent != len){
|
||||
if(bytesSent < 0)
|
||||
avrdude_message(MSG_INFO, "Error sending message: %s\n", hid_error(udev));
|
||||
return USB_ERROR_IO;
|
||||
}
|
||||
return USB_ERROR_NONE;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static int usbGetReport(union filedescriptor *fdp, int reportType, int reportNumber,
|
||||
char *buffer, int *len)
|
||||
{
|
||||
hid_device *udev = (hid_device *)fdp->usb.handle;
|
||||
int bytesReceived = -1;
|
||||
|
||||
switch(reportType){
|
||||
case USB_HID_REPORT_TYPE_INPUT:
|
||||
bytesReceived = hid_read_timeout(udev, (unsigned char*) buffer, *len, 300);
|
||||
break;
|
||||
case USB_HID_REPORT_TYPE_OUTPUT:
|
||||
break;
|
||||
case USB_HID_REPORT_TYPE_FEATURE:
|
||||
bytesReceived = hid_get_feature_report(udev, (unsigned char*) buffer, *len);
|
||||
break;
|
||||
}
|
||||
if(bytesReceived < 0){
|
||||
avrdude_message(MSG_INFO, "Error sending message: %s\n", hid_error(udev));
|
||||
return USB_ERROR_IO;
|
||||
}
|
||||
*len = bytesReceived;
|
||||
return USB_ERROR_NONE;
|
||||
}
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#else /* !defined(HAVE_LIBHIDAPI) */
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#if defined(WIN32NATIVE) && defined(HAVE_LIBHID)
|
||||
|
||||
#include <windows.h>
|
||||
#include <setupapi.h>
|
||||
@@ -332,6 +237,204 @@ static int usbGetReport(union filedescriptor *fdp, int reportType, int reportNum
|
||||
return rval == 0 ? USB_ERROR_IO : 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#else /* !(WIN32NATIVE && HAVE_LIBHID) */
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#if defined(HAVE_USB_H)
|
||||
# include <usb.h>
|
||||
#elif defined(HAVE_LUSB0_USB_H)
|
||||
# include <lusb0_usb.h>
|
||||
#else
|
||||
# error "libusb needs either <usb.h> or <lusb0_usb.h>"
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#define USBRQ_HID_GET_REPORT 0x01
|
||||
#define USBRQ_HID_SET_REPORT 0x09
|
||||
|
||||
static int usesReportIDs;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static int usbGetStringAscii(usb_dev_handle *dev, int index, int langid, char *buf, int buflen)
|
||||
{
|
||||
char buffer[256];
|
||||
int rval, i;
|
||||
|
||||
if((rval = usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR,
|
||||
(USB_DT_STRING << 8) + index, langid, buffer,
|
||||
sizeof(buffer), 1000)) < 0)
|
||||
return rval;
|
||||
if(buffer[1] != USB_DT_STRING)
|
||||
return 0;
|
||||
if((unsigned char)buffer[0] < rval)
|
||||
rval = (unsigned char)buffer[0];
|
||||
rval /= 2;
|
||||
/* lossy conversion to ISO Latin1 */
|
||||
for(i=1;i<rval;i++){
|
||||
if(i > buflen) /* destination buffer overflow */
|
||||
break;
|
||||
buf[i-1] = buffer[2 * i];
|
||||
if(buffer[2 * i + 1] != 0) /* outside of ISO Latin1 range */
|
||||
buf[i-1] = '?';
|
||||
}
|
||||
buf[i-1] = 0;
|
||||
return i-1;
|
||||
}
|
||||
|
||||
static int usbOpenDevice(union filedescriptor *fdp, int vendor, char *vendorName,
|
||||
int product, char *productName, int doReportIDs)
|
||||
{
|
||||
struct usb_bus *bus;
|
||||
struct usb_device *dev;
|
||||
usb_dev_handle *handle = NULL;
|
||||
int errorCode = USB_ERROR_NOTFOUND;
|
||||
static int didUsbInit = 0;
|
||||
|
||||
if(!didUsbInit){
|
||||
usb_init();
|
||||
didUsbInit = 1;
|
||||
}
|
||||
usb_find_busses();
|
||||
usb_find_devices();
|
||||
for(bus=usb_get_busses(); bus; bus=bus->next){
|
||||
for(dev=bus->devices; dev; dev=dev->next){
|
||||
if(dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product){
|
||||
char string[256];
|
||||
int len;
|
||||
handle = usb_open(dev); /* we need to open the device in order to query strings */
|
||||
if(!handle){
|
||||
errorCode = USB_ERROR_ACCESS;
|
||||
avrdude_message(MSG_INFO, "Warning: cannot open USB device: %s\n",
|
||||
usb_strerror());
|
||||
continue;
|
||||
}
|
||||
if(vendorName == NULL && productName == NULL){ /* name does not matter */
|
||||
break;
|
||||
}
|
||||
/* now check whether the names match: */
|
||||
len = usbGetStringAscii(handle, dev->descriptor.iManufacturer,
|
||||
0x0409, string, sizeof(string));
|
||||
if(len < 0){
|
||||
errorCode = USB_ERROR_IO;
|
||||
avrdude_message(MSG_INFO, "Warning: cannot query manufacturer for device: %s\n",
|
||||
usb_strerror());
|
||||
}else{
|
||||
errorCode = USB_ERROR_NOTFOUND;
|
||||
/* avrdude_message(MSG_INFO, "seen device from vendor ->%s<-\n", string); */
|
||||
if(strcmp(string, vendorName) == 0){
|
||||
len = usbGetStringAscii(handle, dev->descriptor.iProduct,
|
||||
0x0409, string, sizeof(string));
|
||||
if(len < 0){
|
||||
errorCode = USB_ERROR_IO;
|
||||
avrdude_message(MSG_INFO, "Warning: cannot query product for device: %s\n",
|
||||
usb_strerror());
|
||||
}else{
|
||||
errorCode = USB_ERROR_NOTFOUND;
|
||||
/* avrdude_message(MSG_INFO, "seen product ->%s<-\n", string); */
|
||||
if(strcmp(string, productName) == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
usb_close(handle);
|
||||
handle = NULL;
|
||||
}
|
||||
}
|
||||
if(handle)
|
||||
break;
|
||||
}
|
||||
if(handle != NULL){
|
||||
int rval, retries = 3;
|
||||
if(usb_set_configuration(handle, 1)){
|
||||
avrdude_message(MSG_INFO, "Warning: could not set configuration: %s\n",
|
||||
usb_strerror());
|
||||
}
|
||||
/* now try to claim the interface and detach the kernel HID driver on
|
||||
* linux and other operating systems which support the call.
|
||||
*/
|
||||
while((rval = usb_claim_interface(handle, 0)) != 0 && retries-- > 0){
|
||||
#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
|
||||
if(usb_detach_kernel_driver_np(handle, 0) < 0){
|
||||
avrdude_message(MSG_INFO, "Warning: could not detach kernel HID driver: %s\n",
|
||||
usb_strerror());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if(rval != 0)
|
||||
avrdude_message(MSG_INFO, "Warning: could not claim interface\n");
|
||||
/* Continue anyway, even if we could not claim the interface. Control transfers
|
||||
* should still work.
|
||||
*/
|
||||
errorCode = 0;
|
||||
fdp->pfd = (void *)handle;
|
||||
usesReportIDs = doReportIDs;
|
||||
}
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static void usbCloseDevice(union filedescriptor *fdp)
|
||||
{
|
||||
usb_close((usb_dev_handle *)fdp->pfd);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static int usbSetReport(union filedescriptor *fdp, int reportType, char *buffer, int len)
|
||||
{
|
||||
int bytesSent;
|
||||
|
||||
if(!usesReportIDs){
|
||||
buffer++; /* skip dummy report ID */
|
||||
len--;
|
||||
}
|
||||
bytesSent = usb_control_msg((usb_dev_handle *)fdp->pfd, USB_TYPE_CLASS |
|
||||
USB_RECIP_INTERFACE | USB_ENDPOINT_OUT, USBRQ_HID_SET_REPORT,
|
||||
reportType << 8 | buffer[0], 0, buffer, len, 5000);
|
||||
if(bytesSent != len){
|
||||
if(bytesSent < 0)
|
||||
avrdude_message(MSG_INFO, "Error sending message: %s\n", usb_strerror());
|
||||
return USB_ERROR_IO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static int usbGetReport(union filedescriptor *fdp, int reportType, int reportNumber,
|
||||
char *buffer, int *len)
|
||||
{
|
||||
int bytesReceived, maxLen = *len;
|
||||
|
||||
if(!usesReportIDs){
|
||||
buffer++; /* make room for dummy report ID */
|
||||
maxLen--;
|
||||
}
|
||||
bytesReceived = usb_control_msg((usb_dev_handle *)fdp->pfd, USB_TYPE_CLASS |
|
||||
USB_RECIP_INTERFACE | USB_ENDPOINT_IN, USBRQ_HID_GET_REPORT,
|
||||
reportType << 8 | reportNumber, 0, buffer, maxLen, 5000);
|
||||
if(bytesReceived < 0){
|
||||
avrdude_message(MSG_INFO, "Error sending message: %s\n", usb_strerror());
|
||||
return USB_ERROR_IO;
|
||||
}
|
||||
*len = bytesReceived;
|
||||
if(!usesReportIDs){
|
||||
buffer[-1] = reportNumber; /* add dummy report ID */
|
||||
len++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* WIN32NATIVE */
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
@@ -555,4 +658,4 @@ struct serial_device avrdoper_serdev =
|
||||
.flags = SERDEV_FL_NONE,
|
||||
};
|
||||
|
||||
#endif /* defined(HAVE_LIBHIDAPI) || (defined(WIN32NATIVE) && defined(HAVE_LIBHID)) */
|
||||
#endif /* defined(HAVE_LIBUSB) || (defined(WIN32NATIVE) && defined(HAVE_LIBHID)) */
|
||||
|
||||
188
ser_posix.c
188
ser_posix.c
@@ -25,7 +25,6 @@
|
||||
|
||||
#if !defined(WIN32NATIVE)
|
||||
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
@@ -37,6 +36,10 @@
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#ifdef __linux__
|
||||
#include <linux/serial.h>
|
||||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
@@ -52,8 +55,13 @@ struct baud_mapping {
|
||||
speed_t speed;
|
||||
};
|
||||
|
||||
/* There are a lot more baud rates we could handle, but what's the point? */
|
||||
static struct termios original_termios;
|
||||
static int saved_original_termios;
|
||||
|
||||
#if !defined __linux__
|
||||
/* For linux this mapping is no longer needed.
|
||||
* (OSX and *BSD do not need this mapping either because for them,
|
||||
* Bxxx is the same as xxx.) */
|
||||
static struct baud_mapping baud_lookup_table [] = {
|
||||
{ 1200, B1200 },
|
||||
{ 2400, B2400 },
|
||||
@@ -73,8 +81,6 @@ static struct baud_mapping baud_lookup_table [] = {
|
||||
{ 0, 0 } /* Terminator. */
|
||||
};
|
||||
|
||||
static struct termios original_termios;
|
||||
static int saved_original_termios;
|
||||
|
||||
static speed_t serial_baud_lookup(long baud)
|
||||
{
|
||||
@@ -95,12 +101,19 @@ static speed_t serial_baud_lookup(long baud)
|
||||
|
||||
return baud;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int ser_setspeed(union filedescriptor *fd, long baud)
|
||||
{
|
||||
int rc;
|
||||
struct termios termios;
|
||||
#if defined __linux__
|
||||
/* for linux no conversion is needed*/
|
||||
speed_t speed = baud;
|
||||
#else
|
||||
/* converting the baud rate to the bit set needed by posix way*/
|
||||
speed_t speed = serial_baud_lookup (baud);
|
||||
#endif
|
||||
|
||||
if (!isatty(fd->ifd))
|
||||
return -ENOTTY;
|
||||
@@ -128,16 +141,79 @@ static int ser_setspeed(union filedescriptor *fd, long baud)
|
||||
termios.c_cflag = (CS8 | CREAD | CLOCAL);
|
||||
termios.c_cc[VMIN] = 1;
|
||||
termios.c_cc[VTIME] = 0;
|
||||
#ifdef __linux__
|
||||
/* Support for custom baud rate for linux is implemented by setting
|
||||
* a dummy baud rate of 38400 and manupulating the custom divider of
|
||||
* the serial interface*/
|
||||
struct serial_struct ss;
|
||||
int ioret = ioctl(fd->ifd, TIOCGSERIAL, &ss);
|
||||
if (ioret < 0){
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: Cannot get serial port settings. ioctl returned %d\n",
|
||||
progname, ioret);
|
||||
return -errno;
|
||||
}
|
||||
ss.flags = (ss.flags & ~ASYNC_SPD_MASK) | ASYNC_SPD_CUST;
|
||||
ss.custom_divisor = (ss.baud_base + (speed / 2)) / speed;
|
||||
unsigned int closestSpeed = ss.baud_base / ss.custom_divisor;
|
||||
|
||||
cfsetospeed(&termios, speed);
|
||||
cfsetispeed(&termios, speed);
|
||||
|
||||
if (closestSpeed < speed * 98 / 100 || closestSpeed > speed * 102 / 100) {
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: Cannot set serial port speed to %d. Closest possible is %d\n",
|
||||
progname, speed, closestSpeed);
|
||||
return -errno;
|
||||
}
|
||||
ioret= ioctl(fd->ifd, TIOCSSERIAL, &ss);
|
||||
if (ioret < 0){
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: Cannot set serial port speed to %d. ioctl returned %d\n",
|
||||
progname, speed, ioret);
|
||||
return -errno;
|
||||
}
|
||||
if (cfsetispeed(&termios, B38400) < 0){
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: cfsetispeed: failed to set dummy baud\n",
|
||||
progname);
|
||||
return -errno;
|
||||
}
|
||||
if (cfsetospeed(&termios, B38400) < 0){
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: cfsetospeed: failed to set dummy baud\n",
|
||||
progname);
|
||||
return -errno;
|
||||
}
|
||||
#else /* !linux */
|
||||
if (cfsetospeed(&termios, speed) < 0){
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: cfsetospeed: failed to set speed: %d\n",
|
||||
progname, speed);
|
||||
return -errno;
|
||||
}
|
||||
if (cfsetispeed(&termios, speed) < 0){
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: cfsetispeed: failed to set speed: %d\n",
|
||||
progname, speed);
|
||||
return -errno;
|
||||
}
|
||||
#endif /* linux */
|
||||
rc = tcsetattr(fd->ifd, TCSANOW, &termios);
|
||||
if (rc < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: ser_setspeed(): tcsetattr() failed\n",
|
||||
progname);
|
||||
return -errno;
|
||||
}
|
||||
#ifdef __linux__
|
||||
/* a bit more linux specific stuff to set custom baud rates*/
|
||||
if (ioctl(fd->ifd, TIOCGSERIAL, &ss) < 0){
|
||||
avrdude_message(MSG_INFO, "%s: ioctl: failed to get port settins\n", progname);
|
||||
return -errno;
|
||||
}
|
||||
ss.flags &= ~ASYNC_SPD_MASK;
|
||||
if (ioctl(fd->ifd, TIOCSSERIAL, &ss) < 0){
|
||||
avrdude_message(MSG_INFO, "%s: ioctl: failed to set port settins\n", progname);
|
||||
return -errno;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Everything is now set up for a local line without modem control
|
||||
@@ -159,35 +235,23 @@ static int ser_setspeed(union filedescriptor *fd, long baud)
|
||||
static int
|
||||
net_open(const char *port, union filedescriptor *fdp)
|
||||
{
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
char *hp, *hstr, *pstr;
|
||||
int s, fd, ret = -1;
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *result, *rp;
|
||||
char *hstr, *pstr, *end;
|
||||
unsigned int pnum;
|
||||
int fd;
|
||||
struct sockaddr_in sockaddr;
|
||||
struct hostent *hp;
|
||||
|
||||
if ((hstr = hp = strdup(port)) == NULL) {
|
||||
if ((hstr = strdup(port)) == NULL) {
|
||||
avrdude_message(MSG_INFO, "%s: net_open(): Out of memory!\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* As numeric IPv6 addresses use colons as separators, we need to
|
||||
* look for the last colon here, which separates the port number or
|
||||
* service name from the host or IP address.
|
||||
*/
|
||||
if (((pstr = strrchr(hstr, ':')) == NULL) || (pstr == hstr)) {
|
||||
if (((pstr = strchr(hstr, ':')) == NULL) || (pstr == hstr)) {
|
||||
avrdude_message(MSG_INFO, "%s: net_open(): Mangled host:port string \"%s\"\n",
|
||||
progname, hstr);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove brackets from the host part, if present.
|
||||
*/
|
||||
if (*hstr == '[' && *(pstr-1) == ']') {
|
||||
hstr++;
|
||||
*(pstr-1) = '\0';
|
||||
free(hstr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -195,49 +259,43 @@ net_open(const char *port, union filedescriptor *fdp)
|
||||
*/
|
||||
*pstr++ = '\0';
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
s = getaddrinfo(hstr, pstr, &hints, &result);
|
||||
pnum = strtoul(pstr, &end, 10);
|
||||
|
||||
if (s != 0) {
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: net_open(): Cannot resolve "
|
||||
"host=\"%s\", port=\"%s\": %s\n",
|
||||
progname, hstr, pstr, gai_strerror(s));
|
||||
goto error;
|
||||
if ((*pstr == '\0') || (*end != '\0') || (pnum == 0) || (pnum > 65535)) {
|
||||
avrdude_message(MSG_INFO, "%s: net_open(): Bad port number \"%s\"\n",
|
||||
progname, pstr);
|
||||
free(hstr);
|
||||
return -1;
|
||||
}
|
||||
for (rp = result; rp != NULL; rp = rp->ai_next) {
|
||||
fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
||||
if (fd == -1) {
|
||||
/* This one failed, loop over */
|
||||
continue;
|
||||
}
|
||||
if (connect(fd, rp->ai_addr, rp->ai_addrlen) != -1) {
|
||||
/* Success, we are connected */
|
||||
break;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
if ((hp = gethostbyname(hstr)) == NULL) {
|
||||
avrdude_message(MSG_INFO, "%s: net_open(): unknown host \"%s\"\n",
|
||||
progname, hstr);
|
||||
free(hstr);
|
||||
return -1;
|
||||
}
|
||||
if (rp == NULL) {
|
||||
avrdude_message(MSG_INFO, "%s: net_open(): Cannot connect: %s\n",
|
||||
|
||||
free(hstr);
|
||||
|
||||
if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: net_open(): Cannot open socket: %s\n",
|
||||
progname, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
fdp->ifd = fd;
|
||||
ret = 0;
|
||||
}
|
||||
freeaddrinfo(result);
|
||||
|
||||
error:
|
||||
free(hp);
|
||||
return ret;
|
||||
#else
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: Networking is not supported on your platform.\n"
|
||||
"If you need it, please open a bug report.\n", progname);
|
||||
return -1;
|
||||
#endif /* HAVE_GETADDRINFO */
|
||||
memset(&sockaddr, 0, sizeof(struct sockaddr_in));
|
||||
sockaddr.sin_family = AF_INET;
|
||||
sockaddr.sin_port = htons(pnum);
|
||||
memcpy(&(sockaddr.sin_addr.s_addr), hp->h_addr, sizeof(struct in_addr));
|
||||
|
||||
if (connect(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr))) {
|
||||
avrdude_message(MSG_INFO, "%s: net_open(): Connect failed: %s\n",
|
||||
progname, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
fdp->ifd = fd;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
86
ser_win32.c
86
ser_win32.c
@@ -628,95 +628,9 @@ static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBWS2_32
|
||||
static int net_drain(union filedescriptor *fd, int display)
|
||||
{
|
||||
LPVOID lpMsgBuf;
|
||||
struct timeval timeout;
|
||||
fd_set rfds;
|
||||
int nfds;
|
||||
unsigned char buf;
|
||||
int rc;
|
||||
|
||||
if (fd->ifd < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: ser_drain(): connection not open\n", progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (display) {
|
||||
avrdude_message(MSG_INFO, "drain>");
|
||||
}
|
||||
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 250000;
|
||||
|
||||
while (1) {
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(fd->ifd, &rfds);
|
||||
|
||||
reselect:
|
||||
nfds = select(fd->ifd + 1, &rfds, NULL, NULL, &timeout);
|
||||
if (nfds == 0) {
|
||||
if (display) {
|
||||
avrdude_message(MSG_INFO, "<drain\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (nfds == -1) {
|
||||
if (WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEINPROGRESS) {
|
||||
avrdude_message(MSG_NOTICE, "%s: ser_drain(): programmer is not responding, reselecting\n", progname);
|
||||
goto reselect;
|
||||
} else {
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
WSAGetLastError(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPTSTR)&lpMsgBuf,
|
||||
0,
|
||||
NULL);
|
||||
avrdude_message(MSG_INFO, "%s: ser_drain(): select(): %s\n", progname, (char *)lpMsgBuf);
|
||||
LocalFree(lpMsgBuf);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
rc = recv(fd->ifd, &buf, 1, 0);
|
||||
if (rc < 0) {
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
WSAGetLastError(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPTSTR)&lpMsgBuf,
|
||||
0,
|
||||
NULL);
|
||||
avrdude_message(MSG_INFO, "%s: ser_drain(): read error: %s\n", progname, (char *)lpMsgBuf);
|
||||
LocalFree(lpMsgBuf);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (display) {
|
||||
avrdude_message(MSG_INFO, "%02x ", buf);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int ser_drain(union filedescriptor *fd, int display)
|
||||
{
|
||||
#ifdef HAVE_LIBWS2_32
|
||||
if (serial_over_ethernet) {
|
||||
return net_drain(fd, display);
|
||||
}
|
||||
#endif
|
||||
|
||||
// int rc;
|
||||
unsigned char buf[10];
|
||||
BOOL readres;
|
||||
|
||||
2
serbb.h
2
serbb.h
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2005 Juliane Holzt <avrdude@juliane.holzt.de>
|
||||
* Copyright (C) 2005 Michael Holzt <kju-avr@fqdn.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2005 Juliane Holzt <avrdude@juliane.holzt.de>
|
||||
* Copyright (C) 2005 Michael Holzt <kju-avr@fqdn.org>
|
||||
* Copyright (C) 2006 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2003, 2004 Martin J. Thomas <mthomas@rhrk.uni-kl.de>
|
||||
* Copyright (C) 2005 Juliane Holzt <avrdude@juliane.holzt.de>
|
||||
* Copyright (C) 2005 Michael Holzt <kju-avr@fqdn.org>
|
||||
* Copyright (C) 2005, 2006 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
||||
2
stk500.c
2
stk500.c
@@ -1118,7 +1118,7 @@ static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value)
|
||||
else if (buf[0] != Resp_STK_OK) {
|
||||
avrdude_message(MSG_INFO, "\n%s: stk500_getparm(): (a) protocol error, "
|
||||
"expect=0x%02x, resp=0x%02x\n",
|
||||
progname, Resp_STK_OK, buf[0]);
|
||||
progname, Resp_STK_INSYNC, buf[0]);
|
||||
return -3;
|
||||
}
|
||||
|
||||
|
||||
56
stk500v2.c
56
stk500v2.c
@@ -78,9 +78,17 @@
|
||||
// Retry count
|
||||
#define RETRIES 5
|
||||
|
||||
#define DEBUG(...) avrdude_message(MSG_TRACE2, __VA_ARGS__)
|
||||
#if 0
|
||||
#define DEBUG(...) avrdude_message(MSG_INFO, __VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG(...)
|
||||
#endif
|
||||
|
||||
#define DEBUGRECV(...) avrdude_message(MSG_TRACE2, __VA_ARGS__)
|
||||
#if 0
|
||||
#define DEBUGRECV(...) avrdude_message(MSG_INFO, __VA_ARGS__)
|
||||
#else
|
||||
#define DEBUGRECV(...)
|
||||
#endif
|
||||
|
||||
enum hvmode
|
||||
{
|
||||
@@ -348,9 +356,6 @@ static void stk500v2_jtagmkII_teardown(PROGRAMMER * pgm)
|
||||
{
|
||||
void *mycookie;
|
||||
|
||||
free(PDATA(pgm)->flash_pagecache);
|
||||
free(PDATA(pgm)->eeprom_pagecache);
|
||||
|
||||
mycookie = pgm->cookie;
|
||||
pgm->cookie = PDATA(pgm)->chained_pdata;
|
||||
jtagmkII_teardown(pgm);
|
||||
@@ -573,7 +578,6 @@ static int stk500v2_jtagmkII_recv(PROGRAMMER * pgm, unsigned char *msg,
|
||||
return -1;
|
||||
}
|
||||
memcpy(msg, jtagmsg + 1, rv - 1);
|
||||
free(jtagmsg);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -1290,14 +1294,14 @@ static int stk500v2_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
for (ln = lfirst(p->mem); ln; ln = lnext(ln)) {
|
||||
m = ldata(ln);
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
if (m->page_size > 1) {
|
||||
if (m->page_size > 0) {
|
||||
if (m->page_size > 256)
|
||||
PDATA(pgm)->flash_pagesize = 256;
|
||||
else
|
||||
PDATA(pgm)->flash_pagesize = m->page_size;
|
||||
}
|
||||
} else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
if (m->page_size > 1)
|
||||
if (m->page_size > 0)
|
||||
PDATA(pgm)->eeprom_pagesize = m->page_size;
|
||||
}
|
||||
}
|
||||
@@ -1389,14 +1393,14 @@ static int stk500v2_jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
for (ln = lfirst(p->mem); ln; ln = lnext(ln)) {
|
||||
m = ldata(ln);
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
if (m->page_size > 1) {
|
||||
if (m->page_size > 0) {
|
||||
if (m->page_size > 256)
|
||||
PDATA(pgm)->flash_pagesize = 256;
|
||||
else
|
||||
PDATA(pgm)->flash_pagesize = m->page_size;
|
||||
}
|
||||
} else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
if (m->page_size > 1)
|
||||
if (m->page_size > 0)
|
||||
PDATA(pgm)->eeprom_pagesize = m->page_size;
|
||||
}
|
||||
}
|
||||
@@ -1460,14 +1464,14 @@ static int stk500hv_initialize(PROGRAMMER * pgm, AVRPART * p, enum hvmode mode)
|
||||
for (ln = lfirst(p->mem); ln; ln = lnext(ln)) {
|
||||
m = ldata(ln);
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
if (m->page_size > 1) {
|
||||
if (m->page_size > 0) {
|
||||
if (m->page_size > 256)
|
||||
PDATA(pgm)->flash_pagesize = 256;
|
||||
else
|
||||
PDATA(pgm)->flash_pagesize = m->page_size;
|
||||
}
|
||||
} else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
if (m->page_size > 1)
|
||||
if (m->page_size > 0)
|
||||
PDATA(pgm)->eeprom_pagesize = m->page_size;
|
||||
}
|
||||
}
|
||||
@@ -1613,11 +1617,11 @@ static int stk500v2_open(PROGRAMMER * pgm, char * port)
|
||||
PDATA(pgm)->pgmtype = PGMTYPE_UNKNOWN;
|
||||
|
||||
if(strcasecmp(port, "avrdoper") == 0){
|
||||
#if defined(HAVE_LIBHIDAPI) || (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
|
||||
#if defined(HAVE_LIBUSB) || (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
|
||||
serdev = &avrdoper_serdev;
|
||||
PDATA(pgm)->pgmtype = PGMTYPE_STK500;
|
||||
#else
|
||||
avrdude_message(MSG_INFO, "avrdoper requires avrdude with hid support.\n");
|
||||
avrdude_message(MSG_INFO, "avrdude was compiled without usb support.\n");
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
@@ -2172,9 +2176,6 @@ static int stk500isp_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
paddr = addr & ~(pagesize - 1);
|
||||
paddr_ptr = &PDATA(pgm)->flash_pageaddr;
|
||||
cache_ptr = PDATA(pgm)->flash_pagecache;
|
||||
if ((mem->mode & 1) == 0)
|
||||
/* old, unpaged device, really write single bytes */
|
||||
pagesize = 1;
|
||||
} else {
|
||||
pagesize = mem->page_size;
|
||||
if (pagesize == 0)
|
||||
@@ -2823,17 +2824,11 @@ static int stk500v2_set_sck_period_mk2(PROGRAMMER * pgm, double v)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(avrispmkIIfreqs) / sizeof(avrispmkIIfreqs[0]); i++) {
|
||||
for (i = 0; i < sizeof(avrispmkIIfreqs); i++) {
|
||||
if (1 / avrispmkIIfreqs[i] >= v)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= sizeof(avrispmkIIfreqs) / sizeof(avrispmkIIfreqs[0])) {
|
||||
avrdude_message(MSG_INFO, "%s: stk500v2_set_sck_period_mk2(): "
|
||||
"invalid SCK period: %g\n", progname, v);
|
||||
return -1;
|
||||
}
|
||||
|
||||
avrdude_message(MSG_NOTICE2, "Using p = %.2f us for SCK (param = %d)\n",
|
||||
1000000 / avrispmkIIfreqs[i], i);
|
||||
|
||||
@@ -3158,9 +3153,8 @@ static const char *stk600_get_cardname(const struct carddata *table,
|
||||
|
||||
static void stk500v2_display(PROGRAMMER * pgm, const char * p)
|
||||
{
|
||||
unsigned char maj = 0, min = 0, hdw = 0, topcard = 0,
|
||||
maj_s1 = 0, min_s1 = 0, maj_s2 = 0, min_s2 = 0;
|
||||
unsigned int rev = 0;
|
||||
unsigned char maj, min, hdw, topcard, maj_s1, min_s1, maj_s2, min_s2;
|
||||
unsigned int rev;
|
||||
const char *topcard_name, *pgmname;
|
||||
|
||||
switch (PDATA(pgm)->pgmtype) {
|
||||
@@ -3731,7 +3725,7 @@ static int stk600_xprog_program_enable(PROGRAMMER * pgm, AVRPART * p)
|
||||
return -1;
|
||||
}
|
||||
if ((mem = avr_locate_mem(p, "eeprom")) != NULL) {
|
||||
if (mem->page_size <= 1) {
|
||||
if (mem->page_size == 0) {
|
||||
avrdude_message(MSG_INFO, "%s: stk600_xprog_program_enable(): no EEPROM page_size parameter for PDI device\n",
|
||||
progname);
|
||||
return -1;
|
||||
@@ -3938,8 +3932,7 @@ static int stk600_xprog_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
b[1] = XPRG_MEM_TYPE_FUSE;
|
||||
} else if (strncmp(mem->desc, "lock", strlen("lock")) == 0) {
|
||||
b[1] = XPRG_MEM_TYPE_LOCKBITS;
|
||||
} else if (strcmp(mem->desc, "calibration") == 0 ||
|
||||
strcmp(mem->desc, "prodsig") == 0) {
|
||||
} else if (strcmp(mem->desc, "calibration") == 0) {
|
||||
b[1] = XPRG_MEM_TYPE_FACTORY_CALIBRATION;
|
||||
} else if (strcmp(mem->desc, "usersig") == 0) {
|
||||
b[1] = XPRG_MEM_TYPE_USERSIG;
|
||||
@@ -4013,8 +4006,7 @@ static int stk600_xprog_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
memtype = XPRG_MEM_TYPE_FUSE;
|
||||
} else if (strncmp(mem->desc, "lock", strlen("lock")) == 0) {
|
||||
memtype = XPRG_MEM_TYPE_LOCKBITS;
|
||||
} else if (strcmp(mem->desc, "calibration") == 0 ||
|
||||
strcmp(mem->desc, "prodsig") == 0) {
|
||||
} else if (strcmp(mem->desc, "calibration") == 0) {
|
||||
memtype = XPRG_MEM_TYPE_FACTORY_CALIBRATION;
|
||||
} else if (strcmp(mem->desc, "usersig") == 0) {
|
||||
memtype = XPRG_MEM_TYPE_USERSIG;
|
||||
|
||||
13
term.c
13
term.c
@@ -342,7 +342,7 @@ static int cmd_write(PROGRAMMER * pgm, struct avrpart * p,
|
||||
|
||||
if (argc < 4) {
|
||||
avrdude_message(MSG_INFO, "Usage: write <memtype> <addr> <byte1> "
|
||||
"<byte2> ... <byteN>\n");
|
||||
"<byte2> ... byteN>\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -624,7 +624,7 @@ static int cmd_fosc(PROGRAMMER * pgm, struct avrpart * p,
|
||||
return -2;
|
||||
}
|
||||
if ((rc = pgm->set_fosc(pgm, v)) != 0) {
|
||||
avrdude_message(MSG_INFO, "%s (fosc): failed to set oscillator frequency (rc = %d)\n",
|
||||
avrdude_message(MSG_INFO, "%s (fosc): failed to set oscillator_frequency (rc = %d)\n",
|
||||
progname, rc);
|
||||
return -3;
|
||||
}
|
||||
@@ -780,12 +780,11 @@ static int cmd_verbose(PROGRAMMER * pgm, struct avrpart * p,
|
||||
|
||||
static int tokenize(char * s, char *** argv)
|
||||
{
|
||||
int i, n, l, k, nargs, offset;
|
||||
int i, n, l, nargs, offset;
|
||||
int len, slen;
|
||||
char * buf;
|
||||
int bufsize;
|
||||
char ** bufv;
|
||||
char * bufp;
|
||||
char * q, * r;
|
||||
char * nbuf;
|
||||
char ** av;
|
||||
@@ -822,15 +821,9 @@ static int tokenize(char * s, char *** argv)
|
||||
/* realloc space for another 20 args */
|
||||
bufsize += 20;
|
||||
nargs += 20;
|
||||
bufp = buf;
|
||||
buf = realloc(buf, bufsize);
|
||||
bufv = realloc(bufv, nargs*sizeof(char *));
|
||||
nbuf = &buf[l];
|
||||
/* correct bufv pointers */
|
||||
k = buf - bufp;
|
||||
for (i=0; i<n; i++) {
|
||||
bufv[i] = bufv[i] + k;
|
||||
}
|
||||
for (i=n; i<nargs; i++)
|
||||
bufv[i] = NULL;
|
||||
}
|
||||
|
||||
@@ -1,229 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:f="http://functions"
|
||||
exclude-result-prefixes="xs f"
|
||||
version="2.0">
|
||||
|
||||
<!--
|
||||
avrdude - A Downloader/Uploader for AVR device programmers
|
||||
Copyright (C) 2018 Morten Engelhardt Olsen <meolsen@atmel.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<xsl:output method="text"/>
|
||||
|
||||
<xsl:template match="/">
|
||||
|
||||
<xsl:variable name="architecture"
|
||||
select="/avr-tools-device-file/devices/device/@architecture"/>
|
||||
|
||||
<xsl:choose>
|
||||
<xsl:when test="$architecture = 'AVR8X'">
|
||||
<xsl:call-template name="create-avr8x-config"/>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:message terminate="yes">No support for architecture '<xsl:value-of select="$architecture"/>'</xsl:message>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="create-avr8x-config">
|
||||
|
||||
<xsl:variable name="device-name"
|
||||
select="/avr-tools-device-file/devices/device/@name"/>
|
||||
<xsl:variable name="device-id">
|
||||
<xsl:call-template name="get-device-id">
|
||||
<xsl:with-param name="device-name" select="$device-name"/>
|
||||
</xsl:call-template>
|
||||
</xsl:variable>
|
||||
<xsl:variable name="parent-name">
|
||||
<xsl:call-template name="get-parent-name">
|
||||
<xsl:with-param name="device-name" select="$device-name"/>
|
||||
</xsl:call-template>
|
||||
</xsl:variable>
|
||||
<xsl:variable name="device-signature">
|
||||
<xsl:call-template name="get-device-signature">
|
||||
<xsl:with-param name="device-name" select="$device-name"/>
|
||||
</xsl:call-template>
|
||||
</xsl:variable>
|
||||
|
||||
<xsl:call-template name="write-conf-header">
|
||||
<xsl:with-param name="device-name" select="$device-name"/>
|
||||
</xsl:call-template>
|
||||
|
||||
<xsl:text>part parent "</xsl:text><xsl:value-of select="normalize-space($parent-name)"/><xsl:text>";
</xsl:text>
|
||||
<xsl:text> id = "</xsl:text><xsl:value-of select="normalize-space($device-id)"/><xsl:text>";
</xsl:text>
|
||||
<xsl:text> desc = "</xsl:text><xsl:value-of select="normalize-space($device-name)"/><xsl:text>";
</xsl:text>
|
||||
<xsl:text> signature = </xsl:text><xsl:value-of select="normalize-space($device-signature)"/><xsl:text>;
</xsl:text>
|
||||
|
||||
<xsl:call-template name="write-memories">
|
||||
<xsl:with-param name="device-name" select="$device-name"/>
|
||||
</xsl:call-template>
|
||||
|
||||
<xsl:text>;
</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="write-memories">
|
||||
<xsl:param name="device-name"/>
|
||||
|
||||
<xsl:call-template name="write-memory">
|
||||
<xsl:with-param name="memory-name" select="'PROGMEM'"/>
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="write-memory">
|
||||
<xsl:with-param name="memory-name" select="'EEPROM'"/>
|
||||
</xsl:call-template>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="write-memory">
|
||||
<xsl:param name="memory-name"/>
|
||||
|
||||
<xsl:variable name="memory-segment" select="//memory-segment[@name = $memory-name]"/>
|
||||
<xsl:choose>
|
||||
<xsl:when test="not($memory-segment)">
|
||||
<xsl:message terminate="yes">No memory-segment named '<xsl:value-of select="$memory-name"/>'</xsl:message>
|
||||
</xsl:when>
|
||||
<xsl:when test="count($memory-segment) > 1">
|
||||
<xsl:message terminate="yes">More than one memory-segments named '<xsl:value-of select="$memory-name"/>'</xsl:message>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:call-template name="write-memory-segment">
|
||||
<xsl:with-param name="memory-segment" select="$memory-segment"/>
|
||||
</xsl:call-template>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="write-memory-segment">
|
||||
<xsl:param name="memory-segment"/>
|
||||
|
||||
<xsl:variable name="size">
|
||||
<xsl:value-of select="concat('0x', f:decimalToHex(f:hexToDec($memory-segment/@size)))"/>
|
||||
</xsl:variable>
|
||||
|
||||
<xsl:variable name="offset">
|
||||
<xsl:choose>
|
||||
<xsl:when test="$memory-segment/@type = 'flash' and $memory-segment/ancestor::device/@architecture = 'AVR8X'">
|
||||
<xsl:variable name="progmem-base"
|
||||
select="f:hexToDec($memory-segment/ancestor::device/property-groups/property-group[@name = 'UPDI_INTERFACE']/property[@name = 'PROGMEM_OFFSET']/@value)"/>
|
||||
<xsl:value-of select="concat('0x', f:decimalToHex(f:hexToDec($memory-segment/@start) + $progmem-base))"/>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="concat('0x', f:decimalToHex(f:hexToDec($memory-segment/@start)))"/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:variable>
|
||||
|
||||
<xsl:text>
</xsl:text>
|
||||
<xsl:text> memory "</xsl:text><xsl:value-of select="$memory-segment/@type"/><xsl:text>"
</xsl:text>
|
||||
<xsl:text> size = </xsl:text><xsl:value-of select="$size"/><xsl:text>;
</xsl:text>
|
||||
<xsl:text> offset = </xsl:text><xsl:value-of select="$offset"/><xsl:text>;
</xsl:text>
|
||||
<xsl:text> page_size = </xsl:text><xsl:value-of select="$memory-segment/@pagesize"/><xsl:text>;
</xsl:text>
|
||||
<xsl:text> readsize = 0x100;
</xsl:text>
|
||||
<xsl:text> ;
</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="write-conf-header">
|
||||
<xsl:param name="device-name"/>
|
||||
|
||||
<xsl:text>#------------------------------------------------------------
</xsl:text>
|
||||
<xsl:text># </xsl:text><xsl:value-of select="$device-name"/><xsl:text>
</xsl:text>
|
||||
<xsl:text>#------------------------------------------------------------
</xsl:text>
|
||||
<xsl:text>
</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="get-device-id">
|
||||
<xsl:param name="device-name"/>
|
||||
|
||||
<xsl:choose>
|
||||
<xsl:when test="contains($device-name, 'ATtiny')">
|
||||
<xsl:value-of select="replace($device-name, 'ATtiny', 't')"/>
|
||||
</xsl:when>
|
||||
<xsl:when test="contains($device-name, 'ATmega')">
|
||||
<xsl:value-of select="replace($device-name, 'ATmega', 'm')"/>
|
||||
</xsl:when>
|
||||
<xsl:when test="starts-with($device-name, 'AVR')">
|
||||
<xsl:value-of select="lower-case($device-name)"/>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:message terminate="yes">Unable to deduce device id from '<xsl:value-of select="$device-name"/>'</xsl:message>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="get-parent-name">
|
||||
<xsl:param name="device-name"/>
|
||||
|
||||
<xsl:choose>
|
||||
<xsl:when test="contains($device-name, 'ATtiny')">.avr8x_tiny</xsl:when>
|
||||
<xsl:when test="contains($device-name, 'ATmega')">.avr8x_mega</xsl:when>
|
||||
<xsl:when test="matches($device-name, '^AVR[0-9]{1,3}D')">.avrdx</xsl:when>
|
||||
<xsl:when test="matches($device-name, '^AVR[0-9]{1,3}E')">.avrex</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:message terminate="yes">Unable to deduce parent name from '<xsl:value-of select="$device-name"/>'</xsl:message>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="get-device-signature">
|
||||
<xsl:param name="device-name"/>
|
||||
|
||||
<xsl:variable name="signatures"
|
||||
select="/avr-tools-device-file/devices/device/property-groups/property-group[@name = 'SIGNATURES']"/>
|
||||
|
||||
<xsl:for-each select="$signatures/property[contains(@name, 'SIGNATURE')]">
|
||||
<xsl:value-of select="@value"/><xsl:text> </xsl:text>
|
||||
</xsl:for-each>
|
||||
</xsl:template>
|
||||
|
||||
<!-- Helper functions (from https://stackoverflow.com/questions/22905134/convert-a-hexadecimal-number-to-an-integer-in-xslt) -->
|
||||
<xsl:function name="f:hexToDec">
|
||||
<xsl:param name="hex"/>
|
||||
<xsl:variable name="dec"
|
||||
select="string-length(substring-before('0123456789ABCDEF', substring($hex,1,1)))"/>
|
||||
<xsl:choose>
|
||||
<xsl:when test="matches($hex, '([0-9]*|[A-F]*)')">
|
||||
<xsl:value-of
|
||||
select="if ($hex = '') then 0
|
||||
else $dec * f:power(16, string-length($hex) - 1) + f:hexToDec(substring($hex,2))"/>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:message>Provided value is not hexadecimal...</xsl:message>
|
||||
<xsl:value-of select="$hex"/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:function>
|
||||
|
||||
<xsl:function name="f:power">
|
||||
<xsl:param name="base"/>
|
||||
<xsl:param name="exp"/>
|
||||
<xsl:sequence
|
||||
select="if ($exp lt 0) then f:power(1.0 div $base, -$exp)
|
||||
else if ($exp eq 0)
|
||||
then 1e0
|
||||
else $base * f:power($base, $exp - 1)"
|
||||
/>
|
||||
</xsl:function>
|
||||
|
||||
<xsl:function name="f:decimalToHex">
|
||||
<xsl:param name="dec"/>
|
||||
<xsl:if test="$dec > 0">
|
||||
<xsl:value-of
|
||||
select="f:decimalToHex(floor($dec div 16)),substring('0123456789ABCDEF', (($dec mod 16) + 1), 1)"
|
||||
separator=""
|
||||
/>
|
||||
</xsl:if>
|
||||
</xsl:function>
|
||||
</xsl:stylesheet>
|
||||
@@ -40,8 +40,8 @@ mkdir -p ${BUILDDIR} || { echo "Cannot create build dir $BUILDDIR"; exit 1; }
|
||||
|
||||
cd ${BUILDDIR} || { echo "Cannot chdir to $BUILDDIR"; exit 1; }
|
||||
|
||||
LDFLAGS="-L${MINGW32_PREFIX}/lib -L${LIBUSB_PREFIX}/lib/gcc -L/tmp/libftdi1-1.3git_devkit_mingw32_13Dec2015/lib"
|
||||
CPPFLAGS="-I${MINGW32_PREFIX}/include -I${LIBUSB_PREFIX}/include -I/tmp/libftdi1-1.3git_devkit_mingw32_13Dec2015/include"
|
||||
LDFLAGS="-L${MINGW32_PREFIX}/lib -L${LIBUSB_PREFIX}/lib/gcc"
|
||||
CPPFLAGS="-I${MINGW32_PREFIX}/include -I${LIBUSB_PREFIX}/include"
|
||||
|
||||
env \
|
||||
CC="${CC}" \
|
||||
@@ -51,4 +51,4 @@ env \
|
||||
--host=$(../../config.guess) \
|
||||
--target=${tgt}
|
||||
|
||||
${MAKE:-make} all
|
||||
make all
|
||||
|
||||
13
update.c
13
update.c
@@ -113,9 +113,7 @@ UPDATE * parse_op(char * s)
|
||||
cp = p;
|
||||
p = strrchr(cp, ':');
|
||||
if (p == NULL) {
|
||||
// missing format, default to "AUTO" for write and verify,
|
||||
// and to binary for read operations:
|
||||
upd->format = upd->op == DEVICE_READ? FMT_RBIN: FMT_AUTO;
|
||||
upd->format = FMT_AUTO;
|
||||
fnlen = strlen(cp);
|
||||
upd->filename = (char *)malloc(fnlen + 1);
|
||||
} else {
|
||||
@@ -230,12 +228,6 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f
|
||||
/*
|
||||
* read out the specified device memory and write it to a file
|
||||
*/
|
||||
if (upd->format == FMT_IMM) {
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: Invalid file format 'immediate' for output\n",
|
||||
progname, upd->filename);
|
||||
return -1;
|
||||
}
|
||||
if (quell_progress < 2) {
|
||||
avrdude_message(MSG_INFO, "%s: reading %s memory:\n",
|
||||
progname, mem->desc);
|
||||
@@ -354,7 +346,6 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f
|
||||
avrdude_message(MSG_INFO, "%s: failed to read all of %s memory, rc=%d\n",
|
||||
progname, mem->desc, rc);
|
||||
pgm->err_led(pgm, ON);
|
||||
avr_free_part(v);
|
||||
return -1;
|
||||
}
|
||||
report_progress (1,1,NULL);
|
||||
@@ -369,7 +360,6 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f
|
||||
avrdude_message(MSG_INFO, "%s: verification error; content mismatch\n",
|
||||
progname);
|
||||
pgm->err_led(pgm, ON);
|
||||
avr_free_part(v);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -379,7 +369,6 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f
|
||||
}
|
||||
|
||||
pgm->vfy_led(pgm, OFF);
|
||||
avr_free_part(v);
|
||||
}
|
||||
else {
|
||||
avrdude_message(MSG_INFO, "%s: invalid update operation (%d) requested\n",
|
||||
|
||||
357
usb_hidapi.c
357
usb_hidapi.c
@@ -1,357 +0,0 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2016 Joerg Wunsch
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* USB interface via libhidapi for avrdude.
|
||||
*/
|
||||
|
||||
#include "ac_cfg.h"
|
||||
#if defined(HAVE_LIBHIDAPI)
|
||||
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "libavrdude.h"
|
||||
|
||||
#include "usbdevs.h"
|
||||
|
||||
#if defined(WIN32NATIVE)
|
||||
/* someone has defined "interface" to "struct" in Cygwin */
|
||||
# undef interface
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The "baud" parameter is meaningless for USB devices, so we reuse it
|
||||
* to pass the desired USB device ID.
|
||||
*/
|
||||
static int usbhid_open(char * port, union pinfo pinfo, union filedescriptor *fd)
|
||||
{
|
||||
hid_device *dev;
|
||||
char *serno, *cp2;
|
||||
size_t x;
|
||||
unsigned char usbbuf[USBDEV_MAX_XFER_3 + 1];
|
||||
|
||||
if (fd->usb.max_xfer == 0)
|
||||
fd->usb.max_xfer = USBDEV_MAX_XFER_3;
|
||||
|
||||
/*
|
||||
* The syntax for usb devices is defined as:
|
||||
*
|
||||
* -P usb[:serialnumber]
|
||||
*
|
||||
* See if we've got a serial number passed here. The serial number
|
||||
* might contain colons which we remove below, and we compare it
|
||||
* right-to-left, so only the least significant nibbles need to be
|
||||
* specified.
|
||||
*/
|
||||
if ((serno = strchr(port, ':')) != NULL)
|
||||
{
|
||||
/* first, drop all colons there if any */
|
||||
cp2 = ++serno;
|
||||
|
||||
while ((cp2 = strchr(cp2, ':')) != NULL)
|
||||
{
|
||||
x = strlen(cp2) - 1;
|
||||
memmove(cp2, cp2 + 1, x);
|
||||
cp2[x] = '\0';
|
||||
}
|
||||
|
||||
if (strlen(serno) > 12)
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: usbhid_open(): invalid serial number \"%s\"\n",
|
||||
progname, serno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
wchar_t wserno[15];
|
||||
mbstowcs(wserno, serno, 15);
|
||||
size_t serlen = strlen(serno);
|
||||
|
||||
/*
|
||||
* Now, try finding all devices matching VID:PID, and compare
|
||||
* their serial numbers against the requested one.
|
||||
*/
|
||||
struct hid_device_info *list, *walk;
|
||||
list = hid_enumerate(pinfo.usbinfo.vid, pinfo.usbinfo.pid);
|
||||
if (list == NULL)
|
||||
return -1;
|
||||
|
||||
walk = list;
|
||||
while (walk)
|
||||
{
|
||||
avrdude_message(MSG_NOTICE, "%s: usbhid_open(): Found %ls, serno: %ls\n",
|
||||
progname, walk->product_string, walk->serial_number);
|
||||
size_t slen = wcslen(walk->serial_number);
|
||||
if (slen >= serlen &&
|
||||
wcscmp(walk->serial_number + slen - serlen, wserno) == 0)
|
||||
{
|
||||
/* found matching serial number */
|
||||
break;
|
||||
}
|
||||
avrdude_message(MSG_DEBUG, "%s: usbhid_open(): serial number doesn't match\n",
|
||||
progname);
|
||||
walk = walk->next;
|
||||
}
|
||||
if (walk == NULL)
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: usbhid_open(): No matching device found\n",
|
||||
progname);
|
||||
hid_free_enumeration(list);
|
||||
return -1;
|
||||
}
|
||||
avrdude_message(MSG_DEBUG, "%s: usbhid_open(): Opening path %s\n",
|
||||
progname, walk->path);
|
||||
dev = hid_open_path(walk->path);
|
||||
hid_free_enumeration(list);
|
||||
if (dev == NULL)
|
||||
{
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: usbhid_open(): Found device, but hid_open_path() failed\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* No serial number requested, pass straight to hid_open()
|
||||
*/
|
||||
dev = hid_open(pinfo.usbinfo.vid, pinfo.usbinfo.pid, NULL);
|
||||
if (dev == NULL)
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: usbhid_open(): No device found\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
fd->usb.handle = dev;
|
||||
|
||||
/*
|
||||
* Try finding out the endpoint size. Alas, libhidapi doesn't
|
||||
* provide us with an API function for that, nor for the report
|
||||
* descriptor (which also contains that information).
|
||||
*
|
||||
* Since the Atmel tools a very picky to only respond to incoming
|
||||
* packets that have full size, we need to know whether our device
|
||||
* handles 512-byte data (JTAGICE3 in CMSIS-DAP mode, or AtmelICE,
|
||||
* both on USB 2.0 connections), or 64-byte data only (both these on
|
||||
* USB 1.1 connections, or mEDBG devices).
|
||||
*
|
||||
* In order to find out, we send a CMSIS-DAP DAP_Info command
|
||||
* (0x00), with an ID of 0xFF (get maximum packet size). In theory,
|
||||
* this gets us the desired information, but this suffers from a
|
||||
* chicken-and-egg problem: the request must be sent with a
|
||||
* full-sized packet lest the ICE won't answer. Thus, we send a
|
||||
* 64-byte packet first, and if we don't get a timely reply,
|
||||
* complete that request by sending another 448 bytes, and hope it
|
||||
* will eventually reply.
|
||||
*
|
||||
* Note that libhidapi always requires a report ID as the first
|
||||
* byte. If the target doesn't use report IDs (Atmel targets
|
||||
* don't), this first byte must be 0x00. However, the length must
|
||||
* be incremented by one, as the report ID will be omitted by the
|
||||
* hidapi library.
|
||||
*/
|
||||
if (pinfo.usbinfo.vid == USB_VENDOR_ATMEL)
|
||||
{
|
||||
avrdude_message(MSG_DEBUG, "%s: usbhid_open(): Probing for max. packet size\n",
|
||||
progname);
|
||||
memset(usbbuf, 0, sizeof usbbuf);
|
||||
usbbuf[0] = 0; /* no HID reports used */
|
||||
usbbuf[1] = 0; /* DAP_Info */
|
||||
usbbuf[2] = 0xFF; /* get max. packet size */
|
||||
|
||||
hid_write(dev, usbbuf, 65);
|
||||
fd->usb.max_xfer = 64; /* first guess */
|
||||
|
||||
memset(usbbuf, 0, sizeof usbbuf);
|
||||
int res = hid_read_timeout(dev, usbbuf, 10 /* bytes */, 50 /* milliseconds */);
|
||||
if (res == 0) {
|
||||
/* no timely response, assume 512 byte size */
|
||||
hid_write(dev, usbbuf, (512 - 64) + 1);
|
||||
fd->usb.max_xfer = 512;
|
||||
res = hid_read_timeout(dev, usbbuf, 10, 50);
|
||||
}
|
||||
if (res <= 0) {
|
||||
avrdude_message(MSG_INFO, "%s: usbhid_open(): No response from device\n",
|
||||
progname);
|
||||
hid_close(dev);
|
||||
return -1;
|
||||
}
|
||||
if (usbbuf[0] != 0 || usbbuf[1] != 2) {
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: usbhid_open(): Unexpected reply to DAP_Info: 0x%02x 0x%02x\n",
|
||||
progname, usbbuf[0], usbbuf[1]);
|
||||
} else {
|
||||
fd->usb.max_xfer = usbbuf[2] + (usbbuf[3] << 8);
|
||||
avrdude_message(MSG_DEBUG,
|
||||
"%s: usbhid_open(): Setting max_xfer from DAP_Info response to %d\n",
|
||||
progname, fd->usb.max_xfer);
|
||||
}
|
||||
}
|
||||
if (fd->usb.max_xfer > USBDEV_MAX_XFER_3) {
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: usbhid_open(): Unexpected max size %d, reducing to %d\n",
|
||||
progname, fd->usb.max_xfer, USBDEV_MAX_XFER_3);
|
||||
fd->usb.max_xfer = USBDEV_MAX_XFER_3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void usbhid_close(union filedescriptor *fd)
|
||||
{
|
||||
hid_device *udev = (hid_device *)fd->usb.handle;
|
||||
|
||||
if (udev == NULL)
|
||||
return;
|
||||
|
||||
hid_close(udev);
|
||||
}
|
||||
|
||||
|
||||
static int usbhid_send(union filedescriptor *fd, const unsigned char *bp, size_t mlen)
|
||||
{
|
||||
hid_device *udev = (hid_device *)fd->usb.handle;
|
||||
int rv;
|
||||
int i = mlen;
|
||||
const unsigned char * p = bp;
|
||||
unsigned char usbbuf[USBDEV_MAX_XFER_3 + 1];
|
||||
|
||||
|
||||
int tx_size;
|
||||
|
||||
if (udev == NULL)
|
||||
return -1;
|
||||
|
||||
tx_size = (mlen < USBDEV_MAX_XFER_3)? mlen: USBDEV_MAX_XFER_3;
|
||||
usbbuf[0] = 0; /* no report ID used */
|
||||
memcpy(usbbuf + 1, bp, tx_size);
|
||||
rv = hid_write(udev, usbbuf, tx_size + 1);
|
||||
if (rv < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: Failed to write %d bytes to USB\n",
|
||||
progname, tx_size);
|
||||
return -1;
|
||||
}
|
||||
if (rv != tx_size + 1)
|
||||
avrdude_message(MSG_INFO, "%s: Short write to USB: %d bytes out of %d written\n",
|
||||
progname, rv, tx_size + 1);
|
||||
|
||||
if (verbose > 4)
|
||||
{
|
||||
avrdude_message(MSG_TRACE2, "%s: Sent: ", progname);
|
||||
|
||||
while (i) {
|
||||
unsigned char c = *p;
|
||||
if (isprint(c)) {
|
||||
avrdude_message(MSG_TRACE2, "%c ", c);
|
||||
}
|
||||
else {
|
||||
avrdude_message(MSG_TRACE2, ". ");
|
||||
}
|
||||
avrdude_message(MSG_TRACE2, "[%02x] ", c);
|
||||
|
||||
p++;
|
||||
i--;
|
||||
}
|
||||
avrdude_message(MSG_TRACE2, "\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int usbhid_recv(union filedescriptor *fd, unsigned char *buf, size_t nbytes)
|
||||
{
|
||||
hid_device *udev = (hid_device *)fd->usb.handle;
|
||||
int i, rv;
|
||||
unsigned char * p = buf;
|
||||
|
||||
if (udev == NULL)
|
||||
return -1;
|
||||
|
||||
rv = i = hid_read_timeout(udev, buf, nbytes, 300);
|
||||
if (i != nbytes)
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: Short read, read only %d out of %u bytes\n",
|
||||
progname, i, nbytes);
|
||||
|
||||
if (verbose > 4)
|
||||
{
|
||||
avrdude_message(MSG_TRACE2, "%s: Recv: ", progname);
|
||||
|
||||
while (i) {
|
||||
unsigned char c = *p;
|
||||
if (isprint(c)) {
|
||||
avrdude_message(MSG_TRACE2, "%c ", c);
|
||||
}
|
||||
else {
|
||||
avrdude_message(MSG_TRACE2, ". ");
|
||||
}
|
||||
avrdude_message(MSG_TRACE2, "[%02x] ", c);
|
||||
|
||||
p++;
|
||||
i--;
|
||||
}
|
||||
avrdude_message(MSG_TRACE2, "\n");
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int usbhid_drain(union filedescriptor *fd, int display)
|
||||
{
|
||||
/*
|
||||
* There is not much point in trying to flush any data
|
||||
* on an USB endpoint, as the endpoint is supposed to
|
||||
* start afresh after being configured from the host.
|
||||
*
|
||||
* As trying to flush the data here caused strange effects
|
||||
* in some situations (see
|
||||
* https://savannah.nongnu.org/bugs/index.php?43268 )
|
||||
* better avoid it.
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Device descriptor.
|
||||
*/
|
||||
struct serial_device usbhid_serdev =
|
||||
{
|
||||
.open = usbhid_open,
|
||||
.close = usbhid_close,
|
||||
.send = usbhid_send,
|
||||
.recv = usbhid_recv,
|
||||
.drain = usbhid_drain,
|
||||
.flags = SERDEV_FL_NONE,
|
||||
};
|
||||
|
||||
#endif /* HAVE_LIBHIDAPI */
|
||||
@@ -166,13 +166,6 @@ static int usbdev_open(char * port, union pinfo pinfo, union filedescriptor *fd)
|
||||
fd->usb.eep = 0;
|
||||
}
|
||||
|
||||
if(strstr(product, "mEDBG") != NULL)
|
||||
{
|
||||
/* The AVR Xplained Mini uses different endpoints. */
|
||||
fd->usb.rep = 0x81;
|
||||
fd->usb.wep = 0x02;
|
||||
}
|
||||
|
||||
avrdude_message(MSG_NOTICE, "%s: usbdev_open(): Found %s, serno: %s\n",
|
||||
progname, product, string);
|
||||
if (serno != NULL)
|
||||
@@ -360,7 +353,7 @@ static int usbdev_send(union filedescriptor *fd, const unsigned char *bp, size_t
|
||||
}
|
||||
bp += tx_size;
|
||||
mlen -= tx_size;
|
||||
} while (mlen > 0);
|
||||
} while (tx_size == fd->usb.max_xfer);
|
||||
|
||||
if (verbose > 3)
|
||||
{
|
||||
|
||||
107
usbasp.c
107
usbasp.c
@@ -120,8 +120,6 @@ struct pdata
|
||||
int sckfreq_hz;
|
||||
unsigned int capabilities;
|
||||
int use_tpi;
|
||||
int section_e;
|
||||
int sck_3mhz;
|
||||
};
|
||||
|
||||
#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
|
||||
@@ -133,7 +131,6 @@ struct pdata
|
||||
// interface - management
|
||||
static void usbasp_setup(PROGRAMMER * pgm);
|
||||
static void usbasp_teardown(PROGRAMMER * pgm);
|
||||
static int usbasp_parseextparms(PROGRAMMER * pgm, LISTID extparms);
|
||||
// internal functions
|
||||
static int usbasp_transmit(PROGRAMMER * pgm, unsigned char receive,
|
||||
unsigned char functionid, const unsigned char *send,
|
||||
@@ -195,31 +192,6 @@ static void usbasp_teardown(PROGRAMMER * pgm)
|
||||
free(pgm->cookie);
|
||||
}
|
||||
|
||||
static int usbasp_parseextparms(PROGRAMMER * pgm, LISTID extparms)
|
||||
{
|
||||
LNODEID ln;
|
||||
const char *extended_param;
|
||||
int rv = 0;
|
||||
|
||||
for (ln = lfirst(extparms); ln; ln = lnext(ln)) {
|
||||
extended_param = ldata(ln);
|
||||
|
||||
if (strncmp(extended_param, "section_config", strlen("section_config")) == 0) {
|
||||
avrdude_message(MSG_NOTICE2, "%s: usbasp_parseextparms(): set section_e to 1 (config section)\n",
|
||||
progname);
|
||||
PDATA(pgm)->section_e = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
avrdude_message(MSG_INFO, "%s: usbasp_parseextparms(): invalid extended parameter '%s'\n",
|
||||
progname, extended_param);
|
||||
rv = -1;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/* Internal functions */
|
||||
|
||||
static const char *usbasp_get_funcname(unsigned char functionid)
|
||||
@@ -598,9 +570,6 @@ static int usbasp_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
pdata->capabilities = 0;
|
||||
|
||||
pdata->use_tpi = ((pdata->capabilities & USBASP_CAP_TPI) != 0 && (p->flags & AVRPART_HAS_TPI) != 0) ? 1 : 0;
|
||||
// query support for 3 MHz SCK in UsbAsp-flash firmware
|
||||
// https://github.com/nofeletru/UsbAsp-flash
|
||||
pdata->sck_3mhz = ((pdata->capabilities & USBASP_CAP_3MHZ) != 0) ? 1 :0;
|
||||
|
||||
if(pdata->use_tpi)
|
||||
{
|
||||
@@ -666,7 +635,7 @@ static int usbasp_spi_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
|
||||
if (verbose == 3)
|
||||
putc('\n', stderr);
|
||||
|
||||
avrdude_message(MSG_INFO, "%s: error: wrong response size\n",
|
||||
avrdude_message(MSG_INFO, "%s: error: wrong responds size\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
@@ -867,7 +836,6 @@ static int usbasp_spi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
|
||||
/* The list of SCK frequencies in Hz supported by USBasp */
|
||||
static struct sckoptions_t usbaspSCKoptions[] = {
|
||||
{ USBASP_ISP_SCK_3000, 3000000 },
|
||||
{ USBASP_ISP_SCK_1500, 1500000 },
|
||||
{ USBASP_ISP_SCK_750, 750000 },
|
||||
{ USBASP_ISP_SCK_375, 375000 },
|
||||
@@ -913,23 +881,14 @@ static int usbasp_spi_set_sck_period(PROGRAMMER *pgm, double sckperiod)
|
||||
|
||||
avrdude_message(MSG_NOTICE2, "%s: try to set SCK period to %g s (= %i Hz)\n", progname, sckperiod, sckfreq);
|
||||
|
||||
/* Check if programmer is capable of 3 MHz SCK, if not then ommit 3 MHz setting */
|
||||
int i;
|
||||
if (PDATA(pgm)->sck_3mhz) {
|
||||
avrdude_message(MSG_NOTICE2, "%s: connected USBasp is capable of 3 MHz SCK\n",progname);
|
||||
i = 0;
|
||||
} else {
|
||||
avrdude_message(MSG_NOTICE2, "%s: connected USBasp is not cabable of 3 MHz SCK\n",progname);
|
||||
i = 1;
|
||||
}
|
||||
if (sckfreq >= usbaspSCKoptions[i].frequency) {
|
||||
clockoption = usbaspSCKoptions[i].id;
|
||||
usefreq = usbaspSCKoptions[i].frequency;
|
||||
if (sckfreq >= usbaspSCKoptions[0].frequency) {
|
||||
clockoption = usbaspSCKoptions[0].id;
|
||||
usefreq = usbaspSCKoptions[0].frequency;
|
||||
} else {
|
||||
|
||||
/* find clock option next to given clock */
|
||||
|
||||
for (; i < sizeof(usbaspSCKoptions) / sizeof(usbaspSCKoptions[0]); i++) {
|
||||
int i;
|
||||
for (i = 0; i < sizeof(usbaspSCKoptions) / sizeof(usbaspSCKoptions[0]); i++) {
|
||||
if (sckfreq >= usbaspSCKoptions[i].frequency - 1) { /* subtract 1 to compensate round errors */
|
||||
clockoption = usbaspSCKoptions[i].id;
|
||||
usefreq = usbaspSCKoptions[i].frequency;
|
||||
@@ -977,7 +936,7 @@ static int usbasp_tpi_recv_byte(PROGRAMMER * pgm)
|
||||
|
||||
if(usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_RAWREAD, temp, temp, sizeof(temp)) != 1)
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: error: wrong response size\n", progname);
|
||||
avrdude_message(MSG_INFO, "%s: error: wrong responds size\n", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1056,40 +1015,21 @@ static int usbasp_tpi_program_enable(PROGRAMMER * pgm, AVRPART * p)
|
||||
|
||||
static int usbasp_tpi_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
int pr_0;
|
||||
int pr_1;
|
||||
int nvm_cmd;
|
||||
avrdude_message(MSG_DEBUG, "%s: usbasp_tpi_chip_erase()\n", progname);
|
||||
|
||||
switch (PDATA(pgm)->section_e) {
|
||||
/* Config bits section erase */
|
||||
case 1:
|
||||
pr_0 = 0x41;
|
||||
pr_1 = 0x3F;
|
||||
nvm_cmd = NVMCMD_SECTION_ERASE;
|
||||
avrdude_message(MSG_DEBUG, "%s: usbasp_tpi_chip_erase() - section erase\n", progname);
|
||||
break;
|
||||
/* Chip erase (flash only) */
|
||||
default:
|
||||
pr_0 = 0x01;
|
||||
pr_1 = 0x40;
|
||||
nvm_cmd = NVMCMD_CHIP_ERASE;
|
||||
avrdude_message(MSG_DEBUG, "%s: usbasp_tpi_chip_erase() - chip erase\n", progname);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set PR */
|
||||
/* Set PR to flash */
|
||||
usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(0));
|
||||
usbasp_tpi_send_byte(pgm, pr_0);
|
||||
usbasp_tpi_send_byte(pgm, 0x01);
|
||||
usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(1));
|
||||
usbasp_tpi_send_byte(pgm, pr_1);
|
||||
/* select what been erase */
|
||||
usbasp_tpi_send_byte(pgm, 0x40);
|
||||
/* select ERASE */
|
||||
usbasp_tpi_send_byte(pgm, TPI_OP_SOUT(NVMCMD));
|
||||
usbasp_tpi_send_byte(pgm, nvm_cmd);
|
||||
usbasp_tpi_send_byte(pgm, NVMCMD_CHIP_ERASE);
|
||||
/* dummy write */
|
||||
usbasp_tpi_send_byte(pgm, TPI_OP_SST_INC);
|
||||
usbasp_tpi_send_byte(pgm, 0x00);
|
||||
usbasp_tpi_nvm_waitbusy(pgm);
|
||||
|
||||
|
||||
usleep(p->chip_erase_delay);
|
||||
pgm->initialize(pgm, p);
|
||||
|
||||
@@ -1156,24 +1096,6 @@ static int usbasp_tpi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
pr = addr + m->offset;
|
||||
writed = 0;
|
||||
|
||||
/* must erase fuse first */
|
||||
if(strcmp(m->desc, "fuse") == 0)
|
||||
{
|
||||
/* Set PR */
|
||||
usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(0));
|
||||
usbasp_tpi_send_byte(pgm, (pr & 0xFF) | 1 );
|
||||
usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(1));
|
||||
usbasp_tpi_send_byte(pgm, (pr >> 8) );
|
||||
/* select SECTION_ERASE */
|
||||
usbasp_tpi_send_byte(pgm, TPI_OP_SOUT(NVMCMD));
|
||||
usbasp_tpi_send_byte(pgm, NVMCMD_SECTION_ERASE);
|
||||
/* dummy write */
|
||||
usbasp_tpi_send_byte(pgm, TPI_OP_SST_INC);
|
||||
usbasp_tpi_send_byte(pgm, 0x00);
|
||||
|
||||
usbasp_tpi_nvm_waitbusy(pgm);
|
||||
}
|
||||
|
||||
/* Set PR to flash */
|
||||
usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(0));
|
||||
usbasp_tpi_send_byte(pgm, (pr & 0xFF) | 1 );
|
||||
@@ -1272,7 +1194,6 @@ void usbasp_initpgm(PROGRAMMER * pgm)
|
||||
pgm->setup = usbasp_setup;
|
||||
pgm->teardown = usbasp_teardown;
|
||||
pgm->set_sck_period = usbasp_spi_set_sck_period;
|
||||
pgm->parseextparams = usbasp_parseextparms;
|
||||
|
||||
}
|
||||
|
||||
|
||||
2
usbasp.h
2
usbasp.h
@@ -42,7 +42,6 @@
|
||||
|
||||
/* USBASP capabilities */
|
||||
#define USBASP_CAP_TPI 0x01
|
||||
#define USBASP_CAP_3MHZ (1 << 24) // 3 MHz SCK in UsbAsp-flash firmware
|
||||
|
||||
/* Block mode flags */
|
||||
#define USBASP_BLOCKFLAG_FIRST 1
|
||||
@@ -66,7 +65,6 @@
|
||||
#define USBASP_ISP_SCK_375 10 /* 375 kHz */
|
||||
#define USBASP_ISP_SCK_750 11 /* 750 kHz */
|
||||
#define USBASP_ISP_SCK_1500 12 /* 1.5 MHz */
|
||||
#define USBASP_ISP_SCK_3000 13 /* 3 MHz only UsbAsp-flash firmware*/
|
||||
|
||||
/* TPI instructions */
|
||||
#define TPI_OP_SLD 0x20
|
||||
|
||||
@@ -69,14 +69,7 @@
|
||||
#define USBDEV_BULK_EP_WRITE_3 0x01
|
||||
#define USBDEV_BULK_EP_READ_3 0x82
|
||||
#define USBDEV_EVT_EP_READ_3 0x83
|
||||
/*
|
||||
* The mk3 tools (type jtagice3) have a maxPayloadSize of 912. When
|
||||
* accessing paged memory the access should be limited to pageSize.
|
||||
* When accessing memory without pageSize the payload should be
|
||||
* limited to 256.
|
||||
*/
|
||||
#define USBDEV_MAX_XFER_3 912
|
||||
#define USBDEV_MAX_XFER_3_UNPAGED 256
|
||||
#define USBDEV_MAX_XFER_3 512
|
||||
|
||||
/*
|
||||
* When operating on the JTAGICE3, usbdev_recv_frame() returns an
|
||||
|
||||
217
usbtiny.c
217
usbtiny.c
@@ -47,19 +47,6 @@
|
||||
# error "libusb needs either <usb.h> or <lusb0_usb.h>"
|
||||
#endif
|
||||
|
||||
#include "tpi.h"
|
||||
|
||||
#define TPIPCR_GT_0b 0x07
|
||||
#define TPI_STOP_BITS 0x03
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
# define LITTLE_TO_BIG_16(x) (htons(x))
|
||||
#else
|
||||
// WIN32
|
||||
# define LITTLE_TO_BIG_16(x) ((((x) << 8) & 0xFF00) | (((x) >> 8) & 0x00FF))
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_UINT_T
|
||||
typedef unsigned int uint_t;
|
||||
#endif
|
||||
@@ -186,109 +173,6 @@ static int usb_out (PROGRAMMER * pgm,
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
/* Reverse the bits in a byte. Needed since TPI uses little-endian
|
||||
bit order (LSB first) whereas SPI uses big-endian (MSB first).*/
|
||||
static unsigned char reverse(unsigned char b) {
|
||||
return
|
||||
( (b & 0x01) << 7)
|
||||
| ((b & 0x02) << 5)
|
||||
| ((b & 0x04) << 3)
|
||||
| ((b & 0x08) << 1)
|
||||
| ((b & 0x10) >> 1)
|
||||
| ((b & 0x20) >> 3)
|
||||
| ((b & 0x40) >> 5)
|
||||
| ((b & 0x80) >> 7);
|
||||
}
|
||||
|
||||
/* Calculate even parity. */
|
||||
static unsigned char tpi_parity(unsigned char b)
|
||||
{
|
||||
unsigned char parity = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
if (b & 1)
|
||||
parity ^= 1;
|
||||
b >>= 1;
|
||||
}
|
||||
return parity;
|
||||
}
|
||||
|
||||
/* Encode 1 start bit (0), 8 data bits, 1 parity, 2 stop bits (1)
|
||||
inside 16 bits. The data is padded to 16 bits by 4 leading 1s
|
||||
(which will be ignored since they're not start bits). This layout
|
||||
enables a write to be followed by a read. */
|
||||
static unsigned short tpi_frame(unsigned char b) {
|
||||
return LITTLE_TO_BIG_16(0xf000 |
|
||||
(reverse(b) << 3) |
|
||||
tpi_parity(b) << 2 |
|
||||
TPI_STOP_BITS);
|
||||
}
|
||||
|
||||
/* Transmit a single byte encapsulated in a 32-bit transfer. Unused
|
||||
bits are padded with 1s. */
|
||||
static int usbtiny_tpi_tx(PROGRAMMER *pgm, unsigned char b0)
|
||||
{
|
||||
unsigned char res[4];
|
||||
|
||||
if (usb_in(pgm, USBTINY_SPI, tpi_frame(b0), 0xffff,
|
||||
res, sizeof(res), 8 * sizeof(res) * PDATA(pgm)->sck_period) < 0)
|
||||
return -1;
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "CMD_TPI_TX: [0x%02x]\n", b0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Transmit a two bytes encapsulated in a 32-bit transfer. Unused
|
||||
bits are padded with 1s. */
|
||||
static int usbtiny_tpi_txtx(PROGRAMMER *pgm,
|
||||
unsigned char b0, unsigned char b1)
|
||||
{
|
||||
unsigned char res[4];
|
||||
|
||||
if (usb_in(pgm, USBTINY_SPI, tpi_frame(b0), tpi_frame(b1),
|
||||
res, sizeof(res), 8 * sizeof(res) * PDATA(pgm)->sck_period) < 0)
|
||||
return -1;
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "CMD_TPI_TX_TX: [0x%02x 0x%02x]\n", b0, b1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Transmit a byte then receive a byte, all encapsulated in a 32-bit
|
||||
transfer. Unused bits are padded with 1s. This code assumes that
|
||||
the start bit of the byte being received arrives within at most 2
|
||||
TPICLKs. We ensure this by calling avr_tpi_program_enable() with
|
||||
delay==TPIPCR_GT_0b. */
|
||||
static int usbtiny_tpi_txrx(PROGRAMMER *pgm, unsigned char b0)
|
||||
{
|
||||
unsigned char res[4], r;
|
||||
short w;
|
||||
|
||||
if (usb_in(pgm, USBTINY_SPI, tpi_frame(b0), 0xffff,
|
||||
res, sizeof(res), 8 * sizeof(res) * PDATA(pgm)->sck_period) < 0)
|
||||
return -1;
|
||||
|
||||
w = (res[2] << 8) | res[3];
|
||||
/* Look for start bit (there shoule be no more than two 1 bits): */
|
||||
while (w < 0)
|
||||
w <<= 1;
|
||||
/* Now that we found the start bit, the top 9 bits contain the start
|
||||
bit and the 8 data bits, but the latter in reverse order. */
|
||||
r = reverse(w >> 7);
|
||||
if (tpi_parity(r) != ((w >> 6) & 1)) {
|
||||
fprintf(stderr, "%s: parity bit is wrong\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
if (((w >> 4) & 0x3) != TPI_STOP_BITS) {
|
||||
fprintf(stderr, "%s: stop bits not received correctly\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "CMD_TPI_TX_RX: [0x%02x -> 0x%02x]\n", b0, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
// Sometimes we just need to know the SPI command for the part to perform
|
||||
// a function. Here we wrap this request for an operation so that we
|
||||
// can just specify the part and operation and it'll do the right stuff
|
||||
@@ -450,7 +334,6 @@ static int usbtiny_set_sck_period (PROGRAMMER *pgm, double v)
|
||||
static int usbtiny_initialize (PROGRAMMER *pgm, AVRPART *p )
|
||||
{
|
||||
unsigned char res[4]; // store the response from usbtinyisp
|
||||
int tries;
|
||||
|
||||
// Check for bit-clock and tell the usbtiny to adjust itself
|
||||
if (pgm->bitclock > 0.0) {
|
||||
@@ -470,40 +353,8 @@ static int usbtiny_initialize (PROGRAMMER *pgm, AVRPART *p )
|
||||
// Let the device wake up.
|
||||
usleep(50000);
|
||||
|
||||
if (p->flags & AVRPART_HAS_TPI) {
|
||||
/* Since there is a single TPIDATA line, MOSI and MISO must be
|
||||
linked together through a 1kOhm resistor. Verify that
|
||||
everything we send on MOSI gets mirrored back on MISO. */
|
||||
if (verbose >= 2)
|
||||
fprintf(stderr, "doing MOSI-MISO link check\n");
|
||||
|
||||
memset(res, 0xaa, sizeof(res));
|
||||
if (usb_in(pgm, USBTINY_SPI, LITTLE_TO_BIG_16(0x1234), LITTLE_TO_BIG_16(0x5678),
|
||||
res, 4, 32 * PDATA(pgm)->sck_period) < 0) {
|
||||
fprintf(stderr, "usb_in() failed\n");
|
||||
return -1;
|
||||
}
|
||||
if (res[0] != 0x12 || res[1] != 0x34 || res[2] != 0x56 || res[3] != 0x78) {
|
||||
fprintf(stderr,
|
||||
"MOSI->MISO check failed (got 0x%02x 0x%02x 0x%02x 0x%02x)\n"
|
||||
"\tPlease verify that MISO is connected directly to TPIDATA and\n"
|
||||
"\tMOSI is connected to TPIDATA through a 1kOhm resistor.\n",
|
||||
res[0], res[1], res[2], res[3]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* keep TPIDATA high for >= 16 clock cycles: */
|
||||
if (usb_in(pgm, USBTINY_SPI, 0xffff, 0xffff, res, 4,
|
||||
32 * PDATA(pgm)->sck_period) < 0)
|
||||
{
|
||||
fprintf(stderr, "Unable to switch chip into TPI mode\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
for (tries = 0; tries < 4; ++tries) {
|
||||
if (pgm->program_enable(pgm, p) >= 0)
|
||||
break;
|
||||
// Attempt to use the underlying avrdude methods to connect (MEME: is this kosher?)
|
||||
if (! usbtiny_avr_op(pgm, p, AVR_OP_PGM_ENABLE, res)) {
|
||||
// no response, RESET and try again
|
||||
if (usb_control(pgm, USBTINY_POWERUP,
|
||||
PDATA(pgm)->sck_period, RESET_HIGH) < 0 ||
|
||||
@@ -511,9 +362,11 @@ static int usbtiny_initialize (PROGRAMMER *pgm, AVRPART *p )
|
||||
PDATA(pgm)->sck_period, RESET_LOW) < 0)
|
||||
return -1;
|
||||
usleep(50000);
|
||||
if ( ! usbtiny_avr_op( pgm, p, AVR_OP_PGM_ENABLE, res)) {
|
||||
// give up
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (tries >= 4)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -550,50 +403,11 @@ static int usbtiny_cmd(PROGRAMMER * pgm, const unsigned char *cmd, unsigned char
|
||||
res[2] == cmd[1]); // AVR's do a delayed-echo thing
|
||||
}
|
||||
|
||||
int usbtiny_cmd_tpi(PROGRAMMER * pgm, const unsigned char *cmd,
|
||||
int cmd_len, unsigned char *res, int res_len)
|
||||
{
|
||||
unsigned char b0, b1;
|
||||
int tx, rx, r;
|
||||
|
||||
/* Transmits command two bytes at the time until we're down to 0 or
|
||||
1 command byte. Then we're either done or we transmit the final
|
||||
byte optionally followed by reading 1 byte. With the current TPI
|
||||
protocol, we never receive more than one byte. */
|
||||
for (tx = rx = 0; tx < cmd_len; ) {
|
||||
b0 = cmd[tx++];
|
||||
if (tx < cmd_len) {
|
||||
b1 = cmd[tx++];
|
||||
if (usbtiny_tpi_txtx(pgm, b0, b1) < 0)
|
||||
return -1;
|
||||
} else {
|
||||
if (res_len > 0) {
|
||||
if ((r = usbtiny_tpi_txrx(pgm, b0)) < 0)
|
||||
return -1;
|
||||
res[rx++] = r;
|
||||
} else {
|
||||
if (usbtiny_tpi_tx(pgm, b0) < 0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rx < res_len) {
|
||||
fprintf(stderr, "%s: unexpected cmd_len=%d/res_len=%d\n",
|
||||
__func__, cmd_len, res_len);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Send the chip-erase command */
|
||||
static int usbtiny_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
unsigned char res[4];
|
||||
|
||||
if (p->flags & AVRPART_HAS_TPI)
|
||||
return avr_tpi_chip_erase(pgm, p);
|
||||
|
||||
if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
|
||||
avrdude_message(MSG_INFO, "Chip erase instruction not defined for part \"%s\"\n",
|
||||
p->desc);
|
||||
@@ -641,9 +455,6 @@ static int usbtiny_paged_load (PROGRAMMER * pgm, AVRPART * p, AVRMEM* m,
|
||||
|
||||
for (; addr < maxaddr; addr += chunk) {
|
||||
chunk = PDATA(pgm)->chunk_size; // start with the maximum chunk size possible
|
||||
if (addr + chunk > maxaddr) {
|
||||
chunk = maxaddr - addr;
|
||||
}
|
||||
|
||||
// Send the chunk of data to the USBtiny with the function we want
|
||||
// to perform
|
||||
@@ -699,9 +510,6 @@ static int usbtiny_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
for (; addr < maxaddr; addr += chunk) {
|
||||
// start with the max chunk size
|
||||
chunk = PDATA(pgm)->chunk_size;
|
||||
if (addr + chunk > maxaddr) {
|
||||
chunk = maxaddr - addr;
|
||||
}
|
||||
|
||||
// we can only write a page at a time anyways
|
||||
if (m->paged && chunk > page_size)
|
||||
@@ -730,16 +538,6 @@ static int usbtiny_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
return n_bytes;
|
||||
}
|
||||
|
||||
static int usbtiny_program_enable(PROGRAMMER *pgm, AVRPART *p)
|
||||
{
|
||||
unsigned char buf[4];
|
||||
|
||||
if (p->flags & AVRPART_HAS_TPI)
|
||||
return avr_tpi_program_enable(pgm, p, TPIPCR_GT_0b);
|
||||
else
|
||||
return usbtiny_avr_op(pgm, p, AVR_OP_PGM_ENABLE, buf);
|
||||
}
|
||||
|
||||
void usbtiny_initpgm ( PROGRAMMER* pgm )
|
||||
{
|
||||
strcpy(pgm->type, "USBtiny");
|
||||
@@ -748,10 +546,9 @@ void usbtiny_initpgm ( PROGRAMMER* pgm )
|
||||
pgm->initialize = usbtiny_initialize;
|
||||
pgm->enable = usbtiny_enable;
|
||||
pgm->disable = usbtiny_disable;
|
||||
pgm->program_enable = usbtiny_program_enable;
|
||||
pgm->program_enable = NULL;
|
||||
pgm->chip_erase = usbtiny_chip_erase;
|
||||
pgm->cmd = usbtiny_cmd;
|
||||
pgm->cmd_tpi = usbtiny_cmd_tpi;
|
||||
pgm->open = usbtiny_open;
|
||||
pgm->close = usbtiny_close;
|
||||
pgm->read_byte = avr_read_byte_default;
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
// The SCK speed can be set by avrdude, to allow programming of slow-clocked parts
|
||||
#define SCK_MIN 1 // usec delay (target clock >= 4 MHz)
|
||||
#define SCK_MAX 250 // usec (target clock >= 16 kHz)
|
||||
#define SCK_MAX 250 // usec (target clock >= 16 KHz)
|
||||
#define SCK_DEFAULT 10 // usec (target clock >= 0.4 MHz)
|
||||
|
||||
// How much data, max, do we want to send in one USB packet?
|
||||
|
||||
@@ -45,7 +45,6 @@ void DisplayErrorText(DWORD dwLastError) {
|
||||
int exists(char *filename) {
|
||||
FILE * pFile;
|
||||
pFile = fopen(filename, "r");
|
||||
if (pFile) fclose(pFile);
|
||||
return pFile != NULL;
|
||||
}
|
||||
|
||||
|
||||
27
xbee.h
27
xbee.h
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2015-2020 David Sainty
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef xbee_h__
|
||||
#define xbee_h__
|
||||
|
||||
extern const char xbee_desc[];
|
||||
void xbee_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user