169 Commits

Author SHA1 Message Date
Marius Greuel
15fe12b1a9 Add CMakeSettings.json for Visual Studio 2022 2022-05-09 15:42:48 +02:00
Marius Greuel
b8420ee52d Update GitHub deploy action 2022-05-09 15:42:48 +02:00
Marius Greuel
6ebbd4e162 Update README.md 2022-05-09 15:42:48 +02:00
Marius Greuel
4b2bf38849 Add support for COM port discovery via USB VID/PID Add support for Leonardo USB bootloader auto-reset 2022-05-09 15:41:06 +02:00
Marius Greuel
9d6420e723 Correct endpoint direction for control messages of USBtinyISP devices 2022-05-09 15:41:06 +02:00
Marius Greuel
bc9b67a153 Change Intel HEX line length from 32 to 16 to match line length of avr-objcopy 2022-05-09 15:41:06 +02:00
Marius Greuel
93b2a56c0e Change program URL to github.com 2022-05-09 15:41:06 +02:00
Joerg Wunsch
a855692d97 Correctly name the release in CMakeLists.txt as well 2022-05-08 13:58:44 +02:00
Joerg Wunsch
ec50337434 Correctly name the release in NEWS 2022-05-07 22:39:47 +02:00
Joerg Wunsch
a2e456ca8a v7.0 release preparation 2022-05-07 22:20:31 +02:00
Joerg Wunsch
43ddea9102 Calibration memory of ATtiny43U is only 1 byte
Closes issue #921.
2022-05-05 22:58:45 +02:00
Joerg Wunsch
a4c9fcdcd7 More fixes for PR #915 2022-05-02 22:51:22 +02:00
Joerg Wunsch
28ccd82edc PR 930 931 issue 927 are done 2022-05-01 22:32:54 +02:00
Jörg Wunsch
ca16fc2ce6 Merge pull request #930 from cederom/cederom-programmer-avrftdi-ktlink
Added KT-LINK FT2232H interface with IO switching and voltage buffers.
2022-05-01 22:29:46 +02:00
Jörg Wunsch
d7c59ca2f9 Merge pull request #931 from MCUdude/linuxspi-baud-fix
Fix linuxspi baud to clock period calculation
2022-05-01 22:26:23 +02:00
Joerg Wunsch
4bcd0eaa1d Fix a number of mistakes in avrdude.conf.in
Stefan Rueger found a lot of mistakes in this file.

Closes #915
2022-05-01 21:55:50 +02:00
Joerg Wunsch
08ad5ea445 Fix broken texinfo
@ must be escaped as @@
2022-04-26 23:19:20 +02:00
Joerg Wunsch
5a3ff78844 Fix syntax error in workflow build.yml file 2022-04-26 21:41:03 +02:00
Joerg Wunsch
74a92d7991 Try to exclude the 'onlinedocs' branch from actions
There's no sourcecode within that branch, anyway.
2022-04-26 21:29:46 +02:00
MCUdude
9d025e6a70 Fix linuxspi baud to clock period calculation
#927 related
2022-04-10 23:36:53 +02:00
Tomasz 'CeDeROM' CEDRO
b99a145b9f Added KT-LINK FT2232H interface with IO switching and voltage buffers.
Example TPI run: https://github.com/avrdudes/avrdude/issues/928

Signed-off-by: Tomasz 'CeDeROM' CEDRO <tomek@cedro.info>
2022-04-10 22:28:44 +02:00
Joerg Wunsch
60960ba590 Closed 922, 924, 929 2022-04-10 22:20:11 +02:00
Jörg Wunsch
99a75701b1 Merge pull request #924 from MCUdude/terminal-overflow-fix
Fix terminal write buffer overflow issue
2022-04-10 22:19:27 +02:00
Jörg Wunsch
abe7180bb8 Merge pull request #929 from per1234/update-docs-link
Update documentation link to new URL
2022-04-10 22:15:23 +02:00
per1234
157b6a63c1 Update documentation link to new URL
The project documentation is now hosted on GitHub pages. Pointing the documentation link to the documentation site home page will offer the reader easy access to the documentation for the latest and previous releases while also avoiding the maintenance burden of updating the readme on every release
2022-04-10 11:28:39 -07:00
MCUdude
1363c7fe76 Fix buffer overflow issue
when in terminal fill mode
2022-04-09 20:08:44 +02:00
Joerg Wunsch
7e26a15375 PRs/Issues 900, 901, 913, 914 done 2022-04-05 20:55:23 +02:00
Jörg Wunsch
e84210c6b0 Merge pull request #914 from MCUdude/terminal-write-str
Add terminal write string functionality
2022-04-05 20:54:20 +02:00
MCUdude
08bd5fa938 Add string write to terminal example 2022-04-05 19:37:45 +02:00
MCUdude
17b67da03e Make sure memory can be filled with a string
... and not just the last character
2022-04-04 09:38:02 +02:00
MCUdude
795dd91575 Code cleanup + formatting 2022-04-01 22:23:55 +02:00
MCUdude
8f100f5df3 Initial support for string write 2022-04-01 21:57:53 +02:00
MCUdude
f0f9059ade Tweak nexttok for better string handling
Now a string that starts and ends with a quote (") is combined into a single (argc) argument rather than being split where spaces used to be
2022-04-01 16:52:59 +02:00
Nav
e069871c8e Increased timeout passed to hid_read_timeout() - set to 10000 for consistency (#901) 2022-03-31 23:26:53 +02:00
Joerg Wunsch
0aa43968a0 Add PR 908, 909, 910, 912 2022-03-31 23:14:35 +02:00
Hans
f22bc62b06 Mask out unused ATmega32U4 efuse bits (#909)
Closes #446
2022-03-31 23:13:57 +02:00
Hans
d09a4e93a2 Add ATmega16U4 to avrdude.conf (#910)
Closes #447
2022-03-31 23:12:32 +02:00
Hans
aa7ae7bb87 Add MacOS serial/parallel port note (#908)
Closes #510
2022-03-31 22:32:57 +02:00
Hans
1d0cbc2246 Add progressbar for read and write command (#912) 2022-03-31 22:21:49 +02:00
Joerg Wunsch
79c4137289 Mention the new search order for avrdude.conf 2022-03-22 08:49:04 +01:00
Joerg Wunsch
8697f6def7 Remove remnants of the old erase-cycle counter from examples 2022-03-21 06:38:28 +01:00
Joerg Wunsch
981a6f1f20 Restore the -u option as a dummy.
Closes #890
2022-03-20 21:50:45 +01:00
Joerg Wunsch
c64db5fb76 Link the project's "Pages" for documentation 2022-03-19 23:26:27 +01:00
Joerg Wunsch
50c373bf71 Mention issues #771, #897, PRs #898, #899, #902, #903 2022-03-19 23:05:19 +01:00
Jörg Wunsch
0c722bf288 Merge pull request #903 from dl8dtl/term-docs
Terminal mode documentation
2022-03-19 23:04:50 +01:00
Jörg Wunsch
28d1442fc8 Merge pull request #902 from MCUdude/terminal-fix
Minor terminal write improvements
2022-03-19 23:02:24 +01:00
Jörg Wunsch
75e4d06463 Merge pull request #899 from MCUdude/avrdude-conf-fix
Fix errors in Avrdude.conf

This also closes #897
2022-03-19 23:01:12 +01:00
Jörg Wunsch
99f191a0ca Merge pull request #898 from dl8dtl/macos-nonstandard-baudrates
Macos nonstandard baudrates

closes #266
2022-03-19 22:57:37 +01:00
Joerg Wunsch
33bace0cee Provide an example for the second form of the "write" command
In terminal mode, there are two forms of "write", one that
explicitly mentions all data values, and a second one that
instead specifies a total range to write, where the last data
value given is replicated as needed.
2022-03-19 17:30:55 +01:00
Joerg Wunsch
0c912a201f Try making the cindex (concept index) meaningful
Rearrange existing @cindex entries, add a lot of new ones.
2022-03-19 00:03:17 +01:00
Joerg Wunsch
31feb9ff75 Link the concept index 2022-03-19 00:00:54 +01:00
Joerg Wunsch
c5a28eedc0 Also tweak smallexample 2022-03-19 00:00:41 +01:00
Joerg Wunsch
29a01c1047 Terminal mode: fix documentation of second version of "write"
Right after start_addr, the next element is the number of bytes
to be written.
2022-03-18 23:42:32 +01:00
MCUdude
426ea1fa78 Add missing free()'s 2022-03-18 21:20:58 +01:00
MCUdude
6a5988ad64 Print write info message when in verbose mode 2022-03-18 21:19:36 +01:00
MCUdude
dcf771424b Increase buffer size to prevent potential overflow 2022-03-18 19:17:17 +01:00
Joerg Wunsch
67b56d322b Update texinfo documentation for terminal-mode changes
This documents the recent changes that have been implemented in
terminal mode.
2022-03-17 23:13:52 +01:00
Joerg Wunsch
27d201acb1 Also tweak smallexample 2022-03-17 07:21:33 +01:00
Joerg Wunsch
ded30f86bc CSS test 2022-03-16 23:22:14 +01:00
Joerg Wunsch
9bc4a2463d Attempt to tweak CSS of the generated HTML docs a bit 2022-03-16 23:19:45 +01:00
Joerg Wunsch
8ad55e07ac Update generated documentation 2022-03-13 22:55:33 +01:00
Joerg Wunsch
d89817ddb9 Merge branch 'main' into pages-test 2022-03-13 22:54:24 +01:00
Joerg Wunsch
fc6a71a142 Merge remote-tracking branch 'upstream/main' 2022-03-13 22:53:46 +01:00
Joerg Wunsch
da1271642e Remove the pointer to the mailing list
It makes more sense to point people to Github issue trackers now,
even for questions.
2022-03-13 22:52:44 +01:00
Joerg Wunsch
0e441013e9 Update docs 2022-03-13 00:31:27 +01:00
Joerg Wunsch
c5f7939fca Merge branch 'main' into pages-test 2022-03-13 00:29:54 +01:00
Joerg Wunsch
297d81818a Merge remote-tracking branch 'upstream/main' 2022-03-13 00:25:50 +01:00
Joerg Wunsch
7391e569b3 Bring the texinfo doc up to date
* remove copyright years; they are not meaningful anyway
* reflect the project move from Savannah to Github
2022-03-13 00:21:35 +01:00
Joerg Wunsch
67ab74cd6a Fix a one-bit error in ATmega165* signature read command. 2022-03-13 00:21:35 +01:00
Joerg Wunsch
631f671fe8 Mention PRs #893, #894, #896, bug #889 2022-03-13 00:21:20 +01:00
MCUdude
248b554e8d Add support for read with ... "operator"
This means that you can use ... to read the "rest" of the memory.
$ read eeprom ...   will dump the entire memory
$ read eeorm 0x80 ...   will dump the memory from address 0x80 to the end address
2022-03-13 00:20:07 +01:00
MCUdude
40e3aa1790 Incread default read size to 256 bytes 2022-03-13 00:20:07 +01:00
MCUdude
dca5fc92bf Restructure "write mode" code 2022-03-13 00:20:07 +01:00
MCUdude
4e05a8fa41 Update description 2022-03-13 00:20:07 +01:00
MCUdude
1299d6b8bd Fix terminal write bug
Wouldn't write data properly after an integer >= 2 bytes was written
2022-03-13 00:20:07 +01:00
MCUdude
da315d7323 Support both userrow and usersig names 2022-03-13 00:20:07 +01:00
Joerg Wunsch
416c465ec0 Bring the texinfo doc up to date
* remove copyright years; they are not meaningful anyway
* reflect the project move from Savannah to Github
2022-03-13 00:13:29 +01:00
MCUdude
41f524c1ba Use the same device signature on ATmega165 and ATmega165A 2022-03-08 13:17:01 +01:00
MCUdude
5ebb9047be Fix incorrect ATxmega128D4 flash page size 2022-03-08 12:50:17 +01:00
MCUdude
fde7881611 Fix incorrect ATmega64M1 flash and eeprom size
#897 related
2022-03-08 12:34:06 +01:00
MCUdude
1c94c95f1c Fix target names not following the standard 2022-03-08 12:32:41 +01:00
Joerg Wunsch
e2995857ac Remove verboseness from build.sh
Got accidentally committed.
2022-03-07 23:27:54 +01:00
Joerg Wunsch
a4cbd5c6fc Append a newline to the nonstandard baudrate warning 2022-03-07 23:25:36 +01:00
Joerg Wunsch
87b39637ff Implement nonstandard baudrate handling on MacOS
Alas, MacOS doesn't handle nonstandard baud rates like other systems
in regular tcsetattr() calls. Instead, they invented a new ioctl
(IOSSIOSPEED). So, if we notice we are going to configure a
nonstandard rate on MacOS, issue that ioctl after configuring
everything else using tcsetattr().
2022-03-07 23:20:50 +01:00
Joerg Wunsch
34168759b0 Fix a one-bit error in ATmega165* signature read command. 2022-03-07 22:52:14 +01:00
Joerg Wunsch
c746c9bc9e Fix a one-bit error in ATmega165* signature read command. 2022-03-07 22:49:46 +01:00
Joerg Wunsch
65618ed655 Fix a one-bit error in the signature read command for ATmega165* 2022-03-07 21:38:17 +01:00
Joerg Wunsch
00ea962abe Add link to docs 2022-03-07 00:22:59 +01:00
Joerg Wunsch
d62f309a00 Add symlink for index.html 2022-03-07 00:18:04 +01:00
Joerg Wunsch
92a5ae20a6 Test for Github pages 2022-03-07 00:09:47 +01:00
Joerg Wunsch
5cbc9c37fc Mention PRs #893, #894, #896, bug #889 2022-03-03 23:15:20 +01:00
Jörg Wunsch
0f4b5b223b Merge pull request #894 from MCUdude/terminal
Improve terminal read functionality
2022-03-03 23:14:37 +01:00
Jörg Wunsch
0b82b5c573 Merge pull request #896 from MCUdude/terminal-write
Fix ugly terminal write bug
2022-03-03 23:12:47 +01:00
Jörg Wunsch
9355d67e0f Merge pull request #893 from MCUdude/userrow-fix
Support both userrow and usersig names
2022-03-03 23:09:20 +01:00
MCUdude
d9c52249a9 Restructure "write mode" code 2022-03-03 19:37:42 +01:00
MCUdude
c7174d7678 Update description 2022-03-02 20:24:51 +01:00
MCUdude
df6e2eea12 Fix terminal write bug
Wouldn't write data properly after an integer >= 2 bytes was written
2022-03-02 20:09:59 +01:00
Joerg Wunsch
0d58adb10a Close #892 #895 2022-03-01 23:30:11 +01:00
Jörg Wunsch
ebb1849724 Merge pull request #895 from janegilruud/bugfix/fix-cnano-updi-flash-read
For UPDI devices do not add offset when accessing flash.
2022-03-01 23:26:11 +01:00
Jan Egil Ruud
0c8b42524e For UPDI devices do not add offset when accessing flash. 2022-03-01 14:24:33 +01:00
MCUdude
b688b1f601 Add support for read with ... "operator"
This means that you can use ... to read the "rest" of the memory.
$ read eeprom ...   will dump the entire memory
$ read eeorm 0x80 ...   will dump the memory from address 0x80 to the end address
2022-02-28 23:59:30 +01:00
MCUdude
d89f695c31 Incread default read size to 256 bytes 2022-02-28 23:59:30 +01:00
MCUdude
1f2b570216 Support both userrow and usersig names 2022-02-28 19:46:47 +01:00
Joerg Wunsch
64cc54ac35 PR #888 done 2022-02-21 23:28:50 +01:00
Jörg Wunsch
e2e5e44bab Merge pull request #888 from MCUdude/userrow-alias
Add userrow and usersig aliases
2022-02-21 23:28:05 +01:00
MCUdude
07ea8f5e09 Add userrow and usersig aliases 2022-02-21 22:36:06 +01:00
Joerg Wunsch
0269817217 Add a missing @end table
Has been slipped when adding some -x documentation before.
2022-02-21 22:01:05 +01:00
Joerg Wunsch
fe6290072a PR #880 done 2022-02-21 21:54:47 +01:00
Jörg Wunsch
008f95f6ff Merge pull request #880 from MCUdude/terminal-write
Avrdude terminal write improvements
2022-02-21 21:53:38 +01:00
MCUdude
a73567893b Properly handle negative number sizes 2022-02-21 13:43:38 +01:00
MCUdude
fa706f0d01 Handle data size warning better
Now it only outputs a warning when the size of the data the user input is actually ambiguous
2022-02-20 23:03:31 +01:00
MCUdude
3532c567ac Add suffix for 8-bit data
use [val]HH or [val]hh to force 8-bit writes to memory
2022-02-20 22:23:15 +01:00
Joerg Wunsch
14f646822c PR #886 done 2022-02-20 20:59:28 +01:00
Jörg Wunsch
bb73ade70b Merge pull request #886 from dbuchwald/ser_posix_cleanup
Cleanup of POSIX serial init code
2022-02-20 20:58:22 +01:00
MCUdude
bb99a36a14 Formatting
Use enums for write mode, and change datatypes from int/long/char to int32_t/uint8_t where possible
2022-02-20 19:08:30 +01:00
Joerg Wunsch
0d7d034d24 Issue #884 closed 2022-02-20 16:58:39 +01:00
Joerg Wunsch
c7d1ebcf1f Issue #881 also fixed 2022-02-20 14:37:04 +01:00
Joerg Wunsch
b891b7c64b Issue #874 is closed 2022-02-20 14:35:50 +01:00
MCUdude
a9b756e5c7 Add struct initialization list 2022-02-20 12:46:53 +01:00
Dawid Buchwald
cf67a76c23 Merge branch 'main' into ser_posix_cleanup 2022-02-20 12:37:19 +01:00
MCUdude
0e29b43bd0 Add support for 64-bit integers
Also, move everything data related into a struct, to keep tings a little more organized
2022-02-19 23:34:50 +01:00
MCUdude
4b9219edee Add support for suffixes for manually specifying data size
H/h/S/s: 16-bit, L/l: 32-bit, F/f: 32-bit float
2022-02-19 22:48:58 +01:00
Joerg Wunsch
428cd89e8d PRs #878, #873, #885 done 2022-02-19 21:54:23 +01:00
Jörg Wunsch
3efd3b2052 Merge pull request #873 from MCUdude/add-arduino-programmers
Add missing USBtiny derived programmers
2022-02-19 21:51:31 +01:00
Jörg Wunsch
7c65adba26 Merge pull request #885 from dbuchwald/simple_updi_fix
Smallest possible fix for PL2303HX
2022-02-19 21:50:41 +01:00
Dawid Buchwald
75ab3c418e Fixed warning with unsigned char 2022-02-19 21:18:03 +01:00
MCUdude
62f3b84eee Use union for simpler data representation
It is a bit hacky, but for this purpose it fits surprisingly well
2022-02-19 20:15:52 +01:00
Dawid Buchwald
066f54fbfa Cleanup of POSIX serial init code 2022-02-19 18:00:58 +01:00
Dawid Buchwald
de19f203e0 Smallest possible fix for PL2303HX 2022-02-19 15:07:32 +01:00
Jörg Wunsch
d054c68b19 Merge pull request #878 from MCUdude/fix-pkob-target-voltage
Fix Curiosity Nano target voltage
2022-02-18 23:01:49 +01:00
Joerg Wunsch
5c90fbbaae PR #877 done 2022-02-18 22:53:45 +01:00
Jörg Wunsch
c2fe68ef7d Merge pull request #877 from MCUdude/jtag3-verbosity
Reduce jtag3 output verbosity
2022-02-18 22:38:40 +01:00
Hans
c345985928 Merge branch 'avrdudes:main' into terminal-write 2022-02-18 22:09:42 +01:00
Joerg Wunsch
c1ec836fbd PR #882 done 2022-02-18 21:37:27 +01:00
Jörg Wunsch
ba01fd7e30 Merge pull request #882 from mariusgreuel/pr-libhid-cleanup-part1
Remove libhid support in ser_avrdoper.c in favor of libhidapi
2022-02-18 21:36:12 +01:00
Marius Greuel
59ecd4cc65 Remove libhid support in ser_avrdoper.c in favor of libhidapi 2022-02-18 20:05:52 +01:00
Marius Greuel
e31be88ce0 Add LIB_LIBHID to CMake project to fix MinGW build issue 2022-02-18 19:58:13 +01:00
MCUdude
6e7f38e81f Properly handle negative numbers
Now -3.141592 and -32768 are valid numbers that's stored correctly in memory
2022-02-18 09:58:16 +01:00
MCUdude
10e05eed21 Require single quotes when writing characters 2022-02-18 09:58:16 +01:00
MCUdude
551046052e Add support for writing floats 2022-02-18 09:58:16 +01:00
MCUdude
2a92b8cce4 Add support for memory "fill" with arbitrary data too
If you run the following command: $ write eeprom 0x00 0x10 A B C ...

It will write the following data to EEPROM:
|ABCCCCCCCCCCCCCC|
starting from address 0x00
2022-02-18 09:58:16 +01:00
MCUdude
c007dc7d24 Add support for writing single characters
Now this is possible: write eeprom 0x00 a b c d e f 0x80 0x90 ! H E L L O
2022-02-18 09:58:16 +01:00
MCUdude
2589b17640 Add support for memory "fill" mode
Syntax: write <memtype> <start addr> <no. byte to write> <byte to write> ...
2022-02-18 09:58:13 +01:00
MCUdude
19e2cae053 Add Curiosity Nano to terminal list 2022-02-14 10:30:21 +01:00
MCUdude
932f68f24c Set target voltage even thoug not target is detected 2022-02-14 10:28:54 +01:00
MCUdude
b1d34a510c Reduce jtag3 output verbosity 2022-02-13 19:23:48 +01:00
MCUdude
f2bdcbe977 Add missing USBtiny derived programmers
ArduinoISP and the Arduino.org ISP are commercial versions of the USBtiny programmer with different USB VIDs/PIDs
2022-02-11 22:46:11 +01:00
Joerg Wunsch
7b79b72794 PR #872 done 2022-02-11 22:17:24 +01:00
Jörg Wunsch
76a17be4d0 Merge pull request #872 from MCUdude/jtag-string-formatting
Tweak programmer info formatting strings
2022-02-11 22:16:39 +01:00
MCUdude
80f1d96e07 Tweak programmer info formatting strings
Now all colons are on a straight line, just like #853 did to all jtag3 compatible programmers
2022-02-11 22:10:52 +01:00
Joerg Wunsch
09fe08e51c PR #853 done 2022-02-11 21:45:31 +01:00
Jörg Wunsch
f2c73c2bb8 Merge pull request #853 from MCUdude/jtag3-clock-update
Print JTAG3 clocks after configuration + string formatting
2022-02-11 21:44:54 +01:00
MCUdude
b581d14823 String formatting
Allign colons, only print clocks that are actually present (>0 kHz)
2022-02-11 21:35:07 +01:00
Joerg Wunsch
354a1c4f1f PR #869 closed 2022-02-11 21:17:01 +01:00
Jörg Wunsch
23a09a6197 Merge pull request #869 from MCUdude/alias-memories
Add fuse name aliases to avrdude.conf + tweak update.c
2022-02-11 21:15:34 +01:00
MCUdude
3fc39c47ad Print memory name alias together with the canonical name if present
in avrdude.conf. An example would be "avrdude: reading fuse0/wdtcfg memory:"
2022-02-11 21:10:05 +01:00
MCUdude
d6ccf7a3ff Add memory alias names for megaAVR0/tinyAVR0,1,2/AVR-Dx/AVR-Ex fuses 2022-02-10 22:34:33 +01:00
Joerg Wunsch
452f673f38 Back out the last "alias" commit (search for existing alias).
It breaks the alias handling completely as the search happens
way too late. So instead, just keep any possibly duplicate
name as it won't be in our way anyway.
2022-02-10 21:26:05 +01:00
Joerg Wunsch
38a3af37e2 Mention PRs #863 and #868. 2022-02-10 20:39:51 +01:00
Jörg Wunsch
d134dc8fff Alias keyword (#868)
Implementation for an "alias" keyword.

By now, only applied inside memory descriptions.

* Make "mem_alias" a separate nonterminal.

The previous implementation attempt caused a syntax error in
yacc code, and separating mem_alias on the same level as
mem_spec appears to be the cleaner solution anyway.

* Maintain real memory aliases.

Instead of duplicating the aliased memory with a new name, maintain a
second list of memory aliases (per device) that contains a pointer to
the memory area it is aliased to. That way, a memory name can be
clearly distinguished between the canonical one and any aliases.

* Check p->mem_alias != NULL before touching it

* Add avr_find_memalias()

This takes a memory region as input, and searches whether an
alias can be found for it.

* We need to add a list structure for the mem_alias list, always.

By that means, mem_alias won't ever be NULL, so no need to check
later.

Also, in avr_dup_part(), duplicate the alias list.

* In a memory alias, actually remember the current name.

* In avr_dup_part(), adjust pointers of aliased memories

While walking the list of memories, for each entry, see if there is an
alias pointing to it. If so, allocate a duplicated one, and fix its
aliased_mem pointer to point to the duplicated memory region instead
of the original one.

* Add avr_locate_mem_noalias()

When looking whether any memory region has already been defined for
the current part while parsing the config file, only non-aliased names
must be considered. Otherwise, a newly defined alias would kick out
the memory definition it is being aliased to.

* When defining a mem_alias, drop any existing one of that name.

* Actually use avr_find_memalias() to find aliases

* Add declaration for avr_find_memalias()

* When defining a memory, also search for an existing alias

If the newly defined name has the same as an existing alias, the alias
can be removed.

Note that we do explicitly *not* remove any memory by the same name of
a later defined alias, as this might invalidate another alias'es
pointer. If someone defines that, the alias name just won't ever be
found by avr_locate_mem().
2022-02-10 20:39:19 +01:00
Jörg Wunsch
ba314f23e9 Merge pull request #863 from MCUdude/jtag3-read-memory-alias
Add support for reading from more memory sections
2022-02-10 20:35:06 +01:00
MCUdude
a43f220ef9 Add support for reading from more memory sections
It's now possible to read the following memories if present: osccal16, osccal20, tempsense, osc16err, osc20err
2022-02-07 21:51:35 +01:00
Joerg Wunsch
1c0b70da89 PR #859 done 2022-02-05 22:03:59 +01:00
Jörg Wunsch
b6a6c681df Merge pull request #859 from dl8dtl/safemode-removal
Remove the "safemode" feature.
2022-02-05 22:03:12 +01:00
Joerg Wunsch
3eda1d15f9 Mention PR #858 2022-02-05 21:59:04 +01:00
Marius Greuel
c6438532f0 Merge pull request #858 from yegorich/cmake-install-fix
CMake: use CMAKE_CURRENT_BINARY_DIR to locate avrdude.conf
2022-02-05 21:46:38 +01:00
Joerg Wunsch
8c6c6a14ec Remove the "safemode" feature.
This feature has been designed with the sometimes quite flakey direct
(parallel or serial port attached) bitbang programming adapters in
mind that were quite common about two decades ago.

With parallel ports vanishing from modern PCs almost completely, and
the advent of various USB-attached low-cost programming devices,
this class of programmers disappeared almost completely.

Furthermore, the fuse combinations that were covered by the feature
are no longer around on all recent AVR devices, so for an ever
increasing number of devices, safemode already became meaningless and
was turned off anyway.

With the prospective version 7.x release, it's a good point in time to
introduce a major change like this one.
2022-01-31 20:44:32 +01:00
Yegor Yefremov
7ed3632902 CMake: use CMAKE_CURRENT_BINARY_DIR to locate avrdude.conf
With the split CMakeLists.txt infrastructure avrdude.conf
will be created in the build/src and not build folder. Hence,
fix its location in the install command.
2022-01-31 07:18:59 +01:00
MCUdude
f6bbaadfa6 Print clock info after the correct clock speeds has been set
The "new" clock speed set by the -B flag wasn't reflected in the output log
2022-01-23 22:45:54 +01:00
36 changed files with 1504 additions and 1339 deletions

View File

@@ -20,7 +20,11 @@ name: Build
on:
push:
branches-ignore:
- 'onlinedocs'
pull_request:
branches-ignore:
- 'onlinedocs'
workflow_call:
env:

View File

@@ -1,51 +0,0 @@
#
# build_extra.yml - GitHub build action for AVRDUDE
# Copyright (C) 2021 Marius Greuel
#
# 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/>.
#
name: Build Extra
on:
push:
pull_request:
workflow_call:
env:
BUILD_TYPE: RelWithDebInfo
jobs:
freebsd-x86_64:
runs-on: macos-10.15
steps:
- uses: actions/checkout@v2
- name: Build
id: build
uses: vmactions/freebsd-vm@v0.1.5
with:
prepare: pkg install -y git cmake flex bison libftdi1 hidapi
run: |
cd src
cmake -D DEBUG_CMAKE=1 -D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -D CMAKE_C_FLAGS=-I/usr/local/include -D CMAKE_EXE_LINKER_FLAGS=-L/usr/local/lib -B ../build
cmake --build ../build
- name: Archive build artifacts
if: always()
uses: actions/upload-artifact@v2
with:
name: freebsd-x86_64
path: |
build/
!**/*.d
!**/*.o

View File

@@ -21,7 +21,7 @@
# cmake --build build
cmake_minimum_required(VERSION 3.12)
project(avrdude VERSION 6.99)
project(avrdude VERSION 7.0)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED True)
@@ -182,6 +182,9 @@ endif()
# Find libhidapi
find_library(HAVE_LIBHID NAMES hid)
if(HAVE_LIBHID)
set(LIB_LIBHID ${HAVE_LIBHID})
endif()
find_library(HAVE_LIBHIDAPI NAMES ${PREFERRED_LIBHIDAPI})
if(HAVE_LIBHIDAPI)

View File

@@ -2,7 +2,7 @@
"configurations": [
{
"name": "x86-Debug",
"generator": "Visual Studio 16 2019",
"generator": "Visual Studio 17 2022",
"configurationType": "Debug",
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
@@ -25,7 +25,7 @@
},
{
"name": "x86-Release",
"generator": "Visual Studio 16 2019",
"generator": "Ninja",
"configurationType": "RelWithDebInfo",
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
@@ -63,7 +63,7 @@
},
{
"name": "x64-Debug",
"generator": "Visual Studio 16 2019 Win64",
"generator": "Visual Studio 17 2022 Win64",
"configurationType": "Debug",
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
@@ -86,7 +86,7 @@
},
{
"name": "x64-Release",
"generator": "Visual Studio 16 2019 Win64",
"generator": "Ninja",
"configurationType": "RelWithDebInfo",
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",

67
NEWS
View File

@@ -5,7 +5,7 @@ Approximate change log for AVRDUDE by version.
(For detailed changes, see the version control system logs.)
----------------------------------------------------------------------
Changes since version 6.4:
Changes in version 7.0:
* Major changes compared to the previous version:
@@ -13,6 +13,17 @@ Changes since version 6.4:
- Started to add CMake (by now, parallel with autoconf/automake)
- New-architecture devices (AVR8X mega and tiny) can access all
fuses, and memory display shows meaningful alias names
- The "safemode" feature has been removed. The major class of
programmers it has been designed for (lowlevel bitbang
programmers on parallel or serial ports) virtually doesn't exist
anymore, and the fuse combination that was covered by it do not
match the fuses of modern AVR devices anyway.
- avrdude.conf is now being looked up in the location of the
executable file first, before considering the configured default
location; this eases a "portable use" where the entire suite is
not installed into its configured default location. (Basically
only relevant for unixoid systems; on Windows, this search order
has been used for many years already.)
* New devices supported:
@@ -30,6 +41,7 @@ Changes since version 6.4:
- ATtiny3224, ATtiny3226 and ATtiny3227
- AVR16DD14/20/28/32, AVR32DD14/20/28/32 and AVR64DD14/20/28/32
- AVR8EA28/32, AVR16EA28/32/48, AVR32EA28/32/48 and AVR64EA28/32/64
- ATmega16U4
* New programmers supported:
@@ -40,6 +52,8 @@ Changes since version 6.4:
- Teensy bootloader (PR #802)
- Micronucleus bootloader (PR #786)
- ft232h (generic variant, PR #842)
- Kristech KT-LINK FT2232H interface with IO switching and voltage
buffers (PR #930)
* Issues fixed:
@@ -63,6 +77,22 @@ Changes since version 6.4:
- Segmentation fault when writing ATtiny104 fuse #823
- USBasp returns ERANGE for unknown error #848
- Compiler warnings #856
- Can't get serialupdi to work #874
- Rework HID support for Windows #881
- List of signing keys? #884
- Pickit4 UPDI is writing at offset 0x4000 into flash instead of 0x0000. #892
- SerialUPDI programmer can't write to usersig/userrow in terminal mode #889
- Signature read command for ATmega165* was wrong (no-id)
- Cannot use non-standard baud rates for uploading on MacOS #771
- Wrong values in avrdude.conf #897
- AVR-Eclipse plugin broken by missing -u commandline option #890
- Timeout passed to hid_read_timeout() is too short for instances
where the EDBG AVRISP 'Enter Programming Mode' command fails #900
- Terminal write mode doesn't support string input (yet) #913
- Terminal mode: memory fill with strings may cause Avrdude to crash. #922
- Some parts have wrong or missing ISP commands #915
- Incorrect -b conversion for linuxspi programmer #927
- ATtiny43U calibration memory size #921
* Pull requests:
@@ -119,10 +149,45 @@ Changes since version 6.4:
- Fix libusb-1.0 error strings #850
- Assign proper type to msg[] in errstr() #857
- Fix Arduino retry attempts #855
- CMake: use CMAKE_CURRENT_BINARY_DIR to locate avrdude.conf #858
- Remove the "safemode" feature. #859
- Add support for reading from more memory sections #863
- Alias keyword #868
- Add fuse name aliases to avrdude.conf + tweak update.c #869
- Print JTAG3 clocks after configuration + string formatting #853
- Tweak programmer info formatting strings #872
- Remove libhid support in ser_avrdoper.c in favor of libhidapi #882
- Reduce jtag3 output verbosity #877
- Fix Curiosity Nano target voltage #878
- Smallest possible fix for PL2303HX #885
- Add missing USBtiny derived programmers #873
- Cleanup of POSIX serial init code #886
- Avrdude terminal write improvements #880
- Add userrow and usersig aliases #888
- For UPDI devices do not add offset when accessing flash. #895
- Support both userrow and usersig names #893
- Fix ugly terminal write bug #896
- Improve terminal read functionality #894
- Macos nonstandard baudrates #898
- Fix errors in Avrdude.conf #899
- Minor terminal write improvements #902
- Term docs #903
- Add progressbar for read and write command #912
- Add MacOS serial/parallel port note #908
- Add ATmega16U4 to avrdude.conf #910
- Mask out unused ATmega32U4 efuse bits #909
- Increased timeout passed to hid_read_timeout() #901
- Add terminal write string functionality #914
- Update documentation link to new URL #929
- Fix terminal write buffer overflow issue #924
- Fix linuxspi baud to clock period calculation #931
- Added KT-LINK FT2232H interface with IO switching and voltage buffers. #930
* Internals:
- Development moved to Github
- Addition of "alias" keyword to avrdude.conf.in syntax; used
for fuse name aliases right now
Version 6.4:

View File

@@ -16,6 +16,10 @@ with the help of [various contributors](./AUTHORS).
The latest version of AVRDUDE is always available here:\
<https://github.com/avrdudes/avrdude>
## Documentation
Documentation for current and previous releases is [on Github Pages](https://avrdudes.github.io/avrdude/).
## Getting AVRDUDE for Windows
To get AVRDUDE for Windows, install the latest version from the [Releases](http://download.savannah.gnu.org/releases/avrdude/) page.
@@ -57,4 +61,4 @@ avrdude -c arduino -P COM1 -b 115200 -p atmega328p -D -U flash:w:objs/blink.hex:
There are many different programmers and options that may be required for the programming to succeed.
For more information, refer to the [AVRDUDE documentation](http://download.savannah.gnu.org/releases/avrdude/avrdude-doc-6.4.pdf).
For more information, refer to the [AVRDUDE documentation](https://avrdudes.github.io/avrdude/).

View File

@@ -2,7 +2,7 @@
[![Build Status](https://github.com/mariusgreuel/avrdude/actions/workflows/build.yml/badge.svg?branch=windows)](https://github.com/mariusgreuel/avrdude/actions/workflows/build.yml)
This is a fork of AVRDUDE 6.4 from <https://github.com/avrdudes/avrdude>.
This is a fork of AVRDUDE 7.0 from <https://github.com/avrdudes/avrdude>.
The purpose of this fork is to add better support for Windows to bring it on par with the Linux version of AVRDUDE.
@@ -19,7 +19,11 @@ Noteable changes include:
- [Support Visual Studio](#support-visual-studio)
- [Miscellaneous bug-fixes and patches](#miscellaneous-bug-fixes-and-patches)
The original AVRDUDE project homepage can be found here <https://savannah.nongnu.org/projects/avrdude>.
The original AVRDUDE project homepage can be found here <https://github.com/avrdudes/avrdude>.
## Documentation
Documentation for current and previous releases is [on Github Pages](https://avrdudes.github.io/avrdude/).
## Download

View File

@@ -174,7 +174,6 @@ add_library(libavrdude
ppi.c
ppi.h
ppiwin.c
safemode.c
serbb.h
serbb_posix.c
serbb_win32.c
@@ -241,6 +240,7 @@ target_link_libraries(libavrdude
${LIB_LIBELF}
${LIB_LIBUSB}
${LIB_LIBUSB_1_0}
${LIB_LIBHID}
${LIB_LIBHIDAPI}
${LIB_LIBFTDI}
${LIB_LIBFTDI1}
@@ -269,5 +269,5 @@ install(TARGETS libavrdude
ARCHIVE DESTINATION lib
PUBLIC_HEADER DESTINATION include COMPONENT dev
)
install(FILES "${PROJECT_BINARY_DIR}/avrdude.conf" TYPE SYSCONF)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/avrdude.conf" TYPE SYSCONF)
install(FILES avrdude.1 TYPE MAN)

View File

@@ -148,7 +148,6 @@ libavrdude_a_SOURCES = \
ppi.c \
ppi.h \
ppiwin.c \
safemode.c \
serbb.h \
serbb_posix.c \
serbb_win32.c \

View File

@@ -791,30 +791,6 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char data)
{
unsigned char safemode_lfuse;
unsigned char safemode_hfuse;
unsigned char safemode_efuse;
unsigned char safemode_fuse;
/* If we write the fuses, then we need to tell safemode that they *should* change */
safemode_memfuses(0, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse);
if (strcmp(mem->desc, "fuse")==0) {
safemode_fuse = data;
}
if (strcmp(mem->desc, "lfuse")==0) {
safemode_lfuse = data;
}
if (strcmp(mem->desc, "hfuse")==0) {
safemode_hfuse = data;
}
if (strcmp(mem->desc, "efuse")==0) {
safemode_efuse = data;
}
safemode_memfuses(1, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse);
return pgm->write_byte(pgm, p, mem, addr, data);
}
@@ -877,11 +853,15 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
/* setup for WORD_WRITE */
avr_tpi_setup_rw(pgm, m, 0, TPI_NVMCMD_WORD_WRITE);
/* make sure it's aligned to a word boundary */
if (wsize & 0x1) {
wsize++;
}
/* write words, low byte first */
for (lastaddr = i = 0; i < wsize; i += 2) {
bool have_two_bytes = i + 1 < wsize;
if ((m->tags[i] & TAG_ALLOCATED) != 0 ||
(have_two_bytes && m->tags[i + 1] & TAG_ALLOCATED) != 0) {
(m->tags[i + 1] & TAG_ALLOCATED) != 0) {
if (lastaddr != i) {
/* need to setup new address */
@@ -893,11 +873,8 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
cmd[1] = m->buf[i];
rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0);
if (have_two_bytes)
{
cmd[1] = m->buf[i + 1];
rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0);
}
lastaddr += 2;
@@ -905,7 +882,7 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
}
report_progress(i, wsize, NULL);
}
return wsize;
return i;
}
if (pgm->paged_write != NULL && m->page_size > 1) {

View File

@@ -607,40 +607,11 @@ 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.
.It Fl s
Disable safemode prompting. When safemode discovers that one or more
fuse bits have unintentionally changed, it will prompt for
confirmation regarding whether or not it should attempt to recover the
fuse bit(s). Specifying this flag disables the prompt and assumes
that the fuse bit(s) should be recovered without asking for
confirmation first.
.It Fl t
Tells
.Nm
to enter the interactive ``terminal'' mode instead of up- or downloading
files. See below for a detailed description of the terminal mode.
.It Fl u
Disable the safemode fuse bit checks. Safemode is enabled by default
and is intended to prevent unintentional fuse bit changes. When
enabled, safemode will issue a warning if the any fuse bits are found
to be different at program exit than they were when
.Nm
was invoked. Safemode won't alter fuse bits itself, but rather will
prompt for instructions, unless the terminal is non-interactive, in
which case safemode is disabled. See the
.Fl s
option to disable safemode prompting.
.Pp
If one of the configuration files has a line
.Dl "default_safemode = no;"
safemode is disabled by default.
The
.Fl u
option's effect is negated in that case, i. e. it
.Em enables
safemode.
.Pp
Safemode is always disabled for AVR32, Xmega and TPI devices.
.It Xo Fl U Ar memtype Ns
.Ar \&: Ns Ar op Ns
.Ar \&: Ns Ar filename Ns

View File

@@ -339,10 +339,6 @@ default_parallel = "@DEFAULT_PAR_PORT@";
default_serial = "@DEFAULT_SER_PORT@";
# default_bitclock = 2.5;
# Turn off safemode by default
#default_safemode = no;
#
# PROGRAMMER DEFINITIONS
#
@@ -597,6 +593,38 @@ programmer
reset = 3; # TMS 7
;
# Kristech KT-LINK FT2232H interface with IO switching and voltage buffers.
# Created on 20220410 by CeDeROM Tomasz CEDRO (www.cederom.io).
# Interface DataSheet: https://kristech.pl/files/KT-LINK-UM-ENG.pdf
# AVRDUDE FT2232H PIN NUMBER DECODE:
# | 0 | 1 | .. | 7 | 8 | 9 | .. | 15 |
# | ADBUS0 | ADBUS1 | .. | ADBUS7 | ACBUS0 | ACBUS1 | .. | ACBUS7 |
# KT-LINK JTAG CONN:
# 1=Vsense(->EXT13), 19=5V(EXT1->EXT3), 20=GND, 3=TPIRST, 9=TPICLK, 7=TPIDATA.
# INTERNALS CONFIGURATION ("~" MEANS ACTIVE LOW):
# ~TRST_EN=10(ACBUS2), ~CLK_EN=14(ACBUS6), ~MOSI_EN=13(ACBUS5),
# TMS_SEL=5(ADBUS5), ~TMS_EN=12(ACBUS4), LED=~15(ACBUS7).
# CONNECTION NOTES:
# * Connect EXT connector pin 1 with 3 to get 5V on JTAG connector pin 19.
# * Connect JTAG connector pin 1 to 5V (i.e. EXT pin 13 or JTAG pin 19).
# * For TPI connection use resistors: TDO --[470R]-- TPIDATA --[470R]-- TDI.
# * Powering target from JTAG pin 19 allows KT-LINK current measurement.
programmer
id = "ktlink";
desc = "KT-LINK FT2232H interface with IO switching and voltage buffers.";
type = "avrftdi";
connection_type = usb;
usbvid= 0x0403;
usbpid= 0xBBE2;
usbdev= "A";
reset = 8;
sck = 0;
mosi = 1;
miso = 2;
buff = ~10,~14,~13,5;
rdyled = ~15;
;
programmer
id = "serialupdi";
desc = "SerialUPDI";
@@ -890,6 +918,24 @@ programmer
usbpid = 0x0c9f;
;
programmer
id = "arduinoisp";
desc = "Arduino ISP Programmer";
type = "usbtiny";
connection_type = usb;
usbvid = 0x2341;
usbpid = 0x0049;
;
programmer
id = "arduinoisporg";
desc = "Arduino ISP Programmer";
type = "usbtiny";
connection_type = usb;
usbvid = 0x2A03;
usbpid = 0x0049;
;
# commercial version of USBtiny, using a separate VID/PID
programmer
id = "ehajo-isp";
@@ -900,6 +946,16 @@ programmer
usbpid = 0x0BA5;
;
# commercial version of USBtiny, using a separate VID/PID
programmer
id = "iseavrprog";
desc = "USBtiny-based USB programmer, https://github.com/IowaScaledEngineering/ckt-avrprogrammer";
type = "usbtiny";
connection_type = usb;
usbvid = 0x1209;
usbpid = 0x6570;
;
programmer
id = "micronucleus";
desc = "Micronucleus Bootloader";
@@ -918,16 +974,6 @@ programmer
usbpid = 0x0478;
;
# commercial version of USBtiny, using a separate VID/PID
programmer
id = "iseavrprog";
desc = "USBtiny-based USB programmer, https://github.com/IowaScaledEngineering/ckt-avrprogrammer";
type = "usbtiny";
connection_type = usb;
usbvid = 0x1209;
usbpid = 0x6570;
;
programmer
id = "butterfly";
desc = "Atmel Butterfly Development Board";
@@ -4727,8 +4773,37 @@ part parent "m324p"
signature = 0x1e 0x94 0x0a;
memory "eeprom"
paged = no; /* leave this "no" */
size = 512;
page_size = 4;
min_write_delay = 9000;
max_write_delay = 9000;
readback_p1 = 0xff;
readback_p2 = 0xff;
read = " 1 0 1 0 0 0 0 0",
" 0 0 x x x a10 a9 a8",
" a7 a6 a5 a4 a3 a2 a1 a0",
" o o o o o o o o";
write = " 1 1 0 0 0 0 0 0",
" 0 0 x x x a10 a9 a8",
" a7 a6 a5 a4 a3 a2 a1 a0",
" i i i i i i i i";
loadpage_lo = " 1 1 0 0 0 0 0 1",
" 0 0 0 0 0 0 0 0",
" 0 0 0 0 0 0 a1 a0",
" i i i i i i i i";
writepage = " 1 1 0 0 0 0 1 0",
" 0 0 x x x a10 a9 a8",
" a7 a6 a5 a4 a3 a2 0 0",
" x x x x x x x x";
mode = 0x41;
delay = 10;
blocksize = 128;
readsize = 256;
;
memory "flash"
@@ -4736,7 +4811,41 @@ part parent "m324p"
size = 16384;
page_size = 128;
num_pages = 128;
min_write_delay = 4500;
max_write_delay = 4500;
readback_p1 = 0xff;
readback_p2 = 0xff;
read_lo = " 0 0 1 0 0 0 0 0",
" 0 a14 a13 a12 a11 a10 a9 a8",
" a7 a6 a5 a4 a3 a2 a1 a0",
" o o o o o o o o";
read_hi = " 0 0 1 0 1 0 0 0",
" 0 a14 a13 a12 a11 a10 a9 a8",
" a7 a6 a5 a4 a3 a2 a1 a0",
" o o o o o o o o";
loadpage_lo = " 0 1 0 0 0 0 0 0",
" 0 0 x x x x x x",
" x x a5 a4 a3 a2 a1 a0",
" i i i i i i i i";
loadpage_hi = " 0 1 0 0 1 0 0 0",
" 0 0 x x x x x x",
" x x a5 a4 a3 a2 a1 a0",
" i i i i i i i i";
writepage = " 0 1 0 0 1 1 0 0",
" 0 a14 a13 a12 a11 a10 a9 a8",
" a7 a6 x x x x x x",
" x x x x x x x x";
mode = 0x21;
delay = 6;
blocksize = 256;
readsize = 256;
;
;
#------------------------------------------------------------
@@ -5893,7 +6002,7 @@ part
" i i i i i i i i";
writepage = " 0 1 0 0 1 1 0 0",
" x x x a12 a11 a10 a9 a8",
" x a14 a13 a12 a11 a10 a9 a8",
" a7 a6 x x x x x x",
" x x x x x x x x";
@@ -5966,7 +6075,7 @@ part
part parent "m329"
id = "m329a";
desc = "ATmega329a";
desc = "ATmega329A";
;
#------------------------------------------------------------
@@ -6147,7 +6256,7 @@ part
" i i i i i i i i";
writepage = " 0 1 0 0 1 1 0 0",
" x x x a12 a11 a10 a9 a8",
"a15 a14 a13 a12 a11 a10 a9 a8",
" a7 x x x x x x x",
" x x x x x x x x";
@@ -8832,7 +8941,7 @@ part
"a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
write = "1 1 0 0 0 0 0 0 0 0 x x x x x a8",
"a8 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
"a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
loadpage_lo = " 1 1 0 0 0 0 0 1",
" 0 0 0 0 0 0 0 0",
@@ -8840,8 +8949,8 @@ part
" i i i i i i i i";
writepage = " 1 1 0 0 0 0 1 0",
" 0 0 x x x x x x",
" 0 0 a5 a4 a3 a2 0 0",
" 0 0 x x x x x a8",
" a7 a6 a5 a4 a3 a2 0 0",
" x x x x x x x x";
mode = 0x41;
@@ -9019,7 +9128,7 @@ part
"a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
write = "1 1 0 0 0 0 0 0 0 0 x x x x x a8",
"a8 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
"a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
loadpage_lo = " 1 1 0 0 0 0 0 1",
" 0 0 0 0 0 0 0 0",
@@ -9027,8 +9136,8 @@ part
" i i i i i i i i";
writepage = " 1 1 0 0 0 0 1 0",
" 0 0 x x x x x x",
" 0 0 a5 a4 a3 a2 0 0",
" 0 0 x x x x x a8",
" a7 a6 a5 a4 a3 a2 0 0",
" x x x x x x x x";
mode = 0x41;
@@ -9762,6 +9871,81 @@ part parent "m328"
signature = 0x1e 0x96 0x84;
bs2 = 0xe2;
memory "eeprom"
paged = no;
size = 2048;
page_size = 8;
min_write_delay = 3600;
max_write_delay = 3600;
readback_p1 = 0xff;
readback_p2 = 0xff;
read = " 1 0 1 0 0 0 0 0",
" 0 0 0 x x a10 a9 a8",
" a7 a6 a5 a4 a3 a2 a1 a0",
" o o o o o o o o";
write = " 1 1 0 0 0 0 0 0",
" 0 0 0 x x a10 a9 a8",
" a7 a6 a5 a4 a3 a2 a1 a0",
" i i i i i i i i";
loadpage_lo = " 1 1 0 0 0 0 0 1",
" 0 0 0 0 0 0 0 0",
" 0 0 0 0 0 a2 a1 a0",
" i i i i i i i i";
writepage = " 1 1 0 0 0 0 1 0",
" 0 0 x x x a10 a9 a8",
" a7 a6 a5 a4 a3 0 0 0",
" x x x x x x x x";
mode = 0x41;
delay = 20;
blocksize = 4;
readsize = 256;
;
memory "flash"
paged = yes;
size = 65536;
page_size = 256;
num_pages = 256;
min_write_delay = 4500;
max_write_delay = 4500;
readback_p1 = 0xff;
readback_p2 = 0xff;
read_lo = " 0 0 1 0 0 0 0 0",
" a15 a14 a13 a12 a11 a10 a9 a8",
" a7 a6 a5 a4 a3 a2 a1 a0",
" o o o o o o o o";
read_hi = " 0 0 1 0 1 0 0 0",
" a15 a14 a13 a12 a11 a10 a9 a8",
" a7 a6 a5 a4 a3 a2 a1 a0",
" o o o o o o o o";
loadpage_lo = " 0 1 0 0 0 0 0 0",
" 0 0 0 x x x x x",
" x a6 a5 a4 a3 a2 a1 a0",
" i i i i i i i i";
loadpage_hi = " 0 1 0 0 1 0 0 0",
" 0 0 0 x x x x x",
" x a6 a5 a4 a3 a2 a1 a0",
" i i i i i i i i";
writepage = " 0 1 0 0 1 1 0 0",
" a15 a14 a13 a12 a11 a10 a9 a8",
" a7 x x x x x x x",
" x x x x x x x x";
mode = 0x41;
delay = 6;
blocksize = 128;
readsize = 256;
;
memory "efuse"
size = 1;
min_write_delay = 4500;
@@ -10233,7 +10417,7 @@ part
" i i i i i i i i";
writepage = " 1 1 0 0 0 0 1 0",
" 0 0 x x x x x x",
" 0 0 x x x x x a8",
" a7 a6 a5 a4 a3 a2 0 0",
" x x x x x x x x";
@@ -12101,7 +12285,7 @@ part
writepage = " 1 1 0 0 0 0 1 0",
" 0 0 x x x x x x",
" x a6 a5 a4 a3 a2 0 0",
" a7 a6 a5 a4 a3 a2 0 0",
" x x x x x x x x";
mode = 0x41;
@@ -12293,8 +12477,8 @@ part
" i i i i i i i i";
writepage = " 1 1 0 0 0 0 1 0",
" 0 0 x x x x x x",
" x a6 a5 a4 a3 a2 0 0",
" 0 0 x x x x x a8",
" a7 a6 a5 a4 a3 a2 0 0",
" x x x x x x x x";
mode = 0x41;
@@ -12535,7 +12719,7 @@ part parent "t84"
part
id = "t43u";
desc = "ATtiny43u";
desc = "ATtiny43U";
has_debugwire = yes;
flash_instr = 0xB4, 0x07, 0x17;
eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
@@ -12595,7 +12779,7 @@ part
readback_p1 = 0xff;
readback_p2 = 0xff;
read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
"0 0 a4 a3 a2 a1 a0 o o o o o o o o";
"0 0 a5 a4 a3 a2 a1 a0 o o o o o o o o";
write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
"0 0 a5 a4 a3 a2 a1 a0 i i i i i i i i";
@@ -12664,6 +12848,8 @@ part
size = 1;
write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
"x x x x x x x x 1 1 i i i i i i";
read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
"x x x x x x x x o o o o o o o o";
min_write_delay = 4500;
max_write_delay = 4500;
;
@@ -12702,12 +12888,203 @@ part
;
memory "calibration"
size = 2;
size = 1;
read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
"0 0 0 0 0 0 0 a0 o o o o o o o o";
;
;
#------------------------------------------------------------
# ATmega16u4
#------------------------------------------------------------
part
id = "m16u4";
desc = "ATmega16U4";
signature = 0x1e 0x94 0x88;
usbpid = 0x2ff4;
has_jtag = yes;
# stk500_devcode = 0xB2;
# avr910_devcode = 0x43;
chip_erase_delay = 9000;
pagel = 0xD7;
bs2 = 0xA0;
reset = dedicated;
pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
"x x x x x x x x x x x x x x x x";
chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
"x x x x x x x x x x x x x x x x";
timeout = 200;
stabdelay = 100;
cmdexedelay = 25;
synchloops = 32;
bytedelay = 0;
pollindex = 3;
pollvalue = 0x53;
predelay = 1;
postdelay = 1;
pollmethod = 1;
pp_controlstack =
0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
hventerstabdelay = 100;
progmodedelay = 0;
latchcycles = 5;
togglevtg = 1;
poweroffdelay = 15;
resetdelayms = 1;
resetdelayus = 0;
hvleavestabdelay = 15;
chiperasepulsewidth = 0;
chiperasepolltimeout = 10;
programfusepulsewidth = 0;
programfusepolltimeout = 5;
programlockpulsewidth = 0;
programlockpolltimeout = 5;
idr = 0x31;
spmcr = 0x57;
rampz = 0x3b;
allowfullpagebitstream = no;
ocdrev = 3;
memory "eeprom"
paged = no; /* leave this "no" */
page_size = 4; /* for parallel programming */
size = 512;
min_write_delay = 9000;
max_write_delay = 9000;
readback_p1 = 0x00;
readback_p2 = 0x00;
read = " 1 0 1 0 0 0 0 0",
" x x x x x x x a8",
" a7 a6 a5 a4 a3 a2 a1 a0",
" o o o o o o o o";
write = " 1 1 0 0 0 0 0 0",
" x x x x x x x a8",
" a7 a6 a5 a4 a3 a2 a1 a0",
" i i i i i i i i";
loadpage_lo = " 1 1 0 0 0 0 0 1",
" 0 0 0 0 0 0 0 0",
" 0 0 0 0 0 0 a1 a0",
" i i i i i i i i";
writepage = " 1 1 0 0 0 0 1 0",
" 0 0 x x x x x a8",
" a7 a6 a5 a4 a3 a2 0 0",
" x x x x x x x x";
mode = 0x41;
delay = 20;
blocksize = 4;
readsize = 256;
;
memory "flash"
paged = yes;
size = 16384;
page_size = 128;
num_pages = 128;
min_write_delay = 4500;
max_write_delay = 4500;
readback_p1 = 0x00;
readback_p2 = 0x00;
read_lo = " 0 0 1 0 0 0 0 0",
" 0 a14 a13 a12 a11 a10 a9 a8",
" a7 a6 a5 a4 a3 a2 a1 a0",
" o o o o o o o o";
read_hi = " 0 0 1 0 1 0 0 0",
" 0 a14 a13 a12 a11 a10 a9 a8",
" a7 a6 a5 a4 a3 a2 a1 a0",
" o o o o o o o o";
loadpage_lo = " 0 1 0 0 0 0 0 0",
" x x x x x x x x",
" x x a5 a4 a3 a2 a1 a0",
" i i i i i i i i";
loadpage_hi = " 0 1 0 0 1 0 0 0",
" x x x x x x x x",
" x x a5 a4 a3 a2 a1 a0",
" i i i i i i i i";
writepage = " 0 1 0 0 1 1 0 0",
" a15 a14 a13 a12 a11 a10 a9 a8",
" a7 a6 x x x x x x",
" x x x x x x x x";
mode = 0x41;
delay = 6;
blocksize = 128;
readsize = 256;
;
memory "lfuse"
size = 1;
write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
"x x x x x x x x i i i i i i i i";
read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
"x x x x x x x x o o o o o o o o";
min_write_delay = 9000;
max_write_delay = 9000;
;
memory "hfuse"
size = 1;
write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
"x x x x x x x x i i i i i i i i";
read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
"x x x x x x x x o o o o o o o o";
min_write_delay = 9000;
max_write_delay = 9000;
;
memory "efuse"
size = 1;
write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
"x x x x x x x x 1 1 1 1 i i i i";
read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
"x x x x x x x x o o o o o o o o";
min_write_delay = 9000;
max_write_delay = 9000;
;
memory "lock"
size = 1;
read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
"x x x x x x x x 0 0 o o o o o o";
write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
"x x x x x x x x 1 1 i i i i i i";
min_write_delay = 9000;
max_write_delay = 9000;
;
memory "calibration"
size = 1;
read = "0 0 1 1 1 0 0 0 x x x x x x x x",
"0 0 0 0 0 0 0 0 o o o o o o o o";
;
memory "signature"
size = 3;
read = "0 0 1 1 0 0 0 0 x x x x x x x x",
"x x x x x x a1 a0 o o o o o o o o";
;
;
#------------------------------------------------------------
# ATmega32u4
#------------------------------------------------------------
@@ -12788,12 +13165,12 @@ part
loadpage_lo = " 1 1 0 0 0 0 0 1",
" 0 0 0 0 0 0 0 0",
" 0 0 0 0 0 a2 a1 a0",
" 0 0 0 0 0 0 a1 a0",
" i i i i i i i i";
writepage = " 1 1 0 0 0 0 1 0",
" 0 0 x x x a10 a9 a8",
" a7 a6 a5 a4 a3 0 0 0",
" a7 a6 a5 a4 a3 a2 0 0",
" x x x x x x x x";
mode = 0x41;
@@ -12867,7 +13244,7 @@ part
memory "efuse"
size = 1;
write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
"x x x x x x x x x x x x i i i i";
"x x x x x x x x 1 1 1 1 i i i i";
read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
"x x x x x x x x o o o o o o o o";
@@ -13187,7 +13564,7 @@ part
" i i i i i i i i";
writepage = " 1 1 0 0 0 0 1 0",
" 0 0 x x x a10 a9 a8",
" 0 0 x x a11 a10 a9 a8",
" a7 a6 a5 a4 a3 0 0 0",
" x x x x x x x x";
@@ -14249,7 +14626,7 @@ part
part
id = "m165";
desc = "ATmega165";
signature = 0x1e 0x94 0x07;
signature = 0x1e 0x94 0x10;
has_jtag = yes;
# stk500_devcode = 0x??;
# avr910_devcode = 0x??;
@@ -14423,7 +14800,7 @@ part
memory "signature"
size = 3;
read = "0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0",
read = "0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0",
"x x x x x x a1 a0 o o o o o o o o";
;
@@ -15431,6 +15808,13 @@ part parent "x128c3"
id = "x128d4";
desc = "ATxmega128D4";
signature = 0x1e 0x97 0x47;
memory "flash"
size = 0x22000;
offset = 0x800000;
page_size = 0x100;
readsize = 0x100;
;
;
#------------------------------------------------------------
@@ -16239,28 +16623,28 @@ part
readback_p1 = 0xff;
readback_p2 = 0xff;
read_lo = " 0 0 1 0 0 0 0 0",
" 0 0 0 a12 a11 a10 a9 a8",
" 0 0 a13 a12 a11 a10 a9 a8",
" a7 a6 a5 a4 a3 a2 a1 a0",
" o o o o o o o o";
read_hi = " 0 0 1 0 1 0 0 0",
" 0 0 0 a12 a11 a10 a9 a8",
" 0 0 a13 a12 a11 a10 a9 a8",
" a7 a6 a5 a4 a3 a2 a1 a0",
" o o o o o o o o";
loadpage_lo = " 0 1 0 0 0 0 0 0",
" 0 0 0 x x x x x",
" x x a5 a4 a3 a2 a1 a0",
" x x x x a3 a2 a1 a0",
" i i i i i i i i";
loadpage_hi = " 0 1 0 0 1 0 0 0",
" 0 0 0 x x x x x",
" x x a5 a4 a3 a2 a1 a0",
" x x x x a3 a2 a1 a0",
" i i i i i i i i";
writepage = " 0 1 0 0 1 1 0 0",
" 0 0 0 a12 a11 a10 a9 a8",
" a7 a6 x x x x x x",
" 0 0 a13 a12 a11 a10 a9 a8",
" a7 a6 a5 a4 x x x x",
" x x x x x x x x";
mode = 0x41;
@@ -16499,7 +16883,7 @@ part parent ".reduced_core_tiny"
part
id = "m406";
desc = "ATMEGA406";
desc = "ATmega406";
has_jtag = yes;
signature = 0x1e 0x95 0x07;
@@ -16632,9 +17016,7 @@ part
;
memory "wdtcfg"
size = 1;
offset = 0x1280;
readsize = 1;
alias "fuse0";
;
memory "fuse1"
@@ -16644,9 +17026,7 @@ part
;
memory "bodcfg"
size = 1;
offset = 0x1281;
readsize = 1;
alias "fuse1";
;
memory "fuse2"
@@ -16656,9 +17036,7 @@ part
;
memory "osccfg"
size = 1;
offset = 0x1282;
readsize = 1;
alias "fuse2";
;
memory "fuse4"
@@ -16668,9 +17046,7 @@ part
;
memory "tcd0cfg"
size = 1;
offset = 0x1284;
readsize = 1;
alias "fuse4";
;
memory "fuse5"
@@ -16680,9 +17056,7 @@ part
;
memory "syscfg0"
size = 1;
offset = 0x1285;
readsize = 1;
alias "fuse5";
;
memory "fuse6"
@@ -16692,9 +17066,7 @@ part
;
memory "syscfg1"
size = 1;
offset = 0x1286;
readsize = 1;
alias "fuse6";
;
memory "fuse7"
@@ -16704,9 +17076,11 @@ part
;
memory "append"
size = 1;
offset = 0x1287;
readsize = 1;
alias "fuse7";
;
memory "codesize"
alias "fuse7";
;
memory "fuse8"
@@ -16716,9 +17090,11 @@ part
;
memory "bootend"
size = 1;
offset = 0x1288;
readsize = 1;
alias "fuse8";
;
memory "bootsize"
alias "fuse8";
;
memory "lock"
@@ -16742,12 +17118,16 @@ part parent ".avr8x"
desc = "AVR8X tiny family common values";
family_id = "tinyAVR";
memory "usersig"
memory "userrow"
size = 0x20;
offset = 0x1300;
page_size = 0x20;
readsize = 0x100;
;
memory "usersig"
alias "userrow";
;
;
#------------------------------------------------------------
@@ -16759,12 +17139,16 @@ part parent ".avr8x"
desc = "AVR8X mega family common values";
family_id = "megaAVR";
memory "usersig"
memory "userrow"
size = 0x40;
offset = 0x1300;
page_size = 0x40;
readsize = 0x100;
;
memory "usersig"
alias "userrow";
;
;
#------------------------------------------------------------
@@ -17900,9 +18284,7 @@ part
;
memory "wdtcfg"
size = 1;
offset = 0x1050;
readsize = 1;
alias "fuse0";
;
memory "fuse1"
@@ -17912,9 +18294,7 @@ part
;
memory "bodcfg"
size = 1;
offset = 0x1051;
readsize = 1;
alias "fuse1";
;
memory "fuse2"
@@ -17924,9 +18304,7 @@ part
;
memory "osccfg"
size = 1;
offset = 0x1052;
readsize = 1;
alias "fuse2";
;
memory "fuse4"
@@ -17936,9 +18314,7 @@ part
;
memory "tcd0cfg"
size = 1;
offset = 0x1054;
readsize = 1;
alias "fuse4";
;
memory "fuse5"
@@ -17948,9 +18324,7 @@ part
;
memory "syscfg0"
size = 1;
offset = 0x1055;
readsize = 1;
alias "fuse5";
;
memory "fuse6"
@@ -17960,9 +18334,7 @@ part
;
memory "syscfg1"
size = 1;
offset = 0x1056;
readsize = 1;
alias "fuse6";
;
memory "fuse7"
@@ -17972,15 +18344,11 @@ part
;
memory "codesize"
size = 1;
offset = 0x1057;
readsize = 1;
alias "fuse7";
;
memory "append"
size = 1;
offset = 0x1057;
readsize = 1;
alias "fuse7";
;
memory "fuse8"
@@ -17990,15 +18358,11 @@ part
;
memory "bootsize"
size = 1;
offset = 0x1058;
readsize = 1;
alias "fuse8";
;
memory "bootend"
size = 1;
offset = 0x1058;
readsize = 1;
alias "fuse8";
;
memory "lock"
@@ -18015,6 +18379,10 @@ part
readsize = 0x20;
;
memory "usersig"
alias "userrow";
;
memory "data"
# SRAM, only used to supply the offset
offset = 0x1000000;
@@ -18851,6 +19219,10 @@ part parent ".avrdx"
page_size = 0x40;
readsize = 0x40;
;
memory "usersig"
alias "userrow";
;
;
#------------------------------------------------------------

View File

@@ -260,6 +260,21 @@ AVRMEM * avr_new_memtype(void)
return m;
}
AVRMEM_ALIAS * avr_new_memalias(void)
{
AVRMEM_ALIAS * m;
m = (AVRMEM_ALIAS *)malloc(sizeof(*m));
if (m == NULL) {
avrdude_message(MSG_INFO, "avr_new_memalias(): out of memory\n");
exit(1);
}
memset(m, 0, sizeof(*m));
return m;
}
/*
* Allocate and initialize memory buffers for each of the device's
@@ -326,6 +341,17 @@ AVRMEM * avr_dup_mem(AVRMEM * m)
return n;
}
AVRMEM_ALIAS * avr_dup_memalias(AVRMEM_ALIAS * m)
{
AVRMEM_ALIAS * n;
n = avr_new_memalias();
*n = *m;
return n;
}
void avr_free_mem(AVRMEM * m)
{
int i;
@@ -348,7 +374,36 @@ void avr_free_mem(AVRMEM * m)
free(m);
}
AVRMEM * avr_locate_mem(AVRPART * p, char * desc)
void avr_free_memalias(AVRMEM_ALIAS * m)
{
free(m);
}
AVRMEM_ALIAS * avr_locate_memalias(AVRPART * p, char * desc)
{
AVRMEM_ALIAS * m, * match;
LNODEID ln;
int matches;
int l;
l = strlen(desc);
matches = 0;
match = NULL;
for (ln=lfirst(p->mem_alias); ln; ln=lnext(ln)) {
m = ldata(ln);
if (strncmp(desc, m->desc, l) == 0) {
match = m;
matches++;
}
}
if (matches == 1)
return match;
return NULL;
}
AVRMEM * avr_locate_mem_noalias(AVRPART * p, char * desc)
{
AVRMEM * m, * match;
LNODEID ln;
@@ -373,11 +428,54 @@ AVRMEM * avr_locate_mem(AVRPART * p, char * desc)
}
AVRMEM * avr_locate_mem(AVRPART * p, char * desc)
{
AVRMEM * m, * match;
AVRMEM_ALIAS * alias;
LNODEID ln;
int matches;
int l;
l = strlen(desc);
matches = 0;
match = NULL;
for (ln=lfirst(p->mem); ln; ln=lnext(ln)) {
m = ldata(ln);
if (strncmp(desc, m->desc, l) == 0) {
match = m;
matches++;
}
}
if (matches == 1)
return match;
/* not yet found: look for matching alias name */
alias = avr_locate_memalias(p, desc);
if (alias != NULL)
return alias->aliased_mem;
return NULL;
}
AVRMEM_ALIAS * avr_find_memalias(AVRPART * p, AVRMEM * m_orig)
{
AVRMEM_ALIAS * m;
LNODEID ln;
for (ln=lfirst(p->mem_alias); ln; ln=lnext(ln)) {
m = ldata(ln);
if (m->aliased_mem == m_orig)
return m;
}
return NULL;
}
void avr_mem_display(const char * prefix, FILE * f, AVRMEM * m, AVRPART * p,
int type, int verbose)
{
static LNODEID ln;
static AVRMEM * n;
static unsigned int prev_mem_offset, prev_mem_size;
int i, j;
char * optr;
@@ -398,25 +496,14 @@ void avr_mem_display(const char * prefix, FILE * f, AVRMEM * m, AVRPART * p,
prefix, prefix, prefix);
}
// Get the next memory section, and stop before going out of band
if (ln == NULL)
ln = lnext(lfirst(p->mem));
else
ln = lnext(ln);
if (ln != NULL)
n = ldata(ln);
// Only print memory section if the previous section printed isn't identical
if(prev_mem_offset != m->offset || prev_mem_size != m->size || (strcmp(p->family_id, "") == 0)) {
prev_mem_offset = m->offset;
prev_mem_size = m->size;
AVRMEM_ALIAS *ap = avr_find_memalias(p, m);
/* Show alias if the current and the next memory section has the same offset
and size, we're not out of band and a family_id is present */
char * mem_desc_alias = m->offset == n->offset && \
m->size == n->size && \
ln != NULL && \
strcmp(p->family_id, "") != 0 ?
n->desc : "";
char * mem_desc_alias = ap? ap->desc: "";
fprintf(f,
"%s%-11s %-8s %4d %5d %5d %4d %-6s %6d %4d %6d %5d %5d 0x%02x 0x%02x\n",
prefix,
@@ -488,6 +575,7 @@ AVRPART * avr_new_part(void)
p->ocdrev = -1;
p->mem = lcreat(NULL, 0);
p->mem_alias = lcreat(NULL, 0);
return p;
}
@@ -496,19 +584,35 @@ AVRPART * avr_new_part(void)
AVRPART * avr_dup_part(AVRPART * d)
{
AVRPART * p;
LISTID save;
LNODEID ln;
LISTID save, save2;
LNODEID ln, ln2;
int i;
p = avr_new_part();
save = p->mem;
save2 = p->mem_alias;
*p = *d;
p->mem = save;
p->mem_alias = save2;
for (ln=lfirst(d->mem); ln; ln=lnext(ln)) {
ladd(p->mem, avr_dup_mem(ldata(ln)));
AVRMEM *m = ldata(ln);
AVRMEM *m2 = avr_dup_mem(m);
ladd(p->mem, m2);
// see if there is any alias for it
for (ln2=lfirst(d->mem_alias); ln2; ln2=lnext(ln2)) {
AVRMEM_ALIAS *a = ldata(ln2);
if (a->aliased_mem == m) {
// yes, duplicate it
AVRMEM_ALIAS *a2 = avr_dup_memalias(a);
// ... adjust the pointer ...
a2->aliased_mem = m2;
// ... and add to new list
ladd(p->mem_alias, a2);
}
}
}
for (i = 0; i < AVR_OP_MAX; i++) {
@@ -523,6 +627,8 @@ void avr_free_part(AVRPART * d)
int i;
ldestroy_cb(d->mem, (void(*)(void *))avr_free_mem);
d->mem = NULL;
ldestroy_cb(d->mem_alias, (void(*)(void *))avr_free_memalias);
d->mem_alias = NULL;
for(i=0;i<sizeof(d->op)/sizeof(d->op[0]);i++)
{
if (d->op[i] != NULL)

View File

@@ -36,7 +36,6 @@ char default_programmer[MAX_STR_CONST];
char default_parallel[PATH_MAX];
char default_serial[PATH_MAX];
double default_bitclock;
int default_safemode;
char string_buf[MAX_STR_CONST];
char *string_buf_ptr;
@@ -48,6 +47,7 @@ AVRPART * current_part;
AVRMEM * current_mem;
LISTID part_list;
LISTID programmers;
bool is_alias;
int lineno;
const char * infile;
@@ -73,6 +73,7 @@ int init_config(void)
current_mem = NULL;
part_list = lcreat(NULL, 0);
programmers = lcreat(NULL, 0);
is_alias = false;
lineno = 1;
infile = NULL;

View File

@@ -54,6 +54,7 @@ extern int lineno;
extern const char * infile;
extern LISTID string_list;
extern LISTID number_list;
extern bool is_alias; // current entry is alias
#if !defined(HAS_YYSTYPE)

View File

@@ -68,6 +68,7 @@ static int pin_name;
%token K_PAGE_SIZE
%token K_PAGED
%token K_ALIAS
%token K_BAUDRATE
%token K_BS2
%token K_BUFF
@@ -77,7 +78,6 @@ static int pin_name;
%token K_DEFAULT_BITCLOCK
%token K_DEFAULT_PARALLEL
%token K_DEFAULT_PROGRAMMER
%token K_DEFAULT_SAFEMODE
%token K_DEFAULT_SERIAL
%token K_DESC
%token K_FAMILY_ID
@@ -257,14 +257,6 @@ def :
K_DEFAULT_BITCLOCK TKN_EQUAL number_real TKN_SEMI {
default_bitclock = $3->value.number_real;
free_token($3);
} |
K_DEFAULT_SAFEMODE TKN_EQUAL yesno TKN_SEMI {
if ($3->primary == K_YES)
default_safemode = 1;
else if ($3->primary == K_NO)
default_safemode = 0;
free_token($3);
}
;
@@ -1248,12 +1240,17 @@ part_parm :
{
AVRMEM * existing_mem;
existing_mem = avr_locate_mem(current_part, current_mem->desc);
existing_mem = avr_locate_mem_noalias(current_part, current_mem->desc);
if (existing_mem != NULL) {
lrmv_d(current_part->mem, existing_mem);
avr_free_mem(existing_mem);
}
if (is_alias) {
avr_free_mem(current_mem); // alias mem has been already entered below
is_alias = false;
} else {
ladd(current_part->mem, current_mem);
}
current_mem = NULL;
} |
@@ -1290,6 +1287,7 @@ yesno :
mem_specs :
mem_spec TKN_SEMI |
mem_alias TKN_SEMI |
mem_specs mem_spec TKN_SEMI
;
@@ -1419,6 +1417,38 @@ mem_spec :
}
;
mem_alias :
K_ALIAS TKN_STRING
{
AVRMEM * existing_mem;
existing_mem = avr_locate_mem(current_part, $2->value.string);
if (existing_mem == NULL) {
yyerror("%s alias to non-existent memory %s",
current_mem->desc, $2->value.string);
free_token($2);
YYABORT;
}
// if this alias does already exist, drop the old one
AVRMEM_ALIAS * alias = avr_locate_memalias(current_part, current_mem->desc);
if (alias) {
lrmv_d(current_part->mem_alias, alias);
avr_free_memalias(alias);
}
is_alias = true;
alias = avr_new_memalias();
// alias->desc and current_mem->desc have the same length
// definition, thus no need to check for length here
strcpy(alias->desc, current_mem->desc);
alias->aliased_mem = existing_mem;
ladd(current_part->mem_alias, alias);
free_token($2);
}
;
%%

View File

@@ -23,7 +23,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.60)
AC_INIT(avrdude, 6.99-20211218, avrdude-dev@nongnu.org)
AC_INIT(avrdude, 7.0, avrdude-dev@nongnu.org)
AC_CANONICAL_BUILD
AC_CANONICAL_HOST

View File

@@ -40,7 +40,7 @@ all-local: info html ps pdf
html: avrdude-html/avrdude.html
avrdude-html/avrdude.html: $(srcdir)/$(info_TEXINFOS) $(GENERATED_TEXINFOS)
texi2html -split_node $(srcdir)/$(info_TEXINFOS)
texi2html --split=node --css-include=$(srcdir)/avrdude.css $(srcdir)/$(info_TEXINFOS)
if [ -e ./avrdude.html -o -e ./avrdude_1.html ]; then \
mkdir -p avrdude-html ; \
mv -f *.html avrdude-html ; \

20
src/doc/avrdude.css Normal file
View File

@@ -0,0 +1,20 @@
body { background-color: #ffd; }
h1 { text-shadow: .05em .05em #ccc; }
table {
border: 3px solid #ccf;
background-color: white;
}
div.smallexample {
background-color: #dfd;
border: 3px solid #cfc;
}
div.example {
background-color: #dfd;
border: 3px solid #cfc;
}
samp {
color: blue;
}
code {
color: green;
}

View File

@@ -28,9 +28,7 @@ This file documents the avrdude program.
For avrdude version @value{VERSION}, @value{UPDATED}.
Copyright @copyright{} 2003, 2005 Brian Dean
Copyright @copyright{} 2006 - 2021 J@"org Wunsch
Copyright @copyright{} Brian Dean, J@"org Wunsch
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
@@ -64,13 +62,10 @@ the terms of the GNU Free Documentation License (FDL), version 1.3.
@author by Brian S. Dean
@page
Send comments on AVRDUDE to @w{@email{avrdude-dev@@nongnu.org}}.
Use @uref{http://savannah.nongnu.org/bugs/?group=avrdude} to report bugs.
Use @uref{https://github.com/avrdudes/avrdude/issues} to report bugs and ask questions.
Copyright @copyright{} 2003,2005 Brian S. Dean
Copyright @copyright{} 2006 - 2013 J@"org Wunsch
Copyright @copyright{} Brian S. Dean, J@"org Wunsch
@sp 2
Permission is granted to make and distribute verbatim copies of
@@ -102,13 +97,9 @@ programs to Atmel AVR microcontrollers.
For avrdude version @value{VERSION}, @value{UPDATED}.
Send comments on AVRDUDE to @w{@email{avrdude-dev@@nongnu.org}}.
Use @uref{https://github.com/avrdudes/avrdude/issues} to report bugs and ask questions.
Use @uref{http://savannah.nongnu.org/bugs/?group=avrdude} to report bugs.
Copyright @copyright{} 2003,2005 Brian S. Dean
Copyright @copyright{} 2006 J@"org Wunsch
Copyright @copyright{} Brian S. Dean, J@"org Wunsch
@end ifinfo
@menu
@@ -119,6 +110,7 @@ Copyright @copyright{} 2006 J@"org Wunsch
* Programmer Specific Information::
* Platform Dependent Information::
* Troubleshooting::
* Index::
@end menu
@c
@@ -127,7 +119,7 @@ Copyright @copyright{} 2006 J@"org Wunsch
@node Introduction, Command Line Options, Top, Top
@comment node-name, next, previous, up
@chapter Introduction
@cindex introduction
@cindex Introduction
AVRDUDE - AVR Downloader Uploader - is a program for downloading and
uploading the on-chip memories of Atmel's AVR microcontrollers. It can
@@ -145,6 +137,8 @@ from the contents of a file, while interactive mode is useful for
exploring memory contents, modifying individual bytes of eeprom,
programming fuse/lock bits, etc.
@cindex Programmers supported
AVRDUDE supports the following basic programmer types: Atmel's STK500,
Atmel's AVRISP and AVRISP mkII devices,
Atmel's STK600,
@@ -345,6 +339,7 @@ below for Teensy specific options.
@c Node
@c
@node History, , Introduction, Introduction
@cindex History
@section History and Credits
AVRDUDE was written by Brian S. Dean under the name of AVRPROG to run on
@@ -353,13 +348,15 @@ AVRDUDE when interest grew in a Windows port of the software so that the
name did not conflict with AVRPROG.EXE which is the name of Atmel's
Windows programming software.
The AVRDUDE source now resides in the public CVS repository on
savannah.gnu.org (@url{http://savannah.gnu.org/projects/avrdude/}),
where it continues to be enhanced and ported to other systems. In
For many years, the AVRDUDE source resided in public repositories on
savannah.nongnu.org,
where it continued to be enhanced and ported to other systems. In
addition to FreeBSD, AVRDUDE now runs on Linux and Windows. The
developers behind the porting effort primarily were Ted Roth, Eric
Weddington, and Joerg Wunsch.
In 2022, the project moved to Github (@url{https://github.com/avrdudes/avrdude/}).
And in the spirit of many open source projects, this manual also draws
on the work of others. The initial revision was composed of parts of
the original Unix manual page written by Joerg Wunsch, the original web
@@ -374,7 +371,6 @@ Roth.
@c
@node Command Line Options, Terminal Mode Operation, Introduction, Top
@chapter Command Line Options
@cindex options
@menu
* Option Descriptions::
@@ -386,6 +382,7 @@ Roth.
@c Node
@c
@node Option Descriptions, Programmers accepting extended parameters, Command Line Options, Command Line Options
@cindex Options (command-line)
@section Option Descriptions
@noindent
@@ -410,6 +407,8 @@ but it can be added to the configuration file if you have the Atmel
datasheet so that you can enter the programming specifications.
Currently, the following MCU types are understood:
@cindex Device support
@multitable @columnfractions .15 .3
@include parts.texi
@end multitable
@@ -461,6 +460,8 @@ file without any code changes to AVRDUDE. Simply copy an existing entry
and change the pin definitions to match that of the unknown programmer.
Currently, the following programmer ids are understood and supported:
@cindex Programmer support
@multitable @columnfractions .2 .6
@include programmers.texi
@end multitable
@@ -681,32 +682,6 @@ Posix systems (by now).
Disable (or quell) output of the progress bar while reading or writing
to the device. Specify it a second time for even quieter operation.
@item -u
Disables the default behaviour of reading out the fuses three times before
programming, then verifying at the end of programming that the fuses have not
changed. If you want to change fuses you will need to specify this option,
as avrdude will see the fuses have changed (even though you wanted to) and
will change them back for your "safety". This option was designed to
prevent cases of fuse bits magically changing (usually called @emph{safemode}).
If one of the configuration files contains a line
@code{default_safemode = no;}
safemode is disabled by default.
The @option{-u} option's effect is negated in that case, i. e. it
@emph{enables} safemode.
Safemode is always disabled for AVR32, Xmega and TPI devices.
@item -s
Disable safemode prompting. When safemode discovers that one or more
fuse bits have unintentionally changed, it will prompt for
confirmation regarding whether or not it should attempt to recover the
fuse bit(s). Specifying this flag disables the prompt and assumes
that the fuse bit(s) should be recovered without asking for
confirmation first.
@item -t
Tells AVRDUDE to enter the interactive ``terminal'' mode instead of up-
or downloading files. See below for a detailed description of the
@@ -864,7 +839,7 @@ accepting extended parameters.
@c
@node Programmers accepting extended parameters, Example Command Line Invocations, Option Descriptions, Command Line Options
@section Programmers accepting extended parameters
@cindex @code{-x} AVR Dragon
@table @code
@item JTAG ICE mkII/3
@@ -881,6 +856,7 @@ Each AVR unit within the chain shifts by 4 bits.
Other JTAG units might require a different bit shift count.
@end table
@cindex @code{-x} AVR910
@item AVR910
The AVR910 programmer type accepts the following extended parameter:
@@ -901,13 +877,16 @@ Use
programmer creates errors during initial sequence.
@end table
@cindex @code{-x} Arduino
@item Arduino
The Arduino programmer type accepts the following extended parameter:
@table @code
@item @samp{attemps=VALUE}
Overide the default number of connection retry attempt by using @var{VALUE}.
@end table
@cindex @code{-x} Buspirate
@item BusPirate
The BusPirate programmer type accepts the following extended parameters:
@@ -997,6 +976,7 @@ The default value is 100ms. Using 10ms might work in most cases.
@end table
@cindex @code{-x} Micronucleus bootloader
@item Micronucleus bootloader
When using the Micronucleus programmer type, the
@@ -1009,6 +989,7 @@ If no time-out is specified, AVRDUDE will wait indefinitely until the
device is plugged in.
@end table
@cindex @code{-x} Teensy bootloader
@item Teensy bootloader
When using the Teensy programmer type, the
@@ -1021,6 +1002,7 @@ If no time-out is specified, AVRDUDE will wait indefinitely until the
device is plugged in.
@end table
@cindex @code{-x} Wiring
@item Wiring
When using the Wiring programmer type, the
@@ -1032,6 +1014,7 @@ After performing the port open phase, AVRDUDE will wait/snooze for
No toggling of DTR/RTS is performed if @var{snooze} > 0.
@end table
@cindex @code{-x} PICkit2
@item PICkit2
Connection to the PICkit2 programmer:
@multitable @columnfractions .05 .3
@@ -1052,6 +1035,7 @@ 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
@cindex @code{-x} USBasp
@item USBasp
Extended parameters:
@table @code
@@ -1062,6 +1046,7 @@ rather than entire chip.
Only applicable to TPI devices (ATtiny 4/5/9/10/20/40).
@end table
@cindex @code{-x} xbee
@item xbee
Extended parameters:
@table @code
@@ -1078,6 +1063,7 @@ The remaining two necessary XBee-to-MCU connections are not selectable
the MCU's TXD line.
@end table
@cindex @code{-x} serialupdi
@item serialupdi
Extended parameters:
@table @code
@@ -1133,8 +1119,6 @@ Reading | ################################################## | 100% 6.83s
avrdude: verifying ...
avrdude: 19278 bytes of flash verified
avrdude: safemode: Fuses OK
avrdude done. Thank you.
%
@@ -1162,8 +1146,6 @@ Reading | ################################################## | 100% 46.10s
avrdude: writing output file "c:/diag flash.bin"
avrdude: safemode: Fuses OK
avrdude done. Thank you.
%
@@ -1284,6 +1266,7 @@ commands can be recalled and edited.
@end menu
@node Terminal Mode Commands, Terminal Mode Examples, Terminal Mode Operation, Terminal Mode Operation
@cindex Terminal Mode
@section Terminal Mode Commands
@noindent
@@ -1291,20 +1274,83 @@ The following commands are implemented:
@table @code
@item dump @var{memtype} @var{addr} @var{nbytes}
@item dump @var{memtype} [@var{start_addr} [@var{nbytes}]]
Read @var{nbytes} from the specified memory area, and display them in
the usual hexadecimal and ASCII form.
@item dump
@item dump @var{memtype} [@var{start_addr}] @dots{}
Start reading from @var{start_addr}, all the way to the last memory address.
@item dump @var{memtype}
Continue dumping the memory contents for another @var{nbytes} where the
previous dump command left off.
@item write @var{memtype} @var{addr} @var{byte1} @dots{} @var{byteN}
Manually program the respective memory cells, starting at address addr,
using the values @var{byte1} through @var{byteN}. This feature is not
@item write @var{memtype} @var{start_addr} @var{data1} @var{data2} @dots{} @var{dataN}
Manually program the respective memory cells, starting at address @var{start_addr},
using the values @var{data1} through @var{dataN}. This feature is not
implemented for bank-addressed memories such as the flash memory of
ATMega devices.
Items @var{dataN} can have the following formats:
@multitable @columnfractions .3 .4 .3
@item @strong{Type}
@tab @strong{Example}
@tab @strong{Size (bytes)}
@item Character
@tab @code{'A'}
@tab 1
@item Decimal integer
@tab 12345
@tab 1, 2, 4, or 8 (see below)
@item Octal integer
@tab 012345
@tab 1, 2, 4, or 8 (see below)
@item Hexadecimal integer
@tab 0x12345
@tab 1, 2, 4, or 8 (see below)
@item Float
@tab 3.1415926
@tab 4
@end multitable
Integer constants can be 1, 2, 4, or 8 bytes long.
By default, the smallest possible size will be used where
the specified number just fits into.
A specific size can be denoted by appending one of these suffixes:
@table @code
@item LL
@itemx ll
8 bytes / 64 bits
@item L
@itemx l
4 bytes / 32 bits
@item H
@itemx h
@itemx S
@itemx s
2 bytes / 16 bits
@item HH
@itemx hh
1 byte / 8 bits
@end table
Similarly, floating-point constants can have an @code{F} or @code{f}
appended, but only 32-bit floating-point values are supported.
@item write @var{memtype} @var{start_addr} @var{length} @var{data1} @var{data2} @var{dataN} @dots{}
Similar to the above, but @var{length} byte of the memory are written.
For that purpose, after writing the initial items, @var{dataN} is
replicated as many times as needed.
@item erase
Perform a chip erase.
@@ -1397,6 +1443,7 @@ Display the current target supply voltage and JTAG bit clock rate/period.
@c Node
@c
@node Terminal Mode Examples, , Terminal Mode Commands, Terminal Mode Operation
@cindex Terminal Mode
@section Terminal Mode Examples
@noindent
@@ -1408,7 +1455,6 @@ Display part parameters, modify eeprom cells, perform a chip erase:
avrdude: AVR device initialized and ready to accept instructions
avrdude: Device signature = 0x1e9702
avrdude: current erase-rewrite cycle count is 52 (if being tracked)
avrdude> part
>>> part
@@ -1470,7 +1516,6 @@ display the factory defaults, then reprogram:
avrdude: AVR device initialized and ready to accept instructions
avrdude: Device signature = 0x1e9702
avrdude: current erase-rewrite cycle count is 52 (if being tracked)
avrdude> d efuse
>>> d efuse
0000 fd |. |
@@ -1496,11 +1541,56 @@ avrdude>
@end cartouche
@end smallexample
@smallexample
@cartouche
% avrdude -c pkobn_updi -p avr128db48 -t
Vtarget : 4.71 V
PDI/UPDI clock Xmega/megaAVR : 100 kHz
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.01s
avrdude: Device signature = 0x1e970c (probably avr128db48)
avrdude> write eeprom 0 1234567890 'A' 'V' 'R' 2.718282 "Hello World!"
>>> write eeprom 0 1234567890 'A' 'V' 'R' 2.718282 "Hello World!"
Warning: no size suffix specified for "1234567890". Writing 4 byte(s)
Info: Writing 24 bytes starting from address 0x00
avrdude> dump eeprom 0 32
>>> dump eeprom 0 32
0000 d2 02 96 49 41 56 52 55 f8 2d 40 48 65 6c 6c 6f |...IAVRU.-@@Hello|
0010 20 57 6f 72 6c 64 21 00 ff ff ff ff ff ff ff ff | World!.........|
avrdude> q
@end cartouche
@end smallexample
The following example demonstrates the second form of the @code{write}
command where the last data value provided is used to fill up the
indicated memory range.
@smallexample
@cartouche
avrdude> write eeprom 0x00 0x20 'a' 'b' 'c' 0x11 0xcafe 0x55 ...
>>> write eeprom 0x00 0x20 'a' 'b' 'c' 0x11 0xcafe 0x55 ...
avrdude> dump eeprom 0 0x30
>>> dump eeprom 0 0x30
0000 61 62 63 11 fe ca 55 55 55 55 55 55 55 55 55 55 |abc...UUUUUUUUUU|
0010 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 |UUUUUUUUUUUUUUUU|
0020 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
@end cartouche
@end smallexample
@c
@c Node
@c
@node Configuration File, Programmer Specific Information, Terminal Mode Operation, Top
@cindex Configuration File
@cindex @code{avrdude.conf}
@chapter Configuration File
@noindent
@@ -1845,9 +1935,6 @@ 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
functionality does not make sense for these boot loaders.
@end itemize
@c
@@ -1866,6 +1953,7 @@ functionality does not make sense for these boot loaders.
@c Node
@c
@node Atmel STK600, Atmel DFU bootloader using FLIP version 1, Programmer Specific Information, Programmer Specific Information
@cindex STK600
@section Atmel STK600
@c
@@ -1962,6 +2050,7 @@ least 4.5 V in order to work. This can be done using
@c Node
@c
@node Atmel DFU bootloader using FLIP version 1, SerialUPDI programmer , Atmel STK600, Programmer Specific Information
@cindex DFU bootloader
@section Atmel DFU bootloader using FLIP version 1
Bootloaders using the FLIP protocol version 1 experience some very
@@ -1990,6 +2079,7 @@ versions of the bootloader.
@c Node
@c
@node SerialUPDI programmer, , Atmel DFU bootloader using FLIP version 1, Programmer Specific Information
@cindex SerialUPDI
@section SerialUPDI programmer
SerialUPDI programmer can be used for programming UPDI-only devices
@@ -2021,9 +2111,6 @@ fuse, extended fuse) have no meaning whatsoever, as they have been
simply replaced by array of fuses: fuse0..9. Therefore you can simply
ignore this particular line of AVRDUDE output.
In connection to the above, @emph{safemode} has no meaning in context
of UPDI devices and should be ignored.
Currently available devices support only UPDI NVM programming model 0
and 2, but there is also experimental implementation of model 3 - not
yet tested.
@@ -2243,6 +2330,8 @@ configuration file will be always be @code{/etc/avrdude.conf}.
@noindent
The parallel and serial port device file names are system specific.
MacOS has no default serial or parallel port names, but available
ports can be found under @code{/dev/cu.*}.
The following table lists the default names for a given system.
@multitable @columnfractions .30 .30 .30
@@ -2475,13 +2564,13 @@ such as @option{--prefix} and @option{--datadir}.
@c
@c Node
@c
@node Troubleshooting, ,Platform Dependent Information ,Top
@node Troubleshooting,Index ,Platform Dependent Information ,Top
@appendix Troubleshooting
@noindent
In general, please report any bugs encountered via
@*
@url{http://savannah.nongnu.org/bugs/?group=avrdude}.
@url{https://github.com/avrdudes/avrdude/issues}.
@itemize @bullet
@@ -2786,7 +2875,11 @@ erase cycle.
@end itemize
@node Index, , Troubleshooting, Top
@unnumbered Concept Index
@printindex cp
@bye

View File

@@ -493,7 +493,7 @@ static int jtag3_edbg_send(PROGRAMMER * pgm, unsigned char * data, size_t 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",
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_send(): failed to send command to serial port\n",
progname);
return -1;
}
@@ -509,7 +509,7 @@ static int jtag3_edbg_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
(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",
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_send(): Unexpected response 0x%02x, 0x%02x\n",
progname, status[0], status[1]);
}
data += this_len;
@@ -596,36 +596,36 @@ static int jtag3_edbg_signoff(PROGRAMMER * pgm)
buf[1] = CMSISDAP_LED_CONNECT;
buf[2] = 0;
if (serial_send(&pgm->fd, buf, pgm->fd.usb.max_xfer) != 0) {
avrdude_message(MSG_INFO, "%s: jtag3_edbg_signoff(): failed to send command to serial port\n",
avrdude_message(MSG_NOTICE, "%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) {
avrdude_message(MSG_INFO, "%s: jtag3_edbg_signoff(): failed to read from serial port (%d)\n",
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_signoff(): failed to read from serial port (%d)\n",
progname, rv);
return -1;
}
if (status[0] != CMSISDAP_CMD_LED ||
status[1] != 0)
avrdude_message(MSG_INFO, "%s: jtag3_edbg_signoff(): unexpected response 0x%02x, 0x%02x\n",
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_signoff(): unexpected response 0x%02x, 0x%02x\n",
progname, status[0], status[1]);
buf[0] = CMSISDAP_CMD_DISCONNECT;
if (serial_send(&pgm->fd, buf, pgm->fd.usb.max_xfer) != 0) {
avrdude_message(MSG_INFO, "%s: jtag3_edbg_signoff(): failed to send command to serial port\n",
avrdude_message(MSG_NOTICE, "%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) {
avrdude_message(MSG_INFO, "%s: jtag3_edbg_signoff(): failed to read from serial port (%d)\n",
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_signoff(): failed to read from serial port (%d)\n",
progname, rv);
return -1;
}
if (status[0] != CMSISDAP_CMD_DISCONNECT ||
status[1] != 0)
avrdude_message(MSG_INFO, "%s: jtag3_edbg_signoff(): unexpected response 0x%02x, 0x%02x\n",
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_signoff(): unexpected response 0x%02x, 0x%02x\n",
progname, status[0], status[1]);
return 0;
@@ -686,12 +686,12 @@ static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
avrdude_message(MSG_TRACE, "%s: jtag3_edbg_recv():\n", progname);
if ((buf = malloc(USBDEV_MAX_XFER_3)) == NULL) {
avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): out of memory\n",
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_recv(): out of memory\n",
progname);
return -1;
}
if ((request = malloc(pgm->fd.usb.max_xfer)) == NULL) {
avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): out of memory\n",
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_recv(): out of memory\n",
progname);
free(buf);
return -1;
@@ -706,7 +706,7 @@ static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
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",
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_recv(): error sending CMSIS-DAP vendor command\n",
progname);
free(request);
free(*msg);
@@ -725,7 +725,7 @@ static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
}
if (buf[0] != EDBG_VENDOR_AVR_RSP) {
avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): Unexpected response 0x%02x\n",
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_recv(): Unexpected response 0x%02x\n",
progname, buf[0]);
free(*msg);
free(request);
@@ -736,7 +736,7 @@ static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
// Documentation says:
// "FragmentInfo 0x00 indicates that no response data is
// available, and the rest of the packet is ignored."
avrdude_message(MSG_INFO,
avrdude_message(MSG_NOTICE,
"%s: jtag3_edbg_recv(): "
"No response available\n",
progname);
@@ -752,7 +752,7 @@ static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
thisfrag = 1;
} else {
if (nfrags != (buf[1] & 0x0F)) {
avrdude_message(MSG_INFO,
avrdude_message(MSG_NOTICE,
"%s: jtag3_edbg_recv(): "
"Inconsistent # of fragments; had %d, now %d\n",
progname, nfrags, (buf[1] & 0x0F));
@@ -762,7 +762,7 @@ static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
}
}
if (thisfrag != ((buf[1] >> 4) & 0x0F)) {
avrdude_message(MSG_INFO,
avrdude_message(MSG_NOTICE,
"%s: jtag3_edbg_recv(): "
"Inconsistent fragment number; expect %d, got %d\n",
progname, thisfrag, ((buf[1] >> 4) & 0x0F));
@@ -773,12 +773,12 @@ static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
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",
avrdude_message(MSG_NOTICE, "%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",
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_recv(): Length exceeds max size (%d > %d)\n",
progname, len + thislen, USBDEV_MAX_XFER_3);
thislen = USBDEV_MAX_XFER_3 - len;
}
@@ -865,7 +865,7 @@ int jtag3_recv(PROGRAMMER * pgm, unsigned char **msg) {
"%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",
avrdude_message(MSG_NOTICE, "%s: bad response to %s command: 0x%02x\n",
progname, descr, c);
}
status = (*resp)[3];
@@ -1129,7 +1129,7 @@ static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
if (PDATA(pgm)->set_sck(pgm, parm) < 0)
return -1;
}
jtag3_print_parms1(pgm, progbuf);
if (conn == PARM3_CONN_JTAG)
{
avrdude_message(MSG_NOTICE2, "%s: jtag3_initialize(): "
@@ -1174,7 +1174,8 @@ static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
u32_to_b4(xd.nvm_fuse_offset, m->offset & ~7);
} else if (matches(m->desc, "lock")) {
u32_to_b4(xd.nvm_lock_offset, m->offset);
} else if (strcmp(m->desc, "usersig") == 0) {
} else if (strcmp(m->desc, "usersig") == 0 ||
strcmp(m->desc, "userrow") == 0) {
u32_to_b4(xd.nvm_user_sig_offset, m->offset);
} else if (strcmp(m->desc, "prodsig") == 0) {
u32_to_b4(xd.nvm_prod_sig_offset, m->offset);
@@ -1225,7 +1226,8 @@ static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
u16_to_b2(xd.eeprom_bytes, m->size);
u16_to_b2(xd.eeprom_base, m->offset);
}
else if (strcmp(m->desc, "usersig") == 0)
else if (strcmp(m->desc, "usersig") == 0 ||
strcmp(m->desc, "userrow") == 0)
{
u16_to_b2(xd.user_sig_bytes, m->size);
u16_to_b2(xd.user_sig_base, m->offset);
@@ -1265,7 +1267,7 @@ static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
"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->ocd=%x %x\n\t"
"xd->address_mode=%x\n",
xd.prog_base_msb,
xd.prog_base[0], xd.prog_base[1],
@@ -1351,11 +1353,12 @@ static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
if ((status = jtag3_command(pgm, cmd, 4, &resp, "AVR sign-on")) >= 0)
break;
avrdude_message(MSG_INFO, "%s: retrying with external reset applied\n",
avrdude_message(MSG_NOTICE, "%s: retrying with external reset applied\n",
progname);
}
if (use_ext_reset > 1) {
if(strcmp(pgm->type, "JTAGICE3") == 0 && p->flags & AVRPART_HAS_JTAG)
avrdude_message(MSG_INFO, "%s: JTAGEN fuse disabled?\n", progname);
return -1;
}
@@ -1685,9 +1688,10 @@ static int jtag3_page_erase(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
cmd[3] = XMEGA_ERASE_BOOT_PAGE;
} else if (strcmp(m->desc, "eeprom") == 0) {
cmd[3] = XMEGA_ERASE_EEPROM_PAGE;
} else if ( ( strcmp(m->desc, "usersig") == 0 ) ) {
} else if (strcmp(m->desc, "usersig") == 0 ||
strcmp(m->desc, "userrow") == 0) {
cmd[3] = XMEGA_ERASE_USERSIG;
} else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
} else if (strcmp(m->desc, "boot") == 0) {
cmd[3] = XMEGA_ERASE_BOOT_PAGE;
} else {
cmd[3] = XMEGA_ERASE_APP_PAGE;
@@ -1759,9 +1763,10 @@ static int jtag3_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
}
cmd[3] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_EEPROM_XMEGA : MTYPE_EEPROM_PAGE;
PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
} else if ( ( strcmp(m->desc, "usersig") == 0 ) ) {
} else if (strcmp(m->desc, "usersig") == 0 ||
strcmp(m->desc, "userrow") == 0) {
cmd[3] = MTYPE_USERSIG;
} else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
} else if (strcmp(m->desc, "boot") == 0) {
cmd[3] = MTYPE_BOOT_FLASH;
} else if ( p->flags & AVRPART_HAS_PDI || p->flags & AVRPART_HAS_UPDI ) {
cmd[3] = MTYPE_FLASH;
@@ -1848,11 +1853,12 @@ static int jtag3_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
cmd[3] = ( p->flags & AVRPART_HAS_PDI || p->flags & AVRPART_HAS_UPDI ) ? MTYPE_EEPROM : MTYPE_EEPROM_PAGE;
if (pgm->flag & PGM_FL_IS_DW)
return -1;
} else if ( ( strcmp(m->desc, "prodsig") == 0 ) ) {
} else if (strcmp(m->desc, "prodsig") == 0) {
cmd[3] = MTYPE_PRODSIG;
} else if ( ( strcmp(m->desc, "usersig") == 0 ) ) {
} else if (strcmp(m->desc, "usersig") == 0 ||
strcmp(m->desc, "userrow") == 0) {
cmd[3] = MTYPE_USERSIG;
} else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
} else if (strcmp(m->desc, "boot") == 0) {
cmd[3] = MTYPE_BOOT_FLASH;
} else if ( p->flags & AVRPART_HAS_PDI ) {
cmd[3] = MTYPE_FLASH;
@@ -1964,10 +1970,23 @@ static int jtag3_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
cmd[3] = MTYPE_FUSE_BITS;
if (!(p->flags & AVRPART_HAS_UPDI))
addr = mem->offset & 7;
} else if (strcmp(mem->desc, "usersig") == 0) {
} else if (strcmp(mem->desc, "usersig") == 0 ||
strcmp(mem->desc, "userrow") == 0) {
cmd[3] = MTYPE_USERSIG;
} else if (strcmp(mem->desc, "prodsig") == 0) {
cmd[3] = MTYPE_PRODSIG;
} else if (strcmp(mem->desc, "sernum") == 0) {
cmd[3] = MTYPE_SIGN_JTAG;
} else if (strcmp(mem->desc, "osccal16") == 0) {
cmd[3] = MTYPE_SIGN_JTAG;
} else if (strcmp(mem->desc, "osccal20") == 0) {
cmd[3] = MTYPE_SIGN_JTAG;
} else if (strcmp(mem->desc, "tempsense") == 0) {
cmd[3] = MTYPE_SIGN_JTAG;
} else if (strcmp(mem->desc, "osc16err") == 0) {
cmd[3] = MTYPE_SIGN_JTAG;
} else if (strcmp(mem->desc, "osc20err") == 0) {
cmd[3] = MTYPE_SIGN_JTAG;
} else if (strcmp(mem->desc, "calibration") == 0) {
cmd[3] = MTYPE_OSCCAL_BYTE;
if (pgm->flag & PGM_FL_IS_DW)
@@ -2113,7 +2132,8 @@ static int jtag3_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
cmd[3] = MTYPE_FUSE_BITS;
if (!(p->flags & AVRPART_HAS_UPDI))
addr = mem->offset & 7;
} else if (strcmp(mem->desc, "usersig") == 0) {
} else if (strcmp(mem->desc, "usersig") == 0 ||
strcmp(mem->desc, "userrow") == 0) {
cmd[3] = MTYPE_USERSIG;
} else if (strcmp(mem->desc, "prodsig") == 0) {
cmd[3] = MTYPE_PRODSIG;
@@ -2228,7 +2248,7 @@ int jtag3_getparm(PROGRAMMER * pgm, unsigned char scope,
c = resp[1];
if (c != RSP3_DATA || status < 3) {
avrdude_message(MSG_INFO, "%s: jtag3_getparm(): "
avrdude_message(MSG_NOTICE, "%s: jtag3_getparm(): "
"bad response to %s\n",
progname, descr);
free(resp);
@@ -2313,9 +2333,8 @@ static int jtag3_set_vtarget(PROGRAMMER * pgm, double v)
utarg = (unsigned)(v * 1000);
if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_VTARGET, buf, 2) < 0) {
avrdude_message(MSG_INFO, "%s: jtag3_set_vtarget(): cannot obtain V[aref]\n",
avrdude_message(MSG_INFO, "%s: jtag3_set_vtarget(): cannot obtain V[target]\n",
progname);
return -1;
}
uaref = b2_to_u16(buf);
@@ -2324,8 +2343,11 @@ static int jtag3_set_vtarget(PROGRAMMER * pgm, double v)
avrdude_message(MSG_INFO, "%s: jtag3_set_vtarget(): changing V[target] from %.1f to %.1f\n",
progname, uaref / 1000.0, v);
if (jtag3_setparm(pgm, SCOPE_GENERAL, 1, PARM3_VADJUST, buf, sizeof(buf)) < 0)
if (jtag3_setparm(pgm, SCOPE_GENERAL, 1, PARM3_VADJUST, buf, sizeof(buf)) < 0) {
avrdude_message(MSG_INFO, "%s: jtag3_set_vtarget(): cannot confirm new V[target] value\n",
progname);
return -1;
}
return 0;
}
@@ -2364,14 +2386,12 @@ static void jtag3_display(PROGRAMMER * pgm, const char * p)
memmove(resp, resp + 3, status - 3);
resp[status - 3] = 0;
avrdude_message(MSG_INFO, "%sICE hardware version: %d\n", p, parms[0]);
avrdude_message(MSG_INFO, "%sICE firmware version: %d.%02d (rel. %d)\n", p,
avrdude_message(MSG_INFO, "%sICE HW version : %d\n", p, parms[0]);
avrdude_message(MSG_INFO, "%sICE FW version : %d.%02d (rel. %d)\n", p,
parms[1], parms[2],
(parms[3] | (parms[4] << 8)));
avrdude_message(MSG_INFO, "%sSerial number : %s\n", p, resp);
avrdude_message(MSG_INFO, "%sSerial number : %s", p, resp);
free(resp);
jtag3_print_parms1(pgm, p);
}
@@ -2382,29 +2402,41 @@ static void jtag3_print_parms1(PROGRAMMER * pgm, const char * p)
if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_VTARGET, buf, 2) < 0)
return;
avrdude_message(MSG_INFO, "%sVtarget : %.2f V\n", p,
b2_to_u16(buf) / 1000.0);
avrdude_message(MSG_INFO, "%sVtarget %s: %.2f V\n", p,
verbose ? "" : " ", b2_to_u16(buf) / 1000.0);
if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_MEGA_PROG, buf, 2) < 0)
return;
if (b2_to_u16(buf) > 0) {
avrdude_message(MSG_INFO, "%sJTAG clock megaAVR/program : %u kHz\n", p,
b2_to_u16(buf));
}
if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_MEGA_DEBUG, buf, 2) < 0)
return;
if (b2_to_u16(buf) > 0) {
avrdude_message(MSG_INFO, "%sJTAG clock megaAVR/debug : %u kHz\n", p,
b2_to_u16(buf));
}
if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_XMEGA_JTAG, buf, 2) < 0)
return;
if (b2_to_u16(buf) > 0) {
avrdude_message(MSG_INFO, "%sJTAG clock Xmega : %u kHz\n", p,
b2_to_u16(buf));
}
if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_XMEGA_PDI, buf, 2) < 0)
return;
avrdude_message(MSG_INFO, "%sPDI clock Xmega : %u kHz\n", p,
if (b2_to_u16(buf) > 0) {
avrdude_message(MSG_INFO, "%sPDI/UPDI clock Xmega/megaAVR : %u kHz\n\n", p,
b2_to_u16(buf));
}
}
static void jtag3_print_parms(PROGRAMMER * pgm)
{
@@ -2440,13 +2472,13 @@ 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;
if (strcmp(m->desc, "flash") == 0) {
return addr;
}
else if (matches(m->desc, "fuse")) {
else if (m->size == 1) {
addr = m->offset;
}
else if (strcmp(m->desc, "flash") != 0) {
else if (m->size > 1) {
addr += m->offset;
}
}

View File

@@ -1275,8 +1275,8 @@ static void jtagmkI_display(PROGRAMMER * pgm, const char * p)
jtagmkI_getparm(pgm, PARM_SW_VERSION, &fw) < 0)
return;
avrdude_message(MSG_INFO, "%sICE hardware version: 0x%02x\n", p, hw);
avrdude_message(MSG_INFO, "%sICE firmware version: 0x%02x\n", p, fw);
avrdude_message(MSG_INFO, "%sICE HW version: 0x%02x\n", p, hw);
avrdude_message(MSG_INFO, "%sICE FW version: 0x%02x\n", p, fw);
jtagmkI_print_parms1(pgm, p);

View File

@@ -1056,7 +1056,8 @@ static void jtagmkII_set_xmega_params(PROGRAMMER * pgm, AVRPART * p)
u32_to_b4(sendbuf.dd.nvm_fuse_offset, m->offset & ~7);
} else if (strncmp(m->desc, "lock", 4) == 0) {
u32_to_b4(sendbuf.dd.nvm_lock_offset, m->offset);
} else if (strcmp(m->desc, "usersig") == 0) {
} else if (strcmp(m->desc, "usersig") == 0 ||
strcmp(m->desc, "userrow") == 0) {
u32_to_b4(sendbuf.dd.nvm_user_sig_offset, m->offset);
} else if (strcmp(m->desc, "prodsig") == 0) {
u32_to_b4(sendbuf.dd.nvm_prod_sig_offset, m->offset);
@@ -1933,9 +1934,10 @@ static int jtagmkII_page_erase(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
cmd[1] = XMEGA_ERASE_BOOT_PAGE;
} else if (strcmp(m->desc, "eeprom") == 0) {
cmd[1] = XMEGA_ERASE_EEPROM_PAGE;
} else if ( ( strcmp(m->desc, "usersig") == 0 ) ) {
} else if (strcmp(m->desc, "usersig") == 0 ||
strcmp(m->desc, "userrow") == 0) {
cmd[1] = XMEGA_ERASE_USERSIG;
} else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
} else if (strcmp(m->desc, "boot") == 0) {
cmd[1] = XMEGA_ERASE_BOOT_PAGE;
} else {
cmd[1] = XMEGA_ERASE_APP_PAGE;
@@ -2046,9 +2048,10 @@ static int jtagmkII_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
}
cmd[1] = (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI)) ? MTYPE_EEPROM : MTYPE_EEPROM_PAGE;
PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
} else if ( ( strcmp(m->desc, "usersig") == 0 ) ) {
} else if (strcmp(m->desc, "usersig") == 0 ||
strcmp(m->desc, "userrow") == 0) {
cmd[1] = MTYPE_USERSIG;
} else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
} else if (strcmp(m->desc, "boot") == 0) {
cmd[1] = MTYPE_BOOT_FLASH;
} else if (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI)) {
cmd[1] = MTYPE_FLASH;
@@ -2159,11 +2162,12 @@ static int jtagmkII_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
cmd[1] = (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI)) ? MTYPE_EEPROM : MTYPE_EEPROM_PAGE;
if (pgm->flag & PGM_FL_IS_DW)
return -1;
} else if ( ( strcmp(m->desc, "prodsig") == 0 ) ) {
} else if (strcmp(m->desc, "prodsig") == 0) {
cmd[1] = MTYPE_PRODSIG;
} else if ( ( strcmp(m->desc, "usersig") == 0 ) ) {
} else if (strcmp(m->desc, "usersig") == 0 ||
strcmp(m->desc, "userrow") == 0) {
cmd[1] = MTYPE_USERSIG;
} else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
} else if (strcmp(m->desc, "boot") == 0) {
cmd[1] = MTYPE_BOOT_FLASH;
} else if (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI)) {
cmd[1] = MTYPE_FLASH;
@@ -2291,7 +2295,8 @@ static int jtagmkII_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsupp = 1;
} else if (strncmp(mem->desc, "fuse", strlen("fuse")) == 0) {
cmd[1] = MTYPE_FUSE_BITS;
} else if (strcmp(mem->desc, "usersig") == 0) {
} else if (strcmp(mem->desc, "usersig") == 0 ||
strcmp(mem->desc, "userrow") == 0) {
cmd[1] = MTYPE_USERSIG;
} else if (strcmp(mem->desc, "prodsig") == 0) {
cmd[1] = MTYPE_PRODSIG;
@@ -2460,7 +2465,8 @@ static int jtagmkII_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsupp = 1;
} else if (strncmp(mem->desc, "fuse", strlen("fuse")) == 0) {
cmd[1] = MTYPE_FUSE_BITS;
} else if (strcmp(mem->desc, "usersig") == 0) {
} else if (strcmp(mem->desc, "usersig") == 0 ||
strcmp(mem->desc, "userrow") == 0) {
cmd[1] = MTYPE_USERSIG;
} else if (strcmp(mem->desc, "prodsig") == 0) {
cmd[1] = MTYPE_PRODSIG;
@@ -2688,10 +2694,10 @@ static void jtagmkII_display(PROGRAMMER * pgm, const char * p)
jtagmkII_getparm(pgm, PAR_FW_VERSION, fw) < 0)
return;
avrdude_message(MSG_INFO, "%sM_MCU hardware version: %d\n", p, hw[0]);
avrdude_message(MSG_INFO, "%sM_MCU firmware version: %d.%02d\n", p, fw[1], fw[0]);
avrdude_message(MSG_INFO, "%sS_MCU hardware version: %d\n", p, hw[1]);
avrdude_message(MSG_INFO, "%sS_MCU firmware version: %d.%02d\n", p, fw[3], fw[2]);
avrdude_message(MSG_INFO, "%sM_MCU HW version: %d\n", p, hw[0]);
avrdude_message(MSG_INFO, "%sM_MCU FW version: %d.%02d\n", p, fw[1], fw[0]);
avrdude_message(MSG_INFO, "%sS_MCU HW version: %d\n", p, hw[1]);
avrdude_message(MSG_INFO, "%sS_MCU FW version: %d.%02d\n", p, fw[3], fw[2]);
avrdude_message(MSG_INFO, "%sSerial number : %02x:%02x:%02x:%02x:%02x:%02x\n",
p, PDATA(pgm)->serno[0], PDATA(pgm)->serno[1], PDATA(pgm)->serno[2], PDATA(pgm)->serno[3], PDATA(pgm)->serno[4], PDATA(pgm)->serno[5]);

View File

@@ -117,6 +117,7 @@ SIGN [+-]
<strng>\n { yyerror("unterminated character constant");
return YYERRCODE; }
alias { yylval=NULL; return K_ALIAS; }
allowfullpagebitstream { yylval=NULL; return K_ALLOWFULLPAGEBITSTREAM; }
avr910_devcode { yylval=NULL; return K_AVR910_DEVCODE; }
bank_size { yylval=NULL; return K_PAGE_SIZE; }
@@ -137,7 +138,6 @@ dedicated { yylval=new_token(K_DEDICATED); return K_DEDICATED; }
default_bitclock { yylval=NULL; return K_DEFAULT_BITCLOCK; }
default_parallel { yylval=NULL; return K_DEFAULT_PARALLEL; }
default_programmer { yylval=NULL; return K_DEFAULT_PROGRAMMER; }
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; }

View File

@@ -261,6 +261,7 @@ typedef struct avrpart {
OPCODE * op[AVR_OP_MAX]; /* opcodes */
LISTID mem; /* avr memory definitions */
LISTID mem_alias; /* memory alias definitions */
char config_file[PATH_MAX]; /* config file where defined */
int lineno; /* config file line number */
} AVRPART;
@@ -292,6 +293,11 @@ typedef struct avrmem {
OPCODE * op[AVR_OP_MAX]; /* opcodes */
} AVRMEM;
typedef struct avrmem_alias {
char desc[AVR_MEMDESCLEN]; /* alias name ("syscfg0" etc.) */
AVRMEM *aliased_mem;
} AVRMEM_ALIAS;
#ifdef __cplusplus
extern "C" {
#endif
@@ -307,10 +313,15 @@ int avr_get_output_index(OPCODE * op);
/* Functions for AVRMEM structures */
AVRMEM * avr_new_memtype(void);
AVRMEM_ALIAS * avr_new_memalias(void);
int avr_initmem(AVRPART * p);
AVRMEM * avr_dup_mem(AVRMEM * m);
void avr_free_mem(AVRMEM * m);
void avr_free_memalias(AVRMEM_ALIAS * m);
AVRMEM * avr_locate_mem(AVRPART * p, char * desc);
AVRMEM * avr_locate_mem_noalias(AVRPART * p, char * desc);
AVRMEM_ALIAS * avr_locate_memalias(AVRPART * p, char * desc);
AVRMEM_ALIAS * avr_find_memalias(AVRPART * p, AVRMEM * m_orig);
void avr_mem_display(const char * prefix, FILE * f, AVRMEM * m, AVRPART * p,
int type, int verbose);
@@ -831,30 +842,6 @@ int fileio(int op, char * filename, FILEFMT format,
#endif
/* formerly safemode.h */
#ifdef __cplusplus
extern "C" {
#endif
/* Writes the specified fuse in fusename (can be "lfuse", "hfuse", or "efuse") and verifies it. Will try up to tries
amount of times before giving up */
int safemode_writefuse (unsigned char fuse, char * fusename, PROGRAMMER * pgm, AVRPART * p, int tries);
/* Reads the fuses three times, checking that all readings are the same. This will ensure that the before values aren't in error! */
int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse, unsigned char * efuse, unsigned char * fuse, PROGRAMMER * pgm, AVRPART * p);
/* This routine will store the current values pointed to by lfuse, hfuse, and efuse into an internal buffer in this routine
when save is set to 1. When save is 0 (or not 1 really) it will copy the values from the internal buffer into the locations
pointed to be lfuse, hfuse, and efuse. This allows you to change the fuse bits if needed from another routine (ie: have it so
if user requests fuse bits are changed, the requested value is now verified */
int safemode_memfuses (int save, unsigned char * lfuse, unsigned char * hfuse, unsigned char * efuse, unsigned char * fuse);
#ifdef __cplusplus
}
#endif
/* formerly update.h */
enum {
@@ -926,7 +913,6 @@ extern char default_programmer[];
extern char default_parallel[];
extern char default_serial[];
extern double default_bitclock;
extern int default_safemode;
/* This name is fixed, it's only here for symmetry with
* default_parallel and default_serial. */

View File

@@ -223,7 +223,7 @@ static int linuxspi_open(PROGRAMMER *pgm, char *port)
avrdude_message(MSG_INFO,
"%s: obsolete use of -b <clock> option for bit clock; use -B <clock>\n",
progname);
pgm->bitclock = 1E6 / pgm->baudrate;
pgm->bitclock = 1.0 / pgm->baudrate;
}
if (pgm->bitclock == 0) {
avrdude_message(MSG_NOTICE,

View File

@@ -122,9 +122,6 @@ static void usage(void)
" is performed in the order specified.\n"
" -n Do not write anything to the device.\n"
" -V Do not verify.\n"
" -u Disable safemode, default when running from a script.\n"
" -s Silent safemode operation, will not ask you if\n"
" fuses should be changed back.\n"
" -t Enter terminal mode.\n"
" -E <exitspec>[,<exitspec>] List programmer exit specifications.\n"
" -x <extended_param> Pass <extended_param> to programmer.\n"
@@ -349,19 +346,11 @@ int main(int argc, char * argv [])
int baudrate; /* override default programmer baud rate */
double bitclock; /* Specify programmer bit clock (JTAG ICE) */
int ispdelay; /* Specify the delay for ISP clock */
int safemode; /* Enable safemode, 1=safemode on, 0=normal */
int silentsafe; /* Don't ask about fuses, 1=silent, 0=normal */
int init_ok; /* Device initialization worked well */
int is_open; /* Device open succeeded */
char * logfile; /* Use logfile rather than stderr for diagnostics */
enum updateflags uflags = UF_AUTO_ERASE; /* Flags for do_op() */
unsigned char safemode_lfuse = 0xff;
unsigned char safemode_hfuse = 0xff;
unsigned char safemode_efuse = 0xff;
unsigned char safemode_fuse = 0xff;
char * safemode_response;
int fuses_updated = 0;
#if !defined(WIN32)
char * homedir;
#endif
@@ -394,7 +383,6 @@ int main(int argc, char * argv [])
default_parallel[0] = 0;
default_serial[0] = 0;
default_bitclock = 0.0;
default_safemode = -1;
init_config();
@@ -434,8 +422,6 @@ int main(int argc, char * argv [])
baudrate = 0;
bitclock = 0.0;
ispdelay = 0;
safemode = 1; /* Safemode on by default */
silentsafe = 0; /* Ask by default */
is_open = 0;
logfile = NULL;
@@ -581,17 +567,13 @@ int main(int argc, char * argv [])
quell_progress++ ;
break;
case 's' : /* Silent safemode */
silentsafe = 1;
safemode = 1;
break;
case 't': /* enter terminal mode */
terminal = 1;
break;
case 'u' : /* Disable safemode */
safemode = 0;
case 'u':
avrdude_message(MSG_INFO, "%s: \"safemode\" feature no longer supported\n",
progname);
break;
case 'U':
@@ -975,29 +957,6 @@ int main(int argc, char * argv [])
}
}
if (default_safemode == 0) {
/* configuration disables safemode: revert meaning of -u */
if (safemode == 0)
/* -u was given: enable safemode */
safemode = 1;
else
/* -u not given: turn off */
safemode = 0;
}
if (isatty(STDIN_FILENO) == 0 && silentsafe == 0)
safemode = 0; /* Turn off safemode if this isn't a terminal */
if(p->flags & AVRPART_AVR32) {
safemode = 0;
}
if(p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_TPI)) {
safemode = 0;
}
if (avr_initmem(p) != 0)
{
avrdude_message(MSG_INFO, "\n%s: failed to initialize memories\n",
@@ -1281,36 +1240,6 @@ int main(int argc, char * argv [])
}
}
if (init_ok && safemode == 1) {
/* If safemode is enabled, go ahead and read the current low, high,
and extended fuse bytes as needed */
rc = safemode_readfuses(&safemode_lfuse, &safemode_hfuse,
&safemode_efuse, &safemode_fuse, pgm, p);
if (rc != 0) {
//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"
" Safemode disabled.\n", progname);
}
else
{
avrdude_message(MSG_INFO, "%s: safemode: To protect your AVR the programming "
"will be aborted\n",
progname);
exitrc = 1;
goto main_exit;
}
} else {
//Save the fuses as default
safemode_memfuses(1, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse);
}
}
if (uflags & UF_AUTO_ERASE) {
if ((p->flags & AVRPART_HAS_PDI) && pgm->page_erase != NULL &&
lsize(updates) > 0) {
@@ -1386,169 +1315,6 @@ int main(int argc, char * argv [])
}
}
/* Right before we exit programming mode, which will make the fuse
bits active, check to make sure they are still correct */
if (safemode == 1) {
/* If safemode is enabled, go ahead and read the current low,
* high, and extended fuse bytes as needed */
unsigned char safemodeafter_lfuse = 0xff;
unsigned char safemodeafter_hfuse = 0xff;
unsigned char safemodeafter_efuse = 0xff;
unsigned char safemodeafter_fuse = 0xff;
unsigned char failures = 0;
char yes[1] = {'y'};
if (quell_progress < 2) {
avrdude_message(MSG_INFO, "\n");
}
//Restore the default fuse values
safemode_memfuses(0, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse);
/* Try reading back fuses, make sure they are reliable to read back */
if (safemode_readfuses(&safemodeafter_lfuse, &safemodeafter_hfuse,
&safemodeafter_efuse, &safemodeafter_fuse, pgm, p) != 0) {
/* Uh-oh.. try once more to read back fuses */
if (safemode_readfuses(&safemodeafter_lfuse, &safemodeafter_hfuse,
&safemodeafter_efuse, &safemodeafter_fuse, pgm, p) != 0) {
avrdude_message(MSG_INFO, "%s: safemode: Sorry, reading back fuses was unreliable. "
"I have given up and exited programming mode\n",
progname);
exitrc = 1;
goto main_exit;
}
}
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)) {
fuses_updated = 1;
avrdude_message(MSG_INFO, "%s: safemode: fuse changed! Was %x, and is now %x\n",
progname, safemode_fuse, safemodeafter_fuse);
/* Ask user - should we change them */
if (silentsafe == 0)
safemode_response = terminal_get_input("Would you like this fuse to be changed back? [y/n] ");
else
safemode_response = yes;
if (tolower((int)(safemode_response[0])) == 'y') {
/* Enough chit-chat, time to program some fuses and check them */
if (safemode_writefuse (safemode_fuse, "fuse", pgm, p,
10) == 0) {
avrdude_message(MSG_INFO, "%s: safemode: and is now rescued\n", progname);
}
else {
avrdude_message(MSG_INFO, "%s: and COULD NOT be changed\n", progname);
failures++;
}
}
}
/* 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)) {
fuses_updated = 1;
avrdude_message(MSG_INFO, "%s: safemode: lfuse changed! Was %x, and is now %x\n",
progname, safemode_lfuse, safemodeafter_lfuse);
/* Ask user - should we change them */
if (silentsafe == 0)
safemode_response = terminal_get_input("Would you like this fuse to be changed back? [y/n] ");
else
safemode_response = yes;
if (tolower((int)(safemode_response[0])) == 'y') {
/* Enough chit-chat, time to program some fuses and check them */
if (safemode_writefuse (safemode_lfuse, "lfuse", pgm, p,
10) == 0) {
avrdude_message(MSG_INFO, "%s: safemode: and is now rescued\n", progname);
}
else {
avrdude_message(MSG_INFO, "%s: and COULD NOT be changed\n", progname);
failures++;
}
}
}
/* 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)) {
fuses_updated = 1;
avrdude_message(MSG_INFO, "%s: safemode: hfuse changed! Was %x, and is now %x\n",
progname, safemode_hfuse, safemodeafter_hfuse);
/* Ask user - should we change them */
if (silentsafe == 0)
safemode_response = terminal_get_input("Would you like this fuse to be changed back? [y/n] ");
else
safemode_response = yes;
if (tolower((int)(safemode_response[0])) == 'y') {
/* Enough chit-chat, time to program some fuses and check them */
if (safemode_writefuse(safemode_hfuse, "hfuse", pgm, p,
10) == 0) {
avrdude_message(MSG_INFO, "%s: safemode: and is now rescued\n", progname);
}
else {
avrdude_message(MSG_INFO, "%s: and COULD NOT be changed\n", progname);
failures++;
}
}
}
/* 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)) {
fuses_updated = 1;
avrdude_message(MSG_INFO, "%s: safemode: efuse changed! Was %x, and is now %x\n",
progname, safemode_efuse, safemodeafter_efuse);
/* Ask user - should we change them */
if (silentsafe == 0)
safemode_response = terminal_get_input("Would you like this fuse to be changed back? [y/n] ");
else
safemode_response = yes;
if (tolower((int)(safemode_response[0])) == 'y') {
/* Enough chit-chat, time to program some fuses and check them */
if (safemode_writefuse (safemode_efuse, "efuse", pgm, p,
10) == 0) {
avrdude_message(MSG_INFO, "%s: safemode: and is now rescued\n", progname);
}
else {
avrdude_message(MSG_INFO, "%s: and COULD NOT be changed\n", progname);
failures++;
}
}
}
if (quell_progress < 2) {
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);
}
else {
avrdude_message(MSG_INFO, "Fuses not recovered, sorry\n");
}
}
if (fuses_updated) {
exitrc = 1;
}
}
main_exit:
/*

View File

@@ -1,318 +0,0 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* avrdude is Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
*
* This file: Copyright (C) 2005-2007 Colin O'Flynn <coflynn@newae.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/>.
*/
#include <stdio.h>
#include "ac_cfg.h"
#include "avrdude.h"
#include "libavrdude.h"
/* This value from ac_cfg.h */
/*
* Writes the specified fuse in fusename (can be "lfuse", "hfuse", or
* "efuse") and verifies it. Will try up to tries amount of times
* before giving up
*/
int safemode_writefuse (unsigned char fuse, char * fusename, PROGRAMMER * pgm,
AVRPART * p, int tries)
{
AVRMEM * m;
unsigned char fuseread;
int returnvalue = -1;
m = avr_locate_mem(p, fusename);
if (m == NULL) {
return -1;
}
/* Keep trying to write then read back the fuse values */
while (tries > 0) {
if (avr_write_byte(pgm, p, m, 0, fuse) != 0)
{
continue;
}
if (pgm->read_byte(pgm, p, m, 0, &fuseread) != 0)
{
continue;
}
/* Report information to user if needed */
avrdude_message(MSG_NOTICE, "%s: safemode: Wrote %s to %x, read as %x. %d attempts left\n",
progname, fusename, fuse, fuseread, tries-1);
/* If fuse wrote OK, no need to keep going */
if (fuse == fuseread) {
tries = 0;
returnvalue = 0;
}
tries--;
}
return returnvalue;
}
/*
* Reads the fuses three times, checking that all readings are the
* same. This will ensure that the before values aren't in error!
*/
int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
unsigned char * efuse, unsigned char * fuse,
PROGRAMMER * pgm, AVRPART * p)
{
unsigned char value;
unsigned char fusegood = 0;
unsigned char allowfuseread = 1;
unsigned char safemode_lfuse;
unsigned char safemode_hfuse;
unsigned char safemode_efuse;
unsigned char safemode_fuse;
AVRMEM * m;
safemode_lfuse = *lfuse;
safemode_hfuse = *hfuse;
safemode_efuse = *efuse;
safemode_fuse = *fuse;
/* Read fuse three times */
fusegood = 2; /* If AVR device doesn't support this fuse, don't want
to generate a verify error */
m = avr_locate_mem(p, "fuse");
if (m != NULL) {
fusegood = 0; /* By default fuse is a failure */
if(pgm->read_byte(pgm, p, m, 0, &safemode_fuse) != 0)
{
allowfuseread = 0;
}
avrdude_message(MSG_DEBUG, "%s: safemode read 1, fuse value: %x\n",progname, safemode_fuse);
if(pgm->read_byte(pgm, p, m, 0, &value) != 0)
{
allowfuseread = 0;
}
avrdude_message(MSG_DEBUG, "%s: safemode read 2, fuse value: %x\n",progname, value);
if (value == safemode_fuse) {
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
{
allowfuseread = 0;
}
avrdude_message(MSG_DEBUG, "%s: safemode read 3, fuse value: %x\n",progname, value);
if (value == safemode_fuse)
{
fusegood = 1; /* Fuse read OK three times */
}
}
}
//Programmer does not allow fuse reading.... no point trying anymore
if (allowfuseread == 0)
{
return -5;
}
if (fusegood == 0) {
avrdude_message(MSG_INFO, "%s: safemode: Verify error - unable to read fuse properly. "
"Programmer may not be reliable.\n", progname);
return -1;
}
else if (fusegood == 1) {
avrdude_message(MSG_NOTICE, "%s: safemode: fuse reads as %X\n", progname, safemode_fuse);
}
/* Read lfuse three times */
fusegood = 2; /* If AVR device doesn't support this fuse, don't want
to generate a verify error */
m = avr_locate_mem(p, "lfuse");
if (m != NULL) {
fusegood = 0; /* By default fuse is a failure */
if (pgm->read_byte(pgm, p, m, 0, &safemode_lfuse) != 0)
{
allowfuseread = 0;
}
avrdude_message(MSG_DEBUG, "%s: safemode read 1, lfuse value: %x\n",progname, safemode_lfuse);
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
{
allowfuseread = 0;
}
avrdude_message(MSG_DEBUG, "%s: safemode read 2, lfuse value: %x\n",progname, value);
if (value == safemode_lfuse) {
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
{
allowfuseread = 0;
}
avrdude_message(MSG_DEBUG, "%s: safemode read 3, lfuse value: %x\n",progname, value);
if (value == safemode_lfuse){
fusegood = 1; /* Fuse read OK three times */
}
}
}
//Programmer does not allow fuse reading.... no point trying anymore
if (allowfuseread == 0)
{
return -5;
}
if (fusegood == 0) {
avrdude_message(MSG_INFO, "%s: safemode: Verify error - unable to read lfuse properly. "
"Programmer may not be reliable.\n", progname);
return -1;
}
else if (fusegood == 1) {
avrdude_message(MSG_NOTICE, "%s: safemode: lfuse reads as %X\n", progname, safemode_lfuse);
}
/* Read hfuse three times */
fusegood = 2; /* If AVR device doesn't support this fuse, don't want
to generate a verify error */
m = avr_locate_mem(p, "hfuse");
if (m != NULL) {
fusegood = 0; /* By default fuse is a failure */
if (pgm->read_byte(pgm, p, m, 0, &safemode_hfuse) != 0)
{
allowfuseread = 0;
}
avrdude_message(MSG_DEBUG, "%s: safemode read 1, hfuse value: %x\n",progname, safemode_hfuse);
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
{
allowfuseread = 0;
}
avrdude_message(MSG_DEBUG, "%s: safemode read 2, hfuse value: %x\n",progname, value);
if (value == safemode_hfuse) {
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
{
allowfuseread = 0;
}
avrdude_message(MSG_DEBUG, "%s: safemode read 3, hfuse value: %x\n",progname, value);
if (value == safemode_hfuse){
fusegood = 1; /* Fuse read OK three times */
}
}
}
//Programmer does not allow fuse reading.... no point trying anymore
if (allowfuseread == 0)
{
return -5;
}
if (fusegood == 0) {
avrdude_message(MSG_INFO, "%s: safemode: Verify error - unable to read hfuse properly. "
"Programmer may not be reliable.\n", progname);
return -2;
}
else if (fusegood == 1){
avrdude_message(MSG_NOTICE, "%s: safemode: hfuse reads as %X\n", progname, safemode_hfuse);
}
/* Read efuse three times */
fusegood = 2; /* If AVR device doesn't support this fuse, don't want
to generate a verify error */
m = avr_locate_mem(p, "efuse");
if (m != NULL) {
fusegood = 0; /* By default fuse is a failure */
if (pgm->read_byte(pgm, p, m, 0, &safemode_efuse) != 0)
{
allowfuseread = 0;
}
avrdude_message(MSG_DEBUG, "%s: safemode read 1, efuse value: %x\n",progname, safemode_efuse);
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
{
allowfuseread = 0;
}
avrdude_message(MSG_DEBUG, "%s: safemode read 2, efuse value: %x\n",progname, value);
if (value == safemode_efuse) {
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
{
allowfuseread = 0;
}
avrdude_message(MSG_DEBUG, "%s: safemode read 3, efuse value: %x\n",progname, value);
if (value == safemode_efuse){
fusegood = 1; /* Fuse read OK three times */
}
}
}
//Programmer does not allow fuse reading.... no point trying anymore
if (allowfuseread == 0)
{
return -5;
}
if (fusegood == 0) {
avrdude_message(MSG_INFO, "%s: safemode: Verify error - unable to read efuse properly. "
"Programmer may not be reliable.\n", progname);
return -3;
}
else if (fusegood == 1) {
avrdude_message(MSG_NOTICE, "%s: safemode: efuse reads as %X\n", progname, safemode_efuse);
}
*lfuse = safemode_lfuse;
*hfuse = safemode_hfuse;
*efuse = safemode_efuse;
*fuse = safemode_fuse;
return 0;
}
/*
* This routine will store the current values pointed to by lfuse,
* hfuse, and efuse into an internal buffer in this routine when save
* is set to 1. When save is 0 (or not 1 really) it will copy the
* values from the internal buffer into the locations pointed to be
* lfuse, hfuse, and efuse. This allows you to change the fuse bits if
* needed from another routine (ie: have it so if user requests fuse
* bits are changed, the requested value is now verified
*/
int safemode_memfuses (int save, unsigned char * lfuse, unsigned char * hfuse,
unsigned char * efuse, unsigned char * fuse)
{
static unsigned char safemode_lfuse = 0xff;
static unsigned char safemode_hfuse = 0xff;
static unsigned char safemode_efuse = 0xff;
static unsigned char safemode_fuse = 0xff;
switch (save) {
/* Save the fuses as safemode setting */
case 1:
safemode_lfuse = *lfuse;
safemode_hfuse = *hfuse;
safemode_efuse = *efuse;
safemode_fuse = *fuse;
break;
/* Read back the fuses */
default:
*lfuse = safemode_lfuse;
*hfuse = safemode_hfuse;
*efuse = safemode_efuse;
*fuse = safemode_fuse;
break;
}
return 0;
}

View File

@@ -26,11 +26,12 @@
#include "ac_cfg.h"
#if defined(HAVE_LIBHIDAPI) || (defined(WIN32) && defined(HAVE_LIBHID))
#if defined(HAVE_LIBHIDAPI)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <hidapi/hidapi.h>
#include "avrdude.h"
#include "libavrdude.h"
@@ -64,12 +65,6 @@ 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)
{
@@ -154,181 +149,6 @@ static int usbGetReport(union filedescriptor *fdp, int reportType, int reportNum
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
#else /* !defined(HAVE_LIBHIDAPI) */
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <setupapi.h>
#include <hidsdi.h>
#include <hidpi.h>
#ifdef USB_DEBUG
#define DEBUG_PRINT(arg) printf arg
#else
#define DEBUG_PRINT(arg)
#endif
/* ------------------------------------------------------------------------ */
static void convertUniToAscii(char *buffer)
{
unsigned short *uni = (void *)buffer;
char *ascii = buffer;
while(*uni != 0){
if(*uni >= 256){
*ascii++ = '?';
uni++;
}else{
*ascii++ = *uni++;
}
}
*ascii++ = 0;
}
static int usbOpenDevice(union filedescriptor *fdp, int vendor, char *vendorName,
int product, char *productName, int usesReportIDs)
{
GUID hidGuid; /* GUID for HID driver */
HDEVINFO deviceInfoList;
SP_DEVICE_INTERFACE_DATA deviceInfo;
SP_DEVICE_INTERFACE_DETAIL_DATA *deviceDetails = NULL;
DWORD size;
int i, openFlag = 0; /* may be FILE_FLAG_OVERLAPPED */
int errorCode = USB_ERROR_NOTFOUND;
HANDLE handle = INVALID_HANDLE_VALUE;
HIDD_ATTRIBUTES deviceAttributes;
HidD_GetHidGuid(&hidGuid);
deviceInfoList = SetupDiGetClassDevs(&hidGuid, NULL, NULL,
DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
deviceInfo.cbSize = sizeof(deviceInfo);
for(i=0;;i++){
if(handle != INVALID_HANDLE_VALUE){
CloseHandle(handle);
handle = INVALID_HANDLE_VALUE;
}
if(!SetupDiEnumDeviceInterfaces(deviceInfoList, 0, &hidGuid, i, &deviceInfo))
break; /* no more entries */
/* first do a dummy call just to determine the actual size required */
SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, NULL, 0, &size, NULL);
if(deviceDetails != NULL)
free(deviceDetails);
deviceDetails = malloc(size);
deviceDetails->cbSize = sizeof(*deviceDetails);
/* this call is for real: */
SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, deviceDetails,
size, &size, NULL);
DEBUG_PRINT(("checking HID path \"%s\"\n", deviceDetails->DevicePath));
/* attempt opening for R/W -- we don't care about devices which can't be accessed */
handle = CreateFile(deviceDetails->DevicePath, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
openFlag, NULL);
if(handle == INVALID_HANDLE_VALUE){
DEBUG_PRINT(("opening failed: %d\n", (int)GetLastError()));
/* errorCode = USB_ERROR_ACCESS; opening will always fail for mouse -- ignore */
continue;
}
deviceAttributes.Size = sizeof(deviceAttributes);
HidD_GetAttributes(handle, &deviceAttributes);
DEBUG_PRINT(("device attributes: vid=%d pid=%d\n",
deviceAttributes.VendorID, deviceAttributes.ProductID));
if(deviceAttributes.VendorID != vendor || deviceAttributes.ProductID != product)
continue; /* ignore this device */
errorCode = USB_ERROR_NOTFOUND;
if(vendorName != NULL && productName != NULL){
char buffer[512];
if(!HidD_GetManufacturerString(handle, buffer, sizeof(buffer))){
DEBUG_PRINT(("error obtaining vendor name\n"));
errorCode = USB_ERROR_IO;
continue;
}
convertUniToAscii(buffer);
DEBUG_PRINT(("vendorName = \"%s\"\n", buffer));
if(strcmp(vendorName, buffer) != 0)
continue;
if(!HidD_GetProductString(handle, buffer, sizeof(buffer))){
DEBUG_PRINT(("error obtaining product name\n"));
errorCode = USB_ERROR_IO;
continue;
}
convertUniToAscii(buffer);
DEBUG_PRINT(("productName = \"%s\"\n", buffer));
if(strcmp(productName, buffer) != 0)
continue;
}
break; /* we have found the device we are looking for! */
}
SetupDiDestroyDeviceInfoList(deviceInfoList);
if(deviceDetails != NULL)
free(deviceDetails);
if(handle != INVALID_HANDLE_VALUE){
fdp->pfd = (void *)handle;
errorCode = 0;
}
return errorCode;
}
/* ------------------------------------------------------------------------ */
static void usbCloseDevice(union filedescriptor *fdp)
{
CloseHandle((HANDLE)fdp->pfd);
}
/* ------------------------------------------------------------------------ */
static int usbSetReport(union filedescriptor *fdp, int reportType, char *buffer, int len)
{
HANDLE handle = (HANDLE)fdp->pfd;
BOOLEAN rval = 0;
DWORD bytesWritten;
switch(reportType){
case USB_HID_REPORT_TYPE_INPUT:
break;
case USB_HID_REPORT_TYPE_OUTPUT:
rval = WriteFile(handle, buffer, len, &bytesWritten, NULL);
break;
case USB_HID_REPORT_TYPE_FEATURE:
rval = HidD_SetFeature(handle, buffer, len);
break;
}
return rval == 0 ? USB_ERROR_IO : 0;
}
/* ------------------------------------------------------------------------ */
static int usbGetReport(union filedescriptor *fdp, int reportType, int reportNumber,
char *buffer, int *len)
{
HANDLE handle = (HANDLE)fdp->pfd;
BOOLEAN rval = 0;
DWORD bytesRead;
switch(reportType){
case USB_HID_REPORT_TYPE_INPUT:
buffer[0] = reportNumber;
rval = ReadFile(handle, buffer, *len, &bytesRead, NULL);
if(rval)
*len = bytesRead;
break;
case USB_HID_REPORT_TYPE_OUTPUT:
break;
case USB_HID_REPORT_TYPE_FEATURE:
buffer[0] = reportNumber;
rval = HidD_GetFeature(handle, buffer, *len);
break;
}
return rval == 0 ? USB_ERROR_IO : 0;
}
#endif /* WIN32 */
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
@@ -551,4 +371,4 @@ struct serial_device avrdoper_serdev =
.flags = SERDEV_FL_NONE,
};
#endif /* defined(HAVE_LIBHIDAPI) || (defined(WIN32) && defined(HAVE_LIBHID)) */
#endif /* defined(HAVE_LIBHIDAPI) */

View File

@@ -28,6 +28,7 @@
#include "ac_cfg.h"
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -42,6 +43,10 @@
#include <termios.h>
#include <unistd.h>
#ifdef __APPLE__
# include <IOKit/serial/ioss.h>
#endif
#include "avrdude.h"
#include "libavrdude.h"
@@ -78,10 +83,12 @@ static struct baud_mapping baud_lookup_table [] = {
static struct termios original_termios;
static int saved_original_termios;
static speed_t serial_baud_lookup(long baud)
static speed_t serial_baud_lookup(long baud, bool *nonstandard)
{
struct baud_mapping *map = baud_lookup_table;
*nonstandard = false;
while (map->baud) {
if (map->baud == baud)
return map->speed;
@@ -92,30 +99,20 @@ static speed_t serial_baud_lookup(long baud)
* If a non-standard BAUD rate is used, issue
* a warning (if we are verbose) and return the raw rate
*/
avrdude_message(MSG_NOTICE, "%s: serial_baud_lookup(): Using non-standard baud rate: %ld",
avrdude_message(MSG_NOTICE, "%s: serial_baud_lookup(): Using non-standard baud rate: %ld\n",
progname, baud);
return baud;
}
*nonstandard = true;
static tcflag_t translate_flags(unsigned long cflags)
{
return ((cflags & SERIAL_CS5) ? CS5 : 0) |
((cflags & SERIAL_CS6) ? CS6 : 0) |
((cflags & SERIAL_CS7) ? CS7 : 0) |
((cflags & SERIAL_CS8) ? CS8 : 0) |
((cflags & SERIAL_CSTOPB) ? CSTOPB : 0) |
((cflags & SERIAL_CREAD) ? CREAD : 0) |
((cflags & (SERIAL_PARENB | SERIAL_PARODD)) ? PARENB : 0) |
((cflags & SERIAL_PARODD) ? PARODD : 0) |
((cflags & SERIAL_CLOCAL) ? CLOCAL : 0) ;
return baud;
}
static int ser_setparams(union filedescriptor *fd, long baud, unsigned long cflags)
{
int rc;
struct termios termios;
speed_t speed = serial_baud_lookup (baud);
bool nonstandard;
speed_t speed = serial_baud_lookup (baud, &nonstandard);
if (!isatty(fd->ifd))
return -ENOTTY;
@@ -137,15 +134,86 @@ static int ser_setparams(union filedescriptor *fd, long baud, unsigned long cfla
original_termios = termios;
}
termios.c_iflag = IGNBRK;
termios.c_oflag = 0;
termios.c_lflag = 0;
termios.c_cflag = translate_flags(cflags);
termios.c_cc[VMIN] = 1;
termios.c_cc[VTIME] = 0;
if (cflags & SERIAL_CREAD) {
termios.c_cflag |= CREAD;
}
if (cflags & SERIAL_CLOCAL) {
termios.c_cflag |= CLOCAL;
}
termios.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | ISIG | IEXTEN);
#ifdef ECHOCTL
termios.c_lflag &= ~ECHOCTL;
#endif /* ECHOCTL */
#ifdef ECHOKE
termios.c_lflag &= ~ECHOKE;
#endif /* ECHOKE */
termios.c_oflag &= ~(OPOST | ONLCR | OCRNL);
termios.c_iflag &= ~(INLCR | IGNCR | ICRNL | IGNBRK);
#ifdef IUCLC
termios.c_iflag &= ~IUCLC;
#endif /* IUCLC */
#ifdef PARMRK
termios.c_iflag &= ~PARMRK;
#endif /* PARMRK */
// MacOS doesn't handle nonstandard baudrate values in
// normal tcsetattr(), sigh.
#ifdef __APPLE__
if (!nonstandard) {
#endif
cfsetospeed(&termios, speed);
cfsetispeed(&termios, speed);
#ifdef __APPLE__
}
#endif
termios.c_cflag &= ~CSIZE;
if (cflags & SERIAL_CS8) {
termios.c_cflag |= CS8;
}
if (cflags & SERIAL_CS7) {
termios.c_cflag |= CS7;
}
if (cflags & SERIAL_CS6) {
termios.c_cflag |= CS6;
}
if (cflags & SERIAL_CS5) {
termios.c_cflag |= CS5;
}
if (cflags & SERIAL_CSTOPB) {
termios.c_cflag |= CSTOPB;
} else {
termios.c_cflag &= ~CSTOPB;
}
termios.c_iflag &= ~(INPCK | ISTRIP);
if (cflags & (SERIAL_PARENB | SERIAL_PARODD)) {
termios.c_cflag |= PARENB;
} else {
termios.c_cflag &= ~PARENB;
}
if (cflags & SERIAL_PARODD) {
termios.c_cflag |= PARODD;
} else {
termios.c_cflag &= ~PARODD;
}
#ifdef IXANY
termios.c_iflag &= ~IXANY;
#endif /* IXANY */
termios.c_iflag &= ~(IXON | IXOFF);
#ifdef CRTSCTS
termios.c_iflag &= ~CRTSCTS;
#endif /* CRTSCTS */
#ifdef CNEW_RTSCTS
termios.c_iflag &= ~CNEW_RTSCTS;
#endif /* CRTSCTS */
rc = tcsetattr(fd->ifd, TCSANOW, &termios);
if (rc < 0) {
@@ -154,13 +222,18 @@ static int ser_setparams(union filedescriptor *fd, long baud, unsigned long cfla
return -errno;
}
/*
* Everything is now set up for a local line without modem control
* or flow control, so clear O_NONBLOCK again.
*/
rc = fcntl(fd->ifd, F_GETFL, 0);
if (rc != -1)
fcntl(fd->ifd, F_SETFL, rc & ~O_NONBLOCK);
#ifdef __APPLE__
// handle nonstandard speed values the MacOS way
if (nonstandard) {
if (ioctl(fd->ifd, IOSSIOSPEED, &speed) < 0) {
avrdude_message(MSG_INFO, "%s: ser_setparams(): ioctrl(IOSSIOSPEED) failed\n",
progname);
return -errno;
}
}
#endif // __APPLE__
tcflush(fd->ifd, TCIFLUSH);
return 0;
}
@@ -520,3 +593,4 @@ struct serial_device serial_serdev =
struct serial_device *serdev = &serial_serdev;
#endif /* WIN32 */

View File

@@ -1613,11 +1613,11 @@ static int stk500v2_open(PROGRAMMER * pgm, char * port)
PDATA(pgm)->pgmtype = PGMTYPE_UNKNOWN;
if(strcasecmp(port, "avrdoper") == 0){
#if defined(HAVE_LIBHIDAPI) || (defined(WIN32) && defined(HAVE_LIBHID))
#if defined(HAVE_LIBHIDAPI)
serdev = &avrdoper_serdev;
PDATA(pgm)->pgmtype = PGMTYPE_STK500;
#else
avrdude_message(MSG_INFO, "avrdoper requires avrdude with hid support.\n");
avrdude_message(MSG_INFO, "avrdoper requires avrdude with libhidapi support.\n");
return -1;
#endif
}
@@ -3869,7 +3869,8 @@ static int stk600_xprog_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
* fuses.
*/
need_erase = 1;
} else if (strcmp(mem->desc, "usersig") == 0) {
} else if (strcmp(mem->desc, "usersig") == 0 ||
strcmp(mem->desc, "userrow") == 0) {
memcode = XPRG_MEM_TYPE_USERSIG;
} else {
avrdude_message(MSG_INFO, "%s: stk600_xprog_write_byte(): unknown memory \"%s\"\n",
@@ -3944,7 +3945,8 @@ static int stk600_xprog_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
} else if (strcmp(mem->desc, "calibration") == 0 ||
strcmp(mem->desc, "prodsig") == 0) {
b[1] = XPRG_MEM_TYPE_FACTORY_CALIBRATION;
} else if (strcmp(mem->desc, "usersig") == 0) {
} else if (strcmp(mem->desc, "usersig") == 0 ||
strcmp(mem->desc, "userrow") == 0) {
b[1] = XPRG_MEM_TYPE_USERSIG;
} else {
avrdude_message(MSG_INFO, "%s: stk600_xprog_read_byte(): unknown memory \"%s\"\n",
@@ -4019,7 +4021,8 @@ static int stk600_xprog_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
} else if (strcmp(mem->desc, "calibration") == 0 ||
strcmp(mem->desc, "prodsig") == 0) {
memtype = XPRG_MEM_TYPE_FACTORY_CALIBRATION;
} else if (strcmp(mem->desc, "usersig") == 0) {
} else if (strcmp(mem->desc, "usersig") == 0 ||
strcmp(mem->desc, "userrow") == 0) {
memtype = XPRG_MEM_TYPE_USERSIG;
} else {
avrdude_message(MSG_INFO, "%s: stk600_xprog_paged_load(): unknown paged memory \"%s\"\n",
@@ -4132,7 +4135,8 @@ static int stk600_xprog_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
} else if (strcmp(mem->desc, "calibration") == 0) {
memtype = XPRG_MEM_TYPE_FACTORY_CALIBRATION;
writemode = (1 << XPRG_MEM_WRITE_WRITE);
} else if (strcmp(mem->desc, "usersig") == 0) {
} else if (strcmp(mem->desc, "usersig") == 0 ||
strcmp(mem->desc, "userrow") == 0) {
memtype = XPRG_MEM_TYPE_USERSIG;
writemode = (1 << XPRG_MEM_WRITE_WRITE);
} else {
@@ -4290,7 +4294,8 @@ static int stk600_xprog_page_erase(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
b[1] = XPRG_ERASE_BOOT_PAGE;
} else if (strcmp(m->desc, "eeprom") == 0) {
b[1] = XPRG_ERASE_EEPROM_PAGE;
} else if (strcmp(m->desc, "usersig") == 0) {
} else if (strcmp(m->desc, "usersig") == 0 ||
strcmp(m->desc, "userrow") == 0) {
b[1] = XPRG_ERASE_USERSIG;
} else {
avrdude_message(MSG_INFO, "%s: stk600_xprog_page_erase(): unknown paged memory \"%s\"\n",

View File

@@ -23,6 +23,7 @@
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <limits.h>
@@ -97,8 +98,8 @@ struct command cmd[] = {
{ "sig", cmd_sig, "display device signature bytes" },
{ "part", cmd_part, "display the current part information" },
{ "send", cmd_send, "send a raw command : %s <b1> <b2> <b3> <b4>" },
{ "parms", cmd_parms, "display adjustable parameters (STK500 only)" },
{ "vtarg", cmd_vtarg, "set <V[target]> (STK500 only)" },
{ "parms", cmd_parms, "display adjustable parameters (STK500 and Curiosity Nano only)" },
{ "vtarg", cmd_vtarg, "set <V[target]> (STK500 and Curiosity Nano only)" },
{ "varef", cmd_varef, "set <V[aref]> (STK500 only)" },
{ "fosc", cmd_fosc, "set <oscillator frequency> (STK500 only)" },
{ "sck", cmd_sck, "set <SCK period> (STK500 only)" },
@@ -125,9 +126,15 @@ static int nexttok(char * buf, char ** tok, char ** next)
q++;
/* isolate first token */
n = q+1;
while (*n && !isspace((int)*n))
n = q;
uint8_t quotes = 0;
while (*n && (!isspace((int)*n) || quotes)) {
if (*n == '\"')
quotes++;
else if (isspace((int)*n) && *(n-1) == '\"')
break;
n++;
}
if (*n) {
*n = 0;
@@ -148,12 +155,10 @@ static int nexttok(char * buf, char ** tok, char ** next)
static int hexdump_line(char * buffer, unsigned char * p, int n, int pad)
{
char * hexdata = "0123456789abcdef";
char * b;
int i, j;
char * b = buffer;
int32_t i = 0;
int32_t j = 0;
b = buffer;
j = 0;
for (i=0; i<n; i++) {
if (i && ((i % 8) == 0))
b[j++] = ' ';
@@ -182,7 +187,7 @@ static int chardump_line(char * buffer, unsigned char * p, int n, int pad)
int i;
char b [ 128 ];
for (i=0; i<n; i++) {
for (int32_t i = 0; i < n; i++) {
memcpy(b, p, n);
buffer[i] = '.';
if (isalpha((int)(b[i])) || isdigit((int)(b[i])) || ispunct((int)(b[i])))
@@ -202,16 +207,13 @@ static int chardump_line(char * buffer, unsigned char * p, int n, int pad)
static int hexdump_buf(FILE * f, int startaddr, unsigned char * buf, int len)
{
int addr;
int n;
unsigned char * p;
char dst1[80];
char dst2[80];
addr = startaddr;
p = (unsigned char *)buf;
int32_t addr = startaddr;
unsigned char * p = (unsigned char *)buf;
while (len) {
n = 16;
int32_t n = 16;
if (n > len)
n = len;
hexdump_line(dst1, p, n, 48);
@@ -229,80 +231,86 @@ static int hexdump_buf(FILE * f, int startaddr, unsigned char * buf, int len)
static int cmd_dump(PROGRAMMER * pgm, struct avrpart * p,
int argc, char * argv[])
{
static char prevmem[128] = {0};
char * e;
unsigned char * buf;
int maxsize;
unsigned long i;
static unsigned long addr=0;
static int len=64;
AVRMEM * mem;
char * memtype = NULL;
int rc;
if (!((argc == 2) || (argc == 4))) {
avrdude_message(MSG_INFO, "Usage: dump <memtype> [<addr> <len>]\n");
if (argc < 2) {
avrdude_message(MSG_INFO, "Usage: %s <memtype> [<start addr> <len>]\n"
" %s <memtype> [<start addr> <...>]\n"
" %s <memtype> <...>\n"
" %s <memtype>\n",
argv[0], argv[0], argv[0], argv[0]);
return -1;
}
memtype = argv[1];
if (strncmp(prevmem, memtype, strlen(memtype)) != 0) {
addr = 0;
len = 64;
strncpy(prevmem, memtype, sizeof(prevmem)-1);
prevmem[sizeof(prevmem)-1] = 0;
}
mem = avr_locate_mem(p, memtype);
enum { read_size = 256 };
static char prevmem[128] = {0x00};
char * memtype = argv[1];
AVRMEM * mem = avr_locate_mem(p, memtype);
if (mem == NULL) {
avrdude_message(MSG_INFO, "\"%s\" memory type not defined for part \"%s\"\n",
memtype, p->desc);
return -1;
}
uint32_t maxsize = mem->size;
// Get start address if present
char * end_ptr;
static uint32_t addr = 0;
if (argc == 4) {
addr = strtoul(argv[2], &e, 0);
if (*e || (e == argv[2])) {
avrdude_message(MSG_INFO, "%s (dump): can't parse address \"%s\"\n",
progname, argv[2]);
addr = strtoul(argv[2], &end_ptr, 0);
if (*end_ptr || (end_ptr == argv[2])) {
avrdude_message(MSG_INFO, "%s (%s): can't parse address \"%s\"\n",
progname, argv[0], argv[2]);
return -1;
}
len = strtol(argv[3], &e, 0);
if (*e || (e == argv[3])) {
avrdude_message(MSG_INFO, "%s (dump): can't parse length \"%s\"\n",
progname, argv[3]);
} else if (addr >= maxsize) {
avrdude_message(MSG_INFO, "%s (%s): address 0x%05lx is out of range for %s memory\n",
progname, argv[0], addr, mem->desc);
return -1;
}
}
maxsize = mem->size;
if (addr >= maxsize) {
if (argc == 2) {
/* wrap around */
// Get no. bytes to read if present
static int32_t len = read_size;
if (argc >= 3) {
memset(prevmem, 0x00, sizeof(prevmem));
if (strcmp(argv[argc - 1], "...") == 0) {
if (argc == 3)
addr = 0;
}
else {
avrdude_message(MSG_INFO, "%s (dump): address 0x%05lx is out of range for %s memory\n",
progname, addr, mem->desc);
len = maxsize - addr;
} else if (argc == 4) {
len = strtol(argv[3], &end_ptr, 0);
if (*end_ptr || (end_ptr == argv[3])) {
avrdude_message(MSG_INFO, "%s (%s): can't parse length \"%s\"\n",
progname, argv[0], argv[3]);
return -1;
}
} else {
len = read_size;
}
}
// No address or length specified
else if (argc == 2) {
if (strncmp(prevmem, memtype, strlen(memtype)) != 0) {
addr = 0;
len = read_size;
strncpy(prevmem, memtype, sizeof(prevmem) - 1);
prevmem[sizeof(prevmem) - 1] = 0;
}
if (addr >= maxsize)
addr = 0; // Wrap around
}
/* trim len if nessary to not read past the end of memory */
// Trim len if nessary to not read past the end of memory
if ((addr + len) > maxsize)
len = maxsize - addr;
buf = malloc(len);
uint8_t * buf = malloc(len);
if (buf == NULL) {
avrdude_message(MSG_INFO, "%s (dump): out of memory\n", progname);
return -1;
}
for (i=0; i<len; i++) {
rc = pgm->read_byte(pgm, p, mem, addr+i, &buf[i]);
report_progress(0, 1, "Reading");
for (uint32_t i = 0; i < len; i++) {
int32_t rc = pgm->read_byte(pgm, p, mem, addr + i, &buf[i]);
if (rc != 0) {
avrdude_message(MSG_INFO, "error reading %s address 0x%05lx of part %s\n",
mem->desc, addr + i, p->desc);
@@ -311,10 +319,11 @@ static int cmd_dump(PROGRAMMER * pgm, struct avrpart * p,
mem->desc);
return -1;
}
report_progress(i, len, NULL);
}
report_progress(1, 1, NULL);
hexdump_buf(stdout, addr, buf, len);
fprintf(stdout, "\n");
free(buf);
@@ -328,35 +337,31 @@ static int cmd_dump(PROGRAMMER * pgm, struct avrpart * p,
static int cmd_write(PROGRAMMER * pgm, struct avrpart * p,
int argc, char * argv[])
{
char * e;
int len, maxsize;
char * memtype;
unsigned long addr, i;
unsigned char * buf;
unsigned char b;
int rc;
int werror;
AVRMEM * mem;
if (argc < 4) {
avrdude_message(MSG_INFO, "Usage: write <memtype> <addr> <byte1> "
"<byte2> ... <byteN>\n");
avrdude_message(MSG_INFO,
"Usage: write <memtype> <start addr> <data1> <data2> <dataN>\n"
" write <memtype> <start addr> <no. bytes> <data1> <dataN> <...>\n\n"
" Add a suffix to manually specify the size for each field:\n"
" HH/hh: 8-bit, H/h/S/s: 16-bit, L/l: 32-bit, LL/ll: 64-bit, F/f: 32-bit float\n");
return -1;
}
memtype = argv[1];
mem = avr_locate_mem(p, memtype);
int32_t i;
uint8_t write_mode; // Operation mode, "standard" or "fill"
uint8_t start_offset; // Which argc argument
int32_t len; // Number of bytes to write to memory
char * memtype = argv[1]; // Memory name string
AVRMEM * mem = avr_locate_mem(p, memtype);
if (mem == NULL) {
avrdude_message(MSG_INFO, "\"%s\" memory type not defined for part \"%s\"\n",
memtype, p->desc);
return -1;
}
uint32_t maxsize = mem->size;
maxsize = mem->size;
addr = strtoul(argv[2], &e, 0);
if (*e || (e == argv[2])) {
char * end_ptr;
int32_t addr = strtoul(argv[2], &end_ptr, 0);
if (*end_ptr || (end_ptr == argv[2])) {
avrdude_message(MSG_INFO, "%s (write): can't parse address \"%s\"\n",
progname, argv[2]);
return -1;
@@ -368,61 +373,228 @@ static int cmd_write(PROGRAMMER * pgm, struct avrpart * p,
return -1;
}
/* number of bytes to write at the specified address */
len = argc - 3;
if ((addr + len) > maxsize) {
avrdude_message(MSG_INFO, "%s (write): selected address and # bytes exceed "
"range for %s memory\n",
progname, memtype);
return -1;
}
buf = malloc(len);
// Allocate a buffer guaranteed to be large enough
uint8_t * buf = calloc(mem->size + 0x10 + strlen(argv[argc - 2]), sizeof(uint8_t));
if (buf == NULL) {
avrdude_message(MSG_INFO, "%s (write): out of memory\n", progname);
return -1;
}
for (i=3; i<argc; i++) {
buf[i-3] = strtoul(argv[i], &e, 0);
if (*e || (e == argv[i])) {
avrdude_message(MSG_INFO, "%s (write): can't parse byte \"%s\"\n",
progname, argv[i]);
// Find the first argument to write to flash and how many arguments to parse and write
if (strcmp(argv[argc - 1], "...") == 0) {
write_mode = WRITE_MODE_FILL;
start_offset = 4;
len = strtoul(argv[3], &end_ptr, 0);
if (*end_ptr || (end_ptr == argv[3])) {
avrdude_message(MSG_INFO, "%s (write ...): can't parse address \"%s\"\n",
progname, argv[3]);
free(buf);
return -1;
}
} else {
write_mode = WRITE_MODE_STANDARD;
start_offset = 3;
len = argc - start_offset;
}
pgm->err_led(pgm, OFF);
for (werror=0, i=0; i<len; i++) {
// Structure related to data that is being written to memory
struct Data {
// Data info
int32_t bytes_grown;
uint8_t size;
bool is_float;
bool is_signed;
char * str_ptr;
// Data union
union {
float f;
int64_t ll;
uint8_t a[8];
};
} data = {
.bytes_grown = 0,
.size = 0,
.is_float = false,
.is_signed = false,
.str_ptr = NULL,
.ll = 0
};
rc = avr_write_byte(pgm, p, mem, addr+i, buf[i]);
for (i = start_offset; i < len + start_offset; i++) {
data.is_float = false;
data.size = 0;
// Handle the next argument
if (i < argc - start_offset + 3) {
// Free string pointer if already allocated
if(data.str_ptr) {
free(data.str_ptr);
data.str_ptr = NULL;
}
// Get suffix if present
char suffix = argv[i][strlen(argv[i]) - 1];
char lsuffix = argv[i][strlen(argv[i]) - 2];
if ((suffix == 'L' && lsuffix == 'L') || (suffix == 'l' && lsuffix == 'l')) {
argv[i][strlen(argv[i]) - 2] = '\0';
data.size = 8;
} else if (suffix == 'L' || suffix == 'l') {
argv[i][strlen(argv[i]) - 1] = '\0';
data.size = 4;
} else if ((suffix == 'F' || suffix == 'f') &&
strncmp(argv[i], "0x", 2) != 0 && strncmp(argv[i], "-0x", 3) != 0) {
argv[i][strlen(argv[i]) - 1] = '\0';
data.size = 4;
} else if ((suffix == 'H' && lsuffix == 'H') || (suffix == 'h' && lsuffix == 'h')) {
argv[i][strlen(argv[i]) - 2] = '\0';
data.size = 1;
} else if (suffix == 'H' || suffix == 'h' || suffix == 'S' || suffix == 's') {
argv[i][strlen(argv[i]) - 1] = '\0';
data.size = 2;
} else if (suffix == '\'') {
data.size = 1;
}
// Try integers
data.ll = strtoll(argv[i], &end_ptr, 0);
if (*end_ptr || (end_ptr == argv[i])) {
// Try float
data.f = strtof(argv[i], &end_ptr);
data.is_float = true;
if (*end_ptr || (end_ptr == argv[i])) {
data.is_float = false;
// Try single character
if (argv[i][0] == '\'' && argv[i][2] == '\'') {
data.ll = argv[i][1];
} else {
// Try string that starts and ends with quotes
if (argv[i][0] == '\"' && argv[i][strlen(argv[i]) - 1] == '\"') {
data.str_ptr = calloc(strlen(argv[i]), sizeof(char));
if (data.str_ptr == NULL) {
avrdude_message(MSG_INFO, "%s (write str): out of memory\n", progname);
return -1;
}
// Strip start and end quotes
strncpy(data.str_ptr, argv[i] + 1, strlen(argv[i]) - 2);
} else {
avrdude_message(MSG_INFO, "\n%s (write): can't parse data '%s'\n",
progname, argv[i]);
free(buf);
if(data.str_ptr != NULL)
free(data.str_ptr);
return -1;
}
}
}
}
// Print warning if data size might be ambiguous
bool is_hex = (strncmp(argv[i], "0x", 2) == 0);
bool is_neg_hex = (strncmp(argv[i], "-0x", 3) == 0);
bool leading_zero = (strncmp(argv[i], "0x0", 3) == 0);
int8_t hex_digits = (strlen(argv[i]) - 2);
if(!data.size // No pre-defined size
&& (is_neg_hex // Hex with - sign in front
|| (is_hex && leading_zero && (hex_digits & (hex_digits - 1))) // Hex with 3, 5, 6 or 7 digits
|| (!is_hex && !data.is_float && llabs(data.ll) > 0xFF && strlen(argv[i]) > 2))) // Base10 int greater than 255
{
avrdude_message(MSG_INFO, "Warning: no size suffix specified for \"%s\". "
"Writing %d byte(s)\n",
argv[i],
llabs(data.ll) > UINT32_MAX ? 8 :
llabs(data.ll) > UINT16_MAX || data.is_float ? 4 : \
llabs(data.ll) > UINT8_MAX ? 2 : 1);
}
// Flag if signed integer and adjust size
if (data.ll < 0 && !data.is_float) {
data.is_signed = true;
if (data.ll < INT32_MIN)
data.size = 8;
else if (data.ll < INT16_MIN)
data.size = 4;
else if (data.ll < INT8_MIN)
data.size = 2;
else
data.size = 1;
}
}
if(data.str_ptr) {
for(int16_t j = 0; j < strlen(data.str_ptr); j++)
buf[i - start_offset + data.bytes_grown++] = (uint8_t)data.str_ptr[j];
} else {
buf[i - start_offset + data.bytes_grown] = data.a[0];
if (llabs(data.ll) > 0x000000FF || data.size >= 2 || data.is_float)
buf[i - start_offset + ++data.bytes_grown] = data.a[1];
if (llabs(data.ll) > 0x0000FFFF || data.size >= 4 || data.is_float) {
buf[i - start_offset + ++data.bytes_grown] = data.a[2];
buf[i - start_offset + ++data.bytes_grown] = data.a[3];
}
if (llabs(data.ll) > 0xFFFFFFFF || data.size == 8) {
buf[i - start_offset + ++data.bytes_grown] = data.a[4];
buf[i - start_offset + ++data.bytes_grown] = data.a[5];
buf[i - start_offset + ++data.bytes_grown] = data.a[6];
buf[i - start_offset + ++data.bytes_grown] = data.a[7];
}
}
// Make sure buf does not overflow
if (i - start_offset + data.bytes_grown > maxsize)
break;
}
// When in "fill" mode, the maximum size is already predefined
if (write_mode == WRITE_MODE_FILL)
data.bytes_grown = 0;
if ((addr + len + data.bytes_grown) > maxsize) {
avrdude_message(MSG_INFO, "%s (write): selected address and # bytes exceed "
"range for %s memory\n",
progname, memtype);
free(buf);
return -1;
}
if(data.str_ptr)
free(data.str_ptr);
avrdude_message(MSG_NOTICE, "\nInfo: Writing %d bytes starting from address 0x%02x",
len + data.bytes_grown, addr);
if (write_mode == WRITE_MODE_FILL)
avrdude_message(MSG_NOTICE, ". Remaining space filled with %s", argv[argc - 2]);
avrdude_message(MSG_NOTICE, "\n");
pgm->err_led(pgm, OFF);
bool werror = false;
report_progress(0, 1, "Writing");
for (i = 0; i < (len + data.bytes_grown); i++) {
int32_t rc = avr_write_byte(pgm, p, mem, addr+i, buf[i]);
if (rc) {
avrdude_message(MSG_INFO, "%s (write): error writing 0x%02x at 0x%05lx, rc=%d\n",
progname, buf[i], addr+i, rc);
if (rc == -1)
avrdude_message(MSG_INFO, "write operation not supported on memory type \"%s\"\n",
mem->desc);
werror = 1;
werror = true;
}
uint8_t b;
rc = pgm->read_byte(pgm, p, mem, addr+i, &b);
if (b != buf[i]) {
avrdude_message(MSG_INFO, "%s (write): error writing 0x%02x at 0x%05lx cell=0x%02x\n",
progname, buf[i], addr+i, b);
werror = 1;
werror = true;
}
if (werror) {
pgm->err_led(pgm, ON);
}
report_progress(i, (len + data.bytes_grown), NULL);
}
report_progress(1, 1, NULL);
free(buf);
fprintf(stdout, "\n");
return 0;
}

View File

@@ -27,6 +27,11 @@
extern "C" {
#endif
typedef enum {
WRITE_MODE_STANDARD = 0,
WRITE_MODE_FILL = 1,
} mode;
int terminal_mode(PROGRAMMER * pgm, struct avrpart * p);
char * terminal_get_input(const char *prompt);

View File

@@ -227,6 +227,13 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f
return -1;
}
AVRMEM_ALIAS * alias_mem = avr_find_memalias(p, mem);
char alias_mem_desc[AVR_DESCLEN + 1] = "";
if(alias_mem) {
strcat(alias_mem_desc, "/");
strcat(alias_mem_desc, alias_mem->desc);
}
if (upd->op == DEVICE_READ) {
/*
* read out the specified device memory and write it to a file
@@ -238,14 +245,14 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f
return -1;
}
if (quell_progress < 2) {
avrdude_message(MSG_INFO, "%s: reading %s memory:\n",
progname, mem->desc);
avrdude_message(MSG_INFO, "%s: reading %s%s memory:\n",
progname, mem->desc, alias_mem_desc);
}
report_progress(0,1,"Reading");
rc = avr_read(pgm, p, upd->memtype, 0);
if (rc < 0) {
avrdude_message(MSG_INFO, "%s: failed to read all of %s memory, rc=%d\n",
progname, mem->desc, rc);
avrdude_message(MSG_INFO, "%s: failed to read all of %s%s memory, rc=%d\n",
progname, mem->desc, alias_mem_desc, rc);
return -1;
}
report_progress(1,1,NULL);
@@ -288,8 +295,8 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f
* write the buffer contents to the selected memory type
*/
if (quell_progress < 2) {
avrdude_message(MSG_INFO, "%s: writing %s (%d bytes):\n",
progname, mem->desc, size);
avrdude_message(MSG_INFO, "%s: writing %s%s (%d bytes):\n",
progname, mem->desc, alias_mem_desc, size);
}
if (!(flags & UF_NOWRITE)) {
@@ -306,16 +313,16 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f
}
if (rc < 0) {
avrdude_message(MSG_INFO, "%s: failed to write %s memory, rc=%d\n",
progname, mem->desc, rc);
avrdude_message(MSG_INFO, "%s: failed to write %s%s memory, rc=%d\n",
progname, mem->desc, alias_mem_desc, rc);
return -1;
}
vsize = rc;
if (quell_progress < 2) {
avrdude_message(MSG_INFO, "%s: %d bytes of %s written\n", progname,
vsize, mem->desc);
avrdude_message(MSG_INFO, "%s: %d bytes of %s%s written\n", progname,
vsize, mem->desc, alias_mem_desc);
}
}
@@ -327,11 +334,11 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f
pgm->vfy_led(pgm, ON);
if (quell_progress < 2) {
avrdude_message(MSG_INFO, "%s: verifying %s memory against %s:\n",
progname, mem->desc, upd->filename);
avrdude_message(MSG_INFO, "%s: verifying %s%s memory against %s:\n",
progname, mem->desc, alias_mem_desc, upd->filename);
avrdude_message(MSG_NOTICE2, "%s: load data %s data from input file %s:\n",
progname, mem->desc, upd->filename);
avrdude_message(MSG_NOTICE2, "%s: load data %s%s data from input file %s:\n",
progname, mem->desc, alias_mem_desc, upd->filename);
}
rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1);
@@ -345,15 +352,15 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f
if (quell_progress < 2) {
avrdude_message(MSG_NOTICE2, "%s: input file %s contains %d bytes\n",
progname, upd->filename, size);
avrdude_message(MSG_NOTICE2, "%s: reading on-chip %s data:\n",
progname, mem->desc);
avrdude_message(MSG_NOTICE2, "%s: reading on-chip %s%s data:\n",
progname, mem->desc, alias_mem_desc);
}
report_progress (0,1,"Reading");
rc = avr_read(pgm, p, upd->memtype, v);
if (rc < 0) {
avrdude_message(MSG_INFO, "%s: failed to read all of %s memory, rc=%d\n",
progname, mem->desc, rc);
avrdude_message(MSG_INFO, "%s: failed to read all of %s%s memory, rc=%d\n",
progname, mem->desc, alias_mem_desc, rc);
pgm->err_led(pgm, ON);
avr_free_part(v);
return -1;
@@ -375,8 +382,8 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f
}
if (quell_progress < 2) {
avrdude_message(MSG_INFO, "%s: %d bytes of %s verified\n",
progname, rc, mem->desc);
avrdude_message(MSG_INFO, "%s: %d bytes of %s%s verified\n",
progname, rc, mem->desc, alias_mem_desc);
}
pgm->vfy_led(pgm, OFF);

View File

@@ -53,7 +53,7 @@ static void updi_set_rtsdtr_mode(PROGRAMMER* pgm)
static int updi_physical_open(PROGRAMMER* pgm, int baudrate, unsigned long cflags)
{
serial_recv_timeout = 100;
serial_recv_timeout = 1000;
union pinfo pinfo;
pinfo.serialinfo.baud = baudrate;
@@ -155,12 +155,19 @@ static int updi_physical_send_double_break(PROGRAMMER * pgm)
serial_send(&pgm->fd, buffer, 1);
serial_recv(&pgm->fd, buffer, 1);
serial_drain(&pgm->fd, 0);
if (serial_setparams(&pgm->fd, pgm->baudrate? pgm->baudrate: 115200, SERIAL_8E2) < 0) {
return -1;
}
updi_set_rtsdtr_mode(pgm);
/*
* drain any extraneous input
*/
serial_drain(&pgm->fd, 0);
return 0;
}
@@ -191,10 +198,14 @@ int updi_physical_sib(PROGRAMMER * pgm, unsigned char * buffer, uint8_t size)
int updi_link_open(PROGRAMMER * pgm)
{
unsigned char init_buffer[1];
if (updi_physical_open(pgm, pgm->baudrate? pgm->baudrate: 115200, SERIAL_8E2) < 0) {
return -1;
}
return updi_physical_send_double_break(pgm);
init_buffer[0]=UPDI_BREAK;
return updi_physical_send(pgm, init_buffer, 1);
}
void updi_link_close(PROGRAMMER * pgm)

View File

@@ -291,7 +291,7 @@ static int usbhid_recv(union filedescriptor *fd, unsigned char *buf, size_t nbyt
if (udev == NULL)
return -1;
rv = i = hid_read_timeout(udev, buf, nbytes, 300);
rv = i = hid_read_timeout(udev, buf, nbytes, 10000);
if (i != nbytes)
avrdude_message(MSG_INFO,
"%s: Short read, read only %d out of %u bytes\n",