mirror of
https://github.com/mariusgreuel/avrdude.git
synced 2025-12-15 02:01:07 +00:00
Compare commits
533 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
55204bc53b | ||
|
|
493113907c | ||
|
|
7021e5022b | ||
|
|
be7642861a | ||
|
|
d8013732ed | ||
|
|
9330d9000e | ||
|
|
85ab99b2ea | ||
|
|
6fdd7e2ad0 | ||
|
|
f663500996 | ||
|
|
a17e93fc2d | ||
|
|
141a19049a | ||
|
|
9161daeaa1 | ||
|
|
91f6cc9ac2 | ||
|
|
1c55f53261 | ||
|
|
5290713bb9 | ||
|
|
09df6aa664 | ||
|
|
4f075ae3b3 | ||
|
|
90943bf2bb | ||
|
|
e293f2b5a2 | ||
|
|
acf6f3060b | ||
|
|
795b5ded83 | ||
|
|
a21d1f3ceb | ||
|
|
c5ec274a19 | ||
|
|
a824d108c6 | ||
|
|
a76d845880 | ||
|
|
27072552fa | ||
|
|
d32338b5ba | ||
|
|
efc97346a2 | ||
|
|
71262c2d44 | ||
|
|
1d41442054 | ||
|
|
822d9bc3f2 | ||
|
|
9c9c479e37 | ||
|
|
d1c90c4ce2 | ||
|
|
f7e7ac43be | ||
|
|
98aa7dbb5a | ||
|
|
39ac828213 | ||
|
|
f913088cdb | ||
|
|
9fdeb5444d | ||
|
|
47660adc4b | ||
|
|
03d6bcda04 | ||
|
|
f1411fca7e | ||
|
|
abb56b44fb | ||
|
|
27ad2caa5b | ||
|
|
6bfb5f1f94 | ||
|
|
d70f6c343c | ||
|
|
e031a67542 | ||
|
|
cafa88eb9e | ||
|
|
889b1f3e48 | ||
|
|
f8f1e6486a | ||
|
|
d888b1bbb5 | ||
|
|
d230a46035 | ||
|
|
fae57bc0fa | ||
|
|
499b0bec72 | ||
|
|
40e63d4d1a | ||
|
|
8ae6321da2 | ||
|
|
130eda2439 | ||
|
|
0ee630eeca | ||
|
|
fb55e7e383 | ||
|
|
39902a7b7b | ||
|
|
5252991341 | ||
|
|
85cb696790 | ||
|
|
cc4caf1d92 | ||
|
|
d9ce7185a4 | ||
|
|
712282c81d | ||
|
|
853080dfeb | ||
|
|
e92c22e2a3 | ||
|
|
948534b2b6 | ||
|
|
89e53f2e3d | ||
|
|
fa07082d30 | ||
|
|
d3bb347e4f | ||
|
|
c8c9c6b087 | ||
|
|
30a3143cc3 | ||
|
|
2afd3d882e | ||
|
|
a566b4a888 | ||
|
|
9693e039cb | ||
|
|
7f188d48db | ||
|
|
477f1f1049 | ||
|
|
15d320cbfe | ||
|
|
83334a1794 | ||
|
|
122f2e8ec6 | ||
|
|
9858495500 | ||
|
|
007f4b378d | ||
|
|
f721cc0d53 | ||
|
|
ff700a8f1a | ||
|
|
4f47c560ac | ||
|
|
4f4497f94e | ||
|
|
e79a210517 | ||
|
|
54997a4b27 | ||
|
|
ff3368d7d7 | ||
|
|
b94afc55e9 | ||
|
|
54ad687999 | ||
|
|
8029f19918 | ||
|
|
2b024eff77 | ||
|
|
dbb4766f81 | ||
|
|
6632049d6f | ||
|
|
633922546f | ||
|
|
35380e1d70 | ||
|
|
728326c479 | ||
|
|
06e4769d2b | ||
|
|
92b95ef36d | ||
|
|
7082eecf2a | ||
|
|
f0ad4dc3aa | ||
|
|
6a9ee90a06 | ||
|
|
3407d4312a | ||
|
|
df256ba7bd | ||
|
|
2a7aeaa742 | ||
|
|
a3349385d6 | ||
|
|
6897c7b4a5 | ||
|
|
9436ea57d1 | ||
|
|
f2154ce2ea | ||
|
|
6aed88281a | ||
|
|
2e7333d3cc | ||
|
|
8daaa34ba8 | ||
|
|
0058fff9d8 | ||
|
|
37ecc60f24 | ||
|
|
1fc0d26959 | ||
|
|
c59ed7097e | ||
|
|
ba82e4bb01 | ||
|
|
b2c5030890 | ||
|
|
1652c1b781 | ||
|
|
22fe8cd1e1 | ||
|
|
9749ffcd75 | ||
|
|
ac95d249d6 | ||
|
|
f239ffa1d1 | ||
|
|
ef04ad29bf | ||
|
|
a1afb8ea4a | ||
|
|
631f057984 | ||
|
|
dfe36d084b | ||
|
|
7abd4c5bb2 | ||
|
|
f25cf95909 | ||
|
|
10eb9c7f5c | ||
|
|
08f272851c | ||
|
|
35a87b9b6f | ||
|
|
ab86a7d09b | ||
|
|
fa205ce214 | ||
|
|
7d1d5424d2 | ||
|
|
a473be7683 | ||
|
|
84e401d795 | ||
|
|
17ac6b9989 | ||
|
|
4108e10380 | ||
|
|
71cd3f3dd1 | ||
|
|
47bc86120d | ||
|
|
22879832f1 | ||
|
|
a4fa4ea9fc | ||
|
|
074b7a0868 | ||
|
|
1da689ac37 | ||
|
|
c02384d670 | ||
|
|
45d7a727cd | ||
|
|
d11d70ea6c | ||
|
|
885333687c | ||
|
|
197dc966e9 | ||
|
|
25e7980b28 | ||
|
|
38c5d278aa | ||
|
|
f2d7a52f51 | ||
|
|
79ce8f34bf | ||
|
|
2ccc76a66d | ||
|
|
6b8fa85a0b | ||
|
|
8c215d1da5 | ||
|
|
860aea6e04 | ||
|
|
0353e3ade9 | ||
|
|
f39e957354 | ||
|
|
b8d0a34c44 | ||
|
|
0734c16f98 | ||
|
|
73f657ac41 | ||
|
|
2e86c833ce | ||
|
|
f3dfeb6ecf | ||
|
|
8e5f9c7e1b | ||
|
|
af4f648cf5 | ||
|
|
4f9cd863b8 | ||
|
|
84ed521326 | ||
|
|
c788c75014 | ||
|
|
c4e4fa62c3 | ||
|
|
16c7a11538 | ||
|
|
ac7bf0624c | ||
|
|
6e45624477 | ||
|
|
4bc635da8c | ||
|
|
3318df48ed | ||
|
|
f615f8cbad | ||
|
|
3b69ebd4e9 | ||
|
|
9a2971fb35 | ||
|
|
66fa9f0689 | ||
|
|
1abf521ee3 | ||
|
|
8962bec663 | ||
|
|
d973ae28e3 | ||
|
|
4074a28682 | ||
|
|
cba56a46fe | ||
|
|
82a9e3cd60 | ||
|
|
74f8cf9dd5 | ||
|
|
1c121a456a | ||
|
|
c71e4d3674 | ||
|
|
54b633cace | ||
|
|
6eeab88fd4 | ||
|
|
fc87fe433a | ||
|
|
5dbc32c73e | ||
|
|
fa5465b63f | ||
|
|
6460235802 | ||
|
|
4b97ebc9ad | ||
|
|
00791df09d | ||
|
|
9473243b2c | ||
|
|
8a833f921e | ||
|
|
ca1ed48a5e | ||
|
|
d54f7a4fdb | ||
|
|
879dd88de5 | ||
|
|
291c0515b9 | ||
|
|
fc2bb33bb6 | ||
|
|
1ac704aa18 | ||
|
|
7c00e9ce8d | ||
|
|
1066d7cbb2 | ||
|
|
656a37122e | ||
|
|
c4770ee293 | ||
|
|
13ae062376 | ||
|
|
fafd64f35d | ||
|
|
3f6708683a | ||
|
|
be32054156 | ||
|
|
8e64e0b3ca | ||
|
|
de999a4df4 | ||
|
|
1c27d0b72c | ||
|
|
72b22aa078 | ||
|
|
cf07755f50 | ||
|
|
2ff1624077 | ||
|
|
9243abcf3b | ||
|
|
9a055d4128 | ||
|
|
29daef32db | ||
|
|
e860b3091f | ||
|
|
75bf98f073 | ||
|
|
3745f482d9 | ||
|
|
f638a4caab | ||
|
|
4cf622cbf9 | ||
|
|
688e194b10 | ||
|
|
bb60925d96 | ||
|
|
e663123831 | ||
|
|
6ed65069bf | ||
|
|
e2e97bca93 | ||
|
|
c8c576ff35 | ||
|
|
c814037d98 | ||
|
|
4d5a479c86 | ||
|
|
2d146130a6 | ||
|
|
a8a9ed2ca1 | ||
|
|
285ae1ab31 | ||
|
|
a8e190bd30 | ||
|
|
f76b51b554 | ||
|
|
51770e1a4b | ||
|
|
a71e6218b8 | ||
|
|
7f81f23269 | ||
|
|
ed1637d25c | ||
|
|
56ef0aafe8 | ||
|
|
4d4b87df15 | ||
|
|
e20799eefe | ||
|
|
06a5af36ba | ||
|
|
cee67f5f4b | ||
|
|
bbe2807089 | ||
|
|
b17ff40a09 | ||
|
|
db16162922 | ||
|
|
cb4000d7d3 | ||
|
|
d7bddada25 | ||
|
|
df364f59c3 | ||
|
|
cd07291aae | ||
|
|
ede97a0ed2 | ||
|
|
caec621eaa | ||
|
|
c23519f392 | ||
|
|
4cbcbe84ec | ||
|
|
fddb673ee8 | ||
|
|
b561874f07 | ||
|
|
5e68193a6c | ||
|
|
d9866f6219 | ||
|
|
645961163d | ||
|
|
e9750a7712 | ||
|
|
0b197a6c6f | ||
|
|
70fdf3082e | ||
|
|
e58b699f41 | ||
|
|
6b379d8842 | ||
|
|
6fa8db276f | ||
|
|
7f7974ce25 | ||
|
|
f0c7b52223 | ||
|
|
0935636c7b | ||
|
|
1b38485a23 | ||
|
|
fa935481aa | ||
|
|
5ea6e54f96 | ||
|
|
92010244dc | ||
|
|
85e827043d | ||
|
|
25d844791c | ||
|
|
3ef11e335a | ||
|
|
58233bbed4 | ||
|
|
ad9238b29e | ||
|
|
5ce121ab1c | ||
|
|
5105a871be | ||
|
|
496ab3fd81 | ||
|
|
a1c528dbe2 | ||
|
|
50b587155d | ||
|
|
d1342a1984 | ||
|
|
f9331bc6b4 | ||
|
|
08e0114447 | ||
|
|
0f12718ab6 | ||
|
|
1b3d1fb776 | ||
|
|
63aab0383c | ||
|
|
367a80150f | ||
|
|
551aff83c5 | ||
|
|
f366d16c75 | ||
|
|
736905dcdb | ||
|
|
3fc237abff | ||
|
|
e792a592f5 | ||
|
|
93105b3214 | ||
|
|
d9a67805b5 | ||
|
|
ee515ad636 | ||
|
|
e5fb5ed3a6 | ||
|
|
e2a99a00a4 | ||
|
|
56b04c2511 | ||
|
|
71aa89490e | ||
|
|
9823296d6f | ||
|
|
305c28943d | ||
|
|
2d992bd6ea | ||
|
|
3cd7546e74 | ||
|
|
61157b7985 | ||
|
|
733391725b | ||
|
|
bfbe775df8 | ||
|
|
afbe273a6a | ||
|
|
859a5aee59 | ||
|
|
133e824f8d | ||
|
|
12d7cceb2b | ||
|
|
8c1da56fe2 | ||
|
|
814abdde80 | ||
|
|
17d6c4e14c | ||
|
|
8cb8923eca | ||
|
|
ae1a671a68 | ||
|
|
66a5f13b2c | ||
|
|
f6c2213871 | ||
|
|
dccd12548d | ||
|
|
59e0241a40 | ||
|
|
2d30c6588b | ||
|
|
a4f79a194a | ||
|
|
2e7ce68927 | ||
|
|
cfe306e66d | ||
|
|
6d420f9a61 | ||
|
|
5b6506ff17 | ||
|
|
b7810ccb40 | ||
|
|
7a68b92089 | ||
|
|
d89d05867d | ||
|
|
37e8d60512 | ||
|
|
c047f5ce52 | ||
|
|
36bc2d37df | ||
|
|
434ee1d708 | ||
|
|
12b9d0a8d7 | ||
|
|
7a27c1840c | ||
|
|
749c20d5d1 | ||
|
|
21b946baa5 | ||
|
|
069e3d4a2b | ||
|
|
4d9e862ef0 | ||
|
|
7dea3d5801 | ||
|
|
f6b3053f39 | ||
|
|
f83a8bb29d | ||
|
|
615054330b | ||
|
|
e889417afb | ||
|
|
949a24ec44 | ||
|
|
c51374cfe2 | ||
|
|
8387b93696 | ||
|
|
143ee7d79d | ||
|
|
3e222a978a | ||
|
|
e7ee18fa4b | ||
|
|
b141abc41f | ||
|
|
b6d759569a | ||
|
|
025e464387 | ||
|
|
e10928ada9 | ||
|
|
039fe615c0 | ||
|
|
6757ebee57 | ||
|
|
5cc4ed40bd | ||
|
|
6af6fe9b3a | ||
|
|
6d05dfda8c | ||
|
|
df37b7faf5 | ||
|
|
083406de7c | ||
|
|
c136e38a1d | ||
|
|
da412d2274 | ||
|
|
546761708d | ||
|
|
872f75d4fb | ||
|
|
c8b9561f1e | ||
|
|
8a2d4aa7f2 | ||
|
|
e77bacaac6 | ||
|
|
3ad88ee11c | ||
|
|
aa3b5ee436 | ||
|
|
978b2bfa3b | ||
|
|
c3e97730b0 | ||
|
|
4b5a5be064 | ||
|
|
9482eea8b6 | ||
|
|
a11bc3dd8f | ||
|
|
27e53d7aac | ||
|
|
c5cfb14c31 | ||
|
|
2f1ab78f45 | ||
|
|
95e9010c9e | ||
|
|
5f5919e607 | ||
|
|
6bf083fdb3 | ||
|
|
fd510f0056 | ||
|
|
d527d692f4 | ||
|
|
15ec4ccfa6 | ||
|
|
7fc5e2a7c2 | ||
|
|
bf9c6167e9 | ||
|
|
5f3c3869f8 | ||
|
|
46db932124 | ||
|
|
d4e7f8fa07 | ||
|
|
55e524871a | ||
|
|
e14ffeda9d | ||
|
|
7ce38d550e | ||
|
|
277e1a1e7a | ||
|
|
cecaa934f0 | ||
|
|
e34df14b61 | ||
|
|
ff618a3bcb | ||
|
|
ecd94e0dbb | ||
|
|
86f80611d3 | ||
|
|
86b1947132 | ||
|
|
86c7465611 | ||
|
|
3c3531b575 | ||
|
|
2b3bfc1858 | ||
|
|
266b92449f | ||
|
|
f1ed5e5813 | ||
|
|
637626e9d6 | ||
|
|
5d919b7395 | ||
|
|
12a479b526 | ||
|
|
ab9c7f69a3 | ||
|
|
27456c9052 | ||
|
|
ccdffe88f3 | ||
|
|
8aa48a293c | ||
|
|
646cc45b23 | ||
|
|
8bfad495f3 | ||
|
|
5a481c813d | ||
|
|
1dfa7127da | ||
|
|
c7442f9f91 | ||
|
|
f77891017e | ||
|
|
95124f0ea8 | ||
|
|
357ccfdd21 | ||
|
|
7b50700c6a | ||
|
|
23dc288317 | ||
|
|
225c4f3b83 | ||
|
|
9ebf10ba19 | ||
|
|
97aa546db3 | ||
|
|
59a823acb8 | ||
|
|
6f57db045f | ||
|
|
3674e125f9 | ||
|
|
19d4d87047 | ||
|
|
44617af1ed | ||
|
|
2364219ff2 | ||
|
|
aeec873e54 | ||
|
|
7d41abdb6d | ||
|
|
8ef93bad7c | ||
|
|
c11fbbfc07 | ||
|
|
1ad0277475 | ||
|
|
06595e3ec3 | ||
|
|
aa98d8a24b | ||
|
|
f5cb51e1bf | ||
|
|
c1e0721545 | ||
|
|
0a24f1d205 | ||
|
|
4e2677cc5c | ||
|
|
9be62d28c3 | ||
|
|
f72d42b80e | ||
|
|
08669937dc | ||
|
|
f0808da915 | ||
|
|
fb9e9ca66a | ||
|
|
ddfd0b658c | ||
|
|
d05271766a | ||
|
|
92059f41a3 | ||
|
|
ed14409bf9 | ||
|
|
ea652e7b78 | ||
|
|
3bd2da1766 | ||
|
|
d1eb58dbde | ||
|
|
ede8a48d52 | ||
|
|
6acb859507 | ||
|
|
698769dcca | ||
|
|
1188a0313b | ||
|
|
ae39cd7c57 | ||
|
|
77bc532fd2 | ||
|
|
ce6e943739 | ||
|
|
9560dfe881 | ||
|
|
61c60d3b5b | ||
|
|
f2a77c44f0 | ||
|
|
3c507aee9e | ||
|
|
964a170f39 | ||
|
|
d2e0c4eab3 | ||
|
|
c19d7efe7a | ||
|
|
e603e71c45 | ||
|
|
e8d5bce16f | ||
|
|
b8af1211d8 | ||
|
|
96b8604351 | ||
|
|
0d61a7e3f7 | ||
|
|
b4a23dddc0 | ||
|
|
ca01d072ab | ||
|
|
f6a14f4c25 | ||
|
|
f3a6fc6ab0 | ||
|
|
4facd0e3d9 | ||
|
|
17422985b6 | ||
|
|
6ff0c4a47e | ||
|
|
ede6981133 | ||
|
|
3e70d4566f | ||
|
|
4446ed3a7d | ||
|
|
e0026ff0fd | ||
|
|
1fa0b23de1 | ||
|
|
229481f5ac | ||
|
|
0b1f5b8a0d | ||
|
|
25d2b42f87 | ||
|
|
4e10f943ff | ||
|
|
16d49775d0 | ||
|
|
29658b756a | ||
|
|
39dbaf4903 | ||
|
|
9baed74e69 | ||
|
|
8c70fa36ec | ||
|
|
83cb042b9e | ||
|
|
2528839c95 | ||
|
|
57c7412a3c | ||
|
|
b54f273812 | ||
|
|
56823c7aa5 | ||
|
|
d6e5083b97 | ||
|
|
7d5184da75 | ||
|
|
62f2e06711 | ||
|
|
bd11e34965 | ||
|
|
e358fd203a | ||
|
|
5fa160a365 | ||
|
|
8513530063 | ||
|
|
6c3cb9fbb2 | ||
|
|
d2317147db | ||
|
|
20bf291163 | ||
|
|
a58f2c8d66 | ||
|
|
4996510f4c | ||
|
|
c3412f1f57 | ||
|
|
dc21830241 | ||
|
|
191a5a4430 | ||
|
|
ee87b080c3 | ||
|
|
5bd3b081eb | ||
|
|
6fba5faaf5 | ||
|
|
5d6dace3c3 | ||
|
|
200283a902 | ||
|
|
ea977f6062 | ||
|
|
a13d87de00 | ||
|
|
5a74a905b4 | ||
|
|
eb551b1d0d | ||
|
|
f0c2dcf820 | ||
|
|
8da3ff76e4 | ||
|
|
8f15af9679 |
@@ -4,17 +4,30 @@ y.output
|
||||
y.tab.h
|
||||
lexer.c
|
||||
config_gram.c
|
||||
config_gram.h
|
||||
.cvsignore
|
||||
.depend
|
||||
.deps
|
||||
INSTALL
|
||||
Makefile.in
|
||||
Makefile
|
||||
ac_cfg.h.in
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
configure
|
||||
depcomp
|
||||
install-sh
|
||||
compile
|
||||
missing
|
||||
mkinstalldirs
|
||||
stamp-h.in
|
||||
|
||||
stamp-h1
|
||||
ac_cfg.h
|
||||
avrdude.conf
|
||||
avrdude.conf.tmp
|
||||
avrdude.spec
|
||||
config.guess
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
avrdude
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
AVRDUDE was written by:
|
||||
|
||||
Brian S. Dean <bsd@bsdhome.com>.
|
||||
Brian S. Dean <bsd@bdmicro.com>
|
||||
|
||||
Contributors:
|
||||
|
||||
Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
Eric Weddington <eric@umginc.net>
|
||||
Eric Weddington <ericw@evcohs.com>
|
||||
Jan-Hinnerk Reichert <hinni@despammed.com>
|
||||
Alex Shepherd <maillists@ajsystems.co.nz>
|
||||
Martin Thomas <mthomas@rhrk.uni-kl.de>
|
||||
Theodore A. Roth <troth@openavr.org>
|
||||
Michael Holzt <kju-avr@fqdn.org>
|
||||
Colin O'Flynn <coflynn@newae.com>
|
||||
|
||||
For minor contributions, please see the ChangeLog files.
|
||||
|
||||
|
||||
@@ -1,601 +1,268 @@
|
||||
2003-03-11 Theodore A. Roth <troth@openavr.org>
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* Makefile.am: Add CLEANFILES to remove all files from a make.
|
||||
* doc/Makefile.am: Ditto
|
||||
* configure.ac: Prepare for releasing version 5.7
|
||||
|
||||
2003-03-11 Theodore A. Roth <troth@openavr.org>
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* windows/Makefile.am: Fix uninstall-local rule (forget the $$file
|
||||
part of the rm command).
|
||||
* main.c: Add my name to the copyright output when being verbose.
|
||||
|
||||
2003-03-11 Theodore A. Roth <troth@openavr.org>
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* AUTHORS: Updated.
|
||||
* CHANGELOG: Move contents to NEWS and remove file.
|
||||
* ChangeLog: All of the changes for this year.
|
||||
* ChangeLog-2001: All 2001 changes.
|
||||
* ChangeLog-2002: All 2002 changes.
|
||||
* Makefile.am (EXTRA_DIST): Remove CHANGELOG and and Change-200[12].
|
||||
* NEWS: Moved contents of CHANGELOG file here.
|
||||
* README: Add note pointing to savannah site.
|
||||
Contributed by Shaun Jackman <sjackman@gmail.com>
|
||||
bug #21798: Fix both XSLT scripts
|
||||
* tools/get-dw-params.xsl (format-hex): Add the parameter count.
|
||||
* tools/get-hv-params.xsl (format_cstack): Ditto.
|
||||
|
||||
2003-03-11 Eric Weddington <eric@umginc.net>
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* doc/avrdude.texi:
|
||||
Add Install and Documentation sections for Windows. Fix typo.
|
||||
bug #21922: ATmega163 still not working in version 5.5
|
||||
* avrdude.conf.in (atmega163): fill in stk500v2 parameters, correct
|
||||
some flash programming parameters as well.
|
||||
|
||||
2003-03-10 Theodore A. Roth <troth@openavr.org>
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* Makefile.am: * Makefile.am (EXTRA_DIST): Add CHANGELOG.
|
||||
bug #22206: avrdude: ser_setspeed(): tcsetattr() failed
|
||||
* ser_posix.c (ser_setspeed): Don't pass TCSAFLUSH to tcsetattr() as
|
||||
it apparently fails to work on Solaris. After reading the
|
||||
documentation again, it seems TCSAFLUSH and TCSANOW are indeed
|
||||
mutually exclusive.
|
||||
|
||||
2003-03-10 Brian S. Dean <bsd@bsdhome.com>
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500.c: Disable debugging printf.
|
||||
bug #22234: WINDOWS version: HOWTO: Specify Serial Ports Larger than COM9
|
||||
* ser_win32.c (ser_open): prepend \\.\ to any COM port name, so it is
|
||||
safe to be used for COM ports above 9.
|
||||
|
||||
* configure.ac: Update version number in preparation for release.
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
2003-03-10 Theodore A. Roth <troth@openavr.org>
|
||||
bug #26408: Crash in stk500v2_open()
|
||||
* stk500generic.c: Implement setup and teardown hooks, calling in turn
|
||||
the respective hooks of the stk500v2 implementation.
|
||||
|
||||
* doc/avrdude.texi:
|
||||
Add comment before each node to make them stand out better.
|
||||
Use @option{} command for options instead of @code{}.
|
||||
Merge FreeBSD and Linux platform dependent information.
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
2003-03-10 Brian S. Dean <bsd@bsdhome.com>
|
||||
bug #26130: Avrdude doesn't display it's version.
|
||||
* main.c (usage): add a version number display to the default usage
|
||||
message.
|
||||
|
||||
* avrdude.1: Minor man page updates to better reflect reality.
|
||||
2009-07-01 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
2003-03-10 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
bug #26412: avrdude segfaults when called with a programmer that does not
|
||||
support it
|
||||
* main.c: do not call pgm->perform_osccal() unless it is != 0.
|
||||
|
||||
* bootstrap:
|
||||
Export all the AUTO* variables. Hopefully, that way the generated
|
||||
Makefile might get them correctly.
|
||||
2009-06-24 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* bootstrap:
|
||||
Export ${AUTOCONF} so automake will find it by whatever name it will be
|
||||
called today.
|
||||
Contributed by Zoltan Laday:
|
||||
patch #6825: xmega problems with JTAGICEmkII
|
||||
* jtagmkII.c: Many fixes for Xmega devices.
|
||||
* jtagmkII_private.h: Add various new constants required for
|
||||
Xmega devices.
|
||||
* avrdude.conf.in: New devices: ATXMEGA64A1, ATXMEGA192A1,
|
||||
ATXMEGA256A1, ATXMEGA64A3, ATXMEGA128A3, ATXMEGA192A3,
|
||||
ATXMEGA256A3, ATXMEGA256A3B, ATXMEGA16A4, ATXMEGA32A4,
|
||||
ATXMEGA64A4, ATXMEGA128A4
|
||||
* avr.c (avr_read, avr_write): Add more names for (Xmega)
|
||||
memory areas that require paged operation.
|
||||
|
||||
2003-03-06 Eric Weddington <eric@umginc.net>
|
||||
2009-06-24 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* doc/avrdude.texi:
|
||||
Add notes about ability to list parts and list programmers in the
|
||||
config file in -p and -c descriptions. Change info about where to
|
||||
find Windows search method in -C description.
|
||||
* stk500v2.c (stk600_xprog_write_byte): Handle writing fuse bytes.
|
||||
|
||||
* main.c:
|
||||
Change software version from hardcoded value to getting it from
|
||||
the configuration.
|
||||
2009-04-28 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
2003-03-06 Theodore A. Roth <troth@openavr.org>
|
||||
Submitted by Carl Hamilton:
|
||||
* update.c (parse_op): correctly \0-terminate buf after filling
|
||||
it, before it is potentially used as the source of a call to
|
||||
strlen or strcpy.
|
||||
|
||||
* avrdude.spec.in: * avrdude.spec.in: Add docs sub-package.
|
||||
Add %post and %preun scriptlets for handling info files.
|
||||
2009-04-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac, doc/Makefile.am:
|
||||
* configure.ac: Add --enable-versioned-doc option and set DOC_INST_DIR.
|
||||
* doc/Makefile.am: Add rules to install docs in DOC_INST_DIR.
|
||||
* doc/avrdude.texi: Merge the -P 0xXXX option description from
|
||||
avrdude.1.
|
||||
|
||||
* doc/Makefile.am:
|
||||
Delete the lines which where commented out in previous commit.
|
||||
2009-04-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac, doc/Makefile.am:
|
||||
* configure.ac: Remove hack to make work with automake-1.5.
|
||||
* doc/Makefile.am: Remove extra rules that were needed to work with
|
||||
automake-1.5.
|
||||
* configure.ac: declare AM_PROG_CC_C_O to avoid the warning
|
||||
"compiling `config_gram.c' with per-target flags
|
||||
requires `AM_PROG_CC_C_O' in `configure.ac'"
|
||||
|
||||
* bootstrap:
|
||||
* bootstrap: Force use of autoconf-2.57 and automake-1.7.x.
|
||||
2009-03-22 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
2003-03-05 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
bug #25971: "error writing to <stdout>" with multiple -U params.
|
||||
* fileio.c: Do not close the input/output stream when working on an
|
||||
stdio stream.
|
||||
|
||||
* avrdude.conf.in: Add a definition for the popular Ponyprog dongle.
|
||||
2009-02-28 Thomas Fischl <tfischl@gmx.de>
|
||||
|
||||
Submitted by: Daniel Williamson <dannyw@maconmgt.co.uk>
|
||||
Based on patch #6484 commited by Jurgis Brigmanis:
|
||||
* usbasp.c: added software control for ISP speed
|
||||
* usbasp.h: (Ditto.)
|
||||
|
||||
2003-03-05 Brian S. Dean <bsd@bsdhome.com>
|
||||
2009-02-28 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* main.c:
|
||||
Check the programmer type against 'STK500' instead of the programmer
|
||||
name when checking to see if we should default to the default_serial
|
||||
port instead of the default_parallel port. This has us do the right
|
||||
thing for the new 'avrisp' programmer.
|
||||
* avr910.c (avr910_read_byte_flash): Eliminate a static variable that
|
||||
hasn't been in use for 5 years.
|
||||
|
||||
* stk500.c:
|
||||
Make the page size used for non-paged parts for the 'paged_write'
|
||||
command be 128 bytes. This cuts 6 seconds off the programming time
|
||||
for uploading a 6K file into an AT90S8515 vs the time loading the same
|
||||
file using a 16 byte buffer, and the response feedback is still good.
|
||||
2009-02-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avr.c, stk500.c:
|
||||
Fix stk500 page write (Program Page command). This is supported after
|
||||
all on non-paged-memory parts. The problem was that the page size was
|
||||
defaulting to 256 (maximum for the stk500), but the timeout for a
|
||||
response from the stk500 before declaring it dead was only 0.5
|
||||
seconds. But it takes much longer than 0.5 seconds to program 256
|
||||
bytes, so we just weren't waiting long enough.
|
||||
* configure.ac: Post-release 5.6.
|
||||
|
||||
Fix this in two ways - increase the timeout to 5 seconds, and decrease
|
||||
the page size to 16 bytes for non-paged parts. The programming time
|
||||
for 16 bytes is short enough to provide the user with some feedback
|
||||
that something is happening.
|
||||
2009-02-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avr.c, stk500.c:
|
||||
Don't call the programmer's 'paged_write' routine unless the memory
|
||||
itself is paged as it doesn't appear to work otherwise.
|
||||
* configure.ac: Prepare for releasing version 5.6.
|
||||
|
||||
* avrdude.conf.in: Fix device codes for at90s8515 and at90s8535.
|
||||
2009-02-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in:
|
||||
Add PAGEL and BS2 parms for parts I have datasheets for.
|
||||
Submitted by Ed Okerson:
|
||||
* jtagmkII.c (jtagmkII_read_byte): Fix signature reading of
|
||||
Xmega.
|
||||
|
||||
* config_gram.y:
|
||||
Do that last commit slightly differently - this way results in no
|
||||
shift-reduce conflicts.
|
||||
2009-02-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* config_gram.y:
|
||||
It shouldn't be an error to have an empty configuration file. This
|
||||
causes some shift-reduce conflicts, but I think they are OK.
|
||||
Submitted by Mikael Hermansson:
|
||||
* avrdude.conf.in (ATxmega256A3): new device.
|
||||
* stk500v2 (stk500v2_initialize): Enable the AVRISPmkII as a
|
||||
PDI-capable device for ATxmega parts.
|
||||
|
||||
* main.c:
|
||||
Print out a list of valid parts for '-p ?' and a list of valid
|
||||
programmers for '-c ?'.
|
||||
2009-02-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
2003-03-04 Eric Weddington <eric@umginc.net>
|
||||
Submitted by Lars Immisch:
|
||||
patch #6750: Arduino support - new programmer-id
|
||||
* arduino.c: New file, inherits stk500.c.
|
||||
* arduino.h: New file.
|
||||
* Makefile.am: Add arduino.c and arduino.h.
|
||||
* config_gram.y: Add arduino keyword.
|
||||
* lexer.l: (Ditto.)
|
||||
* avrdude.conf.in: (Ditto.)
|
||||
* avrdude.1: Document the new programmer type.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
* doc/avrdude.texi: Minor Windows doc corrections.
|
||||
2009-02-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* doc/TODO: Add TODO file.
|
||||
* stk500v2.c: Turn all non-const static data into instance data.
|
||||
|
||||
* avrdude.conf.in: Add AVR ISP programmer.
|
||||
2009-02-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
2003-03-04 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Makefile.am: Move term.[ch] from the library into the CLI
|
||||
application section, as it is not useful for anything else but
|
||||
the CLI frontend.
|
||||
|
||||
* stk500.c:
|
||||
Don't try to set extended device programming parameters if they
|
||||
haven't been specified in the config file for the part.
|
||||
2009-02-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500.c: Set extended device parameters for all firmware versions.
|
||||
* avrdude.conf.in (ATmega1284P): new device.
|
||||
|
||||
* stk500.c:
|
||||
First attempt at supporting STK500 firmware past 1.10. Thanks to
|
||||
Jason Kyle for the needed protocol information.
|
||||
2009-02-23 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
2003-03-03 Theodore A. Roth <troth@openavr.org>
|
||||
More fixes for Solaris, including fixes for the Sunpro compiler:
|
||||
* avr.h: Remove stray semicolon.
|
||||
* configure.ac: Add check for predefined types uint_t and ulong_t.
|
||||
* confwin.c: Include "avrdude.h" on top to avoid empty translation
|
||||
unit warning.
|
||||
* ppwin.c: (Ditto.)
|
||||
* ser_win32.c: (Ditto.)
|
||||
* serbb_win32.c: (Ditto.)
|
||||
* jtagmkII.c (jtagmkII_recv): remove unreachable "return".
|
||||
* stk500.c (stk500_initialize): (Ditto.)
|
||||
* par.c: Test for both, __sun__ and __sun to see whether we are
|
||||
being compiled on Solaris.
|
||||
* ppi.c: (Ditto.)
|
||||
* stk500v2.c: Implement the DEBUG and DEBUGRECV macros in a way
|
||||
that is compatible with the ISO C99 standard.
|
||||
* usbtiny.c: Only typedef uint_t and ulong_t if they have not
|
||||
been found already by the autoconf checks.
|
||||
|
||||
* doc/Makefile.am:
|
||||
* doc/Makefile.am: Add ps and pdf rules since they aren't supplied by
|
||||
automake versions prior to 1.7.
|
||||
2009-02-23 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* doc/avrdude.texi:
|
||||
* doc/avrdude.texi: Add node and menu information for the info system.
|
||||
bug #22204: Solaris10/11 Undefiniertes Symbol gethostbyname socket
|
||||
connect
|
||||
* configure.ac: Add checks for gethostent() and socket().
|
||||
While being here, remove some old cruft left from ancient days.
|
||||
|
||||
* Makefile.am, configure.ac, doc/Makefile.am, doc/avrdude.texi:
|
||||
* Makefile.am (SUBDIRS): Add doc dir.
|
||||
* configure.ac (AC_CONFIG_FILES): Add doc/Makefile.
|
||||
* doc/Makefile.am: New file.
|
||||
* doc/avrdude.texi: Use automatically generated version.texi.
|
||||
2009-02-22 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
2003-03-02 Brian S. Dean <bsd@bsdhome.com>
|
||||
* lexer.l: Bump the %p size so AT&T lex will continue to work.
|
||||
|
||||
* doc/avrdude.texi: Initial manual.
|
||||
2009-02-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
2003-02-27 Theodore A. Roth <troth@openavr.org>
|
||||
(Partially) submitted by John Voltz:
|
||||
bug #20004: AVRDUDE update (-U) operations do not close files
|
||||
* fileio.c (fmt_autodetect, fileio): fclose() files.
|
||||
|
||||
* term.c: * term.c: Use fgets() if readline() is not available.
|
||||
2009-02-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
2003-02-27 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
* usbtiny.c: Replace all but one (very unlikely to trigger) exit(1)
|
||||
by return -1.
|
||||
|
||||
* bootstrap:
|
||||
Oops, accidentally spammed the repository with my private version of
|
||||
"bootstrap". Back out that change.
|
||||
2009-02-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* bootstrap, lexer.l:
|
||||
Ignore \r as white space, to make the Windows people happy.
|
||||
Submitted by Dick Streefland:
|
||||
patch #6749: make reading from the USBtinyISP programmer more robust
|
||||
* usbtiny.c: Add code to retry failed communication attempts.
|
||||
|
||||
2003-02-27 Theodore A. Roth <troth@openavr.org>
|
||||
2009-02-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* Makefile.am (EXTRA_DIST): Add avrdude.spec and make entries one
|
||||
per line so future patches are obvious as to what changed.
|
||||
* avrdude.spec.in: New file to support creation of binaries in rpm
|
||||
format.
|
||||
* configure.ac (AC_OUTPUT): Add avrdude.spec. Reorder so that
|
||||
Makefile is the last entry.
|
||||
Submitted by Nick Hibma:
|
||||
bug #22271: usb_reset in usb_libusb.c not necessary in FreeBSD 6.x
|
||||
* usb_libusb.c (usbdev_close): Do not call usb_reset() on FreeBSD.
|
||||
It is not necessary there.
|
||||
|
||||
2003-02-26 Theodore A. Roth <troth@openavr.org>
|
||||
2009-02-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* Makefile.am (SUBDIRS): Add windows dir.
|
||||
* configure.ac: If $target is a windows system, build whats in
|
||||
windows sub dir.
|
||||
* windows/Makefile.am: New file.
|
||||
Submitted by Andrew O. Shadoura:
|
||||
bug #25156: add direct SPI transfer mode
|
||||
* bitbang.c: Implement direct SPI transfers.
|
||||
* bitbang.h: (Ditto.)
|
||||
* par.c: (Ditto.)
|
||||
* pgm.c: (Ditto.)
|
||||
* pgm.h: (Ditto.)
|
||||
* term.c: Add the "spi" and "pgm" commands.
|
||||
* avrdude.1: Document the changes.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2003-02-25 Theodore A. Roth <troth@openavr.org>
|
||||
2009-02-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* ChangeLog: Point reader to the CHANGELOG file.
|
||||
* Makefile.am (EXTRA_DIST): Rename avrdude.conf.sample to
|
||||
avrdude.conf.in.
|
||||
Remove avrdude.conf and distclean-local rules.
|
||||
Add install-exec-local and backup-avrdude-conf rules.
|
||||
* avrdude.conf.in:
|
||||
Set default_parallel to "@DEFAULT_PAR_PORT@" for autoconf expansion.
|
||||
Set default_serial to "@DEFAULT_SER_PORT@" for autoconf expansion.
|
||||
* configure.ac: Add call to AC_CANONICAL_{BUILD,HOST,TARGET} macros.
|
||||
Set DEFAULT_PAR_PORT and DEFAULT_SER_PORT based on $host.
|
||||
Add copyright header.
|
||||
Define avrdude_version so AC_INIT and AM_INIT_AUTOMAKE are sure
|
||||
to get the same version.
|
||||
Submitted by Limor ("Lady Ada"):
|
||||
bug #24749: add support for '328p
|
||||
* avrdude.conf.in (ATmega328P): new device support.
|
||||
|
||||
* avrdude.conf.in, avrdude.conf.sample:
|
||||
Renamed avrdude.conf.sample to avrdude.conf.in.
|
||||
2009-02-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
2003-02-25 Eric Weddington <eric@umginc.net>
|
||||
Submitted by "Womo":
|
||||
bug #25241: AT90USB162, AT90USB82 device support patch for avrdude-5.5
|
||||
(also: bug #21745: AT90USBxx2 support)
|
||||
* avrdude.conf.in (AT90USB162, AT90USB82): new device support.
|
||||
|
||||
* ppiwin.c: CRs again.
|
||||
2009-02-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* confwin.c, confwin.h: Get rid of CRs.
|
||||
Submitted by Evangelos Arkalis:
|
||||
patch #6069: Atmel AT89ISP Cable
|
||||
* avrdude.conf.in (89isp): new programmer support.
|
||||
|
||||
* main.c, Makefile.am: Get rid of CRs again.
|
||||
2009-02-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
2003-02-24 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
Submitted by Bob Paddock:
|
||||
patch #6748: ATTiny88 Config
|
||||
* avrdude.conf.in (ATtiny88): new device support.
|
||||
|
||||
* avrdude.1: Atmel has rearranged their web site, so now the AVR
|
||||
docs have been moved to a more logically sounding URL.
|
||||
2009-02-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
2003-02-24 Eric Weddington <eric@umginc.net>
|
||||
Submitted by Mark Litwack:
|
||||
patch #6261: avrdude won't use dragon/debugwire to write a file
|
||||
to eeprom
|
||||
* jtagmkII.c (jtagmkII_paged_write): when in debugWire mode,
|
||||
implement a paged write to EEPROM as a series of byte writes.
|
||||
|
||||
* Makefile.am, main.c: Integrate Windows search of config files.
|
||||
2009-02-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* confwin.c, confwin.h: config file search on Windows.
|
||||
Submitted by Janos Sallai:
|
||||
patch #6542: paged_load fails on the MIB510 programming board
|
||||
* stk500.c: Add a workaround for the different signon sequence on
|
||||
MIB510 programmers.
|
||||
|
||||
* ppiwin.c: Change port value from lpt1alt to lpt3. Other
|
||||
formatting changes.
|
||||
2009-02-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* windows/giveio.c:
|
||||
Add giveio device driver source. Requires MS DDK to build.
|
||||
* avrdude.conf.in: Add the ATmega128RFA1.
|
||||
* avrdude.1: document the addition of ATmega128RFA1.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
* windows/giveio.sys: Add giveio device driver binary.
|
||||
|
||||
* giveio.sys, install_giveio.bat, remove_giveio.bat, status_giveio.bat:
|
||||
Move Windows specific files.
|
||||
|
||||
* windows/loaddrv.c, windows/loaddrv.h, windows/remove_giveio.bat:
|
||||
* windows/status_giveio.bat, windows/install_giveio.bat:
|
||||
Add Windows specific files.
|
||||
|
||||
* main.c: Usage back to stderr.
|
||||
|
||||
2003-02-22 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* CHANGELOG: Add note about .avrduderc.
|
||||
|
||||
* avr.c, avrdude.conf.sample, avrpart.h, config_gram.y, main.c,
|
||||
* par.c, pgm.c, pgm.h:
|
||||
Add the ability to read a per-user config file located at
|
||||
$HOME/.avrduderc. Entries from .avrduderc take precedence over those
|
||||
from the system wide config file in ${PREFIX}/etc/avrdude.conf.
|
||||
|
||||
Track and display the config file name and line number when we print
|
||||
out the available parts and programmers. This is useful in case
|
||||
someone has overridden a definition in their .avrduderc file and is
|
||||
wondering why the definition in the system wide config file is not
|
||||
being used.
|
||||
|
||||
Remove the default programmer 'stk500' from the distributed config
|
||||
file.
|
||||
|
||||
* CHANGELOG: Spelling.
|
||||
|
||||
2003-02-21 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* CHANGELOG:
|
||||
Put some stuff in the CHANGELOG for this upcoming new version before I
|
||||
forget.
|
||||
|
||||
* main.c:
|
||||
Update comment due to removal of the default parallel port pin config.
|
||||
|
||||
* config.c, config.h, config_gram.y, lexer.l, main.c:
|
||||
* avrdude.conf.sample:
|
||||
Introduce 'default_programmer' to the config file instead of requiring
|
||||
one of the programmers to be tagged "default" within its definition.
|
||||
|
||||
Also, axe the notion of a compiled-in default programmer. It is
|
||||
kind've pointless now that nearly all configuration comes from the
|
||||
config file, thus, avrdude is not very useful without the config file,
|
||||
and thus, having a programmer compiled-in offers little or no benefit.
|
||||
|
||||
2003-02-21 Eric Weddington <eric@umginc.net>
|
||||
|
||||
* main.c: Change usage text to be verbose.
|
||||
|
||||
* giveio.sys: Add Windows parallel port device driver (binary).
|
||||
|
||||
* install_giveio.bat, remove_giveio.bat, status_giveio.bat:
|
||||
Windows batch files to work with giveio.sys.
|
||||
|
||||
2003-02-21 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrdude.conf.sample, config.c, config.h, config_gram.y, lexer.l:
|
||||
* main.c:
|
||||
Add port name defaults to the config file instead of hard-coding.
|
||||
This adds 'default_parallel' and 'default_serial' keywords to the
|
||||
grammar, which take quoted string arguments.
|
||||
|
||||
* avrdude.conf.sample:
|
||||
Document the recent additions to the config file.
|
||||
|
||||
* stk500.c, avr.c, avrpart.h, config_gram.y, lexer.l, par.c:
|
||||
Add the ability to specify which pin to pulse when retrying entry into
|
||||
programming mode. Use 'retry_pulse' in the per-part specification
|
||||
that can currently take values of 'reset' or 'sck', the default being
|
||||
'sck' which preserves the previous behaviour. Some newer parts
|
||||
indicate that /RESET should be pulsed, while older parts say to pulse
|
||||
SCK.
|
||||
|
||||
2003-02-20 Eric Weddington <eric@umginc.net>
|
||||
|
||||
* main.c, par.c:
|
||||
Make verbose global. Make debug code in par_cmd() based on verbose=2.
|
||||
|
||||
2003-02-20 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* stk500.c: Fix pseudo/full parallel mode selection logic.
|
||||
|
||||
* avrdude.conf.sample:
|
||||
Woops, didn't really mean to commit those changes that slipped in with
|
||||
the last commit. Those were just there for testing.
|
||||
|
||||
* avr.c, avrdude.conf.sample, avrpart.h, config_gram.y, lexer.l:
|
||||
* stk500.c:
|
||||
Add 'serial' and 'parallel' keywords to the grammar so that one can
|
||||
say whether parts support these programming modes or not. Possible
|
||||
values for 'serial' are 'yes' or 'no'. Possible values for 'parallel'
|
||||
are 'yes', 'no', or 'pseudo'. Add a bit mask of flags to the AVRPART
|
||||
structure to capture these settings. Use these within
|
||||
stk500_initialize() to set the device parameters correctly.
|
||||
|
||||
Defaults for 'serial' and 'parallel' are 'yes' unless specified
|
||||
otherwise.
|
||||
|
||||
2003-02-20 Eric Weddington <eric@umginc.net>
|
||||
|
||||
* Makefile.am, ppiwin.c: Get rid of CRs.
|
||||
|
||||
* Makefile.am: Add ppiwin.c to avrdude_SOURCES.
|
||||
|
||||
* ppiwin.c: Added ppiwin.c: Windows parallel port driver.
|
||||
|
||||
* stk500.c:
|
||||
Add error message for fail to enter programming mode. Fix typos.
|
||||
|
||||
2003-02-20 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avr.c, avrdude.conf.sample, avrpart.h, config_gram.y, lexer.l:
|
||||
Add a few parameters needed for parallel programming: assignment of
|
||||
PAGEL and BS2 signals and the disposition of the reset pin
|
||||
('dedicated' or 'io').
|
||||
|
||||
2003-02-20 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* avrdude.1: Fix spacing for m169 entry. (tabs not spaces ;-)
|
||||
|
||||
2003-02-20 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrdude.1, fileio.c, main.c: Add Motorola S-record support.
|
||||
|
||||
Submitted by: "Alexey V.Levdikov" <tsar@kemford.com>
|
||||
|
||||
2003-02-19 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* avrdude.1: Add m169 to list of supported targets.
|
||||
|
||||
2003-02-19 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.sample, avrdude.1:
|
||||
My colleague contributed a part definition for the AT90S2343.
|
||||
|
||||
Submitted by: Mirko Kaffka <mirko@mkaffka.de>
|
||||
|
||||
2003-02-18 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* avrdude.conf.sample:
|
||||
Add support for mega169. (tested with stk500 with 1.7 firmware)
|
||||
|
||||
* avrdude.conf.sample:
|
||||
Add commments to separate parts (makes it easier for the eye to parse).
|
||||
|
||||
2003-02-15 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* Makefile.am: Add $srcdir to sample config filename so that
|
||||
building in a separate dir works.
|
||||
|
||||
2003-02-15 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* Makefile.am:
|
||||
Only GNU make sets $< in non-inference rules, so rather explicitly
|
||||
spell the source file(s) to remain compatible.
|
||||
|
||||
2003-02-14 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* Makefile.am: Add distclean rule and EXTRA_DIST list to get 'make
|
||||
distcheck' to succeed.
|
||||
|
||||
These changes add basic support for a autoconf/automake based
|
||||
build system.
|
||||
|
||||
* .cvsignore: Ignore autoconf files.
|
||||
* AUTHORS: New file.
|
||||
* ChangeLog: New file.
|
||||
* Makefile: Removed file.
|
||||
* Makefile.am: New file.
|
||||
* NEWS: New file.
|
||||
* README: New file.
|
||||
* bootstrap: New file.
|
||||
* configure.ac: New file.
|
||||
* avr.c: Include ac_cfg.h (generated by autoconf).
|
||||
* config.c: Include ac_cfg.h.
|
||||
Include config_gram.h instead of y.tab.h.
|
||||
* config.h: If HAS_YYSTYPE is not defined, define YYSTYPE.
|
||||
* config_gram.y: Include ac_cfg.h.
|
||||
* fileio.c: Include ac_cfg.h.
|
||||
* lexer.l: Include config_gram.h instead of y.tab.h.
|
||||
* lists.c: Include ac_cfg.h.
|
||||
* main.c: Include ac_cfg.h.
|
||||
* par.c: Include ac_cfg.h.
|
||||
* pgm.c: Include ac_cfg.h.
|
||||
* ppi.c: Include ac_cfg.h.
|
||||
* stk500.c: Include ac_cfg.h.
|
||||
* term.c: Include ac_cfg.h.
|
||||
|
||||
2003-02-14 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* stk500.c: Fix typos. Fix error messages.
|
||||
|
||||
2003-02-13 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* Makefile, avrdude.conf.sample, config_gram.y, lexer.l, main.c:
|
||||
* par.c, par.h, ppi.c, ppi.h, stk500.c:
|
||||
Split higher level parallel port programmer code off from ppi.c into
|
||||
its own file par.c, leaving low level parallel port accessor routines
|
||||
in ppi.c to help with portability. Change the programmer type to
|
||||
'PAR' now instead of 'PPI' - 'PAR' represents the parallel port
|
||||
programmer type.
|
||||
|
||||
Be more liberal with 'static' function declarations within the
|
||||
programmer implimentation files - these functions should never be
|
||||
called directly - always use the programmer function references.
|
||||
|
||||
There are still a few places in 'main.c' that directly reference the
|
||||
parallel programmer explicitly (par_getpinmask). These should be
|
||||
fixed somehow.
|
||||
|
||||
Axe a few unused functions.
|
||||
|
||||
2003-02-12 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* .cvsignore: New file.
|
||||
|
||||
* stk500.c: Remove need for inttypes.h.
|
||||
|
||||
* lexer.l: Define YY_NO_UNPUT to quell a compiler warning.
|
||||
|
||||
* Makefile: Remove YACC assignment.
|
||||
Add '-b y' options to YACC invocation.
|
||||
Remove leading '-' from 'include .depend'.
|
||||
|
||||
2003-02-12 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* config_gram.y:
|
||||
Declare the internally used static functions on top, to get rid of the
|
||||
compiler warnings.
|
||||
|
||||
Reported by: bison-generated parsers
|
||||
|
||||
2003-02-11 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* linux_ppdev.h: New file.
|
||||
* ppi.c: Include system dependant parallel port interface file.
|
||||
(ppi_open): Add call to ppi_claim().
|
||||
(ppi_close): Add call to ppi_release().
|
||||
* ppi.h: Define ppi_claim() and ppi_release() as NOPs if not previously
|
||||
defined.
|
||||
* stk500.c: Include inttypes header to quell compiler warning.
|
||||
|
||||
2003-02-11 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* pgm.c, ppi.c, stk500.c: Fix some implicit declaration warnings.
|
||||
|
||||
* config_gram.y:
|
||||
Move the C declarations to the top of the file. While [b]yacc doesn't
|
||||
care, bison does, and this is normally the way it's meant to be
|
||||
anyway.
|
||||
|
||||
2003-02-11 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* Makefile: Generate dependencies specific to the target system.
|
||||
Explicitly use byacc.
|
||||
|
||||
* Makefile:
|
||||
Remove reference to avr-gcc in depend rule (cut & paste error).
|
||||
|
||||
2003-02-09 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* main.c, pgm.c, pgm.h, pindefs.h, ppi.c, ppi.h, stk500.c:
|
||||
* stk500.h, stk500_private.h, term.c, term.h, CHANGELOG, COPYING:
|
||||
* Makefile, avr.c, avr.h, avrdude.1, avrdude.conf.sample:
|
||||
* avrdude.pdf, avrpart.h, config.c, config.h, config_gram.y:
|
||||
* fileio.c, fileio.h, lexer.l, lists.c, lists.h:
|
||||
Test commit in new public repository. Before this time this repo
|
||||
existed on a private system. Commits made by 'bsd' on the old system
|
||||
were made by Brian Dean (bdean on the current system).
|
||||
|
||||
2003-02-08 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* Makefile, avr.c, avr.h, avrdude.1, avrpart.h, config.c,
|
||||
* config.h, config_gram.y, fileio.c, fileio.h, lexer.l, lists.c:
|
||||
* lists.h, main.c, pgm.c, pgm.h, pindefs.h, ppi.c, ppi.h:
|
||||
* stk500.c, stk500.h, term.c, term.h:
|
||||
The last part of that last commit message should read:
|
||||
|
||||
All others - modify program description.
|
||||
|
||||
* Makefile, avr.c, avr.h, avrdude.1, avrpart.h, config.c:
|
||||
* config.h, config_gram.y, fileio.c, fileio.h, lexer.l, lists.c:
|
||||
* lists.h, main.c, pgm.c, pgm.h, pindefs.h, ppi.c, ppi.h:
|
||||
* stk500.c, stk500.h, term.c, term.h:
|
||||
Makefile: include a target to automatically generate the dependency
|
||||
list.
|
||||
|
||||
All others
|
||||
|
||||
2003-02-06 Brian S. Dean <bsd@bsdhome.com>
|
||||
|
||||
* avrdude.1: Update license to GPL, permission by Joerg Wunsch.
|
||||
|
||||
* lexer.l: Add GPL.
|
||||
|
||||
* Makefile, config_gram.y: Add GPL to the Makefile and config_gram.y.
|
||||
|
||||
* Makefile, stk500.h:
|
||||
Add stk500.h as a dependency for stk500.c. Remove carraige returns
|
||||
from stk500.h - don't know how those got in there (pointed out by Ted
|
||||
Roth).
|
||||
|
||||
* COPYING, avr.c, avr.h, avrpart.h, config.c, config.h, fileio.c:
|
||||
* fileio.h, lists.c, lists.h, main.c, pgm.c, pgm.h, pindefs.h:
|
||||
* ppi.c, ppi.h, stk500.c, stk500.h, term.c, term.h:
|
||||
Re-license using the GNU GPL. Thanks to Ted Roth for the patch.
|
||||
|
||||
* avr.c, avr.h, config.c, config.h, config_gram.y, fileio.c:
|
||||
* fileio.h, lexer.l, lists.c, lists.h, main.c, pgm.c, pgm.h:
|
||||
* pindefs.h, ppi.c, ppi.h, stk500.c, stk500.h, term.c, term.h:
|
||||
Get rid of the verbose printing of individual file CVS version ids.
|
||||
This was intended to be used for identifying code in the field for
|
||||
incoming bug reports, but I've never really found it all that useful.
|
||||
|
||||
* CHANGELOG, Makefile, Makefile.inc, avr.c, avrdude.1:
|
||||
* avrdude.conf.sample, config_gram.y, lexer.l, main.c, stk500.c:
|
||||
* term.c:
|
||||
Change the name from AVRPROG to AVRDUDE.
|
||||
|
||||
This change represents a name change only. There is currently an
|
||||
effort to port AVRPROG to other platforms including Linux and Windows.
|
||||
Since Atmel's programmer binary that's included within their AVR
|
||||
Studio software is named AVRPROG.EXE on the Windows OS, there is the
|
||||
chance for confusion if we keep calling this program AVRPROG as well.
|
||||
Up until now the name hasn't really been a problem since there was no
|
||||
chance to confuse 'avrprog' on Unix with Atmel's AVRPROG because
|
||||
Atmel's tools only run on Windows. But with the Unix 'avrprog'
|
||||
possibly being ported to Windows, I felt a name change was the best
|
||||
way to avoid problems.
|
||||
|
||||
So - from this point forward, my FreeBSD Unix program formerly
|
||||
known as AVRPROG will subsequently be known as AVRDUDE (AVR
|
||||
Downloader/UploaDEr).
|
||||
|
||||
This change also represents a time when the AVRDUDE sources move from
|
||||
my own private repository to a public repository. This will give
|
||||
other developers a chance to port AVRDUDE to other platforms and
|
||||
extend its functionality to support additional programming hardware,
|
||||
etc.
|
||||
|
||||
So goodbye AVRPROG, welcome AVRDUDE!
|
||||
|
||||
1095
avrdude/ChangeLog-2003
Normal file
1095
avrdude/ChangeLog-2003
Normal file
File diff suppressed because it is too large
Load Diff
1644
avrdude/ChangeLog-2004-2006
Normal file
1644
avrdude/ChangeLog-2004-2006
Normal file
File diff suppressed because it is too large
Load Diff
364
avrdude/ChangeLog-2007
Normal file
364
avrdude/ChangeLog-2007
Normal file
@@ -0,0 +1,364 @@
|
||||
2007-11-08 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* main.c: Partially revert the line buffered output change,
|
||||
and turn stderr into unbuffered output while producing the
|
||||
progress report.
|
||||
|
||||
2007-11-07 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* main.c: Add setup and teardown hooks to the programmer
|
||||
definition. If present, call the setup hook immediately after
|
||||
finding the respective programmer object, and schedule the
|
||||
teardown hook to be called upon exit. This allows the
|
||||
programmer implementation to dynamically allocate private
|
||||
programmer data.
|
||||
* pgm.c: (Ditto.)
|
||||
* pgm.h: (Ditto.)
|
||||
* avr910.c: Convert static programmer data into dynamically
|
||||
allocated data.
|
||||
* butterfly.c: (Ditto.)
|
||||
* jtagmkI.c: (Ditto.)
|
||||
* jtagmkII.c: (Ditto.)
|
||||
* stk500v2.c: (Ditto.)
|
||||
* usbasp.c: (Ditto.)
|
||||
* usbtiny.c: (Ditto.)
|
||||
|
||||
2007-11-06 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* butterfly.c: Remove the no_show_func_info() calls, as Brian
|
||||
promised some 4 years ago.
|
||||
|
||||
2007-11-06 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* main.c: Add the -x option to pass extended parameters to
|
||||
the programmer backend.
|
||||
* pgm.c: (Ditto.)
|
||||
* pgm.h: (Ditto.)
|
||||
* jtagmkII.c: Implement the extended parameter jtagchain=
|
||||
to support JTAG daisy-chains.
|
||||
* avrdude.1: Document all of the above.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2007-10-30 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (AC_INIT): Bump version for post-release.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (AC_INIT): Bump version, releasing avrdude-5.5.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Submitted by <bikenomad@gmail.com>:
|
||||
patch #5007: Patch for line-buffering of stdout and stderr
|
||||
* main.c: call setvbuf() for stdout and stderr.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Submitted by <graceindustries@gmail.com>:
|
||||
patch #5953: Add AT90CAN64 and AT90CAN32 to avrdude.conf
|
||||
* avrdude.conf.in: Add entry for AT90CAN64 and AT90CAN32.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Wolfgang Moser:
|
||||
patch #6121: ISP support for the C2N232I device (serial port
|
||||
bitbanging)
|
||||
* avrdude.conf.in: Add entry for c2n232i.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Submitted by <karl.yerkes@gmail.com>:
|
||||
patch #6141: accept binary format immediate values
|
||||
* fileio.c: Detect a 0b prefix, and call strtoul() differently
|
||||
in that case.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
bug #21076: -vvvv serial receive prints are empty in Win32 build
|
||||
* ser_win32.c (ser_recv): Drop the essentially unused variable
|
||||
"len", and use the variable "read" in order to track how many
|
||||
bytes have just been read in.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
bug #21145: atmega329p not recognized
|
||||
* avrdude.conf.in: Add definitions for the ATmega329P/3290P.
|
||||
Same as ATmega329/3290 except of the different signature.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
bug #21152: Unable to program atmega324p with avrdude 5.4 and AVRISP
|
||||
using default configuration file.
|
||||
* avrdude.conf.in: Uncomment the (bogus) stk500_devcode lines for
|
||||
the ATmega164P, ATmega324P, ATmega644, and ATmega644P definitions.
|
||||
This only affects users of STK500v1 firmware.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Submitted by <ladyada@gmail.com>:
|
||||
Patch #6233: Add support for USBtinyISP programmer
|
||||
* usbtiny.c: New file.
|
||||
* usbtiny.h: (Ditto.)
|
||||
* Makefile.am: Include usbtiny into the build.
|
||||
* avrdude.conf.in: (Ditto.)
|
||||
* config_gram.y: (Ditto.)
|
||||
* lexer.l: (Ditto.)
|
||||
* avrdude.1: Document the usbtiny support.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* doc/avrdude.texi: Sort list of supported programmers into
|
||||
alphabetical order, add all missing programmers.
|
||||
|
||||
2007-07-24 Thomas Fischl <tfischl@gmx.de>
|
||||
|
||||
* usbasp.c: Added long addresses to support devices with more
|
||||
than 64kB flash. Closes bug #20558: Long address problem with
|
||||
USBasp.
|
||||
|
||||
2007-06-27 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* Makefile.am (EXTRA_DIST): Add ChangeLog-2004-2006.
|
||||
|
||||
2007-05-16 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (AC_INIT): Bump version for post-release.
|
||||
|
||||
2007-05-16 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (AC_INIT): Bump version, releasing avrdude-5.4.
|
||||
|
||||
2007-05-16 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in: Fix AVR910 devcodes. It seems that the AVR109
|
||||
listing refers to "BOOT"-type code, while the standard codes are
|
||||
different (usually one below).
|
||||
|
||||
2007-05-16 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avr.c (avr_read, avr_write): only use the paged_load and
|
||||
paged_write backend functions iff the memory area in question has
|
||||
a page_size != 0.
|
||||
This is supposed to fix bug #19234: avrdude-5.3.1 segfaults when
|
||||
stk500v1 tries to program an ATtiny15
|
||||
|
||||
2007-05-15 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avr910.c: Fall back to avr_{read,write}_byte_default(). Fixes
|
||||
bug #18803: Fuse reading regression in avrdude 5.3.1 with avr910
|
||||
programmer
|
||||
|
||||
2007-05-15 Colin O'Flynn <coflynn@newae.com>
|
||||
|
||||
* avrdude.conf.in: Rename the ATmega164 and ATmega324 into
|
||||
ATmega164P and ATmega324P, resp. Add an entry for the ATmega644P.
|
||||
Fixes bug #19769: ATmega164p not recognized
|
||||
|
||||
2007-05-15 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* ser_posix.c (ser_send): Don't select() on the output fd before
|
||||
trying to write something to the serial line. That kind of
|
||||
polling isn't very useful anyway, and it seems it breaks for the
|
||||
Linux CP210x USB<->RS-232 bridge driver which is certainly a bug
|
||||
in the driver, but we can just avoid that bug alltogether.
|
||||
|
||||
2007-05-15 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in: Fix the STK500v2 ISP delay parameter for
|
||||
ATmega640/1280/1281/2560/2561. Atmel has changed the XML
|
||||
files after the initial release.
|
||||
|
||||
2007-05-01 Colin O'Flynn <coflynn@newae.com>
|
||||
|
||||
* safemode.c: -Oops - bug in verbose output. Fixed.
|
||||
-Fixed handling of cases where programmer cannot read fuses (AVR910)
|
||||
* main.c: -Also fixing handling of cases where programmer cannot
|
||||
read fuses
|
||||
This should close one or more bugs (18803, 19570)
|
||||
|
||||
2007-05-01 Colin O'Flynn <coflynn@newae.com>
|
||||
|
||||
* safemode.c: Added verbose output from safemode routines.
|
||||
|
||||
2007-03-25 Colin O'Flynn <coflynn@newae.com>
|
||||
|
||||
* stk500generic.c: Forgot to close the serial port before trying to
|
||||
open it again, caused problems on Windows machines.
|
||||
Closes bug #19411
|
||||
|
||||
2007-02-26 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in: Add the AT90PWM2/3B devices.
|
||||
|
||||
2007-02-02 Thomas Fischl <tfischl@gmx.de>
|
||||
|
||||
* usbasp.c: Changed return value of function usbasp_initialize to stop
|
||||
avrdude on communication errors between programmer and target.
|
||||
Closes bug #18581: safemode destroys fuse bits
|
||||
|
||||
2007-02-01 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* config_gram.y: Remove duplicate definition of token K_WRITEPAGE
|
||||
|
||||
2007-01-30 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* butterfly.c: Implement ATmega256x support for butterfly/avr109.
|
||||
|
||||
2007-01-30 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Fix subdir handling. Now finally, "make
|
||||
distcheck" will include the documentation into the tarball even if
|
||||
the configure had been run without the --enable-doc.
|
||||
|
||||
2007-01-30 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* safemode.c: Obtain progname from avrdude.h rather than trying to
|
||||
roll our own (duplicate) copy of it.
|
||||
* avr910.c: Constify char pointers.
|
||||
* avrpart.c: (Ditto.)
|
||||
* avrpart.h: (Ditto.)
|
||||
* butterfly.c: (Ditto.)
|
||||
* config.c: (Ditto.)
|
||||
* config.h: (Ditto.)
|
||||
* jtagmkI.c: (Ditto.)
|
||||
* jtagmkII.c: (Ditto.)
|
||||
* par.c: (Ditto.)
|
||||
* pgm.c: (Ditto.)
|
||||
* pgm.h: (Ditto.)
|
||||
* serbb_posix.c: (Ditto.)
|
||||
* serbb_win32.c: (Ditto.)
|
||||
* stk500.c: (Ditto.)
|
||||
* stk500v2.c: (Ditto.)
|
||||
* usbasp.c: (Ditto.)
|
||||
|
||||
2007-01-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avrpart.c: More backend/library abstraction and generalization:
|
||||
turn the list_parts() and list_programmers() functions into
|
||||
general list iteration functions that call a caller-supplied
|
||||
callback for each element. Implement list_parts() and
|
||||
list_programmers() as private functions in main.c based on that
|
||||
approach.
|
||||
* avrpart.h: (Ditto.)
|
||||
* main.c: (Ditto.)
|
||||
* pgm.c: (Ditto.)
|
||||
* pgm.h: (Ditto.)
|
||||
|
||||
2007-01-25 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* Makefile.am: Rearrange everything so it is now built into a
|
||||
libavrdude.a library, and link main.c against that library.
|
||||
* configure.ac: Add AC_PROG_RANLIB as we are building a library
|
||||
now.
|
||||
|
||||
2007-01-24 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Major code cleanup.
|
||||
- Make all internal functions "static".
|
||||
- Make sure each module's header and implementation file match.
|
||||
- Remove all library-like functionality from main.c, so only
|
||||
the actual frontend remains in main.c.
|
||||
- Add C++ brackets to all header files.
|
||||
* avr.c: (Ditto.)
|
||||
* avr.h: (Ditto.)
|
||||
* avr910.c: (Ditto.)
|
||||
* avr910.h: (Ditto.)
|
||||
* avrdude.h: (Ditto.)
|
||||
* avrpart.c: (Ditto.)
|
||||
* avrpart.h: (Ditto.)
|
||||
* bitbang.h: (Ditto.)
|
||||
* butterfly.h: (Ditto.)
|
||||
* config.c: (Ditto.)
|
||||
* config.h: (Ditto.)
|
||||
* confwin.h: (Ditto.)
|
||||
* crc16.c: (Ditto.)
|
||||
* crc16.h: (Ditto.)
|
||||
* fileio.c: (Ditto.)
|
||||
* fileio.h: (Ditto.)
|
||||
* jtagmkI.h: (Ditto.)
|
||||
* jtagmkII.h: (Ditto.)
|
||||
* lexer.l: (Ditto.)
|
||||
* lists.h: (Ditto.)
|
||||
* main.c: (Ditto.)
|
||||
* par.h: (Ditto.)
|
||||
* pgm.c: (Ditto.)
|
||||
* pgm.h: (Ditto.)
|
||||
* ppi.c: (Ditto.)
|
||||
* ppi.h: (Ditto.)
|
||||
* safemode.h: (Ditto.)
|
||||
* serbb.h: (Ditto.)
|
||||
* serial.h: (Ditto.)
|
||||
* stk500.h: (Ditto.)
|
||||
* stk500v2.c: (Ditto.)
|
||||
* stk500v2.h: (Ditto.)
|
||||
* term.c: (Ditto.)
|
||||
* term.h: (Ditto.)
|
||||
* usbasp.h: (Ditto.)
|
||||
* update.c: New file.
|
||||
* update.h: New file.
|
||||
* Makefile.am: Include update.c and update.h.
|
||||
|
||||
2007-01-24 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Move all "extern" declarations into a centreal header file.
|
||||
* Makefile.am: Add new avrdude.h.
|
||||
* avrdude.h: New file.
|
||||
* avr.c: Replace private extern decl's by #include "avrdude.h".
|
||||
* avr910.c: (Ditto.)
|
||||
* avrpart.c: (Ditto.)
|
||||
* bitbang.c: (Ditto.)
|
||||
* butterfly.c: (Ditto.)
|
||||
* config.c: (Ditto.)
|
||||
* config_gram.y: (Ditto.)
|
||||
* fileio.c: (Ditto.)
|
||||
* jtagmkI.c: (Ditto.)
|
||||
* jtagmkII.c: (Ditto.)
|
||||
* lexer.l: (Ditto.)
|
||||
* main.c: (Ditto.)
|
||||
* par.c: (Ditto.)
|
||||
* pgm.c: (Ditto.)
|
||||
* ppi.c: (Ditto.)
|
||||
* ppiwin.c: (Ditto.)
|
||||
* ser_avrdoper.c: (Ditto.)
|
||||
* ser_posix.c: (Ditto.)
|
||||
* ser_win32.c: (Ditto.)
|
||||
* serbb_posix.c: (Ditto.)
|
||||
* serbb_win32.c: (Ditto.)
|
||||
* stk500.c: (Ditto.)
|
||||
* stk500generic.c: (Ditto.)
|
||||
* stk500v2.c: (Ditto.)
|
||||
* term.c: (Ditto.)
|
||||
* usb_libusb.c: (Ditto.)
|
||||
* usbasp.c: (Ditto.)
|
||||
|
||||
2007-01-13 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in (ATmega8): Bump the delay values for flash
|
||||
and EEPROM, based on the current Atmel XML file.
|
||||
|
||||
2007-01-12 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Improve the detection of the Win32 HID library,
|
||||
and the presence of the header ddk/hidsdi.h. It now works
|
||||
correctly under Cygwin and several flavours of MinGW.
|
||||
* Makefile.am: Add new LIBHID pattern.
|
||||
|
||||
2007-01-11 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* butterfly.c (butterfly_initialize): when sending the 'T'
|
||||
command (which is ignored by current AVR109 bootloaders),
|
||||
send the first reply from the list of supported device
|
||||
codes back rather than using avrdude.conf's idea about
|
||||
an AVR910 device code. Apparently, this solves disagreements
|
||||
between different versions of at least the ATmega8 AVR910
|
||||
device code.
|
||||
Closes bug #18727: Writing flash failed
|
||||
|
||||
2007-01-07 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Reported by Till Harbaum:
|
||||
* avrdude.conf.in (ATtiny25/45/85): Change HVSP reset from
|
||||
500 microseconds to 1 ms, matching the most recent Atmel XML
|
||||
specs.
|
||||
185
avrdude/ChangeLog-2008
Normal file
185
avrdude/ChangeLog-2008
Normal file
@@ -0,0 +1,185 @@
|
||||
2008-11-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.h: Change the prototype for usleep() to be more Cygwin-
|
||||
friendly.
|
||||
* ppiwin.c: (Ditto.)
|
||||
|
||||
2008-11-06 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by limor <limor@ladyada.net>
|
||||
* usbtiny.c (usbtiny_cmd): Replace sizeof() by a fixed constant
|
||||
4 for the result array, because otherwise it would take the size
|
||||
of a pointer which miserably fails on 64-bit machines.
|
||||
|
||||
2008-11-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #6609: Using PCI parallel port cards on Windows
|
||||
* ppiwin.c (ppi_open): If the port parameter passed from the
|
||||
-p option is neither lpt1/2/3, try interpreting it directly as
|
||||
a base address.
|
||||
* avrdude.1: Document the change.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2008-11-04 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #22882: Erase Cycle Counter does not work for stk500v2
|
||||
* stk500v2.c (stk500v2_chip_erase,stk500hv_chip_erase): Return
|
||||
the expected 0 for success rather than a protocol-dependant
|
||||
number.
|
||||
|
||||
2008-11-04 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #22883: Chip Erase performed even with no-write flag (-n)
|
||||
* main.c: Do not erase the chip if both, -e and -n options have
|
||||
been specified.
|
||||
|
||||
2008-11-04 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #24589: AT90USB64* have wrong signature
|
||||
* avrdude.conf.in: Uncomment the correct, and delete the wrong
|
||||
signature for AT90USB646/647. Alas, the datasheet has never been
|
||||
corrected for years.
|
||||
|
||||
2008-10-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c: Fix a serious memory corruption that happened when
|
||||
using the JTAG ICE mkII (or AVR Dragon) in ISP mode. The wrong
|
||||
set of per-programmer private data had been allocated (stk500v2
|
||||
vs. jtagmkII) which was too small to hold the actual data.
|
||||
* jtagmkII.h: (Ditto.)
|
||||
* stk500v2.c: (Ditto.)
|
||||
|
||||
2008-07-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c: Implement Xmega JTAG support.
|
||||
* jtagmkII_private.h: Add EMULATOR_MODE_JTAG_XMEGA.
|
||||
|
||||
2008-07-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* main.c: Remember whether the device initialization worked, and
|
||||
allow to continue with -F if it failed yet do not attempt to
|
||||
perform anything on the device itself. That way, -tF could be
|
||||
specified for programmers like the STK500/STK600 even without a
|
||||
device connected, just in order to allow changing parameters on
|
||||
the programmer itself.
|
||||
* avrdude.1: Document that possible use of the -F option.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2008-07-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c (stk600_xprog_paged_write): Fix a fatal miscalculation
|
||||
of the number of bytes to be written which caused a malloc chunk
|
||||
corruption.
|
||||
|
||||
2008-07-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
First implementation of ATxmega support. By now, only the
|
||||
PDI mode of the STK600 is supported. Single-byte EEPROM
|
||||
(and flash) updates do not work yet.
|
||||
* avr.c: "boot" memory is a candidate memory region for paged
|
||||
operations, besides "flash" and "eeprom".
|
||||
* avrdude.conf.in: add ATxmega128A1 and ATxmega128A1revD
|
||||
* avrpart.h: add the AVRPART_HAS_PDI flag (used to distinguish
|
||||
ATxmega parts from classic AVRs), the nvm_base part field, and
|
||||
the offset field for a memory region.
|
||||
* config_gram.y: add "has_pdi", "nvm_base", and "offset"
|
||||
* lexer.l: (Ditto.)
|
||||
* main.c: disable auto_erase for ATxmega parts
|
||||
* stk500v2.c: implement the XPROG functionality, and divert to
|
||||
this for ATxmega parts
|
||||
* avrdude.1: Document the changes.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2008-07-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Fix a bunch of warnings.
|
||||
* avr910.c (avr910_paged_load): possible unitialized use of
|
||||
rd_size
|
||||
* jtagmkI.c (jtagmkI_initialize): pointer signedness mixup
|
||||
* jtagmkII.c (jtagmkII_print_parms1): propagate const'ness
|
||||
of parameter
|
||||
* usbasp.c (usbasp_transmit): pointer signedness mixup
|
||||
* ser_avrdoper.c (usbGetReport): remove useless pointer deref
|
||||
|
||||
2008-07-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Contributed by Ville Voipio:
|
||||
patch #6501: New autotools support for avrdude
|
||||
* Makefile.am: add @WINDOWS_DIRS@ to SUBDIR
|
||||
* bootstrap: allow for autconf-2.61 and automake-1.10, too
|
||||
* configure.ac: fix @WINDOWS_DIRS@ recursion, replace
|
||||
AC_PROG_CC by AM_PROG_CC_C_O, for esoteric reasons
|
||||
|
||||
2008-06-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Contributed by Janos Sallai <janos.sallai@vanderbilt.edu>:
|
||||
patch #6074: added support for crossbow's MIB510 programmer
|
||||
* avrdude.conf.in: Add entry for mib510.
|
||||
* stk500.c: Add special hooks to handle the MIB510 programmer.
|
||||
It mostly talks STK500v1 protocol but has a special hello and
|
||||
goodbye sequence, and uses a fixed block size of 256 bytes.
|
||||
* doc/avrdude.texi: Document support for mib510.
|
||||
|
||||
2008-06-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Contributed by Klaus Leidinger <klaus@mikrocontroller-projekte.de>:
|
||||
* main.c: Realign verbose messages.
|
||||
* avrpart.c: (Ditto.)
|
||||
* avr910.c: Print the device code selected in verbose mode.
|
||||
* butterfly.c: (Ditto.)
|
||||
|
||||
2008-06-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Contributed by Klaus Leidinger <klaus@mikrocontroller-projekte.de>:
|
||||
Add check for buffermode feature, and use it if present. Can be
|
||||
turned off using -x no_blockmode.
|
||||
* avr910.c: Implement buffermode test and usage.
|
||||
* avrdude.1: Document -x no_blockmode.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2008-03-24 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usb_libusb.c: #undef interface for Win32
|
||||
|
||||
2008-03-24 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avr910.c: Add support for the -x devcode option.
|
||||
* avrdude.1: Document -x devcode for avr910.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2008-03-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Add initial support for the Atmel STK600, for
|
||||
"classic" AVRs (AT90, ATtiny, ATmega) in both,
|
||||
ISP and high-voltage programming modes.
|
||||
* Makefile.am: Add -lm.
|
||||
* avrdude.conf.in: Add stk600, stk600pp, and stk600hvsp.
|
||||
* config_gram.y: Add support for the stk600* keywords.
|
||||
* lexer.l: (Ditto.)
|
||||
* pgm.h: Add the "chan" parameter to set_varef().
|
||||
* stk500.c: (Ditto.)
|
||||
* serial.h: Add USB endpoint support to struct filedescriptor.
|
||||
* stk500v2.c: Implement the meat of the STK600 support.
|
||||
* stk500v2.h: Add new prototypes for stk600*() programmers.
|
||||
* stk500v2_private.h: Add new constants used in the STK600.
|
||||
* term.c: Add AREF channel support.
|
||||
* usb_libusb.c: Automatically determine the correct write
|
||||
endpoint ID, the STK600 uses 0x83 while all other tools use
|
||||
0x82. Propagate the EP to use through struct filedescriptor.
|
||||
* usbdevs.h: Add the STK600 USB product ID.
|
||||
* tools/get-stk600-cards.xsl: XSL transformation for
|
||||
targetboards.xml to obtain the list of socket and routing
|
||||
card IDs, to be used in stk500v2.c (for displaying the
|
||||
names).
|
||||
* tools/get-stk600-devices.xsl: XSL transformation for
|
||||
targetboards.xml to obtain the table of socket/routing cards
|
||||
and their respective AVR device support for doc/avrdude.texi.
|
||||
* avrdude.1: Document all the STK600 stuff.
|
||||
* doc/avrdude.texi: Ditto. Added a new chapter for
|
||||
Programmer Specific Information.
|
||||
|
||||
2008-01-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c (stk500v2_recv): Make length computation unsigned so
|
||||
it cannot accidentally become negative.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#
|
||||
# avrdude - A Downloader/Uploader for AVR device programmers
|
||||
# Copyright (C) 2003 Theodore A. Roth <troth@openavr.org>
|
||||
# Copyright (C) 2003, 2004 Theodore A. Roth <troth@openavr.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -22,10 +22,12 @@
|
||||
#
|
||||
|
||||
EXTRA_DIST = \
|
||||
ChangeLog \
|
||||
ChangeLog-2001 \
|
||||
ChangeLog-2002 \
|
||||
ChangeLog-2003 \
|
||||
ChangeLog-2004-2006 \
|
||||
avrdude.1 \
|
||||
avrdude.pdf \
|
||||
avrdude.spec \
|
||||
bootstrap
|
||||
|
||||
@@ -34,31 +36,79 @@ CLEANFILES = \
|
||||
config_gram.h \
|
||||
lexer.c
|
||||
|
||||
SUBDIRS = doc @WINDOWS_DIRS@
|
||||
DIST_SUBDIRS = doc windows
|
||||
#SUBDIRS = doc @WINDOWS_DIRS@
|
||||
#DIST_SUBDIRS = doc windows
|
||||
|
||||
SUBDIRS = @SUBDIRS_AC@
|
||||
SUBDIRS += @WINDOWS_DIRS@
|
||||
DIST_SUBDIRS = @DIST_SUBDIRS_AC@
|
||||
|
||||
AM_YFLAGS = -d
|
||||
|
||||
AM_CPPFLAGS = -DCONFIG_DIR=\"$(sysconfdir)\"
|
||||
avrdude_CPPFLAGS = -DCONFIG_DIR=\"$(sysconfdir)\"
|
||||
|
||||
libavrdude_a_CPPFLAGS = -DCONFIG_DIR=\"$(sysconfdir)\"
|
||||
|
||||
avrdude_CFLAGS = @ENABLE_WARNINGS@
|
||||
|
||||
libavrdude_a_CFLAGS = @ENABLE_WARNINGS@
|
||||
|
||||
avrdude_LDADD = $(top_builddir)/$(noinst_LIBRARIES) @LIBUSB@ @LIBHID@ -lm
|
||||
|
||||
bin_PROGRAMS = avrdude
|
||||
|
||||
avrdude_SOURCES = \
|
||||
noinst_LIBRARIES = libavrdude.a
|
||||
|
||||
# automake thinks these generated files should be in the distribution,
|
||||
# but this might cause trouble for some users, so we rather don't want
|
||||
# to have them there.
|
||||
#
|
||||
# See
|
||||
#
|
||||
# https://savannah.nongnu.org/bugs/index.php?func=detailitem&item_id=15536
|
||||
#
|
||||
# for why we don't want to have them.
|
||||
dist-hook:
|
||||
rm -f \
|
||||
$(distdir)/lexer.c \
|
||||
$(distdir)/config_gram.c \
|
||||
$(distdir)/config_gram.h
|
||||
|
||||
libavrdude_a_SOURCES = \
|
||||
config_gram.y \
|
||||
lexer.l \
|
||||
arduino.h \
|
||||
arduino.c \
|
||||
avr.c \
|
||||
avr.h \
|
||||
avr910.c \
|
||||
avr910.h \
|
||||
avrdude.h \
|
||||
avrpart.c \
|
||||
avrpart.h \
|
||||
bitbang.c \
|
||||
bitbang.h \
|
||||
butterfly.c \
|
||||
butterfly.h \
|
||||
config.c \
|
||||
config.h \
|
||||
confwin.c \
|
||||
confwin.h \
|
||||
crc16.c \
|
||||
crc16.h \
|
||||
fileio.c \
|
||||
fileio.h \
|
||||
freebsd_ppi.h \
|
||||
jtagmkI.c \
|
||||
jtagmkI.h \
|
||||
jtagmkI_private.h \
|
||||
jtagmkII.c \
|
||||
jtagmkII.h \
|
||||
jtagmkII_private.h \
|
||||
linux_ppdev.h \
|
||||
lists.c \
|
||||
lists.h \
|
||||
main.c \
|
||||
my_ddk_hidsdi.h \
|
||||
par.c \
|
||||
par.h \
|
||||
pgm.c \
|
||||
@@ -67,9 +117,35 @@ avrdude_SOURCES = \
|
||||
ppi.c \
|
||||
ppi.h \
|
||||
ppiwin.c \
|
||||
safemode.c \
|
||||
safemode.h \
|
||||
serial.h \
|
||||
serbb.h \
|
||||
serbb_posix.c \
|
||||
serbb_win32.c \
|
||||
ser_avrdoper.c \
|
||||
ser_posix.c \
|
||||
ser_win32.c \
|
||||
solaris_ecpp.h \
|
||||
stk500.c \
|
||||
stk500.h \
|
||||
stk500_private.h \
|
||||
stk500v2.c \
|
||||
stk500v2.h \
|
||||
stk500v2_private.h \
|
||||
stk500generic.c \
|
||||
stk500generic.h \
|
||||
usbasp.c \
|
||||
usbasp.h \
|
||||
usbdevs.h \
|
||||
usb_libusb.c \
|
||||
usbtiny.h \
|
||||
usbtiny.c \
|
||||
update.h \
|
||||
update.c
|
||||
|
||||
avrdude_SOURCES = \
|
||||
main.c \
|
||||
term.c \
|
||||
term.h
|
||||
|
||||
@@ -79,6 +155,9 @@ sysconf_DATA = avrdude.conf
|
||||
|
||||
install-exec-local: backup-avrdude-conf
|
||||
|
||||
distclean-local:
|
||||
rm -f avrdude.conf
|
||||
|
||||
# This will get run before the config file is installed.
|
||||
backup-avrdude-conf:
|
||||
@echo "Backing up avrdude.conf in ${DESTDIR}${sysconfdir}"
|
||||
|
||||
291
avrdude/NEWS
291
avrdude/NEWS
@@ -5,19 +5,300 @@ Approximate change log for AVRDUDE by version.
|
||||
(For more detailed changes, see the ChangeLog file.)
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Version 5.7:
|
||||
|
||||
* New devices supported:
|
||||
|
||||
- ATXMEGA64A1
|
||||
- ATXMEGA192A1
|
||||
- ATXMEGA256A1
|
||||
- ATXMEGA64A3
|
||||
- ATXMEGA128A3
|
||||
- ATXMEGA192A3
|
||||
- ATXMEGA256A3
|
||||
- ATXMEGA256A3B
|
||||
- ATXMEGA16A4
|
||||
- ATXMEGA32A4
|
||||
- ATXMEGA64A4
|
||||
- ATXMEGA128A4
|
||||
|
||||
* Major Xmega fixes for the JTAG ICE mkII (patch #6825)
|
||||
|
||||
* Bugfixes.
|
||||
|
||||
Version 5.6:
|
||||
|
||||
* New devices supported:
|
||||
|
||||
- AT90USB82
|
||||
- AT90USB162
|
||||
- ATtiny88
|
||||
- ATmega328P
|
||||
- ATmega1284P
|
||||
- ATmega128RFA1
|
||||
- ATxmega128A1 rev D
|
||||
- ATxmega128A1
|
||||
- ATxmega256A3
|
||||
|
||||
* New programmers supported:
|
||||
|
||||
- AT89ISP cable (patch #6069)
|
||||
- Arduino
|
||||
|
||||
* Add support for the -x option to pass extended parameters to the
|
||||
programmer backend.
|
||||
|
||||
* Add support for JTAG daisy-chains, using the -x daisychain=
|
||||
option.
|
||||
|
||||
* Add support for the Atmel STK600 for "classic" AVRs (AT90, ATtiny,
|
||||
ATmega), using either ISP or high-voltage programming modes.
|
||||
|
||||
* Add support for the -x devcode extended parameter to the avr910
|
||||
programmer, to allow overriding the device code sent to the
|
||||
programmer.
|
||||
|
||||
* Add support for the Crossbow MIB510 programmer (patch #6074, #6542).
|
||||
|
||||
* Add support to bootstrap with GNU autoconf 2.61, and automake 1.10,
|
||||
respectively.
|
||||
|
||||
* Add support for ATxmega128A1 (including the revision D engineering
|
||||
samples) for STK600 and AVRISPmkII tools using PDI
|
||||
|
||||
* The option combination -tF now enters terminal mode even if the
|
||||
device initialization failed, so the user can modify programmer
|
||||
parameters (like Vtarget).
|
||||
|
||||
* Add preliminary support for ATxmega128A1 for the JTAG ICE mkII using
|
||||
JTAG.
|
||||
|
||||
* Add support for direct SPI transfers (bug #25156).
|
||||
|
||||
* Bugfixes.
|
||||
|
||||
Version 5.5:
|
||||
|
||||
* Add support for the USBtinyISP programmer (patch #6233)
|
||||
|
||||
* Add support for the C2N232I serial bitbang programmer (patch #6121)
|
||||
|
||||
* Bugfixes.
|
||||
|
||||
Version 5.4:
|
||||
|
||||
* New devices supported:
|
||||
|
||||
- AT90PWM2B/AT90PWM3B
|
||||
|
||||
* Bugfixes.
|
||||
|
||||
* Source code rearranged so that the functionality is now built
|
||||
into a libavrdude.a library where main.c is currently the only
|
||||
existing frontend.
|
||||
|
||||
* Implement ATmega256x support for butterfly/avr109.
|
||||
|
||||
Version 5.3.1:
|
||||
|
||||
* Add support for the AVR Dragon (all modes: ISP, JTAG, HVSP, PP,
|
||||
debugWire).
|
||||
|
||||
* Add support for debugWire (both, JTAG ICE mkII, and AVR Dragon).
|
||||
|
||||
* Add support for the AVR Doper USB HID-class programmer.
|
||||
|
||||
* Bugfixes.
|
||||
|
||||
Version 5.2:
|
||||
|
||||
* New devices supported:
|
||||
|
||||
- AT90USB646/647/1286/1287
|
||||
- ATmega2560/2561
|
||||
- ATmega325/3250/645/6450
|
||||
- ATtiny11 (HVSP only device)
|
||||
- ATtiny261/461/861
|
||||
|
||||
* Fixed paged flash write operations for AT90PWMx devices
|
||||
(error in datasheet).
|
||||
|
||||
* Add signature verification.
|
||||
|
||||
* Add high-voltage mode programming for the STK500 (both,
|
||||
parallel, and high-voltage serial programming).
|
||||
|
||||
* Add support for using the JTAG ICE mkII as a generic ISP
|
||||
programmer.
|
||||
|
||||
* Allow for specifying the ISP clock delay as an option for
|
||||
bit-bang programming adapters.
|
||||
|
||||
* Add support for Thomas Fischl's USBasp low-cost USB-attached
|
||||
programmer.
|
||||
|
||||
* The "stk500" programmer type is now implemented as a stub
|
||||
that tries to probe for either "stk500v1" or "stk500v2".
|
||||
|
||||
* Many bugfixes.
|
||||
|
||||
Version 5.1:
|
||||
|
||||
* New devices supported:
|
||||
|
||||
- ATmega640/1280/1281
|
||||
- ATtiny24/44/84
|
||||
|
||||
* JTAG mkII support now works with libusb-win32, too
|
||||
|
||||
* JTAG ICE mkI support has been added
|
||||
|
||||
* Solaris support has been added (including ecpp(7D) parallel-port
|
||||
bit-bang mode)
|
||||
|
||||
|
||||
Version 5.0:
|
||||
|
||||
* Support for JTAGICE MkII device
|
||||
|
||||
* Support for STK500 Version 2 Protocol
|
||||
|
||||
* New devices supported:
|
||||
|
||||
- AT90CAN128
|
||||
- ATmega329x/649x
|
||||
- ATmega164/324/644
|
||||
- AT90PWM2/3,
|
||||
- ATmega164/324/644
|
||||
- ATmega329x/649x
|
||||
- ATtiny25/45/85
|
||||
|
||||
* Support for serial bit-bang adapters: Ponyprog serial, UISP DASA,
|
||||
UISP DASA3.
|
||||
|
||||
* DAPA programmer pinout supported
|
||||
|
||||
* New "safemode" feature where fuse bits are verified before exit
|
||||
and if possible recovered if they have changed. This is intended
|
||||
to protect against changed fuses which were not requested which is
|
||||
reported to sometimes happen due to improper power supply or other
|
||||
reasons.
|
||||
|
||||
* Various fixes for avr910 and butterfly programmers
|
||||
|
||||
* Full support for AVR109 boot loaders (butterfly)
|
||||
|
||||
* Adding -q -q suppresses most terminal output
|
||||
|
||||
|
||||
Version 4.4.0:
|
||||
|
||||
* Native Win32 support: The windows build doesn't need Cygwin
|
||||
anymore. Additionally, the delay timing on windows should be
|
||||
more accurate now.
|
||||
Contributed by Martin Thomas
|
||||
|
||||
* Add support for
|
||||
- ATmega48, ATmega88 (contributed by Galen Seitz)
|
||||
- ATtiny2313 (contributed by Bob Paddock)
|
||||
- ATtiny13 (contributed by Pawel Moll)
|
||||
|
||||
* Added command to change the SCK of STK500-programmers. Now it
|
||||
is possible to program uC with slow oscillator.
|
||||
Contributed by Galen Seitz
|
||||
|
||||
* Baudrate for serial programmers (STK500 and AVR910) is
|
||||
configurable in the config or at the command-line.
|
||||
This way some more tweaked bootloaders and programmers can be used.
|
||||
|
||||
* Deprecated options have been removed.
|
||||
Now the "-U" option must be used.
|
||||
|
||||
* MacOS X now supported by default.
|
||||
|
||||
Version 4.3.0:
|
||||
|
||||
* Added support for "Butterfly" evaluation board.
|
||||
|
||||
* Make cycle-count work with AVR910-programmers.
|
||||
|
||||
* Added "Troubleshooting"-Appendix to the manual.
|
||||
|
||||
* Add ATmega8515 support.
|
||||
Contributed by: Matthias Wei<65>er <matthias@matwei.de>
|
||||
|
||||
* Add ATmega64 support.
|
||||
Contributed by: Erik Christiansen <erik@dd.nec.com.au>
|
||||
|
||||
* Improved polling algorithm to speed up
|
||||
programming of byte oriented parallel programmers.
|
||||
Contributed by: Jan-Hinnerk Reichert <jan-hinnerk_reichert@hamburg.de>
|
||||
|
||||
* Add "fuse" and "lock" definitions for the AT90S8535.
|
||||
|
||||
* STK500 skips empty pages in paged write resulting in faster downloads
|
||||
when there are empty blocks in between code (such as files that contain
|
||||
application code and bootloader code).
|
||||
|
||||
Version 4.2.0:
|
||||
|
||||
* Add basic support for reading and writing fuses via SPI with avr910
|
||||
programmers. Submitted by
|
||||
Jan-Hinnerk Reichert <jan-hinnerk_reichert@hamburg.de>.
|
||||
|
||||
* Perform an auto erase before programming if the flash memory is
|
||||
anywhere specified to be written by any of the -U requests. Old
|
||||
style memory specification options (-f, -i, -I, -m, and -o) are
|
||||
deprecated in favor of the new -U options. Auto erase is disabled
|
||||
if any of the old-style options (specifically -i and -o) are
|
||||
specified.
|
||||
|
||||
* Add new -U option for specifying programming operations - allows
|
||||
multiple memory operations on a single command line.
|
||||
|
||||
* New progress reporting, looks nicer and is nicer to wrapper
|
||||
environments such as emacs.
|
||||
|
||||
* Fix long-standing timing (verify) problems on Windows platform.
|
||||
Submitted by Alex Shepherd <ashepherd@wave.co.nz>.
|
||||
|
||||
* Add new file format option - 'm' for "immediate mode." In this
|
||||
case, the filename argument of the -o, -i, or -U options is
|
||||
treated as the data for uploading - useful for specifying fuse
|
||||
bits without having to create a single-byte file for uploading.
|
||||
|
||||
* Add support for displaying and setting the various STK500 operational
|
||||
parameters (Vtarget, Varef, Master clock).
|
||||
|
||||
* Add 'picoweb' programming cable programmer.
|
||||
Contributed by Rune Christensen <rune.christensen@adslhome.dk>.
|
||||
|
||||
* Add support for the sp12 programmer. Submitted by
|
||||
Larry Barello <larryba@barrello.net>.
|
||||
|
||||
|
||||
Version 4.1.0
|
||||
|
||||
* Add support for the Bascom SAMPLE programmer. Submitted by
|
||||
Larry Barello <larryba@barrello.net>.
|
||||
|
||||
* Add support for avr910 type programmers (mcu00100, pavr avr910, etc).
|
||||
|
||||
* Support new devices: ATmega8535, ATtiny26
|
||||
|
||||
|
||||
Version 4.0.0
|
||||
|
||||
* Now support Linux - added by "Theodore A. Roth" <troth@openavr.org>
|
||||
* Now support Linux - added by "Theodore A. Roth" <troth@openavr.org>.
|
||||
|
||||
* Now support Windows - added by "E. Weddington" <eric@umginc.net>
|
||||
* Now support Windows - added by "Eric B. Weddington" <eric@ecentral.com>.
|
||||
|
||||
* Use 'configure' scripts to tailor the code to the system avrdude
|
||||
is getting ready to be compiled on - added by "Theodore A. Roth"
|
||||
<troth@openavr.org>
|
||||
<troth@openavr.org>.
|
||||
|
||||
* Motorola S-Record support - submitted by "Alexey V.Levdikov "
|
||||
<tsar@kemford.com>
|
||||
<tsar@kemford.com>.
|
||||
|
||||
* Support parallel programming on the STK500. Introduce 'pagel' and
|
||||
'bs2' keywords to the config file for this purpose.
|
||||
@@ -233,4 +514,4 @@ Version 1.3.0 :
|
||||
|
||||
Version 1.2.2 :
|
||||
|
||||
* Initial public release
|
||||
* Initial public release.
|
||||
|
||||
94
avrdude/arduino.c
Normal file
94
avrdude/arduino.c
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2009 Lars Immisch
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* avrdude interface for Arduino programmer
|
||||
*
|
||||
* The Arduino programmer is mostly a STK500v1, just the signature bytes
|
||||
* are read differently.
|
||||
*/
|
||||
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "pgm.h"
|
||||
#include "stk500_private.h"
|
||||
#include "stk500.h"
|
||||
#include "serial.h"
|
||||
|
||||
/* read signature bytes - arduino version */
|
||||
static int arduino_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
|
||||
{
|
||||
unsigned char buf[32];
|
||||
|
||||
/* Signature byte reads are always 3 bytes. */
|
||||
|
||||
if (m->size < 3) {
|
||||
fprintf(stderr, "%s: memsize too small for sig byte read", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf[0] = Cmnd_STK_READ_SIGN;
|
||||
buf[1] = Sync_CRC_EOP;
|
||||
|
||||
serial_send(&pgm->fd, buf, 2);
|
||||
|
||||
if (serial_recv(&pgm->fd, buf, 5) < 0)
|
||||
return -1;
|
||||
if (buf[0] == Resp_STK_NOSYNC) {
|
||||
fprintf(stderr, "%s: stk500_cmd(): programmer is out of sync\n",
|
||||
progname);
|
||||
return -1;
|
||||
} else if (buf[0] != Resp_STK_INSYNC) {
|
||||
fprintf(stderr,
|
||||
"\n%s: arduino_read_sig_bytes(): (a) protocol error, "
|
||||
"expect=0x%02x, resp=0x%02x\n",
|
||||
progname, Resp_STK_INSYNC, buf[0]);
|
||||
return -2;
|
||||
}
|
||||
if (buf[4] != Resp_STK_OK) {
|
||||
fprintf(stderr,
|
||||
"\n%s: arduino_read_sig_bytes(): (a) protocol error, "
|
||||
"expect=0x%02x, resp=0x%02x\n",
|
||||
progname, Resp_STK_OK, buf[4]);
|
||||
return -3;
|
||||
}
|
||||
|
||||
m->buf[0] = buf[1];
|
||||
m->buf[1] = buf[2];
|
||||
m->buf[2] = buf[3];
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
void arduino_initpgm(PROGRAMMER * pgm)
|
||||
{
|
||||
/* This is mostly a STK500; just the signature is read
|
||||
differently than on real STK500v1 */
|
||||
stk500_initpgm(pgm);
|
||||
|
||||
strcpy(pgm->type, "Arduino");
|
||||
pgm->read_sig_bytes = arduino_read_sig_bytes;
|
||||
|
||||
}
|
||||
29
avrdude/arduino.h
Normal file
29
avrdude/arduino.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2009 Lars Immisch
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef arduino_h__
|
||||
#define arduino_h__
|
||||
|
||||
void arduino_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
859
avrdude/avr.c
859
avrdude/avr.c
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.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
|
||||
@@ -25,37 +25,22 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "avrpart.h"
|
||||
#include "lists.h"
|
||||
#include "pgm.h"
|
||||
|
||||
|
||||
typedef void (*FP_UpdateProgress)(int percent, double etime, char *hdr);
|
||||
|
||||
extern struct avrpart parts[];
|
||||
|
||||
extern FP_UpdateProgress update_progress;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
AVRPART * avr_find_part(char * p);
|
||||
int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned long addr, unsigned char * value);
|
||||
|
||||
AVRPART * avr_new_part(void);
|
||||
|
||||
OPCODE * avr_new_opcode(void);
|
||||
|
||||
AVRMEM * avr_new_memtype(void);
|
||||
|
||||
AVRPART * avr_dup_part(AVRPART * d);
|
||||
|
||||
AVRMEM * avr_locate_mem(AVRPART * p, char * desc);
|
||||
|
||||
int avr_txrx_bit(int fd, int bit);
|
||||
|
||||
unsigned char avr_txrx(int fd, unsigned char byte);
|
||||
|
||||
int avr_set_bits(OPCODE * op, unsigned char * cmd);
|
||||
|
||||
int avr_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned long addr, unsigned char * value);
|
||||
|
||||
int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
||||
int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
||||
int verbose);
|
||||
|
||||
int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
@@ -64,24 +49,28 @@ int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned long addr, unsigned char data);
|
||||
|
||||
int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
||||
int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned long addr, unsigned char data);
|
||||
|
||||
int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
||||
int verbose);
|
||||
|
||||
int avr_signature(PROGRAMMER * pgm, AVRPART * p);
|
||||
|
||||
char * avr_memtstr(int memtype);
|
||||
|
||||
int avr_initmem(AVRPART * p);
|
||||
|
||||
int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size);
|
||||
|
||||
void avr_mem_display(char * prefix, FILE * f, AVRMEM * m, int type,
|
||||
int verbose);
|
||||
|
||||
void avr_display(FILE * f, AVRPART * p, char * prefix, int verbose);
|
||||
|
||||
int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles);
|
||||
|
||||
int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles);;
|
||||
int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles);
|
||||
|
||||
int avr_mem_hiaddr(AVRMEM * mem);
|
||||
|
||||
int avr_chip_erase(PROGRAMMER * pgm, AVRPART * p);
|
||||
|
||||
void report_progress (int completed, int total, char *hdr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
796
avrdude/avr910.c
Normal file
796
avrdude/avr910.c
Normal file
@@ -0,0 +1,796 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org>
|
||||
* Copyright 2007 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
* Copyright 2008 Klaus Leidinger <klaus@mikrocontroller-projekte.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* avrdude interface for Atmel Low Cost Serial programmers which adher to the
|
||||
* protocol described in application note avr910.
|
||||
*/
|
||||
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "avr.h"
|
||||
#include "config.h"
|
||||
#include "pgm.h"
|
||||
#include "avr910.h"
|
||||
#include "serial.h"
|
||||
|
||||
/*
|
||||
* Private data for this programmer.
|
||||
*/
|
||||
struct pdata
|
||||
{
|
||||
char has_auto_incr_addr;
|
||||
unsigned char devcode;
|
||||
unsigned int buffersize;
|
||||
unsigned char test_blockmode;
|
||||
unsigned char use_blockmode;
|
||||
};
|
||||
|
||||
#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
|
||||
|
||||
static void avr910_setup(PROGRAMMER * pgm)
|
||||
{
|
||||
if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
|
||||
fprintf(stderr,
|
||||
"%s: avr910_setup(): Out of memory allocating private data\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
memset(pgm->cookie, 0, sizeof(struct pdata));
|
||||
PDATA(pgm)->test_blockmode = 1;
|
||||
}
|
||||
|
||||
static void avr910_teardown(PROGRAMMER * pgm)
|
||||
{
|
||||
free(pgm->cookie);
|
||||
}
|
||||
|
||||
|
||||
static int avr910_send(PROGRAMMER * pgm, char * buf, size_t len)
|
||||
{
|
||||
return serial_send(&pgm->fd, (unsigned char *)buf, len);
|
||||
}
|
||||
|
||||
|
||||
static int avr910_recv(PROGRAMMER * pgm, char * buf, size_t len)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv = serial_recv(&pgm->fd, (unsigned char *)buf, len);
|
||||
if (rv < 0) {
|
||||
fprintf(stderr,
|
||||
"%s: avr910_recv(): programmer is not responding\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int avr910_drain(PROGRAMMER * pgm, int display)
|
||||
{
|
||||
return serial_drain(&pgm->fd, display);
|
||||
}
|
||||
|
||||
|
||||
static void avr910_vfy_cmd_sent(PROGRAMMER * pgm, char * errmsg)
|
||||
{
|
||||
char c;
|
||||
|
||||
avr910_recv(pgm, &c, 1);
|
||||
if (c != '\r') {
|
||||
fprintf(stderr, "%s: error: programmer did not respond to command: %s\n",
|
||||
progname, errmsg);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* issue the 'chip erase' command to the AVR device
|
||||
*/
|
||||
static int avr910_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
avr910_send(pgm, "e", 1);
|
||||
avr910_vfy_cmd_sent(pgm, "chip erase");
|
||||
|
||||
/*
|
||||
* avr910 firmware may not delay long enough
|
||||
*/
|
||||
usleep (p->chip_erase_delay);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void avr910_enter_prog_mode(PROGRAMMER * pgm)
|
||||
{
|
||||
avr910_send(pgm, "P", 1);
|
||||
avr910_vfy_cmd_sent(pgm, "enter prog mode");
|
||||
}
|
||||
|
||||
|
||||
static void avr910_leave_prog_mode(PROGRAMMER * pgm)
|
||||
{
|
||||
avr910_send(pgm, "L", 1);
|
||||
avr910_vfy_cmd_sent(pgm, "leave prog mode");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* issue the 'program enable' command to the AVR device
|
||||
*/
|
||||
static int avr910_program_enable(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* initialize the AVR device and prepare it to accept commands
|
||||
*/
|
||||
static int avr910_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
char id[8];
|
||||
char sw[2];
|
||||
char hw[2];
|
||||
char buf[10];
|
||||
char type;
|
||||
char c, devtype_1st;
|
||||
int dev_supported = 0;
|
||||
AVRPART * part;
|
||||
|
||||
/* Get the programmer identifier. Programmer returns exactly 7 chars
|
||||
_without_ the null.*/
|
||||
|
||||
avr910_send(pgm, "S", 1);
|
||||
memset (id, 0, sizeof(id));
|
||||
avr910_recv(pgm, id, sizeof(id)-1);
|
||||
|
||||
/* Get the HW and SW versions to see if the programmer is present. */
|
||||
|
||||
avr910_send(pgm, "V", 1);
|
||||
avr910_recv(pgm, sw, sizeof(sw));
|
||||
|
||||
avr910_send(pgm, "v", 1);
|
||||
avr910_recv(pgm, hw, sizeof(hw));
|
||||
|
||||
/* Get the programmer type (serial or parallel). Expect serial. */
|
||||
|
||||
avr910_send(pgm, "p", 1);
|
||||
avr910_recv(pgm, &type, 1);
|
||||
|
||||
fprintf(stderr, "Found programmer: Id = \"%s\"; type = %c\n", id, type);
|
||||
fprintf(stderr, " Software Version = %c.%c; ", sw[0], sw[1]);
|
||||
fprintf(stderr, "Hardware Version = %c.%c\n", hw[0], hw[1]);
|
||||
|
||||
/* See if programmer supports autoincrement of address. */
|
||||
|
||||
avr910_send(pgm, "a", 1);
|
||||
avr910_recv(pgm, &PDATA(pgm)->has_auto_incr_addr, 1);
|
||||
if (PDATA(pgm)->has_auto_incr_addr == 'Y')
|
||||
fprintf(stderr, "Programmer supports auto addr increment.\n");
|
||||
|
||||
/* Check support for buffered memory access, ignore if not available */
|
||||
|
||||
if (PDATA(pgm)->test_blockmode == 1) {
|
||||
avr910_send(pgm, "b", 1);
|
||||
avr910_recv(pgm, &c, 1);
|
||||
if (c == 'Y') {
|
||||
avr910_recv(pgm, &c, 1);
|
||||
PDATA(pgm)->buffersize = (unsigned int)(unsigned char)c<<8;
|
||||
avr910_recv(pgm, &c, 1);
|
||||
PDATA(pgm)->buffersize += (unsigned int)(unsigned char)c;
|
||||
fprintf(stderr,
|
||||
"Programmer supports buffered memory access with "
|
||||
"buffersize = %u bytes.\n",
|
||||
PDATA(pgm)->buffersize);
|
||||
PDATA(pgm)->use_blockmode = 1;
|
||||
} else {
|
||||
PDATA(pgm)->use_blockmode = 0;
|
||||
}
|
||||
} else {
|
||||
PDATA(pgm)->use_blockmode = 0;
|
||||
}
|
||||
|
||||
if (PDATA(pgm)->devcode == 0) {
|
||||
|
||||
/* Get list of devices that the programmer supports. */
|
||||
|
||||
avr910_send(pgm, "t", 1);
|
||||
fprintf(stderr, "\nProgrammer supports the following devices:\n");
|
||||
devtype_1st = 0;
|
||||
while (1) {
|
||||
avr910_recv(pgm, &c, 1);
|
||||
if (devtype_1st == 0)
|
||||
devtype_1st = c;
|
||||
if (c == 0)
|
||||
break;
|
||||
part = locate_part_by_avr910_devcode(part_list, c);
|
||||
|
||||
fprintf(stderr, " Device code: 0x%02x = %s\n", c, part ? part->desc : "(unknown)");
|
||||
|
||||
/* FIXME: Need to lookup devcode and report the device. */
|
||||
|
||||
if (p->avr910_devcode == c)
|
||||
dev_supported = 1;
|
||||
};
|
||||
fprintf(stderr,"\n");
|
||||
|
||||
if (!dev_supported) {
|
||||
fprintf(stderr,
|
||||
"%s: %s: selected device is not supported by programmer: %s\n",
|
||||
progname, ovsigck? "warning": "error", p->id);
|
||||
if (!ovsigck)
|
||||
exit(1);
|
||||
}
|
||||
/* If the user forced the selection, use the first device
|
||||
type that is supported by the programmer. */
|
||||
buf[1] = ovsigck? devtype_1st: p->avr910_devcode;
|
||||
} else {
|
||||
/* devcode overridden by -x devcode= option */
|
||||
buf[1] = (char)(PDATA(pgm)->devcode);
|
||||
}
|
||||
|
||||
/* Tell the programmer which part we selected. */
|
||||
buf[0] = 'T';
|
||||
/* buf[1] has been set up above */
|
||||
|
||||
avr910_send(pgm, buf, 2);
|
||||
avr910_vfy_cmd_sent(pgm, "select device");
|
||||
|
||||
if (verbose)
|
||||
fprintf(stderr,
|
||||
"%s: avr910_devcode selected: 0x%02x\n",
|
||||
progname, (unsigned)buf[1]);
|
||||
|
||||
avr910_enter_prog_mode(pgm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void avr910_disable(PROGRAMMER * pgm)
|
||||
{
|
||||
/* Do nothing. */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void avr910_enable(PROGRAMMER * pgm)
|
||||
{
|
||||
/* Do nothing. */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* transmit an AVR device command and return the results; 'cmd' and
|
||||
* 'res' must point to at least a 4 byte data buffer
|
||||
*/
|
||||
static int avr910_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
|
||||
unsigned char res[4])
|
||||
{
|
||||
char buf[5];
|
||||
|
||||
/* FIXME: Insert version check here */
|
||||
|
||||
buf[0] = '.'; /* New Universal Command */
|
||||
buf[1] = cmd[0];
|
||||
buf[2] = cmd[1];
|
||||
buf[3] = cmd[2];
|
||||
buf[4] = cmd[3];
|
||||
|
||||
avr910_send (pgm, buf, 5);
|
||||
avr910_recv (pgm, buf, 2);
|
||||
|
||||
res[0] = 0x00; /* Dummy value */
|
||||
res[1] = cmd[0];
|
||||
res[2] = cmd[1];
|
||||
res[3] = buf[0];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int avr910_parseextparms(PROGRAMMER * pgm, LISTID extparms)
|
||||
{
|
||||
LNODEID ln;
|
||||
const char *extended_param;
|
||||
int rv = 0;
|
||||
|
||||
for (ln = lfirst(extparms); ln; ln = lnext(ln)) {
|
||||
extended_param = ldata(ln);
|
||||
|
||||
if (strncmp(extended_param, "devcode=", strlen("devcode=")) == 0) {
|
||||
int devcode;
|
||||
if (sscanf(extended_param, "devcode=%i", &devcode) != 1 ||
|
||||
devcode <= 0 || devcode > 255) {
|
||||
fprintf(stderr,
|
||||
"%s: avr910_parseextparms(): invalid devcode '%s'\n",
|
||||
progname, extended_param);
|
||||
rv = -1;
|
||||
continue;
|
||||
}
|
||||
if (verbose >= 2) {
|
||||
fprintf(stderr,
|
||||
"%s: avr910_parseextparms(): devcode overwritten as 0x%02x\n",
|
||||
progname, devcode);
|
||||
}
|
||||
PDATA(pgm)->devcode = devcode;
|
||||
|
||||
continue;
|
||||
}
|
||||
if (strncmp(extended_param, "no_blockmode", strlen("no_blockmode")) == 0) {
|
||||
if (verbose >= 2) {
|
||||
fprintf(stderr,
|
||||
"%s: avr910_parseextparms(-x): no testing for Blockmode\n",
|
||||
progname);
|
||||
}
|
||||
PDATA(pgm)->test_blockmode = 0;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
fprintf(stderr,
|
||||
"%s: avr910_parseextparms(): invalid extended parameter '%s'\n",
|
||||
progname, extended_param);
|
||||
rv = -1;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
static int avr910_open(PROGRAMMER * pgm, char * port)
|
||||
{
|
||||
/*
|
||||
* If baudrate was not specified use 19.200 Baud
|
||||
*/
|
||||
if(pgm->baudrate == 0) {
|
||||
pgm->baudrate = 19200;
|
||||
}
|
||||
|
||||
strcpy(pgm->port, port);
|
||||
serial_open(port, pgm->baudrate, &pgm->fd);
|
||||
|
||||
/*
|
||||
* drain any extraneous input
|
||||
*/
|
||||
avr910_drain (pgm, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void avr910_close(PROGRAMMER * pgm)
|
||||
{
|
||||
avr910_leave_prog_mode(pgm);
|
||||
|
||||
serial_close(&pgm->fd);
|
||||
pgm->fd.ifd = -1;
|
||||
}
|
||||
|
||||
|
||||
static void avr910_display(PROGRAMMER * pgm, const char * p)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void avr910_set_addr(PROGRAMMER * pgm, unsigned long addr)
|
||||
{
|
||||
char cmd[3];
|
||||
|
||||
cmd[0] = 'A';
|
||||
cmd[1] = (addr >> 8) & 0xff;
|
||||
cmd[2] = addr & 0xff;
|
||||
|
||||
avr910_send(pgm, cmd, sizeof(cmd));
|
||||
avr910_vfy_cmd_sent(pgm, "set addr");
|
||||
}
|
||||
|
||||
|
||||
static int avr910_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned long addr, unsigned char value)
|
||||
{
|
||||
char cmd[2];
|
||||
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
if (addr & 0x01) {
|
||||
cmd[0] = 'C'; /* Write Program Mem high byte */
|
||||
}
|
||||
else {
|
||||
cmd[0] = 'c';
|
||||
}
|
||||
|
||||
addr >>= 1;
|
||||
}
|
||||
else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
cmd[0] = 'D';
|
||||
}
|
||||
else {
|
||||
return avr_write_byte_default(pgm, p, m, addr, value);
|
||||
}
|
||||
|
||||
cmd[1] = value;
|
||||
|
||||
avr910_set_addr(pgm, addr);
|
||||
|
||||
avr910_send(pgm, cmd, sizeof(cmd));
|
||||
avr910_vfy_cmd_sent(pgm, "write byte");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int avr910_read_byte_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned long addr, unsigned char * value)
|
||||
{
|
||||
char buf[2];
|
||||
|
||||
avr910_set_addr(pgm, addr >> 1);
|
||||
|
||||
avr910_send(pgm, "R", 1);
|
||||
|
||||
/* Read back the program mem word (MSB first) */
|
||||
avr910_recv(pgm, buf, sizeof(buf));
|
||||
|
||||
if ((addr & 0x01) == 0) {
|
||||
*value = buf[1];
|
||||
}
|
||||
else {
|
||||
*value = buf[0];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int avr910_read_byte_eeprom(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned long addr, unsigned char * value)
|
||||
{
|
||||
avr910_set_addr(pgm, addr);
|
||||
avr910_send(pgm, "d", 1);
|
||||
avr910_recv(pgm, (char *)value, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int avr910_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned long addr, unsigned char * value)
|
||||
{
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
return avr910_read_byte_flash(pgm, p, m, addr, value);
|
||||
}
|
||||
|
||||
if (strcmp(m->desc, "eeprom") == 0) {
|
||||
return avr910_read_byte_eeprom(pgm, p, m, addr, value);
|
||||
}
|
||||
|
||||
return avr_read_byte_default(pgm, p, m, addr, value);
|
||||
}
|
||||
|
||||
|
||||
static int avr910_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int n_bytes)
|
||||
{
|
||||
unsigned char cmd[] = {'c', 'C'};
|
||||
char buf[2];
|
||||
unsigned int addr = 0;
|
||||
unsigned int max_addr = n_bytes;
|
||||
unsigned int page_addr;
|
||||
int page_bytes = page_size;
|
||||
int page_wr_cmd_pending = 0;
|
||||
|
||||
page_addr = addr;
|
||||
avr910_set_addr(pgm, addr>>1);
|
||||
|
||||
while (addr < max_addr) {
|
||||
page_wr_cmd_pending = 1;
|
||||
buf[0] = cmd[addr & 0x01];
|
||||
buf[1] = m->buf[addr];
|
||||
avr910_send(pgm, buf, sizeof(buf));
|
||||
avr910_vfy_cmd_sent(pgm, "write byte");
|
||||
|
||||
addr++;
|
||||
page_bytes--;
|
||||
|
||||
if (m->paged && (page_bytes == 0)) {
|
||||
/* Send the "Issue Page Write" if we have sent a whole page. */
|
||||
|
||||
avr910_set_addr(pgm, page_addr>>1);
|
||||
avr910_send(pgm, "m", 1);
|
||||
avr910_vfy_cmd_sent(pgm, "flush page");
|
||||
|
||||
page_wr_cmd_pending = 0;
|
||||
usleep(m->max_write_delay);
|
||||
avr910_set_addr(pgm, addr>>1);
|
||||
|
||||
/* Set page address for next page. */
|
||||
|
||||
page_addr = addr;
|
||||
page_bytes = page_size;
|
||||
}
|
||||
else if ((PDATA(pgm)->has_auto_incr_addr != 'Y') && ((addr & 0x01) == 0)) {
|
||||
avr910_set_addr(pgm, addr>>1);
|
||||
}
|
||||
|
||||
report_progress (addr, max_addr, NULL);
|
||||
}
|
||||
|
||||
/* If we didn't send the page wr cmd after the last byte written in the
|
||||
loop, send it now. */
|
||||
|
||||
if (page_wr_cmd_pending) {
|
||||
avr910_set_addr(pgm, page_addr>>1);
|
||||
avr910_send(pgm, "m", 1);
|
||||
avr910_vfy_cmd_sent(pgm, "flush final page");
|
||||
usleep(m->max_write_delay);
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
||||
static int avr910_paged_write_eeprom(PROGRAMMER * pgm, AVRPART * p,
|
||||
AVRMEM * m, int page_size, int n_bytes)
|
||||
{
|
||||
char cmd[2];
|
||||
unsigned int addr = 0;
|
||||
unsigned int max_addr = n_bytes;
|
||||
|
||||
avr910_set_addr(pgm, addr);
|
||||
|
||||
cmd[0] = 'D';
|
||||
|
||||
while (addr < max_addr) {
|
||||
cmd[1] = m->buf[addr];
|
||||
avr910_send(pgm, cmd, sizeof(cmd));
|
||||
avr910_vfy_cmd_sent(pgm, "write byte");
|
||||
usleep(m->max_write_delay);
|
||||
|
||||
addr++;
|
||||
|
||||
if (PDATA(pgm)->has_auto_incr_addr != 'Y') {
|
||||
avr910_set_addr(pgm, addr);
|
||||
}
|
||||
|
||||
report_progress (addr, max_addr, NULL);
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
||||
static int avr910_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int n_bytes)
|
||||
{
|
||||
int rval = 0;
|
||||
if (PDATA(pgm)->use_blockmode == 0) {
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
rval = avr910_paged_write_flash(pgm, p, m, page_size, n_bytes);
|
||||
} else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
rval = avr910_paged_write_eeprom(pgm, p, m, page_size, n_bytes);
|
||||
} else {
|
||||
rval = -2;
|
||||
}
|
||||
}
|
||||
|
||||
if (PDATA(pgm)->use_blockmode == 1) {
|
||||
unsigned int addr = 0;
|
||||
unsigned int max_addr = n_bytes;
|
||||
char *cmd;
|
||||
unsigned int blocksize = PDATA(pgm)->buffersize;
|
||||
|
||||
if (strcmp(m->desc, "flash") && strcmp(m->desc, "eeprom"))
|
||||
rval = -2;
|
||||
|
||||
if (m->desc[0] == 'e')
|
||||
blocksize = 1; /* Write to eeprom single bytes only */
|
||||
avr910_set_addr(pgm, addr);
|
||||
|
||||
cmd = malloc(4 + blocksize);
|
||||
if (!cmd) rval = -1;
|
||||
cmd[0] = 'B';
|
||||
cmd[3] = toupper(m->desc[0]);
|
||||
|
||||
while (addr < max_addr) {
|
||||
if ((max_addr - addr) < blocksize) {
|
||||
blocksize = max_addr - addr;
|
||||
};
|
||||
memcpy(&cmd[4], &m->buf[addr], blocksize);
|
||||
cmd[1] = (blocksize >> 8) & 0xff;
|
||||
cmd[2] = blocksize & 0xff;
|
||||
|
||||
avr910_send(pgm, cmd, 4 + blocksize);
|
||||
avr910_vfy_cmd_sent(pgm, "write block");
|
||||
|
||||
addr += blocksize;
|
||||
|
||||
report_progress (addr, max_addr, NULL);
|
||||
} /* while */
|
||||
free(cmd);
|
||||
|
||||
rval = addr;
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
||||
static int avr910_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int n_bytes)
|
||||
{
|
||||
char cmd;
|
||||
int rd_size = 1;
|
||||
unsigned int addr = 0;
|
||||
unsigned int max_addr;
|
||||
char buf[2];
|
||||
int rval=0;
|
||||
|
||||
if (PDATA(pgm)->use_blockmode == 0) {
|
||||
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
cmd = 'R';
|
||||
rd_size = 2; /* read two bytes per addr */
|
||||
} else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
cmd = 'd';
|
||||
rd_size = 1;
|
||||
} else {
|
||||
rval = -2;
|
||||
}
|
||||
|
||||
max_addr = n_bytes/rd_size;
|
||||
|
||||
avr910_set_addr(pgm, addr);
|
||||
|
||||
while (addr < max_addr) {
|
||||
avr910_send(pgm, &cmd, 1);
|
||||
if (cmd == 'R') {
|
||||
/* The 'R' command returns two bytes, MSB first, we need to put the data
|
||||
into the memory buffer LSB first. */
|
||||
avr910_recv(pgm, buf, 2);
|
||||
m->buf[addr*2] = buf[1]; /* LSB */
|
||||
m->buf[addr*2+1] = buf[0]; /* MSB */
|
||||
}
|
||||
else {
|
||||
avr910_recv(pgm, (char *)&m->buf[addr], 1);
|
||||
}
|
||||
|
||||
addr++;
|
||||
|
||||
if (PDATA(pgm)->has_auto_incr_addr != 'Y') {
|
||||
avr910_set_addr(pgm, addr);
|
||||
}
|
||||
|
||||
report_progress (addr, max_addr, NULL);
|
||||
}
|
||||
|
||||
rval = addr * rd_size;
|
||||
}
|
||||
|
||||
if (PDATA(pgm)->use_blockmode == 1) {
|
||||
unsigned int addr = 0;
|
||||
unsigned int max_addr = n_bytes;
|
||||
int rd_size = 1;
|
||||
|
||||
/* check parameter syntax: only "flash" or "eeprom" is allowed */
|
||||
if (strcmp(m->desc, "flash") && strcmp(m->desc, "eeprom"))
|
||||
rval = -2;
|
||||
|
||||
/* use buffered mode */
|
||||
char cmd[4];
|
||||
int blocksize = PDATA(pgm)->buffersize;
|
||||
|
||||
cmd[0] = 'g';
|
||||
cmd[3] = toupper(m->desc[0]);
|
||||
|
||||
avr910_set_addr(pgm, addr);
|
||||
|
||||
while (addr < max_addr) {
|
||||
if ((max_addr - addr) < blocksize) {
|
||||
blocksize = max_addr - addr;
|
||||
};
|
||||
cmd[1] = (blocksize >> 8) & 0xff;
|
||||
cmd[2] = blocksize & 0xff;
|
||||
|
||||
avr910_send(pgm, cmd, 4);
|
||||
avr910_recv(pgm, (char *)&m->buf[addr], blocksize);
|
||||
|
||||
addr += blocksize;
|
||||
|
||||
report_progress (addr, max_addr, NULL);
|
||||
}
|
||||
|
||||
rval = addr * rd_size;
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/* Signature byte reads are always 3 bytes. */
|
||||
|
||||
static int avr910_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
|
||||
{
|
||||
unsigned char tmp;
|
||||
|
||||
if (m->size < 3) {
|
||||
fprintf(stderr, "%s: memsize too small for sig byte read", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
avr910_send(pgm, "s", 1);
|
||||
avr910_recv(pgm, (char *)m->buf, 3);
|
||||
/* Returned signature has wrong order. */
|
||||
tmp = m->buf[2];
|
||||
m->buf[2] = m->buf[0];
|
||||
m->buf[0] = tmp;
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
||||
void avr910_initpgm(PROGRAMMER * pgm)
|
||||
{
|
||||
strcpy(pgm->type, "avr910");
|
||||
|
||||
/*
|
||||
* mandatory functions
|
||||
*/
|
||||
pgm->initialize = avr910_initialize;
|
||||
pgm->display = avr910_display;
|
||||
pgm->enable = avr910_enable;
|
||||
pgm->disable = avr910_disable;
|
||||
pgm->program_enable = avr910_program_enable;
|
||||
pgm->chip_erase = avr910_chip_erase;
|
||||
pgm->cmd = avr910_cmd;
|
||||
pgm->open = avr910_open;
|
||||
pgm->close = avr910_close;
|
||||
|
||||
/*
|
||||
* optional functions
|
||||
*/
|
||||
|
||||
pgm->write_byte = avr910_write_byte;
|
||||
pgm->read_byte = avr910_read_byte;
|
||||
|
||||
pgm->paged_write = avr910_paged_write;
|
||||
pgm->paged_load = avr910_paged_load;
|
||||
|
||||
pgm->read_sig_bytes = avr910_read_sig_bytes;
|
||||
|
||||
pgm->parseextparams = avr910_parseextparms;
|
||||
pgm->setup = avr910_setup;
|
||||
pgm->teardown = avr910_teardown;
|
||||
}
|
||||
37
avrdude/avr910.h
Normal file
37
avrdude/avr910.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef avr910_h
|
||||
#define avr910_h
|
||||
|
||||
#include "avrpart.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void avr910_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* avr910_h */
|
||||
@@ -1,6 +1,6 @@
|
||||
.\"
|
||||
.\" avrdude - A Downloader/Uploader for AVR device programmers
|
||||
.\" Copyright (C) 2001, 2002, 2003 Joerg Wunsch
|
||||
.\" Copyright (C) 2001, 2002, 2003, 2005 - 2009 Joerg Wunsch
|
||||
.\"
|
||||
.\" This program is free software; you can redistribute it and/or modify
|
||||
.\" it under the terms of the GNU General Public License as published by
|
||||
@@ -19,7 +19,7 @@
|
||||
.\"
|
||||
.\" $Id$
|
||||
.\"
|
||||
.Dd DATE January 11, 2002
|
||||
.Dd DATE November 5, 2008
|
||||
.Os
|
||||
.Dt AVRDUDE 1
|
||||
.Sh NAME
|
||||
@@ -28,21 +28,27 @@
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Fl p Ar partno
|
||||
.Op Fl b Ar baudrate
|
||||
.Op Fl B Ar bitclock
|
||||
.Op Fl c Ar programmer-id
|
||||
.Op Fl C Ar config-file
|
||||
.Op Fl D
|
||||
.Op Fl e
|
||||
.Oo Fl E Ar exitspec Ns
|
||||
.Op \&, Ns Ar exitspec
|
||||
.Oc
|
||||
.Op Fl f Ar format
|
||||
.Op Fl F
|
||||
.Op Fl i Ar filename
|
||||
.Op Fl m Ar memtype
|
||||
.Op Fl o Ar filename
|
||||
.Op Fl i Ar delay
|
||||
.Op Fl n
|
||||
.Op Fl O
|
||||
.Op Fl P Ar port
|
||||
.Op Fl q
|
||||
.Op Fl s
|
||||
.Op Fl t
|
||||
.Op Fl u
|
||||
.Op Fl U Ar memtype:op:filename:filefmt
|
||||
.Op Fl v
|
||||
.Op Fl x Ar extended_param
|
||||
.Op Fl V
|
||||
.Op Fl y
|
||||
.Op Fl Y
|
||||
@@ -51,10 +57,18 @@
|
||||
is a program for downloading code and data to Atmel AVR
|
||||
microcontrollers.
|
||||
.Nm Avrdude
|
||||
supports Atmel's STK500 programmer as well as a simple hard-wired
|
||||
supports Atmel's STK500 programmer,
|
||||
Atmel's AVRISP and AVRISP mkII devices,
|
||||
Atmel's STK600,
|
||||
Atmel's JTAG ICE (both mkI and mkII, the latter also in ISP mode),
|
||||
programmers complying to AppNote AVR910 and AVR109 (including the Butterfly),
|
||||
as well as a simple hard-wired
|
||||
programmer connected directly to a
|
||||
.Xr ppi 4
|
||||
parallel port. In the simplest case, the hardware consists just of a
|
||||
or
|
||||
.Xr parport 4
|
||||
parallel port, or to a standard serial port.
|
||||
In the simplest case, the hardware consists just of a
|
||||
cable connecting the respective AVR signal lines to the parallel port.
|
||||
.Pp
|
||||
The MCU is programmed in
|
||||
@@ -70,20 +84,63 @@ and
|
||||
need to be connected to the parallel port. Optionally, some otherwise
|
||||
unused output pins of the parallel port can be used to supply power
|
||||
for the MCU part, so it is also possible to construct a passive
|
||||
standalone programming device. Some status LEDs indicating the
|
||||
stand-alone programming device. Some status LEDs indicating the
|
||||
current operating state of the programmer can be connected, and a
|
||||
signal is available to control a buffer/driver IC 74LS367 (or
|
||||
74HCT367). The latter can be useful to decouple the parallel port
|
||||
from the MCU when in-system programming is used.
|
||||
.Pp
|
||||
See the file
|
||||
.Pa ${PREFIX}/share/doc/avrdude/avrdude.pdf
|
||||
for a schematic of the
|
||||
.Xr ppi 4
|
||||
based programming hardware.
|
||||
A number of equally simple bit-bang programming adapters that connect
|
||||
to a serial port are supported as well, among them the popular
|
||||
Ponyprog serial adapter, and the DASA and DASA3 adapters that used to
|
||||
be supported by uisp(1).
|
||||
Note that these adapters are meant to be attached to a physical serial
|
||||
port.
|
||||
Connecting to a serial port emulated on top of USB is likely to not
|
||||
work at all, or to work abysmally slow.
|
||||
.Pp
|
||||
Atmel's STK500 programmer is also supported and connects to a serial
|
||||
port.
|
||||
Both, firmware versions 1.x and 2.x can be handled, but require a
|
||||
different programmer type specification (by now).
|
||||
Using firmware version 2, high-voltage programming is also supported,
|
||||
both parallel and serial
|
||||
(programmer types stk500pp and stk500hvsp).
|
||||
.Pp
|
||||
The Arduino (which is very similar to the STK500 1.x) is supported via
|
||||
its own programmer type specification ``arduino''.
|
||||
.Pp
|
||||
Atmel's STK600 programmer is supported in ISP and high-voltage
|
||||
programming modes, and connects through the USB.
|
||||
For ATxmega devices, the STK600 is supported in PDI mode.
|
||||
.Pp
|
||||
The simple serial programmer described in Atmel's application note
|
||||
AVR910, and the bootloader described in Atmel's application note
|
||||
AVR109 (which is also used by the AVR Butterfly evaluation board), are
|
||||
supported on a serial port.
|
||||
.Pp
|
||||
Atmel's JTAG ICE (both mkI and mkII) is supported as well to up- or download memory
|
||||
areas from/to an AVR target (no support for on-chip debugging).
|
||||
For the JTAG ICE mkII, JTAG, debugWire and ISP mode are supported.
|
||||
See below for the limitations of debugWire.
|
||||
.Pp
|
||||
The AVR Dragon is supported in all modes (ISP, JTAG, HVSP, PP, debugWire).
|
||||
When used in JTAG and debugWire mode, the AVR Dragon behaves similar to a
|
||||
JTAG ICE mkII, so all device-specific comments for that device
|
||||
will apply as well.
|
||||
When used in ISP mode, the AVR Dragon behaves similar to an
|
||||
AVRISP mkII (or JTAG ICE mkII in ISP mode), so all device-specific
|
||||
comments will apply there.
|
||||
In particular, the Dragon starts out with a rather fast ISP clock
|
||||
frequency, so the
|
||||
.Fl B Ar bitclock
|
||||
option might be required to achieve a stable ISP communication.
|
||||
.Pp
|
||||
The USBasp ISP and USBtinyISP adapters are also supported, provided
|
||||
.Nm avrdude
|
||||
has been compiled with libusb support.
|
||||
They both feature simple firwmare-only USB implementations, running on
|
||||
an ATmega8 (or ATmega88), or ATtiny2313, respectively.
|
||||
.Pp
|
||||
Input files can be provided, and output files can be written in
|
||||
different file formats, such as raw binary files containing the data
|
||||
@@ -100,7 +157,7 @@ can program the EEPROM and flash ROM memory cells of supported AVR
|
||||
parts. Where supported by the serial instruction set, fuse bits and
|
||||
lock bits can be programmed as well. These are implemented within
|
||||
.Nm
|
||||
as seperate memory types and can be programmed using data from a file
|
||||
as separate memory types and can be programmed using data from a file
|
||||
(see the
|
||||
.Fl m
|
||||
option) or from terminal mode (see the
|
||||
@@ -112,6 +169,9 @@ been code-protected previously, of course) and store the data in a
|
||||
file. Finally, a ``terminal'' mode is available that allows one to
|
||||
interactively communicate with the MCU, and to display or program
|
||||
individual memory cells.
|
||||
On the STK500 and STK600 programmer, several operational parameters (target supply
|
||||
voltage, target Aref voltage, master clock) can be examined and changed
|
||||
from within terminal mode as well.
|
||||
.Ss Options
|
||||
In order to control all the different operation modi, a number of options
|
||||
need to be specified to
|
||||
@@ -130,7 +190,9 @@ the format. Currently, the following MCU types are understood:
|
||||
.TS
|
||||
ll.
|
||||
\fBOption tag\fP \fBOfficial part name\fP
|
||||
t15 ATtiny15
|
||||
c128 AT90CAN128
|
||||
pwm2 AT90PWM2
|
||||
pwm3 AT90PWM3
|
||||
1200 AT90S1200
|
||||
2313 AT90S2313
|
||||
2333 AT90S2333
|
||||
@@ -140,17 +202,66 @@ t15 ATtiny15
|
||||
4434 AT90S4434
|
||||
8515 AT90S8515
|
||||
8535 AT90S8535
|
||||
m163 ATMEGA163
|
||||
m169 ATMEGA169
|
||||
m128 ATMEGA128
|
||||
m103 ATMEGA103
|
||||
m16 ATMEGA16
|
||||
m8 ATMEGA8
|
||||
m103 ATmega103
|
||||
m128 ATmega128
|
||||
m1280 ATmega1280
|
||||
m1281 ATmega1281
|
||||
m1284p ATmega1284P
|
||||
m128rfa1 ATmega128RFA1
|
||||
m16 ATmega16
|
||||
m161 ATmega161
|
||||
m162 ATmega162
|
||||
m163 ATmega163
|
||||
m164 ATmega164
|
||||
m169 ATmega169
|
||||
m2560 ATmega2560 (**)
|
||||
m2561 ATmega2561 (**)
|
||||
m32 ATmega32
|
||||
m324 ATmega324
|
||||
m329 ATmega329
|
||||
m3290 ATmega3290
|
||||
m48 ATmega48
|
||||
m64 ATmega64
|
||||
m640 ATmega640
|
||||
m644 ATmega644
|
||||
m649 ATmega649
|
||||
m6490 ATmega6490
|
||||
m8 ATmega8
|
||||
m8515 ATmega8515
|
||||
m8535 ATmega8535
|
||||
m88 ATmega88
|
||||
t12 ATtiny12
|
||||
t13 ATtiny13
|
||||
t15 ATtiny15
|
||||
t2313 ATtiny2313
|
||||
t25 ATtiny25
|
||||
t26 ATtiny26
|
||||
t45 ATtiny45
|
||||
t85 ATtiny85
|
||||
x128a1 ATxmega128A1
|
||||
x128a1d ATxmega128A1revD
|
||||
.TE
|
||||
.Bl -tag -width "(*) "
|
||||
.Bl -tag -width "(**) "
|
||||
.It "(*)"
|
||||
The AT90S2323 uses the same algorithm.
|
||||
The AT90S2323 and ATtiny22 use the same algorithm.
|
||||
.It "(**)"
|
||||
Flash addressing above 128 KB is not supported by all
|
||||
programming hardware. Known to work are jtag2, stk500v2,
|
||||
and bit-bang programmers.
|
||||
.El
|
||||
.It Fl b Ar baudrate
|
||||
Override the RS-232 connection baud rate specified in the respective
|
||||
programmer's entry of the configuration file.
|
||||
.It Fl B Ar bitclock
|
||||
Specify the bit clock period for the JTAG interface or the ISP clock (JTAG ICE only).
|
||||
The value is a floating-point number in microseconds.
|
||||
The default value of the JTAG ICE results in about 1 microsecond bit
|
||||
clock period, suitable for target MCUs running at 4 MHz clock and
|
||||
above.
|
||||
Unlike certain parameters in the STK500, the JTAG ICE resets all its
|
||||
parameters to default values when the programming software signs
|
||||
off from the ICE, so for MCUs running at lower clock speeds, this
|
||||
parameter must be specified on the command-line.
|
||||
.It Fl c Ar programmer-id
|
||||
Use the pin configuration specified by the argument. Pin
|
||||
configurations are read from the config file (see the
|
||||
@@ -175,11 +286,26 @@ submit a patch back to the author so that it can be incorporated for
|
||||
the next version). See the config file, located at
|
||||
.Pa ${PREFIX}/etc/avrdude.conf ,
|
||||
which contains a description of the format.
|
||||
.It Fl D
|
||||
Disable auto erase for flash. When the
|
||||
.Fl U
|
||||
option with flash memory is specified,
|
||||
.Nm
|
||||
will perform a chip erase before starting any of the programming
|
||||
operations, since it generally is a mistake to program the flash
|
||||
without performing an erase first. This option disables that.
|
||||
Auto erase is not used for ATxmega devices as these devices can
|
||||
use page erase before writing each page so no explicit chip erase
|
||||
is required.
|
||||
Note however that any page not affected by the current operation
|
||||
will retain its previous contents.
|
||||
.It Fl e
|
||||
Causes a chip erase to be executed. This will reset the contents of the
|
||||
flash ROM and EEPROM to the value
|
||||
.Ql 0xff ,
|
||||
and is basically a prerequisite command before the flash ROM can be
|
||||
and clear all lock bits.
|
||||
Except for ATxmega devices which can use page erase,
|
||||
it is basically a prerequisite command before the flash ROM can be
|
||||
reprogrammed again. The only exception would be if the new
|
||||
contents would exclusively cause bits to be programmed from the value
|
||||
.Ql 1
|
||||
@@ -238,26 +364,6 @@ pins of the parallel port down at program exit.
|
||||
Multiple
|
||||
.Ar exitspec
|
||||
arguments can be separated with commas.
|
||||
.It Fl f Ar format
|
||||
This option specifies the file format for the input or output files
|
||||
to be processed.
|
||||
.Ar Format
|
||||
can be one of:
|
||||
.Bl -tag -width sss
|
||||
.It Ar i
|
||||
Intel Hex
|
||||
.It Ar s
|
||||
Motorola S-record
|
||||
.It Ar r
|
||||
raw binary; little-endian byte order, in the case of the flash ROM data
|
||||
.It Ar a
|
||||
auto detect; valid for input only, and only if the input is not
|
||||
provided at
|
||||
.Em stdin .
|
||||
.El
|
||||
.Pp
|
||||
The default is to use auto detection for input files, and raw binary
|
||||
format for output files.
|
||||
.It Fl F
|
||||
Normally,
|
||||
.Nm
|
||||
@@ -266,36 +372,40 @@ reasonable before continuing. Since it can happen from time to time
|
||||
that a device has a broken (erased or overwritten) device signature
|
||||
but is otherwise operating normally, this options is provided to
|
||||
override the check.
|
||||
.It Fl i Ar filename
|
||||
Specifies the input file to be programmed into the MCU. Can be specified
|
||||
as
|
||||
.Ql \&-
|
||||
to use
|
||||
.Em stdin
|
||||
as the input.
|
||||
.It Fl m Ar memtype
|
||||
Specifies which program area of the MCU to read or write; allowable
|
||||
values depend on the MCU being programmed, but most support at least
|
||||
.Em eeprom
|
||||
for the EEPROM, and
|
||||
.Em flash
|
||||
for the flash ROM. Use the
|
||||
.Fl v
|
||||
option on the command line or the
|
||||
.Ar part
|
||||
command from terminal mode to display all the memory types supported
|
||||
by a particular device. The default is
|
||||
.Em flash .
|
||||
Also, for programmers like the Atmel STK500 and STK600 which can
|
||||
adjust parameters local to the programming tool (independent of an
|
||||
actual connection to a target controller), this option can be used
|
||||
together with
|
||||
.Fl t
|
||||
to continue in terminal mode.
|
||||
.It Fl i Ar delay
|
||||
For bitbang-type programmers, delay for approximately
|
||||
.Ar delay
|
||||
microseconds between each bit state change.
|
||||
If the host system is very fast, or the target runs off a slow clock
|
||||
(like a 32 kHz crystal, or the 128 kHz internal RC oscillator), this
|
||||
can become necessary to satisfy the requirement that the ISP clock
|
||||
frequency must not be higher than 1/4 of the CPU clock frequency.
|
||||
This is implemented as a spin-loop delay to allow even for very
|
||||
short delays.
|
||||
On Unix-style operating systems, the spin loop is initially calibrated
|
||||
against a system timer, so the number of microseconds might be rather
|
||||
realistic, assuming a constant system load while
|
||||
.Nm
|
||||
is running.
|
||||
On Win32 operating systems, a preconfigured number of cycles per
|
||||
microsecond is assumed that might be off a bit for very fast or very
|
||||
slow machines.
|
||||
.It Fl n
|
||||
No-write - disables actually writing data to the MCU (useful for debugging
|
||||
.Nm avrdude
|
||||
).
|
||||
.It Fl o Ar filename
|
||||
Specifies the name of the output file to write, and causes the respective
|
||||
memory area to be read from the MCU. Can be specified as
|
||||
.Ql \&-
|
||||
to write to
|
||||
.Em stdout .
|
||||
.It Fl O
|
||||
Perform a RC oscillator run-time calibration according to Atmel
|
||||
application note AVR053.
|
||||
This is only supported on the STK500v2, AVRISP mkII, and JTAG ICE mkII
|
||||
hardware.
|
||||
Note that the result will be stored in the EEPROM cell at address 0.
|
||||
.It Fl P Ar port
|
||||
Use
|
||||
.Ar port
|
||||
@@ -307,15 +417,208 @@ serial port, the
|
||||
.Pa /dev/cuaa0
|
||||
port is the default. If you need to use a different parallel or
|
||||
serial port, use this option to specify the alternate port name.
|
||||
.Pp
|
||||
On Win32 operating systems, the parallel ports are referred to as lpt1
|
||||
through lpt3, referring to the addresses 0x378, 0x278, and 0x3BC,
|
||||
respectively. If the parallel port can be accessed through a different
|
||||
address, this address can be specified directly, using the common C
|
||||
language notation (i. e., hexadecimal values are prefixed by
|
||||
.Ql 0x
|
||||
).
|
||||
.Pp
|
||||
For the JTAG ICE mkII, if
|
||||
.Nm
|
||||
has been configured with libusb support,
|
||||
.Ar port
|
||||
can alternatively be specified as
|
||||
.Pa usb Ns Op \&: Ns Ar serialno .
|
||||
This will cause
|
||||
.Nm
|
||||
to search a JTAG ICE mkII on USB.
|
||||
If
|
||||
.Ar serialno
|
||||
is also specified, it will be matched against the serial number read
|
||||
from any JTAG ICE mkII found on USB.
|
||||
The match is done after stripping any existing colons from the given
|
||||
serial number, and right-to-left, so only the least significant bytes
|
||||
from the serial number need to be given.
|
||||
.Pp
|
||||
As the AVRISP mkII device can only be talked to over USB, the very
|
||||
same method of specifying the port is required there.
|
||||
.Pp
|
||||
For the USB programmer "AVR-Doper" running in HID mode, the port must
|
||||
be specified as
|
||||
.Ar avrdoper.
|
||||
Libusb support is required on Unix but not on Windows. For more
|
||||
information about AVR-Doper see http://www.obdev.at/avrusb/avrdoper.html.
|
||||
.Pp
|
||||
For programmers that attach to a serial port using some kind of
|
||||
higher level protocol (as opposed to bit-bang style programmers),
|
||||
.Ar port
|
||||
can be specified as
|
||||
.Pa net Ns \&: Ns Ar host Ns \&: Ns Ar port .
|
||||
In this case, instead of trying to open a local device, a TCP
|
||||
network connection to (TCP)
|
||||
.Ar port
|
||||
on
|
||||
.Ar host
|
||||
is established.
|
||||
The remote endpoint is assumed to be a terminal or console server
|
||||
that connects the network stream to a local serial port where the
|
||||
actual programmer has been attached to.
|
||||
The port is assumed to be properly configured, for example using a
|
||||
transparent 8-bit data connection without parity at 115200 Baud
|
||||
for a STK500.
|
||||
.Em This feature is currently not implemented for Win32 systems.
|
||||
.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.
|
||||
.It Xo Fl U Ar memtype Ns
|
||||
.Ar \&: Ns Ar op Ns
|
||||
.Ar \&: Ns Ar filename Ns
|
||||
.Op \&: Ns Ar format
|
||||
.Xc
|
||||
Perform a memory operation as indicated. The
|
||||
.Ar memtype
|
||||
field specifies the memory type to operate on.
|
||||
The available memory types are device-dependent, the actual
|
||||
configuration can be viewed with the
|
||||
.Cm part
|
||||
command in terminal mode.
|
||||
Typically, a device's memory configuration at least contains
|
||||
the memory types
|
||||
.Ar flash
|
||||
and
|
||||
.Ar eeprom .
|
||||
All memory types currently known are:
|
||||
.Bl -tag -width "calibration" -compact
|
||||
.It calibration
|
||||
One or more bytes of RC oscillator calibration data.
|
||||
.It eeprom
|
||||
The EEPROM of the device.
|
||||
.It efuse
|
||||
The extended fuse byte.
|
||||
.It flash
|
||||
The flash ROM of the device.
|
||||
.It fuse
|
||||
The fuse byte in devices that have only a single fuse byte.
|
||||
.It hfuse
|
||||
The high fuse byte.
|
||||
.It lfuse
|
||||
The low fuse byte.
|
||||
.It lock
|
||||
The lock byte.
|
||||
.It signature
|
||||
The three device signature bytes (device ID).
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Ar op
|
||||
field specifies what operation to perform:
|
||||
.Bl -tag -width noreset
|
||||
.It Ar r
|
||||
read device memory and write to the specified file
|
||||
.It Ar w
|
||||
read data from the specified file and write to the device memory
|
||||
.It Ar v
|
||||
read data from both the device and the specified file and perform a verify
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Ar filename
|
||||
field indicates the name of the file to read or write.
|
||||
The
|
||||
.Ar format
|
||||
field is optional and contains the format of the file to read or
|
||||
write.
|
||||
.Ar Format
|
||||
can be one of:
|
||||
.Bl -tag -width sss
|
||||
.It Ar i
|
||||
Intel Hex
|
||||
.It Ar s
|
||||
Motorola S-record
|
||||
.It Ar r
|
||||
raw binary; little-endian byte order, in the case of the flash ROM data
|
||||
.It Ar m
|
||||
immediate; actual byte values specified on the command line, separated
|
||||
by commas or spaces. This is good for programming fuse bytes without
|
||||
having to create a single-byte file or enter terminal mode.
|
||||
.It Ar a
|
||||
auto detect; valid for input only, and only if the input is not
|
||||
provided at
|
||||
.Em stdin .
|
||||
.It Ar d
|
||||
decimal; this and the following formats are only valid on output.
|
||||
They generate one line of output for the respective memory section,
|
||||
forming a comma-separated list of the values.
|
||||
This can be particularly useful for subsequent processing, like for
|
||||
fuse bit settings.
|
||||
.It Ar h
|
||||
hexadecimal; each value will get the string
|
||||
.Em 0x
|
||||
prepended.
|
||||
.It Ar o
|
||||
octal; each value will get a
|
||||
.Em 0
|
||||
prepended unless it is less than 8 in which case it gets no prefix.
|
||||
.It Ar b
|
||||
binary; each value will get the string
|
||||
.Em 0b
|
||||
prepended.
|
||||
.El
|
||||
.Pp
|
||||
The default is to use auto detection for input files, and raw binary
|
||||
format for output files.
|
||||
Note that if
|
||||
.Ar filename
|
||||
contains a colon, the
|
||||
.Ar format
|
||||
field is no longer optional since the filename part following the colon
|
||||
would otherwise be misinterpreted as
|
||||
.Ar format .
|
||||
.Pp
|
||||
As an abbreviation, the form
|
||||
.Fl U Ar filename
|
||||
is equivalent to specifying
|
||||
.Fl U Em flash:w: Ns Ar filename Ns :a .
|
||||
This will only work if
|
||||
.Ar filename
|
||||
does not have a colon in it.
|
||||
.It Fl v
|
||||
Enable verbose output.
|
||||
.It Fl V
|
||||
Disable automatic verify check when uploading data.
|
||||
.It Fl x Ar extended_param
|
||||
Pass
|
||||
.Ar extended_param
|
||||
to the chosen programmer implementation as an extended parameter.
|
||||
The interpretation of the extended parameter depends on the
|
||||
programmer itself.
|
||||
See below for a list of programmers accepting extended parameters.
|
||||
.It Fl y
|
||||
Tells
|
||||
.Nm
|
||||
@@ -380,11 +683,72 @@ feature of an AVR part that is not directly supported by
|
||||
.Nm ,
|
||||
this command allows you to use it, even though
|
||||
.Nm
|
||||
does not implement the command.
|
||||
does not implement the command. When using direct SPI mode, up to 3 bytes
|
||||
can be omitted.
|
||||
.It Ar sig
|
||||
Display the device signature bytes.
|
||||
.It Ar spi
|
||||
Enter direct SPI mode. The
|
||||
.Em pgmled
|
||||
pin acts as slave select.
|
||||
.Em Only supported on parallel bitbang programmers.
|
||||
.It Ar part
|
||||
Display the current part settings.
|
||||
Display the current part settings and parameters. Includes chip
|
||||
specific information including all memory types supported by the
|
||||
device, read/write timing, etc.
|
||||
.It Ar pgm
|
||||
Return to programming mode (from direct SPI mode).
|
||||
.It Ar vtarg voltage
|
||||
Set the target's supply voltage to
|
||||
.Ar voltage
|
||||
Volts.
|
||||
.Em Only supported on the STK500 and STK600 programmer.
|
||||
.It Ar varef Oo Ar channel Oc Ar voltage
|
||||
Set the adjustable voltage source to
|
||||
.Ar voltage
|
||||
Volts.
|
||||
This voltage is normally used to drive the target's
|
||||
.Em Aref
|
||||
input on the STK500.
|
||||
On the Atmel STK600, two reference voltages are available, which
|
||||
can be selected by the optional
|
||||
.Ar channel
|
||||
argument (either 0 or 1).
|
||||
.Em Only supported on the STK500 and STK600 programmer.
|
||||
.It Ar fosc freq Ns Op M Ns \&| Ns k
|
||||
Set the master oscillator to
|
||||
.Ar freq
|
||||
Hz.
|
||||
An optional trailing letter
|
||||
.Ar \&M
|
||||
multiplies by 1E6, a trailing letter
|
||||
.Ar \&k
|
||||
by 1E3.
|
||||
.Em Only supported on the STK500 and STK600 programmer.
|
||||
.It Ar fosc off
|
||||
Turn the master oscillator off.
|
||||
.Em Only supported on the STK500 and STK600 programmer.
|
||||
.It Ar sck period
|
||||
.Em STK500 and STK600 programmer only:
|
||||
Set the SCK clock period to
|
||||
.Ar period
|
||||
microseconds.
|
||||
.Pp
|
||||
.Em JTAG ICE only:
|
||||
Set the JTAG ICE bit clock period to
|
||||
.Ar period
|
||||
microseconds.
|
||||
Note that unlike STK500 settings, this setting will be reverted to
|
||||
its default value (approximately 1 microsecond) when the programming
|
||||
software signs off from the JTAG ICE.
|
||||
This parameter can also be used on the JTAG ICE mkII to specify the
|
||||
ISP clock period when operating the ICE in ISP mode.
|
||||
.It Ar parms
|
||||
.Em STK500 and STK600 programmer only:
|
||||
Display the current voltage and master oscillator parameters.
|
||||
.Pp
|
||||
.Em JTAG ICE only:
|
||||
Display the current target supply voltage and JTAG bit clock rate/period.
|
||||
.It Ar \&?
|
||||
.It Ar help
|
||||
Give a short on-line summary of the available commands.
|
||||
@@ -406,6 +770,79 @@ ll.
|
||||
10 MISO (from MCU)
|
||||
18-25 GND
|
||||
.TE
|
||||
.Ss debugWire limitations
|
||||
The debugWire protocol is Atmel's proprietary one-wire (plus ground)
|
||||
protocol to allow an in-circuit emulation of the smaller AVR devices,
|
||||
using the
|
||||
.Ql /RESET
|
||||
line.
|
||||
DebugWire mode is initiated by activating the
|
||||
.Ql DWEN
|
||||
fuse, and then power-cycling the target.
|
||||
While this mode is mainly intented for debugging/emulation, it
|
||||
also offers limited programming capabilities.
|
||||
Effectively, the only memory areas that can be read or programmed
|
||||
in this mode are flash ROM and EEPROM.
|
||||
It is also possible to read out the signature.
|
||||
All other memory areas cannot be accessed.
|
||||
There is no
|
||||
.Em chip erase
|
||||
functionality in debugWire mode; instead, while reprogramming the
|
||||
flash ROM, each flash ROM page is erased right before updating it.
|
||||
This is done transparently by the JTAG ICE mkII (or AVR Dragon).
|
||||
The only way back from debugWire mode is to initiate a special
|
||||
sequence of commands to the JTAG ICE mkII (or AVR Dragon), so the
|
||||
debugWire mode will be temporarily disabled, and the target can
|
||||
be accessed using normal ISP programming.
|
||||
This sequence is automatically initiated by using the JTAG ICE mkII
|
||||
or AVR Dragon in ISP mode, when they detect that ISP mode cannot be
|
||||
entered.
|
||||
.Ss Programmers accepting extended parameters
|
||||
.Bl -tag -offset indent -width indent
|
||||
.It Ar JTAG ICE mkII
|
||||
.It Ar AVR Dragon
|
||||
When using the JTAG ICE mkII or AVR Dragon in JTAG mode, the
|
||||
following extended parameter is accepted:
|
||||
.Bl -tag -offset indent -width indent
|
||||
.It Ar jtagchain=UB,UA,BB,BA
|
||||
Setup the JTAG scan chain for
|
||||
.Ar UB
|
||||
units before,
|
||||
.Ar UA
|
||||
units after,
|
||||
.Ar BB
|
||||
bits before, and
|
||||
.Ar BA
|
||||
bits after the target AVR, respectively.
|
||||
Each AVR unit within the chain shifts by 4 bits.
|
||||
Other JTAG units might require a different bit shift count.
|
||||
.El
|
||||
.It Ar AVR910
|
||||
.Bl -tag -offset indent -width indent
|
||||
.It Ar devcode=VALUE
|
||||
Override the device code selection by using
|
||||
.Ar VALUE
|
||||
as the device code.
|
||||
The programmer is not queried for the list of supported
|
||||
device codes, and the specified
|
||||
.Ar VALUE
|
||||
is not verified but used directly within the
|
||||
.Ql T
|
||||
command sent to the programmer.
|
||||
.Ar VALUE
|
||||
can be specified using the conventional number notation of the
|
||||
C programming language.
|
||||
.El
|
||||
.Bl -tag -offset indent -width indent
|
||||
.It Ar no_blockmode
|
||||
Disables the default checking for block transfer capability.
|
||||
Use
|
||||
.Ar no_blockmode
|
||||
only if your
|
||||
.Ar AVR910
|
||||
programmer creates errors during initial sequence.
|
||||
.El
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -offset indent -width /dev/ppi0XXX
|
||||
.It Pa /dev/ppi0
|
||||
@@ -423,7 +860,31 @@ library
|
||||
Schematic of programming hardware
|
||||
.El
|
||||
.\" .Sh EXAMPLES
|
||||
.\" .Sh DIAGNOSTICS
|
||||
.Sh DIAGNOSTICS
|
||||
.Bd -literal
|
||||
avrdude: jtagmkII_setparm(): bad response to set parameter command: RSP_FAILED
|
||||
avrdude: jtagmkII_getsync(): ISP activation failed, trying debugWire
|
||||
avrdude: Target prepared for ISP, signed off.
|
||||
avrdude: Please restart avrdude without power-cycling the target.
|
||||
.Ed
|
||||
.Pp
|
||||
If the target AVR has been set up for debugWire mode (i. e. the
|
||||
.Em DWEN
|
||||
fuse is programmed), normal ISP connection attempts will fail as
|
||||
the
|
||||
.Em /RESET
|
||||
pin is not available.
|
||||
When using the JTAG ICE mkII in ISP mode, the message shown indicates
|
||||
that
|
||||
.Nm
|
||||
has guessed this condition, and tried to initiate a debugWire reset
|
||||
to the target.
|
||||
When successful, this will leave the target AVR in a state where it
|
||||
can respond to normal ISP communication again (until the next power
|
||||
cycle).
|
||||
Typically, the same command is going to be retried again immediately
|
||||
afterwards, and will then succeed connecting to the target using
|
||||
normal ISP communication.
|
||||
.Sh SEE ALSO
|
||||
.Xr avr-objcopy 1 ,
|
||||
.Xr ppi 4 ,
|
||||
@@ -441,4 +902,20 @@ This man page by
|
||||
.ie t J\(:org Wunsch.
|
||||
.el Joerg Wunsch.
|
||||
.Sh BUGS
|
||||
Please report bugs to avrdude-dev@nongnu.org.
|
||||
Please report bugs via
|
||||
.Dl "http://savannah.nongnu.org/bugs/?group=avrdude" .
|
||||
.Pp
|
||||
The JTAG ICE programmers currently cannot write to the flash ROM
|
||||
one byte at a time.
|
||||
For that reason, updating the flash ROM from terminal mode does not
|
||||
work.
|
||||
.Pp
|
||||
Page-mode programming the EEPROM through JTAG (i.e. through an
|
||||
.Fl U
|
||||
option) requires a prior chip erase.
|
||||
This is an inherent feature of the way JTAG EEPROM programming works.
|
||||
This also applies to the STK500 and STK600 in parallel programming mode.
|
||||
.Pp
|
||||
The USBasp and USBtinyISP drivers do not offer any option to distinguish multiple
|
||||
devices connected simultaneously, so effectively only a single device
|
||||
is supported.
|
||||
|
||||
13557
avrdude/avrdude.conf.in
13557
avrdude/avrdude.conf.in
File diff suppressed because it is too large
Load Diff
61
avrdude/avrdude.h
Normal file
61
avrdude/avrdude.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2007 Joerg Wunsch
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef avrdude_h
|
||||
#define avrdude_h
|
||||
|
||||
extern char * progname; /* name of program, for messages */
|
||||
extern char progbuf[]; /* spaces same length as progname */
|
||||
|
||||
extern int do_cycles; /* track erase-rewrite cycles (-y) */
|
||||
extern int ovsigck; /* override signature check (-F) */
|
||||
extern int verbose; /* verbosity level (-v, -vv, ...) */
|
||||
extern int quell_progress; /* quiteness level (-q, -qq) */
|
||||
|
||||
#if defined(WIN32NATIVE)
|
||||
|
||||
#include "ac_cfg.h"
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* usleep replacements */
|
||||
/* sleep Windows in ms, Unix usleep in us
|
||||
#define usleep(us) Sleep((us)<20000?20:us/1000)
|
||||
#define usleep(us) Sleep(us/1000)
|
||||
#define ANTIWARP 3
|
||||
#define usleep(us) Sleep(us/1000*ANTIWARP)
|
||||
*/
|
||||
int usleep(unsigned int us);
|
||||
|
||||
#if !defined(HAVE_GETTIMEOFDAY)
|
||||
struct timezone;
|
||||
int gettimeofday(struct timeval *tv, struct timezone *tz);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* HAVE_GETTIMEOFDAY */
|
||||
|
||||
#endif /* defined(WIN32NATIVE) */
|
||||
|
||||
#endif
|
||||
Binary file not shown.
@@ -5,6 +5,11 @@
|
||||
## @configure_input@
|
||||
##
|
||||
|
||||
%define debug_package %{nil}
|
||||
|
||||
%define _with_docs 1
|
||||
%{?_without_docs: %define _with_docs 0}
|
||||
|
||||
Summary: AVRDUDE is software for programming Atmel AVR Microcontrollers.
|
||||
Name: avrdude
|
||||
Version: @VERSION@
|
||||
@@ -18,12 +23,14 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-root
|
||||
%description
|
||||
AVRDUDE is software for programming Atmel AVR Microcontrollers.
|
||||
|
||||
%if %{_with_docs}
|
||||
## The avrdude-docs subpackage
|
||||
%package docs
|
||||
Summary: Documentation for AVRDUDE.
|
||||
Group: Documentation
|
||||
%description docs
|
||||
Documentation for avrdude in html, postscript and pdf formats.
|
||||
Documentation for avrdude in info, html, postscript and pdf formats.
|
||||
%endif
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
@@ -31,7 +38,12 @@ Documentation for avrdude in html, postscript and pdf formats.
|
||||
%build
|
||||
|
||||
./configure --prefix=%{_prefix} --sysconfdir=/etc --mandir=%{_mandir} \
|
||||
--infodir=%{_infodir}
|
||||
--infodir=%{_infodir} \
|
||||
%if %{_with_docs}
|
||||
--enable-doc=yes
|
||||
%else
|
||||
--enable-doc=no
|
||||
%endif
|
||||
|
||||
make
|
||||
|
||||
@@ -43,36 +55,54 @@ make prefix=$RPM_BUILD_ROOT%{_prefix} \
|
||||
infodir=$RPM_BUILD_ROOT%{_infodir} \
|
||||
install
|
||||
|
||||
rm -rf $RPM_BUILD_ROOT%{_datadir}/doc/%{name}-%{version}
|
||||
rm -f $RPM_BUILD_ROOT%{_infodir}/dir
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%post
|
||||
%if %{_with_docs}
|
||||
%post docs
|
||||
[ -f %{_infodir}/avrdude.info ] && \
|
||||
/sbin/install-info %{_infodir}/avrdude.info %{_infodir}/dir || :
|
||||
[ -f %{_infodir}/avrdude.info.gz ] && \
|
||||
/sbin/install-info %{_infodir}/avrdude.info.gz %{_infodir}/dir || :
|
||||
|
||||
%preun
|
||||
%preun docs
|
||||
if [ $1 = 0 ]; then
|
||||
[ -f %{_infodir}/avrdude.info ] && \
|
||||
/sbin/install-info --delete %{_infodir}/avrdude.info %{_infodir}/dir || :
|
||||
[ -f %{_infodir}/avrdude.info.gz ] && \
|
||||
/sbin/install-info --delete %{_infodir}/avrdude.info.gz %{_infodir}/dir || :
|
||||
fi
|
||||
%endif
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%{_prefix}/bin/avrdude
|
||||
%{_mandir}/man1/avrdude.1.gz
|
||||
%{_infodir}/*info*
|
||||
%attr(0644,root,root) %config /etc/avrdude.conf
|
||||
|
||||
%if %{_with_docs}
|
||||
%files docs
|
||||
%doc doc/avrdude-html
|
||||
%doc %{_infodir}/*info*
|
||||
%doc doc/avrdude-html/*.html
|
||||
%doc doc/TODO
|
||||
%doc doc/avrdude.ps
|
||||
%doc doc/avrdude.pdf
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Fri Sep 23 2005 Galen Seitz <galens@seitzassoc.com>
|
||||
- Default to enable-doc=yes during configure.
|
||||
- Move info file to docs package.
|
||||
- Make building of docs package conditional. Basic idea copied from avr-gcc.
|
||||
|
||||
* Wed Aug 27 2003 Theodore A. Roth <troth@openavr.org>
|
||||
[Thanks to Artur Lipowski <LAL@pro.onet.pl>]
|
||||
- Do not build debug package.
|
||||
- Remove files not packaged to quell RH9 rpmbuild complaints.
|
||||
|
||||
* Wed Mar 05 2003 Theodore A. Roth <troth@openavr.org>
|
||||
- Add docs sub-package.
|
||||
- Add %post and %preun scriptlets for handling info files.
|
||||
|
||||
547
avrdude/avrpart.c
Normal file
547
avrdude/avrpart.c
Normal file
@@ -0,0 +1,547 @@
|
||||
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2006 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "avrpart.h"
|
||||
#include "pindefs.h"
|
||||
|
||||
/***
|
||||
*** Elementary functions dealing with OPCODE structures
|
||||
***/
|
||||
|
||||
OPCODE * avr_new_opcode(void)
|
||||
{
|
||||
OPCODE * m;
|
||||
|
||||
m = (OPCODE *)malloc(sizeof(*m));
|
||||
if (m == NULL) {
|
||||
fprintf(stderr, "avr_new_opcode(): out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(m, 0, sizeof(*m));
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* avr_set_bits()
|
||||
*
|
||||
* Set instruction bits in the specified command based on the opcode.
|
||||
*/
|
||||
int avr_set_bits(OPCODE * op, unsigned char * cmd)
|
||||
{
|
||||
int i, j, bit;
|
||||
unsigned char mask;
|
||||
|
||||
for (i=0; i<32; i++) {
|
||||
if (op->bit[i].type == AVR_CMDBIT_VALUE) {
|
||||
j = 3 - i / 8;
|
||||
bit = i % 8;
|
||||
mask = 1 << bit;
|
||||
if (op->bit[i].value)
|
||||
cmd[j] = cmd[j] | mask;
|
||||
else
|
||||
cmd[j] = cmd[j] & ~mask;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* avr_set_addr()
|
||||
*
|
||||
* Set address bits in the specified command based on the opcode, and
|
||||
* the address.
|
||||
*/
|
||||
int avr_set_addr(OPCODE * op, unsigned char * cmd, unsigned long addr)
|
||||
{
|
||||
int i, j, bit;
|
||||
unsigned long value;
|
||||
unsigned char mask;
|
||||
|
||||
for (i=0; i<32; i++) {
|
||||
if (op->bit[i].type == AVR_CMDBIT_ADDRESS) {
|
||||
j = 3 - i / 8;
|
||||
bit = i % 8;
|
||||
mask = 1 << bit;
|
||||
value = addr >> op->bit[i].bitno & 0x01;
|
||||
if (value)
|
||||
cmd[j] = cmd[j] | mask;
|
||||
else
|
||||
cmd[j] = cmd[j] & ~mask;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* avr_set_input()
|
||||
*
|
||||
* Set input data bits in the specified command based on the opcode,
|
||||
* and the data byte.
|
||||
*/
|
||||
int avr_set_input(OPCODE * op, unsigned char * cmd, unsigned char data)
|
||||
{
|
||||
int i, j, bit;
|
||||
unsigned char value;
|
||||
unsigned char mask;
|
||||
|
||||
for (i=0; i<32; i++) {
|
||||
if (op->bit[i].type == AVR_CMDBIT_INPUT) {
|
||||
j = 3 - i / 8;
|
||||
bit = i % 8;
|
||||
mask = 1 << bit;
|
||||
value = data >> op->bit[i].bitno & 0x01;
|
||||
if (value)
|
||||
cmd[j] = cmd[j] | mask;
|
||||
else
|
||||
cmd[j] = cmd[j] & ~mask;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* avr_get_output()
|
||||
*
|
||||
* Retreive output data bits from the command results based on the
|
||||
* opcode data.
|
||||
*/
|
||||
int avr_get_output(OPCODE * op, unsigned char * res, unsigned char * data)
|
||||
{
|
||||
int i, j, bit;
|
||||
unsigned char value;
|
||||
unsigned char mask;
|
||||
|
||||
for (i=0; i<32; i++) {
|
||||
if (op->bit[i].type == AVR_CMDBIT_OUTPUT) {
|
||||
j = 3 - i / 8;
|
||||
bit = i % 8;
|
||||
mask = 1 << bit;
|
||||
value = ((res[j] & mask) >> bit) & 0x01;
|
||||
value = value << op->bit[i].bitno;
|
||||
if (value)
|
||||
*data = *data | value;
|
||||
else
|
||||
*data = *data & ~value;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static char * avr_op_str(int op)
|
||||
{
|
||||
switch (op) {
|
||||
case AVR_OP_READ : return "READ"; break;
|
||||
case AVR_OP_WRITE : return "WRITE"; break;
|
||||
case AVR_OP_READ_LO : return "READ_LO"; break;
|
||||
case AVR_OP_READ_HI : return "READ_HI"; break;
|
||||
case AVR_OP_WRITE_LO : return "WRITE_LO"; break;
|
||||
case AVR_OP_WRITE_HI : return "WRITE_HI"; break;
|
||||
case AVR_OP_LOADPAGE_LO : return "LOADPAGE_LO"; break;
|
||||
case AVR_OP_LOADPAGE_HI : return "LOADPAGE_HI"; break;
|
||||
case AVR_OP_LOAD_EXT_ADDR : return "LOAD_EXT_ADDR"; break;
|
||||
case AVR_OP_WRITEPAGE : return "WRITEPAGE"; break;
|
||||
case AVR_OP_CHIP_ERASE : return "CHIP_ERASE"; break;
|
||||
case AVR_OP_PGM_ENABLE : return "PGM_ENABLE"; break;
|
||||
default : return "<unknown opcode>"; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static char * bittype(int type)
|
||||
{
|
||||
switch (type) {
|
||||
case AVR_CMDBIT_IGNORE : return "IGNORE"; break;
|
||||
case AVR_CMDBIT_VALUE : return "VALUE"; break;
|
||||
case AVR_CMDBIT_ADDRESS : return "ADDRESS"; break;
|
||||
case AVR_CMDBIT_INPUT : return "INPUT"; break;
|
||||
case AVR_CMDBIT_OUTPUT : return "OUTPUT"; break;
|
||||
default : return "<unknown bit type>"; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***
|
||||
*** Elementary functions dealing with AVRMEM structures
|
||||
***/
|
||||
|
||||
AVRMEM * avr_new_memtype(void)
|
||||
{
|
||||
AVRMEM * m;
|
||||
|
||||
m = (AVRMEM *)malloc(sizeof(*m));
|
||||
if (m == NULL) {
|
||||
fprintf(stderr, "avr_new_memtype(): out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(m, 0, sizeof(*m));
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Allocate and initialize memory buffers for each of the device's
|
||||
* defined memory regions.
|
||||
*/
|
||||
int avr_initmem(AVRPART * p)
|
||||
{
|
||||
LNODEID ln;
|
||||
AVRMEM * m;
|
||||
|
||||
for (ln=lfirst(p->mem); ln; ln=lnext(ln)) {
|
||||
m = ldata(ln);
|
||||
m->buf = (unsigned char *) malloc(m->size);
|
||||
if (m->buf == NULL) {
|
||||
fprintf(stderr, "%s: can't alloc buffer for %s size of %d bytes\n",
|
||||
progname, m->desc, m->size);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
AVRMEM * avr_dup_mem(AVRMEM * m)
|
||||
{
|
||||
AVRMEM * n;
|
||||
|
||||
n = avr_new_memtype();
|
||||
|
||||
*n = *m;
|
||||
|
||||
n->buf = (unsigned char *)malloc(n->size);
|
||||
if (n->buf == NULL) {
|
||||
fprintf(stderr,
|
||||
"avr_dup_mem(): out of memory (memsize=%d)\n",
|
||||
n->size);
|
||||
exit(1);
|
||||
}
|
||||
memset(n->buf, 0, n->size);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
AVRMEM * avr_locate_mem(AVRPART * p, char * desc)
|
||||
{
|
||||
AVRMEM * m, * match;
|
||||
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;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void avr_mem_display(const char * prefix, FILE * f, AVRMEM * m, int type,
|
||||
int verbose)
|
||||
{
|
||||
int i, j;
|
||||
char * optr;
|
||||
|
||||
if (m == NULL) {
|
||||
fprintf(f,
|
||||
"%s Block Poll Page Polled\n"
|
||||
"%sMemory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack\n"
|
||||
"%s----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------\n",
|
||||
prefix, prefix, prefix);
|
||||
}
|
||||
else {
|
||||
if (verbose > 2) {
|
||||
fprintf(f,
|
||||
"%s Block Poll Page Polled\n"
|
||||
"%sMemory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack\n"
|
||||
"%s----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------\n",
|
||||
prefix, prefix, prefix);
|
||||
}
|
||||
fprintf(f,
|
||||
"%s%-11s %4d %5d %5d %4d %-6s %6d %4d %6d %5d %5d 0x%02x 0x%02x\n",
|
||||
prefix, m->desc, m->mode, m->delay, m->blocksize, m->pollindex,
|
||||
m->paged ? "yes" : "no",
|
||||
m->size,
|
||||
m->page_size,
|
||||
m->num_pages,
|
||||
m->min_write_delay,
|
||||
m->max_write_delay,
|
||||
m->readback[0],
|
||||
m->readback[1]);
|
||||
if (verbose > 4) {
|
||||
fprintf(stderr,
|
||||
"%s Memory Ops:\n"
|
||||
"%s Oeration Inst Bit Bit Type Bitno Value\n"
|
||||
"%s ----------- -------- -------- ----- -----\n",
|
||||
prefix, prefix, prefix);
|
||||
for (i=0; i<AVR_OP_MAX; i++) {
|
||||
if (m->op[i]) {
|
||||
for (j=31; j>=0; j--) {
|
||||
if (j==31)
|
||||
optr = avr_op_str(i);
|
||||
else
|
||||
optr = " ";
|
||||
fprintf(f,
|
||||
"%s %-11s %8d %8s %5d %5d\n",
|
||||
prefix, optr, j,
|
||||
bittype(m->op[i]->bit[j].type),
|
||||
m->op[i]->bit[j].bitno,
|
||||
m->op[i]->bit[j].value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Elementary functions dealing with AVRPART structures
|
||||
*/
|
||||
|
||||
|
||||
AVRPART * avr_new_part(void)
|
||||
{
|
||||
AVRPART * p;
|
||||
|
||||
p = (AVRPART *)malloc(sizeof(AVRPART));
|
||||
if (p == NULL) {
|
||||
fprintf(stderr, "new_part(): out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(p, 0, sizeof(*p));
|
||||
|
||||
p->id[0] = 0;
|
||||
p->desc[0] = 0;
|
||||
p->reset_disposition = RESET_DEDICATED;
|
||||
p->retry_pulse = PIN_AVR_SCK;
|
||||
p->flags = AVRPART_SERIALOK | AVRPART_PARALLELOK | AVRPART_ENABLEPAGEPROGRAMMING;
|
||||
p->config_file[0] = 0;
|
||||
p->lineno = 0;
|
||||
memset(p->signature, 0xFF, 3);
|
||||
p->ctl_stack_type = CTL_STACK_NONE;
|
||||
|
||||
p->mem = lcreat(NULL, 0);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
AVRPART * avr_dup_part(AVRPART * d)
|
||||
{
|
||||
AVRPART * p;
|
||||
LISTID save;
|
||||
LNODEID ln;
|
||||
|
||||
p = avr_new_part();
|
||||
save = p->mem;
|
||||
|
||||
*p = *d;
|
||||
|
||||
p->mem = save;
|
||||
|
||||
for (ln=lfirst(d->mem); ln; ln=lnext(ln)) {
|
||||
ladd(p->mem, avr_dup_mem(ldata(ln)));
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
AVRPART * locate_part(LISTID parts, char * partdesc)
|
||||
{
|
||||
LNODEID ln1;
|
||||
AVRPART * p = NULL;
|
||||
int found;
|
||||
|
||||
found = 0;
|
||||
|
||||
for (ln1=lfirst(parts); ln1 && !found; ln1=lnext(ln1)) {
|
||||
p = ldata(ln1);
|
||||
if ((strcasecmp(partdesc, p->id) == 0) ||
|
||||
(strcasecmp(partdesc, p->desc) == 0))
|
||||
found = 1;
|
||||
}
|
||||
|
||||
if (found)
|
||||
return p;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AVRPART * locate_part_by_avr910_devcode(LISTID parts, int devcode)
|
||||
{
|
||||
LNODEID ln1;
|
||||
AVRPART * p = NULL;
|
||||
|
||||
for (ln1=lfirst(parts); ln1; ln1=lnext(ln1)) {
|
||||
p = ldata(ln1);
|
||||
if (p->avr910_devcode == devcode)
|
||||
return p;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate over the list of avrparts given as "avrparts", and
|
||||
* call the callback function cb for each entry found. cb is being
|
||||
* passed the following arguments:
|
||||
* . the name of the avrpart (for -p)
|
||||
* . the descriptive text given in the config file
|
||||
* . the name of the config file this avrpart has been defined in
|
||||
* . the line number of the config file this avrpart has been defined at
|
||||
* . the "cookie" passed into walk_avrparts() (opaque client data)
|
||||
*/
|
||||
void walk_avrparts(LISTID avrparts, walk_avrparts_cb cb, void *cookie)
|
||||
{
|
||||
LNODEID ln1;
|
||||
AVRPART * p;
|
||||
|
||||
for (ln1 = lfirst(avrparts); ln1; ln1 = lnext(ln1)) {
|
||||
p = ldata(ln1);
|
||||
cb(p->id, p->desc, p->config_file, p->lineno, cookie);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static char * reset_disp_str(int r)
|
||||
{
|
||||
switch (r) {
|
||||
case RESET_DEDICATED : return "dedicated";
|
||||
case RESET_IO : return "possible i/o";
|
||||
default : return "<invalid>";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static char * pin_name(int pinno)
|
||||
{
|
||||
switch (pinno) {
|
||||
case PIN_AVR_RESET : return "RESET";
|
||||
case PIN_AVR_MISO : return "MISO";
|
||||
case PIN_AVR_MOSI : return "MOSI";
|
||||
case PIN_AVR_SCK : return "SCK";
|
||||
default : return "<unknown>";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void avr_display(FILE * f, AVRPART * p, const char * prefix, int verbose)
|
||||
{
|
||||
int i;
|
||||
char * buf;
|
||||
const char * px;
|
||||
LNODEID ln;
|
||||
AVRMEM * m;
|
||||
|
||||
fprintf(f,
|
||||
"%sAVR Part : %s\n"
|
||||
"%sChip Erase delay : %d us\n"
|
||||
"%sPAGEL : P%02X\n"
|
||||
"%sBS2 : P%02X\n"
|
||||
"%sRESET disposition : %s\n"
|
||||
"%sRETRY pulse : %s\n"
|
||||
"%sserial program mode : %s\n"
|
||||
"%sparallel program mode : %s\n"
|
||||
"%sTimeout : %d\n"
|
||||
"%sStabDelay : %d\n"
|
||||
"%sCmdexeDelay : %d\n"
|
||||
"%sSyncLoops : %d\n"
|
||||
"%sByteDelay : %d\n"
|
||||
"%sPollIndex : %d\n"
|
||||
"%sPollValue : 0x%02x\n"
|
||||
"%sMemory Detail :\n\n",
|
||||
prefix, p->desc,
|
||||
prefix, p->chip_erase_delay,
|
||||
prefix, p->pagel,
|
||||
prefix, p->bs2,
|
||||
prefix, reset_disp_str(p->reset_disposition),
|
||||
prefix, pin_name(p->retry_pulse),
|
||||
prefix, (p->flags & AVRPART_SERIALOK) ? "yes" : "no",
|
||||
prefix, (p->flags & AVRPART_PARALLELOK) ?
|
||||
((p->flags & AVRPART_PSEUDOPARALLEL) ? "psuedo" : "yes") : "no",
|
||||
prefix, p->timeout,
|
||||
prefix, p->stabdelay,
|
||||
prefix, p->cmdexedelay,
|
||||
prefix, p->synchloops,
|
||||
prefix, p->bytedelay,
|
||||
prefix, p->pollindex,
|
||||
prefix, p->pollvalue,
|
||||
prefix);
|
||||
|
||||
px = prefix;
|
||||
i = strlen(prefix) + 5;
|
||||
buf = (char *)malloc(i);
|
||||
if (buf == NULL) {
|
||||
/* ugh, this is not important enough to bail, just ignore it */
|
||||
}
|
||||
else {
|
||||
strcpy(buf, prefix);
|
||||
strcat(buf, " ");
|
||||
px = buf;
|
||||
}
|
||||
|
||||
if (verbose <= 2) {
|
||||
avr_mem_display(px, f, NULL, 0, verbose);
|
||||
}
|
||||
for (ln=lfirst(p->mem); ln; ln=lnext(ln)) {
|
||||
m = ldata(ln);
|
||||
avr_mem_display(px, f, m, i, verbose);
|
||||
}
|
||||
|
||||
if (buf)
|
||||
free(buf);
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2003 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2003-2004 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2006 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -19,13 +20,14 @@
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef __avrpart_h__
|
||||
#define __avrpart_h__
|
||||
#ifndef avrpart_h
|
||||
#define avrpart_h
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "lists.h"
|
||||
|
||||
|
||||
/*
|
||||
* AVR serial programming instructions
|
||||
*/
|
||||
@@ -38,6 +40,7 @@ enum {
|
||||
AVR_OP_WRITE_HI,
|
||||
AVR_OP_LOADPAGE_LO,
|
||||
AVR_OP_LOADPAGE_HI,
|
||||
AVR_OP_LOAD_EXT_ADDR,
|
||||
AVR_OP_WRITEPAGE,
|
||||
AVR_OP_CHIP_ERASE,
|
||||
AVR_OP_PGM_ENABLE,
|
||||
@@ -58,6 +61,12 @@ enum { /* these are assigned to reset_disposition of AVRPART */
|
||||
RESET_IO /* reset pin might be configured as an I/O pin */
|
||||
};
|
||||
|
||||
enum ctl_stack_t {
|
||||
CTL_STACK_NONE, /* no control stack defined */
|
||||
CTL_STACK_PP, /* parallel programming control stack */
|
||||
CTL_STACK_HVSP /* high voltage serial programming control stack */
|
||||
};
|
||||
|
||||
/*
|
||||
* serial programming instruction bit specifications
|
||||
*/
|
||||
@@ -75,21 +84,72 @@ typedef struct opcode {
|
||||
#define AVRPART_SERIALOK 0x0001 /* part supports serial programming */
|
||||
#define AVRPART_PARALLELOK 0x0002 /* part supports parallel programming */
|
||||
#define AVRPART_PSEUDOPARALLEL 0x0004 /* part has pseudo parallel support */
|
||||
#define AVRPART_HAS_JTAG 0x0008 /* part has a JTAG i/f */
|
||||
#define AVRPART_ALLOWFULLPAGEBITSTREAM 0x0010 /* JTAG ICE mkII param. */
|
||||
#define AVRPART_ENABLEPAGEPROGRAMMING 0x0020 /* JTAG ICE mkII param. */
|
||||
#define AVRPART_HAS_DW 0x0040 /* part has a debugWire i/f */
|
||||
#define AVRPART_HAS_PDI 0x0080 /* part has PDI i/f rather than ISP (ATxmega) */
|
||||
|
||||
#define AVR_DESCLEN 64
|
||||
#define AVR_IDLEN 32
|
||||
#define CTL_STACK_SIZE 32
|
||||
#define FLASH_INSTR_SIZE 3
|
||||
#define EEPROM_INSTR_SIZE 20
|
||||
typedef struct avrpart {
|
||||
char desc[AVR_DESCLEN]; /* long part name */
|
||||
char id[AVR_IDLEN]; /* short part name */
|
||||
int devicecode; /* Atmel STK500 device code */
|
||||
int stk500_devcode; /* stk500 device code */
|
||||
int avr910_devcode; /* avr910 device code */
|
||||
int chip_erase_delay; /* microseconds */
|
||||
unsigned char pagel; /* for parallel programming */
|
||||
unsigned char bs2; /* for parallel programming */
|
||||
unsigned char signature[3]; /* expected value of signature bytes */
|
||||
int reset_disposition; /* see RESET_ enums */
|
||||
int retry_pulse; /* retry program enable by pulsing
|
||||
this pin (PIN_AVR_*) */
|
||||
unsigned flags; /* see AVRPART_ masks */
|
||||
|
||||
int timeout; /* stk500 v2 xml file parameter */
|
||||
int stabdelay; /* stk500 v2 xml file parameter */
|
||||
int cmdexedelay; /* stk500 v2 xml file parameter */
|
||||
int synchloops; /* stk500 v2 xml file parameter */
|
||||
int bytedelay; /* stk500 v2 xml file parameter */
|
||||
int pollindex; /* stk500 v2 xml file parameter */
|
||||
unsigned char pollvalue; /* stk500 v2 xml file parameter */
|
||||
int predelay; /* stk500 v2 xml file parameter */
|
||||
int postdelay; /* stk500 v2 xml file parameter */
|
||||
int pollmethod; /* stk500 v2 xml file parameter */
|
||||
|
||||
enum ctl_stack_t ctl_stack_type; /* what to use the ctl stack for */
|
||||
unsigned char controlstack[CTL_STACK_SIZE]; /* stk500v2 PP/HVSP ctl stack */
|
||||
unsigned char flash_instr[FLASH_INSTR_SIZE]; /* flash instructions (debugWire, JTAG) */
|
||||
unsigned char eeprom_instr[EEPROM_INSTR_SIZE]; /* EEPROM instructions (debugWire, JTAG) */
|
||||
|
||||
int hventerstabdelay; /* stk500 v2 hv mode parameter */
|
||||
int progmodedelay; /* stk500 v2 hv mode parameter */
|
||||
int latchcycles; /* stk500 v2 hv mode parameter */
|
||||
int togglevtg; /* stk500 v2 hv mode parameter */
|
||||
int poweroffdelay; /* stk500 v2 hv mode parameter */
|
||||
int resetdelayms; /* stk500 v2 hv mode parameter */
|
||||
int resetdelayus; /* stk500 v2 hv mode parameter */
|
||||
int hvleavestabdelay; /* stk500 v2 hv mode parameter */
|
||||
int resetdelay; /* stk500 v2 hv mode parameter */
|
||||
int chiperasepulsewidth; /* stk500 v2 hv mode parameter */
|
||||
int chiperasepolltimeout; /* stk500 v2 hv mode parameter */
|
||||
int chiperasetime; /* stk500 v2 hv mode parameter */
|
||||
int programfusepulsewidth; /* stk500 v2 hv mode parameter */
|
||||
int programfusepolltimeout; /* stk500 v2 hv mode parameter */
|
||||
int programlockpulsewidth; /* stk500 v2 hv mode parameter */
|
||||
int programlockpolltimeout; /* stk500 v2 hv mode parameter */
|
||||
int synchcycles; /* stk500 v2 hv mode parameter */
|
||||
int hvspcmdexedelay; /* stk500 v2 xml file parameter */
|
||||
|
||||
unsigned char idr; /* JTAG ICE mkII XML file parameter */
|
||||
unsigned char rampz; /* JTAG ICE mkII XML file parameter */
|
||||
unsigned char spmcr; /* JTAG ICE mkII XML file parameter */
|
||||
unsigned short eecr; /* JTAC ICE mkII XML file parameter */
|
||||
unsigned int nvm_base; /* Base address of NVM controller in ATxmega devices */
|
||||
|
||||
OPCODE * op[AVR_OP_MAX]; /* opcodes */
|
||||
|
||||
LISTID mem; /* avr memory definitions */
|
||||
@@ -104,6 +164,7 @@ typedef struct avrmem {
|
||||
int size; /* total memory size in bytes */
|
||||
int page_size; /* size of memory page (if page addressed) */
|
||||
int num_pages; /* number of pages (if page addressed) */
|
||||
unsigned int offset; /* offset in IO memory (ATxmega) */
|
||||
int min_write_delay; /* microseconds */
|
||||
int max_write_delay; /* microseconds */
|
||||
int pwroff_after_write; /* after this memory type is written to,
|
||||
@@ -111,8 +172,50 @@ typedef struct avrmem {
|
||||
back on, see errata
|
||||
http://www.atmel.com/atmel/acrobat/doc1280.pdf */
|
||||
unsigned char readback[2]; /* polled read-back values */
|
||||
|
||||
int mode; /* stk500 v2 xml file parameter */
|
||||
int delay; /* stk500 v2 xml file parameter */
|
||||
int blocksize; /* stk500 v2 xml file parameter */
|
||||
int readsize; /* stk500 v2 xml file parameter */
|
||||
int pollindex; /* stk500 v2 xml file parameter */
|
||||
|
||||
unsigned char * buf; /* pointer to memory buffer */
|
||||
OPCODE * op[AVR_OP_MAX]; /* opcodes */
|
||||
} AVRMEM;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Functions for OPCODE structures */
|
||||
OPCODE * avr_new_opcode(void);
|
||||
int avr_set_bits(OPCODE * op, unsigned char * cmd);
|
||||
int avr_set_addr(OPCODE * op, unsigned char * cmd, unsigned long addr);
|
||||
int avr_set_input(OPCODE * op, unsigned char * cmd, unsigned char data);
|
||||
int avr_get_output(OPCODE * op, unsigned char * res, unsigned char * data);
|
||||
|
||||
/* Functions for AVRMEM structures */
|
||||
AVRMEM * avr_new_memtype(void);
|
||||
int avr_initmem(AVRPART * p);
|
||||
AVRMEM * avr_dup_mem(AVRMEM * m);
|
||||
AVRMEM * avr_locate_mem(AVRPART * p, char * desc);
|
||||
void avr_mem_display(const char * prefix, FILE * f, AVRMEM * m, int type,
|
||||
int verbose);
|
||||
|
||||
/* Functions for AVRPART structures */
|
||||
AVRPART * avr_new_part(void);
|
||||
AVRPART * avr_dup_part(AVRPART * d);
|
||||
AVRPART * locate_part(LISTID parts, char * partdesc);
|
||||
AVRPART * locate_part_by_avr910_devcode(LISTID parts, int devcode);
|
||||
void avr_display(FILE * f, AVRPART * p, const char * prefix, int verbose);
|
||||
|
||||
typedef void (*walk_avrparts_cb)(const char *name, const char *desc,
|
||||
const char *cfgname, int cfglineno,
|
||||
void *cookie);
|
||||
void walk_avrparts(LISTID programmers, walk_avrparts_cb cb, void *cookie);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* avrpart_h */
|
||||
|
||||
394
avrdude/bitbang.c
Normal file
394
avrdude/bitbang.c
Normal file
@@ -0,0 +1,394 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2005 Michael Holzt <kju-avr@fqdn.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
/* $Id$ */
|
||||
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if !defined(WIN32NATIVE)
|
||||
# include <signal.h>
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "avr.h"
|
||||
#include "pindefs.h"
|
||||
#include "pgm.h"
|
||||
#include "par.h"
|
||||
#include "serbb.h"
|
||||
|
||||
static int delay_decrement;
|
||||
|
||||
#if !defined(WIN32NATIVE)
|
||||
static volatile int done;
|
||||
|
||||
typedef void (*mysighandler_t)(int);
|
||||
static mysighandler_t saved_alarmhandler;
|
||||
|
||||
static void alarmhandler(int signo)
|
||||
{
|
||||
done = 1;
|
||||
signal(SIGALRM, saved_alarmhandler);
|
||||
}
|
||||
#endif /* !WIN32NATIVE */
|
||||
|
||||
/*
|
||||
* Calibrate the microsecond delay loop below.
|
||||
*/
|
||||
static void bitbang_calibrate_delay(void)
|
||||
{
|
||||
/*
|
||||
* Right now, we don't have any Win32 implementation for this, so we
|
||||
* can only run on a preconfigured delay stepping there. The figure
|
||||
* below should at least be correct within an order of magnitude,
|
||||
* judging from the auto-calibration figures seen on various Unix
|
||||
* systems on comparable hardware.
|
||||
*/
|
||||
#if defined(WIN32NATIVE)
|
||||
delay_decrement = 100;
|
||||
#else /* !WIN32NATIVE */
|
||||
struct itimerval itv;
|
||||
volatile int i;
|
||||
|
||||
if (verbose >= 2)
|
||||
fprintf(stderr,
|
||||
"%s: Calibrating delay loop...",
|
||||
progname);
|
||||
i = 0;
|
||||
done = 0;
|
||||
saved_alarmhandler = signal(SIGALRM, alarmhandler);
|
||||
/*
|
||||
* Set ITIMER_REAL to 100 ms. All known systems have a timer
|
||||
* granularity of 10 ms or better, so counting the delay cycles
|
||||
* accumulating over 100 ms should give us a rather realistic
|
||||
* picture, without annoying the user by a lengthy startup time (as
|
||||
* an alarm(1) would do). Of course, if heavy system activity
|
||||
* happens just during calibration but stops before the remaining
|
||||
* part of AVRDUDE runs, this will yield wrong values. There's not
|
||||
* much we can do about this.
|
||||
*/
|
||||
itv.it_value.tv_sec = 0;
|
||||
itv.it_value.tv_usec = 100000;
|
||||
itv.it_interval.tv_sec = itv.it_interval.tv_usec = 0;
|
||||
setitimer(ITIMER_REAL, &itv, 0);
|
||||
while (!done)
|
||||
i--;
|
||||
itv.it_value.tv_sec = itv.it_value.tv_usec = 0;
|
||||
setitimer(ITIMER_REAL, &itv, 0);
|
||||
/*
|
||||
* Calculate back from 100 ms to 1 us.
|
||||
*/
|
||||
delay_decrement = -i / 100000;
|
||||
if (verbose >= 2)
|
||||
fprintf(stderr,
|
||||
" calibrated to %d cycles per us\n",
|
||||
delay_decrement);
|
||||
#endif /* WIN32NATIVE */
|
||||
}
|
||||
|
||||
/*
|
||||
* Delay for approximately the number of microseconds specified.
|
||||
* usleep()'s granularity is usually like 1 ms or 10 ms, so it's not
|
||||
* really suitable for short delays in bit-bang algorithms.
|
||||
*/
|
||||
void bitbang_delay(int us)
|
||||
{
|
||||
volatile int del = us * delay_decrement;
|
||||
|
||||
while (del > 0)
|
||||
del--;
|
||||
}
|
||||
|
||||
/*
|
||||
* transmit and receive a byte of data to/from the AVR device
|
||||
*/
|
||||
static unsigned char bitbang_txrx(PROGRAMMER * pgm, unsigned char byte)
|
||||
{
|
||||
int i;
|
||||
unsigned char r, b, rbyte;
|
||||
|
||||
rbyte = 0;
|
||||
for (i=7; i>=0; i--) {
|
||||
/*
|
||||
* Write and read one bit on SPI.
|
||||
* Some notes on timing: Let T be the time it takes to do
|
||||
* one pgm->setpin()-call resp. par clrpin()-call, then
|
||||
* - SCK is high for 2T
|
||||
* - SCK is low for 2T
|
||||
* - MOSI setuptime is 1T
|
||||
* - MOSI holdtime is 3T
|
||||
* - SCK low to MISO read is 2T to 3T
|
||||
* So we are within programming specs (expect for AT90S1200),
|
||||
* if and only if T>t_CLCL (t_CLCL=clock period of target system).
|
||||
*
|
||||
* Due to the delay introduced by "IN" and "OUT"-commands,
|
||||
* T is greater than 1us (more like 2us) on x86-architectures.
|
||||
* So programming works safely down to 1MHz target clock.
|
||||
*/
|
||||
|
||||
b = (byte >> i) & 0x01;
|
||||
|
||||
/* set the data input line as desired */
|
||||
pgm->setpin(pgm, pgm->pinno[PIN_AVR_MOSI], b);
|
||||
|
||||
pgm->setpin(pgm, pgm->pinno[PIN_AVR_SCK], 1);
|
||||
|
||||
/*
|
||||
* read the result bit (it is either valid from a previous falling
|
||||
* edge or it is ignored in the current context)
|
||||
*/
|
||||
r = pgm->getpin(pgm, pgm->pinno[PIN_AVR_MISO]);
|
||||
|
||||
pgm->setpin(pgm, pgm->pinno[PIN_AVR_SCK], 0);
|
||||
|
||||
rbyte |= r << i;
|
||||
}
|
||||
|
||||
return rbyte;
|
||||
}
|
||||
|
||||
|
||||
int bitbang_rdy_led(PROGRAMMER * pgm, int value)
|
||||
{
|
||||
pgm->setpin(pgm, pgm->pinno[PIN_LED_RDY], !value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bitbang_err_led(PROGRAMMER * pgm, int value)
|
||||
{
|
||||
pgm->setpin(pgm, pgm->pinno[PIN_LED_ERR], !value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bitbang_pgm_led(PROGRAMMER * pgm, int value)
|
||||
{
|
||||
pgm->setpin(pgm, pgm->pinno[PIN_LED_PGM], !value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bitbang_vfy_led(PROGRAMMER * pgm, int value)
|
||||
{
|
||||
pgm->setpin(pgm, pgm->pinno[PIN_LED_VFY], !value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* transmit an AVR device command and return the results; 'cmd' and
|
||||
* 'res' must point to at least a 4 byte data buffer
|
||||
*/
|
||||
int bitbang_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
|
||||
unsigned char res[4])
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<4; i++) {
|
||||
res[i] = bitbang_txrx(pgm, cmd[i]);
|
||||
}
|
||||
|
||||
if(verbose >= 2)
|
||||
{
|
||||
fprintf(stderr, "bitbang_cmd(): [ ");
|
||||
for(i = 0; i < 4; i++)
|
||||
fprintf(stderr, "%02X ", cmd[i]);
|
||||
fprintf(stderr, "] [ ");
|
||||
for(i = 0; i < 4; i++)
|
||||
{
|
||||
fprintf(stderr, "%02X ", res[i]);
|
||||
}
|
||||
fprintf(stderr, "]\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* transmit bytes via SPI and return the results; 'cmd' and
|
||||
* 'res' must point to data buffers
|
||||
*/
|
||||
int bitbang_spi(PROGRAMMER * pgm, unsigned char cmd[],
|
||||
unsigned char res[], int count)
|
||||
{
|
||||
int i;
|
||||
|
||||
pgm->setpin(pgm, pgm->pinno[PIN_LED_PGM], 0);
|
||||
|
||||
for (i=0; i<count; i++) {
|
||||
res[i] = bitbang_txrx(pgm, cmd[i]);
|
||||
}
|
||||
|
||||
pgm->setpin(pgm, pgm->pinno[PIN_LED_PGM], 1);
|
||||
|
||||
if(verbose >= 2)
|
||||
{
|
||||
fprintf(stderr, "bitbang_cmd(): [ ");
|
||||
for(i = 0; i < count; i++)
|
||||
fprintf(stderr, "%02X ", cmd[i]);
|
||||
fprintf(stderr, "] [ ");
|
||||
for(i = 0; i < count; i++)
|
||||
{
|
||||
fprintf(stderr, "%02X ", res[i]);
|
||||
}
|
||||
fprintf(stderr, "]\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* issue the 'chip erase' command to the AVR device
|
||||
*/
|
||||
int bitbang_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
unsigned char cmd[4];
|
||||
unsigned char res[4];
|
||||
|
||||
if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
|
||||
fprintf(stderr, "chip erase instruction not defined for part \"%s\"\n",
|
||||
p->desc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pgm->pgm_led(pgm, ON);
|
||||
|
||||
memset(cmd, 0, sizeof(cmd));
|
||||
|
||||
avr_set_bits(p->op[AVR_OP_CHIP_ERASE], cmd);
|
||||
pgm->cmd(pgm, cmd, res);
|
||||
usleep(p->chip_erase_delay);
|
||||
pgm->initialize(pgm, p);
|
||||
|
||||
pgm->pgm_led(pgm, OFF);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* issue the 'program enable' command to the AVR device
|
||||
*/
|
||||
int bitbang_program_enable(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
unsigned char cmd[4];
|
||||
unsigned char res[4];
|
||||
|
||||
if (p->op[AVR_OP_PGM_ENABLE] == NULL) {
|
||||
fprintf(stderr, "program enable instruction not defined for part \"%s\"\n",
|
||||
p->desc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(cmd, 0, sizeof(cmd));
|
||||
avr_set_bits(p->op[AVR_OP_PGM_ENABLE], cmd);
|
||||
pgm->cmd(pgm, cmd, res);
|
||||
|
||||
if (res[2] != cmd[1])
|
||||
return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize the AVR device and prepare it to accept commands
|
||||
*/
|
||||
int bitbang_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
int rc;
|
||||
int tries;
|
||||
|
||||
bitbang_calibrate_delay();
|
||||
|
||||
pgm->powerup(pgm);
|
||||
usleep(20000);
|
||||
|
||||
pgm->setpin(pgm, pgm->pinno[PIN_AVR_SCK], 0);
|
||||
pgm->setpin(pgm, pgm->pinno[PIN_AVR_RESET], 0);
|
||||
usleep(20000);
|
||||
|
||||
pgm->highpulsepin(pgm, pgm->pinno[PIN_AVR_RESET]);
|
||||
|
||||
usleep(20000); /* 20 ms XXX should be a per-chip parameter */
|
||||
|
||||
/*
|
||||
* Enable programming mode. If we are programming an AT90S1200, we
|
||||
* can only issue the command and hope it worked. If we are using
|
||||
* one of the other chips, the chip will echo 0x53 when issuing the
|
||||
* third byte of the command. In this case, try up to 32 times in
|
||||
* order to possibly get back into sync with the chip if we are out
|
||||
* of sync.
|
||||
*/
|
||||
if (strcmp(p->desc, "AT90S1200")==0) {
|
||||
pgm->program_enable(pgm, p);
|
||||
}
|
||||
else {
|
||||
tries = 0;
|
||||
do {
|
||||
rc = pgm->program_enable(pgm, p);
|
||||
if ((rc == 0)||(rc == -1))
|
||||
break;
|
||||
pgm->highpulsepin(pgm, pgm->pinno[p->retry_pulse/*PIN_AVR_SCK*/]);
|
||||
tries++;
|
||||
} while (tries < 65);
|
||||
|
||||
/*
|
||||
* can't sync with the device, maybe it's not attached?
|
||||
*/
|
||||
if (rc) {
|
||||
fprintf(stderr, "%s: AVR device not responding\n", progname);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void verify_pin_assigned(PROGRAMMER * pgm, int pin, char * desc)
|
||||
{
|
||||
if (pgm->pinno[pin] == 0) {
|
||||
fprintf(stderr, "%s: error: no pin has been assigned for %s\n",
|
||||
progname, desc);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Verify all prerequisites for a bit-bang programmer are present.
|
||||
*/
|
||||
void bitbang_check_prerequisites(PROGRAMMER *pgm)
|
||||
{
|
||||
|
||||
verify_pin_assigned(pgm, PIN_AVR_RESET, "AVR RESET");
|
||||
verify_pin_assigned(pgm, PIN_AVR_SCK, "AVR SCK");
|
||||
verify_pin_assigned(pgm, PIN_AVR_MISO, "AVR MISO");
|
||||
verify_pin_assigned(pgm, PIN_AVR_MOSI, "AVR MOSI");
|
||||
|
||||
if (pgm->cmd == NULL) {
|
||||
fprintf(stderr, "%s: error: no cmd() method defined for bitbang programmer\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
56
avrdude/bitbang.h
Normal file
56
avrdude/bitbang.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2005 Michael Holzt <kju-avr@fqdn.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef bitbang_h
|
||||
#define bitbang_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int bitbang_setpin(int fd, int pin, int value);
|
||||
int bitbang_getpin(int fd, int pin);
|
||||
int bitbang_highpulsepin(int fd, int pin);
|
||||
void bitbang_delay(unsigned int us);
|
||||
|
||||
void bitbang_check_prerequisites(PROGRAMMER *pgm);
|
||||
|
||||
int bitbang_rdy_led (PROGRAMMER * pgm, int value);
|
||||
int bitbang_err_led (PROGRAMMER * pgm, int value);
|
||||
int bitbang_pgm_led (PROGRAMMER * pgm, int value);
|
||||
int bitbang_vfy_led (PROGRAMMER * pgm, int value);
|
||||
int bitbang_cmd (PROGRAMMER * pgm, unsigned char cmd[4],
|
||||
unsigned char res[4]);
|
||||
int bitbang_spi (PROGRAMMER * pgm, unsigned char cmd[],
|
||||
unsigned char res[], int count);
|
||||
int bitbang_chip_erase (PROGRAMMER * pgm, AVRPART * p);
|
||||
int bitbang_program_enable (PROGRAMMER * pgm, AVRPART * p);
|
||||
void bitbang_powerup (PROGRAMMER * pgm);
|
||||
void bitbang_powerdown (PROGRAMMER * pgm);
|
||||
int bitbang_initialize (PROGRAMMER * pgm, AVRPART * p);
|
||||
void bitbang_disable (PROGRAMMER * pgm);
|
||||
void bitbang_enable (PROGRAMMER * pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,11 +1,11 @@
|
||||
#! /bin/sh
|
||||
|
||||
# autoconf-2.57 is required
|
||||
# autoconf-2.59 or 2.61 is known to work
|
||||
|
||||
: ${AUTOHEADER="autoheader${AC_VER}"}
|
||||
: ${AUTOCONF="autoconf${AC_VER}"}
|
||||
|
||||
# automake-1.7.x is required
|
||||
# automake-1.9.x or 1.10 is known to work
|
||||
|
||||
: ${ACLOCAL="aclocal${AM_VER}"}
|
||||
: ${AUTOMAKE="automake${AM_VER}"}
|
||||
@@ -14,22 +14,20 @@
|
||||
|
||||
AUTOCONF_VER=`(${AUTOCONF} --version 2>/dev/null | head -n 1 | \
|
||||
cut -d ' ' -f 4) 2>/dev/null`
|
||||
if [ "$AUTOCONF_VER" != "2.57" ]
|
||||
if [ "$AUTOCONF_VER" != "2.59" -a "$AUTOCONF_VER" != "2.61" ]
|
||||
then
|
||||
echo "You need to use autoconf version 2.57."
|
||||
echo "Warning: This program is tested with autoconf version 2.59 and 2.61."
|
||||
echo "You are using `${AUTOCONF} --version | head -n 1`."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verify automake version
|
||||
|
||||
AUTOMAKE_VER=`(${AUTOMAKE} --version | head -n 1 | \
|
||||
cut -d ' ' -f 4 | cut -d '.' -f -2) 2>/dev/null`
|
||||
if [ "$AUTOMAKE_VER" != "1.7" ]
|
||||
if [ "$AUTOMAKE_VER" != "1.9" -a "$AUTOMAKE_VER" != "1.10" ]
|
||||
then
|
||||
echo "You need to use automake version 1.7 (preferrably 1.7.3)."
|
||||
echo "Warning: This program is tested with automake version 1.9 and 1.10."
|
||||
echo "You are using `${AUTOMAKE} --version | head -n 1`."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export ACLOCAL AUTOHEADER AUTOCONF AUTOMAKE
|
||||
@@ -38,6 +36,8 @@ export ACLOCAL AUTOHEADER AUTOCONF AUTOMAKE
|
||||
|
||||
set -x
|
||||
|
||||
rm -rf autom4te.cache
|
||||
|
||||
${ACLOCAL}
|
||||
${AUTOHEADER}
|
||||
${AUTOCONF}
|
||||
|
||||
699
avrdude/butterfly.c
Normal file
699
avrdude/butterfly.c
Normal file
@@ -0,0 +1,699 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org>
|
||||
* Copyright (C) 2005, 2007 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* avrdude interface for the serial programming mode of the Atmel butterfly
|
||||
* evaluation board. This board features a bootloader which uses a protocol
|
||||
* very similar, but not identical, to the one described in application note
|
||||
* avr910.
|
||||
*
|
||||
* Actually, the butterfly uses a predecessor of the avr910 protocol
|
||||
* which is described in application notes avr109 (generic AVR
|
||||
* bootloader) and avr911 (opensource programmer). This file now
|
||||
* fully handles the features present in avr109. It should probably
|
||||
* be renamed to avr109, but we rather stick with the old name inside
|
||||
* the file. We'll provide aliases for "avr109" and "avr911" in
|
||||
* avrdude.conf so users could call it by these name as well.
|
||||
*/
|
||||
|
||||
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "avr.h"
|
||||
#include "pgm.h"
|
||||
#include "butterfly.h"
|
||||
#include "serial.h"
|
||||
|
||||
/*
|
||||
* Private data for this programmer.
|
||||
*/
|
||||
struct pdata
|
||||
{
|
||||
char has_auto_incr_addr;
|
||||
unsigned int buffersize;
|
||||
};
|
||||
|
||||
#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
|
||||
|
||||
static void butterfly_setup(PROGRAMMER * pgm)
|
||||
{
|
||||
if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
|
||||
fprintf(stderr,
|
||||
"%s: butterfly_setup(): Out of memory allocating private data\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
memset(pgm->cookie, 0, sizeof(struct pdata));
|
||||
}
|
||||
|
||||
static void butterfly_teardown(PROGRAMMER * pgm)
|
||||
{
|
||||
free(pgm->cookie);
|
||||
}
|
||||
|
||||
static int butterfly_send(PROGRAMMER * pgm, char * buf, size_t len)
|
||||
{
|
||||
return serial_send(&pgm->fd, (unsigned char *)buf, len);
|
||||
}
|
||||
|
||||
|
||||
static int butterfly_recv(PROGRAMMER * pgm, char * buf, size_t len)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv = serial_recv(&pgm->fd, (unsigned char *)buf, len);
|
||||
if (rv < 0) {
|
||||
fprintf(stderr,
|
||||
"%s: butterfly_recv(): programmer is not responding\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int butterfly_drain(PROGRAMMER * pgm, int display)
|
||||
{
|
||||
return serial_drain(&pgm->fd, display);
|
||||
}
|
||||
|
||||
|
||||
static void butterfly_vfy_cmd_sent(PROGRAMMER * pgm, char * errmsg)
|
||||
{
|
||||
char c;
|
||||
|
||||
butterfly_recv(pgm, &c, 1);
|
||||
if (c != '\r') {
|
||||
fprintf(stderr, "%s: error: programmer did not respond to command: %s\n",
|
||||
progname, errmsg);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int butterfly_rdy_led(PROGRAMMER * pgm, int value)
|
||||
{
|
||||
/* Do nothing. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int butterfly_err_led(PROGRAMMER * pgm, int value)
|
||||
{
|
||||
/* Do nothing. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int butterfly_pgm_led(PROGRAMMER * pgm, int value)
|
||||
{
|
||||
/* Do nothing. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int butterfly_vfy_led(PROGRAMMER * pgm, int value)
|
||||
{
|
||||
/* Do nothing. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* issue the 'chip erase' command to the butterfly board
|
||||
*/
|
||||
static int butterfly_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
butterfly_send(pgm, "e", 1);
|
||||
butterfly_vfy_cmd_sent(pgm, "chip erase");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void butterfly_enter_prog_mode(PROGRAMMER * pgm)
|
||||
{
|
||||
butterfly_send(pgm, "P", 1);
|
||||
butterfly_vfy_cmd_sent(pgm, "enter prog mode");
|
||||
}
|
||||
|
||||
|
||||
static void butterfly_leave_prog_mode(PROGRAMMER * pgm)
|
||||
{
|
||||
butterfly_send(pgm, "L", 1);
|
||||
butterfly_vfy_cmd_sent(pgm, "leave prog mode");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* issue the 'program enable' command to the AVR device
|
||||
*/
|
||||
static int butterfly_program_enable(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* apply power to the AVR processor
|
||||
*/
|
||||
static void butterfly_powerup(PROGRAMMER * pgm)
|
||||
{
|
||||
/* Do nothing. */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* remove power from the AVR processor
|
||||
*/
|
||||
static void butterfly_powerdown(PROGRAMMER * pgm)
|
||||
{
|
||||
/* Do nothing. */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* initialize the AVR device and prepare it to accept commands
|
||||
*/
|
||||
static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
char id[8];
|
||||
char sw[2];
|
||||
char hw[2];
|
||||
char buf[10];
|
||||
char type;
|
||||
char c, devtype_1st;
|
||||
|
||||
/*
|
||||
* Send some ESC to activate butterfly bootloader. This is not needed
|
||||
* for plain avr109 bootloaders but does not harm there either.
|
||||
*/
|
||||
fprintf(stderr, "Connecting to programmer: ");
|
||||
do {
|
||||
putc('.', stderr);
|
||||
butterfly_send(pgm, "\033", 1);
|
||||
butterfly_drain(pgm, 0);
|
||||
butterfly_send(pgm, "S", 1);
|
||||
butterfly_recv(pgm, &c, 1);
|
||||
if (c != '?') {
|
||||
putc('\n', stderr);
|
||||
/*
|
||||
* Got a useful response, continue getting the programmer
|
||||
* identifier. Programmer returns exactly 7 chars _without_
|
||||
* the null.
|
||||
*/
|
||||
id[0] = c;
|
||||
butterfly_recv(pgm, &id[1], sizeof(id)-2);
|
||||
id[sizeof(id)-1] = '\0';
|
||||
}
|
||||
} while (c == '?');
|
||||
|
||||
/* Get the HW and SW versions to see if the programmer is present. */
|
||||
|
||||
butterfly_send(pgm, "V", 1);
|
||||
butterfly_recv(pgm, sw, sizeof(sw));
|
||||
|
||||
butterfly_send(pgm, "v", 1);
|
||||
butterfly_recv(pgm, hw, 1); /* first, read only _one_ byte */
|
||||
if (hw[0]!='?') {
|
||||
butterfly_recv(pgm, &hw[1], 1);/* now, read second byte */
|
||||
};
|
||||
|
||||
/* Get the programmer type (serial or parallel). Expect serial. */
|
||||
|
||||
butterfly_send(pgm, "p", 1);
|
||||
butterfly_recv(pgm, &type, 1);
|
||||
|
||||
fprintf(stderr, "Found programmer: Id = \"%s\"; type = %c\n", id, type);
|
||||
fprintf(stderr, " Software Version = %c.%c; ", sw[0], sw[1]);
|
||||
if (hw[0]=='?') {
|
||||
fprintf(stderr, "No Hardware Version given.\n");
|
||||
} else {
|
||||
fprintf(stderr, "Hardware Version = %c.%c\n", hw[0], hw[1]);
|
||||
};
|
||||
|
||||
/* See if programmer supports autoincrement of address. */
|
||||
|
||||
butterfly_send(pgm, "a", 1);
|
||||
butterfly_recv(pgm, &PDATA(pgm)->has_auto_incr_addr, 1);
|
||||
if (PDATA(pgm)->has_auto_incr_addr == 'Y')
|
||||
fprintf(stderr, "Programmer supports auto addr increment.\n");
|
||||
|
||||
/* Check support for buffered memory access, abort if not available */
|
||||
|
||||
butterfly_send(pgm, "b", 1);
|
||||
butterfly_recv(pgm, &c, 1);
|
||||
if (c != 'Y') {
|
||||
fprintf(stderr,
|
||||
"%s: error: buffered memory access not supported. Maybe it isn't\n"\
|
||||
"a butterfly/AVR109 but a AVR910 device?\n", progname);
|
||||
exit(1);
|
||||
};
|
||||
butterfly_recv(pgm, &c, 1);
|
||||
PDATA(pgm)->buffersize = (unsigned int)(unsigned char)c<<8;
|
||||
butterfly_recv(pgm, &c, 1);
|
||||
PDATA(pgm)->buffersize += (unsigned int)(unsigned char)c;
|
||||
fprintf(stderr,
|
||||
"Programmer supports buffered memory access with buffersize=%i bytes.\n",
|
||||
PDATA(pgm)->buffersize);
|
||||
|
||||
/* Get list of devices that the programmer supports. */
|
||||
|
||||
butterfly_send(pgm, "t", 1);
|
||||
fprintf(stderr, "\nProgrammer supports the following devices:\n");
|
||||
devtype_1st = 0;
|
||||
while (1) {
|
||||
butterfly_recv(pgm, &c, 1);
|
||||
if (devtype_1st == 0)
|
||||
devtype_1st = c;
|
||||
|
||||
if (c == 0)
|
||||
break;
|
||||
fprintf(stderr, " Device code: 0x%02x\n", (unsigned int)(unsigned char)c);
|
||||
};
|
||||
fprintf(stderr,"\n");
|
||||
|
||||
/* Tell the programmer which part we selected.
|
||||
According to the AVR109 code, this is ignored by the bootloader. As
|
||||
some early versions might not properly ignore it, rather pick up the
|
||||
first device type as reported above than anything out of avrdude.conf,
|
||||
so to avoid a potential conflict. There appears to be no general
|
||||
agreement on AVR910 device IDs beyond the ones from the original
|
||||
appnote 910. */
|
||||
|
||||
buf[0] = 'T';
|
||||
buf[1] = devtype_1st;
|
||||
|
||||
butterfly_send(pgm, buf, 2);
|
||||
butterfly_vfy_cmd_sent(pgm, "select device");
|
||||
|
||||
if (verbose)
|
||||
fprintf(stderr,
|
||||
"%s: devcode selected: 0x%02x\n",
|
||||
progname, (unsigned)buf[1]);
|
||||
|
||||
butterfly_enter_prog_mode(pgm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void butterfly_disable(PROGRAMMER * pgm)
|
||||
{
|
||||
butterfly_leave_prog_mode(pgm);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void butterfly_enable(PROGRAMMER * pgm)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static int butterfly_open(PROGRAMMER * pgm, char * port)
|
||||
{
|
||||
strcpy(pgm->port, port);
|
||||
/*
|
||||
* If baudrate was not specified use 19200 Baud
|
||||
*/
|
||||
if(pgm->baudrate == 0) {
|
||||
pgm->baudrate = 19200;
|
||||
}
|
||||
serial_open(port, pgm->baudrate, &pgm->fd);
|
||||
|
||||
/*
|
||||
* drain any extraneous input
|
||||
*/
|
||||
butterfly_drain (pgm, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void butterfly_close(PROGRAMMER * pgm)
|
||||
{
|
||||
/* "exit programmer" */
|
||||
butterfly_send(pgm, "E", 1);
|
||||
butterfly_vfy_cmd_sent(pgm, "exit bootloader");
|
||||
|
||||
serial_close(&pgm->fd);
|
||||
pgm->fd.ifd = -1;
|
||||
}
|
||||
|
||||
|
||||
static void butterfly_display(PROGRAMMER * pgm, const char * p)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void butterfly_set_addr(PROGRAMMER * pgm, unsigned long addr)
|
||||
{
|
||||
char cmd[3];
|
||||
|
||||
cmd[0] = 'A';
|
||||
cmd[1] = (addr >> 8) & 0xff;
|
||||
cmd[2] = addr & 0xff;
|
||||
|
||||
butterfly_send(pgm, cmd, sizeof(cmd));
|
||||
butterfly_vfy_cmd_sent(pgm, "set addr");
|
||||
}
|
||||
|
||||
|
||||
static void butterfly_set_extaddr(PROGRAMMER * pgm, unsigned long addr)
|
||||
{
|
||||
char cmd[4];
|
||||
|
||||
cmd[0] = 'H';
|
||||
cmd[1] = (addr >> 16) & 0xff;
|
||||
cmd[2] = (addr >> 8) & 0xff;
|
||||
cmd[3] = addr & 0xff;
|
||||
|
||||
butterfly_send(pgm, cmd, sizeof(cmd));
|
||||
butterfly_vfy_cmd_sent(pgm, "set extaddr");
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int butterfly_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned long addr, unsigned char value)
|
||||
{
|
||||
char cmd[6];
|
||||
int size;
|
||||
int use_ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL;
|
||||
|
||||
if ((strcmp(m->desc, "flash") == 0) || (strcmp(m->desc, "eeprom") == 0))
|
||||
{
|
||||
cmd[0] = 'B';
|
||||
cmd[1] = 0;
|
||||
if ((cmd[3] = toupper(m->desc[0])) == 'E') { /* write to eeprom */
|
||||
cmd[2] = 1;
|
||||
cmd[4] = value;
|
||||
size = 5;
|
||||
} else { /* write to flash */
|
||||
/* @@@ not yet implemented */
|
||||
cmd[2] = 2;
|
||||
size = 6;
|
||||
return -1;
|
||||
}
|
||||
if (use_ext_addr) {
|
||||
butterfly_set_extaddr(pgm, addr);
|
||||
} else {
|
||||
butterfly_set_addr(pgm, addr);
|
||||
}
|
||||
}
|
||||
else if (strcmp(m->desc, "lock") == 0)
|
||||
{
|
||||
cmd[0] = 'l';
|
||||
cmd[1] = value;
|
||||
size = 2;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
|
||||
butterfly_send(pgm, cmd, size);
|
||||
butterfly_vfy_cmd_sent(pgm, "write byte");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int butterfly_read_byte_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned long addr, unsigned char * value)
|
||||
{
|
||||
static int cached = 0;
|
||||
static unsigned char cvalue;
|
||||
static unsigned long caddr;
|
||||
int use_ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL;
|
||||
|
||||
if (cached && ((caddr + 1) == addr)) {
|
||||
*value = cvalue;
|
||||
cached = 0;
|
||||
}
|
||||
else {
|
||||
char buf[2];
|
||||
|
||||
if (use_ext_addr) {
|
||||
butterfly_set_extaddr(pgm, addr >> 1);
|
||||
} else {
|
||||
butterfly_set_addr(pgm, addr >> 1);
|
||||
}
|
||||
|
||||
butterfly_send(pgm, "g\000\002F", 4);
|
||||
|
||||
/* Read back the program mem word (MSB first) */
|
||||
butterfly_recv(pgm, buf, sizeof(buf));
|
||||
|
||||
if ((addr & 0x01) == 0) {
|
||||
*value = buf[1];
|
||||
cached = 1;
|
||||
cvalue = buf[0];
|
||||
caddr = addr;
|
||||
}
|
||||
else {
|
||||
*value = buf[0];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int butterfly_read_byte_eeprom(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned long addr, unsigned char * value)
|
||||
{
|
||||
butterfly_set_addr(pgm, addr);
|
||||
butterfly_send(pgm, "g\000\001E", 4);
|
||||
butterfly_recv(pgm, (char *)value, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int butterfly_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned long addr, unsigned char * value)
|
||||
{
|
||||
char cmd;
|
||||
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
return butterfly_read_byte_flash(pgm, p, m, addr, value);
|
||||
}
|
||||
|
||||
if (strcmp(m->desc, "eeprom") == 0) {
|
||||
return butterfly_read_byte_eeprom(pgm, p, m, addr, value);
|
||||
}
|
||||
|
||||
if (strcmp(m->desc, "lfuse") == 0) {
|
||||
cmd = 'F';
|
||||
}
|
||||
else if (strcmp(m->desc, "hfuse") == 0) {
|
||||
cmd = 'N';
|
||||
}
|
||||
else if (strcmp(m->desc, "efuse") == 0) {
|
||||
cmd = 'Q';
|
||||
}
|
||||
else if (strcmp(m->desc, "lock") == 0) {
|
||||
cmd = 'r';
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
|
||||
butterfly_send(pgm, &cmd, 1);
|
||||
butterfly_recv(pgm, (char *)value, 1);
|
||||
|
||||
return *value == '?'? -1: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int butterfly_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int n_bytes)
|
||||
{
|
||||
unsigned int addr = 0;
|
||||
unsigned int max_addr = n_bytes;
|
||||
char *cmd;
|
||||
unsigned int blocksize = PDATA(pgm)->buffersize;
|
||||
int use_ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL;
|
||||
|
||||
if (strcmp(m->desc, "flash") && strcmp(m->desc, "eeprom"))
|
||||
return -2;
|
||||
|
||||
if (m->desc[0] == 'e')
|
||||
blocksize = 1; /* Write to eeprom single bytes only */
|
||||
|
||||
if (use_ext_addr) {
|
||||
butterfly_set_extaddr(pgm, addr);
|
||||
} else {
|
||||
butterfly_set_addr(pgm, addr);
|
||||
}
|
||||
|
||||
#if 0
|
||||
usleep(1000000);
|
||||
butterfly_send(pgm, "y", 1);
|
||||
butterfly_vfy_cmd_sent(pgm, "clear LED");
|
||||
#endif
|
||||
|
||||
cmd = malloc(4+blocksize);
|
||||
if (!cmd) return -1;
|
||||
cmd[0] = 'B';
|
||||
cmd[3] = toupper(m->desc[0]);
|
||||
|
||||
while (addr < max_addr) {
|
||||
if ((max_addr - addr) < blocksize) {
|
||||
blocksize = max_addr - addr;
|
||||
};
|
||||
memcpy(&cmd[4], &m->buf[addr], blocksize);
|
||||
cmd[1] = (blocksize >> 8) & 0xff;
|
||||
cmd[2] = blocksize & 0xff;
|
||||
|
||||
butterfly_send(pgm, cmd, 4+blocksize);
|
||||
butterfly_vfy_cmd_sent(pgm, "write block");
|
||||
|
||||
addr += blocksize;
|
||||
|
||||
report_progress (addr, max_addr, NULL);
|
||||
} /* while */
|
||||
free(cmd);
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int butterfly_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int n_bytes)
|
||||
{
|
||||
unsigned int addr = 0;
|
||||
unsigned int max_addr = n_bytes;
|
||||
int rd_size = 1;
|
||||
int use_ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL;
|
||||
|
||||
/* check parameter syntax: only "flash" or "eeprom" is allowed */
|
||||
if (strcmp(m->desc, "flash") && strcmp(m->desc, "eeprom"))
|
||||
return -2;
|
||||
|
||||
{ /* use buffered mode */
|
||||
char cmd[4];
|
||||
int blocksize = PDATA(pgm)->buffersize;
|
||||
|
||||
cmd[0] = 'g';
|
||||
cmd[3] = toupper(m->desc[0]);
|
||||
|
||||
if (use_ext_addr) {
|
||||
butterfly_set_extaddr(pgm, addr);
|
||||
} else {
|
||||
butterfly_set_addr(pgm, addr);
|
||||
}
|
||||
while (addr < max_addr) {
|
||||
if ((max_addr - addr) < blocksize) {
|
||||
blocksize = max_addr - addr;
|
||||
};
|
||||
cmd[1] = (blocksize >> 8) & 0xff;
|
||||
cmd[2] = blocksize & 0xff;
|
||||
|
||||
butterfly_send(pgm, cmd, 4);
|
||||
butterfly_recv(pgm, (char *)&m->buf[addr], blocksize);
|
||||
|
||||
addr += blocksize;
|
||||
|
||||
report_progress (addr, max_addr, NULL);
|
||||
} /* while */
|
||||
}
|
||||
|
||||
return addr * rd_size;
|
||||
}
|
||||
|
||||
|
||||
/* Signature byte reads are always 3 bytes. */
|
||||
static int butterfly_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
|
||||
{
|
||||
unsigned char tmp;
|
||||
|
||||
if (m->size < 3) {
|
||||
fprintf(stderr, "%s: memsize too small for sig byte read", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
butterfly_send(pgm, "s", 1);
|
||||
butterfly_recv(pgm, (char *)m->buf, 3);
|
||||
/* Returned signature has wrong order. */
|
||||
tmp = m->buf[2];
|
||||
m->buf[2] = m->buf[0];
|
||||
m->buf[0] = tmp;
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
||||
void butterfly_initpgm(PROGRAMMER * pgm)
|
||||
{
|
||||
strcpy(pgm->type, "avr910");
|
||||
|
||||
/*
|
||||
* mandatory functions
|
||||
*/
|
||||
pgm->rdy_led = butterfly_rdy_led;
|
||||
pgm->err_led = butterfly_err_led;
|
||||
pgm->pgm_led = butterfly_pgm_led;
|
||||
pgm->vfy_led = butterfly_vfy_led;
|
||||
pgm->initialize = butterfly_initialize;
|
||||
pgm->display = butterfly_display;
|
||||
pgm->enable = butterfly_enable;
|
||||
pgm->disable = butterfly_disable;
|
||||
pgm->powerup = butterfly_powerup;
|
||||
pgm->powerdown = butterfly_powerdown;
|
||||
pgm->program_enable = butterfly_program_enable;
|
||||
pgm->chip_erase = butterfly_chip_erase;
|
||||
pgm->open = butterfly_open;
|
||||
pgm->close = butterfly_close;
|
||||
pgm->read_byte = butterfly_read_byte;
|
||||
pgm->write_byte = butterfly_write_byte;
|
||||
|
||||
/*
|
||||
* optional functions
|
||||
*/
|
||||
|
||||
pgm->paged_write = butterfly_paged_write;
|
||||
pgm->paged_load = butterfly_paged_load;
|
||||
|
||||
pgm->read_sig_bytes = butterfly_read_sig_bytes;
|
||||
|
||||
pgm->setup = butterfly_setup;
|
||||
pgm->teardown = butterfly_teardown;
|
||||
}
|
||||
35
avrdude/butterfly.h
Normal file
35
avrdude/butterfly.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef butterfly_h
|
||||
#define butterfly_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void butterfly_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* butterfly_h */
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.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
|
||||
@@ -21,11 +21,13 @@
|
||||
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "avr.h"
|
||||
#include "config.h"
|
||||
#include "config_gram.h"
|
||||
@@ -45,8 +47,10 @@ AVRMEM * current_mem;
|
||||
LISTID part_list;
|
||||
LISTID programmers;
|
||||
|
||||
int lineno = 0;
|
||||
char * infile = NULL;
|
||||
int lineno;
|
||||
const char * infile;
|
||||
|
||||
extern char * yytext;
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
@@ -261,14 +265,12 @@ void print_token(TOKEN * tkn)
|
||||
void pyytext(void)
|
||||
{
|
||||
#if DEBUG
|
||||
extern char * yytext;
|
||||
|
||||
fprintf(stderr, "TOKEN: \"%s\"\n", yytext);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
char * dup_string(char * str)
|
||||
char * dup_string(const char * str)
|
||||
{
|
||||
char * s;
|
||||
|
||||
@@ -281,3 +283,24 @@ char * dup_string(char * str)
|
||||
return s;
|
||||
}
|
||||
|
||||
int read_config(const char * file)
|
||||
{
|
||||
FILE * f;
|
||||
|
||||
f = fopen(file, "r");
|
||||
if (f == NULL) {
|
||||
fprintf(stderr, "%s: can't open config file \"%s\": %s\n",
|
||||
progname, file, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
lineno = 1;
|
||||
infile = file;
|
||||
yyin = f;
|
||||
|
||||
yyparse();
|
||||
|
||||
fclose(f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.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
|
||||
@@ -19,8 +19,8 @@
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef __config_h__
|
||||
#define __config_h__
|
||||
#ifndef config_h
|
||||
#define config_h
|
||||
|
||||
#include "lists.h"
|
||||
#include "pindefs.h"
|
||||
@@ -41,18 +41,19 @@ typedef struct token_t {
|
||||
int primary;
|
||||
VALUE value;
|
||||
} TOKEN;
|
||||
typedef struct token_t *token_p;
|
||||
|
||||
|
||||
extern FILE * yyin;
|
||||
extern PROGRAMMER * current_prog;
|
||||
extern AVRPART * current_part;
|
||||
extern AVRMEM * current_mem;
|
||||
extern LISTID programmers;
|
||||
extern LISTID part_list;
|
||||
extern int lineno;
|
||||
extern char * infile;
|
||||
extern const char * infile;
|
||||
extern LISTID string_list;
|
||||
extern LISTID number_list;
|
||||
extern LISTID part_list;
|
||||
extern LISTID programmers;
|
||||
extern char default_programmer[];
|
||||
extern char default_parallel[];
|
||||
extern char default_serial[];
|
||||
@@ -60,13 +61,17 @@ extern char default_serial[];
|
||||
|
||||
|
||||
#if !defined(HAS_YYSTYPE)
|
||||
#define YYSTYPE struct token_t *
|
||||
#define YYSTYPE token_p
|
||||
#endif
|
||||
extern YYSTYPE yylval;
|
||||
|
||||
extern char string_buf[MAX_STR_CONST];
|
||||
extern char *string_buf_ptr;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int yyparse(void);
|
||||
|
||||
|
||||
@@ -90,12 +95,14 @@ TOKEN * keyword(int primary);
|
||||
|
||||
void print_token(TOKEN * tkn);
|
||||
|
||||
PROGRAMMER * new_programmer(void);
|
||||
void pyytext(void);
|
||||
|
||||
AVRPART * new_part(void);
|
||||
char * dup_string(const char * str);
|
||||
|
||||
AVRPART * dup_part(AVRPART * d);
|
||||
int read_config(const char * file);
|
||||
|
||||
char * dup_string(char * str);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2006 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -26,21 +27,36 @@
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "lists.h"
|
||||
#include "par.h"
|
||||
#include "serbb.h"
|
||||
#include "pindefs.h"
|
||||
#include "ppi.h"
|
||||
#include "pgm.h"
|
||||
#include "stk500.h"
|
||||
#include "arduino.h"
|
||||
#include "stk500v2.h"
|
||||
#include "stk500generic.h"
|
||||
#include "avr910.h"
|
||||
#include "butterfly.h"
|
||||
#include "usbasp.h"
|
||||
#include "usbtiny.h"
|
||||
#include "avr.h"
|
||||
#include "jtagmkI.h"
|
||||
#include "jtagmkII.h"
|
||||
|
||||
extern char * progname;
|
||||
#if defined(WIN32NATIVE)
|
||||
#define strtok_r( _s, _sep, _lasts ) \
|
||||
( *(_lasts) = strtok( (_s), (_sep) ) )
|
||||
#endif
|
||||
|
||||
int yylex(void);
|
||||
int yyerror(char * errmsg);
|
||||
|
||||
static int assign_pin(int pinno, TOKEN * v);
|
||||
static int assign_pin(int pinno, TOKEN * v, int invert);
|
||||
static int which_opcode(TOKEN * opcode);
|
||||
static int parse_cmdbits(OPCODE * op);
|
||||
|
||||
@@ -54,6 +70,7 @@ static int parse_cmdbits(OPCODE * op);
|
||||
%token K_WRITE_HI
|
||||
%token K_LOADPAGE_LO
|
||||
%token K_LOADPAGE_HI
|
||||
%token K_LOAD_EXT_ADDR
|
||||
%token K_WRITEPAGE
|
||||
%token K_CHIP_ERASE
|
||||
%token K_PGM_ENABLE
|
||||
@@ -63,6 +80,8 @@ static int parse_cmdbits(OPCODE * op);
|
||||
%token K_PAGE_SIZE
|
||||
%token K_PAGED
|
||||
|
||||
%token K_ARDUINO
|
||||
%token K_BAUDRATE
|
||||
%token K_BS2
|
||||
%token K_BUFF
|
||||
%token K_CHIP_ERASE_DELAY
|
||||
@@ -72,17 +91,30 @@ static int parse_cmdbits(OPCODE * op);
|
||||
%token K_DEFAULT_SERIAL
|
||||
%token K_DESC
|
||||
%token K_DEVICECODE
|
||||
%token K_DRAGON_DW
|
||||
%token K_DRAGON_HVSP
|
||||
%token K_DRAGON_ISP
|
||||
%token K_DRAGON_JTAG
|
||||
%token K_DRAGON_PP
|
||||
%token K_STK500_DEVCODE
|
||||
%token K_AVR910_DEVCODE
|
||||
%token K_EEPROM
|
||||
%token K_ERRLED
|
||||
%token K_FLASH
|
||||
%token K_ID
|
||||
%token K_IO
|
||||
%token K_JTAG_MKI
|
||||
%token K_JTAG_MKII
|
||||
%token K_JTAG_MKII_DW
|
||||
%token K_JTAG_MKII_ISP
|
||||
%token K_LOADPAGE
|
||||
%token K_MAX_WRITE_DELAY
|
||||
%token K_MIN_WRITE_DELAY
|
||||
%token K_MISO
|
||||
%token K_MOSI
|
||||
%token K_NUM_PAGES
|
||||
%token K_NVM_BASE
|
||||
%token K_OFFSET
|
||||
%token K_PAGEL
|
||||
%token K_PAR
|
||||
%token K_PARALLEL
|
||||
@@ -97,21 +129,94 @@ static int parse_cmdbits(OPCODE * op);
|
||||
%token K_READMEM
|
||||
%token K_RESET
|
||||
%token K_RETRY_PULSE
|
||||
%token K_SERBB
|
||||
%token K_SERIAL
|
||||
%token K_SCK
|
||||
%token K_SIGNATURE
|
||||
%token K_SIZE
|
||||
%token K_STK500
|
||||
%token K_STK500HVSP
|
||||
%token K_STK500PP
|
||||
%token K_STK500V2
|
||||
%token K_STK500GENERIC
|
||||
%token K_STK600
|
||||
%token K_STK600HVSP
|
||||
%token K_STK600PP
|
||||
%token K_AVR910
|
||||
%token K_USBASP
|
||||
%token K_USBTINY
|
||||
%token K_BUTTERFLY
|
||||
%token K_TYPE
|
||||
%token K_VCC
|
||||
%token K_VFYLED
|
||||
%token K_WRITEPAGE
|
||||
|
||||
%token K_NO
|
||||
%token K_YES
|
||||
|
||||
/* stk500 v2 xml file parameters */
|
||||
/* ISP */
|
||||
%token K_TIMEOUT
|
||||
%token K_STABDELAY
|
||||
%token K_CMDEXEDELAY
|
||||
%token K_HVSPCMDEXEDELAY
|
||||
%token K_SYNCHLOOPS
|
||||
%token K_BYTEDELAY
|
||||
%token K_POLLVALUE
|
||||
%token K_POLLINDEX
|
||||
%token K_PREDELAY
|
||||
%token K_POSTDELAY
|
||||
%token K_POLLMETHOD
|
||||
%token K_MODE
|
||||
%token K_DELAY
|
||||
%token K_BLOCKSIZE
|
||||
%token K_READSIZE
|
||||
/* HV mode */
|
||||
%token K_HVENTERSTABDELAY
|
||||
%token K_PROGMODEDELAY
|
||||
%token K_LATCHCYCLES
|
||||
%token K_TOGGLEVTG
|
||||
%token K_POWEROFFDELAY
|
||||
%token K_RESETDELAYMS
|
||||
%token K_RESETDELAYUS
|
||||
%token K_HVLEAVESTABDELAY
|
||||
%token K_RESETDELAY
|
||||
%token K_SYNCHCYCLES
|
||||
%token K_HVCMDEXEDELAY
|
||||
|
||||
%token K_CHIPERASEPULSEWIDTH
|
||||
%token K_CHIPERASEPOLLTIMEOUT
|
||||
%token K_CHIPERASETIME
|
||||
%token K_PROGRAMFUSEPULSEWIDTH
|
||||
%token K_PROGRAMFUSEPOLLTIMEOUT
|
||||
%token K_PROGRAMLOCKPULSEWIDTH
|
||||
%token K_PROGRAMLOCKPOLLTIMEOUT
|
||||
|
||||
%token K_PP_CONTROLSTACK
|
||||
%token K_HVSP_CONTROLSTACK
|
||||
|
||||
/* JTAG ICE mkII specific parameters */
|
||||
%token K_ALLOWFULLPAGEBITSTREAM /*
|
||||
* Internal parameter for the JTAG
|
||||
* ICE; describes the internal JTAG
|
||||
* streaming behaviour inside the MCU.
|
||||
* 1 for all older chips, 0 for newer
|
||||
* MCUs.
|
||||
*/
|
||||
%token K_ENABLEPAGEPROGRAMMING /* ? yes for mega256*, mega406 */
|
||||
%token K_HAS_JTAG /* MCU has JTAG i/f. */
|
||||
%token K_HAS_DW /* MCU has debugWire i/f. */
|
||||
%token K_HAS_PDI /* MCU has PDI i/f rather than ISP (ATxmega). */
|
||||
%token K_IDR /* address of OCD register in IO space */
|
||||
%token K_RAMPZ /* address of RAMPZ reg. in IO space */
|
||||
%token K_SPMCR /* address of SPMC[S]R in memory space */
|
||||
%token K_EECR /* address of EECR in memory space */
|
||||
%token K_FLASH_INSTR /* flash instructions */
|
||||
%token K_EEPROM_INSTR /* EEPROM instructions */
|
||||
|
||||
%token TKN_COMMA
|
||||
%token TKN_EQUAL
|
||||
%token TKN_SEMI
|
||||
%token TKN_TILDE
|
||||
%token TKN_NUMBER
|
||||
%token TKN_STRING
|
||||
%token TKN_ID
|
||||
@@ -278,12 +383,144 @@ prog_parm :
|
||||
}
|
||||
} |
|
||||
|
||||
K_TYPE TKN_EQUAL K_SERBB {
|
||||
{
|
||||
serbb_initpgm(current_prog);
|
||||
}
|
||||
} |
|
||||
|
||||
K_TYPE TKN_EQUAL K_STK500 {
|
||||
{
|
||||
stk500_initpgm(current_prog);
|
||||
}
|
||||
} |
|
||||
|
||||
K_TYPE TKN_EQUAL K_STK500V2 {
|
||||
{
|
||||
stk500v2_initpgm(current_prog);
|
||||
}
|
||||
} |
|
||||
|
||||
K_TYPE TKN_EQUAL K_STK500HVSP {
|
||||
{
|
||||
stk500hvsp_initpgm(current_prog);
|
||||
}
|
||||
} |
|
||||
|
||||
K_TYPE TKN_EQUAL K_STK500PP {
|
||||
{
|
||||
stk500pp_initpgm(current_prog);
|
||||
}
|
||||
} |
|
||||
|
||||
K_TYPE TKN_EQUAL K_STK500GENERIC {
|
||||
{
|
||||
stk500generic_initpgm(current_prog);
|
||||
}
|
||||
} |
|
||||
|
||||
K_TYPE TKN_EQUAL K_ARDUINO {
|
||||
{
|
||||
arduino_initpgm(current_prog);
|
||||
}
|
||||
} |
|
||||
|
||||
K_TYPE TKN_EQUAL K_STK600 {
|
||||
{
|
||||
stk600_initpgm(current_prog);
|
||||
}
|
||||
} |
|
||||
|
||||
K_TYPE TKN_EQUAL K_STK600HVSP {
|
||||
{
|
||||
stk600hvsp_initpgm(current_prog);
|
||||
}
|
||||
} |
|
||||
|
||||
K_TYPE TKN_EQUAL K_STK600PP {
|
||||
{
|
||||
stk600pp_initpgm(current_prog);
|
||||
}
|
||||
} |
|
||||
|
||||
K_TYPE TKN_EQUAL K_AVR910 {
|
||||
{
|
||||
avr910_initpgm(current_prog);
|
||||
}
|
||||
} |
|
||||
|
||||
K_TYPE TKN_EQUAL K_USBASP {
|
||||
{
|
||||
usbasp_initpgm(current_prog);
|
||||
}
|
||||
} |
|
||||
|
||||
K_TYPE TKN_EQUAL K_USBTINY {
|
||||
{
|
||||
usbtiny_initpgm(current_prog);
|
||||
}
|
||||
} |
|
||||
|
||||
K_TYPE TKN_EQUAL K_BUTTERFLY {
|
||||
{
|
||||
butterfly_initpgm(current_prog);
|
||||
}
|
||||
} |
|
||||
|
||||
K_TYPE TKN_EQUAL K_JTAG_MKI {
|
||||
{
|
||||
jtagmkI_initpgm(current_prog);
|
||||
}
|
||||
} |
|
||||
|
||||
K_TYPE TKN_EQUAL K_JTAG_MKII {
|
||||
{
|
||||
jtagmkII_initpgm(current_prog);
|
||||
}
|
||||
} |
|
||||
|
||||
K_TYPE TKN_EQUAL K_JTAG_MKII_DW {
|
||||
{
|
||||
jtagmkII_dw_initpgm(current_prog);
|
||||
}
|
||||
} |
|
||||
|
||||
K_TYPE TKN_EQUAL K_JTAG_MKII_ISP {
|
||||
{
|
||||
stk500v2_jtagmkII_initpgm(current_prog);
|
||||
}
|
||||
} |
|
||||
|
||||
K_TYPE TKN_EQUAL K_DRAGON_DW {
|
||||
{
|
||||
jtagmkII_dragon_dw_initpgm(current_prog);
|
||||
}
|
||||
} |
|
||||
|
||||
K_TYPE TKN_EQUAL K_DRAGON_HVSP {
|
||||
{
|
||||
stk500v2_dragon_hvsp_initpgm(current_prog);
|
||||
}
|
||||
} |
|
||||
|
||||
K_TYPE TKN_EQUAL K_DRAGON_ISP {
|
||||
{
|
||||
stk500v2_dragon_isp_initpgm(current_prog);
|
||||
}
|
||||
} |
|
||||
|
||||
K_TYPE TKN_EQUAL K_DRAGON_JTAG {
|
||||
{
|
||||
jtagmkII_dragon_initpgm(current_prog);
|
||||
}
|
||||
} |
|
||||
|
||||
K_TYPE TKN_EQUAL K_DRAGON_PP {
|
||||
{
|
||||
stk500v2_dragon_pp_initpgm(current_prog);
|
||||
}
|
||||
} |
|
||||
|
||||
K_DESC TKN_EQUAL TKN_STRING {
|
||||
strncpy(current_prog->desc, $3->value.string, PGM_DESCLEN);
|
||||
current_prog->desc[PGM_DESCLEN-1] = 0;
|
||||
@@ -300,15 +537,7 @@ prog_parm :
|
||||
while (lsize(number_list)) {
|
||||
t = lrmv_n(number_list, 1);
|
||||
pin = t->value.number;
|
||||
if ((pin < 2) || (pin > 9)) {
|
||||
fprintf(stderr,
|
||||
"%s: error at line %d of %s: VCC must be one or more "
|
||||
"pins from the range 2-9\n",
|
||||
progname, lineno, infile);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
current_prog->pinno[PPI_AVR_VCC] |= (1 << (pin-2));
|
||||
current_prog->pinno[PPI_AVR_VCC] |= (1 << pin);
|
||||
|
||||
free_token(t);
|
||||
}
|
||||
@@ -325,31 +554,40 @@ prog_parm :
|
||||
while (lsize(number_list)) {
|
||||
t = lrmv_n(number_list, 1);
|
||||
pin = t->value.number;
|
||||
if ((pin < 2) || (pin > 9)) {
|
||||
fprintf(stderr,
|
||||
"%s: error at line %d of %s: BUFF must be one or more "
|
||||
"pins from the range 2-9\n",
|
||||
progname, lineno, infile);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
current_prog->pinno[PPI_AVR_BUFF] |= (1 << (pin-2));
|
||||
current_prog->pinno[PPI_AVR_BUFF] |= (1 << pin);
|
||||
|
||||
free_token(t);
|
||||
}
|
||||
}
|
||||
} |
|
||||
|
||||
K_BAUDRATE TKN_EQUAL TKN_NUMBER {
|
||||
{
|
||||
current_prog->baudrate = $3->value.number;
|
||||
}
|
||||
} |
|
||||
|
||||
K_RESET TKN_EQUAL TKN_NUMBER { free_token($1);
|
||||
assign_pin(PIN_AVR_RESET, $3); } |
|
||||
assign_pin(PIN_AVR_RESET, $3, 0); } |
|
||||
K_SCK TKN_EQUAL TKN_NUMBER { free_token($1);
|
||||
assign_pin(PIN_AVR_SCK, $3); } |
|
||||
K_MOSI TKN_EQUAL TKN_NUMBER { assign_pin(PIN_AVR_MOSI, $3); } |
|
||||
K_MISO TKN_EQUAL TKN_NUMBER { assign_pin(PIN_AVR_MISO, $3); } |
|
||||
K_ERRLED TKN_EQUAL TKN_NUMBER { assign_pin(PIN_LED_ERR, $3); } |
|
||||
K_RDYLED TKN_EQUAL TKN_NUMBER { assign_pin(PIN_LED_RDY, $3); } |
|
||||
K_PGMLED TKN_EQUAL TKN_NUMBER { assign_pin(PIN_LED_PGM, $3); } |
|
||||
K_VFYLED TKN_EQUAL TKN_NUMBER { assign_pin(PIN_LED_VFY, $3); }
|
||||
assign_pin(PIN_AVR_SCK, $3, 0); } |
|
||||
K_MOSI TKN_EQUAL TKN_NUMBER { assign_pin(PIN_AVR_MOSI, $3, 0); } |
|
||||
K_MISO TKN_EQUAL TKN_NUMBER { assign_pin(PIN_AVR_MISO, $3, 0); } |
|
||||
K_ERRLED TKN_EQUAL TKN_NUMBER { assign_pin(PIN_LED_ERR, $3, 0); } |
|
||||
K_RDYLED TKN_EQUAL TKN_NUMBER { assign_pin(PIN_LED_RDY, $3, 0); } |
|
||||
K_PGMLED TKN_EQUAL TKN_NUMBER { assign_pin(PIN_LED_PGM, $3, 0); } |
|
||||
K_VFYLED TKN_EQUAL TKN_NUMBER { assign_pin(PIN_LED_VFY, $3, 0); } |
|
||||
|
||||
K_RESET TKN_EQUAL TKN_TILDE TKN_NUMBER { free_token($1);
|
||||
assign_pin(PIN_AVR_RESET, $4, 1); } |
|
||||
K_SCK TKN_EQUAL TKN_TILDE TKN_NUMBER { free_token($1);
|
||||
assign_pin(PIN_AVR_SCK, $4, 1); } |
|
||||
K_MOSI TKN_EQUAL TKN_TILDE TKN_NUMBER { assign_pin(PIN_AVR_MOSI, $4, 1); } |
|
||||
K_MISO TKN_EQUAL TKN_TILDE TKN_NUMBER { assign_pin(PIN_AVR_MISO, $4, 1); } |
|
||||
K_ERRLED TKN_EQUAL TKN_TILDE TKN_NUMBER { assign_pin(PIN_LED_ERR, $4, 1); } |
|
||||
K_RDYLED TKN_EQUAL TKN_TILDE TKN_NUMBER { assign_pin(PIN_LED_RDY, $4, 1); } |
|
||||
K_PGMLED TKN_EQUAL TKN_TILDE TKN_NUMBER { assign_pin(PIN_LED_PGM, $4, 1); } |
|
||||
K_VFYLED TKN_EQUAL TKN_TILDE TKN_NUMBER { assign_pin(PIN_LED_VFY, $4, 1); }
|
||||
;
|
||||
|
||||
|
||||
@@ -362,6 +600,7 @@ opcode :
|
||||
K_WRITE_HI |
|
||||
K_LOADPAGE_LO |
|
||||
K_LOADPAGE_HI |
|
||||
K_LOAD_EXT_ADDR |
|
||||
K_WRITEPAGE |
|
||||
K_CHIP_ERASE |
|
||||
K_PGM_ENABLE
|
||||
@@ -403,11 +642,187 @@ part_parm :
|
||||
|
||||
K_DEVICECODE TKN_EQUAL TKN_NUMBER {
|
||||
{
|
||||
current_part->devicecode = $3->value.number;
|
||||
fprintf(stderr,
|
||||
"%s: error at %s:%d: devicecode is deprecated, use "
|
||||
"stk500_devcode instead\n",
|
||||
progname, infile, lineno);
|
||||
exit(1);
|
||||
}
|
||||
} |
|
||||
|
||||
K_STK500_DEVCODE TKN_EQUAL TKN_NUMBER {
|
||||
{
|
||||
current_part->stk500_devcode = $3->value.number;
|
||||
free_token($3);
|
||||
}
|
||||
} |
|
||||
|
||||
K_AVR910_DEVCODE TKN_EQUAL TKN_NUMBER {
|
||||
{
|
||||
current_part->avr910_devcode = $3->value.number;
|
||||
free_token($3);
|
||||
}
|
||||
} |
|
||||
|
||||
K_SIGNATURE TKN_EQUAL TKN_NUMBER TKN_NUMBER TKN_NUMBER {
|
||||
{
|
||||
current_part->signature[0] = $3->value.number;
|
||||
current_part->signature[1] = $4->value.number;
|
||||
current_part->signature[2] = $5->value.number;
|
||||
free_token($3);
|
||||
free_token($4);
|
||||
free_token($5);
|
||||
}
|
||||
} |
|
||||
|
||||
K_PP_CONTROLSTACK TKN_EQUAL num_list {
|
||||
{
|
||||
TOKEN * t;
|
||||
unsigned nbytes;
|
||||
int ok;
|
||||
|
||||
if (current_part->ctl_stack_type != CTL_STACK_NONE)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: error at line %d of %s: "
|
||||
"control stack already defined\n",
|
||||
progname, lineno, infile);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
current_part->ctl_stack_type = CTL_STACK_PP;
|
||||
nbytes = 0;
|
||||
ok = 1;
|
||||
|
||||
while (lsize(number_list)) {
|
||||
t = lrmv_n(number_list, 1);
|
||||
if (nbytes < CTL_STACK_SIZE)
|
||||
{
|
||||
current_part->controlstack[nbytes] = t->value.number;
|
||||
nbytes++;
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = 0;
|
||||
}
|
||||
free_token(t);
|
||||
}
|
||||
if (!ok)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: Warning: line %d of %s: "
|
||||
"too many bytes in control stack\n",
|
||||
progname, lineno, infile);
|
||||
}
|
||||
}
|
||||
} |
|
||||
|
||||
K_HVSP_CONTROLSTACK TKN_EQUAL num_list {
|
||||
{
|
||||
TOKEN * t;
|
||||
unsigned nbytes;
|
||||
int ok;
|
||||
|
||||
if (current_part->ctl_stack_type != CTL_STACK_NONE)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: error at line %d of %s: "
|
||||
"control stack already defined\n",
|
||||
progname, lineno, infile);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
current_part->ctl_stack_type = CTL_STACK_HVSP;
|
||||
nbytes = 0;
|
||||
ok = 1;
|
||||
|
||||
while (lsize(number_list)) {
|
||||
t = lrmv_n(number_list, 1);
|
||||
if (nbytes < CTL_STACK_SIZE)
|
||||
{
|
||||
current_part->controlstack[nbytes] = t->value.number;
|
||||
nbytes++;
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = 0;
|
||||
}
|
||||
free_token(t);
|
||||
}
|
||||
if (!ok)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: Warning: line %d of %s: "
|
||||
"too many bytes in control stack\n",
|
||||
progname, lineno, infile);
|
||||
}
|
||||
}
|
||||
} |
|
||||
|
||||
K_FLASH_INSTR TKN_EQUAL num_list {
|
||||
{
|
||||
TOKEN * t;
|
||||
unsigned nbytes;
|
||||
int ok;
|
||||
|
||||
nbytes = 0;
|
||||
ok = 1;
|
||||
|
||||
while (lsize(number_list)) {
|
||||
t = lrmv_n(number_list, 1);
|
||||
if (nbytes < FLASH_INSTR_SIZE)
|
||||
{
|
||||
current_part->flash_instr[nbytes] = t->value.number;
|
||||
nbytes++;
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = 0;
|
||||
}
|
||||
free_token(t);
|
||||
}
|
||||
if (!ok)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: Warning: line %d of %s: "
|
||||
"too many bytes in flash instructions\n",
|
||||
progname, lineno, infile);
|
||||
}
|
||||
}
|
||||
} |
|
||||
|
||||
K_EEPROM_INSTR TKN_EQUAL num_list {
|
||||
{
|
||||
TOKEN * t;
|
||||
unsigned nbytes;
|
||||
int ok;
|
||||
|
||||
nbytes = 0;
|
||||
ok = 1;
|
||||
|
||||
while (lsize(number_list)) {
|
||||
t = lrmv_n(number_list, 1);
|
||||
if (nbytes < EEPROM_INSTR_SIZE)
|
||||
{
|
||||
current_part->eeprom_instr[nbytes] = t->value.number;
|
||||
nbytes++;
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = 0;
|
||||
}
|
||||
free_token(t);
|
||||
}
|
||||
if (!ok)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: Warning: line %d of %s: "
|
||||
"too many bytes in EEPROM instructions\n",
|
||||
progname, lineno, infile);
|
||||
}
|
||||
}
|
||||
} |
|
||||
|
||||
K_CHIP_ERASE_DELAY TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->chip_erase_delay = $3->value.number;
|
||||
@@ -436,6 +851,254 @@ part_parm :
|
||||
free_tokens(2, $1, $3);
|
||||
} |
|
||||
|
||||
K_TIMEOUT TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->timeout = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_STABDELAY TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->stabdelay = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_CMDEXEDELAY TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->cmdexedelay = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_HVSPCMDEXEDELAY TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->hvspcmdexedelay = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_SYNCHLOOPS TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->synchloops = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_BYTEDELAY TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->bytedelay = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_POLLVALUE TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->pollvalue = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_POLLINDEX TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->pollindex = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_PREDELAY TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->predelay = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_POSTDELAY TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->postdelay = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_POLLMETHOD TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->pollmethod = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_HVENTERSTABDELAY TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->hventerstabdelay = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_PROGMODEDELAY TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->progmodedelay = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_LATCHCYCLES TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->latchcycles = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_TOGGLEVTG TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->togglevtg = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_POWEROFFDELAY TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->poweroffdelay = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_RESETDELAYMS TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->resetdelayms = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_RESETDELAYUS TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->resetdelayus = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_HVLEAVESTABDELAY TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->hvleavestabdelay = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_RESETDELAY TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->resetdelay = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_CHIPERASEPULSEWIDTH TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->chiperasepulsewidth = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_CHIPERASEPOLLTIMEOUT TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->chiperasepolltimeout = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_CHIPERASETIME TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->chiperasetime = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_PROGRAMFUSEPULSEWIDTH TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->programfusepulsewidth = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_PROGRAMFUSEPOLLTIMEOUT TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->programfusepolltimeout = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_PROGRAMLOCKPULSEWIDTH TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->programlockpulsewidth = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_PROGRAMLOCKPOLLTIMEOUT TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->programlockpolltimeout = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_SYNCHCYCLES TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->synchcycles = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_HAS_JTAG TKN_EQUAL yesno
|
||||
{
|
||||
if ($3->primary == K_YES)
|
||||
current_part->flags |= AVRPART_HAS_JTAG;
|
||||
else if ($3->primary == K_NO)
|
||||
current_part->flags &= ~AVRPART_HAS_JTAG;
|
||||
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_HAS_DW TKN_EQUAL yesno
|
||||
{
|
||||
if ($3->primary == K_YES)
|
||||
current_part->flags |= AVRPART_HAS_DW;
|
||||
else if ($3->primary == K_NO)
|
||||
current_part->flags &= ~AVRPART_HAS_DW;
|
||||
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_HAS_PDI TKN_EQUAL yesno
|
||||
{
|
||||
if ($3->primary == K_YES)
|
||||
current_part->flags |= AVRPART_HAS_PDI;
|
||||
else if ($3->primary == K_NO)
|
||||
current_part->flags &= ~AVRPART_HAS_PDI;
|
||||
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_ALLOWFULLPAGEBITSTREAM TKN_EQUAL yesno
|
||||
{
|
||||
if ($3->primary == K_YES)
|
||||
current_part->flags |= AVRPART_ALLOWFULLPAGEBITSTREAM;
|
||||
else if ($3->primary == K_NO)
|
||||
current_part->flags &= ~AVRPART_ALLOWFULLPAGEBITSTREAM;
|
||||
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_ENABLEPAGEPROGRAMMING TKN_EQUAL yesno
|
||||
{
|
||||
if ($3->primary == K_YES)
|
||||
current_part->flags |= AVRPART_ENABLEPAGEPROGRAMMING;
|
||||
else if ($3->primary == K_NO)
|
||||
current_part->flags &= ~AVRPART_ENABLEPAGEPROGRAMMING;
|
||||
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_IDR TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->idr = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_RAMPZ TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->rampz = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_SPMCR TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->spmcr = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_EECR TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->eecr = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_NVM_BASE TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_part->nvm_base = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_SERIAL TKN_EQUAL yesno
|
||||
{
|
||||
if ($3->primary == K_YES)
|
||||
@@ -553,6 +1216,12 @@ mem_spec :
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_OFFSET TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_mem->offset = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_MIN_WRITE_DELAY TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_mem->min_write_delay = $3->value.number;
|
||||
@@ -583,6 +1252,38 @@ mem_spec :
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
|
||||
K_MODE TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_mem->mode = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_DELAY TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_mem->delay = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_BLOCKSIZE TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_mem->blocksize = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_READSIZE TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_mem->readsize = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_POLLINDEX TKN_EQUAL TKN_NUMBER
|
||||
{
|
||||
current_mem->pollindex = $3->value.number;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
|
||||
opcode TKN_EQUAL string_list {
|
||||
{
|
||||
int opnum;
|
||||
@@ -614,7 +1315,7 @@ static char * vtypestr(int type)
|
||||
#endif
|
||||
|
||||
|
||||
static int assign_pin(int pinno, TOKEN * v)
|
||||
static int assign_pin(int pinno, TOKEN * v, int invert)
|
||||
{
|
||||
int value;
|
||||
|
||||
@@ -627,6 +1328,8 @@ static int assign_pin(int pinno, TOKEN * v)
|
||||
progname, lineno, infile);
|
||||
exit(1);
|
||||
}
|
||||
if (invert)
|
||||
value |= PIN_INVERSE;
|
||||
|
||||
current_prog->pinno[pinno] = value;
|
||||
|
||||
@@ -645,6 +1348,7 @@ static int which_opcode(TOKEN * opcode)
|
||||
case K_WRITE_HI : return AVR_OP_WRITE_HI; break;
|
||||
case K_LOADPAGE_LO : return AVR_OP_LOADPAGE_LO; break;
|
||||
case K_LOADPAGE_HI : return AVR_OP_LOADPAGE_HI; break;
|
||||
case K_LOAD_EXT_ADDR : return AVR_OP_LOAD_EXT_ADDR; break;
|
||||
case K_WRITEPAGE : return AVR_OP_WRITEPAGE; break;
|
||||
case K_CHIP_ERASE : return AVR_OP_CHIP_ERASE; break;
|
||||
case K_PGM_ENABLE : return AVR_OP_PGM_ENABLE; break;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#
|
||||
# avrdude - A Downloader/Uploader for AVR device programmers
|
||||
# Copyright (C) 2003 Theodore A. Roth <troth@openavr.org>
|
||||
# Copyright (C) 2003, 2004 Theodore A. Roth <troth@openavr.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -24,7 +24,7 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.57)
|
||||
AC_INIT(avrdude, 4.0.0, avrdude-dev@nongnu.org)
|
||||
AC_INIT(avrdude, 5.7, avrdude-dev@nongnu.org)
|
||||
|
||||
AC_CANONICAL_BUILD
|
||||
AC_CANONICAL_HOST
|
||||
@@ -32,30 +32,101 @@ AC_CANONICAL_TARGET
|
||||
|
||||
AC_CONFIG_SRCDIR([main.c])
|
||||
AM_INIT_AUTOMAKE
|
||||
AM_CONFIG_HEADER([ac_cfg.h])
|
||||
AM_CONFIG_HEADER(ac_cfg.h)
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_YACC
|
||||
AM_PROG_LEX
|
||||
AC_PROG_LEX
|
||||
AC_PROG_RANLIB
|
||||
|
||||
dnl Makefile.am:77: compiling `config_gram.c' with per-target flags requires `AM_PROG_CC_C_O' in `configure.ac'
|
||||
AM_PROG_CC_C_O
|
||||
|
||||
# Checks for libraries.
|
||||
AC_CHECK_LIB([termcap], [tputs])
|
||||
AC_CHECK_LIB([ncurses], [tputs])
|
||||
AC_CHECK_LIB([readline], [readline])
|
||||
AC_SEARCH_LIBS([gethostent], [nsl])
|
||||
AC_SEARCH_LIBS([setsockopt], [socket])
|
||||
AH_TEMPLATE([HAVE_LIBUSB],
|
||||
[Define if USB support is enabled via libusb])
|
||||
AC_CHECK_LIB([usb], [usb_get_string_simple], [have_libusb=yes])
|
||||
if test x$have_libusb = xyes; then
|
||||
case $target in
|
||||
*-*-darwin*)
|
||||
LIBUSB="-lusb -framework CoreFoundation -framework IOKit"
|
||||
;;
|
||||
*)
|
||||
LIBUSB="-lusb"
|
||||
;;
|
||||
esac
|
||||
AC_DEFINE([HAVE_LIBUSB])
|
||||
fi
|
||||
AC_SUBST(LIBUSB, $LIBUSB)
|
||||
|
||||
# Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS([fcntl.h limits.h stdlib.h string.h sys/ioctl.h sys/time.h termios.h unistd.h])
|
||||
AC_CHECK_HEADERS([limits.h stdlib.h string.h])
|
||||
AC_CHECK_HEADERS([fcntl.h sys/ioctl.h sys/time.h termios.h unistd.h])
|
||||
AC_CHECK_HEADERS([ddk/hidsdi.h],,,[#include <windows.h>
|
||||
#include <setupapi.h>])
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
AC_HEADER_TIME
|
||||
|
||||
# Checks for library functions.
|
||||
AC_PROG_GCC_TRADITIONAL
|
||||
AC_FUNC_MALLOC
|
||||
AC_CHECK_FUNCS([memset select strcasecmp strdup strerror strncasecmp strtol strtoul])
|
||||
AC_CHECK_FUNCS([memset select strcasecmp strdup strerror strncasecmp strtol strtoul gettimeofday])
|
||||
|
||||
AC_MSG_CHECKING([for a Win32 HID libray])
|
||||
SAVED_LIBS="${LIBS}"
|
||||
case $target in
|
||||
*-*-mingw32* | *-*-cygwin* | *-*-windows*)
|
||||
LIBHID="-lhid -lsetupapi"
|
||||
if test $ac_cv_header_ddk_hidsdi_h = yes
|
||||
then
|
||||
HIDINCLUDE="#include <ddk/hidsdi.h>"
|
||||
else
|
||||
HIDINCLUDE="#include \"my_ddk_hidsdi.h\""
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
LIBHID=""
|
||||
;;
|
||||
esac
|
||||
LIBS="${LIBS} ${LIBHID}"
|
||||
|
||||
AH_TEMPLATE([HAVE_LIBHID],
|
||||
[Define if HID support is enabled via the Win32 DDK])
|
||||
AC_TRY_RUN([#include <windows.h>
|
||||
#include <setupapi.h>
|
||||
$HIDINCLUDE
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
GUID hidGuid;
|
||||
HidD_GetHidGuid(&hidGuid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
], [have_libhid=yes], [have_libhid=no], [have_libhid=no])
|
||||
AC_MSG_RESULT([$have_libhid])
|
||||
if test x$have_libhid = xyes; then
|
||||
AC_DEFINE([HAVE_LIBHID])
|
||||
else
|
||||
LIBHID=""
|
||||
fi
|
||||
LIBS="${SAVED_LIBS}"
|
||||
AC_SUBST(LIBHID, $LIBHID)
|
||||
|
||||
# Check for types
|
||||
|
||||
# Solaris has uint_t and ulong_t typedefs in <sys/types.h>, avoid
|
||||
# the redeclaration in usbtiny.c.
|
||||
AC_CHECK_TYPES([uint_t], [], [], [#include <sys/types.h>])
|
||||
AC_CHECK_TYPES([ulong_t], [], [], [#include <sys/types.h>])
|
||||
|
||||
# Checks for misc stuff.
|
||||
|
||||
@@ -77,12 +148,47 @@ else
|
||||
DOC_INST_DIR='$(DESTDIR)$(datadir)/doc/avrdude'
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
[doc],
|
||||
AC_HELP_STRING(
|
||||
[--enable-doc],
|
||||
[Enable building documents]),
|
||||
[case "${enableval}" in
|
||||
yes) enabled_doc=yes ;;
|
||||
no) enabled_doc=no ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for disable-doc option) ;;
|
||||
esac],
|
||||
[enabled_doc=no])
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
[parport],
|
||||
AC_HELP_STRING(
|
||||
[--enable-parport],
|
||||
[Enable accessing parallel ports(default)]),
|
||||
[case "${enableval}" in
|
||||
yes) enabled_parport=yes ;;
|
||||
no) enabled_parport=no ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for enable-parport option) ;;
|
||||
esac],
|
||||
[enabled_parport=yes])
|
||||
|
||||
DIST_SUBDIRS_AC='doc windows'
|
||||
|
||||
if test "$enabled_doc" = "yes"; then
|
||||
SUBDIRS_AC='doc'
|
||||
else
|
||||
SUBDIRS_AC=''
|
||||
fi
|
||||
|
||||
AC_SUBST(DOC_INST_DIR, $DOC_INST_DIR)
|
||||
AC_SUBST(SUBDIRS_AC, $SUBDIRS_AC)
|
||||
AC_SUBST(DIST_SUBDIRS_AC, $DIST_SUBDIRS_AC)
|
||||
|
||||
|
||||
# Find the parallel serial device files based on target system
|
||||
# If a system doesn't have a PC style parallel, mark it as unknown.
|
||||
case $target in
|
||||
i[[3456]]86-*-linux*)
|
||||
i[[3456]]86-*-linux*|x86_64-*-linux*)
|
||||
DEFAULT_PAR_PORT="/dev/parport0"
|
||||
DEFAULT_SER_PORT="/dev/ttyS0"
|
||||
;;
|
||||
@@ -90,7 +196,7 @@ case $target in
|
||||
DEFAULT_PAR_PORT="unknown"
|
||||
DEFAULT_SER_PORT="/dev/ttyS0"
|
||||
;;
|
||||
i[[3456]]86-*-freebsd*)
|
||||
i[[3456]]86-*-freebsd*|amd64-*-freebsd*)
|
||||
DEFAULT_PAR_PORT="/dev/ppi0"
|
||||
DEFAULT_SER_PORT="/dev/cuaa0"
|
||||
;;
|
||||
@@ -98,6 +204,10 @@ case $target in
|
||||
DEFAULT_PAR_PORT="unknown"
|
||||
DEFAULT_SER_PORT="/dev/cuaa0"
|
||||
;;
|
||||
*-*-solaris*)
|
||||
DEFAULT_PAR_PORT="/dev/printers/0"
|
||||
DEFAULT_SER_PORT="/dev/term/a"
|
||||
;;
|
||||
*-*-msdos* | *-*-mingw32* | *-*-cygwin* | *-*-windows*)
|
||||
DEFAULT_PAR_PORT="lpt1"
|
||||
DEFAULT_SER_PORT="com1"
|
||||
@@ -108,27 +218,60 @@ case $target in
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_MSG_CHECKING([for parallel device])
|
||||
AC_MSG_RESULT([$DEFAULT_PAR_PORT])
|
||||
AC_SUBST(DEFAULT_PAR_PORT, $DEFAULT_PAR_PORT)
|
||||
if test "$enabled_parport" = "yes"; then
|
||||
AC_MSG_CHECKING([for parallel device])
|
||||
if test "$DEFAULT_PAR_PORT" = "unknown"; then
|
||||
AC_MSG_NOTICE([parallel port access disabled for this system])
|
||||
enabled_parport=no
|
||||
else
|
||||
AC_MSG_RESULT([$DEFAULT_PAR_PORT])
|
||||
fi
|
||||
AC_SUBST(DEFAULT_PAR_PORT, $DEFAULT_PAR_PORT)
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([for serial device])
|
||||
AC_MSG_RESULT([$DEFAULT_SER_PORT])
|
||||
AC_SUBST(DEFAULT_SER_PORT, $DEFAULT_SER_PORT)
|
||||
|
||||
if test "$enabled_parport" = "yes"; then
|
||||
AC_DEFINE(HAVE_PARPORT, 1, [parallel port access enabled])
|
||||
confsubst="-e /^@HAVE_PARPORT_/d"
|
||||
else
|
||||
confsubst="-e /^@HAVE_PARPORT_BEGIN@/,/^@HAVE_PARPORT_END@/d"
|
||||
fi
|
||||
export confsubst
|
||||
|
||||
# See if we need to drop into the windows subdir.
|
||||
case $target in
|
||||
*-*-mingw32* | *-*-cygwin* | *-*-windows*)
|
||||
WINDOWS_DIRS="windows"
|
||||
CFLAGS="${CFLAGS} -mno-cygwin -DWIN32NATIVE"
|
||||
LDFLAGS="${LDFLAGS} -static"
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(WINDOWS_DIRS,$WINDOWS_DIRS)
|
||||
|
||||
# If we are compiling with gcc, enable all warning and make warnings errors.
|
||||
if test "$GCC" = yes; then
|
||||
ENABLE_WARNINGS="-Wall"
|
||||
fi
|
||||
AC_SUBST(ENABLE_WARNINGS,$ENABLE_WARNINGS)
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
doc/Makefile
|
||||
windows/Makefile
|
||||
avrdude.spec
|
||||
avrdude.conf
|
||||
Makefile
|
||||
doc/Makefile
|
||||
windows/Makefile
|
||||
avrdude.spec
|
||||
Makefile
|
||||
])
|
||||
|
||||
# The procedure to create avrdude.conf involves two steps. First,
|
||||
# normal autoconf substitution will be applied, resulting in
|
||||
# avrdude.conf.tmp. Finally, a sed command will be applied to filter
|
||||
# out unwanted parts (currently the parallel port programmer types)
|
||||
# based on previous configuration results, thereby producing the final
|
||||
# avrdude.conf file.
|
||||
|
||||
AC_CONFIG_FILES([avrdude.conf.tmp:avrdude.conf.in],
|
||||
[sed $confsubst avrdude.conf.tmp > avrdude.conf])
|
||||
|
||||
AC_OUTPUT
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2003 Eric B. Weddington <eric@umginc.net> or <eric@ecentral.com>
|
||||
* Copyright (C) 2003-2004 Eric B. Weddington <eric@ecentral.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
|
||||
@@ -18,8 +18,9 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "avrdude.h"
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
#if defined(WIN32NATIVE)
|
||||
|
||||
#include <limits.h>
|
||||
#include <windows.h>
|
||||
@@ -30,6 +31,8 @@ static char *filename;
|
||||
|
||||
void win_sys_config_set(char sys_config[PATH_MAX])
|
||||
{
|
||||
sys_config[0] = 0;
|
||||
|
||||
/* Use Windows API call to search for the Windows default system config file.*/
|
||||
SearchPath(NULL, "avrdude.conf", NULL, PATH_MAX, sys_config, &filename);
|
||||
return;
|
||||
@@ -38,6 +41,8 @@ void win_sys_config_set(char sys_config[PATH_MAX])
|
||||
|
||||
void win_usr_config_set(char usr_config[PATH_MAX])
|
||||
{
|
||||
usr_config[0] = 0;
|
||||
|
||||
/* Use Windows API call to search for the Windows default user config file. */
|
||||
SearchPath(NULL, "avrdude.rc", NULL, PATH_MAX, usr_config, &filename);
|
||||
return;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2003 Eric B. Weddington <eric@umginc.net> or <eric@ecentral.com>
|
||||
* Copyright (C) 2003-2004 Eric B. Weddington <eric@ecentral.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
|
||||
@@ -19,15 +19,20 @@
|
||||
|
||||
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
#ifndef __confwin_h__
|
||||
#define __confwin_h__
|
||||
#if defined(WIN32NATIVE)
|
||||
#ifndef confwin_h
|
||||
#define confwin_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void win_sys_config_set(char sys_config[PATH_MAX]);
|
||||
void win_usr_config_set(char usr_config[PATH_MAX]);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
83
avrdude/crc16.c
Normal file
83
avrdude/crc16.c
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Derived from CRC algorithm for JTAG ICE mkII, published in Atmel
|
||||
* Appnote AVR067. Converted from C++ to C.
|
||||
*/
|
||||
#include "crc16.h"
|
||||
|
||||
/* CRC16 Definitions */
|
||||
static const unsigned short crc_table[256] = {
|
||||
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
|
||||
0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
|
||||
0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
|
||||
0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
|
||||
0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
|
||||
0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
|
||||
0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
|
||||
0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
|
||||
0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
|
||||
0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
|
||||
0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
|
||||
0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
|
||||
0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
|
||||
0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
|
||||
0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
|
||||
0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
|
||||
0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
|
||||
0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
|
||||
0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
|
||||
0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
|
||||
0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
|
||||
0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
|
||||
0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
|
||||
0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
|
||||
0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
|
||||
0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
|
||||
0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
|
||||
0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
|
||||
0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
|
||||
0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
|
||||
0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
|
||||
0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
|
||||
};
|
||||
|
||||
/* CRC calculation macros */
|
||||
#define CRC_INIT 0xFFFF
|
||||
#define CRC(crcval,newchar) crcval = (crcval >> 8) ^ \
|
||||
crc_table[(crcval ^ newchar) & 0x00ff]
|
||||
|
||||
unsigned short
|
||||
crcsum(const unsigned char* message, unsigned long length,
|
||||
unsigned short crc)
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
for(i = 0; i < length; i++)
|
||||
{
|
||||
CRC(crc, message[i]);
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
int
|
||||
crcverify(const unsigned char* message, unsigned long length)
|
||||
{
|
||||
/*
|
||||
* Returns true if the last two bytes in a message is the crc of the
|
||||
* preceding bytes.
|
||||
*/
|
||||
unsigned short expected;
|
||||
|
||||
expected = crcsum(message, length - 2, CRC_INIT);
|
||||
return (expected & 0xff) == message[length - 2] &&
|
||||
((expected >> 8) & 0xff) == message[length - 1];
|
||||
}
|
||||
|
||||
void
|
||||
crcappend(unsigned char* message, unsigned long length)
|
||||
{
|
||||
unsigned long crc;
|
||||
|
||||
crc = crcsum(message, length, CRC_INIT);
|
||||
message[length] = (unsigned char)(crc & 0xff);
|
||||
message[length+1] = (unsigned char)((crc >> 8) & 0xff);
|
||||
}
|
||||
34
avrdude/crc16.h
Normal file
34
avrdude/crc16.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef CRC16_H
|
||||
#define CRC16_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Derived from CRC algorithm for JTAG ICE mkII, published in Atmel
|
||||
* Appnote AVR067. Converted from C++ to C.
|
||||
*/
|
||||
|
||||
extern unsigned short crcsum(const unsigned char* message,
|
||||
unsigned long length,
|
||||
unsigned short crc);
|
||||
/*
|
||||
* Verify that the last two bytes is a (LSB first) valid CRC of the
|
||||
* message.
|
||||
*/
|
||||
extern int crcverify(const unsigned char* message,
|
||||
unsigned long length);
|
||||
/*
|
||||
* Append a two byte CRC (LSB first) to message. length is size of
|
||||
* message excluding crc. Space for the CRC bytes must be allocated
|
||||
* in advance!
|
||||
*/
|
||||
extern void crcappend(unsigned char* message,
|
||||
unsigned long length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
22
avrdude/doc/.cvsignore
Normal file
22
avrdude/doc/.cvsignore
Normal file
@@ -0,0 +1,22 @@
|
||||
.cvsignore
|
||||
Makefile
|
||||
Makefile.in
|
||||
avrdude-html
|
||||
avrdude.aux
|
||||
avrdude.cp
|
||||
avrdude.cps
|
||||
avrdude.dvi
|
||||
avrdude.fn
|
||||
avrdude.info
|
||||
avrdude.ky
|
||||
avrdude.log
|
||||
avrdude.pdf
|
||||
avrdude.pg
|
||||
avrdude.ps
|
||||
avrdude.toc
|
||||
avrdude.tp
|
||||
avrdude.vr
|
||||
mdate-sh
|
||||
stamp-vti
|
||||
texinfo.tex
|
||||
version.texi
|
||||
@@ -29,10 +29,16 @@ info_TEXINFOS = avrdude.texi
|
||||
|
||||
all-local: info html ps pdf
|
||||
|
||||
html:
|
||||
mkdir -p avrdude-html
|
||||
html: avrdude-html/avrdude.html
|
||||
|
||||
avrdude-html/avrdude.html: $(srcdir)/$(info_TEXINFOS)
|
||||
texi2html -split_node $(srcdir)/$(info_TEXINFOS)
|
||||
mv *.html avrdude-html
|
||||
if [ -e ./avrdude.html -o -e ./avrdude_1.html ]; then \
|
||||
mkdir -p avrdude-html ; \
|
||||
mv -f *.html avrdude-html ; \
|
||||
else \
|
||||
mv -f avrdude avrdude-html; \
|
||||
fi;
|
||||
|
||||
clean-local:
|
||||
rm -rf avrdude-html *.info
|
||||
|
||||
@@ -1,11 +1,26 @@
|
||||
|
||||
General:
|
||||
- Man page needs updated for avr910 info.
|
||||
|
||||
- Website needs to link to docs:
|
||||
http://savannah.nongnu.org/download/avrdude/doc/avrdude-html/
|
||||
|
||||
- Add "skip empty pages" optimization on avr910 paged write. The stk500 has
|
||||
this optimization already.
|
||||
|
||||
Windows:
|
||||
- Use Windows API for stk500 serial port communications on Windows port.
|
||||
This might remove dependency on Cygwin.
|
||||
|
||||
- Add ability to find all parallel port names available and base addresses
|
||||
of available ports.
|
||||
- Fix "overfull \hbox" issues in building documentation.
|
||||
|
||||
- FIXME: term.c: terminal_get_input(): strip newlines in non-readline input
|
||||
code.
|
||||
|
||||
- FIXME: avr910.c: avr910_cmd(): Insert version check here.
|
||||
|
||||
- FIXME: ser_posix.c: serial_close(): Should really restore the terminal to
|
||||
original state here.
|
||||
|
||||
- FIXME: main.c, par.c: exitspecs don't work if RESET-pin is controlled over
|
||||
PPICTRL.
|
||||
|
||||
- transfer ppi-speedtuning to the windows version (CAVEAT: This will make
|
||||
programming too fast for chips with 500kHz clock)
|
||||
|
||||
- make SCK-period configurable for PPI-programmers
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
390
avrdude/fileio.c
390
avrdude/fileio.c
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.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
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "avr.h"
|
||||
#include "fileio.h"
|
||||
|
||||
@@ -46,37 +47,38 @@ struct ihexrec {
|
||||
};
|
||||
|
||||
|
||||
extern char * progname;
|
||||
extern char progbuf[];
|
||||
|
||||
int b2ihex(unsigned char * inbuf, int bufsize,
|
||||
static int b2ihex(unsigned char * inbuf, int bufsize,
|
||||
int recsize, int startaddr,
|
||||
char * outfile, FILE * outf);
|
||||
|
||||
int ihex2b(char * infile, FILE * inf,
|
||||
static int ihex2b(char * infile, FILE * inf,
|
||||
unsigned char * outbuf, int bufsize);
|
||||
|
||||
int b2srec(unsigned char * inbuf, int bufsize,
|
||||
static int b2srec(unsigned char * inbuf, int bufsize,
|
||||
int recsize, int startaddr,
|
||||
char * outfile, FILE * outf);
|
||||
|
||||
int srec2b(char * infile, FILE * inf,
|
||||
static int srec2b(char * infile, FILE * inf,
|
||||
unsigned char * outbuf, int bufsize);
|
||||
|
||||
int ihex_readrec(struct ihexrec * ihex, char * rec);
|
||||
static int ihex_readrec(struct ihexrec * ihex, char * rec);
|
||||
|
||||
int srec_readrec(struct ihexrec * srec, char * rec);
|
||||
static int srec_readrec(struct ihexrec * srec, char * rec);
|
||||
|
||||
int fileio_rbin(struct fioparms * fio,
|
||||
static int fileio_rbin(struct fioparms * fio,
|
||||
char * filename, FILE * f, unsigned char * buf, int size);
|
||||
|
||||
int fileio_ihex(struct fioparms * fio,
|
||||
static int fileio_ihex(struct fioparms * fio,
|
||||
char * filename, FILE * f, unsigned char * buf, int size);
|
||||
|
||||
int fileio_srec(struct fioparms * fio,
|
||||
static int fileio_srec(struct fioparms * fio,
|
||||
char * filename, FILE * f, unsigned char * buf, int size);
|
||||
|
||||
int fmt_autodetect(char * fname);
|
||||
static int fileio_num(struct fioparms * fio,
|
||||
char * filename, FILE * f, unsigned char * buf, int size,
|
||||
FILEFMT fmt);
|
||||
|
||||
static int fmt_autodetect(char * fname);
|
||||
|
||||
|
||||
|
||||
@@ -93,7 +95,7 @@ char * fmtstr(FILEFMT format)
|
||||
|
||||
|
||||
|
||||
int b2ihex(unsigned char * inbuf, int bufsize,
|
||||
static int b2ihex(unsigned char * inbuf, int bufsize,
|
||||
int recsize, int startaddr,
|
||||
char * outfile, FILE * outf)
|
||||
{
|
||||
@@ -171,7 +173,7 @@ int b2ihex(unsigned char * inbuf, int bufsize,
|
||||
}
|
||||
|
||||
|
||||
int ihex_readrec(struct ihexrec * ihex, char * rec)
|
||||
static int ihex_readrec(struct ihexrec * ihex, char * rec)
|
||||
{
|
||||
int i, j;
|
||||
char buf[8];
|
||||
@@ -260,7 +262,7 @@ int ihex_readrec(struct ihexrec * ihex, char * rec)
|
||||
*
|
||||
* */
|
||||
|
||||
int ihex2b(char * infile, FILE * inf,
|
||||
static int ihex2b(char * infile, FILE * inf,
|
||||
unsigned char * outbuf, int bufsize)
|
||||
{
|
||||
char buffer [ MAX_LINE_LEN ];
|
||||
@@ -355,16 +357,15 @@ int ihex2b(char * infile, FILE * inf,
|
||||
}
|
||||
|
||||
|
||||
int b2srec(unsigned char * inbuf, int bufsize,
|
||||
static int b2srec(unsigned char * inbuf, int bufsize,
|
||||
int recsize, int startaddr,
|
||||
char * outfile, FILE * outf)
|
||||
{
|
||||
unsigned char * buf;
|
||||
unsigned int nextaddr, stopaddr;
|
||||
unsigned int nextaddr;
|
||||
int n, nbytes, addr_width;
|
||||
int i;
|
||||
unsigned char cksum;
|
||||
unsigned char startf, stopf ,emptyf;
|
||||
|
||||
char * tmpl=0;
|
||||
|
||||
@@ -373,39 +374,11 @@ int b2srec(unsigned char * inbuf, int bufsize,
|
||||
progname, recsize);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
nextaddr = startaddr;
|
||||
buf = inbuf;
|
||||
nextaddr = 0;
|
||||
stopaddr = 0;
|
||||
startf = 0;
|
||||
stopf = 0;
|
||||
nbytes = 0;
|
||||
|
||||
/* search for ranges of 'real' data */
|
||||
for (i=startaddr; i<bufsize; i++) {
|
||||
if (buf[i] == 0xff) {
|
||||
if (startf == 0)
|
||||
continue;
|
||||
else if (stopf == 0) {
|
||||
stopf = 1;
|
||||
stopaddr = i;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (startf == 0) {
|
||||
startf = 1;
|
||||
nextaddr = i;
|
||||
while (nextaddr % recsize != 0)
|
||||
nextaddr --;
|
||||
}
|
||||
else if (stopf == 1) {
|
||||
stopf = 0;
|
||||
stopaddr = bufsize;
|
||||
}
|
||||
}
|
||||
}
|
||||
nbytes = i;
|
||||
|
||||
bufsize = stopaddr - nextaddr;
|
||||
addr_width = 0;
|
||||
|
||||
while (bufsize) {
|
||||
@@ -435,34 +408,23 @@ int b2srec(unsigned char * inbuf, int bufsize,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* skip the lines filled with 0xff */
|
||||
emptyf = 1;
|
||||
fprintf(outf, tmpl, n + addr_width + 1, nextaddr);
|
||||
|
||||
cksum += n + addr_width + 1;
|
||||
|
||||
for (i=addr_width; i>0; i--)
|
||||
cksum += (nextaddr >> (i-1) * 8) & 0xff;
|
||||
|
||||
for (i=nextaddr; i<nextaddr + n; i++) {
|
||||
if (buf[i] != 0xff) {
|
||||
emptyf=0;
|
||||
break;
|
||||
}
|
||||
fprintf(outf, "%02X", buf[i]);
|
||||
cksum += buf[i];
|
||||
}
|
||||
|
||||
if (emptyf != 1) {
|
||||
|
||||
fprintf(outf, tmpl, n + addr_width + 1, nextaddr);
|
||||
|
||||
cksum += n + addr_width + 1;
|
||||
|
||||
for (i=addr_width; i>0; i--)
|
||||
cksum += (nextaddr >> (i-1) * 8) & 0xff;
|
||||
|
||||
for (i=nextaddr; i<nextaddr + n; i++) {
|
||||
fprintf(outf, "%02X", buf[i]);
|
||||
cksum += buf[i];
|
||||
}
|
||||
|
||||
cksum = 0xff - cksum;
|
||||
fprintf(outf, "%02X\n", cksum);
|
||||
}
|
||||
cksum = 0xff - cksum;
|
||||
fprintf(outf, "%02X\n", cksum);
|
||||
|
||||
nextaddr += n;
|
||||
nbytes +=n;
|
||||
}
|
||||
|
||||
/* advance to next 'recsize' bytes */
|
||||
@@ -501,7 +463,7 @@ int b2srec(unsigned char * inbuf, int bufsize,
|
||||
}
|
||||
|
||||
|
||||
int srec_readrec(struct ihexrec * srec, char * rec)
|
||||
static int srec_readrec(struct ihexrec * srec, char * rec)
|
||||
{
|
||||
int i, j;
|
||||
char buf[8];
|
||||
@@ -577,7 +539,7 @@ int srec_readrec(struct ihexrec * srec, char * rec)
|
||||
}
|
||||
|
||||
|
||||
int srec2b(char * infile, FILE * inf,
|
||||
static int srec2b(char * infile, FILE * inf,
|
||||
unsigned char * outbuf, int bufsize)
|
||||
{
|
||||
char buffer [ MAX_LINE_LEN ];
|
||||
@@ -697,8 +659,47 @@ int srec2b(char * infile, FILE * inf,
|
||||
return maxaddr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple itoa() implementation. Caller needs to allocate enough
|
||||
* space in buf. Only positive integers are handled.
|
||||
*/
|
||||
static char *itoa_simple(int n, char *buf, int base)
|
||||
{
|
||||
div_t q;
|
||||
char c, *cp, *cp2;
|
||||
|
||||
int fileio_rbin(struct fioparms * fio,
|
||||
cp = buf;
|
||||
/*
|
||||
* Divide by base until the number disappeared, but ensure at least
|
||||
* one digit will be emitted.
|
||||
*/
|
||||
do {
|
||||
q = div(n, base);
|
||||
n = q.quot;
|
||||
if (q.rem >= 10)
|
||||
c = q.rem - 10 + 'a';
|
||||
else
|
||||
c = q.rem + '0';
|
||||
*cp++ = c;
|
||||
} while (q.quot != 0);
|
||||
|
||||
/* Terminate the string. */
|
||||
*cp-- = '\0';
|
||||
|
||||
/* Now revert the result string. */
|
||||
cp2 = buf;
|
||||
while (cp > cp2) {
|
||||
c = *cp;
|
||||
*cp-- = *cp2;
|
||||
*cp2++ = c;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int fileio_rbin(struct fioparms * fio,
|
||||
char * filename, FILE * f, unsigned char * buf, int size)
|
||||
{
|
||||
int rc;
|
||||
@@ -728,7 +729,54 @@ int fileio_rbin(struct fioparms * fio,
|
||||
}
|
||||
|
||||
|
||||
int fileio_ihex(struct fioparms * fio,
|
||||
static int fileio_imm(struct fioparms * fio,
|
||||
char * filename, FILE * f, unsigned char * buf, int size)
|
||||
{
|
||||
int rc = 0;
|
||||
char * e, * p;
|
||||
unsigned long b;
|
||||
int loc;
|
||||
|
||||
switch (fio->op) {
|
||||
case FIO_READ:
|
||||
loc = 0;
|
||||
p = strtok(filename, " ,");
|
||||
while (p != NULL && loc < size) {
|
||||
b = strtoul(p, &e, 0);
|
||||
/* check for binary formated (0b10101001) strings */
|
||||
b = (strncmp (p, "0b", 2))?
|
||||
strtoul (p, &e, 0):
|
||||
strtoul (p + 2, &e, 2);
|
||||
if (*e != 0) {
|
||||
fprintf(stderr,
|
||||
"%s: invalid byte value (%s) specified for immediate mode\n",
|
||||
progname, p);
|
||||
return -1;
|
||||
}
|
||||
buf[loc++] = b;
|
||||
p = strtok(NULL, " ,");
|
||||
rc = loc;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "%s: fileio: invalid operation=%d\n",
|
||||
progname, fio->op);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rc < 0 || (fio->op == FIO_WRITE && rc < size)) {
|
||||
fprintf(stderr,
|
||||
"%s: %s error %s %s: %s; %s %d of the expected %d bytes\n",
|
||||
progname, fio->iodesc, fio->dir, filename, strerror(errno),
|
||||
fio->rw, rc, size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int fileio_ihex(struct fioparms * fio,
|
||||
char * filename, FILE * f, unsigned char * buf, int size)
|
||||
{
|
||||
int rc;
|
||||
@@ -758,7 +806,7 @@ int fileio_ihex(struct fioparms * fio,
|
||||
}
|
||||
|
||||
|
||||
int fileio_srec(struct fioparms * fio,
|
||||
static int fileio_srec(struct fioparms * fio,
|
||||
char * filename, FILE * f, unsigned char * buf, int size)
|
||||
{
|
||||
int rc;
|
||||
@@ -789,6 +837,78 @@ int fileio_srec(struct fioparms * fio,
|
||||
}
|
||||
|
||||
|
||||
static int fileio_num(struct fioparms * fio,
|
||||
char * filename, FILE * f, unsigned char * buf, int size,
|
||||
FILEFMT fmt)
|
||||
{
|
||||
const char *prefix;
|
||||
char cbuf[20];
|
||||
int base, i, num;
|
||||
|
||||
switch (fmt) {
|
||||
case FMT_HEX:
|
||||
prefix = "0x";
|
||||
base = 16;
|
||||
break;
|
||||
|
||||
default:
|
||||
case FMT_DEC:
|
||||
prefix = "";
|
||||
base = 10;
|
||||
break;
|
||||
|
||||
case FMT_OCT:
|
||||
prefix = "0";
|
||||
base = 8;
|
||||
break;
|
||||
|
||||
case FMT_BIN:
|
||||
prefix = "0b";
|
||||
base = 2;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
switch (fio->op) {
|
||||
case FIO_WRITE:
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "%s: fileio: invalid operation=%d\n",
|
||||
progname, fio->op);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
if (i > 0) {
|
||||
if (putc(',', f) == EOF)
|
||||
goto writeerr;
|
||||
}
|
||||
num = (unsigned int)buf[i];
|
||||
/*
|
||||
* For a base of 8 and a value < 8 to convert, don't write the
|
||||
* prefix. The conversion will be indistinguishable from a
|
||||
* decimal one then.
|
||||
*/
|
||||
if (prefix[0] != '\0' && !(base == 8 && num < 8)) {
|
||||
if (fputs(prefix, f) == EOF)
|
||||
goto writeerr;
|
||||
}
|
||||
itoa_simple(num, cbuf, base);
|
||||
if (fputs(cbuf, f) == EOF)
|
||||
goto writeerr;
|
||||
}
|
||||
if (putc('\n', f) == EOF)
|
||||
goto writeerr;
|
||||
|
||||
return 0;
|
||||
|
||||
writeerr:
|
||||
fprintf(stderr, "%s: error writing to %s: %s\n",
|
||||
progname, filename, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int fileio_setparms(int op, struct fioparms * fp)
|
||||
{
|
||||
fp->op = op;
|
||||
@@ -820,7 +940,7 @@ int fileio_setparms(int op, struct fioparms * fp)
|
||||
|
||||
|
||||
|
||||
int fmt_autodetect(char * fname)
|
||||
static int fmt_autodetect(char * fname)
|
||||
{
|
||||
FILE * f;
|
||||
unsigned char buf[MAX_LINE_LEN];
|
||||
@@ -849,8 +969,10 @@ int fmt_autodetect(char * fname)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
if (found) {
|
||||
fclose(f);
|
||||
return FMT_RBIN;
|
||||
}
|
||||
|
||||
/* check for lines that look like intel hex */
|
||||
if ((buf[0] == ':') && (len >= 11)) {
|
||||
@@ -861,8 +983,10 @@ int fmt_autodetect(char * fname)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
if (found) {
|
||||
fclose(f);
|
||||
return FMT_IHEX;
|
||||
}
|
||||
}
|
||||
|
||||
/* check for lines that look like motorola s-record */
|
||||
@@ -874,11 +998,14 @@ int fmt_autodetect(char * fname)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
if (found) {
|
||||
fclose(f);
|
||||
return FMT_SREC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -892,8 +1019,8 @@ int fileio(int op, char * filename, FILEFMT format,
|
||||
char * fname;
|
||||
unsigned char * buf;
|
||||
struct fioparms fio;
|
||||
int i;
|
||||
AVRMEM * mem;
|
||||
int using_stdio;
|
||||
|
||||
mem = avr_locate_mem(p, memtype);
|
||||
if (mem == NULL) {
|
||||
@@ -907,6 +1034,33 @@ int fileio(int op, char * filename, FILEFMT format,
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
|
||||
#if defined(WIN32NATIVE)
|
||||
/* Open Raw Binary format in binary mode on Windows.*/
|
||||
if(format == FMT_RBIN)
|
||||
{
|
||||
if(fio.op == FIO_READ)
|
||||
{
|
||||
fio.mode = "rb";
|
||||
}
|
||||
if(fio.op == FIO_WRITE)
|
||||
{
|
||||
fio.mode = "wb";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* point at the requested memory buffer */
|
||||
buf = mem->buf;
|
||||
if (fio.op == FIO_READ)
|
||||
size = mem->size;
|
||||
|
||||
if (fio.op == FIO_READ) {
|
||||
/* 0xff fill unspecified memory */
|
||||
memset(buf, 0xff, size);
|
||||
}
|
||||
|
||||
using_stdio = 0;
|
||||
|
||||
if (strcmp(filename, "-")==0) {
|
||||
if (fio.op == FIO_READ) {
|
||||
fname = "<stdin>";
|
||||
@@ -916,30 +1070,22 @@ int fileio(int op, char * filename, FILEFMT format,
|
||||
fname = "<stdout>";
|
||||
f = stdout;
|
||||
}
|
||||
using_stdio = 1;
|
||||
}
|
||||
else {
|
||||
fname = filename;
|
||||
f = fopen(fname, fio.mode);
|
||||
if (f == NULL) {
|
||||
fprintf(stderr, "%s: can't open %s file %s: %s\n",
|
||||
progname, fio.iodesc, fname, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* point at the requested memory buffer */
|
||||
buf = mem->buf;
|
||||
if (fio.op == FIO_READ)
|
||||
size = mem->size;
|
||||
|
||||
if (fio.op == FIO_READ) {
|
||||
/* 0xff fill unspecified memory */
|
||||
for (i=0; i<size; i++) {
|
||||
buf[i] = 0xff;
|
||||
}
|
||||
f = NULL;
|
||||
}
|
||||
|
||||
if (format == FMT_AUTO) {
|
||||
if (using_stdio) {
|
||||
fprintf(stderr,
|
||||
"%s: can't auto detect file format when using stdin/out.\n"
|
||||
" Please specify a file format using the -f option and try again.\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
format = fmt_autodetect(fname);
|
||||
if (format < 0) {
|
||||
fprintf(stderr,
|
||||
@@ -948,8 +1094,21 @@ int fileio(int op, char * filename, FILEFMT format,
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s: %s file %s auto detected as %s\n",
|
||||
progname, fio.iodesc, fname, fmtstr(format));
|
||||
if (quell_progress < 2) {
|
||||
fprintf(stderr, "%s: %s file %s auto detected as %s\n",
|
||||
progname, fio.iodesc, fname, fmtstr(format));
|
||||
}
|
||||
}
|
||||
|
||||
if (format != FMT_IMM) {
|
||||
if (!using_stdio) {
|
||||
f = fopen(fname, fio.mode);
|
||||
if (f == NULL) {
|
||||
fprintf(stderr, "%s: can't open %s file %s: %s\n",
|
||||
progname, fio.iodesc, fname, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (format) {
|
||||
@@ -965,12 +1124,35 @@ int fileio(int op, char * filename, FILEFMT format,
|
||||
rc = fileio_rbin(&fio, fname, f, buf, size);
|
||||
break;
|
||||
|
||||
case FMT_IMM:
|
||||
rc = fileio_imm(&fio, fname, f, buf, size);
|
||||
break;
|
||||
|
||||
case FMT_HEX:
|
||||
case FMT_DEC:
|
||||
case FMT_OCT:
|
||||
case FMT_BIN:
|
||||
rc = fileio_num(&fio, fname, f, buf, size, format);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "%s: invalid %s file format: %d\n",
|
||||
progname, fio.iodesc, format);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rc > 0) {
|
||||
if ((op == FIO_READ) && (strcasecmp(mem->desc, "flash") == 0)) {
|
||||
/*
|
||||
* if we are reading flash, just mark the size as being the
|
||||
* highest non-0xff byte
|
||||
*/
|
||||
rc = avr_mem_hiaddr(mem);
|
||||
}
|
||||
}
|
||||
if (format != FMT_IMM && !using_stdio) {
|
||||
fclose(f);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.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
|
||||
@@ -19,14 +19,19 @@
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef __fileio_h__
|
||||
#define __fileio_h__
|
||||
#ifndef fileio_h
|
||||
#define fileio_h
|
||||
|
||||
typedef enum {
|
||||
FMT_AUTO,
|
||||
FMT_SREC,
|
||||
FMT_IHEX,
|
||||
FMT_RBIN
|
||||
FMT_RBIN,
|
||||
FMT_IMM,
|
||||
FMT_HEX,
|
||||
FMT_DEC,
|
||||
FMT_OCT,
|
||||
FMT_BIN
|
||||
} FILEFMT;
|
||||
|
||||
struct fioparms {
|
||||
@@ -42,11 +47,19 @@ enum {
|
||||
FIO_WRITE
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
char * fmtstr(FILEFMT format);
|
||||
|
||||
int fileio_setparms(int op, struct fioparms * fp);
|
||||
|
||||
int fileio(int op, char * filename, FILEFMT format,
|
||||
int fileio(int op, char * filename, FILEFMT format,
|
||||
struct avrpart * p, char * memtype, int size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
40
avrdude/freebsd_ppi.h
Normal file
40
avrdude/freebsd_ppi.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2005 Joerg Wunsch
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef freebsd_ppi_h
|
||||
#define freebsd_ppi_h
|
||||
|
||||
#include <dev/ppbus/ppi.h>
|
||||
|
||||
#define ppi_claim(fd) {}
|
||||
|
||||
#define ppi_release(fd) {}
|
||||
|
||||
#define DO_PPI_READ(fd, reg, valp) \
|
||||
(void)ioctl(fd, \
|
||||
(reg) == PPIDATA? PPIGDATA: ((reg) == PPICTRL? PPIGCTRL: PPIGSTATUS), \
|
||||
valp)
|
||||
#define DO_PPI_WRITE(fd, reg, valp) \
|
||||
(void)ioctl(fd, \
|
||||
(reg) == PPIDATA? PPISDATA: ((reg) == PPICTRL? PPISCTRL: PPISSTATUS), \
|
||||
valp)
|
||||
|
||||
#endif /* freebsd_ppi_h */
|
||||
1402
avrdude/jtagmkI.c
Normal file
1402
avrdude/jtagmkI.c
Normal file
File diff suppressed because it is too large
Load Diff
36
avrdude/jtagmkI.h
Normal file
36
avrdude/jtagmkI.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef jtagmkI_h
|
||||
#define jtagmkI_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void jtagmkI_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
2425
avrdude/jtagmkII.c
Normal file
2425
avrdude/jtagmkII.c
Normal file
File diff suppressed because it is too large
Load Diff
54
avrdude/jtagmkII.h
Normal file
54
avrdude/jtagmkII.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2002-2004, 2006 Brian S. Dean <bsd@bsdhome.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef jtagmkII_h
|
||||
#define jtagmkII_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int jtagmkII_send(PROGRAMMER * pgm, unsigned char * data, size_t len);
|
||||
int jtagmkII_recv(PROGRAMMER * pgm, unsigned char **msg);
|
||||
void jtagmkII_close(PROGRAMMER * pgm);
|
||||
int jtagmkII_getsync(PROGRAMMER * pgm, int mode);
|
||||
int jtagmkII_getparm(PROGRAMMER * pgm, unsigned char parm,
|
||||
unsigned char * value);
|
||||
|
||||
void jtagmkII_initpgm (PROGRAMMER * pgm);
|
||||
void jtagmkII_dw_initpgm (PROGRAMMER * pgm);
|
||||
void jtagmkII_dragon_initpgm (PROGRAMMER * pgm);
|
||||
void jtagmkII_dragon_dw_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
/*
|
||||
* These functions are referenced from stk500v2.c for JTAG ICE mkII
|
||||
* and AVR Dragon programmers running in one of the STK500v2
|
||||
* modi.
|
||||
*/
|
||||
void jtagmkII_setup(PROGRAMMER * pgm);
|
||||
void jtagmkII_teardown(PROGRAMMER * pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
303
avrdude/jtagmkII_private.h
Normal file
303
avrdude/jtagmkII_private.h
Normal file
@@ -0,0 +1,303 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2005, 2006 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
|
||||
/*
|
||||
* JTAG ICE mkII definitions
|
||||
* Taken from Appnote AVR067
|
||||
*/
|
||||
|
||||
#if !defined(JTAGMKII_PRIVATE_EXPORTED)
|
||||
/*
|
||||
* Communication with the JTAG ICE works in frames. The protocol
|
||||
* somewhat resembles the STK500v2 protocol, yet it is sufficiently
|
||||
* different to prevent a direct code reuse. :-(
|
||||
*
|
||||
* Frame format:
|
||||
*
|
||||
* +---------------------------------------------------------------+
|
||||
* | 0 | 1 . 2 | 3 . 4 . 5 . 6 | 7 | ... | N-1 . N |
|
||||
* | | | | | | |
|
||||
* | start | LSB MSB | LSB ....... MSB | token | msg | LSB MSB |
|
||||
* | 0x1B | sequence# | message size | 0x0E | | CRC16 |
|
||||
* +---------------------------------------------------------------+
|
||||
*
|
||||
* Each request message will be returned by a response with a matching
|
||||
* sequence #. Sequence # 0xffff is reserved for asynchronous event
|
||||
* notifications that will be sent by the ICE without a request
|
||||
* message (e.g. when the target hit a breakpoint).
|
||||
*
|
||||
* The message size excludes the framing overhead (10 bytes).
|
||||
*
|
||||
* The first byte of the message is always the request or response
|
||||
* code, which is roughly classified as:
|
||||
*
|
||||
* . Messages (commands) use 0x00 through 0x3f. (The documentation
|
||||
* claims that messages start at 0x01, but actually CMND_SIGN_OFF is
|
||||
* 0x00.)
|
||||
* . Internal commands use 0x40 through 0x7f (not documented).
|
||||
* . Success responses use 0x80 through 0x9f.
|
||||
* . Failure responses use 0xa0 through 0xbf.
|
||||
* . Events use 0xe0 through 0xff.
|
||||
*/
|
||||
#define MESSAGE_START 0x1b
|
||||
#define TOKEN 0x0e
|
||||
|
||||
/*
|
||||
* Max message size we are willing to accept. Prevents us from trying
|
||||
* to allocate too much VM in case we received a nonsensical packet
|
||||
* length. We have to allocate the buffer as soon as we've got the
|
||||
* length information (and thus have to trust that information by that
|
||||
* time at first), as the final CRC check can only be done once the
|
||||
* entire packet came it.
|
||||
*/
|
||||
#define MAX_MESSAGE 100000
|
||||
|
||||
#endif /* JTAGMKII_PRIVATE_EXPORTED */
|
||||
|
||||
/* ICE command codes */
|
||||
#define CMND_CHIP_ERASE 0x13
|
||||
#define CMND_CLEAR_EVENTS 0x22
|
||||
#define CMND_CLR_BREAK 0x1A
|
||||
#define CMND_ENTER_PROGMODE 0x14
|
||||
#define CMND_ERASEPAGE_SPM 0x0D
|
||||
#define CMND_FORCED_STOP 0x0A
|
||||
#define CMND_GET_BREAK 0x12
|
||||
#define CMND_GET_PARAMETER 0x03
|
||||
#define CMND_GET_SIGN_ON 0x01
|
||||
#define CMND_GET_SYNC 0x0f
|
||||
#define CMND_GO 0x08
|
||||
#define CMND_ISP_PACKET 0x2F
|
||||
#define CMND_LEAVE_PROGMODE 0x15
|
||||
#define CMND_READ_MEMORY 0x05
|
||||
#define CMND_READ_PC 0x07
|
||||
#define CMND_RESET 0x0B
|
||||
#define CMND_RESTORE_TARGET 0x23
|
||||
#define CMND_RUN_TO_ADDR 0x1C
|
||||
#define CMND_SELFTEST 0x10
|
||||
#define CMND_SET_BREAK 0x11
|
||||
#define CMND_SET_DEVICE_DESCRIPTOR 0x0C
|
||||
#define CMND_SET_N_PARAMETERS 0x16
|
||||
#define CMND_SET_PARAMETER 0x02
|
||||
#define CMND_SIGN_OFF 0x00
|
||||
#define CMND_SINGLE_STEP 0x09
|
||||
#define CMND_SPI_CMD 0x1D
|
||||
#define CMND_WRITE_MEMORY 0x04
|
||||
#define CMND_WRITE_PC 0x06
|
||||
#define CMND_0x34 0x34
|
||||
|
||||
/* ICE responses */
|
||||
#define RSP_DEBUGWIRE_SYNC_FAILED 0xAC
|
||||
#define RSP_FAILED 0xA0
|
||||
#define RSP_GET_BREAK 0x83
|
||||
#define RSP_ILLEGAL_BREAKPOINT 0xA8
|
||||
#define RSP_ILLEGAL_COMMAND 0xAA
|
||||
#define RSP_ILLEGAL_EMULATOR_MODE 0xA4
|
||||
#define RSP_ILLEGAL_JTAG_ID 0xA9
|
||||
#define RSP_ILLEGAL_MCU_STATE 0xA5
|
||||
#define RSP_ILLEGAL_MEMORY_TYPE 0xA2
|
||||
#define RSP_ILLEGAL_MEMORY_RANGE 0xA3
|
||||
#define RSP_ILLEGAL_PARAMETER 0xA1
|
||||
#define RSP_ILLEGAL_POWER_STATE 0xAD
|
||||
#define RSP_ILLEGAL_VALUE 0xA6
|
||||
#define RSP_MEMORY 0x82
|
||||
#define RSP_NO_TARGET_POWER 0xAB
|
||||
#define RSP_OK 0x80
|
||||
#define RSP_PARAMETER 0x81
|
||||
#define RSP_PC 0x84
|
||||
#define RSP_SELFTEST 0x85
|
||||
#define RSP_SET_N_PARAMETERS 0xA7
|
||||
#define RSP_SIGN_ON 0x86
|
||||
#define RSP_SPI_DATA 0x88
|
||||
|
||||
/* ICE events */
|
||||
#define EVT_BREAK 0xE0
|
||||
#define EVT_DEBUG 0xE6
|
||||
#define EVT_ERROR_PHY_FORCE_BREAK_TIMEOUT 0xE2
|
||||
#define EVT_ERROR_PHY_MAX_BIT_LENGTH_DIFF 0xED
|
||||
#define EVT_ERROR_PHY_OPT_RECEIVE_TIMEOUT 0xF9
|
||||
#define EVT_ERROR_PHY_OPT_RECEIVED_BREAK 0xFA
|
||||
#define EVT_ERROR_PHY_RECEIVED_BREAK 0xF8
|
||||
#define EVT_ERROR_PHY_RECEIVE_TIMEOUT 0xF7
|
||||
#define EVT_ERROR_PHY_RELEASE_BREAK_TIMEOUT 0xE3
|
||||
#define EVT_ERROR_PHY_SYNC_OUT_OF_RANGE 0xF5
|
||||
#define EVT_ERROR_PHY_SYNC_TIMEOUT 0xF0
|
||||
#define EVT_ERROR_PHY_SYNC_TIMEOUT_BAUD 0xF4
|
||||
#define EVT_ERROR_PHY_SYNC_WAIT_TIMEOUT 0xF6
|
||||
#define EVT_RESULT_PHY_NO_ACTIVITY 0xFB
|
||||
#define EVT_EXT_RESET 0xE7
|
||||
#define EVT_ICE_POWER_ERROR_STATE 0xEA
|
||||
#define EVT_ICE_POWER_OK 0xEB
|
||||
#define EVT_IDR_DIRTY 0xEC
|
||||
#define EVT_NONE 0xEF
|
||||
#define EVT_PDSB_BREAK 0xF2
|
||||
#define EVT_PDSMB_BREAK 0xF3
|
||||
#define EVT_PROGRAM_BREAK 0xF1
|
||||
#define EVT_RUN 0xE1
|
||||
#define EVT_TARGET_POWER_OFF 0xE5
|
||||
#define EVT_TARGET_POWER_ON 0xE4
|
||||
#define EVT_TARGET_SLEEP 0xE8
|
||||
#define EVT_TARGET_WAKEUP 0xE9
|
||||
|
||||
/* memory types for CMND_{READ,WRITE}_MEMORY */
|
||||
#define MTYPE_IO_SHADOW 0x30 /* cached IO registers? */
|
||||
#define MTYPE_SRAM 0x20 /* target's SRAM or [ext.] IO registers */
|
||||
#define MTYPE_EEPROM 0x22 /* EEPROM, what way? */
|
||||
#define MTYPE_EVENT 0x60 /* ICE event memory */
|
||||
#define MTYPE_SPM 0xA0 /* flash through LPM/SPM */
|
||||
#define MTYPE_FLASH_PAGE 0xB0 /* flash in programming mode */
|
||||
#define MTYPE_EEPROM_PAGE 0xB1 /* EEPROM in programming mode */
|
||||
#define MTYPE_FUSE_BITS 0xB2 /* fuse bits in programming mode */
|
||||
#define MTYPE_LOCK_BITS 0xB3 /* lock bits in programming mode */
|
||||
#define MTYPE_SIGN_JTAG 0xB4 /* signature in programming mode */
|
||||
#define MTYPE_OSCCAL_BYTE 0xB5 /* osccal cells in programming mode */
|
||||
#define MTYPE_CAN 0xB6 /* CAN mailbox */
|
||||
#define MTYPE_FLASH 0xc0 /* xmega flash - undocumented in AVR067 */
|
||||
#define MTYPE_USERSIG 0xc5 /* xmega user signature - undocumented in AVR067 */
|
||||
#define MTYPE_PRODSIG 0xc6 /* xmega production signature - undocumented in AVR067 */
|
||||
|
||||
/* (some) ICE parameters, for CMND_{GET,SET}_PARAMETER */
|
||||
#define PAR_HW_VERSION 0x01
|
||||
#define PAR_FW_VERSION 0x02
|
||||
#define PAR_EMULATOR_MODE 0x03
|
||||
# define EMULATOR_MODE_DEBUGWIRE 0x00
|
||||
# define EMULATOR_MODE_JTAG 0x01
|
||||
# define EMULATOR_MODE_HV 0x02 /* HVSP or PP mode of AVR Dragon */
|
||||
# define EMULATOR_MODE_SPI 0x03
|
||||
# define EMULATOR_MODE_JTAG_XMEGA 0x05
|
||||
#define PAR_IREG 0x04
|
||||
#define PAR_BAUD_RATE 0x05
|
||||
# define PAR_BAUD_2400 0x01
|
||||
# define PAR_BAUD_4800 0x02
|
||||
# define PAR_BAUD_9600 0x03
|
||||
# define PAR_BAUD_19200 0x04 /* default */
|
||||
# define PAR_BAUD_38400 0x05
|
||||
# define PAR_BAUD_57600 0x06
|
||||
# define PAR_BAUD_115200 0x07
|
||||
# define PAR_BAUD_14400 0x08
|
||||
#define PAR_OCD_VTARGET 0x06
|
||||
#define PAR_OCD_JTAG_CLK 0x07
|
||||
#define PAR_OCD_BREAK_CAUSE 0x08
|
||||
#define PAR_TIMERS_RUNNING 0x09
|
||||
#define PAR_BREAK_ON_CHANGE_FLOW 0x0A
|
||||
#define PAR_BREAK_ADDR1 0x0B
|
||||
#define PAR_BREAK_ADDR2 0x0C
|
||||
#define PAR_COMBBREAKCTRL 0x0D
|
||||
#define PAR_JTAGID 0x0E
|
||||
#define PAR_UNITS_BEFORE 0x0F
|
||||
#define PAR_UNITS_AFTER 0x10
|
||||
#define PAR_BIT_BEFORE 0x11
|
||||
#define PAR_BIT_ATER 0x12
|
||||
#define PAR_EXTERNAL_RESET 0x13
|
||||
#define PAR_FLASH_PAGE_SIZE 0x14
|
||||
#define PAR_EEPROM_PAGE_SIZE 0x15
|
||||
#define PAR_UNUSED1 0x16
|
||||
#define PAR_PSB0 0x17
|
||||
#define PAR_PSB1 0x18
|
||||
#define PAR_PROTOCOL_DEBUG_EVENT 0x19
|
||||
#define PAR_MCU_STATE 0x1A
|
||||
# define STOPPED 0x00
|
||||
# define RUNNING 0x01
|
||||
# define PROGRAMMING 0x02
|
||||
#define PAR_DAISY_CHAIN_INFO 0x1B
|
||||
#define PAR_BOOT_ADDRESS 0x1C
|
||||
#define PAR_TARGET_SIGNATURE 0x1D
|
||||
#define PAR_DEBUGWIRE_BAUDRATE 0x1E
|
||||
#define PAR_PROGRAM_ENTRY_POINT 0x1F
|
||||
#define PAR_PDI_OFFSET_START 0x32
|
||||
#define PAR_PDI_OFFSET_END 0x33
|
||||
#define PAR_PACKET_PARSING_ERRORS 0x40
|
||||
#define PAR_VALID_PACKETS_RECEIVED 0x41
|
||||
#define PAR_INTERCOMMUNICATION_TX_FAILURES 0x42
|
||||
#define PAR_INTERCOMMUNICATION_RX_FAILURES 0x43
|
||||
#define PAR_CRC_ERRORS 0x44
|
||||
#define PAR_POWER_SOURCE 0x45
|
||||
# define POWER_EXTERNAL 0x00
|
||||
# define POWER_USB 0x01
|
||||
#define PAR_CAN_FLAG 0x22
|
||||
# define DONT_READ_CAN_MAILBOX 0x00
|
||||
# define READ_CAN_MAILBOX 0x01
|
||||
#define PAR_ENABLE_IDR_IN_RUN_MODE 0x23
|
||||
# define ACCESS_OSCCAL 0x00
|
||||
# define ACCESS_IDR 0x01
|
||||
#define PAR_ALLOW_PAGEPROGRAMMING_IN_SCANCHAIN 0x24
|
||||
# define PAGEPROG_NOT_ALLOWED 0x00
|
||||
# define PAGEPROG_ALLOWED 0x01
|
||||
|
||||
#if !defined(JTAGMKII_PRIVATE_EXPORTED)
|
||||
/*
|
||||
* In appnote AVR067, struct device_descriptor is written with
|
||||
* int/long field types. We cannot use them directly, as they were
|
||||
* neither properly aligned for portability, nor did they care for
|
||||
* endianess issues. We thus use arrays of unsigned chars, plus
|
||||
* conversion macros.
|
||||
*/
|
||||
struct device_descriptor
|
||||
{
|
||||
unsigned char ucReadIO[8]; /*LSB = IOloc 0, MSB = IOloc63 */
|
||||
unsigned char ucReadIOShadow[8]; /*LSB = IOloc 0, MSB = IOloc63 */
|
||||
unsigned char ucWriteIO[8]; /*LSB = IOloc 0, MSB = IOloc63 */
|
||||
unsigned char ucWriteIOShadow[8]; /*LSB = IOloc 0, MSB = IOloc63 */
|
||||
unsigned char ucReadExtIO[52]; /*LSB = IOloc 96, MSB = IOloc511 */
|
||||
unsigned char ucReadIOExtShadow[52]; /*LSB = IOloc 96, MSB = IOloc511 */
|
||||
unsigned char ucWriteExtIO[52]; /*LSB = IOloc 96, MSB = IOloc511 */
|
||||
unsigned char ucWriteIOExtShadow[52];/*LSB = IOloc 96, MSB = IOloc511 */
|
||||
unsigned char ucIDRAddress; /*IDR address */
|
||||
unsigned char ucSPMCRAddress; /*SPMCR Register address and dW BasePC */
|
||||
unsigned char ucRAMPZAddress; /*RAMPZ Register address in SRAM I/O */
|
||||
/*space */
|
||||
unsigned char uiFlashPageSize[2]; /*Device Flash Page Size, Size = */
|
||||
/*2 exp ucFlashPageSize */
|
||||
unsigned char ucEepromPageSize; /*Device Eeprom Page Size in bytes */
|
||||
unsigned char ulBootAddress[4]; /*Device Boot Loader Start Address */
|
||||
unsigned char uiUpperExtIOLoc[2]; /*Topmost (last) extended I/O */
|
||||
/*location, 0 if no external I/O */
|
||||
unsigned char ulFlashSize[4]; /*Device Flash Size */
|
||||
unsigned char ucEepromInst[20]; /*Instructions for W/R EEPROM */
|
||||
unsigned char ucFlashInst[3]; /*Instructions for W/R FLASH */
|
||||
unsigned char ucSPHaddr; /* stack pointer high */
|
||||
unsigned char ucSPLaddr; /* stack pointer low */
|
||||
/* new as of 16-02-2004 */
|
||||
unsigned char uiFlashpages[2]; /* number of pages in flash */
|
||||
unsigned char ucDWDRAddress; /* DWDR register address */
|
||||
unsigned char ucDWBasePC; /* base/mask value of the PC */
|
||||
/* new as of 30-04-2004 */
|
||||
unsigned char ucAllowFullPageBitstream; /* FALSE on ALL new */
|
||||
/*parts */
|
||||
unsigned char uiStartSmallestBootLoaderSection[2]; /* */
|
||||
/* new as of 18-10-2004 */
|
||||
unsigned char EnablePageProgramming; /* For JTAG parts only, */
|
||||
/* default TRUE */
|
||||
unsigned char ucCacheType; /* CacheType_Normal 0x00, */
|
||||
/* CacheType_CAN 0x01, */
|
||||
/* CacheType_HEIMDALL 0x02 */
|
||||
/* new as of 27-10-2004 */
|
||||
unsigned char uiSramStartAddr[2]; /* Start of SRAM */
|
||||
unsigned char ucResetType; /* Selects reset type. ResetNormal = 0x00 */
|
||||
/* ResetAT76CXXX = 0x01 */
|
||||
unsigned char ucPCMaskExtended; /* For parts with extended PC */
|
||||
unsigned char ucPCMaskHigh; /* PC high mask */
|
||||
unsigned char ucEindAddress; /* Selects reset type. [EIND address...] */
|
||||
/* new as of early 2005, firmware 4.x */
|
||||
unsigned char EECRAddress[2]; /* EECR memory-mapped IO address */
|
||||
};
|
||||
#endif /* JTAGMKII_PRIVATE_EXPORTED */
|
||||
169
avrdude/jtagmkI_private.h
Normal file
169
avrdude/jtagmkI_private.h
Normal file
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2005 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
|
||||
/*
|
||||
* JTAG ICE mkI definitions
|
||||
*/
|
||||
|
||||
/* ICE command codes */
|
||||
/* 0x20 Get Synch [Resp_OK] */
|
||||
#define CMD_GET_SYNC ' '
|
||||
|
||||
/* 0x31 Single Step [Sync_CRC/EOP] [Resp_OK] */
|
||||
/* 0x32 Read PC [Sync_CRC/EOP] [Resp_OK] [program counter]
|
||||
* [Resp_OK] */
|
||||
/* 0x33 Write PC [program counter] [Sync_CRC/EOP] [Resp_OK]
|
||||
* [Resp_OK] */
|
||||
/* 0xA2 Firmware Upgrade [upgrade string] [Sync_CRC/EOP] [Resp_OK]
|
||||
* [Resp_OK] */
|
||||
/* 0xA0 Set Device Descriptor [device info] [Sync_CRC/EOP] [Resp_OK]
|
||||
* [Resp_OK] */
|
||||
#define CMD_SET_DEVICE_DESCRIPTOR 0xA0
|
||||
|
||||
/* 0x42 Set Parameter [parameter] [setting] [Sync_CRC/EOP] [Resp_OK]
|
||||
* [Resp_OK] */
|
||||
#define CMD_SET_PARAM 'B'
|
||||
|
||||
/* 0x46 Forced Stop [Sync_CRC/EOP] [Resp_OK] [checksum][program
|
||||
* counter] [Resp_OK] */
|
||||
#define CMD_STOP 'F'
|
||||
|
||||
/* 0x47 Go [Sync_CRC/EOP] [Resp_OK] */
|
||||
#define CMD_GO 'G'
|
||||
|
||||
/* 0x52 Read Memory [memory type] [word count] [start address]
|
||||
* [Sync_CRC/EOP] [Resp_OK] [word 0] ... [word n] [checksum]
|
||||
* [Resp_OK] */
|
||||
#define CMD_READ_MEM 'R'
|
||||
|
||||
/* 0x53 Get Sign On [Sync_CRC/EOP] [Resp_OK] ["AVRNOCD"] [Resp_OK] */
|
||||
#define CMD_GET_SIGNON 'S'
|
||||
|
||||
/* 0XA1 Erase Page spm [address] [Sync_CRC/EOP] [Resp_OK] [Resp_OK] */
|
||||
|
||||
/* 0x57 Write Memory [memory type] [word count] [start address]
|
||||
* [Sync_CRC/EOP] [Resp_OK] [Cmd_DATA] [word 0] ... [word n] */
|
||||
#define CMD_WRITE_MEM 'W'
|
||||
|
||||
/* Second half of write memory: the data command. Undocumented. */
|
||||
#define CMD_DATA 'h'
|
||||
|
||||
/* 0x64 Get Debug Info [Sync_CRC/EOP] [Resp_OK] [0x00] [Resp_OK] */
|
||||
/* 0x71 Get Parameter [parameter] [Sync_CRC/EOP] [Resp_OK] [setting]
|
||||
* [Resp_OK] */
|
||||
#define CMD_GET_PARAM 'q'
|
||||
|
||||
/* 0x78 Reset [Sync_CRC/EOP] [Resp_OK] [Resp_OK] */
|
||||
#define CMD_RESET 'x'
|
||||
|
||||
/* 0xA3 Enter Progmode [Sync_CRC/EOP] [Resp_OK] [Resp_OK] */
|
||||
#define CMD_ENTER_PROGMODE 0xa3
|
||||
|
||||
/* 0xA4 Leave Progmode [Sync_CRC/EOP] [Resp_OK] [Resp_OK] */
|
||||
#define CMD_LEAVE_PROGMODE 0xa4
|
||||
|
||||
/* 0xA5 Chip Erase [Sync_CRC/EOP] [Resp_OK] [Resp_OK] */
|
||||
#define CMD_CHIP_ERASE 0xa5
|
||||
|
||||
|
||||
/* ICE responses */
|
||||
#define RESP_OK 'A'
|
||||
#define RESP_BREAK 'B'
|
||||
#define RESP_INFO 'G'
|
||||
#define RESP_FAILED 'F'
|
||||
#define RESP_SYNC_ERROR 'E'
|
||||
#define RESP_SLEEP 'H'
|
||||
#define RESP_POWER 'I'
|
||||
|
||||
#define PARM_BITRATE 'b'
|
||||
#define PARM_SW_VERSION 0x7b
|
||||
#define PARM_HW_VERSION 0x7a
|
||||
#define PARM_IREG_HIGH 0x81
|
||||
#define PARM_IREG_LOW 0x82
|
||||
#define PARM_OCD_VTARGET 0x84
|
||||
#define PARM_OCD_BREAK_CAUSE 0x85
|
||||
#define PARM_CLOCK 0x86
|
||||
#define PARM_EXTERNAL_RESET 0x8b
|
||||
#define PARM_FLASH_PAGESIZE_LOW 0x88
|
||||
#define PARM_FLASH_PAGESIZE_HIGH 0x89
|
||||
#define PARM_EEPROM_PAGESIZE 0x8a
|
||||
#define PARM_TIMERS_RUNNING 0xa0
|
||||
#define PARM_BP_FLOW 0xa1
|
||||
#define PARM_BP_X_HIGH 0xa2
|
||||
#define PARM_BP_X_LOW 0xa3
|
||||
#define PARM_BP_Y_HIGH 0xa4
|
||||
#define PARM_BP_Y_LOW 0xa5
|
||||
#define PARM_BP_MODE 0xa6
|
||||
#define PARM_JTAGID_BYTE0 0xa7
|
||||
#define PARM_JTAGID_BYTE1 0xa8
|
||||
#define PARM_JTAGID_BYTE2 0xa9
|
||||
#define PARM_JTAGID_BYTE3 0xaa
|
||||
#define PARM_UNITS_BEFORE 0xab
|
||||
#define PARM_UNITS_AFTER 0xac
|
||||
#define PARM_BIT_BEFORE 0xad
|
||||
#define PARM_BIT_AFTER 0xae
|
||||
#define PARM_PSB0_LOW 0xaf
|
||||
#define PARM_PSBO_HIGH 0xb0
|
||||
#define PARM_PSB1_LOW 0xb1
|
||||
#define PARM_PSB1_HIGH 0xb2
|
||||
#define PARM_MCU_MODE 0xb3
|
||||
|
||||
#define JTAG_BITRATE_1_MHz 0xff
|
||||
#define JTAG_BITRATE_500_kHz 0xfe
|
||||
#define JTAG_BITRATE_250_kHz 0xfd
|
||||
#define JTAG_BITRATE_125_kHz 0xfb
|
||||
|
||||
/* memory types for CMND_{READ,WRITE}_MEMORY */
|
||||
#define MTYPE_IO_SHADOW 0x30 /* cached IO registers? */
|
||||
#define MTYPE_SRAM 0x20 /* target's SRAM or [ext.] IO registers */
|
||||
#define MTYPE_EEPROM 0x22 /* EEPROM, what way? */
|
||||
#define MTYPE_EVENT 0x60 /* ICE event memory */
|
||||
#define MTYPE_SPM 0xA0 /* flash through LPM/SPM */
|
||||
#define MTYPE_FLASH_PAGE 0xB0 /* flash in programming mode */
|
||||
#define MTYPE_EEPROM_PAGE 0xB1 /* EEPROM in programming mode */
|
||||
#define MTYPE_FUSE_BITS 0xB2 /* fuse bits in programming mode */
|
||||
#define MTYPE_LOCK_BITS 0xB3 /* lock bits in programming mode */
|
||||
#define MTYPE_SIGN_JTAG 0xB4 /* signature in programming mode */
|
||||
#define MTYPE_OSCCAL_BYTE 0xB5 /* osccal cells in programming mode */
|
||||
|
||||
struct device_descriptor
|
||||
{
|
||||
unsigned char ucReadIO[8]; /*LSB = IOloc 0, MSB = IOloc63 */
|
||||
unsigned char ucWriteIO[8]; /*LSB = IOloc 0, MSB = IOloc63 */
|
||||
unsigned char ucReadIOShadow[8]; /*LSB = IOloc 0, MSB = IOloc63 */
|
||||
unsigned char ucWriteIOShadow[8]; /*LSB = IOloc 0, MSB = IOloc63 */
|
||||
unsigned char ucReadExtIO[20]; /*LSB = IOloc 96, MSB = IOloc255 */
|
||||
unsigned char ucWriteExtIO[20]; /*LSB = IOloc 96, MSB = IOloc255 */
|
||||
unsigned char ucReadIOExtShadow[20]; /*LSB = IOloc 96, MSB = IOloc255 */
|
||||
unsigned char ucWriteIOExtShadow[20];/*LSB = IOloc 96, MSB = IOloc255 */
|
||||
unsigned char ucIDRAddress; /*IDR address */
|
||||
unsigned char ucSPMCRAddress; /*SPMCR Register address and dW BasePC */
|
||||
unsigned char ucRAMPZAddress; /*RAMPZ Register address in SRAM I/O */
|
||||
/*space */
|
||||
unsigned char uiFlashPageSize[2]; /*Device Flash Page Size, Size = */
|
||||
/*2 exp ucFlashPageSize */
|
||||
unsigned char ucEepromPageSize; /*Device Eeprom Page Size in bytes */
|
||||
unsigned char ulBootAddress[4]; /*Device Boot Loader Start Address */
|
||||
unsigned char uiUpperExtIOLoc; /*Topmost (last) extended I/O */
|
||||
/*location, 0 if no external I/O */
|
||||
};
|
||||
124
avrdude/lexer.l
124
avrdude/lexer.l
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2006 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -28,15 +29,12 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "config_gram.h"
|
||||
#include "lists.h"
|
||||
|
||||
extern int lineno;
|
||||
extern char * infile;
|
||||
|
||||
void pyytext(void);
|
||||
|
||||
#define YY_NO_UNPUT
|
||||
|
||||
%}
|
||||
@@ -46,17 +44,22 @@ HEXDIGIT [0-9a-fA-F]
|
||||
ID [_a-zA-Z][_a-zA-Z0-9]*
|
||||
SIGN [+-]
|
||||
|
||||
%x str
|
||||
%x strng
|
||||
%x incl
|
||||
%x comment
|
||||
|
||||
/* Bump resources for classic lex. */
|
||||
%e2000
|
||||
%p10000
|
||||
%n1000
|
||||
|
||||
%%
|
||||
|
||||
{SIGN}*{DIGIT}+ { yylval = number(yytext); return TKN_NUMBER; }
|
||||
{SIGN}*{DIGIT}+"."{DIGIT}* { yylval = number(yytext); return TKN_NUMBER; }
|
||||
{SIGN}*"."{DIGIT}* { yylval = number(yytext); return TKN_NUMBER; }
|
||||
|
||||
"\"" { string_buf_ptr = string_buf; BEGIN(str); }
|
||||
"\"" { string_buf_ptr = string_buf; BEGIN(strng); }
|
||||
|
||||
0x{HEXDIGIT}+ { yylval = hexnumber(yytext); return TKN_NUMBER; }
|
||||
|
||||
@@ -64,7 +67,7 @@ SIGN [+-]
|
||||
|
||||
# { /* The following eats '#' style comments to end of line */
|
||||
BEGIN(comment); }
|
||||
<comment>[^\n] /* eat comments */
|
||||
<comment>[^\n] { /* eat comments */ }
|
||||
<comment>\n { lineno++; BEGIN(INITIAL); }
|
||||
|
||||
|
||||
@@ -99,36 +102,57 @@ SIGN [+-]
|
||||
}
|
||||
|
||||
|
||||
<str>{
|
||||
\" { *string_buf_ptr = 0; string_buf_ptr = string_buf;
|
||||
yylval = string(string_buf_ptr); BEGIN(INITIAL); return TKN_STRING; }
|
||||
\\n *string_buf_ptr++ = '\n';
|
||||
\\t *string_buf_ptr++ = '\t';
|
||||
\\r *string_buf_ptr++ = '\r';
|
||||
\\b *string_buf_ptr++ = '\b';
|
||||
\\f *string_buf_ptr++ = '\f';
|
||||
\\(.|\n) *(string_buf_ptr++) = yytext[1];
|
||||
[^\\\n\"]+ { char *yptr = yytext; while (*yptr)
|
||||
<strng>\" { *string_buf_ptr = 0; string_buf_ptr = string_buf;
|
||||
yylval = string(string_buf_ptr); BEGIN(INITIAL); return TKN_STRING; }
|
||||
<strng>\\n *string_buf_ptr++ = '\n';
|
||||
<strng>\\t *string_buf_ptr++ = '\t';
|
||||
<strng>\\r *string_buf_ptr++ = '\r';
|
||||
<strng>\\b *string_buf_ptr++ = '\b';
|
||||
<strng>\\f *string_buf_ptr++ = '\f';
|
||||
<strng>\\(.|\n) *(string_buf_ptr++) = yytext[1];
|
||||
<strng>[^\\\n\"]+ { char *yptr = yytext; while (*yptr)
|
||||
*(string_buf_ptr++) = *(yptr++); }
|
||||
\n { fprintf(stderr, "error at line %d: unterminated character constant\n",
|
||||
lineno);
|
||||
exit(1); }
|
||||
}
|
||||
<strng>\n { fprintf(stderr, "error at line %d: unterminated character constant\n",
|
||||
lineno);
|
||||
exit(1); }
|
||||
|
||||
allowfullpagebitstream { yylval=NULL; return K_ALLOWFULLPAGEBITSTREAM; }
|
||||
arduino { yylval=NULL; return K_ARDUINO; }
|
||||
avr910 { yylval=NULL; return K_AVR910; }
|
||||
avr910_devcode { yylval=NULL; return K_AVR910_DEVCODE; }
|
||||
usbasp { yylval=NULL; return K_USBASP; }
|
||||
usbtiny { yylval=NULL; return K_USBTINY; }
|
||||
bank_size { yylval=NULL; return K_PAGE_SIZE; }
|
||||
banked { yylval=NULL; return K_PAGED; }
|
||||
baudrate { yylval=NULL; return K_BAUDRATE; }
|
||||
bs2 { yylval=NULL; return K_BS2; }
|
||||
buff { yylval=NULL; return K_BUFF; }
|
||||
butterfly { yylval=NULL; return K_BUTTERFLY; }
|
||||
chip_erase_delay { yylval=NULL; return K_CHIP_ERASE_DELAY; }
|
||||
desc { yylval=NULL; return K_DESC; }
|
||||
default_parallel { yylval=NULL; return K_DEFAULT_PARALLEL; }
|
||||
default_programmer { yylval=NULL; return K_DEFAULT_PROGRAMMER; }
|
||||
default_serial { yylval=NULL; return K_DEFAULT_SERIAL; }
|
||||
devicecode { yylval=NULL; return K_DEVICECODE; }
|
||||
dragon_dw { yylval=NULL; return K_DRAGON_DW; }
|
||||
dragon_hvsp { yylval=NULL; return K_DRAGON_HVSP; }
|
||||
dragon_isp { yylval=NULL; return K_DRAGON_ISP; }
|
||||
dragon_jtag { yylval=NULL; return K_DRAGON_JTAG; }
|
||||
dragon_pp { yylval=NULL; return K_DRAGON_PP; }
|
||||
eecr { yylval=NULL; return K_EECR; }
|
||||
eeprom { yylval=NULL; return K_EEPROM; }
|
||||
enablepageprogramming { yylval=NULL; return K_ENABLEPAGEPROGRAMMING; }
|
||||
errled { yylval=NULL; return K_ERRLED; }
|
||||
flash { yylval=NULL; return K_FLASH; }
|
||||
has_jtag { yylval=NULL; return K_HAS_JTAG; }
|
||||
has_debugwire { yylval=NULL; return K_HAS_DW; }
|
||||
has_pdi { yylval=NULL; return K_HAS_PDI; }
|
||||
id { yylval=NULL; return K_ID; }
|
||||
idr { yylval=NULL; return K_IDR; }
|
||||
jtagmki { yylval=NULL; return K_JTAG_MKI; }
|
||||
jtagmkii { yylval=NULL; return K_JTAG_MKII; }
|
||||
jtagmkii_dw { yylval=NULL; return K_JTAG_MKII_DW; }
|
||||
jtagmkii_isp { yylval=NULL; return K_JTAG_MKII_ISP; }
|
||||
max_write_delay { yylval=NULL; return K_MAX_WRITE_DELAY; }
|
||||
memory { yylval=NULL; return K_MEMORY; }
|
||||
min_write_delay { yylval=NULL; return K_MIN_WRITE_DELAY; }
|
||||
@@ -136,6 +160,8 @@ miso { yylval=NULL; return K_MISO; }
|
||||
mosi { yylval=NULL; return K_MOSI; }
|
||||
num_banks { yylval=NULL; return K_NUM_PAGES; }
|
||||
num_pages { yylval=NULL; return K_NUM_PAGES; }
|
||||
nvm_base { yylval=NULL; return K_NVM_BASE; }
|
||||
offset { yylval=NULL; return K_OFFSET; }
|
||||
page_size { yylval=NULL; return K_PAGE_SIZE; }
|
||||
paged { yylval=NULL; return K_PAGED; }
|
||||
pagel { yylval=NULL; return K_PAGEL; }
|
||||
@@ -145,17 +171,65 @@ part { yylval=NULL; return K_PART; }
|
||||
pgmled { yylval=NULL; return K_PGMLED; }
|
||||
programmer { yylval=NULL; return K_PROGRAMMER; }
|
||||
pwroff_after_write { yylval=NULL; return K_PWROFF_AFTER_WRITE; }
|
||||
rampz { yylval=NULL; return K_RAMPZ; }
|
||||
rdyled { yylval=NULL; return K_RDYLED; }
|
||||
readback_p1 { yylval=NULL; return K_READBACK_P1; }
|
||||
readback_p2 { yylval=NULL; return K_READBACK_P2; }
|
||||
retry_pulse { yylval=NULL; return K_RETRY_PULSE; }
|
||||
serbb { yylval=NULL; return K_SERBB; }
|
||||
serial { yylval=NULL; return K_SERIAL; }
|
||||
signature { yylval=NULL; return K_SIGNATURE; }
|
||||
size { yylval=NULL; return K_SIZE; }
|
||||
spmcr { yylval=NULL; return K_SPMCR; }
|
||||
stk500 { yylval=NULL; return K_STK500; }
|
||||
stk500hvsp { yylval=NULL; return K_STK500HVSP; }
|
||||
stk500pp { yylval=NULL; return K_STK500PP; }
|
||||
stk500v2 { yylval=NULL; return K_STK500V2; }
|
||||
stk500generic { yylval=NULL; return K_STK500GENERIC; }
|
||||
stk500_devcode { yylval=NULL; return K_STK500_DEVCODE; }
|
||||
stk600 { yylval=NULL; return K_STK600; }
|
||||
stk600hvsp { yylval=NULL; return K_STK600HVSP; }
|
||||
stk600pp { yylval=NULL; return K_STK600PP; }
|
||||
type { yylval=NULL; return K_TYPE; }
|
||||
vcc { yylval=NULL; return K_VCC; }
|
||||
vfyled { yylval=NULL; return K_VFYLED; }
|
||||
|
||||
timeout { yylval=NULL; return K_TIMEOUT; }
|
||||
stabdelay { yylval=NULL; return K_STABDELAY; }
|
||||
cmdexedelay { yylval=NULL; return K_CMDEXEDELAY; }
|
||||
hvspcmdexedelay { yylval=NULL; return K_HVSPCMDEXEDELAY; }
|
||||
synchloops { yylval=NULL; return K_SYNCHLOOPS; }
|
||||
bytedelay { yylval=NULL; return K_BYTEDELAY; }
|
||||
pollvalue { yylval=NULL; return K_POLLVALUE; }
|
||||
pollindex { yylval=NULL; return K_POLLINDEX; }
|
||||
predelay { yylval=NULL; return K_PREDELAY; }
|
||||
postdelay { yylval=NULL; return K_POSTDELAY; }
|
||||
pollmethod { yylval=NULL; return K_POLLMETHOD; }
|
||||
mode { yylval=NULL; return K_MODE; }
|
||||
delay { yylval=NULL; return K_DELAY; }
|
||||
blocksize { yylval=NULL; return K_BLOCKSIZE; }
|
||||
readsize { yylval=NULL; return K_READSIZE; }
|
||||
pp_controlstack { yylval=NULL; return K_PP_CONTROLSTACK; }
|
||||
hvsp_controlstack { yylval=NULL; return K_HVSP_CONTROLSTACK; }
|
||||
hventerstabdelay { yylval=NULL; return K_HVENTERSTABDELAY; }
|
||||
progmodedelay { yylval=NULL; return K_PROGMODEDELAY; }
|
||||
latchcycles { yylval=NULL; return K_LATCHCYCLES; }
|
||||
togglevtg { yylval=NULL; return K_TOGGLEVTG; }
|
||||
poweroffdelay { yylval=NULL; return K_POWEROFFDELAY; }
|
||||
resetdelayms { yylval=NULL; return K_RESETDELAYMS; }
|
||||
resetdelayus { yylval=NULL; return K_RESETDELAYUS; }
|
||||
hvleavestabdelay { yylval=NULL; return K_HVLEAVESTABDELAY; }
|
||||
resetdelay { yylval=NULL; return K_RESETDELAY; }
|
||||
synchcycles { yylval=NULL; return K_SYNCHCYCLES; }
|
||||
chiperasepulsewidth { yylval=NULL; return K_CHIPERASEPULSEWIDTH; }
|
||||
chiperasepolltimeout { yylval=NULL; return K_CHIPERASEPOLLTIMEOUT; }
|
||||
chiperasetime { yylval=NULL; return K_CHIPERASETIME; }
|
||||
programfusepulsewidth { yylval=NULL; return K_PROGRAMFUSEPULSEWIDTH; }
|
||||
programfusepolltimeout { yylval=NULL; return K_PROGRAMFUSEPOLLTIMEOUT; }
|
||||
programlockpulsewidth { yylval=NULL; return K_PROGRAMLOCKPULSEWIDTH; }
|
||||
programlockpolltimeout { yylval=NULL; return K_PROGRAMLOCKPOLLTIMEOUT; }
|
||||
flash_instr { yylval=NULL; return K_FLASH_INSTR; }
|
||||
eeprom_instr { yylval=NULL; return K_EEPROM_INSTR; }
|
||||
|
||||
dedicated { yylval=new_token(K_DEDICATED); return K_DEDICATED; }
|
||||
io { yylval=new_token(K_IO); return K_IO; }
|
||||
@@ -172,6 +246,7 @@ write_lo { yylval=new_token(K_WRITE_LO); return K_WRITE_LO; }
|
||||
write_hi { yylval=new_token(K_WRITE_HI); return K_WRITE_HI; }
|
||||
loadpage_lo { yylval=new_token(K_LOADPAGE_LO); return K_LOADPAGE_LO; }
|
||||
loadpage_hi { yylval=new_token(K_LOADPAGE_HI); return K_LOADPAGE_HI; }
|
||||
load_ext_addr { yylval=new_token(K_LOAD_EXT_ADDR); return K_LOAD_EXT_ADDR; }
|
||||
writepage { yylval=new_token(K_WRITEPAGE); return K_WRITEPAGE; }
|
||||
chip_erase { yylval=new_token(K_CHIP_ERASE); return K_CHIP_ERASE; }
|
||||
pgm_enable { yylval=new_token(K_PGM_ENABLE); return K_PGM_ENABLE; }
|
||||
@@ -182,9 +257,10 @@ yes { yylval=new_token(K_YES); return K_YES; }
|
||||
"," { yylval = NULL; pyytext(); return TKN_COMMA; }
|
||||
"=" { yylval = NULL; pyytext(); return TKN_EQUAL; }
|
||||
";" { yylval = NULL; pyytext(); return TKN_SEMI; }
|
||||
"~" { yylval = NULL; pyytext(); return TKN_TILDE; }
|
||||
|
||||
"\n" { lineno++; }
|
||||
[ \r\t]+ /* ignore whitespace */
|
||||
[ \r\t]+ { /* ignore whitespace */ }
|
||||
|
||||
c: { fprintf(stderr, "error at %s:%d: possible old-style config file entry\n",
|
||||
infile, lineno);
|
||||
|
||||
@@ -1,5 +1,26 @@
|
||||
#ifndef __linux_ppdev_h__
|
||||
#define __linux_ppdev_h__
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2003, 2005 Theodore A. Roth
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef linux_ppdev_h
|
||||
#define linux_ppdev_h
|
||||
|
||||
#define OBSOLETE__IOW _IOW
|
||||
|
||||
@@ -9,29 +30,28 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define PPISDATA PPWDATA
|
||||
#define PPIGDATA PPRDATA
|
||||
|
||||
#define PPISCTRL PPWCONTROL
|
||||
#define PPIGCTRL PPRCONTROL
|
||||
|
||||
#define PPISSTATUS PPWSTATUS
|
||||
#define PPIGSTATUS PPRSTATUS
|
||||
|
||||
#define ppi_claim(pgm) \
|
||||
if (ioctl(pgm->fd, PPCLAIM)) { \
|
||||
#define ppi_claim(fd) \
|
||||
if (ioctl(fd, PPCLAIM)) { \
|
||||
fprintf(stderr, "%s: can't claim device \"%s\": %s\n\n", \
|
||||
progname, port, strerror(errno)); \
|
||||
close(pgm->fd); \
|
||||
close(fd); \
|
||||
exit(1); \
|
||||
}
|
||||
}
|
||||
|
||||
#define ppi_release(pgm) \
|
||||
if (ioctl(pgm->fd, PPRELEASE)) { \
|
||||
#define ppi_release(fd) \
|
||||
if (ioctl(fd, PPRELEASE)) { \
|
||||
fprintf(stderr, "%s: can't release device: %s\n\n", \
|
||||
progname, strerror(errno)); \
|
||||
exit(1); \
|
||||
}
|
||||
|
||||
#define DO_PPI_READ(fd, reg, valp) \
|
||||
(void)ioctl(fd, \
|
||||
(reg) == PPIDATA? PPRDATA: ((reg) == PPICTRL? PPRCONTROL: PPRSTATUS), \
|
||||
valp)
|
||||
#define DO_PPI_WRITE(fd, reg, valp) \
|
||||
(void)ioctl(fd, \
|
||||
(reg) == PPIDATA? PPWDATA: ((reg) == PPICTRL? PPWCONTROL: PPWSTATUS), \
|
||||
valp)
|
||||
|
||||
#endif /* __linux_ppdev_h__ */
|
||||
#endif /* linux_ppdev_h */
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
|
||||
* 1998, 1999, 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 1990-2004 Brian S. Dean <bsd@bsdhome.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
|
||||
@@ -413,11 +412,6 @@ lcreat ( void * liststruct, int elements )
|
||||
{
|
||||
LIST * l;
|
||||
|
||||
if (LISTSZ != sizeof(LIST)) {
|
||||
printf ( "lcreat(): warning, LISTSZ[%d] != sizeof(LIST)[%d]\n",
|
||||
LISTSZ, sizeof(LIST) );
|
||||
}
|
||||
|
||||
if (liststruct == NULL) {
|
||||
/*--------------------------------------------------
|
||||
allocate memory for the list itself
|
||||
@@ -1296,8 +1290,8 @@ int lprint ( FILE * f, LISTID lid )
|
||||
|
||||
l = (LIST *)lid;
|
||||
|
||||
fprintf ( f, "list id 0x%08x internal data structures:\n",
|
||||
(unsigned int)lid );
|
||||
fprintf ( f, "list id %p internal data structures:\n",
|
||||
lid );
|
||||
#if CHECK_MAGIC
|
||||
if ((l->magic1 != MAGIC) || (l->magic2 != MAGIC)) {
|
||||
fprintf ( f, " *** WARNING: LIST MAGIC IS CORRUPT ***\n" );
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
|
||||
* 1998, 1999, 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 1990-2004 Brian S. Dean <bsd@bsdhome.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
|
||||
@@ -29,8 +28,8 @@
|
||||
Author : Brian Dean
|
||||
Date : 10 January, 1990
|
||||
----------------------------------------------------------------------*/
|
||||
#ifndef __lists_h__
|
||||
#define __lists_h__
|
||||
#ifndef lists_h
|
||||
#define lists_h
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -68,8 +67,9 @@ typedef void * LNODEID;
|
||||
#define LISTRMV(l,d) lrmv_d(l,d) /* remove from end of the list */
|
||||
|
||||
|
||||
#define LISTSZ 32 /* size of internal private LIST structure */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* .................... Function Prototypes .................... */
|
||||
|
||||
@@ -108,4 +108,8 @@ void * lsrch ( LISTID lid, void * p, int (*compare)(void *p1,void *p2));
|
||||
|
||||
int lprint ( FILE * f, LISTID lid );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
1183
avrdude/main.c
1183
avrdude/main.c
File diff suppressed because it is too large
Load Diff
49
avrdude/my_ddk_hidsdi.h
Normal file
49
avrdude/my_ddk_hidsdi.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2006 Christian Starkjohann
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
The following is a replacement for hidsdi.h from the Windows DDK. It defines some
|
||||
of the types and function prototypes of this header for our project. If you
|
||||
have the Windows DDK version of this file or a version shipped with MinGW, use
|
||||
that instead.
|
||||
*/
|
||||
#ifndef MY_DDK_HIDSDI_H
|
||||
#define MY_DDK_HIDSDI_H
|
||||
#include <pshpack4.h>
|
||||
#include <ddk/hidusage.h>
|
||||
#include <ddk/hidpi.h>
|
||||
typedef struct{
|
||||
ULONG Size;
|
||||
USHORT VendorID;
|
||||
USHORT ProductID;
|
||||
USHORT VersionNumber;
|
||||
}HIDD_ATTRIBUTES;
|
||||
void __stdcall HidD_GetHidGuid(OUT LPGUID hidGuid);
|
||||
BOOLEAN __stdcall HidD_GetAttributes(IN HANDLE device, OUT HIDD_ATTRIBUTES *attributes);
|
||||
BOOLEAN __stdcall HidD_GetManufacturerString(IN HANDLE device, OUT void *buffer, IN ULONG bufferLen);
|
||||
BOOLEAN __stdcall HidD_GetProductString(IN HANDLE device, OUT void *buffer, IN ULONG bufferLen);
|
||||
BOOLEAN __stdcall HidD_GetSerialNumberString(IN HANDLE device, OUT void *buffer, IN ULONG bufferLen);
|
||||
BOOLEAN __stdcall HidD_GetFeature(IN HANDLE device, OUT void *reportBuffer, IN ULONG bufferLen);
|
||||
BOOLEAN __stdcall HidD_SetFeature(IN HANDLE device, IN void *reportBuffer, IN ULONG bufferLen);
|
||||
BOOLEAN __stdcall HidD_GetNumInputBuffers(IN HANDLE device, OUT ULONG *numBuffers);
|
||||
BOOLEAN __stdcall HidD_SetNumInputBuffers(IN HANDLE device, OUT ULONG numBuffers);
|
||||
#include <poppack.h>
|
||||
#endif /* MY_DDK_HIDSDI_H */
|
||||
583
avrdude/par.c
583
avrdude/par.c
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2000-2006 Brian S. Dean <bsd@bsdhome.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
|
||||
@@ -29,18 +29,21 @@
|
||||
#include <errno.h>
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#include <dev/ppbus/ppi.h>
|
||||
# include "freebsd_ppi.h"
|
||||
#elif defined(__linux__)
|
||||
#include "linux_ppdev.h"
|
||||
# include "linux_ppdev.h"
|
||||
#elif defined(__sun__) || defined(__sun) /* Solaris */
|
||||
# include "solaris_ecpp.h"
|
||||
#endif
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "avr.h"
|
||||
#include "pindefs.h"
|
||||
#include "pgm.h"
|
||||
#include "par.h"
|
||||
#include "ppi.h"
|
||||
#include "bitbang.h"
|
||||
|
||||
#define SLOW_TOGGLE 0
|
||||
#if HAVE_PARPORT
|
||||
|
||||
struct ppipins_t {
|
||||
int pin;
|
||||
@@ -49,7 +52,7 @@ struct ppipins_t {
|
||||
int inverted;
|
||||
};
|
||||
|
||||
static struct ppipins_t pins[] = {
|
||||
static struct ppipins_t ppipins[] = {
|
||||
{ 1, PPICTRL, 0x01, 1 },
|
||||
{ 2, PPIDATA, 0x01, 0 },
|
||||
{ 3, PPIDATA, 0x02, 0 },
|
||||
@@ -69,333 +72,136 @@ static struct ppipins_t pins[] = {
|
||||
{ 17, PPICTRL, 0x08, 1 }
|
||||
};
|
||||
|
||||
#define NPINS (sizeof(pins)/sizeof(struct ppipins_t))
|
||||
#define NPINS (sizeof(ppipins)/sizeof(struct ppipins_t))
|
||||
|
||||
|
||||
extern char * progname;
|
||||
extern int do_cycles;
|
||||
extern int verbose;
|
||||
|
||||
|
||||
static int par_setpin (int fd, int pin, int value);
|
||||
|
||||
static int par_getpin (int fd, int pin);
|
||||
|
||||
static int par_pulsepin (int fd, int pin);
|
||||
|
||||
|
||||
static int par_rdy_led (PROGRAMMER * pgm, int value);
|
||||
|
||||
static int par_err_led (PROGRAMMER * pgm, int value);
|
||||
|
||||
static int par_pgm_led (PROGRAMMER * pgm, int value);
|
||||
|
||||
static int par_vfy_led (PROGRAMMER * pgm, int value);
|
||||
|
||||
static int par_cmd (PROGRAMMER * pgm, unsigned char cmd[4],
|
||||
unsigned char res[4]);
|
||||
|
||||
static int par_chip_erase (PROGRAMMER * pgm, AVRPART * p);
|
||||
|
||||
static int par_program_enable (PROGRAMMER * pgm, AVRPART * p);
|
||||
|
||||
static void par_powerup (PROGRAMMER * pgm);
|
||||
|
||||
static void par_powerdown (PROGRAMMER * pgm);
|
||||
|
||||
static int par_initialize (PROGRAMMER * pgm, AVRPART * p);
|
||||
|
||||
static int par_save (PROGRAMMER * pgm);
|
||||
|
||||
static void par_restore (PROGRAMMER * pgm);
|
||||
|
||||
static void par_disable (PROGRAMMER * pgm);
|
||||
|
||||
static void par_enable (PROGRAMMER * pgm);
|
||||
|
||||
static void par_open (PROGRAMMER * pgm, char * port);
|
||||
|
||||
static void par_close (PROGRAMMER * pgm);
|
||||
|
||||
|
||||
static int par_setpin(int fd, int pin, int value)
|
||||
static int par_setpin(PROGRAMMER * pgm, int pin, int value)
|
||||
{
|
||||
int inverted;
|
||||
|
||||
inverted = pin & PIN_INVERSE;
|
||||
pin &= PIN_MASK;
|
||||
|
||||
if (pin < 1 || pin > 17)
|
||||
return -1;
|
||||
|
||||
pin--;
|
||||
|
||||
if (pins[pin].inverted)
|
||||
if (ppipins[pin].inverted)
|
||||
inverted = !inverted;
|
||||
|
||||
if (inverted)
|
||||
value = !value;
|
||||
|
||||
if (value)
|
||||
ppi_set(fd, pins[pin].reg, pins[pin].bit);
|
||||
ppi_set(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
|
||||
else
|
||||
ppi_clr(fd, pins[pin].reg, pins[pin].bit);
|
||||
ppi_clr(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
|
||||
|
||||
#if SLOW_TOGGLE
|
||||
usleep(1000);
|
||||
#endif
|
||||
if (pgm->ispdelay > 1)
|
||||
bitbang_delay(pgm->ispdelay);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void par_setmany(PROGRAMMER * pgm, unsigned int pinset, int value)
|
||||
{
|
||||
int pin;
|
||||
|
||||
static int par_getpin(int fd, int pin)
|
||||
for (pin = 1; pin <= 17; pin++) {
|
||||
if (pinset & (1 << pin))
|
||||
par_setpin(pgm, pin, value);
|
||||
}
|
||||
}
|
||||
|
||||
static int par_getpin(PROGRAMMER * pgm, int pin)
|
||||
{
|
||||
int value;
|
||||
int inverted;
|
||||
|
||||
inverted = pin & PIN_INVERSE;
|
||||
pin &= PIN_MASK;
|
||||
|
||||
if (pin < 1 || pin > 17)
|
||||
return -1;
|
||||
|
||||
pin--;
|
||||
|
||||
value = ppi_get(fd, pins[pin].reg, pins[pin].bit);
|
||||
value = ppi_get(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
|
||||
|
||||
if (value)
|
||||
value = 1;
|
||||
|
||||
if (pins[pin].inverted)
|
||||
if (ppipins[pin].inverted)
|
||||
inverted = !inverted;
|
||||
|
||||
if (inverted)
|
||||
value = !value;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
static int par_pulsepin(int fd, int pin)
|
||||
static int par_highpulsepin(PROGRAMMER * pgm, int pin)
|
||||
{
|
||||
int inverted;
|
||||
|
||||
inverted = pin & PIN_INVERSE;
|
||||
pin &= PIN_MASK;
|
||||
|
||||
if (pin < 1 || pin > 17)
|
||||
return -1;
|
||||
|
||||
pin--;
|
||||
|
||||
ppi_toggle(fd, pins[pin].reg, pins[pin].bit);
|
||||
if (ppipins[pin].inverted)
|
||||
inverted = !inverted;
|
||||
|
||||
#if SLOW_TOGGLE
|
||||
usleep(1000);
|
||||
#endif
|
||||
if (inverted) {
|
||||
ppi_clr(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
|
||||
if (pgm->ispdelay > 1)
|
||||
bitbang_delay(pgm->ispdelay);
|
||||
|
||||
ppi_toggle(fd, pins[pin].reg, pins[pin].bit);
|
||||
ppi_set(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
|
||||
if (pgm->ispdelay > 1)
|
||||
bitbang_delay(pgm->ispdelay);
|
||||
} else {
|
||||
ppi_set(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
|
||||
if (pgm->ispdelay > 1)
|
||||
bitbang_delay(pgm->ispdelay);
|
||||
|
||||
#if SLOW_TOGGLE
|
||||
usleep(1000);
|
||||
#endif
|
||||
ppi_clr(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
|
||||
if (pgm->ispdelay > 1)
|
||||
bitbang_delay(pgm->ispdelay);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int par_getpinmask(int pin)
|
||||
static char * pins_to_str(unsigned int pmask)
|
||||
{
|
||||
if (pin < 1 || pin > 17)
|
||||
return -1;
|
||||
|
||||
return pins[pin-1].bit;
|
||||
}
|
||||
|
||||
|
||||
static char vccpins_buf[64];
|
||||
static char * vccpins_str(unsigned int pmask)
|
||||
{
|
||||
unsigned int mask;
|
||||
static char buf[64];
|
||||
int pin;
|
||||
char b2[8];
|
||||
char * b;
|
||||
|
||||
b = vccpins_buf;
|
||||
|
||||
b[0] = 0;
|
||||
for (pin = 2, mask = 1; mask < 0x80; mask = mask << 1, pin++) {
|
||||
if (pmask & mask) {
|
||||
buf[0] = 0;
|
||||
for (pin = 1; pin <= 17; pin++) {
|
||||
if (pmask & (1 << pin)) {
|
||||
sprintf(b2, "%d", pin);
|
||||
if (b[0] != 0)
|
||||
strcat(b, ",");
|
||||
strcat(b, b2);
|
||||
if (buf[0] != 0)
|
||||
strcat(buf, ",");
|
||||
strcat(buf, b2);
|
||||
}
|
||||
}
|
||||
|
||||
return b;
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* transmit and receive a byte of data to/from the AVR device
|
||||
*/
|
||||
static unsigned char par_txrx(PROGRAMMER * pgm, unsigned char byte)
|
||||
{
|
||||
int i;
|
||||
unsigned char r, b, rbyte;
|
||||
|
||||
rbyte = 0;
|
||||
for (i=0; i<8; i++) {
|
||||
b = (byte >> (7-i)) & 0x01;
|
||||
|
||||
/*
|
||||
* read the result bit (it is either valid from a previous clock
|
||||
* pulse or it is ignored in the current context)
|
||||
*/
|
||||
r = par_getpin(pgm->fd, pgm->pinno[PIN_AVR_MISO]);
|
||||
|
||||
/* set the data input line as desired */
|
||||
par_setpin(pgm->fd, pgm->pinno[PIN_AVR_MOSI], b);
|
||||
|
||||
/*
|
||||
* pulse the clock line, clocking in the MOSI data, and clocking out
|
||||
* the next result bit
|
||||
*/
|
||||
par_pulsepin(pgm->fd, pgm->pinno[PIN_AVR_SCK]);
|
||||
|
||||
rbyte = rbyte | (r << (7-i));
|
||||
}
|
||||
|
||||
return rbyte;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int par_rdy_led(PROGRAMMER * pgm, int value)
|
||||
{
|
||||
par_setpin(pgm->fd, pgm->pinno[PIN_LED_RDY], !value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int par_err_led(PROGRAMMER * pgm, int value)
|
||||
{
|
||||
par_setpin(pgm->fd, pgm->pinno[PIN_LED_ERR], !value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int par_pgm_led(PROGRAMMER * pgm, int value)
|
||||
{
|
||||
par_setpin(pgm->fd, pgm->pinno[PIN_LED_PGM], !value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int par_vfy_led(PROGRAMMER * pgm, int value)
|
||||
{
|
||||
par_setpin(pgm->fd, pgm->pinno[PIN_LED_VFY], !value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* transmit an AVR device command and return the results; 'cmd' and
|
||||
* 'res' must point to at least a 4 byte data buffer
|
||||
*/
|
||||
static int par_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
|
||||
unsigned char res[4])
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<4; i++) {
|
||||
res[i] = par_txrx(pgm, cmd[i]);
|
||||
}
|
||||
|
||||
if(verbose >= 2)
|
||||
{
|
||||
fprintf(stderr, "par_cmd(): [ ");
|
||||
for(i = 0; i < 4; i++)
|
||||
fprintf(stderr, "%02X ", cmd[i]);
|
||||
fprintf(stderr, "] [ ");
|
||||
for(i = 0; i < 4; i++)
|
||||
{
|
||||
fprintf(stderr, "%02X ", res[i]);
|
||||
}
|
||||
fprintf(stderr, "]\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* issue the 'chip erase' command to the AVR device
|
||||
*/
|
||||
static int par_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
unsigned char cmd[4];
|
||||
unsigned char res[4];
|
||||
int cycles;
|
||||
int rc;
|
||||
|
||||
if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
|
||||
fprintf(stderr, "chip erase instruction not defined for part \"%s\"\n",
|
||||
p->desc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = avr_get_cycle_count(pgm, p, &cycles);
|
||||
|
||||
/*
|
||||
* only print out the current cycle count if we aren't going to
|
||||
* display it below
|
||||
*/
|
||||
if (!do_cycles && ((rc >= 0) && (cycles != 0xffffffff))) {
|
||||
fprintf(stderr,
|
||||
"%s: current erase-rewrite cycle count is %d%s\n",
|
||||
progname, cycles,
|
||||
do_cycles ? "" : " (if being tracked)");
|
||||
}
|
||||
|
||||
pgm->pgm_led(pgm, ON);
|
||||
|
||||
memset(cmd, 0, sizeof(cmd));
|
||||
|
||||
avr_set_bits(p->op[AVR_OP_CHIP_ERASE], cmd);
|
||||
pgm->cmd(pgm, cmd, res);
|
||||
usleep(p->chip_erase_delay);
|
||||
pgm->initialize(pgm, p);
|
||||
|
||||
pgm->pgm_led(pgm, OFF);
|
||||
|
||||
if (do_cycles && (cycles != -1)) {
|
||||
if (cycles == 0x00ffff) {
|
||||
cycles = 0;
|
||||
}
|
||||
cycles++;
|
||||
fprintf(stderr, "%s: erase-rewrite cycle count is now %d\n",
|
||||
progname, cycles);
|
||||
avr_put_cycle_count(pgm, p, cycles);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* issue the 'program enable' command to the AVR device
|
||||
*/
|
||||
static int par_program_enable(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
unsigned char cmd[4];
|
||||
unsigned char res[4];
|
||||
|
||||
if (p->op[AVR_OP_PGM_ENABLE] == NULL) {
|
||||
fprintf(stderr, "program enable instruction not defined for part \"%s\"\n",
|
||||
p->desc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(cmd, 0, sizeof(cmd));
|
||||
avr_set_bits(p->op[AVR_OP_PGM_ENABLE], cmd);
|
||||
pgm->cmd(pgm, cmd, res);
|
||||
|
||||
if (res[2] != cmd[1])
|
||||
return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* apply power to the AVR processor
|
||||
*/
|
||||
static void par_powerup(PROGRAMMER * pgm)
|
||||
{
|
||||
ppi_set(pgm->fd, PPIDATA, pgm->pinno[PPI_AVR_VCC]); /* power up */
|
||||
par_setmany(pgm, pgm->pinno[PPI_AVR_VCC], 1); /* power up */
|
||||
usleep(100000);
|
||||
}
|
||||
|
||||
@@ -405,86 +211,12 @@ static void par_powerup(PROGRAMMER * pgm)
|
||||
*/
|
||||
static void par_powerdown(PROGRAMMER * pgm)
|
||||
{
|
||||
ppi_clr(pgm->fd, PPIDATA, pgm->pinno[PPI_AVR_VCC]); /* power down */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* initialize the AVR device and prepare it to accept commands
|
||||
*/
|
||||
static int par_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
int rc;
|
||||
int tries;
|
||||
|
||||
pgm->powerup(pgm);
|
||||
usleep(20000);
|
||||
|
||||
par_setpin(pgm->fd, pgm->pinno[PIN_AVR_SCK], 0);
|
||||
par_setpin(pgm->fd, pgm->pinno[PIN_AVR_RESET], 0);
|
||||
usleep(20000);
|
||||
|
||||
par_pulsepin(pgm->fd, pgm->pinno[PIN_AVR_RESET]);
|
||||
|
||||
usleep(20000); /* 20 ms XXX should be a per-chip parameter */
|
||||
|
||||
/*
|
||||
* Enable programming mode. If we are programming an AT90S1200, we
|
||||
* can only issue the command and hope it worked. If we are using
|
||||
* one of the other chips, the chip will echo 0x53 when issuing the
|
||||
* third byte of the command. In this case, try up to 32 times in
|
||||
* order to possibly get back into sync with the chip if we are out
|
||||
* of sync.
|
||||
*/
|
||||
if (strcmp(p->desc, "AT90S1200")==0) {
|
||||
pgm->program_enable(pgm, p);
|
||||
}
|
||||
else {
|
||||
tries = 0;
|
||||
do {
|
||||
rc = pgm->program_enable(pgm, p);
|
||||
if ((rc == 0)||(rc == -1))
|
||||
break;
|
||||
par_pulsepin(pgm->fd, pgm->pinno[p->retry_pulse/*PIN_AVR_SCK*/]);
|
||||
tries++;
|
||||
} while (tries < 65);
|
||||
|
||||
/*
|
||||
* can't sync with the device, maybe it's not attached?
|
||||
*/
|
||||
if (rc) {
|
||||
fprintf(stderr, "%s: AVR device not responding\n", progname);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int par_save(PROGRAMMER * pgm)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = ppi_getall(pgm->fd, PPIDATA);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: error reading status of ppi data port\n", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pgm->ppidata = rc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void par_restore(PROGRAMMER * pgm)
|
||||
{
|
||||
ppi_setall(pgm->fd, PPIDATA, pgm->ppidata);
|
||||
par_setmany(pgm, pgm->pinno[PPI_AVR_VCC], 0); /* power down */
|
||||
}
|
||||
|
||||
static void par_disable(PROGRAMMER * pgm)
|
||||
{
|
||||
ppi_set(pgm->fd, PPIDATA, pgm->pinno[PPI_AVR_BUFF]);
|
||||
par_setmany(pgm, pgm->pinno[PPI_AVR_BUFF], 1); /* turn off */
|
||||
}
|
||||
|
||||
static void par_enable(PROGRAMMER * pgm)
|
||||
@@ -500,62 +232,119 @@ static void par_enable(PROGRAMMER * pgm)
|
||||
* and not via the buffer chip.
|
||||
*/
|
||||
|
||||
par_setpin(pgm->fd, pgm->pinno[PIN_AVR_RESET], 0);
|
||||
par_setpin(pgm, pgm->pinno[PIN_AVR_RESET], 0);
|
||||
usleep(1);
|
||||
|
||||
/*
|
||||
* enable the 74367 buffer, if connected; this signal is active low
|
||||
*/
|
||||
ppi_clr(pgm->fd, PPIDATA, pgm->pinno[PPI_AVR_BUFF]);
|
||||
par_setmany(pgm, pgm->pinno[PPI_AVR_BUFF], 0);
|
||||
}
|
||||
|
||||
|
||||
static void par_open(PROGRAMMER * pgm, char * port)
|
||||
static int par_open(PROGRAMMER * pgm, char * port)
|
||||
{
|
||||
pgm->fd = ppi_open(port);
|
||||
if (pgm->fd < 0) {
|
||||
int rc;
|
||||
|
||||
bitbang_check_prerequisites(pgm);
|
||||
|
||||
ppi_open(port, &pgm->fd);
|
||||
if (pgm->fd.ifd < 0) {
|
||||
fprintf(stderr, "%s: failed to open parallel port \"%s\"\n\n",
|
||||
progname, port);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ppi_claim(pgm);
|
||||
/*
|
||||
* save pin values, so they can be restored when device is closed
|
||||
*/
|
||||
rc = ppi_getall(&pgm->fd, PPIDATA);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: error reading status of ppi data port\n", progname);
|
||||
return -1;
|
||||
}
|
||||
pgm->ppidata = rc;
|
||||
|
||||
rc = ppi_getall(&pgm->fd, PPICTRL);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: error reading status of ppi ctrl port\n", progname);
|
||||
return -1;
|
||||
}
|
||||
pgm->ppictrl = rc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void par_close(PROGRAMMER * pgm)
|
||||
{
|
||||
ppi_release(pgm);
|
||||
|
||||
ppi_close(pgm->fd);
|
||||
pgm->fd = -1;
|
||||
/*
|
||||
* Restore pin values before closing,
|
||||
* but ensure that buffers are turned off.
|
||||
*/
|
||||
ppi_setall(&pgm->fd, PPIDATA, pgm->ppidata);
|
||||
ppi_setall(&pgm->fd, PPICTRL, pgm->ppictrl);
|
||||
|
||||
par_setpin(pgm, pgm->pinno[PPI_AVR_BUFF], 1);
|
||||
|
||||
/*
|
||||
* Handle exit specs.
|
||||
*/
|
||||
switch (pgm->exit_reset) {
|
||||
case EXIT_RESET_ENABLED:
|
||||
par_setpin(pgm, pgm->pinno[PIN_AVR_RESET], 0);
|
||||
break;
|
||||
|
||||
case EXIT_RESET_DISABLED:
|
||||
par_setpin(pgm, pgm->pinno[PIN_AVR_RESET], 1);
|
||||
break;
|
||||
|
||||
case EXIT_RESET_UNSPEC:
|
||||
/* Leave it alone. */
|
||||
break;
|
||||
}
|
||||
switch (pgm->exit_vcc) {
|
||||
case EXIT_VCC_ENABLED:
|
||||
par_setmany(pgm, pgm->pinno[PPI_AVR_VCC], 1);
|
||||
break;
|
||||
|
||||
case EXIT_VCC_DISABLED:
|
||||
par_setmany(pgm, pgm->pinno[PPI_AVR_VCC], 0);
|
||||
break;
|
||||
|
||||
case EXIT_VCC_UNSPEC:
|
||||
/* Leave it alone. */
|
||||
break;
|
||||
}
|
||||
|
||||
ppi_close(&pgm->fd);
|
||||
pgm->fd.ifd = -1;
|
||||
}
|
||||
|
||||
|
||||
static void par_display(PROGRAMMER * pgm, char * p)
|
||||
static void par_display(PROGRAMMER * pgm, const char * p)
|
||||
{
|
||||
char vccpins[64];
|
||||
char buffpins[64];
|
||||
|
||||
if (pgm->pinno[PPI_AVR_VCC]) {
|
||||
snprintf(vccpins, sizeof(vccpins), " = pins %s",
|
||||
vccpins_str(pgm->pinno[PPI_AVR_VCC]));
|
||||
snprintf(vccpins, sizeof(vccpins), "%s",
|
||||
pins_to_str(pgm->pinno[PPI_AVR_VCC]));
|
||||
}
|
||||
else {
|
||||
strcpy(vccpins, " (not used)");
|
||||
}
|
||||
|
||||
if (pgm->pinno[PPI_AVR_BUFF]) {
|
||||
snprintf(buffpins, sizeof(buffpins), " = pins %s",
|
||||
vccpins_str(pgm->pinno[PPI_AVR_BUFF]));
|
||||
snprintf(buffpins, sizeof(buffpins), "%s",
|
||||
pins_to_str(pgm->pinno[PPI_AVR_BUFF]));
|
||||
}
|
||||
else {
|
||||
strcpy(buffpins, " (not used)");
|
||||
}
|
||||
|
||||
fprintf(stderr,
|
||||
"%s VCC = 0x%02x%s\n"
|
||||
"%s BUFF = 0x%02x%s\n"
|
||||
"%s VCC = %s\n"
|
||||
"%s BUFF = %s\n"
|
||||
"%s RESET = %d\n"
|
||||
"%s SCK = %d\n"
|
||||
"%s MOSI = %d\n"
|
||||
@@ -565,8 +354,8 @@ static void par_display(PROGRAMMER * pgm, char * p)
|
||||
"%s PGM LED = %d\n"
|
||||
"%s VFY LED = %d\n",
|
||||
|
||||
p, pgm->pinno[PPI_AVR_VCC], vccpins,
|
||||
p, pgm->pinno[PPI_AVR_BUFF], buffpins,
|
||||
p, vccpins,
|
||||
p, buffpins,
|
||||
p, pgm->pinno[PIN_AVR_RESET],
|
||||
p, pgm->pinno[PIN_AVR_SCK],
|
||||
p, pgm->pinno[PIN_AVR_MOSI],
|
||||
@@ -578,27 +367,73 @@ static void par_display(PROGRAMMER * pgm, char * p)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* parse the -E string
|
||||
*/
|
||||
static int par_parseexitspecs(PROGRAMMER * pgm, char *s)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
while ((cp = strtok(s, ","))) {
|
||||
if (strcmp(cp, "reset") == 0) {
|
||||
pgm->exit_reset = EXIT_RESET_ENABLED;
|
||||
}
|
||||
else if (strcmp(cp, "noreset") == 0) {
|
||||
pgm->exit_reset = EXIT_RESET_DISABLED;
|
||||
}
|
||||
else if (strcmp(cp, "vcc") == 0) {
|
||||
pgm->exit_vcc = EXIT_VCC_ENABLED;
|
||||
}
|
||||
else if (strcmp(cp, "novcc") == 0) {
|
||||
pgm->exit_vcc = EXIT_VCC_DISABLED;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
s = 0; /* strtok() should be called with the actual string only once */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void par_initpgm(PROGRAMMER * pgm)
|
||||
{
|
||||
strcpy(pgm->type, "PPI");
|
||||
|
||||
pgm->rdy_led = par_rdy_led;
|
||||
pgm->err_led = par_err_led;
|
||||
pgm->pgm_led = par_pgm_led;
|
||||
pgm->vfy_led = par_vfy_led;
|
||||
pgm->initialize = par_initialize;
|
||||
pgm->exit_vcc = EXIT_VCC_UNSPEC;
|
||||
pgm->exit_reset = EXIT_RESET_UNSPEC;
|
||||
|
||||
pgm->rdy_led = bitbang_rdy_led;
|
||||
pgm->err_led = bitbang_err_led;
|
||||
pgm->pgm_led = bitbang_pgm_led;
|
||||
pgm->vfy_led = bitbang_vfy_led;
|
||||
pgm->initialize = bitbang_initialize;
|
||||
pgm->display = par_display;
|
||||
pgm->save = par_save;
|
||||
pgm->restore = par_restore;
|
||||
pgm->enable = par_enable;
|
||||
pgm->disable = par_disable;
|
||||
pgm->powerup = par_powerup;
|
||||
pgm->powerdown = par_powerdown;
|
||||
pgm->program_enable = par_program_enable;
|
||||
pgm->chip_erase = par_chip_erase;
|
||||
pgm->cmd = par_cmd;
|
||||
pgm->program_enable = bitbang_program_enable;
|
||||
pgm->chip_erase = bitbang_chip_erase;
|
||||
pgm->cmd = bitbang_cmd;
|
||||
pgm->spi = bitbang_spi;
|
||||
pgm->open = par_open;
|
||||
pgm->close = par_close;
|
||||
pgm->setpin = par_setpin;
|
||||
pgm->getpin = par_getpin;
|
||||
pgm->highpulsepin = par_highpulsepin;
|
||||
pgm->parseexitspecs = par_parseexitspecs;
|
||||
pgm->read_byte = avr_read_byte_default;
|
||||
pgm->write_byte = avr_write_byte_default;
|
||||
}
|
||||
|
||||
#else /* !HAVE_PARPORT */
|
||||
|
||||
void par_initpgm(PROGRAMMER * pgm)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: parallel port access not available in this configuration\n",
|
||||
progname);
|
||||
}
|
||||
|
||||
#endif /* HAVE_PARPORT */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.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
|
||||
@@ -19,15 +19,17 @@
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef __par_h__
|
||||
#define __par_h__
|
||||
#ifndef par_h
|
||||
#define par_h
|
||||
|
||||
#include "config.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void par_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
int par_getpinmask(int pin);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
161
avrdude/pgm.c
161
avrdude/pgm.c
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright 2007 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -25,17 +26,40 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "pgm.h"
|
||||
|
||||
extern char * progname;
|
||||
static int pgm_default_2 (struct programmer_t *, AVRPART *);
|
||||
static int pgm_default_3 (struct programmer_t * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned long addr, unsigned char * value);
|
||||
static void pgm_default_4 (struct programmer_t *);
|
||||
static int pgm_default_5 (struct programmer_t * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned long addr, unsigned char data);
|
||||
static void pgm_default_6 (struct programmer_t *, const char *);
|
||||
|
||||
int pgm_default_1 (struct programmer_t *, int);
|
||||
int pgm_default_2 (struct programmer_t *, AVRPART *);
|
||||
int pgm_default_3 (struct programmer_t *);
|
||||
void pgm_default_4 (struct programmer_t *);
|
||||
int pgm_default_5 (struct programmer_t *, unsigned char cmd[4],
|
||||
unsigned char res[4]);
|
||||
void pgm_default_6 (struct programmer_t *, char *);
|
||||
|
||||
static int pgm_default_open (struct programmer_t *pgm, char * name)
|
||||
{
|
||||
fprintf (stderr, "\n%s: Fatal error: Programmer does not support open()",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int pgm_default_led (struct programmer_t * pgm, int value)
|
||||
{
|
||||
/*
|
||||
* If programmer has no LEDs, just do nothing.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void pgm_default_powerup_powerdown (struct programmer_t * pgm)
|
||||
{
|
||||
/*
|
||||
* If programmer does not support powerup/down, just do nothing.
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
PROGRAMMER * pgm_new(void)
|
||||
@@ -57,6 +81,7 @@ PROGRAMMER * pgm_new(void)
|
||||
pgm->type[0] = 0;
|
||||
pgm->config_file[0] = 0;
|
||||
pgm->lineno = 0;
|
||||
pgm->baudrate = 0;
|
||||
|
||||
for (i=0; i<N_PINS; i++)
|
||||
pgm->pinno[i] = 0;
|
||||
@@ -65,74 +90,138 @@ PROGRAMMER * pgm_new(void)
|
||||
* mandatory functions - these are called without checking to see
|
||||
* whether they are assigned or not
|
||||
*/
|
||||
pgm->rdy_led = pgm_default_1;
|
||||
pgm->err_led = pgm_default_1;
|
||||
pgm->pgm_led = pgm_default_1;
|
||||
pgm->vfy_led = pgm_default_1;
|
||||
pgm->initialize = pgm_default_2;
|
||||
pgm->display = pgm_default_6;
|
||||
pgm->save = pgm_default_3;
|
||||
pgm->restore = pgm_default_4;
|
||||
pgm->enable = pgm_default_4;
|
||||
pgm->disable = pgm_default_4;
|
||||
pgm->powerup = pgm_default_4;
|
||||
pgm->powerdown = pgm_default_4;
|
||||
pgm->powerup = pgm_default_powerup_powerdown;
|
||||
pgm->powerdown = pgm_default_powerup_powerdown;
|
||||
pgm->program_enable = pgm_default_2;
|
||||
pgm->chip_erase = pgm_default_2;
|
||||
pgm->cmd = pgm_default_5;
|
||||
pgm->open = pgm_default_6;
|
||||
pgm->open = pgm_default_open;
|
||||
pgm->close = pgm_default_4;
|
||||
pgm->read_byte = pgm_default_3;
|
||||
pgm->write_byte = pgm_default_5;
|
||||
|
||||
/*
|
||||
* predefined functions - these functions have a valid default
|
||||
* implementation. Hence, they don't need to be defined in
|
||||
* the programmer.
|
||||
*/
|
||||
pgm->rdy_led = pgm_default_led;
|
||||
pgm->err_led = pgm_default_led;
|
||||
pgm->pgm_led = pgm_default_led;
|
||||
pgm->vfy_led = pgm_default_led;
|
||||
|
||||
/*
|
||||
* optional functions - these are checked to make sure they are
|
||||
* assigned before they are called
|
||||
*/
|
||||
pgm->cmd = NULL;
|
||||
pgm->spi = NULL;
|
||||
pgm->paged_write = NULL;
|
||||
pgm->paged_load = NULL;
|
||||
pgm->write_setup = NULL;
|
||||
pgm->read_sig_bytes = NULL;
|
||||
pgm->set_vtarget = NULL;
|
||||
pgm->set_varef = NULL;
|
||||
pgm->set_fosc = NULL;
|
||||
pgm->perform_osccal = NULL;
|
||||
pgm->parseextparams = NULL;
|
||||
pgm->setup = NULL;
|
||||
pgm->teardown = NULL;
|
||||
|
||||
return pgm;
|
||||
}
|
||||
|
||||
|
||||
void pgm_default(void)
|
||||
static void pgm_default(void)
|
||||
{
|
||||
fprintf(stderr, "%s: programmer operation not supported\n", progname);
|
||||
}
|
||||
|
||||
|
||||
int pgm_default_1 (struct programmer_t * pgm, int value)
|
||||
static int pgm_default_2 (struct programmer_t * pgm, AVRPART * p)
|
||||
{
|
||||
pgm_default();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int pgm_default_2 (struct programmer_t * pgm, AVRPART * p)
|
||||
static int pgm_default_3 (struct programmer_t * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned long addr, unsigned char * value)
|
||||
{
|
||||
pgm_default();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int pgm_default_3 (struct programmer_t * pgm)
|
||||
static void pgm_default_4 (struct programmer_t * pgm)
|
||||
{
|
||||
pgm_default();
|
||||
}
|
||||
|
||||
static int pgm_default_5 (struct programmer_t * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned long addr, unsigned char data)
|
||||
{
|
||||
pgm_default();
|
||||
return -1;
|
||||
}
|
||||
|
||||
void pgm_default_4 (struct programmer_t * pgm)
|
||||
{
|
||||
pgm_default();
|
||||
}
|
||||
|
||||
int pgm_default_5 (struct programmer_t * pgm, unsigned char cmd[4],
|
||||
unsigned char res[4])
|
||||
{
|
||||
pgm_default();
|
||||
return -1;
|
||||
}
|
||||
|
||||
void pgm_default_6 (struct programmer_t * pgm, char * p)
|
||||
static void pgm_default_6 (struct programmer_t * pgm, const char * p)
|
||||
{
|
||||
pgm_default();
|
||||
}
|
||||
|
||||
|
||||
void programmer_display(PROGRAMMER * pgm, const char * p)
|
||||
{
|
||||
fprintf(stderr, "%sProgrammer Type : %s\n", p, pgm->type);
|
||||
fprintf(stderr, "%sDescription : %s\n", p, pgm->desc);
|
||||
|
||||
pgm->display(pgm, p);
|
||||
}
|
||||
|
||||
PROGRAMMER * locate_programmer(LISTID programmers, const char * configid)
|
||||
{
|
||||
LNODEID ln1, ln2;
|
||||
PROGRAMMER * p = NULL;
|
||||
const char * id;
|
||||
int found;
|
||||
|
||||
found = 0;
|
||||
|
||||
for (ln1=lfirst(programmers); ln1 && !found; ln1=lnext(ln1)) {
|
||||
p = ldata(ln1);
|
||||
for (ln2=lfirst(p->id); ln2 && !found; ln2=lnext(ln2)) {
|
||||
id = ldata(ln2);
|
||||
if (strcasecmp(configid, id) == 0)
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
return p;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate over the list of programmers given as "programmers", and
|
||||
* call the callback function cb for each entry found. cb is being
|
||||
* passed the following arguments:
|
||||
* . the name of the programmer (for -c)
|
||||
* . the descriptive text given in the config file
|
||||
* . the name of the config file this programmer has been defined in
|
||||
* . the line number of the config file this programmer has been defined at
|
||||
* . the "cookie" passed into walk_programmers() (opaque client data)
|
||||
*/
|
||||
void walk_programmers(LISTID programmers, walk_programmers_cb cb, void *cookie)
|
||||
{
|
||||
LNODEID ln1;
|
||||
PROGRAMMER * p;
|
||||
|
||||
for (ln1 = lfirst(programmers); ln1; ln1 = lnext(ln1)) {
|
||||
p = ldata(ln1);
|
||||
cb((char *)ldata(lfirst(p->id)), p->desc, p->config_file, p->lineno, cookie);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright 2007 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -19,15 +20,15 @@
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef __pgm_h__
|
||||
#define __pgm_h__
|
||||
#ifndef pgm_h
|
||||
#define pgm_h
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "avrpart.h"
|
||||
#include "lists.h"
|
||||
#include "pindefs.h"
|
||||
|
||||
#include "serial.h"
|
||||
|
||||
#define ON 1
|
||||
#define OFF 0
|
||||
@@ -35,23 +36,40 @@
|
||||
#define PGM_DESCLEN 80
|
||||
#define PGM_PORTLEN PATH_MAX
|
||||
#define PGM_TYPELEN 32
|
||||
|
||||
typedef enum {
|
||||
EXIT_VCC_UNSPEC,
|
||||
EXIT_VCC_ENABLED,
|
||||
EXIT_VCC_DISABLED
|
||||
} exit_vcc_t;
|
||||
|
||||
typedef enum {
|
||||
EXIT_RESET_UNSPEC,
|
||||
EXIT_RESET_ENABLED,
|
||||
EXIT_RESET_DISABLED
|
||||
} exit_reset_t;
|
||||
|
||||
typedef struct programmer_t {
|
||||
LISTID id;
|
||||
char desc[PGM_DESCLEN];
|
||||
char type[PGM_TYPELEN];
|
||||
char port[PGM_PORTLEN];
|
||||
unsigned int pinno[N_PINS];
|
||||
exit_vcc_t exit_vcc;
|
||||
exit_reset_t exit_reset;
|
||||
int ppidata;
|
||||
int fd;
|
||||
int ppictrl;
|
||||
int baudrate;
|
||||
double bitclock; /* JTAG ICE clock period in microseconds */
|
||||
int ispdelay; /* ISP clock delay */
|
||||
union filedescriptor fd;
|
||||
int page_size; /* page size if the programmer supports paged write/load */
|
||||
int (*rdy_led) (struct programmer_t * pgm, int value);
|
||||
int (*err_led) (struct programmer_t * pgm, int value);
|
||||
int (*pgm_led) (struct programmer_t * pgm, int value);
|
||||
int (*vfy_led) (struct programmer_t * pgm, int value);
|
||||
int (*initialize) (struct programmer_t * pgm, AVRPART * p);
|
||||
void (*display) (struct programmer_t * pgm, char * p);
|
||||
int (*save) (struct programmer_t * pgm);
|
||||
void (*restore) (struct programmer_t * pgm);
|
||||
void (*display) (struct programmer_t * pgm, const char * p);
|
||||
void (*enable) (struct programmer_t * pgm);
|
||||
void (*disable) (struct programmer_t * pgm);
|
||||
void (*powerup) (struct programmer_t * pgm);
|
||||
@@ -60,17 +78,55 @@ typedef struct programmer_t {
|
||||
int (*chip_erase) (struct programmer_t * pgm, AVRPART * p);
|
||||
int (*cmd) (struct programmer_t * pgm, unsigned char cmd[4],
|
||||
unsigned char res[4]);
|
||||
void (*open) (struct programmer_t * pgm, char * port);
|
||||
int (*spi) (struct programmer_t * pgm, unsigned char cmd[],
|
||||
unsigned char res[], int count);
|
||||
int (*open) (struct programmer_t * pgm, char * port);
|
||||
void (*close) (struct programmer_t * pgm);
|
||||
int (*paged_write) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int n_bytes);
|
||||
int (*paged_load) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int n_bytes);
|
||||
void (*write_setup) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m);
|
||||
int (*write_byte) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned long addr, unsigned char value);
|
||||
int (*read_byte) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned long addr, unsigned char * value);
|
||||
int (*read_sig_bytes) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m);
|
||||
void (*print_parms) (struct programmer_t * pgm);
|
||||
int (*set_vtarget) (struct programmer_t * pgm, double v);
|
||||
int (*set_varef) (struct programmer_t * pgm, unsigned int chan, double v);
|
||||
int (*set_fosc) (struct programmer_t * pgm, double v);
|
||||
int (*set_sck_period) (struct programmer_t * pgm, double v);
|
||||
int (*setpin) (struct programmer_t * pgm, int pin, int value);
|
||||
int (*getpin) (struct programmer_t * pgm, int pin);
|
||||
int (*highpulsepin) (struct programmer_t * pgm, int pin);
|
||||
int (*parseexitspecs) (struct programmer_t * pgm, char *s);
|
||||
int (*perform_osccal) (struct programmer_t * pgm);
|
||||
int (*parseextparams) (struct programmer_t * pgm, LISTID xparams);
|
||||
void (*setup) (struct programmer_t * pgm);
|
||||
void (*teardown) (struct programmer_t * pgm);
|
||||
char config_file[PATH_MAX]; /* config file where defined */
|
||||
int lineno; /* config file line number */
|
||||
void *cookie; /* for private use by the programmer */
|
||||
char flag; /* for private use of the programmer */
|
||||
} PROGRAMMER;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
PROGRAMMER * pgm_new(void);
|
||||
|
||||
void programmer_display(PROGRAMMER * pgm, const char * p);
|
||||
PROGRAMMER * locate_programmer(LISTID programmers, const char * configid);
|
||||
|
||||
typedef void (*walk_programmers_cb)(const char *name, const char *desc,
|
||||
const char *cfgname, int cfglineno,
|
||||
void *cookie);
|
||||
void walk_programmers(LISTID programmers, walk_programmers_cb cb, void *cookie);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.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
|
||||
@@ -35,6 +35,8 @@ enum {
|
||||
PIN_LED_VFY,
|
||||
N_PINS
|
||||
};
|
||||
#define PIN_INVERSE 0x80 /* flag for inverted pin in serbb */
|
||||
#define PIN_MASK 0x7f
|
||||
|
||||
#define LED_ON(fd,pin) ppi_setpin(fd,pin,0)
|
||||
#define LED_OFF(fd,pin) ppi_setpin(fd,pin,1)
|
||||
|
||||
145
avrdude/ppi.c
145
avrdude/ppi.c
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.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
|
||||
@@ -19,10 +19,13 @@
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__linux__)
|
||||
|
||||
#if !defined(WIN32NATIVE)
|
||||
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#if HAVE_PARPORT
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -31,36 +34,40 @@
|
||||
#include <errno.h>
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#include <dev/ppbus/ppi.h>
|
||||
# include "freebsd_ppi.h"
|
||||
#elif defined(__linux__)
|
||||
#include "linux_ppdev.h"
|
||||
# include "linux_ppdev.h"
|
||||
#elif defined(__sun__) || defined(__sun) /* Solaris */
|
||||
# include "solaris_ecpp.h"
|
||||
#endif
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "avr.h"
|
||||
#include "pindefs.h"
|
||||
#include "pgm.h"
|
||||
#include "ppi.h"
|
||||
|
||||
extern char * progname;
|
||||
enum {
|
||||
PPI_READ,
|
||||
PPI_WRITE,
|
||||
PPI_SHADOWREAD
|
||||
};
|
||||
|
||||
/*
|
||||
* set 'get' and 'set' appropriately for subsequent passage to ioctl()
|
||||
* to get/set the specified PPI registers.
|
||||
*/
|
||||
static int ppi_getops(int reg, unsigned long * get, unsigned long * set)
|
||||
static int ppi_shadow_access(union filedescriptor *fdp, int reg,
|
||||
unsigned char *v, unsigned char action)
|
||||
{
|
||||
static unsigned char shadow[3];
|
||||
int shadow_num;
|
||||
|
||||
switch (reg) {
|
||||
case PPIDATA:
|
||||
*set = PPISDATA;
|
||||
*get = PPIGDATA;
|
||||
shadow_num = 0;
|
||||
break;
|
||||
case PPICTRL:
|
||||
*set = PPISCTRL;
|
||||
*get = PPIGCTRL;
|
||||
shadow_num = 1;
|
||||
break;
|
||||
case PPISTATUS:
|
||||
*set = PPISSTATUS;
|
||||
*get = PPIGSTATUS;
|
||||
shadow_num = 2;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "%s: avr_set(): invalid register=%d\n",
|
||||
@@ -69,27 +76,37 @@ static int ppi_getops(int reg, unsigned long * get, unsigned long * set)
|
||||
break;
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case PPI_SHADOWREAD:
|
||||
*v = shadow[shadow_num];
|
||||
break;
|
||||
case PPI_READ:
|
||||
DO_PPI_READ(fdp->ifd, reg, v);
|
||||
shadow[shadow_num]=*v;
|
||||
break;
|
||||
case PPI_WRITE:
|
||||
shadow[shadow_num]=*v;
|
||||
DO_PPI_WRITE(fdp->ifd, reg, v);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* set the indicated bit of the specified register.
|
||||
*/
|
||||
int ppi_set(int fd, int reg, int bit)
|
||||
int ppi_set(union filedescriptor *fdp, int reg, int bit)
|
||||
{
|
||||
unsigned char v;
|
||||
unsigned long get, set;
|
||||
int rc;
|
||||
|
||||
rc = ppi_getops(reg, &get, &set);
|
||||
rc = ppi_shadow_access(fdp, reg, &v, PPI_SHADOWREAD);
|
||||
v |= bit;
|
||||
rc |= ppi_shadow_access(fdp, reg, &v, PPI_WRITE);
|
||||
|
||||
if (rc)
|
||||
return -1;
|
||||
|
||||
ioctl(fd, get, &v);
|
||||
v |= bit;
|
||||
ioctl(fd, set, &v);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -97,20 +114,18 @@ int ppi_set(int fd, int reg, int bit)
|
||||
/*
|
||||
* clear the indicated bit of the specified register.
|
||||
*/
|
||||
int ppi_clr(int fd, int reg, int bit)
|
||||
int ppi_clr(union filedescriptor *fdp, int reg, int bit)
|
||||
{
|
||||
unsigned char v;
|
||||
unsigned long get, set;
|
||||
int rc;
|
||||
|
||||
rc = ppi_getops(reg, &get, &set);
|
||||
rc = ppi_shadow_access(fdp, reg, &v, PPI_SHADOWREAD);
|
||||
v &= ~bit;
|
||||
rc |= ppi_shadow_access(fdp, reg, &v, PPI_WRITE);
|
||||
|
||||
if (rc)
|
||||
return -1;
|
||||
|
||||
ioctl(fd, get, &v);
|
||||
v &= ~bit;
|
||||
ioctl(fd, set, &v);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -118,39 +133,35 @@ int ppi_clr(int fd, int reg, int bit)
|
||||
/*
|
||||
* get the indicated bit of the specified register.
|
||||
*/
|
||||
int ppi_get(int fd, int reg, int bit)
|
||||
int ppi_get(union filedescriptor *fdp, int reg, int bit)
|
||||
{
|
||||
unsigned char v;
|
||||
unsigned long get, set;
|
||||
int rc;
|
||||
|
||||
rc = ppi_getops(reg, &get, &set);
|
||||
rc = ppi_shadow_access(fdp, reg, &v, PPI_READ);
|
||||
v &= bit;
|
||||
|
||||
if (rc)
|
||||
return -1;
|
||||
|
||||
ioctl(fd, get, &v);
|
||||
v &= bit;
|
||||
|
||||
return v; /* v == bit */
|
||||
}
|
||||
|
||||
/*
|
||||
* toggle the indicated bit of the specified register.
|
||||
*/
|
||||
int ppi_toggle(int fd, int reg, int bit)
|
||||
int ppi_toggle(union filedescriptor *fdp, int reg, int bit)
|
||||
{
|
||||
unsigned char v;
|
||||
unsigned long get, set;
|
||||
int rc;
|
||||
|
||||
rc = ppi_getops(reg, &get, &set);
|
||||
rc = ppi_shadow_access(fdp, reg, &v, PPI_SHADOWREAD);
|
||||
v ^= bit;
|
||||
rc |= ppi_shadow_access(fdp, reg, &v, PPI_WRITE);
|
||||
|
||||
if (rc)
|
||||
return -1;
|
||||
|
||||
ioctl(fd, get, &v);
|
||||
v ^= bit;
|
||||
ioctl(fd, set, &v);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -158,60 +169,70 @@ int ppi_toggle(int fd, int reg, int bit)
|
||||
/*
|
||||
* get all bits of the specified register.
|
||||
*/
|
||||
int ppi_getall(int fd, int reg)
|
||||
int ppi_getall(union filedescriptor *fdp, int reg)
|
||||
{
|
||||
unsigned char v;
|
||||
unsigned long get, set;
|
||||
int rc;
|
||||
|
||||
rc = ppi_getops(reg, &get, &set);
|
||||
rc = ppi_shadow_access(fdp, reg, &v, PPI_READ);
|
||||
|
||||
if (rc)
|
||||
return -1;
|
||||
|
||||
ioctl(fd, get, &v);
|
||||
|
||||
return (int)v;
|
||||
return v; /* v == bit */
|
||||
}
|
||||
|
||||
/*
|
||||
* set all bits of the specified register to val.
|
||||
*/
|
||||
int ppi_setall(int fd, int reg, int val)
|
||||
int ppi_setall(union filedescriptor *fdp, int reg, int val)
|
||||
{
|
||||
unsigned char v;
|
||||
unsigned long get, set;
|
||||
int rc;
|
||||
|
||||
rc = ppi_getops(reg, &get, &set);
|
||||
v = val;
|
||||
rc = ppi_shadow_access(fdp, reg, &v, PPI_WRITE);
|
||||
|
||||
if (rc)
|
||||
return -1;
|
||||
|
||||
v = val;
|
||||
ioctl(fd, set, &v);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ppi_open(char * port)
|
||||
void ppi_open(char * port, union filedescriptor *fdp)
|
||||
{
|
||||
int fd;
|
||||
unsigned char v;
|
||||
|
||||
fd = open(port, O_RDWR);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "%s: can't open device \"%s\": %s\n",
|
||||
progname, port, strerror(errno));
|
||||
return -1;
|
||||
fdp->ifd = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
return fd;
|
||||
ppi_claim (fd);
|
||||
|
||||
/*
|
||||
* Initialize shadow registers
|
||||
*/
|
||||
|
||||
ppi_shadow_access (fdp, PPIDATA, &v, PPI_READ);
|
||||
ppi_shadow_access (fdp, PPICTRL, &v, PPI_READ);
|
||||
ppi_shadow_access (fdp, PPISTATUS, &v, PPI_READ);
|
||||
|
||||
fdp->ifd = fd;
|
||||
}
|
||||
|
||||
|
||||
void ppi_close(int fd)
|
||||
void ppi_close(union filedescriptor *fdp)
|
||||
{
|
||||
close(fd);
|
||||
ppi_release (fdp->ifd);
|
||||
close(fdp->ifd);
|
||||
}
|
||||
|
||||
#endif /* HAVE_PARPORT */
|
||||
|
||||
#endif
|
||||
#endif /* !WIN32NATIVE */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.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
|
||||
@@ -19,10 +19,8 @@
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef __ppi_h__
|
||||
#define __ppi_h__
|
||||
|
||||
#include "config.h"
|
||||
#ifndef ppi_h
|
||||
#define ppi_h
|
||||
|
||||
/*
|
||||
* PPI registers
|
||||
@@ -33,31 +31,30 @@ enum {
|
||||
PPISTATUS
|
||||
};
|
||||
|
||||
|
||||
#if !defined(ppi_claim)
|
||||
# define ppi_claim(pgm)
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined(ppi_release)
|
||||
# define ppi_release(pgm)
|
||||
int ppi_get (union filedescriptor *fdp, int reg, int bit);
|
||||
|
||||
int ppi_set (union filedescriptor *fdp, int reg, int bit);
|
||||
|
||||
int ppi_clr (union filedescriptor *fdp, int reg, int bit);
|
||||
|
||||
int ppi_getall (union filedescriptor *fdp, int reg);
|
||||
|
||||
int ppi_setall (union filedescriptor *fdp, int reg, int val);
|
||||
|
||||
int ppi_toggle (union filedescriptor *fdp, int reg, int bit);
|
||||
|
||||
void ppi_open (char * port, union filedescriptor *fdp);
|
||||
|
||||
void ppi_close (union filedescriptor *fdp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
int ppi_get (int fd, int reg, int bit);
|
||||
|
||||
int ppi_set (int fd, int reg, int bit);
|
||||
|
||||
int ppi_clr (int fd, int reg, int bit);
|
||||
|
||||
int ppi_getall (int fd, int reg);
|
||||
|
||||
int ppi_setall (int fd, int reg, int val);
|
||||
|
||||
int ppi_toggle (int fd, int reg, int bit);
|
||||
|
||||
int ppi_open (char * port);
|
||||
|
||||
void ppi_close (int fd);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
152
avrdude/ppiwin.c
152
avrdude/ppiwin.c
@@ -1,6 +1,8 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2003 Eric B. Weddington <eric@umginc.net> or <eric@ecentral.com>
|
||||
* Copyright (C) 2003, 2004, 2006
|
||||
* Eric B. Weddington <eweddington@cso.atmel.com>
|
||||
* Copyright 2008, Joerg Wunsch
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -17,6 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
This is the parallel port interface for Windows built using Cygwin.
|
||||
@@ -28,9 +31,10 @@ reg = register as defined in an enum in ppi.h. This must be converted
|
||||
*/
|
||||
|
||||
|
||||
#include "ac_cfg.h"
|
||||
#include "avrdude.h"
|
||||
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
#if defined (WIN32NATIVE)
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
@@ -39,14 +43,12 @@ reg = register as defined in an enum in ppi.h. This must be converted
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <windows.h>
|
||||
#include <sys/time.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "serial.h"
|
||||
#include "ppi.h"
|
||||
|
||||
|
||||
|
||||
extern char *progname;
|
||||
|
||||
|
||||
|
||||
#define DEVICE_LPT1 "lpt1"
|
||||
#define DEVICE_LPT2 "lpt2"
|
||||
#define DEVICE_LPT3 "lpt3"
|
||||
@@ -72,7 +74,7 @@ static const winpp winports[DEVICE_MAX] =
|
||||
|
||||
/* FUNCTION PROTOTYPES */
|
||||
static int winnt_pp_open(void);
|
||||
static unsigned short port_get(int fd, int reg);
|
||||
static unsigned short port_get(union filedescriptor *fdp, int reg);
|
||||
static unsigned char reg2offset(int reg);
|
||||
static unsigned char inb(unsigned short port);
|
||||
static void outb(unsigned char value, unsigned short port);
|
||||
@@ -81,7 +83,7 @@ static void outb(unsigned char value, unsigned short port);
|
||||
|
||||
/* FUNCTION DEFINITIONS */
|
||||
|
||||
int ppi_open(char *port)
|
||||
void ppi_open(char *port, union filedescriptor *fdp)
|
||||
{
|
||||
unsigned char i;
|
||||
int fd;
|
||||
@@ -91,7 +93,8 @@ int ppi_open(char *port)
|
||||
if(fd < 0)
|
||||
{
|
||||
fprintf(stderr, "%s: can't open device \"giveio\"\n\n", progname);
|
||||
return(-1);
|
||||
fdp->ifd = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Search the windows port names for a match */
|
||||
@@ -105,13 +108,32 @@ int ppi_open(char *port)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(fd == -1)
|
||||
{
|
||||
/*
|
||||
* Supplied port name did not match any of the pre-defined
|
||||
* names. Try interpreting it as a numeric
|
||||
* (hexadecimal/decimal/octal) address.
|
||||
*/
|
||||
char *cp;
|
||||
|
||||
fd = strtol(port, &cp, 0);
|
||||
if(*port == '\0' || *cp != '\0')
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: port name \"%s\" is neither lpt1/2/3 nor valid number\n",
|
||||
progname, port);
|
||||
fd = -1;
|
||||
}
|
||||
}
|
||||
if(fd < 0)
|
||||
{
|
||||
fprintf(stderr, "%s: can't open device \"%s\"\n\n", progname, port);
|
||||
return(-1);
|
||||
fdp->ifd = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
return(fd);
|
||||
fdp->ifd = fd;
|
||||
}
|
||||
|
||||
|
||||
@@ -156,7 +178,7 @@ static int winnt_pp_open(void)
|
||||
|
||||
|
||||
|
||||
void ppi_close(int fd)
|
||||
void ppi_close(union filedescriptor *fdp)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -166,12 +188,12 @@ void ppi_close(int fd)
|
||||
/*
|
||||
* set the indicated bit of the specified register.
|
||||
*/
|
||||
int ppi_set(int fd, int reg, int bit)
|
||||
int ppi_set(union filedescriptor *fdp, int reg, int bit)
|
||||
{
|
||||
unsigned char v;
|
||||
unsigned short port;
|
||||
|
||||
port = port_get(fd, reg);
|
||||
port = port_get(fdp, reg);
|
||||
v = inb(port);
|
||||
v |= bit;
|
||||
outb(v, port);
|
||||
@@ -182,12 +204,12 @@ int ppi_set(int fd, int reg, int bit)
|
||||
/*
|
||||
* clear the indicated bit of the specified register.
|
||||
*/
|
||||
int ppi_clr(int fd, int reg, int bit)
|
||||
int ppi_clr(union filedescriptor *fdp, int reg, int bit)
|
||||
{
|
||||
unsigned char v;
|
||||
unsigned short port;
|
||||
|
||||
port = port_get(fd, reg);
|
||||
port = port_get(fdp, reg);
|
||||
v = inb(port);
|
||||
v &= ~bit;
|
||||
outb(v, port);
|
||||
@@ -199,11 +221,11 @@ int ppi_clr(int fd, int reg, int bit)
|
||||
/*
|
||||
* get the indicated bit of the specified register.
|
||||
*/
|
||||
int ppi_get(int fd, int reg, int bit)
|
||||
int ppi_get(union filedescriptor *fdp, int reg, int bit)
|
||||
{
|
||||
unsigned char v;
|
||||
|
||||
v = inb(port_get(fd, reg));
|
||||
v = inb(port_get(fdp, reg));
|
||||
v &= bit;
|
||||
|
||||
return(v);
|
||||
@@ -215,12 +237,12 @@ int ppi_get(int fd, int reg, int bit)
|
||||
/*
|
||||
* toggle the indicated bit of the specified register.
|
||||
*/
|
||||
int ppi_toggle(int fd, int reg, int bit)
|
||||
int ppi_toggle(union filedescriptor *fdp, int reg, int bit)
|
||||
{
|
||||
unsigned char v;
|
||||
unsigned short port;
|
||||
|
||||
port = port_get(fd, reg);
|
||||
port = port_get(fdp, reg);
|
||||
|
||||
v = inb(port);
|
||||
v ^= bit;
|
||||
@@ -233,11 +255,11 @@ int ppi_toggle(int fd, int reg, int bit)
|
||||
/*
|
||||
* get all bits of the specified register.
|
||||
*/
|
||||
int ppi_getall(int fd, int reg)
|
||||
int ppi_getall(union filedescriptor *fdp, int reg)
|
||||
{
|
||||
unsigned char v;
|
||||
|
||||
v = inb(port_get(fd, reg));
|
||||
v = inb(port_get(fdp, reg));
|
||||
|
||||
return((int)v);
|
||||
}
|
||||
@@ -248,9 +270,9 @@ int ppi_getall(int fd, int reg)
|
||||
/*
|
||||
* set all bits of the specified register to val.
|
||||
*/
|
||||
int ppi_setall(int fd, int reg, int val)
|
||||
int ppi_setall(union filedescriptor *fdp, int reg, int val)
|
||||
{
|
||||
outb((unsigned char)val, port_get(fd, reg));
|
||||
outb((unsigned char)val, port_get(fdp, reg));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -258,9 +280,9 @@ int ppi_setall(int fd, int reg, int val)
|
||||
|
||||
|
||||
/* Calculate port address to access. */
|
||||
static unsigned short port_get(int fd, int reg)
|
||||
static unsigned short port_get(union filedescriptor *fdp, int reg)
|
||||
{
|
||||
return((unsigned short)(fd + reg2offset(reg)));
|
||||
return((unsigned short)(fdp->ifd + reg2offset(reg)));
|
||||
}
|
||||
|
||||
|
||||
@@ -315,7 +337,79 @@ static void outb(unsigned char value, unsigned short port)
|
||||
return;
|
||||
}
|
||||
|
||||
#if !defined(HAVE_GETTIMEOFDAY)
|
||||
struct timezone;
|
||||
int gettimeofday(struct timeval *tv, struct timezone *unused){
|
||||
// i've found only ms resolution, avrdude expects us
|
||||
|
||||
SYSTEMTIME st;
|
||||
GetSystemTime(&st);
|
||||
|
||||
tv->tv_sec=(long)(st.wSecond+st.wMinute*60+st.wHour*3600);
|
||||
tv->tv_usec=(long)(st.wMilliseconds*1000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* HAVE_GETTIMEOFDAY */
|
||||
|
||||
// #define W32USLEEPDBG
|
||||
|
||||
#ifdef W32USLEEPDBG
|
||||
|
||||
# define DEBUG_QueryPerformanceCounter(arg) QueryPerformanceCounter(arg)
|
||||
# define DEBUG_DisplayTimingInfo(start, stop, freq, us, has_highperf) \
|
||||
do { \
|
||||
unsigned long dt; \
|
||||
dt = (unsigned long)((stop.QuadPart - start.QuadPart) * 1000 * 1000 \
|
||||
/ freq.QuadPart); \
|
||||
fprintf(stderr, \
|
||||
"hpt:%i usleep usec:%lu sleep msec:%lu timed usec:%lu\n", \
|
||||
has_highperf, us, ((us + 999) / 1000), dt); \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
# define DEBUG_QueryPerformanceCounter(arg)
|
||||
# define DEBUG_DisplayTimingInfo(start, stop, freq, us, has_highperf)
|
||||
|
||||
#endif
|
||||
|
||||
int usleep(unsigned int us)
|
||||
{
|
||||
int has_highperf;
|
||||
LARGE_INTEGER freq,start,stop,loopend;
|
||||
|
||||
// workaround: although usleep is very precise if using
|
||||
// high-performance-timers there are sometimes problems with
|
||||
// verify - increasing the delay helps sometimes but not
|
||||
// realiably. There must be some other problem. Maybe just
|
||||
// with my test-hardware maybe in the code-base.
|
||||
//// us=(unsigned long) (us*1.5);
|
||||
|
||||
has_highperf=QueryPerformanceFrequency(&freq);
|
||||
|
||||
//has_highperf=0; // debug
|
||||
|
||||
if (has_highperf) {
|
||||
QueryPerformanceCounter(&start);
|
||||
loopend.QuadPart=start.QuadPart+freq.QuadPart*us/(1000*1000);
|
||||
do {
|
||||
QueryPerformanceCounter(&stop);
|
||||
} while (stop.QuadPart<=loopend.QuadPart);
|
||||
}
|
||||
else {
|
||||
DEBUG_QueryPerformanceCounter(&start);
|
||||
|
||||
Sleep(1);
|
||||
Sleep( (DWORD)((us+999)/1000) );
|
||||
|
||||
DEBUG_QueryPerformanceCounter(&stop);
|
||||
}
|
||||
|
||||
DEBUG_DisplayTimingInfo(start, stop, freq, us, has_highperf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
363
avrdude/safemode.c
Normal file
363
avrdude/safemode.c
Normal file
@@ -0,0 +1,363 @@
|
||||
/*
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ac_cfg.h"
|
||||
#include "avrdude.h"
|
||||
#include "avr.h"
|
||||
#include "pgm.h"
|
||||
#include "safemode.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, int verbose)
|
||||
{
|
||||
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 */
|
||||
if (verbose > 0) {
|
||||
fprintf(stderr,
|
||||
"%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, int verbose)
|
||||
{
|
||||
|
||||
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;
|
||||
}
|
||||
if (verbose > 2)
|
||||
{
|
||||
fprintf(stderr, "%s: safemode read 1, fuse value: %x\n",progname, safemode_fuse);
|
||||
}
|
||||
if(pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
||||
{
|
||||
allowfuseread = 0;
|
||||
}
|
||||
if (verbose > 2)
|
||||
{
|
||||
fprintf(stderr, "%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;
|
||||
}
|
||||
if (verbose > 2)
|
||||
{
|
||||
fprintf(stderr, "%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) {
|
||||
fprintf(stderr,
|
||||
"%s: safemode: Verify error - unable to read fuse properly. "
|
||||
"Programmer may not be reliable.\n", progname);
|
||||
return -1;
|
||||
}
|
||||
else if ((fusegood == 1) && (verbose > 0)) {
|
||||
printf("%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;
|
||||
}
|
||||
if (verbose > 2)
|
||||
{
|
||||
fprintf(stderr, "%s: safemode read 1, lfuse value: %x\n",progname, safemode_lfuse);
|
||||
}
|
||||
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
||||
{
|
||||
allowfuseread = 0;
|
||||
}
|
||||
if (verbose > 2)
|
||||
{
|
||||
fprintf(stderr, "%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;
|
||||
}
|
||||
if (verbose > 2)
|
||||
{
|
||||
fprintf(stderr, "%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) {
|
||||
fprintf(stderr,
|
||||
"%s: safemode: Verify error - unable to read lfuse properly. "
|
||||
"Programmer may not be reliable.\n", progname);
|
||||
return -1;
|
||||
}
|
||||
else if ((fusegood == 1) && (verbose > 0)) {
|
||||
printf("%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;
|
||||
}
|
||||
if (verbose > 2)
|
||||
{
|
||||
fprintf(stderr, "%s: safemode read 1, hfuse value: %x\n",progname, safemode_hfuse);
|
||||
}
|
||||
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
||||
{
|
||||
allowfuseread = 0;
|
||||
}
|
||||
if (verbose > 2)
|
||||
{
|
||||
fprintf(stderr, "%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;
|
||||
}
|
||||
if (verbose > 2)
|
||||
{
|
||||
fprintf(stderr, "%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) {
|
||||
fprintf(stderr,
|
||||
"%s: safemode: Verify error - unable to read hfuse properly. "
|
||||
"Programmer may not be reliable.\n", progname);
|
||||
return -2;
|
||||
}
|
||||
else if ((fusegood == 1) && (verbose > 0)){
|
||||
printf("%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;
|
||||
}
|
||||
if (verbose > 2)
|
||||
{
|
||||
fprintf(stderr, "%s: safemode read 1, efuse value: %x\n",progname, safemode_efuse);
|
||||
}
|
||||
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
||||
{
|
||||
allowfuseread = 0;
|
||||
}
|
||||
if (verbose > 2)
|
||||
{
|
||||
fprintf(stderr, "%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;
|
||||
}
|
||||
if (verbose > 2)
|
||||
{
|
||||
fprintf(stderr, "%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) {
|
||||
fprintf(stderr,
|
||||
"%s: safemode: Verify error - unable to read efuse properly. "
|
||||
"Programmer may not be reliable.\n", progname);
|
||||
return -3;
|
||||
}
|
||||
else if ((fusegood == 1) && (verbose > 0)) {
|
||||
printf("%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;
|
||||
}
|
||||
47
avrdude/safemode.h
Normal file
47
avrdude/safemode.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
#ifndef safemode_h
|
||||
#define 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, int verbose);
|
||||
|
||||
/* 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, int verbose);
|
||||
|
||||
/* 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
|
||||
|
||||
#endif /* safemode_h */
|
||||
646
avrdude/ser_avrdoper.c
Normal file
646
avrdude/ser_avrdoper.c
Normal file
@@ -0,0 +1,646 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org>
|
||||
* Copyright (C) 2006 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
* Copyright (C) 2006 Christian Starkjohann
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Serial Interface emulation for USB programmer "AVR-Doper" in HID mode.
|
||||
*/
|
||||
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#if defined(HAVE_LIBUSB) || (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "serial.h"
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
/* Numeric constants for 'reportType' parameters */
|
||||
#define USB_HID_REPORT_TYPE_INPUT 1
|
||||
#define USB_HID_REPORT_TYPE_OUTPUT 2
|
||||
#define USB_HID_REPORT_TYPE_FEATURE 3
|
||||
|
||||
/* These are the error codes which can be returned by functions of this
|
||||
* module.
|
||||
*/
|
||||
#define USB_ERROR_NONE 0
|
||||
#define USB_ERROR_ACCESS 1
|
||||
#define USB_ERROR_NOTFOUND 2
|
||||
#define USB_ERROR_BUSY 16
|
||||
#define USB_ERROR_IO 5
|
||||
|
||||
#define USB_VENDOR_ID 0x16c0
|
||||
#define USB_PRODUCT_ID 0x05df
|
||||
|
||||
static int reportDataSizes[4] = {13, 29, 61, 125};
|
||||
|
||||
static unsigned char avrdoperRxBuffer[280]; /* buffer for receive data */
|
||||
static int avrdoperRxLength = 0; /* amount of valid bytes in rx buffer */
|
||||
static int avrdoperRxPosition = 0; /* amount of bytes already consumed in rx buffer */
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#if defined(WIN32NATIVE) && defined(HAVE_LIBHID)
|
||||
|
||||
#include <windows.h>
|
||||
#include <setupapi.h>
|
||||
|
||||
#if defined(HAVE_DDK_HIDSDI_H)
|
||||
# include <ddk/hidsdi.h>
|
||||
#else
|
||||
# include "my_ddk_hidsdi.h"
|
||||
#endif
|
||||
#include <ddk/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++ = '?';
|
||||
}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;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#else /* !(WIN32NATIVE && HAVE_LIBHID) */
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#include <usb.h>
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#define USBRQ_HID_GET_REPORT 0x01
|
||||
#define USBRQ_HID_SET_REPORT 0x09
|
||||
|
||||
static int usesReportIDs;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static int usbGetStringAscii(usb_dev_handle *dev, int index, int langid, char *buf, int buflen)
|
||||
{
|
||||
char buffer[256];
|
||||
int rval, i;
|
||||
|
||||
if((rval = usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR,
|
||||
(USB_DT_STRING << 8) + index, langid, buffer,
|
||||
sizeof(buffer), 1000)) < 0)
|
||||
return rval;
|
||||
if(buffer[1] != USB_DT_STRING)
|
||||
return 0;
|
||||
if((unsigned char)buffer[0] < rval)
|
||||
rval = (unsigned char)buffer[0];
|
||||
rval /= 2;
|
||||
/* lossy conversion to ISO Latin1 */
|
||||
for(i=1;i<rval;i++){
|
||||
if(i > buflen) /* destination buffer overflow */
|
||||
break;
|
||||
buf[i-1] = buffer[2 * i];
|
||||
if(buffer[2 * i + 1] != 0) /* outside of ISO Latin1 range */
|
||||
buf[i-1] = '?';
|
||||
}
|
||||
buf[i-1] = 0;
|
||||
return i-1;
|
||||
}
|
||||
|
||||
static int usbOpenDevice(union filedescriptor *fdp, int vendor, char *vendorName,
|
||||
int product, char *productName, int doReportIDs)
|
||||
{
|
||||
struct usb_bus *bus;
|
||||
struct usb_device *dev;
|
||||
usb_dev_handle *handle = NULL;
|
||||
int errorCode = USB_ERROR_NOTFOUND;
|
||||
static int didUsbInit = 0;
|
||||
|
||||
if(!didUsbInit){
|
||||
usb_init();
|
||||
didUsbInit = 1;
|
||||
}
|
||||
usb_find_busses();
|
||||
usb_find_devices();
|
||||
for(bus=usb_get_busses(); bus; bus=bus->next){
|
||||
for(dev=bus->devices; dev; dev=dev->next){
|
||||
if(dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product){
|
||||
char string[256];
|
||||
int len;
|
||||
handle = usb_open(dev); /* we need to open the device in order to query strings */
|
||||
if(!handle){
|
||||
errorCode = USB_ERROR_ACCESS;
|
||||
fprintf(stderr, "Warning: cannot open USB device: %s\n",
|
||||
usb_strerror());
|
||||
continue;
|
||||
}
|
||||
if(vendorName == NULL && productName == NULL){ /* name does not matter */
|
||||
break;
|
||||
}
|
||||
/* now check whether the names match: */
|
||||
len = usbGetStringAscii(handle, dev->descriptor.iManufacturer,
|
||||
0x0409, string, sizeof(string));
|
||||
if(len < 0){
|
||||
errorCode = USB_ERROR_IO;
|
||||
fprintf(stderr,
|
||||
"Warning: cannot query manufacturer for device: %s\n",
|
||||
usb_strerror());
|
||||
}else{
|
||||
errorCode = USB_ERROR_NOTFOUND;
|
||||
/* fprintf(stderr, "seen device from vendor ->%s<-\n", string); */
|
||||
if(strcmp(string, vendorName) == 0){
|
||||
len = usbGetStringAscii(handle, dev->descriptor.iProduct,
|
||||
0x0409, string, sizeof(string));
|
||||
if(len < 0){
|
||||
errorCode = USB_ERROR_IO;
|
||||
fprintf(stderr,
|
||||
"Warning: cannot query product for device: %s\n",
|
||||
usb_strerror());
|
||||
}else{
|
||||
errorCode = USB_ERROR_NOTFOUND;
|
||||
/* fprintf(stderr, "seen product ->%s<-\n", string); */
|
||||
if(strcmp(string, productName) == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
usb_close(handle);
|
||||
handle = NULL;
|
||||
}
|
||||
}
|
||||
if(handle)
|
||||
break;
|
||||
}
|
||||
if(handle != NULL){
|
||||
int rval, retries = 3;
|
||||
if(usb_set_configuration(handle, 1)){
|
||||
fprintf(stderr, "Warning: could not set configuration: %s\n",
|
||||
usb_strerror());
|
||||
}
|
||||
/* now try to claim the interface and detach the kernel HID driver on
|
||||
* linux and other operating systems which support the call.
|
||||
*/
|
||||
while((rval = usb_claim_interface(handle, 0)) != 0 && retries-- > 0){
|
||||
#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
|
||||
if(usb_detach_kernel_driver_np(handle, 0) < 0){
|
||||
fprintf(stderr, "Warning: could not detach kernel HID driver: %s\n",
|
||||
usb_strerror());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if(rval != 0)
|
||||
fprintf(stderr, "Warning: could not claim interface\n");
|
||||
/* Continue anyway, even if we could not claim the interface. Control transfers
|
||||
* should still work.
|
||||
*/
|
||||
errorCode = 0;
|
||||
fdp->pfd = (void *)handle;
|
||||
usesReportIDs = doReportIDs;
|
||||
}
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static void usbCloseDevice(union filedescriptor *fdp)
|
||||
{
|
||||
usb_close((usb_dev_handle *)fdp->pfd);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static int usbSetReport(union filedescriptor *fdp, int reportType, char *buffer, int len)
|
||||
{
|
||||
int bytesSent;
|
||||
|
||||
if(!usesReportIDs){
|
||||
buffer++; /* skip dummy report ID */
|
||||
len--;
|
||||
}
|
||||
bytesSent = usb_control_msg((usb_dev_handle *)fdp->pfd, USB_TYPE_CLASS |
|
||||
USB_RECIP_INTERFACE | USB_ENDPOINT_OUT, USBRQ_HID_SET_REPORT,
|
||||
reportType << 8 | buffer[0], 0, buffer, len, 5000);
|
||||
if(bytesSent != len){
|
||||
if(bytesSent < 0)
|
||||
fprintf(stderr, "Error sending message: %s\n", usb_strerror());
|
||||
return USB_ERROR_IO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static int usbGetReport(union filedescriptor *fdp, int reportType, int reportNumber,
|
||||
char *buffer, int *len)
|
||||
{
|
||||
int bytesReceived, maxLen = *len;
|
||||
|
||||
if(!usesReportIDs){
|
||||
buffer++; /* make room for dummy report ID */
|
||||
maxLen--;
|
||||
}
|
||||
bytesReceived = usb_control_msg((usb_dev_handle *)fdp->pfd, USB_TYPE_CLASS |
|
||||
USB_RECIP_INTERFACE | USB_ENDPOINT_IN, USBRQ_HID_GET_REPORT,
|
||||
reportType << 8 | reportNumber, 0, buffer, maxLen, 5000);
|
||||
if(bytesReceived < 0){
|
||||
fprintf(stderr, "Error sending message: %s\n", usb_strerror());
|
||||
return USB_ERROR_IO;
|
||||
}
|
||||
*len = bytesReceived;
|
||||
if(!usesReportIDs){
|
||||
buffer[-1] = reportNumber; /* add dummy report ID */
|
||||
len++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* WIN32NATIVE */
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static void dumpBlock(char *prefix, unsigned char *buf, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(len <= 8){ /* more compact format for short blocks */
|
||||
fprintf(stderr, "%s: %d bytes: ", prefix, len);
|
||||
for(i = 0; i < len; i++){
|
||||
fprintf(stderr, "%02x ", buf[i]);
|
||||
}
|
||||
fprintf(stderr, " \"");
|
||||
for(i = 0; i < len; i++){
|
||||
if(buf[i] >= 0x20 && buf[i] < 0x7f){
|
||||
fputc(buf[i], stderr);
|
||||
}else{
|
||||
fputc('.', stderr);
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "\"\n");
|
||||
}else{
|
||||
fprintf(stderr, "%s: %d bytes:\n", prefix, len);
|
||||
while(len > 0){
|
||||
for(i = 0; i < 16; i++){
|
||||
if(i < len){
|
||||
fprintf(stderr, "%02x ", buf[i]);
|
||||
}else{
|
||||
fprintf(stderr, " ");
|
||||
}
|
||||
if(i == 7)
|
||||
fputc(' ', stderr);
|
||||
}
|
||||
fprintf(stderr, " \"");
|
||||
for(i = 0; i < 16; i++){
|
||||
if(i < len){
|
||||
if(buf[i] >= 0x20 && buf[i] < 0x7f){
|
||||
fputc(buf[i], stderr);
|
||||
}else{
|
||||
fputc('.', stderr);
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "\"\n");
|
||||
buf += 16;
|
||||
len -= 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static char *usbErrorText(int usbErrno)
|
||||
{
|
||||
static char buffer[32];
|
||||
|
||||
switch(usbErrno){
|
||||
case USB_ERROR_NONE: return "Success.";
|
||||
case USB_ERROR_ACCESS: return "Access denied.";
|
||||
case USB_ERROR_NOTFOUND:return "Device not found.";
|
||||
case USB_ERROR_BUSY: return "Device is busy.";
|
||||
case USB_ERROR_IO: return "I/O Error.";
|
||||
default:
|
||||
sprintf(buffer, "Unknown error %d.", usbErrno);
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static void avrdoper_open(char *port, long baud, union filedescriptor *fdp)
|
||||
{
|
||||
int rval;
|
||||
char *vname = "obdev.at";
|
||||
char *devname = "AVR-Doper";
|
||||
|
||||
rval = usbOpenDevice(fdp, USB_VENDOR_ID, vname, USB_PRODUCT_ID, devname, 1);
|
||||
if(rval != 0){
|
||||
fprintf(stderr, "%s: avrdoper_open(): %s\n", progname, usbErrorText(rval));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static void avrdoper_close(union filedescriptor *fdp)
|
||||
{
|
||||
usbCloseDevice(fdp);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static int chooseDataSize(int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < sizeof(reportDataSizes)/sizeof(reportDataSizes[0]); i++){
|
||||
if(reportDataSizes[i] >= len)
|
||||
return i;
|
||||
}
|
||||
return i - 1;
|
||||
}
|
||||
|
||||
static int avrdoper_send(union filedescriptor *fdp, unsigned char *buf, size_t buflen)
|
||||
{
|
||||
if(verbose > 3)
|
||||
dumpBlock("Send", buf, buflen);
|
||||
while(buflen > 0){
|
||||
unsigned char buffer[256];
|
||||
int rval, lenIndex = chooseDataSize(buflen);
|
||||
int thisLen = buflen > reportDataSizes[lenIndex] ?
|
||||
reportDataSizes[lenIndex] : buflen;
|
||||
buffer[0] = lenIndex + 1; /* report ID */
|
||||
buffer[1] = thisLen;
|
||||
memcpy(buffer + 2, buf, thisLen);
|
||||
if(verbose > 3)
|
||||
fprintf(stderr, "Sending %d bytes data chunk\n", thisLen);
|
||||
rval = usbSetReport(fdp, USB_HID_REPORT_TYPE_FEATURE, (char *)buffer,
|
||||
reportDataSizes[lenIndex] + 2);
|
||||
if(rval != 0){
|
||||
fprintf(stderr, "%s: avrdoper_send(): %s\n", progname, usbErrorText(rval));
|
||||
exit(1);
|
||||
}
|
||||
buflen -= thisLen;
|
||||
buf += thisLen;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static void avrdoperFillBuffer(union filedescriptor *fdp)
|
||||
{
|
||||
int bytesPending = reportDataSizes[1]; /* guess how much data is buffered in device */
|
||||
|
||||
avrdoperRxPosition = avrdoperRxLength = 0;
|
||||
while(bytesPending > 0){
|
||||
int len, usbErr, lenIndex = chooseDataSize(bytesPending);
|
||||
unsigned char buffer[128];
|
||||
len = sizeof(avrdoperRxBuffer) - avrdoperRxLength; /* bytes remaining */
|
||||
if(reportDataSizes[lenIndex] + 2 > len) /* requested data would not fit into buffer */
|
||||
break;
|
||||
len = reportDataSizes[lenIndex] + 2;
|
||||
usbErr = usbGetReport(fdp, USB_HID_REPORT_TYPE_FEATURE, lenIndex + 1,
|
||||
(char *)buffer, &len);
|
||||
if(usbErr != 0){
|
||||
fprintf(stderr, "%s: avrdoperFillBuffer(): %s\n", progname, usbErrorText(usbErr));
|
||||
exit(1);
|
||||
}
|
||||
if(verbose > 3)
|
||||
fprintf(stderr, "Received %d bytes data chunk of total %d\n", len - 2, buffer[1]);
|
||||
len -= 2; /* compensate for report ID and length byte */
|
||||
bytesPending = buffer[1] - len; /* amount still buffered */
|
||||
if(len > buffer[1]) /* cut away padding */
|
||||
len = buffer[1];
|
||||
if(avrdoperRxLength + len > sizeof(avrdoperRxBuffer)){
|
||||
fprintf(stderr,
|
||||
"%s: avrdoperFillBuffer(): internal error: buffer overflow\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
memcpy(avrdoperRxBuffer + avrdoperRxLength, buffer + 2, len);
|
||||
avrdoperRxLength += len;
|
||||
}
|
||||
}
|
||||
|
||||
static int avrdoper_recv(union filedescriptor *fdp, unsigned char *buf, size_t buflen)
|
||||
{
|
||||
unsigned char *p = buf;
|
||||
int remaining = buflen;
|
||||
|
||||
while(remaining > 0){
|
||||
int len, available = avrdoperRxLength - avrdoperRxPosition;
|
||||
if(available <= 0){ /* buffer is empty */
|
||||
avrdoperFillBuffer(fdp);
|
||||
continue;
|
||||
}
|
||||
len = remaining < available ? remaining : available;
|
||||
memcpy(p, avrdoperRxBuffer + avrdoperRxPosition, len);
|
||||
p += len;
|
||||
remaining -= len;
|
||||
avrdoperRxPosition += len;
|
||||
}
|
||||
if(verbose > 3)
|
||||
dumpBlock("Receive", buf, buflen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static int avrdoper_drain(union filedescriptor *fdp, int display)
|
||||
{
|
||||
do{
|
||||
avrdoperFillBuffer(fdp);
|
||||
}while(avrdoperRxLength > 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
struct serial_device avrdoper_serdev =
|
||||
{
|
||||
.open = avrdoper_open,
|
||||
.close = avrdoper_close,
|
||||
.send = avrdoper_send,
|
||||
.recv = avrdoper_recv,
|
||||
.drain = avrdoper_drain,
|
||||
.flags = SERDEV_FL_NONE,
|
||||
};
|
||||
|
||||
#endif /* defined(HAVE_LIBUSB) || (defined(WIN32NATIVE) && defined(HAVE_LIBHID)) */
|
||||
463
avrdude/ser_posix.c
Normal file
463
avrdude/ser_posix.c
Normal file
@@ -0,0 +1,463 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org>
|
||||
* Copyright (C) 2006 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Posix serial interface for avrdude.
|
||||
*/
|
||||
|
||||
#if !defined(WIN32NATIVE)
|
||||
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "serial.h"
|
||||
|
||||
long serial_recv_timeout = 5000; /* ms */
|
||||
|
||||
struct baud_mapping {
|
||||
long baud;
|
||||
speed_t speed;
|
||||
};
|
||||
|
||||
/* There are a lot more baud rates we could handle, but what's the point? */
|
||||
|
||||
static struct baud_mapping baud_lookup_table [] = {
|
||||
{ 1200, B1200 },
|
||||
{ 2400, B2400 },
|
||||
{ 4800, B4800 },
|
||||
{ 9600, B9600 },
|
||||
{ 19200, B19200 },
|
||||
{ 38400, B38400 },
|
||||
{ 57600, B57600 },
|
||||
{ 115200, B115200 },
|
||||
{ 230400, B230400 },
|
||||
{ 0, 0 } /* Terminator. */
|
||||
};
|
||||
|
||||
static struct termios original_termios;
|
||||
static int saved_original_termios;
|
||||
|
||||
static speed_t serial_baud_lookup(long baud)
|
||||
{
|
||||
struct baud_mapping *map = baud_lookup_table;
|
||||
|
||||
while (map->baud) {
|
||||
if (map->baud == baud)
|
||||
return map->speed;
|
||||
map++;
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s: serial_baud_lookup(): unknown baud rate: %ld\n",
|
||||
progname, baud);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int ser_setspeed(union filedescriptor *fd, long baud)
|
||||
{
|
||||
int rc;
|
||||
struct termios termios;
|
||||
speed_t speed = serial_baud_lookup (baud);
|
||||
|
||||
if (!isatty(fd->ifd))
|
||||
return -ENOTTY;
|
||||
|
||||
/*
|
||||
* initialize terminal modes
|
||||
*/
|
||||
rc = tcgetattr(fd->ifd, &termios);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: ser_setspeed(): tcgetattr() failed",
|
||||
progname);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
/*
|
||||
* copy termios for ser_close if we haven't already
|
||||
*/
|
||||
if (! saved_original_termios++) {
|
||||
original_termios = termios;
|
||||
}
|
||||
|
||||
termios.c_iflag = IGNBRK;
|
||||
termios.c_oflag = 0;
|
||||
termios.c_lflag = 0;
|
||||
termios.c_cflag = (CS8 | CREAD | CLOCAL);
|
||||
termios.c_cc[VMIN] = 1;
|
||||
termios.c_cc[VTIME] = 0;
|
||||
|
||||
cfsetospeed(&termios, speed);
|
||||
cfsetispeed(&termios, speed);
|
||||
|
||||
rc = tcsetattr(fd->ifd, TCSANOW, &termios);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: ser_setspeed(): tcsetattr() failed\n",
|
||||
progname);
|
||||
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);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a port description of the form <host>:<port>, open a TCP
|
||||
* connection to the specified destination, which is assumed to be a
|
||||
* terminal/console server with serial parameters configured
|
||||
* appropriately (e. g. 115200-8-N-1 for a STK500.)
|
||||
*/
|
||||
static void
|
||||
net_open(const char *port, union filedescriptor *fdp)
|
||||
{
|
||||
char *hstr, *pstr, *end;
|
||||
unsigned int pnum;
|
||||
int fd;
|
||||
struct sockaddr_in sockaddr;
|
||||
struct hostent *hp;
|
||||
|
||||
if ((hstr = strdup(port)) == NULL) {
|
||||
fprintf(stderr, "%s: net_open(): Out of memory!\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (((pstr = strchr(hstr, ':')) == NULL) || (pstr == hstr)) {
|
||||
fprintf(stderr, "%s: net_open(): Mangled host:port string \"%s\"\n",
|
||||
progname, hstr);
|
||||
free(hstr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Terminate the host section of the description.
|
||||
*/
|
||||
*pstr++ = '\0';
|
||||
|
||||
pnum = strtoul(pstr, &end, 10);
|
||||
|
||||
if ((*pstr == '\0') || (*end != '\0') || (pnum == 0) || (pnum > 65535)) {
|
||||
fprintf(stderr, "%s: net_open(): Bad port number \"%s\"\n",
|
||||
progname, pstr);
|
||||
free(hstr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((hp = gethostbyname(hstr)) == NULL) {
|
||||
fprintf(stderr, "%s: net_open(): unknown host \"%s\"\n",
|
||||
progname, hstr);
|
||||
free(hstr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
free(hstr);
|
||||
|
||||
if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
|
||||
fprintf(stderr, "%s: net_open(): Cannot open socket: %s\n",
|
||||
progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&sockaddr, 0, sizeof(struct sockaddr_in));
|
||||
sockaddr.sin_family = AF_INET;
|
||||
sockaddr.sin_port = htons(pnum);
|
||||
memcpy(&(sockaddr.sin_addr.s_addr), hp->h_addr, sizeof(struct in_addr));
|
||||
|
||||
if (connect(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr))) {
|
||||
fprintf(stderr, "%s: net_open(): Connect failed: %s\n",
|
||||
progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fdp->ifd = fd;
|
||||
}
|
||||
|
||||
static void ser_open(char * port, long baud, union filedescriptor *fdp)
|
||||
{
|
||||
int rc;
|
||||
int fd;
|
||||
|
||||
/*
|
||||
* If the port is of the form "net:<host>:<port>", then
|
||||
* handle it as a TCP connection to a terminal server.
|
||||
*/
|
||||
if (strncmp(port, "net:", strlen("net:")) == 0) {
|
||||
net_open(port + strlen("net:"), fdp);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* open the serial port
|
||||
*/
|
||||
fd = open(port, O_RDWR | O_NOCTTY | O_NONBLOCK);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "%s: ser_open(): can't open device \"%s\": %s\n",
|
||||
progname, port, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fdp->ifd = fd;
|
||||
|
||||
/*
|
||||
* set serial line attributes
|
||||
*/
|
||||
rc = ser_setspeed(fdp, baud);
|
||||
if (rc) {
|
||||
fprintf(stderr,
|
||||
"%s: ser_open(): can't set attributes for device \"%s\": %s\n",
|
||||
progname, port, strerror(-rc));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void ser_close(union filedescriptor *fd)
|
||||
{
|
||||
/*
|
||||
* restore original termios settings from ser_open
|
||||
*/
|
||||
if (saved_original_termios) {
|
||||
int rc = tcsetattr(fd->ifd, TCSANOW | TCSADRAIN, &original_termios);
|
||||
if (rc) {
|
||||
fprintf(stderr,
|
||||
"%s: ser_close(): can't reset attributes for device: %s\n",
|
||||
progname, strerror(errno));
|
||||
}
|
||||
saved_original_termios = 0;
|
||||
}
|
||||
|
||||
close(fd->ifd);
|
||||
}
|
||||
|
||||
|
||||
static int ser_send(union filedescriptor *fd, unsigned char * buf, size_t buflen)
|
||||
{
|
||||
struct timeval timeout, to2;
|
||||
int rc;
|
||||
unsigned char * p = buf;
|
||||
size_t len = buflen;
|
||||
|
||||
if (!len)
|
||||
return 0;
|
||||
|
||||
if (verbose > 3)
|
||||
{
|
||||
fprintf(stderr, "%s: Send: ", progname);
|
||||
|
||||
while (buflen) {
|
||||
unsigned char c = *buf;
|
||||
if (isprint(c)) {
|
||||
fprintf(stderr, "%c ", c);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, ". ");
|
||||
}
|
||||
fprintf(stderr, "[%02x] ", c);
|
||||
|
||||
buf++;
|
||||
buflen--;
|
||||
}
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 500000;
|
||||
to2 = timeout;
|
||||
|
||||
while (len) {
|
||||
rc = write(fd->ifd, p, (len > 1024) ? 1024 : len);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: ser_send(): write error: %s\n",
|
||||
progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
p += rc;
|
||||
len -= rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen)
|
||||
{
|
||||
struct timeval timeout, to2;
|
||||
fd_set rfds;
|
||||
int nfds;
|
||||
int rc;
|
||||
unsigned char * p = buf;
|
||||
size_t len = 0;
|
||||
|
||||
timeout.tv_sec = serial_recv_timeout / 1000L;
|
||||
timeout.tv_usec = (serial_recv_timeout % 1000L) * 1000;
|
||||
to2 = timeout;
|
||||
|
||||
while (len < buflen) {
|
||||
reselect:
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(fd->ifd, &rfds);
|
||||
|
||||
nfds = select(fd->ifd + 1, &rfds, NULL, NULL, &to2);
|
||||
if (nfds == 0) {
|
||||
if (verbose > 1)
|
||||
fprintf(stderr,
|
||||
"%s: ser_recv(): programmer is not responding\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
else if (nfds == -1) {
|
||||
if (errno == EINTR || errno == EAGAIN) {
|
||||
fprintf(stderr,
|
||||
"%s: ser_recv(): programmer is not responding,reselecting\n",
|
||||
progname);
|
||||
goto reselect;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "%s: ser_recv(): select(): %s\n",
|
||||
progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
rc = read(fd->ifd, p, (buflen - len > 1024) ? 1024 : buflen - len);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: ser_recv(): read error: %s\n",
|
||||
progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
p += rc;
|
||||
len += rc;
|
||||
}
|
||||
|
||||
p = buf;
|
||||
|
||||
if (verbose > 3)
|
||||
{
|
||||
fprintf(stderr, "%s: Recv: ", progname);
|
||||
|
||||
while (len) {
|
||||
unsigned char c = *p;
|
||||
if (isprint(c)) {
|
||||
fprintf(stderr, "%c ", c);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, ". ");
|
||||
}
|
||||
fprintf(stderr, "[%02x] ", c);
|
||||
|
||||
p++;
|
||||
len--;
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ser_drain(union filedescriptor *fd, int display)
|
||||
{
|
||||
struct timeval timeout;
|
||||
fd_set rfds;
|
||||
int nfds;
|
||||
int rc;
|
||||
unsigned char buf;
|
||||
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 250000;
|
||||
|
||||
if (display) {
|
||||
fprintf(stderr, "drain>");
|
||||
}
|
||||
|
||||
while (1) {
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(fd->ifd, &rfds);
|
||||
|
||||
reselect:
|
||||
nfds = select(fd->ifd + 1, &rfds, NULL, NULL, &timeout);
|
||||
if (nfds == 0) {
|
||||
if (display) {
|
||||
fprintf(stderr, "<drain\n");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else if (nfds == -1) {
|
||||
if (errno == EINTR) {
|
||||
goto reselect;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "%s: ser_drain(): select(): %s\n",
|
||||
progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
rc = read(fd->ifd, &buf, 1);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: ser_drain(): read error: %s\n",
|
||||
progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (display) {
|
||||
fprintf(stderr, "%02x ", buf);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct serial_device serial_serdev =
|
||||
{
|
||||
.open = ser_open,
|
||||
.setspeed = ser_setspeed,
|
||||
.close = ser_close,
|
||||
.send = ser_send,
|
||||
.recv = ser_recv,
|
||||
.drain = ser_drain,
|
||||
.flags = SERDEV_FL_CANSETSPEED,
|
||||
};
|
||||
|
||||
struct serial_device *serdev = &serial_serdev;
|
||||
|
||||
#endif /* WIN32NATIVE */
|
||||
386
avrdude/ser_win32.c
Normal file
386
avrdude/ser_win32.c
Normal file
@@ -0,0 +1,386 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2003, 2004 Martin J. Thomas <mthomas@rhrk.uni-kl.de>
|
||||
* Copyright (C) 2006 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Native Win32 serial interface for avrdude.
|
||||
*/
|
||||
|
||||
#include "avrdude.h"
|
||||
|
||||
#if defined(WIN32NATIVE)
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h> /* for isprint */
|
||||
|
||||
#include "serial.h"
|
||||
|
||||
long serial_recv_timeout = 5000; /* ms */
|
||||
|
||||
#define W32SERBUFSIZE 1024
|
||||
|
||||
struct baud_mapping {
|
||||
long baud;
|
||||
DWORD speed;
|
||||
};
|
||||
|
||||
/* HANDLE hComPort=INVALID_HANDLE_VALUE; */
|
||||
|
||||
static struct baud_mapping baud_lookup_table [] = {
|
||||
{ 1200, CBR_1200 },
|
||||
{ 2400, CBR_2400 },
|
||||
{ 4800, CBR_4800 },
|
||||
{ 9600, CBR_9600 },
|
||||
{ 19200, CBR_19200 },
|
||||
{ 38400, CBR_38400 },
|
||||
{ 57600, CBR_57600 },
|
||||
{ 115200, CBR_115200 },
|
||||
{ 0, 0 } /* Terminator. */
|
||||
};
|
||||
|
||||
static DWORD serial_baud_lookup(long baud)
|
||||
{
|
||||
struct baud_mapping *map = baud_lookup_table;
|
||||
|
||||
while (map->baud) {
|
||||
if (map->baud == baud)
|
||||
return map->speed;
|
||||
map++;
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s: serial_baud_lookup(): unknown baud rate: %ld",
|
||||
progname, baud);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
static BOOL serial_w32SetTimeOut(HANDLE hComPort, DWORD timeout) // in ms
|
||||
{
|
||||
COMMTIMEOUTS ctmo;
|
||||
ZeroMemory (&ctmo, sizeof(COMMTIMEOUTS));
|
||||
ctmo.ReadIntervalTimeout = timeout;
|
||||
ctmo.ReadTotalTimeoutMultiplier = timeout;
|
||||
ctmo.ReadTotalTimeoutConstant = timeout;
|
||||
|
||||
return SetCommTimeouts(hComPort, &ctmo);
|
||||
}
|
||||
|
||||
static int ser_setspeed(union filedescriptor *fd, long baud)
|
||||
{
|
||||
DCB dcb;
|
||||
HANDLE hComPort = (HANDLE)fd->pfd;
|
||||
|
||||
ZeroMemory (&dcb, sizeof(DCB));
|
||||
dcb.DCBlength = sizeof(DCB);
|
||||
dcb.BaudRate = serial_baud_lookup (baud);
|
||||
dcb.fBinary = 1;
|
||||
dcb.fDtrControl = DTR_CONTROL_DISABLE;
|
||||
dcb.fRtsControl = RTS_CONTROL_DISABLE;
|
||||
dcb.ByteSize = 8;
|
||||
dcb.Parity = NOPARITY;
|
||||
dcb.StopBits = ONESTOPBIT;
|
||||
|
||||
if (!SetCommState(hComPort, &dcb))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void ser_open(char * port, long baud, union filedescriptor *fdp)
|
||||
{
|
||||
LPVOID lpMsgBuf;
|
||||
HANDLE hComPort=INVALID_HANDLE_VALUE;
|
||||
char *newname = 0;
|
||||
|
||||
/*
|
||||
* If the port is of the form "net:<host>:<port>", then
|
||||
* handle it as a TCP connection to a terminal server.
|
||||
*
|
||||
* This is curently not implemented for Win32.
|
||||
*/
|
||||
if (strncmp(port, "net:", strlen("net:")) == 0) {
|
||||
fprintf(stderr,
|
||||
"%s: ser_open(): network connects are currently not"
|
||||
"implemented for Win32 environments\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (strncasecmp(port, "com", strlen("com")) == 0) {
|
||||
|
||||
// prepend "\\\\.\\" to name, required for port # >= 10
|
||||
newname = malloc(strlen("\\\\.\\") + strlen(port) + 1);
|
||||
|
||||
if (newname == 0) {
|
||||
fprintf(stderr,
|
||||
"%s: ser_open(): out of memory\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
strcpy(newname, "\\\\.\\");
|
||||
strcat(newname, port);
|
||||
|
||||
port = newname;
|
||||
}
|
||||
|
||||
hComPort = CreateFile(port, GENERIC_READ | GENERIC_WRITE, 0, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if (hComPort == INVALID_HANDLE_VALUE) {
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
GetLastError(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
(LPTSTR) &lpMsgBuf,
|
||||
0,
|
||||
NULL);
|
||||
fprintf(stderr, "%s: ser_open(): can't open device \"%s\": %s\n",
|
||||
progname, port, (char*)lpMsgBuf);
|
||||
LocalFree( lpMsgBuf );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!SetupComm(hComPort, W32SERBUFSIZE, W32SERBUFSIZE))
|
||||
{
|
||||
CloseHandle(hComPort);
|
||||
fprintf(stderr, "%s: ser_open(): can't set buffers for \"%s\"\n",
|
||||
progname, port);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fdp->pfd = (void *)hComPort;
|
||||
if (ser_setspeed(fdp, baud) != 0)
|
||||
{
|
||||
CloseHandle(hComPort);
|
||||
fprintf(stderr, "%s: ser_open(): can't set com-state for \"%s\"\n",
|
||||
progname, port);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!serial_w32SetTimeOut(hComPort,0))
|
||||
{
|
||||
CloseHandle(hComPort);
|
||||
fprintf(stderr, "%s: ser_open(): can't set initial timeout for \"%s\"\n",
|
||||
progname, port);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (newname != 0) {
|
||||
free(newname);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void ser_close(union filedescriptor *fd)
|
||||
{
|
||||
HANDLE hComPort=(HANDLE)fd->pfd;
|
||||
if (hComPort != INVALID_HANDLE_VALUE)
|
||||
CloseHandle (hComPort);
|
||||
|
||||
hComPort = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
|
||||
static int ser_send(union filedescriptor *fd, unsigned char * buf, size_t buflen)
|
||||
{
|
||||
size_t len = buflen;
|
||||
unsigned char c='\0';
|
||||
DWORD written;
|
||||
unsigned char * b = buf;
|
||||
|
||||
HANDLE hComPort=(HANDLE)fd->pfd;
|
||||
|
||||
if (hComPort == INVALID_HANDLE_VALUE) {
|
||||
fprintf(stderr, "%s: ser_send(): port not open\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!len)
|
||||
return 0;
|
||||
|
||||
if (verbose > 3)
|
||||
{
|
||||
fprintf(stderr, "%s: Send: ", progname);
|
||||
|
||||
while (len) {
|
||||
c = *b;
|
||||
if (isprint(c)) {
|
||||
fprintf(stderr, "%c ", c);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, ". ");
|
||||
}
|
||||
fprintf(stderr, "[%02x] ", c);
|
||||
b++;
|
||||
len--;
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
serial_w32SetTimeOut(hComPort,500);
|
||||
|
||||
if (!WriteFile (hComPort, buf, buflen, &written, NULL)) {
|
||||
fprintf(stderr, "%s: ser_send(): write error: %s\n",
|
||||
progname, "sorry no info avail"); // TODO
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (written != buflen) {
|
||||
fprintf(stderr, "%s: ser_send(): size/send mismatch\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen)
|
||||
{
|
||||
unsigned char c;
|
||||
unsigned char * p = buf;
|
||||
DWORD read;
|
||||
|
||||
HANDLE hComPort=(HANDLE)fd->pfd;
|
||||
|
||||
if (hComPort == INVALID_HANDLE_VALUE) {
|
||||
fprintf(stderr, "%s: ser_read(): port not open\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
serial_w32SetTimeOut(hComPort, serial_recv_timeout);
|
||||
|
||||
if (!ReadFile(hComPort, buf, buflen, &read, NULL)) {
|
||||
LPVOID lpMsgBuf;
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
GetLastError(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
(LPTSTR) &lpMsgBuf,
|
||||
0,
|
||||
NULL );
|
||||
fprintf(stderr, "%s: ser_recv(): read error: %s\n",
|
||||
progname, (char*)lpMsgBuf);
|
||||
LocalFree( lpMsgBuf );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
p = buf;
|
||||
|
||||
if (verbose > 3)
|
||||
{
|
||||
fprintf(stderr, "%s: Recv: ", progname);
|
||||
|
||||
while (read) {
|
||||
c = *p;
|
||||
if (isprint(c)) {
|
||||
fprintf(stderr, "%c ", c);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, ". ");
|
||||
}
|
||||
fprintf(stderr, "[%02x] ", c);
|
||||
|
||||
p++;
|
||||
read--;
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ser_drain(union filedescriptor *fd, int display)
|
||||
{
|
||||
// int rc;
|
||||
unsigned char buf[10];
|
||||
BOOL readres;
|
||||
DWORD read;
|
||||
|
||||
HANDLE hComPort=(HANDLE)fd->pfd;
|
||||
|
||||
if (hComPort == INVALID_HANDLE_VALUE) {
|
||||
fprintf(stderr, "%s: ser_drain(): port not open\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
serial_w32SetTimeOut(hComPort,250);
|
||||
|
||||
if (display) {
|
||||
fprintf(stderr, "drain>");
|
||||
}
|
||||
|
||||
while (1) {
|
||||
readres=ReadFile(hComPort, buf, 1, &read, NULL);
|
||||
if (!readres) {
|
||||
LPVOID lpMsgBuf;
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
GetLastError(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
(LPTSTR) &lpMsgBuf,
|
||||
0,
|
||||
NULL );
|
||||
fprintf(stderr, "%s: ser_drain(): read error: %s\n",
|
||||
progname, (char*)lpMsgBuf);
|
||||
LocalFree( lpMsgBuf );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (read) { // data avail
|
||||
if (display) fprintf(stderr, "%02x ", buf[0]);
|
||||
}
|
||||
else { // no more data
|
||||
if (display) fprintf(stderr, "<drain\n");
|
||||
break;
|
||||
}
|
||||
} // while
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct serial_device serial_serdev =
|
||||
{
|
||||
.open = ser_open,
|
||||
.setspeed = ser_setspeed,
|
||||
.close = ser_close,
|
||||
.send = ser_send,
|
||||
.recv = ser_recv,
|
||||
.drain = ser_drain,
|
||||
.flags = SERDEV_FL_CANSETSPEED,
|
||||
};
|
||||
|
||||
struct serial_device *serdev = &serial_serdev;
|
||||
|
||||
#endif /* WIN32NATIVE */
|
||||
37
avrdude/serbb.h
Normal file
37
avrdude/serbb.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2005 Michael Holzt <kju-avr@fqdn.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef serbb_h
|
||||
#define serbb_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void serbb_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
312
avrdude/serbb_posix.c
Normal file
312
avrdude/serbb_posix.c
Normal file
@@ -0,0 +1,312 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2005 Michael Holzt <kju-avr@fqdn.org>
|
||||
* Copyright (C) 2006 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Posix serial bitbanging interface for avrdude.
|
||||
*/
|
||||
|
||||
#if !defined(WIN32NATIVE)
|
||||
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "avr.h"
|
||||
#include "pindefs.h"
|
||||
#include "pgm.h"
|
||||
#include "bitbang.h"
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
static struct termios oldmode;
|
||||
|
||||
/*
|
||||
serial port/pin mapping
|
||||
|
||||
1 cd <-
|
||||
2 (rxd) <-
|
||||
3 txd ->
|
||||
4 dtr ->
|
||||
5 GND
|
||||
6 dsr <-
|
||||
7 rts ->
|
||||
8 cts <-
|
||||
9 ri <-
|
||||
*/
|
||||
|
||||
#define DB9PINS 9
|
||||
|
||||
static int serregbits[DB9PINS + 1] =
|
||||
{ 0, TIOCM_CD, 0, 0, TIOCM_DTR, 0, TIOCM_DSR, TIOCM_RTS, TIOCM_CTS, TIOCM_RI };
|
||||
|
||||
#ifdef DEBUG
|
||||
static char *serpins[DB9PINS + 1] =
|
||||
{ "NONE", "CD", "RXD", "TXD", "DTR", "GND", "DSR", "RTS", "CTS", "RI" };
|
||||
#endif
|
||||
|
||||
static int serbb_setpin(PROGRAMMER * pgm, int pin, int value)
|
||||
{
|
||||
unsigned int ctl;
|
||||
int r;
|
||||
|
||||
if (pin & PIN_INVERSE)
|
||||
{
|
||||
value = !value;
|
||||
pin &= PIN_MASK;
|
||||
}
|
||||
|
||||
if ( pin < 1 || pin > DB9PINS )
|
||||
return -1;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("%s to %d\n",serpins[pin],value);
|
||||
#endif
|
||||
|
||||
switch ( pin )
|
||||
{
|
||||
case 3: /* txd */
|
||||
r = ioctl(pgm->fd.ifd, value ? TIOCSBRK : TIOCCBRK, 0);
|
||||
if (r < 0) {
|
||||
perror("ioctl(\"TIOCxBRK\")");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case 4: /* dtr */
|
||||
case 7: /* rts */
|
||||
r = ioctl(pgm->fd.ifd, TIOCMGET, &ctl);
|
||||
if (r < 0) {
|
||||
perror("ioctl(\"TIOCMGET\")");
|
||||
return -1;
|
||||
}
|
||||
if ( value )
|
||||
ctl |= serregbits[pin];
|
||||
else
|
||||
ctl &= ~(serregbits[pin]);
|
||||
r = ioctl(pgm->fd.ifd, TIOCMSET, &ctl);
|
||||
if (r < 0) {
|
||||
perror("ioctl(\"TIOCMSET\")");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
default: /* impossible */
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int serbb_getpin(PROGRAMMER * pgm, int pin)
|
||||
{
|
||||
unsigned int ctl;
|
||||
unsigned char invert;
|
||||
int r;
|
||||
|
||||
if (pin & PIN_INVERSE)
|
||||
{
|
||||
invert = 1;
|
||||
pin &= PIN_MASK;
|
||||
} else
|
||||
invert = 0;
|
||||
|
||||
if ( pin < 1 || pin > DB9PINS )
|
||||
return(-1);
|
||||
|
||||
switch ( pin )
|
||||
{
|
||||
case 2: /* rxd, currently not implemented, FIXME */
|
||||
return(-1);
|
||||
|
||||
case 1: /* cd */
|
||||
case 6: /* dsr */
|
||||
case 8: /* cts */
|
||||
case 9: /* ri */
|
||||
r = ioctl(pgm->fd.ifd, TIOCMGET, &ctl);
|
||||
if (r < 0) {
|
||||
perror("ioctl(\"TIOCMGET\")");
|
||||
return -1;
|
||||
}
|
||||
if ( !invert )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("%s is %d\n",serpins[pin],(ctl & serregbits[pin]) ? 1 : 0 );
|
||||
#endif
|
||||
return ( (ctl & serregbits[pin]) ? 1 : 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("%s is %d (~)\n",serpins[pin],(ctl & serregbits[pin]) ? 0 : 1 );
|
||||
#endif
|
||||
return (( ctl & serregbits[pin]) ? 0 : 1 );
|
||||
}
|
||||
|
||||
default: /* impossible */
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
|
||||
static int serbb_highpulsepin(PROGRAMMER * pgm, int pin)
|
||||
{
|
||||
if ( pin < 1 || pin > DB9PINS )
|
||||
return -1;
|
||||
|
||||
serbb_setpin(pgm, pin, 1);
|
||||
if (pgm->ispdelay > 1)
|
||||
bitbang_delay(pgm->ispdelay);
|
||||
|
||||
serbb_setpin(pgm, pin, 0);
|
||||
if (pgm->ispdelay > 1)
|
||||
bitbang_delay(pgm->ispdelay);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void serbb_display(PROGRAMMER *pgm, const char *p)
|
||||
{
|
||||
/* MAYBE */
|
||||
}
|
||||
|
||||
static void serbb_enable(PROGRAMMER *pgm)
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
static void serbb_disable(PROGRAMMER *pgm)
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
static void serbb_powerup(PROGRAMMER *pgm)
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
static void serbb_powerdown(PROGRAMMER *pgm)
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
static int serbb_open(PROGRAMMER *pgm, char *port)
|
||||
{
|
||||
struct termios mode;
|
||||
int flags;
|
||||
int r;
|
||||
|
||||
bitbang_check_prerequisites(pgm);
|
||||
|
||||
/* adapted from uisp code */
|
||||
|
||||
pgm->fd.ifd = open(port, O_RDWR | O_NOCTTY | O_NONBLOCK);
|
||||
|
||||
if (pgm->fd.ifd < 0) {
|
||||
perror(port);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
r = tcgetattr(pgm->fd.ifd, &mode);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "%s: ", port);
|
||||
perror("tcgetattr");
|
||||
return(-1);
|
||||
}
|
||||
oldmode = mode;
|
||||
|
||||
mode.c_iflag = IGNBRK | IGNPAR;
|
||||
mode.c_oflag = 0;
|
||||
mode.c_cflag = CLOCAL | CREAD | CS8 | B9600;
|
||||
mode.c_cc [VMIN] = 1;
|
||||
mode.c_cc [VTIME] = 0;
|
||||
|
||||
r = tcsetattr(pgm->fd.ifd, TCSANOW, &mode);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "%s: ", port);
|
||||
perror("tcsetattr");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* Clear O_NONBLOCK flag. */
|
||||
flags = fcntl(pgm->fd.ifd, F_GETFL, 0);
|
||||
if (flags == -1)
|
||||
{
|
||||
fprintf(stderr, "%s: Can not get flags: %s\n",
|
||||
progname, strerror(errno));
|
||||
return(-1);
|
||||
}
|
||||
flags &= ~O_NONBLOCK;
|
||||
if (fcntl(pgm->fd.ifd, F_SETFL, flags) == -1)
|
||||
{
|
||||
fprintf(stderr, "%s: Can not clear nonblock flag: %s\n",
|
||||
progname, strerror(errno));
|
||||
return(-1);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static void serbb_close(PROGRAMMER *pgm)
|
||||
{
|
||||
if (pgm->fd.ifd != -1)
|
||||
{
|
||||
(void)tcsetattr(pgm->fd.ifd, TCSANOW, &oldmode);
|
||||
pgm->setpin(pgm, pgm->pinno[PIN_AVR_RESET], 1);
|
||||
close(pgm->fd.ifd);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void serbb_initpgm(PROGRAMMER *pgm)
|
||||
{
|
||||
strcpy(pgm->type, "SERBB");
|
||||
|
||||
pgm->rdy_led = bitbang_rdy_led;
|
||||
pgm->err_led = bitbang_err_led;
|
||||
pgm->pgm_led = bitbang_pgm_led;
|
||||
pgm->vfy_led = bitbang_vfy_led;
|
||||
pgm->initialize = bitbang_initialize;
|
||||
pgm->display = serbb_display;
|
||||
pgm->enable = serbb_enable;
|
||||
pgm->disable = serbb_disable;
|
||||
pgm->powerup = serbb_powerup;
|
||||
pgm->powerdown = serbb_powerdown;
|
||||
pgm->program_enable = bitbang_program_enable;
|
||||
pgm->chip_erase = bitbang_chip_erase;
|
||||
pgm->cmd = bitbang_cmd;
|
||||
pgm->open = serbb_open;
|
||||
pgm->close = serbb_close;
|
||||
pgm->setpin = serbb_setpin;
|
||||
pgm->getpin = serbb_getpin;
|
||||
pgm->highpulsepin = serbb_highpulsepin;
|
||||
pgm->read_byte = avr_read_byte_default;
|
||||
pgm->write_byte = avr_write_byte_default;
|
||||
}
|
||||
|
||||
#endif /* WIN32NATIVE */
|
||||
374
avrdude/serbb_win32.c
Normal file
374
avrdude/serbb_win32.c
Normal file
@@ -0,0 +1,374 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2003, 2004 Martin J. Thomas <mthomas@rhrk.uni-kl.de>
|
||||
* Copyright (C) 2005 Michael Holzt <kju-avr@fqdn.org>
|
||||
* Copyright (C) 2005, 2006 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Win32 serial bitbanging interface for avrdude.
|
||||
*/
|
||||
|
||||
#include "avrdude.h"
|
||||
|
||||
#if defined(WIN32NATIVE)
|
||||
|
||||
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "avr.h"
|
||||
#include "pindefs.h"
|
||||
#include "pgm.h"
|
||||
#include "bitbang.h"
|
||||
|
||||
/* cached status lines */
|
||||
static int dtr, rts, txd;
|
||||
|
||||
#define W32SERBUFSIZE 1024
|
||||
|
||||
/*
|
||||
serial port/pin mapping
|
||||
|
||||
1 cd <-
|
||||
2 (rxd) <-
|
||||
3 txd ->
|
||||
4 dtr ->
|
||||
5 GND
|
||||
6 dsr <-
|
||||
7 rts ->
|
||||
8 cts <-
|
||||
9 ri <-
|
||||
*/
|
||||
|
||||
#define DB9PINS 9
|
||||
|
||||
static int serbb_setpin(PROGRAMMER * pgm, int pin, int value)
|
||||
{
|
||||
HANDLE hComPort = (HANDLE)pgm->fd.pfd;
|
||||
LPVOID lpMsgBuf;
|
||||
DWORD dwFunc;
|
||||
const char *name;
|
||||
|
||||
if (pin & PIN_INVERSE)
|
||||
{
|
||||
value = !value;
|
||||
pin &= PIN_MASK;
|
||||
}
|
||||
|
||||
if (pin < 1 || pin > DB9PINS)
|
||||
return -1;
|
||||
|
||||
switch (pin)
|
||||
{
|
||||
case 3: /* txd */
|
||||
dwFunc = value? SETBREAK: CLRBREAK;
|
||||
name = value? "SETBREAK": "CLRBREAK";
|
||||
txd = value;
|
||||
break;
|
||||
|
||||
case 4: /* dtr */
|
||||
dwFunc = value? SETDTR: CLRDTR;
|
||||
name = value? "SETDTR": "CLRDTR";
|
||||
dtr = value;
|
||||
break;
|
||||
|
||||
case 7: /* rts */
|
||||
dwFunc = value? SETRTS: CLRRTS;
|
||||
name = value? "SETRTS": "CLRRTS";
|
||||
break;
|
||||
|
||||
default:
|
||||
if (verbose)
|
||||
fprintf(stderr,
|
||||
"%s: serbb_setpin(): unknown pin %d\n",
|
||||
progname, pin + 1);
|
||||
return -1;
|
||||
}
|
||||
if (verbose > 4)
|
||||
fprintf(stderr,
|
||||
"%s: serbb_setpin(): EscapeCommFunction(%s)\n",
|
||||
progname, name);
|
||||
if (!EscapeCommFunction(hComPort, dwFunc))
|
||||
{
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
GetLastError(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
(LPTSTR) &lpMsgBuf,
|
||||
0,
|
||||
NULL);
|
||||
fprintf(stderr,
|
||||
"%s: serbb_setpin(): SetCommState() failed: %s\n",
|
||||
progname, (char *)lpMsgBuf);
|
||||
CloseHandle(hComPort);
|
||||
LocalFree(lpMsgBuf);
|
||||
exit(1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int serbb_getpin(PROGRAMMER * pgm, int pin)
|
||||
{
|
||||
HANDLE hComPort = (HANDLE)pgm->fd.pfd;
|
||||
LPVOID lpMsgBuf;
|
||||
int invert, rv;
|
||||
const char *name;
|
||||
DWORD modemstate;
|
||||
|
||||
if (pin & PIN_INVERSE)
|
||||
{
|
||||
invert = 1;
|
||||
pin &= PIN_MASK;
|
||||
} else
|
||||
invert = 0;
|
||||
|
||||
if (pin < 1 || pin > DB9PINS)
|
||||
return -1;
|
||||
|
||||
if (pin == 1 /* cd */ || pin == 6 /* dsr */ || pin == 8 /* cts */)
|
||||
{
|
||||
if (!GetCommModemStatus(hComPort, &modemstate))
|
||||
{
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
GetLastError(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
(LPTSTR) &lpMsgBuf,
|
||||
0,
|
||||
NULL);
|
||||
fprintf(stderr,
|
||||
"%s: serbb_setpin(): GetCommModemStatus() failed: %s\n",
|
||||
progname, (char *)lpMsgBuf);
|
||||
CloseHandle(hComPort);
|
||||
LocalFree(lpMsgBuf);
|
||||
exit(1);
|
||||
}
|
||||
if (verbose > 4)
|
||||
fprintf(stderr,
|
||||
"%s: serbb_getpin(): GetCommState() => 0x%lx\n",
|
||||
progname, modemstate);
|
||||
switch (pin)
|
||||
{
|
||||
case 1:
|
||||
modemstate &= MS_RLSD_ON;
|
||||
break;
|
||||
case 6:
|
||||
modemstate &= MS_DSR_ON;
|
||||
break;
|
||||
case 8:
|
||||
modemstate &= MS_CTS_ON;
|
||||
break;
|
||||
}
|
||||
rv = modemstate != 0;
|
||||
if (invert)
|
||||
rv = !rv;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
switch (pin)
|
||||
{
|
||||
case 3: /* txd */
|
||||
rv = txd;
|
||||
name = "TXD";
|
||||
break;
|
||||
case 4: /* dtr */
|
||||
rv = dtr;
|
||||
name = "DTR";
|
||||
break;
|
||||
case 7: /* rts */
|
||||
rv = rts;
|
||||
name = "RTS";
|
||||
break;
|
||||
default:
|
||||
if (verbose)
|
||||
fprintf(stderr,
|
||||
"%s: serbb_getpin(): unknown pin %d\n",
|
||||
progname, pin + 1);
|
||||
return -1;
|
||||
}
|
||||
if (verbose > 4)
|
||||
fprintf(stderr,
|
||||
"%s: serbb_getpin(): return cached state for %s\n",
|
||||
progname, name);
|
||||
if (invert)
|
||||
rv = !rv;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int serbb_highpulsepin(PROGRAMMER * pgm, int pin)
|
||||
{
|
||||
if (pin < 1 || pin > 7)
|
||||
return -1;
|
||||
|
||||
serbb_setpin(pgm, pin, 1);
|
||||
if (pgm->ispdelay > 1)
|
||||
bitbang_delay(pgm->ispdelay);
|
||||
|
||||
serbb_setpin(pgm, pin, 0);
|
||||
if (pgm->ispdelay > 1)
|
||||
bitbang_delay(pgm->ispdelay);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void serbb_display(PROGRAMMER *pgm, const char *p)
|
||||
{
|
||||
/* MAYBE */
|
||||
}
|
||||
|
||||
static void serbb_enable(PROGRAMMER *pgm)
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
static void serbb_disable(PROGRAMMER *pgm)
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
static void serbb_powerup(PROGRAMMER *pgm)
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
static void serbb_powerdown(PROGRAMMER *pgm)
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
static int serbb_open(PROGRAMMER *pgm, char *port)
|
||||
{
|
||||
DCB dcb;
|
||||
LPVOID lpMsgBuf;
|
||||
HANDLE hComPort = INVALID_HANDLE_VALUE;
|
||||
|
||||
bitbang_check_prerequisites(pgm);
|
||||
|
||||
hComPort = CreateFile(port, GENERIC_READ | GENERIC_WRITE, 0, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if (hComPort == INVALID_HANDLE_VALUE) {
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
GetLastError(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
(LPTSTR) &lpMsgBuf,
|
||||
0,
|
||||
NULL);
|
||||
fprintf(stderr, "%s: ser_open(): can't open device \"%s\": %s\n",
|
||||
progname, port, (char*)lpMsgBuf);
|
||||
LocalFree(lpMsgBuf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!SetupComm(hComPort, W32SERBUFSIZE, W32SERBUFSIZE))
|
||||
{
|
||||
CloseHandle(hComPort);
|
||||
fprintf(stderr, "%s: ser_open(): can't set buffers for \"%s\"\n",
|
||||
progname, port);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
ZeroMemory(&dcb, sizeof(DCB));
|
||||
dcb.DCBlength = sizeof(DCB);
|
||||
dcb.BaudRate = CBR_9600;
|
||||
dcb.fBinary = 1;
|
||||
dcb.fDtrControl = DTR_CONTROL_DISABLE;
|
||||
dcb.fRtsControl = RTS_CONTROL_DISABLE;
|
||||
dcb.ByteSize = 8;
|
||||
dcb.Parity = NOPARITY;
|
||||
dcb.StopBits = ONESTOPBIT;
|
||||
|
||||
if (!SetCommState(hComPort, &dcb))
|
||||
{
|
||||
CloseHandle(hComPort);
|
||||
fprintf(stderr, "%s: ser_open(): can't set com-state for \"%s\"\n",
|
||||
progname, port);
|
||||
return -1;
|
||||
}
|
||||
if (verbose > 2)
|
||||
fprintf(stderr,
|
||||
"%s: ser_open(): opened comm port \"%s\", handle 0x%x\n",
|
||||
progname, port, (int)hComPort);
|
||||
|
||||
pgm->fd.pfd = (void *)hComPort;
|
||||
|
||||
dtr = rts = txd = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void serbb_close(PROGRAMMER *pgm)
|
||||
{
|
||||
HANDLE hComPort=(HANDLE)pgm->fd.pfd;
|
||||
if (hComPort != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
pgm->setpin(pgm, pgm->pinno[PIN_AVR_RESET], 1);
|
||||
CloseHandle (hComPort);
|
||||
}
|
||||
if (verbose > 2)
|
||||
fprintf(stderr,
|
||||
"%s: ser_close(): closed comm port handle 0x%x\n",
|
||||
progname, (int)hComPort);
|
||||
|
||||
hComPort = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
void serbb_initpgm(PROGRAMMER *pgm)
|
||||
{
|
||||
strcpy(pgm->type, "SERBB");
|
||||
|
||||
pgm->rdy_led = bitbang_rdy_led;
|
||||
pgm->err_led = bitbang_err_led;
|
||||
pgm->pgm_led = bitbang_pgm_led;
|
||||
pgm->vfy_led = bitbang_vfy_led;
|
||||
pgm->initialize = bitbang_initialize;
|
||||
pgm->display = serbb_display;
|
||||
pgm->enable = serbb_enable;
|
||||
pgm->disable = serbb_disable;
|
||||
pgm->powerup = serbb_powerup;
|
||||
pgm->powerdown = serbb_powerdown;
|
||||
pgm->program_enable = bitbang_program_enable;
|
||||
pgm->chip_erase = bitbang_chip_erase;
|
||||
pgm->cmd = bitbang_cmd;
|
||||
pgm->open = serbb_open;
|
||||
pgm->close = serbb_close;
|
||||
pgm->setpin = serbb_setpin;
|
||||
pgm->getpin = serbb_getpin;
|
||||
pgm->highpulsepin = serbb_highpulsepin;
|
||||
pgm->read_byte = avr_read_byte_default;
|
||||
pgm->write_byte = avr_write_byte_default;
|
||||
}
|
||||
|
||||
#endif /* WIN32NATIVE */
|
||||
73
avrdude/serial.h
Normal file
73
avrdude/serial.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/* This is the API for the generic serial interface. The implementations are
|
||||
actually provided by the target dependant files:
|
||||
|
||||
ser_posix.c : posix serial interface.
|
||||
ser_win32.c : native win32 serial interface.
|
||||
|
||||
The target file will be selected at configure time. */
|
||||
|
||||
#ifndef serial_h
|
||||
#define serial_h
|
||||
|
||||
extern long serial_recv_timeout;
|
||||
union filedescriptor
|
||||
{
|
||||
int ifd;
|
||||
void *pfd;
|
||||
struct
|
||||
{
|
||||
void *handle;
|
||||
int ep;
|
||||
} usb;
|
||||
};
|
||||
|
||||
struct serial_device
|
||||
{
|
||||
void (*open)(char * port, long baud, union filedescriptor *fd);
|
||||
int (*setspeed)(union filedescriptor *fd, long baud);
|
||||
void (*close)(union filedescriptor *fd);
|
||||
|
||||
int (*send)(union filedescriptor *fd, unsigned char * buf, size_t buflen);
|
||||
int (*recv)(union filedescriptor *fd, unsigned char * buf, size_t buflen);
|
||||
int (*drain)(union filedescriptor *fd, int display);
|
||||
|
||||
int flags;
|
||||
#define SERDEV_FL_NONE 0x0000 /* no flags */
|
||||
#define SERDEV_FL_CANSETSPEED 0x0001 /* device can change speed */
|
||||
};
|
||||
|
||||
extern struct serial_device *serdev;
|
||||
extern struct serial_device serial_serdev;
|
||||
extern struct serial_device usb_serdev;
|
||||
extern struct serial_device usb_serdev_frame;
|
||||
extern struct serial_device avrdoper_serdev;
|
||||
|
||||
#define serial_open (serdev->open)
|
||||
#define serial_setspeed (serdev->setspeed)
|
||||
#define serial_close (serdev->close)
|
||||
#define serial_send (serdev->send)
|
||||
#define serial_recv (serdev->recv)
|
||||
#define serial_drain (serdev->drain)
|
||||
|
||||
#endif /* serial_h */
|
||||
51
avrdude/solaris_ecpp.h
Normal file
51
avrdude/solaris_ecpp.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2005 Joerg Wunsch
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef solaris_ecpp_h
|
||||
#define solaris_ecpp_h
|
||||
|
||||
#include <sys/ecppio.h>
|
||||
|
||||
#define ppi_claim(fd) \
|
||||
do { \
|
||||
struct ecpp_transfer_parms p; \
|
||||
(void)ioctl(fd, ECPPIOC_GETPARMS, &p); \
|
||||
p.mode = ECPP_DIAG_MODE; \
|
||||
(void)ioctl(fd, ECPPIOC_SETPARMS, &p); \
|
||||
} while(0);
|
||||
|
||||
#define ppi_release(fd)
|
||||
|
||||
#define DO_PPI_READ(fd, reg, valp) \
|
||||
do { struct ecpp_regs r; \
|
||||
if ((reg) == PPIDATA) { (void)ioctl(fd, ECPPIOC_GETDATA, valp); } \
|
||||
else { (void)ioctl(fd, ECPPIOC_GETREGS, &r); \
|
||||
*(valp) = ((reg) == PPICTRL)? r.dcr: r.dsr; } \
|
||||
} while(0)
|
||||
#define DO_PPI_WRITE(fd, reg, valp) \
|
||||
do { struct ecpp_regs r; \
|
||||
if ((reg) == PPIDATA) { (void)ioctl(fd, ECPPIOC_SETDATA, valp); } \
|
||||
else { if ((reg) == PPICTRL) r.dcr = *(valp); else r.dsr = *(valp); \
|
||||
(void)ioctl(fd, ECPPIOC_SETREGS, &r); } \
|
||||
} while(0)
|
||||
|
||||
|
||||
#endif /* solaris_ecpp_h */
|
||||
917
avrdude/stk500.c
917
avrdude/stk500.c
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.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
|
||||
@@ -19,13 +19,19 @@
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef __stk500_h__
|
||||
#define __stk500_h__
|
||||
#ifndef stk500_h
|
||||
#define stk500_h
|
||||
|
||||
#include "config.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void stk500_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
#define Parm_STK_PARAMODE 0x94 // ' ' - TRUE or FALSE
|
||||
#define Parm_STK_POLLING 0x95 // ' ' - TRUE or FALSE
|
||||
#define Parm_STK_SELFTIMED 0x96 // ' ' - TRUE or FALSE
|
||||
|
||||
#define Param_STK500_TOPCARD_DETECT 0x98 // ' ' - Detect top-card attached
|
||||
|
||||
// *****************[ STK status bit definitions ]***************************
|
||||
|
||||
|
||||
91
avrdude/stk500generic.c
Normal file
91
avrdude/stk500generic.c
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2006 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* avrdude interface for Atmel STK500 programmer
|
||||
*
|
||||
* This is a wrapper around the STK500[v1] and STK500v2 programmers.
|
||||
* Try to select the programmer type that actually responds, and
|
||||
* divert to the actual programmer implementation if successful.
|
||||
*/
|
||||
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "pgm.h"
|
||||
#include "stk500.h"
|
||||
#include "stk500v2.h"
|
||||
|
||||
static int stk500generic_open(PROGRAMMER * pgm, char * port)
|
||||
{
|
||||
stk500_initpgm(pgm);
|
||||
if (pgm->open(pgm, port) >= 0)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: successfully opened stk500v1 device -- please use -c stk500v1\n",
|
||||
progname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pgm->close(pgm);
|
||||
|
||||
stk500v2_initpgm(pgm);
|
||||
if (pgm->open(pgm, port) >= 0)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: successfully opened stk500v2 device -- please use -c stk500v2\n",
|
||||
progname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr,
|
||||
"%s: cannot open either stk500v1 or stk500v2 programmer\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void stk500generic_setup(PROGRAMMER * pgm)
|
||||
{
|
||||
/*
|
||||
* Only STK500v2 needs setup/teardown.
|
||||
*/
|
||||
stk500v2_initpgm(pgm);
|
||||
pgm->setup(pgm);
|
||||
}
|
||||
|
||||
static void stk500generic_teardown(PROGRAMMER * pgm)
|
||||
{
|
||||
stk500v2_initpgm(pgm);
|
||||
pgm->teardown(pgm);
|
||||
}
|
||||
|
||||
|
||||
void stk500generic_initpgm(PROGRAMMER * pgm)
|
||||
{
|
||||
strcpy(pgm->type, "STK500GENERIC");
|
||||
|
||||
pgm->open = stk500generic_open;
|
||||
pgm->setup = stk500generic_setup;
|
||||
pgm->teardown = stk500generic_teardown;
|
||||
}
|
||||
29
avrdude/stk500generic.h
Normal file
29
avrdude/stk500generic.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2006 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef stk500generic_h__
|
||||
#define stk500generic_h__
|
||||
|
||||
void stk500generic_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
3691
avrdude/stk500v2.c
Normal file
3691
avrdude/stk500v2.c
Normal file
File diff suppressed because it is too large
Load Diff
47
avrdude/stk500v2.h
Normal file
47
avrdude/stk500v2.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2002-2005 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2006 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef stk500v2_h
|
||||
#define stk500v2_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void stk500v2_initpgm (PROGRAMMER * pgm);
|
||||
void stk500hvsp_initpgm (PROGRAMMER * pgm);
|
||||
void stk500pp_initpgm (PROGRAMMER * pgm);
|
||||
void stk500v2_jtagmkII_initpgm(PROGRAMMER * pgm);
|
||||
void stk500v2_dragon_hvsp_initpgm(PROGRAMMER * pgm);
|
||||
void stk500v2_dragon_isp_initpgm(PROGRAMMER * pgm);
|
||||
void stk500v2_dragon_pp_initpgm(PROGRAMMER * pgm);
|
||||
void stk600_initpgm (PROGRAMMER * pgm);
|
||||
void stk600hvsp_initpgm (PROGRAMMER * pgm);
|
||||
void stk600pp_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
270
avrdude/stk500v2_private.h
Normal file
270
avrdude/stk500v2_private.h
Normal file
@@ -0,0 +1,270 @@
|
||||
//**** ATMEL AVR - A P P L I C A T I O N N O T E ************************
|
||||
//*
|
||||
//* Title: AVR068 - STK500 Communication Protocol
|
||||
//* Filename: command.h
|
||||
//* Version: 1.0
|
||||
//* Last updated: 10.01.2005
|
||||
//*
|
||||
//* Support E-mail: avr@atmel.com
|
||||
//*
|
||||
//**************************************************************************
|
||||
|
||||
// *****************[ STK message constants ]***************************
|
||||
|
||||
#define MESSAGE_START 0x1B //= ESC = 27 decimal
|
||||
#define TOKEN 0x0E
|
||||
|
||||
// *****************[ STK general command constants ]**************************
|
||||
|
||||
#define CMD_SIGN_ON 0x01
|
||||
#define CMD_SET_PARAMETER 0x02
|
||||
#define CMD_GET_PARAMETER 0x03
|
||||
#define CMD_SET_DEVICE_PARAMETERS 0x04
|
||||
#define CMD_OSCCAL 0x05
|
||||
#define CMD_LOAD_ADDRESS 0x06
|
||||
#define CMD_FIRMWARE_UPGRADE 0x07
|
||||
#define CMD_CHECK_TARGET_CONNECTION 0x0D
|
||||
#define CMD_LOAD_RC_ID_TABLE 0x0E
|
||||
#define CMD_LOAD_EC_ID_TABLE 0x0F
|
||||
|
||||
|
||||
// *****************[ STK ISP command constants ]******************************
|
||||
|
||||
#define CMD_ENTER_PROGMODE_ISP 0x10
|
||||
#define CMD_LEAVE_PROGMODE_ISP 0x11
|
||||
#define CMD_CHIP_ERASE_ISP 0x12
|
||||
#define CMD_PROGRAM_FLASH_ISP 0x13
|
||||
#define CMD_READ_FLASH_ISP 0x14
|
||||
#define CMD_PROGRAM_EEPROM_ISP 0x15
|
||||
#define CMD_READ_EEPROM_ISP 0x16
|
||||
#define CMD_PROGRAM_FUSE_ISP 0x17
|
||||
#define CMD_READ_FUSE_ISP 0x18
|
||||
#define CMD_PROGRAM_LOCK_ISP 0x19
|
||||
#define CMD_READ_LOCK_ISP 0x1A
|
||||
#define CMD_READ_SIGNATURE_ISP 0x1B
|
||||
#define CMD_READ_OSCCAL_ISP 0x1C
|
||||
#define CMD_SPI_MULTI 0x1D
|
||||
|
||||
// *****************[ STK PP command constants ]*******************************
|
||||
|
||||
#define CMD_ENTER_PROGMODE_PP 0x20
|
||||
#define CMD_LEAVE_PROGMODE_PP 0x21
|
||||
#define CMD_CHIP_ERASE_PP 0x22
|
||||
#define CMD_PROGRAM_FLASH_PP 0x23
|
||||
#define CMD_READ_FLASH_PP 0x24
|
||||
#define CMD_PROGRAM_EEPROM_PP 0x25
|
||||
#define CMD_READ_EEPROM_PP 0x26
|
||||
#define CMD_PROGRAM_FUSE_PP 0x27
|
||||
#define CMD_READ_FUSE_PP 0x28
|
||||
#define CMD_PROGRAM_LOCK_PP 0x29
|
||||
#define CMD_READ_LOCK_PP 0x2A
|
||||
#define CMD_READ_SIGNATURE_PP 0x2B
|
||||
#define CMD_READ_OSCCAL_PP 0x2C
|
||||
|
||||
#define CMD_SET_CONTROL_STACK 0x2D
|
||||
|
||||
// *****************[ STK HVSP command constants ]*****************************
|
||||
|
||||
#define CMD_ENTER_PROGMODE_HVSP 0x30
|
||||
#define CMD_LEAVE_PROGMODE_HVSP 0x31
|
||||
#define CMD_CHIP_ERASE_HVSP 0x32
|
||||
#define CMD_PROGRAM_FLASH_HVSP 0x33
|
||||
#define CMD_READ_FLASH_HVSP 0x34
|
||||
#define CMD_PROGRAM_EEPROM_HVSP 0x35
|
||||
#define CMD_READ_EEPROM_HVSP 0x36
|
||||
#define CMD_PROGRAM_FUSE_HVSP 0x37
|
||||
#define CMD_READ_FUSE_HVSP 0x38
|
||||
#define CMD_PROGRAM_LOCK_HVSP 0x39
|
||||
#define CMD_READ_LOCK_HVSP 0x3A
|
||||
#define CMD_READ_SIGNATURE_HVSP 0x3B
|
||||
#define CMD_READ_OSCCAL_HVSP 0x3C
|
||||
// These two are redefined since 0x30/0x31 collide
|
||||
// with the STK600 bootloader.
|
||||
#define CMD_ENTER_PROGMODE_HVSP_STK600 0x3D
|
||||
#define CMD_LEAVE_PROGMODE_HVSP_STK600 0x3E
|
||||
|
||||
// *** XPROG command constants ***
|
||||
|
||||
#define CMD_XPROG 0x50
|
||||
#define CMD_XPROG_SETMODE 0x51
|
||||
|
||||
|
||||
// *** AVR32 JTAG Programming command ***
|
||||
|
||||
#define CMD_JTAG_AVR32 0x80
|
||||
#define CMD_ENTER_PROGMODE_JTAG_AVR32 0x81
|
||||
#define CMD_LEAVE_PROGMODE_JTAG_AVR32 0x82
|
||||
|
||||
|
||||
// *** AVR JTAG Programming command ***
|
||||
|
||||
#define CMD_JTAG_AVR 0x90
|
||||
|
||||
// *****************[ STK test command constants ]***************************
|
||||
|
||||
#define CMD_ENTER_TESTMODE 0x60
|
||||
#define CMD_LEAVE_TESTMODE 0x61
|
||||
#define CMD_CHIP_WRITE 0x62
|
||||
#define CMD_PROGRAM_FLASH_PARTIAL 0x63
|
||||
#define CMD_PROGRAM_EEPROM_PARTIAL 0x64
|
||||
#define CMD_PROGRAM_SIGNATURE_ROW 0x65
|
||||
#define CMD_READ_FLASH_MARGIN 0x66
|
||||
#define CMD_READ_EEPROM_MARGIN 0x67
|
||||
#define CMD_READ_SIGNATURE_ROW_MARGIN 0x68
|
||||
#define CMD_PROGRAM_TEST_FUSE 0x69
|
||||
#define CMD_READ_TEST_FUSE 0x6A
|
||||
#define CMD_PROGRAM_HIDDEN_FUSE_LOW 0x6B
|
||||
#define CMD_READ_HIDDEN_FUSE_LOW 0x6C
|
||||
#define CMD_PROGRAM_HIDDEN_FUSE_HIGH 0x6D
|
||||
#define CMD_READ_HIDDEN_FUSE_HIGH 0x6E
|
||||
#define CMD_PROGRAM_HIDDEN_FUSE_EXT 0x6F
|
||||
#define CMD_READ_HIDDEN_FUSE_EXT 0x70
|
||||
|
||||
// *****************[ STK status constants ]***************************
|
||||
|
||||
// Success
|
||||
#define STATUS_CMD_OK 0x00
|
||||
|
||||
// Warnings
|
||||
#define STATUS_CMD_TOUT 0x80
|
||||
#define STATUS_RDY_BSY_TOUT 0x81
|
||||
#define STATUS_SET_PARAM_MISSING 0x82
|
||||
|
||||
// Errors
|
||||
#define STATUS_CMD_FAILED 0xC0
|
||||
#define STATUS_CKSUM_ERROR 0xC1
|
||||
#define STATUS_CMD_UNKNOWN 0xC9
|
||||
#define STATUS_CMD_ILLEGAL_PARAMETER 0xCA
|
||||
|
||||
// Status
|
||||
#define STATUS_CONN_FAIL_MOSI 0x01
|
||||
#define STATUS_CONN_FAIL_RST 0x02
|
||||
#define STATUS_CONN_FAIL_SCK 0x04
|
||||
#define STATUS_TGT_NOT_DETECTED 0x00
|
||||
#define STATUS_ISP_READY 0x10
|
||||
#define STATUS_TGT_REVERSE_INSERTED 0x20
|
||||
|
||||
// hw_status
|
||||
// Bits in status variable
|
||||
// Bit 0-3: Slave MCU
|
||||
// Bit 4-7: Master MCU
|
||||
|
||||
#define STATUS_AREF_ERROR 0
|
||||
// Set to '1' if AREF is short circuited
|
||||
|
||||
#define STATUS_VTG_ERROR 4
|
||||
// Set to '1' if VTG is short circuited
|
||||
|
||||
#define STATUS_RC_CARD_ERROR 5
|
||||
// Set to '1' if board id changes when board is powered
|
||||
|
||||
#define STATUS_PROGMODE 6
|
||||
// Set to '1' if board is in programming mode
|
||||
|
||||
#define STATUS_POWER_SURGE 7
|
||||
// Set to '1' if board draws excessive current
|
||||
|
||||
// *****************[ STK parameter constants ]***************************
|
||||
#define PARAM_BUILD_NUMBER_LOW 0x80 /* ??? */
|
||||
#define PARAM_BUILD_NUMBER_HIGH 0x81 /* ??? */
|
||||
#define PARAM_HW_VER 0x90
|
||||
#define PARAM_SW_MAJOR 0x91
|
||||
#define PARAM_SW_MINOR 0x92
|
||||
#define PARAM_VTARGET 0x94
|
||||
#define PARAM_VADJUST 0x95 /* STK500 only */
|
||||
#define PARAM_OSC_PSCALE 0x96 /* STK500 only */
|
||||
#define PARAM_OSC_CMATCH 0x97 /* STK500 only */
|
||||
#define PARAM_SCK_DURATION 0x98 /* STK500 only */
|
||||
#define PARAM_TOPCARD_DETECT 0x9A /* STK500 only */
|
||||
#define PARAM_STATUS 0x9C /* STK500 only */
|
||||
#define PARAM_DATA 0x9D /* STK500 only */
|
||||
#define PARAM_RESET_POLARITY 0x9E /* STK500 only, and STK600 FW
|
||||
* version <= 2.0.3 */
|
||||
#define PARAM_CONTROLLER_INIT 0x9F
|
||||
|
||||
/* STK600 parameters */
|
||||
#define PARAM_STATUS_TGT_CONN 0xA1
|
||||
#define PARAM_DISCHARGEDELAY 0xA4
|
||||
#define PARAM_SOCKETCARD_ID 0xA5
|
||||
#define PARAM_ROUTINGCARD_ID 0xA6
|
||||
#define PARAM_EXPCARD_ID 0xA7
|
||||
#define PARAM_SW_MAJOR_SLAVE1 0xA8
|
||||
#define PARAM_SW_MINOR_SLAVE1 0xA9
|
||||
#define PARAM_SW_MAJOR_SLAVE2 0xAA
|
||||
#define PARAM_SW_MINOR_SLAVE2 0xAB
|
||||
#define PARAM_BOARD_ID_STATUS 0xAD
|
||||
#define PARAM_RESET 0xB4
|
||||
|
||||
#define PARAM_JTAG_ALLOW_FULL_PAGE_STREAM 0x50
|
||||
#define PARAM_JTAG_EEPROM_PAGE_SIZE 0x52
|
||||
#define PARAM_JTAG_DAISY_BITS_BEFORE 0x53
|
||||
#define PARAM_JTAG_DAISY_BITS_AFTER 0x54
|
||||
#define PARAM_JTAG_DAISY_UNITS_BEFORE 0x55
|
||||
#define PARAM_JTAG_DAISY_UNITS_AFTER 0x56
|
||||
|
||||
// *** Parameter constants for 2 byte values ***
|
||||
#define PARAM2_SCK_DURATION 0xC0
|
||||
#define PARAM2_CLOCK_CONF 0xC1
|
||||
#define PARAM2_AREF0 0xC2
|
||||
#define PARAM2_AREF1 0xC3
|
||||
|
||||
#define PARAM2_JTAG_FLASH_SIZE_H 0xC5
|
||||
#define PARAM2_JTAG_FLASH_SIZE_L 0xC6
|
||||
#define PARAM2_JTAG_FLASH_PAGE_SIZE 0xC7
|
||||
#define PARAM2_RC_ID_TABLE_REV 0xC8
|
||||
#define PARAM2_EC_ID_TABLE_REV 0xC9
|
||||
|
||||
/* STK600 XPROG section */
|
||||
// XPROG commands
|
||||
#define XPRG_CMD_ENTER_PROGMODE 0x01
|
||||
#define XPRG_CMD_LEAVE_PROGMODE 0x02
|
||||
#define XPRG_CMD_ERASE 0x03
|
||||
#define XPRG_CMD_WRITE_MEM 0x04
|
||||
#define XPRG_CMD_READ_MEM 0x05
|
||||
#define XPRG_CMD_CRC 0x06
|
||||
#define XPRG_CMD_SET_PARAM 0x07
|
||||
|
||||
// Memory types
|
||||
#define XPRG_MEM_TYPE_APPL 1
|
||||
#define XPRG_MEM_TYPE_BOOT 2
|
||||
#define XPRG_MEM_TYPE_EEPROM 3
|
||||
#define XPRG_MEM_TYPE_FUSE 4
|
||||
#define XPRG_MEM_TYPE_LOCKBITS 5
|
||||
#define XPRG_MEM_TYPE_USERSIG 6
|
||||
#define XPRG_MEM_TYPE_FACTORY_CALIBRATION 7
|
||||
|
||||
// Erase types
|
||||
#define XPRG_ERASE_CHIP 1
|
||||
#define XPRG_ERASE_APP 2
|
||||
#define XPRG_ERASE_BOOT 3
|
||||
#define XPRG_ERASE_EEPROM 4
|
||||
#define XPRG_ERASE_APP_PAGE 5
|
||||
#define XPRG_ERASE_BOOT_PAGE 6
|
||||
#define XPRG_ERASE_EEPROM_PAGE 7
|
||||
#define XPRG_ERASE_USERSIG 8
|
||||
|
||||
// Write mode flags
|
||||
#define XPRG_MEM_WRITE_ERASE 0
|
||||
#define XPRG_MEM_WRITE_WRITE 1
|
||||
|
||||
// CRC types
|
||||
#define XPRG_CRC_APP 1
|
||||
#define XPRG_CRC_BOOT 2
|
||||
#define XPRG_CRC_FLASH 3
|
||||
|
||||
// Error codes
|
||||
#define XPRG_ERR_OK 0
|
||||
#define XPRG_ERR_FAILED 1
|
||||
#define XPRG_ERR_COLLISION 2
|
||||
#define XPRG_ERR_TIMEOUT 3
|
||||
|
||||
// XPROG parameters of different sizes
|
||||
// 4-byte address
|
||||
#define XPRG_PARAM_NVMBASE 0x01
|
||||
// 2-byte page size
|
||||
#define XPRG_PARAM_EEPPAGESIZE 0x02
|
||||
|
||||
// *****************[ STK answer constants ]***************************
|
||||
|
||||
#define ANSWER_CKSUM_ERROR 0xB0
|
||||
|
||||
321
avrdude/term.c
321
avrdude/term.c
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.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
|
||||
@@ -21,15 +21,20 @@
|
||||
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
#if defined(HAVE_LIBREADLINE)
|
||||
#if !defined(WIN32NATIVE)
|
||||
# include <readline/readline.h>
|
||||
# include <readline/history.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "avr.h"
|
||||
#include "config.h"
|
||||
#include "lists.h"
|
||||
@@ -37,12 +42,6 @@
|
||||
#include "pindefs.h"
|
||||
#include "ppi.h"
|
||||
|
||||
|
||||
extern char * progname;
|
||||
extern char progbuf[];
|
||||
extern PROGRAMMER * pgm;
|
||||
|
||||
|
||||
struct command {
|
||||
char * name;
|
||||
int (*func)(PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
|
||||
@@ -50,22 +49,50 @@ struct command {
|
||||
};
|
||||
|
||||
|
||||
int cmd_dump (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
|
||||
static int cmd_dump (PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char *argv[]);
|
||||
|
||||
int cmd_write (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
|
||||
static int cmd_write (PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char *argv[]);
|
||||
|
||||
int cmd_erase (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
|
||||
static int cmd_erase (PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char *argv[]);
|
||||
|
||||
int cmd_sig (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
|
||||
static int cmd_sig (PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char *argv[]);
|
||||
|
||||
int cmd_part (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
|
||||
static int cmd_part (PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char *argv[]);
|
||||
|
||||
int cmd_help (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
|
||||
static int cmd_help (PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char *argv[]);
|
||||
|
||||
int cmd_quit (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
|
||||
static int cmd_quit (PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char *argv[]);
|
||||
|
||||
int cmd_send (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
|
||||
static int cmd_send (PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char *argv[]);
|
||||
|
||||
static int cmd_parms (PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char *argv[]);
|
||||
|
||||
static int cmd_vtarg (PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char *argv[]);
|
||||
|
||||
static int cmd_varef (PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char *argv[]);
|
||||
|
||||
static int cmd_fosc (PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char *argv[]);
|
||||
|
||||
static int cmd_sck (PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char *argv[]);
|
||||
|
||||
static int cmd_spi (PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char *argv[]);
|
||||
|
||||
static int cmd_pgm (PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char *argv[]);
|
||||
|
||||
struct command cmd[] = {
|
||||
{ "dump", cmd_dump, "dump memory : %s <memtype> <addr> <N-Bytes>" },
|
||||
@@ -75,6 +102,13 @@ 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)" },
|
||||
{ "varef", cmd_varef, "set <V[aref]> (STK500 only)" },
|
||||
{ "fosc", cmd_fosc, "set <oscillator frequency> (STK500 only)" },
|
||||
{ "sck", cmd_sck, "set <SCK period> (STK500 only)" },
|
||||
{ "spi", cmd_spi, "enter direct SPI mode" },
|
||||
{ "pgm", cmd_pgm, "return to programming mode" },
|
||||
{ "help", cmd_help, "help" },
|
||||
{ "?", cmd_help, "help" },
|
||||
{ "quit", cmd_quit, "quit" }
|
||||
@@ -84,9 +118,9 @@ struct command cmd[] = {
|
||||
|
||||
|
||||
|
||||
static int spi_mode = 0;
|
||||
|
||||
|
||||
int nexttok(char * buf, char ** tok, char ** next)
|
||||
static int nexttok(char * buf, char ** tok, char ** next)
|
||||
{
|
||||
char * q, * n;
|
||||
|
||||
@@ -115,7 +149,7 @@ int nexttok(char * buf, char ** tok, char ** next)
|
||||
}
|
||||
|
||||
|
||||
int hexdump_line(char * buffer, unsigned char * p, int n, int pad)
|
||||
static int hexdump_line(char * buffer, unsigned char * p, int n, int pad)
|
||||
{
|
||||
char * hexdata = "0123456789abcdef";
|
||||
char * b;
|
||||
@@ -147,7 +181,7 @@ int hexdump_line(char * buffer, unsigned char * p, int n, int pad)
|
||||
}
|
||||
|
||||
|
||||
int chardump_line(char * buffer, unsigned char * p, int n, int pad)
|
||||
static int chardump_line(char * buffer, unsigned char * p, int n, int pad)
|
||||
{
|
||||
int i;
|
||||
char b [ 128 ];
|
||||
@@ -170,7 +204,7 @@ int chardump_line(char * buffer, unsigned char * p, int n, int pad)
|
||||
}
|
||||
|
||||
|
||||
int hexdump_buf(FILE * f, int startaddr, unsigned char * buf, int len)
|
||||
static int hexdump_buf(FILE * f, int startaddr, unsigned char * buf, int len)
|
||||
{
|
||||
int addr;
|
||||
int i, n;
|
||||
@@ -197,7 +231,8 @@ int hexdump_buf(FILE * f, int startaddr, unsigned char * buf, int len)
|
||||
}
|
||||
|
||||
|
||||
int cmd_dump(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||
static int cmd_dump(PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char * argv[])
|
||||
{
|
||||
static char prevmem[128] = {0};
|
||||
char * e;
|
||||
@@ -273,7 +308,7 @@ int cmd_dump(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||
}
|
||||
|
||||
for (i=0; i<len; i++) {
|
||||
rc = avr_read_byte(pgm, p, mem, addr+i, &buf[i]);
|
||||
rc = pgm->read_byte(pgm, p, mem, addr+i, &buf[i]);
|
||||
if (rc != 0) {
|
||||
fprintf(stderr, "error reading %s address 0x%05lx of part %s\n",
|
||||
mem->desc, addr+i, p->desc);
|
||||
@@ -296,7 +331,8 @@ int cmd_dump(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||
}
|
||||
|
||||
|
||||
int cmd_write(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||
static int cmd_write(PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char * argv[])
|
||||
{
|
||||
char * e;
|
||||
int len, maxsize;
|
||||
@@ -380,7 +416,7 @@ int cmd_write(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||
werror = 1;
|
||||
}
|
||||
|
||||
rc = avr_read_byte(pgm, p, mem, addr+i, &b);
|
||||
rc = pgm->read_byte(pgm, p, mem, addr+i, &b);
|
||||
if (b != buf[i]) {
|
||||
fprintf(stderr,
|
||||
"%s (write): error writing 0x%02x at 0x%05lx cell=0x%02x\n",
|
||||
@@ -401,15 +437,33 @@ int cmd_write(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||
}
|
||||
|
||||
|
||||
int cmd_send(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||
static int cmd_send(PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char * argv[])
|
||||
{
|
||||
unsigned char cmd[4], res[4];
|
||||
char * e;
|
||||
int i;
|
||||
int len;
|
||||
|
||||
if (argc != 5) {
|
||||
fprintf(stderr, "Usage: send <byte1> <byte2> <byte3> <byte4>\n");
|
||||
if (pgm->cmd == NULL) {
|
||||
fprintf(stderr,
|
||||
"The %s programmer does not support direct ISP commands.\n",
|
||||
pgm->type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (spi_mode && (pgm->spi == NULL)) {
|
||||
fprintf(stderr,
|
||||
"The %s programmer does not support direct SPI transfers.\n",
|
||||
pgm->type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if ((argc > 5) || ((argc < 5) && (!spi_mode))) {
|
||||
fprintf(stderr, spi_mode?
|
||||
"Usage: send <byte1> [<byte2> [<byte3> [<byte4>]]]\n":
|
||||
"Usage: send <byte1> <byte2> <byte3> <byte4>\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -428,7 +482,10 @@ int cmd_send(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||
|
||||
pgm->err_led(pgm, OFF);
|
||||
|
||||
pgm->cmd(pgm, cmd, res);
|
||||
if (spi_mode)
|
||||
pgm->spi(pgm, cmd, res, argc-1);
|
||||
else
|
||||
pgm->cmd(pgm, cmd, res);
|
||||
|
||||
/*
|
||||
* display results
|
||||
@@ -444,7 +501,8 @@ int cmd_send(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||
}
|
||||
|
||||
|
||||
int cmd_erase(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||
static int cmd_erase(PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char * argv[])
|
||||
{
|
||||
fprintf(stderr, "%s: erasing chip\n", progname);
|
||||
pgm->chip_erase(pgm, p);
|
||||
@@ -452,7 +510,8 @@ int cmd_erase(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||
}
|
||||
|
||||
|
||||
int cmd_part(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||
static int cmd_part(PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char * argv[])
|
||||
{
|
||||
fprintf(stdout, "\n");
|
||||
avr_display(stdout, p, "", 0);
|
||||
@@ -462,7 +521,8 @@ int cmd_part(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||
}
|
||||
|
||||
|
||||
int cmd_sig(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||
static int cmd_sig(PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char * argv[])
|
||||
{
|
||||
int i;
|
||||
int rc;
|
||||
@@ -491,13 +551,183 @@ int cmd_sig(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||
}
|
||||
|
||||
|
||||
int cmd_quit(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||
static int cmd_quit(PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char * argv[])
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int cmd_help(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||
static int cmd_parms(PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char * argv[])
|
||||
{
|
||||
if (pgm->print_parms == NULL) {
|
||||
fprintf(stderr,
|
||||
"%s (parms): the %s programmer does not support "
|
||||
"adjustable parameters\n",
|
||||
progname, pgm->type);
|
||||
return -1;
|
||||
}
|
||||
pgm->print_parms(pgm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int cmd_vtarg(PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char * argv[])
|
||||
{
|
||||
int rc;
|
||||
double v;
|
||||
char *endp;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: vtarg <value>\n");
|
||||
return -1;
|
||||
}
|
||||
v = strtod(argv[1], &endp);
|
||||
if (endp == argv[1]) {
|
||||
fprintf(stderr, "%s (vtarg): can't parse voltage \"%s\"\n",
|
||||
progname, argv[1]);
|
||||
return -1;
|
||||
}
|
||||
if (pgm->set_vtarget == NULL) {
|
||||
fprintf(stderr, "%s (vtarg): the %s programmer cannot set V[target]\n",
|
||||
progname, pgm->type);
|
||||
return -2;
|
||||
}
|
||||
if ((rc = pgm->set_vtarget(pgm, v)) != 0) {
|
||||
fprintf(stderr, "%s (vtarg): failed to set V[target] (rc = %d)\n",
|
||||
progname, rc);
|
||||
return -3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int cmd_fosc(PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char * argv[])
|
||||
{
|
||||
int rc;
|
||||
double v;
|
||||
char *endp;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: fosc <value>[M|k] | off\n");
|
||||
return -1;
|
||||
}
|
||||
v = strtod(argv[1], &endp);
|
||||
if (endp == argv[1]) {
|
||||
if (strcmp(argv[1], "off") == 0)
|
||||
v = 0.0;
|
||||
else {
|
||||
fprintf(stderr, "%s (fosc): can't parse frequency \"%s\"\n",
|
||||
progname, argv[1]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (*endp == 'm' || *endp == 'M')
|
||||
v *= 1e6;
|
||||
else if (*endp == 'k' || *endp == 'K')
|
||||
v *= 1e3;
|
||||
if (pgm->set_fosc == NULL) {
|
||||
fprintf(stderr,
|
||||
"%s (fosc): the %s programmer cannot set oscillator frequency\n",
|
||||
progname, pgm->type);
|
||||
return -2;
|
||||
}
|
||||
if ((rc = pgm->set_fosc(pgm, v)) != 0) {
|
||||
fprintf(stderr, "%s (fosc): failed to set oscillator_frequency (rc = %d)\n",
|
||||
progname, rc);
|
||||
return -3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int cmd_sck(PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char * argv[])
|
||||
{
|
||||
int rc;
|
||||
double v;
|
||||
char *endp;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: sck <value>\n");
|
||||
return -1;
|
||||
}
|
||||
v = strtod(argv[1], &endp);
|
||||
if (endp == argv[1]) {
|
||||
fprintf(stderr, "%s (sck): can't parse period \"%s\"\n",
|
||||
progname, argv[1]);
|
||||
return -1;
|
||||
}
|
||||
v *= 1e-6; /* Convert from microseconds to seconds. */
|
||||
if (pgm->set_sck_period == NULL) {
|
||||
fprintf(stderr,
|
||||
"%s (sck): the %s programmer cannot set SCK period\n",
|
||||
progname, pgm->type);
|
||||
return -2;
|
||||
}
|
||||
if ((rc = pgm->set_sck_period(pgm, v)) != 0) {
|
||||
fprintf(stderr, "%s (sck): failed to set SCK period (rc = %d)\n",
|
||||
progname, rc);
|
||||
return -3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int cmd_varef(PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char * argv[])
|
||||
{
|
||||
int rc;
|
||||
unsigned int chan;
|
||||
double v;
|
||||
char *endp;
|
||||
|
||||
if (argc != 2 && argc != 3) {
|
||||
fprintf(stderr, "Usage: varef [channel] <value>\n");
|
||||
return -1;
|
||||
}
|
||||
if (argc == 2) {
|
||||
chan = 0;
|
||||
v = strtod(argv[1], &endp);
|
||||
if (endp == argv[1]) {
|
||||
fprintf(stderr, "%s (varef): can't parse voltage \"%s\"\n",
|
||||
progname, argv[1]);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
chan = strtoul(argv[1], &endp, 10);
|
||||
if (endp == argv[1]) {
|
||||
fprintf(stderr, "%s (varef): can't parse channel \"%s\"\n",
|
||||
progname, argv[1]);
|
||||
return -1;
|
||||
}
|
||||
v = strtod(argv[2], &endp);
|
||||
if (endp == argv[2]) {
|
||||
fprintf(stderr, "%s (varef): can't parse voltage \"%s\"\n",
|
||||
progname, argv[2]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (pgm->set_varef == NULL) {
|
||||
fprintf(stderr, "%s (varef): the %s programmer cannot set V[aref]\n",
|
||||
progname, pgm->type);
|
||||
return -2;
|
||||
}
|
||||
if ((rc = pgm->set_varef(pgm, chan, v)) != 0) {
|
||||
fprintf(stderr, "%s (varef): failed to set V[aref] (rc = %d)\n",
|
||||
progname, rc);
|
||||
return -3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int cmd_help(PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char * argv[])
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -514,8 +744,24 @@ int cmd_help(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_spi(PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char * argv[])
|
||||
{
|
||||
pgm->setpin(pgm, pgm->pinno[PIN_AVR_RESET], 1);
|
||||
spi_mode = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tokenize(char * s, char *** argv)
|
||||
static int cmd_pgm(PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char * argv[])
|
||||
{
|
||||
pgm->setpin(pgm, pgm->pinno[PIN_AVR_RESET], 0);
|
||||
spi_mode = 0;
|
||||
pgm->initialize(pgm, p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tokenize(char * s, char *** argv)
|
||||
{
|
||||
int i, n, l, nargs, offset;
|
||||
int len, slen;
|
||||
@@ -592,7 +838,8 @@ int tokenize(char * s, char *** argv)
|
||||
}
|
||||
|
||||
|
||||
int do_cmd(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||
static int do_cmd(PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char * argv[])
|
||||
{
|
||||
int i;
|
||||
int hold;
|
||||
@@ -626,7 +873,7 @@ int do_cmd(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||
|
||||
char * terminal_get_input(const char *prompt)
|
||||
{
|
||||
#if defined(HAVE_LIBREADLINE)
|
||||
#if defined(HAVE_LIBREADLINE) && !defined(WIN32NATIVE)
|
||||
char *input;
|
||||
input = readline(prompt);
|
||||
if ((input != NULL) && (strlen(input) >= 1))
|
||||
@@ -639,7 +886,7 @@ char * terminal_get_input(const char *prompt)
|
||||
if (fgets(input, sizeof(input), stdin))
|
||||
{
|
||||
/* FIXME: readline strips the '\n', should this too? */
|
||||
strdup(input);
|
||||
return strdup(input);
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.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
|
||||
@@ -19,12 +19,21 @@
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef __term_h__
|
||||
#define __term_h__
|
||||
#ifndef term_h
|
||||
#define term_h
|
||||
|
||||
#include "avr.h"
|
||||
#include "pgm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int terminal_mode(PROGRAMMER * pgm, struct avrpart * p);
|
||||
char * terminal_get_input(const char *prompt);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
156
avrdude/tools/get-dw-params.xsl
Normal file
156
avrdude/tools/get-dw-params.xsl
Normal file
@@ -0,0 +1,156 @@
|
||||
<?xml version="1.0" encoding='ISO-8859-1' ?>
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
<!--
|
||||
* Copyright (c) 2006 Joerg Wunsch
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
*
|
||||
* $Id$
|
||||
-->
|
||||
<!--
|
||||
* Extract the debugWire parameters
|
||||
* from the XML, and format it the way src/devdescr.cc needs it.
|
||||
*
|
||||
* Run this file together with the respective AVR's XML file through
|
||||
* an XSLT processor (xsltproc, saxon), and capture the output for
|
||||
* inclusion into avrdude.conf.in.
|
||||
-->
|
||||
<xsl:output method="text"/>
|
||||
<xsl:template match="/">
|
||||
<!-- Extract everything we need out of the XML. -->
|
||||
<xsl:variable name="devname_orig"
|
||||
select="/AVRPART/ADMIN/PART_NAME" />
|
||||
<xsl:variable name="devname"
|
||||
select="translate(/AVRPART/ADMIN/PART_NAME,
|
||||
'abcdefghijklmnopqrstuvwxyz',
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" />
|
||||
<xsl:variable name="devname_lower"
|
||||
select="translate(/AVRPART/ADMIN/PART_NAME,
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||
'abcdefghijklmnopqrstuvwxyz')" />
|
||||
<xsl:variable name="ucEepromInst"
|
||||
select="//AVRPART/ICE_SETTINGS/JTAGICEmkII/ucEepromInst" />
|
||||
<xsl:variable name="ucFlashInst"
|
||||
select="//AVRPART/ICE_SETTINGS/JTAGICEmkII/ucFlashInst" />
|
||||
|
||||
<!-- If there's a JTAGICEmkII node indicating debugWire, emit the entry. -->
|
||||
<xsl:if test='//AVRPART/ICE_SETTINGS/JTAGICEmkII/Interface="DebugWire"'>
|
||||
|
||||
<!-- start of new entry -->
|
||||
<xsl:text>#------------------------------------------------------------
</xsl:text>
|
||||
<xsl:text># </xsl:text>
|
||||
<xsl:value-of select="$devname_orig" />
|
||||
<xsl:text>
</xsl:text>
|
||||
<xsl:text>#------------------------------------------------------------
</xsl:text>
|
||||
<xsl:text>part
 desc = "</xsl:text>
|
||||
<xsl:value-of select="$devname_orig" />
|
||||
<xsl:text>";
 has_debugwire = yes;
</xsl:text>
|
||||
|
||||
<xsl:text> flash_instr = </xsl:text>
|
||||
<xsl:call-template name="format-hex">
|
||||
<xsl:with-param name="arg" select="$ucFlashInst" />
|
||||
<xsl:with-param name="count" select="0" />
|
||||
</xsl:call-template>
|
||||
<xsl:text>;
</xsl:text>
|
||||
|
||||
<xsl:text> eeprom_instr = </xsl:text>
|
||||
<xsl:call-template name="format-hex">
|
||||
<xsl:with-param name="arg" select="$ucEepromInst" />
|
||||
<xsl:with-param name="count" select="0" />
|
||||
</xsl:call-template>
|
||||
<xsl:text>;
</xsl:text>
|
||||
|
||||
</xsl:if> <!-- JTAGICEmkII uses debugWire -->
|
||||
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="toupper">
|
||||
</xsl:template>
|
||||
|
||||
<!-- return argument $arg if non-empty, 0 otherwise -->
|
||||
<xsl:template name="maybezero">
|
||||
<xsl:param name="arg" />
|
||||
<xsl:choose>
|
||||
<xsl:when test="string-length($arg) = 0"><xsl:text>0</xsl:text></xsl:when>
|
||||
<xsl:otherwise><xsl:value-of select="$arg" /></xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template> <!-- maybezero -->
|
||||
|
||||
<!-- convert $XX hex number in $arg (if any) into 0xXX; -->
|
||||
<!-- return 0 if $arg is empty -->
|
||||
<xsl:template name="dollar-to-0x">
|
||||
<xsl:param name="arg" />
|
||||
<xsl:choose>
|
||||
<xsl:when test="string-length($arg) = 0">
|
||||
<xsl:text>0</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="substring($arg, 1, 1) = '$'">
|
||||
<xsl:text>0x</xsl:text>
|
||||
<xsl:value-of select="substring($arg, 2)" />
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="$arg" />
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template> <!-- dollar-to-0x -->
|
||||
|
||||
<!-- Format a string of 0xXX numbers: start a new line -->
|
||||
<!-- after each 8 hex numbers -->
|
||||
<!-- call with parameter $count = 0, calls itself -->
|
||||
<!-- recursively then until everything has been done -->
|
||||
<xsl:template name="format-hex">
|
||||
<xsl:param name="arg" />
|
||||
<xsl:param name="count" />
|
||||
<xsl:choose>
|
||||
<xsl:when test="string-length($arg) <= 4">
|
||||
<!-- Last element, print it, and leave template. -->
|
||||
<xsl:value-of select="$arg" />
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<!--
|
||||
* More arguments follow, print first value,
|
||||
* followed by a comma, decide whether a space
|
||||
* or a newline needs to be emitted, and recurse
|
||||
* with the remaining part of $arg.
|
||||
-->
|
||||
<xsl:value-of select="substring($arg, 1, 4)" />
|
||||
<xsl:choose>
|
||||
<xsl:when test="$count mod 8 = 7">
|
||||
<xsl:text>,
	 </xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:text>, </xsl:text>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:variable name="newarg">
|
||||
<!-- see whether there is a space after comma -->
|
||||
<xsl:choose>
|
||||
<xsl:when test="substring($arg, 6, 1) = ' '">
|
||||
<xsl:value-of select="substring($arg, 7)" />
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="substring($arg, 6)" />
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:variable>
|
||||
<xsl:call-template name="format-hex">
|
||||
<xsl:with-param name="arg" select="$newarg" />
|
||||
<xsl:with-param name="count" select="$count + 1" />
|
||||
</xsl:call-template>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
||||
255
avrdude/tools/get-hv-params.xsl
Normal file
255
avrdude/tools/get-hv-params.xsl
Normal file
@@ -0,0 +1,255 @@
|
||||
<?xml version="1.0" encoding='ISO-8859-1' ?>
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
<!--
|
||||
* Copyright (c) 2006 Joerg Wunsch
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
*
|
||||
* $Id$
|
||||
-->
|
||||
<!--
|
||||
* Extract high-voltage (parallel and serial) programming parameters
|
||||
* out of the Atmel XML files, and convert them into avrdude.conf
|
||||
* snippets.
|
||||
*
|
||||
* Run this file together with the respective AVR's XML file through
|
||||
* an XSLT processor (xsltproc, saxon), and capture the output for
|
||||
* inclusion into avrdude.conf.in.
|
||||
-->
|
||||
<xsl:output method="text"/>
|
||||
<xsl:template match="/">
|
||||
<xsl:for-each select="//*">
|
||||
<xsl:if test='name() = "STK500_2"'>
|
||||
|
||||
<!--
|
||||
* High-voltage parallel programming parameters.
|
||||
-->
|
||||
<xsl:for-each
|
||||
select="*[starts-with(translate(name(),
|
||||
'abcdefghijklmnopqrstuvwxyz',
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'),
|
||||
'PP')]">
|
||||
<xsl:if test="self::node()[name() = 'PPControlStack']"
|
||||
> pp_controlstack =
|
||||
<xsl:call-template name="format_cstack">
|
||||
<xsl:with-param name="stack" select="." />
|
||||
<xsl:with-param name="count" select="0" />
|
||||
</xsl:call-template>;
|
||||
</xsl:if> <!-- PPControlStack -->
|
||||
|
||||
<xsl:if test="self::node()[name() = 'PpEnterProgMode']">
|
||||
<xsl:for-each select="*">
|
||||
<xsl:if test="self::node()[name() = 'stabDelay']"
|
||||
> hventerstabdelay = <xsl:value-of select="." />;
|
||||
</xsl:if>
|
||||
<xsl:if test="self::node()[name() = 'progModeDelay']"
|
||||
> progmodedelay = <xsl:value-of select="." />;
|
||||
</xsl:if>
|
||||
<xsl:if test="self::node()[name() = 'latchCycles']"
|
||||
> latchcycles = <xsl:value-of select="." />;
|
||||
</xsl:if>
|
||||
<xsl:if test="self::node()[name() = 'toggleVtg']"
|
||||
> togglevtg = <xsl:value-of select="." />;
|
||||
</xsl:if>
|
||||
<xsl:if test="self::node()[name() = 'powerOffDelay']"
|
||||
> poweroffdelay = <xsl:value-of select="." />;
|
||||
</xsl:if>
|
||||
<xsl:if test="self::node()[name() = 'resetDelayMs']"
|
||||
> resetdelayms = <xsl:value-of select="." />;
|
||||
</xsl:if>
|
||||
<xsl:if test="self::node()[name() = 'resetDelayUs']"
|
||||
> resetdelayus = <xsl:value-of select="." />;
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
</xsl:if> <!-- PpEnterProgMode -->
|
||||
|
||||
<xsl:if test="self::node()[name() = 'PpLeaveProgMode']">
|
||||
<xsl:for-each select="*">
|
||||
<xsl:if test="self::node()[name() = 'stabDelay']"
|
||||
> hvleavestabdelay = <xsl:value-of select="." />;
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
</xsl:if> <!-- PpLeaveProgMode -->
|
||||
|
||||
<xsl:if test="self::node()[name() = 'PpChipErase']">
|
||||
<xsl:for-each select="*">
|
||||
<xsl:if test="self::node()[name() = 'pulseWidth']"
|
||||
> chiperasepulsewidth = <xsl:value-of select="." />;
|
||||
</xsl:if>
|
||||
<xsl:if test="self::node()[name() = 'pollTimeout']"
|
||||
> chiperasepolltimeout = <xsl:value-of select="." />;
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
</xsl:if> <!-- PpChipErase -->
|
||||
|
||||
<xsl:if test="self::node()[name() = 'PpProgramFuse']">
|
||||
<xsl:for-each select="*">
|
||||
<xsl:if test="self::node()[name() = 'pulseWidth']"
|
||||
> programfusepulsewidth = <xsl:value-of select="." />;
|
||||
</xsl:if>
|
||||
<xsl:if test="self::node()[name() = 'pollTimeout']"
|
||||
> programfusepolltimeout = <xsl:value-of select="." />;
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
</xsl:if> <!-- PpProgramFuse -->
|
||||
|
||||
<xsl:if test="self::node()[name() = 'PpProgramLock']">
|
||||
<xsl:for-each select="*">
|
||||
<xsl:if test="self::node()[name() = 'pulseWidth']"
|
||||
> programlockpulsewidth = <xsl:value-of select="." />;
|
||||
</xsl:if>
|
||||
<xsl:if test="self::node()[name() = 'pollTimeout']"
|
||||
> programlockpolltimeout = <xsl:value-of select="." />;
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
</xsl:if> <!-- PpProgramLock -->
|
||||
|
||||
</xsl:for-each> <!-- PP parameters -->
|
||||
|
||||
<!--
|
||||
* High-voltage serial programming parameters.
|
||||
-->
|
||||
<xsl:for-each
|
||||
select="*[starts-with(translate(name(),
|
||||
'abcdefghijklmnopqrstuvwxyz',
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'),
|
||||
'HVSP')]">
|
||||
|
||||
<xsl:if test="self::node()[name() = 'HvspControlStack']"
|
||||
> hvsp_controlstack =
|
||||
<xsl:call-template name="format_cstack">
|
||||
<xsl:with-param name="stack" select="." />
|
||||
<xsl:with-param name="count" select="0" />
|
||||
</xsl:call-template>;
|
||||
</xsl:if> <!-- HvspControlStack -->
|
||||
|
||||
<xsl:if test="self::node()[name() = 'HvspEnterProgMode']">
|
||||
<xsl:for-each select="*">
|
||||
<xsl:if test="self::node()[name() = 'stabDelay']"
|
||||
> hventerstabdelay = <xsl:value-of select="." />;
|
||||
</xsl:if>
|
||||
<xsl:if test="self::node()[name() = 'cmdexeDelay']"
|
||||
> hvspcmdexedelay = <xsl:value-of select="." />;
|
||||
</xsl:if>
|
||||
<xsl:if test="self::node()[name() = 'synchCycles']"
|
||||
> synchcycles = <xsl:value-of select="." />;
|
||||
</xsl:if>
|
||||
<xsl:if test="self::node()[name() = 'latchCycles']"
|
||||
> latchcycles = <xsl:value-of select="." />;
|
||||
</xsl:if>
|
||||
<xsl:if test="self::node()[name() = 'toggleVtg']"
|
||||
> togglevtg = <xsl:value-of select="." />;
|
||||
</xsl:if>
|
||||
<xsl:if test="self::node()[name() = 'powoffDelay']"
|
||||
> poweroffdelay = <xsl:value-of select="." />;
|
||||
</xsl:if>
|
||||
<xsl:if test="self::node()[name() = 'resetDelay1']"
|
||||
> resetdelayms = <xsl:value-of select="." />;
|
||||
</xsl:if>
|
||||
<xsl:if test="self::node()[name() = 'resetDelay2']"
|
||||
> resetdelayus = <xsl:value-of select="." />;
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
</xsl:if> <!-- HvspEnterProgMode -->
|
||||
|
||||
<xsl:if test="self::node()[name() = 'HvspLeaveProgMode']">
|
||||
<xsl:for-each select="*">
|
||||
<xsl:if test="self::node()[name() = 'stabDelay']"
|
||||
> hvleavestabdelay = <xsl:value-of select="." />;
|
||||
</xsl:if>
|
||||
<xsl:if test="self::node()[name() = 'resetDelay']"
|
||||
> resetdelay = <xsl:value-of select="." />;
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
</xsl:if> <!-- HvspLeaveProgMode -->
|
||||
|
||||
<xsl:if test="self::node()[name() = 'HvspChipErase']">
|
||||
<xsl:for-each select="*">
|
||||
<xsl:if test="self::node()[name() = 'pollTimeout']"
|
||||
> chiperasepolltimeout = <xsl:value-of select="." />;
|
||||
</xsl:if>
|
||||
<xsl:if test="self::node()[name() = 'eraseTime']"
|
||||
> chiperasetime = <xsl:value-of select="." />;
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
</xsl:if> <!-- HvspChipErase -->
|
||||
|
||||
<xsl:if test="self::node()[name() = 'HvspProgramFuse']">
|
||||
<xsl:for-each select="*">
|
||||
<xsl:if test="self::node()[name() = 'pollTimeout']"
|
||||
> programfusepolltimeout = <xsl:value-of select="." />;
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
</xsl:if> <!-- HvspProgramFuse -->
|
||||
|
||||
<xsl:if test="self::node()[name() = 'HvspProgramLock']">
|
||||
<xsl:for-each select="*">
|
||||
<xsl:if test="self::node()[name() = 'pollTimeout']"
|
||||
> programlockpolltimeout = <xsl:value-of select="." />;
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
</xsl:if> <!-- HvspProgramLock -->
|
||||
|
||||
</xsl:for-each> <!-- HVSP parameters -->
|
||||
|
||||
</xsl:if> <!-- STK500_2 parameters -->
|
||||
</xsl:for-each> <!-- All nodes -->
|
||||
|
||||
</xsl:template>
|
||||
|
||||
<!--
|
||||
* Format the control stack argument: replace space-separated
|
||||
* list by a list separated with commas, followed by either
|
||||
* a space or a newline, dependend on the current argument
|
||||
* count.
|
||||
* This template calls itself recursively, until the entire
|
||||
* argument $stack has been processed.
|
||||
-->
|
||||
<xsl:template name="format_cstack">
|
||||
<xsl:param name="stack" />
|
||||
<xsl:param name="count" />
|
||||
<xsl:choose>
|
||||
<xsl:when test="string-length($stack) <= 4">
|
||||
<!-- Last element, print it, and leave template. -->
|
||||
<xsl:value-of select="$stack" />
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<!--
|
||||
* More arguments follow, print first value,
|
||||
* followed by a comma, decide whether a space
|
||||
* or a newline needs to be emitted, and recurse
|
||||
* with the remaining part of $stack.
|
||||
-->
|
||||
<xsl:value-of select="substring($stack, 1, 4)" />
|
||||
<xsl:choose>
|
||||
<xsl:when test="$count mod 8 = 7">
|
||||
<!-- comma, newline, 8 spaces indentation -->
|
||||
<xsl:text>,
|
||||
</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<!-- comma, space -->
|
||||
<xsl:text>, </xsl:text>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:call-template name="format_cstack">
|
||||
<xsl:with-param name="stack" select="substring($stack, 6)"
|
||||
/>
|
||||
<xsl:with-param name="count" select="$count + 1" />
|
||||
</xsl:call-template>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
63
avrdude/tools/get-stk600-cards.xsl
Normal file
63
avrdude/tools/get-stk600-cards.xsl
Normal file
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding='ISO-8859-1' ?>
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
<!--
|
||||
* Copyright (c) 2008 Joerg Wunsch
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
*
|
||||
* $Id$
|
||||
-->
|
||||
<!--
|
||||
* Extract STK600 routing and socket card information out of
|
||||
* targetboards.xml.
|
||||
*
|
||||
* Run this like:
|
||||
*
|
||||
* xsltproc -param what "'RC'" \
|
||||
* tools/get-stk600-cards.xsl targetboard.xml | sort -u
|
||||
*
|
||||
* xsltproc -param what "'SC'" \
|
||||
* tools/get-stk600-cards.xsl targetboard.xml | sort -u
|
||||
*
|
||||
* and copy&paste the results into the respective tables.
|
||||
-->
|
||||
<xsl:output method="text"/>
|
||||
<xsl:template match="/">
|
||||
<xsl:if test="$what = 'RC'">
|
||||
<xsl:for-each select="/STK600/ROUTING/CARD">
|
||||
<xsl:if test="RC_NAME != ''">
|
||||
<xsl:text> { </xsl:text>
|
||||
<xsl:value-of select="RC_ID" />
|
||||
<xsl:text>, "</xsl:text>
|
||||
<xsl:value-of select="RC_NAME" />
|
||||
<xsl:text>" },
</xsl:text>
|
||||
</xsl:if>
|
||||
</xsl:for-each> <!-- All cards -->
|
||||
</xsl:if> <!-- Routing cards -->
|
||||
|
||||
<xsl:if test="$what = 'SC'">
|
||||
<xsl:for-each select="/STK600/ROUTING/CARD">
|
||||
<xsl:if test="SC_NAME != ''">
|
||||
<xsl:text> { </xsl:text>
|
||||
<xsl:value-of select="SC_ID" />
|
||||
<xsl:text>, "</xsl:text>
|
||||
<xsl:value-of select="SC_NAME" />
|
||||
<xsl:text>" },
</xsl:text>
|
||||
</xsl:if>
|
||||
</xsl:for-each> <!-- All cards -->
|
||||
</xsl:if> <!-- Socket cards -->
|
||||
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
52
avrdude/tools/get-stk600-devices.xsl
Normal file
52
avrdude/tools/get-stk600-devices.xsl
Normal file
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding='ISO-8859-1' ?>
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
<!--
|
||||
* Copyright (c) 2008 Joerg Wunsch
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
*
|
||||
* $Id$
|
||||
-->
|
||||
<!--
|
||||
* Extract STK600 device support out of
|
||||
* targetboards.xml.
|
||||
*
|
||||
* Run this like:
|
||||
*
|
||||
* xsltproc \
|
||||
* tools/get-stk600-devices.xsl targetboard.xml
|
||||
*
|
||||
* and copy&paste the results into the respective table.
|
||||
-->
|
||||
<xsl:output method="text"/>
|
||||
<xsl:template match="/">
|
||||
<xsl:text>@multitable @columnfractions .15 .15 .6
</xsl:text>
|
||||
<xsl:text>Routing card @tab Socket card @tab Devices
</xsl:text>
|
||||
<xsl:for-each select="/STK600/ROUTING/CARD">
|
||||
<xsl:text>@item @code{</xsl:text>
|
||||
<xsl:value-of select="RC_NAME" />
|
||||
<xsl:text>} @tab @code{</xsl:text>
|
||||
<xsl:value-of select="SC_NAME" />
|
||||
<xsl:text>} @tab</xsl:text>
|
||||
<xsl:for-each select="TARGET">
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="NAME" />
|
||||
</xsl:for-each>
|
||||
<xsl:text>
</xsl:text>
|
||||
</xsl:for-each> <!-- All cards -->
|
||||
<xsl:text>@end multitable
</xsl:text>
|
||||
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
372
avrdude/update.c
Normal file
372
avrdude/update.c
Normal file
@@ -0,0 +1,372 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2000-2005 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2007 Joerg Wunsch
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "avr.h"
|
||||
#include "config.h"
|
||||
#include "confwin.h"
|
||||
#include "fileio.h"
|
||||
#include "update.h"
|
||||
|
||||
UPDATE * parse_op(char * s)
|
||||
{
|
||||
char buf[1024];
|
||||
char * p, * cp, c;
|
||||
UPDATE * upd;
|
||||
int i;
|
||||
size_t fnlen;
|
||||
|
||||
upd = (UPDATE *)malloc(sizeof(UPDATE));
|
||||
if (upd == NULL) {
|
||||
fprintf(stderr, "%s: out of memory\n", progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
p = s;
|
||||
while ((i < (sizeof(buf)-1) && *p && (*p != ':')))
|
||||
buf[i++] = *p++;
|
||||
buf[i] = 0;
|
||||
|
||||
if (*p != ':') {
|
||||
upd->memtype = (char *)malloc(strlen("flash")+1);
|
||||
if (upd->memtype == NULL) {
|
||||
outofmem:
|
||||
fprintf(stderr, "%s: out of memory\n", progname);
|
||||
exit(1);
|
||||
}
|
||||
strcpy(upd->memtype, "flash");
|
||||
upd->op = DEVICE_WRITE;
|
||||
upd->filename = (char *)malloc(strlen(buf) + 1);
|
||||
if (upd->filename == NULL)
|
||||
goto outofmem;
|
||||
strcpy(upd->filename, buf);
|
||||
upd->format = FMT_AUTO;
|
||||
return upd;
|
||||
}
|
||||
|
||||
upd->memtype = (char *)malloc(strlen(buf)+1);
|
||||
if (upd->memtype == NULL) {
|
||||
fprintf(stderr, "%s: out of memory\n", progname);
|
||||
exit(1);
|
||||
}
|
||||
strcpy(upd->memtype, buf);
|
||||
|
||||
p++;
|
||||
if (*p == 'r') {
|
||||
upd->op = DEVICE_READ;
|
||||
}
|
||||
else if (*p == 'w') {
|
||||
upd->op = DEVICE_WRITE;
|
||||
}
|
||||
else if (*p == 'v') {
|
||||
upd->op = DEVICE_VERIFY;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "%s: invalid I/O mode '%c' in update specification\n",
|
||||
progname, *p);
|
||||
fprintf(stderr,
|
||||
" allowed values are:\n"
|
||||
" r = read device\n"
|
||||
" w = write device\n"
|
||||
" v = verify device\n");
|
||||
free(upd->memtype);
|
||||
free(upd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p++;
|
||||
|
||||
if (*p != ':') {
|
||||
fprintf(stderr, "%s: invalid update specification\n", progname);
|
||||
free(upd->memtype);
|
||||
free(upd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p++;
|
||||
|
||||
/*
|
||||
* Now, parse the filename component. Instead of looking for the
|
||||
* leftmost possible colon delimiter, we look for the rightmost one.
|
||||
* If we found one, we do have a trailing :format specifier, and
|
||||
* process it. Otherwise, the remainder of the string is our file
|
||||
* name component. That way, the file name itself is allowed to
|
||||
* contain a colon itself (e. g. C:/some/file.hex), except the
|
||||
* optional format specifier becomes mandatory then.
|
||||
*/
|
||||
cp = p;
|
||||
p = strrchr(cp, ':');
|
||||
if (p == NULL) {
|
||||
upd->format = FMT_AUTO;
|
||||
fnlen = strlen(cp);
|
||||
upd->filename = (char *)malloc(fnlen + 1);
|
||||
} else {
|
||||
fnlen = p - cp;
|
||||
upd->filename = (char *)malloc(fnlen +1);
|
||||
c = *++p;
|
||||
if (c && p[1])
|
||||
/* More than one char - force failure below. */
|
||||
c = '?';
|
||||
switch (c) {
|
||||
case 'a': upd->format = FMT_AUTO; break;
|
||||
case 's': upd->format = FMT_SREC; break;
|
||||
case 'i': upd->format = FMT_IHEX; break;
|
||||
case 'r': upd->format = FMT_RBIN; break;
|
||||
case 'm': upd->format = FMT_IMM; break;
|
||||
case 'b': upd->format = FMT_BIN; break;
|
||||
case 'd': upd->format = FMT_DEC; break;
|
||||
case 'h': upd->format = FMT_HEX; break;
|
||||
case 'o': upd->format = FMT_OCT; break;
|
||||
default:
|
||||
fprintf(stderr, "%s: invalid file format '%s' in update specifier\n",
|
||||
progname, p);
|
||||
free(upd->memtype);
|
||||
free(upd);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (upd->filename == NULL) {
|
||||
fprintf(stderr, "%s: out of memory\n", progname);
|
||||
free(upd->memtype);
|
||||
free(upd);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(upd->filename, cp, fnlen);
|
||||
upd->filename[fnlen] = 0;
|
||||
|
||||
return upd;
|
||||
}
|
||||
|
||||
UPDATE * dup_update(UPDATE * upd)
|
||||
{
|
||||
UPDATE * u;
|
||||
|
||||
u = (UPDATE *)malloc(sizeof(UPDATE));
|
||||
if (u == NULL) {
|
||||
fprintf(stderr, "%s: out of memory\n", progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memcpy(u, upd, sizeof(UPDATE));
|
||||
|
||||
u->memtype = strdup(upd->memtype);
|
||||
u->filename = strdup(upd->filename);
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
UPDATE * new_update(int op, char * memtype, int filefmt, char * filename)
|
||||
{
|
||||
UPDATE * u;
|
||||
|
||||
u = (UPDATE *)malloc(sizeof(UPDATE));
|
||||
if (u == NULL) {
|
||||
fprintf(stderr, "%s: out of memory\n", progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
u->memtype = strdup(memtype);
|
||||
u->filename = strdup(filename);
|
||||
u->op = op;
|
||||
u->format = filefmt;
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, int nowrite,
|
||||
int verify)
|
||||
{
|
||||
struct avrpart * v;
|
||||
AVRMEM * mem;
|
||||
int size, vsize;
|
||||
int rc;
|
||||
|
||||
mem = avr_locate_mem(p, upd->memtype);
|
||||
if (mem == NULL) {
|
||||
fprintf(stderr, "\"%s\" memory type not defined for part \"%s\"\n",
|
||||
upd->memtype, p->desc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (upd->op == DEVICE_READ) {
|
||||
/*
|
||||
* read out the specified device memory and write it to a file
|
||||
*/
|
||||
if (quell_progress < 2) {
|
||||
fprintf(stderr, "%s: reading %s memory:\n",
|
||||
progname, mem->desc);
|
||||
}
|
||||
report_progress(0,1,"Reading");
|
||||
rc = avr_read(pgm, p, upd->memtype, 0, 1);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n",
|
||||
progname, mem->desc, rc);
|
||||
return -1;
|
||||
}
|
||||
report_progress(1,1,NULL);
|
||||
size = rc;
|
||||
|
||||
if (quell_progress < 2) {
|
||||
fprintf(stderr,
|
||||
"%s: writing output file \"%s\"\n",
|
||||
progname,
|
||||
strcmp(upd->filename, "-")==0 ? "<stdout>" : upd->filename);
|
||||
}
|
||||
rc = fileio(FIO_WRITE, upd->filename, upd->format, p, upd->memtype, size);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: write to file '%s' failed\n",
|
||||
progname, upd->filename);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (upd->op == DEVICE_WRITE) {
|
||||
/*
|
||||
* write the selected device memory using data from a file; first
|
||||
* read the data from the specified file
|
||||
*/
|
||||
if (quell_progress < 2) {
|
||||
fprintf(stderr,
|
||||
"%s: reading input file \"%s\"\n",
|
||||
progname,
|
||||
strcmp(upd->filename, "-")==0 ? "<stdin>" : upd->filename);
|
||||
}
|
||||
rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: write to file '%s' failed\n",
|
||||
progname, upd->filename);
|
||||
return -1;
|
||||
}
|
||||
size = rc;
|
||||
|
||||
/*
|
||||
* write the buffer contents to the selected memory type
|
||||
*/
|
||||
if (quell_progress < 2) {
|
||||
fprintf(stderr, "%s: writing %s (%d bytes):\n",
|
||||
progname, mem->desc, size);
|
||||
}
|
||||
|
||||
if (!nowrite) {
|
||||
report_progress(0,1,"Writing");
|
||||
rc = avr_write(pgm, p, upd->memtype, size, 1);
|
||||
report_progress(1,1,NULL);
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* test mode, don't actually write to the chip, output the buffer
|
||||
* to stdout in intel hex instead
|
||||
*/
|
||||
rc = fileio(FIO_WRITE, "-", FMT_IHEX, p, upd->memtype, size);
|
||||
}
|
||||
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: failed to write %s memory, rc=%d\n",
|
||||
progname, mem->desc, rc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
vsize = rc;
|
||||
|
||||
if (quell_progress < 2) {
|
||||
fprintf(stderr, "%s: %d bytes of %s written\n", progname,
|
||||
vsize, mem->desc);
|
||||
}
|
||||
|
||||
}
|
||||
else if (upd->op == DEVICE_VERIFY) {
|
||||
/*
|
||||
* verify that the in memory file (p->mem[AVR_M_FLASH|AVR_M_EEPROM])
|
||||
* is the same as what is on the chip
|
||||
*/
|
||||
pgm->vfy_led(pgm, ON);
|
||||
|
||||
v = avr_dup_part(p);
|
||||
|
||||
if (quell_progress < 2) {
|
||||
fprintf(stderr, "%s: verifying %s memory against %s:\n",
|
||||
progname, mem->desc, upd->filename);
|
||||
|
||||
fprintf(stderr, "%s: load data %s data from input file %s:\n",
|
||||
progname, mem->desc, upd->filename);
|
||||
}
|
||||
|
||||
rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: read from file '%s' failed\n",
|
||||
progname, upd->filename);
|
||||
return -1;
|
||||
}
|
||||
size = rc;
|
||||
if (quell_progress < 2) {
|
||||
fprintf(stderr, "%s: input file %s contains %d bytes\n",
|
||||
progname, upd->filename, size);
|
||||
fprintf(stderr, "%s: reading on-chip %s data:\n",
|
||||
progname, mem->desc);
|
||||
}
|
||||
|
||||
report_progress (0,1,"Reading");
|
||||
rc = avr_read(pgm, v, upd->memtype, size, 1);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n",
|
||||
progname, mem->desc, rc);
|
||||
pgm->err_led(pgm, ON);
|
||||
return -1;
|
||||
}
|
||||
report_progress (1,1,NULL);
|
||||
|
||||
|
||||
|
||||
if (quell_progress < 2) {
|
||||
fprintf(stderr, "%s: verifying ...\n", progname);
|
||||
}
|
||||
rc = avr_verify(p, v, upd->memtype, size);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: verification error; content mismatch\n",
|
||||
progname);
|
||||
pgm->err_led(pgm, ON);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (quell_progress < 2) {
|
||||
fprintf(stderr, "%s: %d bytes of %s verified\n",
|
||||
progname, rc, mem->desc);
|
||||
}
|
||||
|
||||
pgm->vfy_led(pgm, OFF);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "%s: invalid update operation (%d) requested\n",
|
||||
progname, upd->op);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
55
avrdude/update.h
Normal file
55
avrdude/update.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2000-2005 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2007 Joerg Wunsch
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef update_h
|
||||
#define update_h
|
||||
|
||||
enum {
|
||||
DEVICE_READ,
|
||||
DEVICE_WRITE,
|
||||
DEVICE_VERIFY
|
||||
};
|
||||
|
||||
|
||||
typedef struct update_t {
|
||||
char * memtype;
|
||||
int op;
|
||||
char * filename;
|
||||
int format;
|
||||
} UPDATE;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern UPDATE * parse_op(char * s);
|
||||
extern UPDATE * dup_update(UPDATE * upd);
|
||||
extern UPDATE * new_update(int op, char * memtype, int filefmt,
|
||||
char * filename);
|
||||
extern int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd,
|
||||
int nowrite, int verify);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
483
avrdude/usb_libusb.c
Normal file
483
avrdude/usb_libusb.c
Normal file
@@ -0,0 +1,483 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2005,2006 Joerg Wunsch
|
||||
* Copyright (C) 2006 David Moore
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* USB interface via libusb for avrdude.
|
||||
*/
|
||||
|
||||
#include "ac_cfg.h"
|
||||
#if defined(HAVE_LIBUSB)
|
||||
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <usb.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "serial.h"
|
||||
#include "usbdevs.h"
|
||||
|
||||
#if defined(WIN32NATIVE)
|
||||
/* someone has defined "interface" to "struct" in Cygwin */
|
||||
# undef interface
|
||||
#endif
|
||||
|
||||
static char usbbuf[USBDEV_MAX_XFER];
|
||||
static int buflen = -1, bufptr;
|
||||
|
||||
static int usb_interface;
|
||||
|
||||
/*
|
||||
* The "baud" parameter is meaningless for USB devices, so we reuse it
|
||||
* to pass the desired USB device ID.
|
||||
*/
|
||||
static void usbdev_open(char * port, long baud, union filedescriptor *fd)
|
||||
{
|
||||
char string[256];
|
||||
char product[256];
|
||||
struct usb_bus *bus;
|
||||
struct usb_device *dev;
|
||||
usb_dev_handle *udev;
|
||||
char *serno, *cp2;
|
||||
int i;
|
||||
size_t x;
|
||||
|
||||
/*
|
||||
* The syntax for usb devices is defined as:
|
||||
*
|
||||
* -P usb[:serialnumber]
|
||||
*
|
||||
* See if we've got a serial number passed here. The serial number
|
||||
* might contain colons which we remove below, and we compare it
|
||||
* right-to-left, so only the least significant nibbles need to be
|
||||
* specified.
|
||||
*/
|
||||
if ((serno = strchr(port, ':')) != NULL)
|
||||
{
|
||||
/* first, drop all colons there if any */
|
||||
cp2 = ++serno;
|
||||
|
||||
while ((cp2 = strchr(cp2, ':')) != NULL)
|
||||
{
|
||||
x = strlen(cp2) - 1;
|
||||
memmove(cp2, cp2 + 1, x);
|
||||
cp2[x] = '\0';
|
||||
}
|
||||
|
||||
if (strlen(serno) > 12)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: usbdev_open(): invalid serial number \"%s\"\n",
|
||||
progname, serno);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
usb_init();
|
||||
|
||||
usb_find_busses();
|
||||
usb_find_devices();
|
||||
|
||||
for (bus = usb_get_busses(); bus; bus = bus->next)
|
||||
{
|
||||
for (dev = bus->devices; dev; dev = dev->next)
|
||||
{
|
||||
udev = usb_open(dev);
|
||||
if (udev)
|
||||
{
|
||||
if (dev->descriptor.idVendor == USB_VENDOR_ATMEL &&
|
||||
dev->descriptor.idProduct == (unsigned short)baud)
|
||||
{
|
||||
/* yeah, we found something */
|
||||
if (usb_get_string_simple(udev,
|
||||
dev->descriptor.iSerialNumber,
|
||||
string, sizeof(string)) < 0)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: usb_open(): cannot read serial number \"%s\"\n",
|
||||
progname, usb_strerror());
|
||||
/*
|
||||
* On some systems, libusb appears to have
|
||||
* problems sending control messages. Catch the
|
||||
* benign case where the user did not request a
|
||||
* particular serial number, so we could
|
||||
* continue anyway.
|
||||
*/
|
||||
if (serno != NULL)
|
||||
exit(1); /* no chance */
|
||||
else
|
||||
strcpy(string, "[unknown]");
|
||||
}
|
||||
|
||||
if (usb_get_string_simple(udev,
|
||||
dev->descriptor.iProduct,
|
||||
product, sizeof(product)) < 0)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: usb_open(): cannot read product name \"%s\"\n",
|
||||
progname, usb_strerror());
|
||||
strcpy(product, "[unnamed product]");
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
fprintf(stderr,
|
||||
"%s: usbdev_open(): Found %s, serno: %s\n",
|
||||
progname, product, string);
|
||||
if (serno != NULL)
|
||||
{
|
||||
/*
|
||||
* See if the serial number requested by the
|
||||
* user matches what we found, matching
|
||||
* right-to-left.
|
||||
*/
|
||||
x = strlen(string) - strlen(serno);
|
||||
if (strcasecmp(string + x, serno) != 0)
|
||||
{
|
||||
if (verbose > 2)
|
||||
fprintf(stderr,
|
||||
"%s: usbdev_open(): serial number doesn't match\n",
|
||||
progname);
|
||||
usb_close(udev);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->config == NULL)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: usbdev_open(): USB device has no configuration\n",
|
||||
progname);
|
||||
goto trynext;
|
||||
}
|
||||
|
||||
if (usb_set_configuration(udev, dev->config[0].bConfigurationValue))
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: usbdev_open(): error setting configuration %d: %s\n",
|
||||
progname, dev->config[0].bConfigurationValue,
|
||||
usb_strerror());
|
||||
goto trynext;
|
||||
}
|
||||
|
||||
usb_interface = dev->config[0].interface[0].altsetting[0].bInterfaceNumber;
|
||||
if (usb_claim_interface(udev, usb_interface))
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: usbdev_open(): error claiming interface %d: %s\n",
|
||||
progname, usb_interface, usb_strerror());
|
||||
goto trynext;
|
||||
}
|
||||
|
||||
fd->usb.handle = udev;
|
||||
fd->usb.ep = -1;
|
||||
/* Try finding out what our read endpoint is. */
|
||||
for (i = 0; i < dev->config[0].interface[0].altsetting[0].bNumEndpoints; i++)
|
||||
{
|
||||
int possible_ep = dev->config[0].interface[0].altsetting[0].
|
||||
endpoint[i].bEndpointAddress;
|
||||
|
||||
if ((possible_ep & USB_ENDPOINT_DIR_MASK) != 0)
|
||||
{
|
||||
if (verbose > 1)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: usbdev_open(): using read endpoint 0x%02x\n",
|
||||
progname, possible_ep);
|
||||
}
|
||||
fd->usb.ep = possible_ep;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fd->usb.ep == -1)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: usbdev_open(): cannot find a read endpoint, using 0x%02x\n",
|
||||
progname, USBDEV_BULK_EP_READ);
|
||||
fd->usb.ep = USBDEV_BULK_EP_READ;
|
||||
}
|
||||
return;
|
||||
}
|
||||
trynext:
|
||||
usb_close(udev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s: usbdev_open(): did not find any%s USB device \"%s\"\n",
|
||||
progname, serno? " (matching)": "", port);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void usbdev_close(union filedescriptor *fd)
|
||||
{
|
||||
usb_dev_handle *udev = (usb_dev_handle *)fd->usb.handle;
|
||||
|
||||
(void)usb_release_interface(udev, usb_interface);
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
/*
|
||||
* Without this reset, the AVRISP mkII seems to stall the second
|
||||
* time we try to connect to it. This is not necessary on
|
||||
* FreeBSD.
|
||||
*/
|
||||
usb_reset(udev);
|
||||
#endif
|
||||
|
||||
usb_close(udev);
|
||||
}
|
||||
|
||||
|
||||
static int usbdev_send(union filedescriptor *fd, unsigned char *bp, size_t mlen)
|
||||
{
|
||||
usb_dev_handle *udev = (usb_dev_handle *)fd->usb.handle;
|
||||
int rv;
|
||||
int i = mlen;
|
||||
unsigned char * p = bp;
|
||||
int tx_size;
|
||||
|
||||
/*
|
||||
* Split the frame into multiple packets. It's important to make
|
||||
* sure we finish with a short packet, or else the device won't know
|
||||
* the frame is finished. For example, if we need to send 64 bytes,
|
||||
* we must send a packet of length 64 followed by a packet of length
|
||||
* 0.
|
||||
*/
|
||||
do {
|
||||
tx_size = (mlen < USBDEV_MAX_XFER)? mlen: USBDEV_MAX_XFER;
|
||||
rv = usb_bulk_write(udev, USBDEV_BULK_EP_WRITE, (char *)bp, tx_size, 5000);
|
||||
if (rv != tx_size)
|
||||
{
|
||||
fprintf(stderr, "%s: usbdev_send(): wrote %d out of %d bytes, err = %s\n",
|
||||
progname, rv, tx_size, usb_strerror());
|
||||
return -1;
|
||||
}
|
||||
bp += tx_size;
|
||||
mlen -= tx_size;
|
||||
} while (tx_size == USBDEV_MAX_XFER);
|
||||
|
||||
if (verbose > 3)
|
||||
{
|
||||
fprintf(stderr, "%s: Sent: ", progname);
|
||||
|
||||
while (i) {
|
||||
unsigned char c = *p;
|
||||
if (isprint(c)) {
|
||||
fprintf(stderr, "%c ", c);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, ". ");
|
||||
}
|
||||
fprintf(stderr, "[%02x] ", c);
|
||||
|
||||
p++;
|
||||
i--;
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* As calls to usb_bulk_read() result in exactly one USB request, we
|
||||
* have to buffer the read results ourselves, so the single-char read
|
||||
* requests performed by the upper layers will be handled. In order
|
||||
* to do this, we maintain a private buffer of what we've got so far,
|
||||
* and transparently issue another USB read request if the buffer is
|
||||
* empty and more data are requested.
|
||||
*/
|
||||
static int
|
||||
usb_fill_buf(usb_dev_handle *udev, int ep)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv = usb_bulk_read(udev, ep, usbbuf, USBDEV_MAX_XFER, 5000);
|
||||
if (rv < 0)
|
||||
{
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "%s: usb_fill_buf(): usb_bulk_read() error %s\n",
|
||||
progname, usb_strerror());
|
||||
return -1;
|
||||
}
|
||||
|
||||
buflen = rv;
|
||||
bufptr = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int usbdev_recv(union filedescriptor *fd, unsigned char *buf, size_t nbytes)
|
||||
{
|
||||
usb_dev_handle *udev = (usb_dev_handle *)fd->usb.handle;
|
||||
int i, amnt;
|
||||
unsigned char * p = buf;
|
||||
|
||||
for (i = 0; nbytes > 0;)
|
||||
{
|
||||
if (buflen <= bufptr)
|
||||
{
|
||||
if (usb_fill_buf(udev, fd->usb.ep) < 0)
|
||||
return -1;
|
||||
}
|
||||
amnt = buflen - bufptr > nbytes? nbytes: buflen - bufptr;
|
||||
memcpy(buf + i, usbbuf + bufptr, amnt);
|
||||
bufptr += amnt;
|
||||
nbytes -= amnt;
|
||||
i += amnt;
|
||||
}
|
||||
|
||||
if (verbose > 3)
|
||||
{
|
||||
fprintf(stderr, "%s: Recv: ", progname);
|
||||
|
||||
while (i) {
|
||||
unsigned char c = *p;
|
||||
if (isprint(c)) {
|
||||
fprintf(stderr, "%c ", c);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, ". ");
|
||||
}
|
||||
fprintf(stderr, "[%02x] ", c);
|
||||
|
||||
p++;
|
||||
i--;
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This version of recv keeps reading packets until we receive a short
|
||||
* packet. Then, the entire frame is assembled and returned to the
|
||||
* user. The length will be unknown in advance, so we return the
|
||||
* length as the return value of this function, or -1 in case of an
|
||||
* error.
|
||||
*
|
||||
* This is used for the AVRISP mkII device.
|
||||
*/
|
||||
static int usbdev_recv_frame(union filedescriptor *fd, unsigned char *buf, size_t nbytes)
|
||||
{
|
||||
usb_dev_handle *udev = (usb_dev_handle *)fd->usb.handle;
|
||||
int rv, n;
|
||||
int i;
|
||||
unsigned char * p = buf;
|
||||
|
||||
n = 0;
|
||||
do
|
||||
{
|
||||
rv = usb_bulk_read(udev, fd->usb.ep, usbbuf,
|
||||
USBDEV_MAX_XFER, 10000);
|
||||
if (rv < 0)
|
||||
{
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "%s: usbdev_recv_frame(): usb_bulk_read(): %s\n",
|
||||
progname, usb_strerror());
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rv <= nbytes)
|
||||
{
|
||||
memcpy (buf, usbbuf, rv);
|
||||
buf += rv;
|
||||
}
|
||||
|
||||
n += rv;
|
||||
nbytes -= rv;
|
||||
}
|
||||
while (rv == USBDEV_MAX_XFER);
|
||||
|
||||
if (nbytes < 0)
|
||||
return -1;
|
||||
|
||||
if (verbose > 3)
|
||||
{
|
||||
i = n;
|
||||
fprintf(stderr, "%s: Recv: ", progname);
|
||||
|
||||
while (i) {
|
||||
unsigned char c = *p;
|
||||
if (isprint(c)) {
|
||||
fprintf(stderr, "%c ", c);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, ". ");
|
||||
}
|
||||
fprintf(stderr, "[%02x] ", c);
|
||||
|
||||
p++;
|
||||
i--;
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
static int usbdev_drain(union filedescriptor *fd, int display)
|
||||
{
|
||||
usb_dev_handle *udev = (usb_dev_handle *)fd->usb.handle;
|
||||
int rv;
|
||||
|
||||
do {
|
||||
rv = usb_bulk_read(udev, fd->usb.ep, usbbuf, USBDEV_MAX_XFER, 100);
|
||||
if (rv > 0 && verbose >= 4)
|
||||
fprintf(stderr, "%s: usbdev_drain(): flushed %d characters\n",
|
||||
progname, rv);
|
||||
} while (rv > 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Device descriptor for the JTAG ICE mkII.
|
||||
*/
|
||||
struct serial_device usb_serdev =
|
||||
{
|
||||
.open = usbdev_open,
|
||||
.close = usbdev_close,
|
||||
.send = usbdev_send,
|
||||
.recv = usbdev_recv,
|
||||
.drain = usbdev_drain,
|
||||
.flags = SERDEV_FL_NONE,
|
||||
};
|
||||
|
||||
/*
|
||||
* Device descriptor for the AVRISP mkII.
|
||||
*/
|
||||
struct serial_device usb_serdev_frame =
|
||||
{
|
||||
.open = usbdev_open,
|
||||
.close = usbdev_close,
|
||||
.send = usbdev_send,
|
||||
.recv = usbdev_recv_frame,
|
||||
.drain = usbdev_drain,
|
||||
.flags = SERDEV_FL_NONE,
|
||||
};
|
||||
|
||||
#endif /* HAVE_LIBUSB */
|
||||
583
avrdude/usbasp.c
Normal file
583
avrdude/usbasp.c
Normal file
@@ -0,0 +1,583 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2006 Thomas Fischl
|
||||
* Copyright 2007 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* Interface to the USBasp programmer.
|
||||
*
|
||||
* See http://www.fischl.de/usbasp/
|
||||
*/
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "avr.h"
|
||||
#include "pgm.h"
|
||||
#include "usbasp.h"
|
||||
|
||||
#ifdef HAVE_LIBUSB
|
||||
#include <usb.h>
|
||||
|
||||
/*
|
||||
* Private data for this programmer.
|
||||
*/
|
||||
struct pdata
|
||||
{
|
||||
usb_dev_handle *usbhandle;
|
||||
};
|
||||
|
||||
#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
|
||||
|
||||
static void usbasp_setup(PROGRAMMER * pgm)
|
||||
{
|
||||
if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
|
||||
fprintf(stderr,
|
||||
"%s: usbasp_setup(): Out of memory allocating private data\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
memset(pgm->cookie, 0, sizeof(struct pdata));
|
||||
}
|
||||
|
||||
static void usbasp_teardown(PROGRAMMER * pgm)
|
||||
{
|
||||
free(pgm->cookie);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* wrapper for usb_control_msg call
|
||||
*/
|
||||
static int usbasp_transmit(PROGRAMMER * pgm,
|
||||
unsigned char receive, unsigned char functionid,
|
||||
unsigned char send[4], unsigned char * buffer, int buffersize)
|
||||
{
|
||||
int nbytes;
|
||||
nbytes = usb_control_msg(PDATA(pgm)->usbhandle,
|
||||
USB_TYPE_VENDOR | USB_RECIP_DEVICE | (receive << 7),
|
||||
functionid,
|
||||
(send[1] << 8) | send[0],
|
||||
(send[3] << 8) | send[2],
|
||||
(char *)buffer, buffersize,
|
||||
5000);
|
||||
if(nbytes < 0){
|
||||
fprintf(stderr, "%s: error: usbasp_transmit: %s\n", progname, usb_strerror());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Try to open USB device with given VID, PID, vendor and product name
|
||||
* Parts of this function were taken from an example code by OBJECTIVE
|
||||
* DEVELOPMENT Software GmbH (www.obdev.at) to meet conditions for
|
||||
* shared VID/PID
|
||||
*/
|
||||
static int usbOpenDevice(usb_dev_handle **device, int vendor,
|
||||
char *vendorName, int product, char *productName)
|
||||
{
|
||||
struct usb_bus *bus;
|
||||
struct usb_device *dev;
|
||||
usb_dev_handle *handle = NULL;
|
||||
int errorCode = USB_ERROR_NOTFOUND;
|
||||
static int didUsbInit = 0;
|
||||
|
||||
if(!didUsbInit){
|
||||
didUsbInit = 1;
|
||||
usb_init();
|
||||
}
|
||||
usb_find_busses();
|
||||
usb_find_devices();
|
||||
for(bus=usb_get_busses(); bus; bus=bus->next){
|
||||
for(dev=bus->devices; dev; dev=dev->next){
|
||||
if(dev->descriptor.idVendor == vendor &&
|
||||
dev->descriptor.idProduct == product){
|
||||
char string[256];
|
||||
int len;
|
||||
/* we need to open the device in order to query strings */
|
||||
handle = usb_open(dev);
|
||||
if(!handle){
|
||||
errorCode = USB_ERROR_ACCESS;
|
||||
fprintf(stderr,
|
||||
"%s: Warning: cannot open USB device: %s\n",
|
||||
progname, usb_strerror());
|
||||
continue;
|
||||
}
|
||||
if(vendorName == NULL && productName == NULL){
|
||||
/* name does not matter */
|
||||
break;
|
||||
}
|
||||
/* now check whether the names match: */
|
||||
len = usb_get_string_simple(handle, dev->descriptor.iManufacturer,
|
||||
string, sizeof(string));
|
||||
if(len < 0){
|
||||
errorCode = USB_ERROR_IO;
|
||||
fprintf(stderr,
|
||||
"%s: Warning: cannot query manufacturer for device: %s\n",
|
||||
progname, usb_strerror());
|
||||
}else{
|
||||
errorCode = USB_ERROR_NOTFOUND;
|
||||
if (verbose > 1)
|
||||
fprintf(stderr,
|
||||
"%s: seen device from vendor ->%s<-\n",
|
||||
progname, string);
|
||||
if(strcmp(string, vendorName) == 0){
|
||||
len = usb_get_string_simple(handle, dev->descriptor.iProduct,
|
||||
string, sizeof(string));
|
||||
if(len < 0){
|
||||
errorCode = USB_ERROR_IO;
|
||||
fprintf(stderr,
|
||||
"%s: Warning: cannot query product for device: %s\n",
|
||||
progname, usb_strerror());
|
||||
}else{
|
||||
errorCode = USB_ERROR_NOTFOUND;
|
||||
if (verbose > 1)
|
||||
fprintf(stderr,
|
||||
"%s: seen product ->%s<-\n",
|
||||
progname, string);
|
||||
if(strcmp(string, productName) == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
usb_close(handle);
|
||||
handle = NULL;
|
||||
}
|
||||
}
|
||||
if(handle)
|
||||
break;
|
||||
}
|
||||
if(handle != NULL){
|
||||
errorCode = 0;
|
||||
*device = handle;
|
||||
}
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
|
||||
static int usbasp_open(PROGRAMMER * pgm, char * port)
|
||||
{
|
||||
usb_init();
|
||||
|
||||
if (usbOpenDevice(&PDATA(pgm)->usbhandle, USBASP_SHARED_VID, "www.fischl.de",
|
||||
USBASP_SHARED_PID, "USBasp") != 0) {
|
||||
|
||||
/* check if device with old VID/PID is available */
|
||||
if (usbOpenDevice(&PDATA(pgm)->usbhandle, USBASP_OLD_VID, "www.fischl.de",
|
||||
USBASP_OLD_PID, "USBasp") != 0) {
|
||||
|
||||
/* no USBasp found */
|
||||
fprintf(stderr,
|
||||
"%s: error: could not find USB device "
|
||||
"\"USBasp\" with vid=0x%x pid=0x%x\n",
|
||||
progname, USBASP_SHARED_VID, USBASP_SHARED_PID);
|
||||
exit(1);
|
||||
|
||||
} else {
|
||||
|
||||
/* found USBasp with old IDs */
|
||||
fprintf(stderr,
|
||||
"%s: Warning: Found USB device \"USBasp\" with "
|
||||
"old VID/PID! Please update firmware of USBasp!\n",
|
||||
progname);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void usbasp_close(PROGRAMMER * pgm)
|
||||
{
|
||||
unsigned char temp[4];
|
||||
memset(temp, 0, sizeof(temp));
|
||||
usbasp_transmit(pgm, 1, USBASP_FUNC_DISCONNECT, temp, temp, sizeof(temp));
|
||||
|
||||
usb_close(PDATA(pgm)->usbhandle);
|
||||
}
|
||||
|
||||
|
||||
static int usbasp_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
|
||||
unsigned char temp[4];
|
||||
memset(temp, 0, sizeof(temp));
|
||||
|
||||
/* set sck period */
|
||||
pgm->set_sck_period(pgm, pgm->bitclock);
|
||||
|
||||
/* connect to target device */
|
||||
usbasp_transmit(pgm, 1, USBASP_FUNC_CONNECT, temp, temp, sizeof(temp));
|
||||
|
||||
/* wait, so device is ready to receive commands */
|
||||
usleep(100000);
|
||||
|
||||
return pgm->program_enable(pgm, p);
|
||||
}
|
||||
|
||||
static void usbasp_disable(PROGRAMMER * pgm)
|
||||
{
|
||||
/* Do nothing. */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void usbasp_enable(PROGRAMMER * pgm)
|
||||
{
|
||||
/* Do nothing. */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void usbasp_display(PROGRAMMER * pgm, const char * p)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static int usbasp_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
|
||||
unsigned char res[4])
|
||||
{
|
||||
int nbytes =
|
||||
usbasp_transmit(pgm, 1, USBASP_FUNC_TRANSMIT, cmd, res, sizeof(res));
|
||||
|
||||
if(nbytes != 4){
|
||||
fprintf(stderr, "%s: error: wrong responds size\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int usbasp_program_enable(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
unsigned char res[4];
|
||||
unsigned char cmd[4];
|
||||
memset(cmd, 0, sizeof(cmd));
|
||||
memset(res, 0, sizeof(res));
|
||||
|
||||
cmd[0] = 0;
|
||||
|
||||
int nbytes =
|
||||
usbasp_transmit(pgm, 1, USBASP_FUNC_ENABLEPROG, cmd, res, sizeof(res));
|
||||
|
||||
if ((nbytes != 1) | (res[0] != 0)) {
|
||||
fprintf(stderr, "%s: error: programm enable: target doesn't answer. %x \n",
|
||||
progname, res[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int usbasp_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
unsigned char cmd[4];
|
||||
unsigned char res[4];
|
||||
|
||||
if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
|
||||
fprintf(stderr, "chip erase instruction not defined for part \"%s\"\n",
|
||||
p->desc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(cmd, 0, sizeof(cmd));
|
||||
|
||||
avr_set_bits(p->op[AVR_OP_CHIP_ERASE], cmd);
|
||||
pgm->cmd(pgm, cmd, res);
|
||||
usleep(p->chip_erase_delay);
|
||||
pgm->initialize(pgm, p);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int usbasp_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int n_bytes)
|
||||
{
|
||||
int n;
|
||||
unsigned char cmd[4];
|
||||
int address = 0;
|
||||
int wbytes = n_bytes;
|
||||
int blocksize;
|
||||
unsigned char * buffer = m->buf;
|
||||
int function;
|
||||
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
function = USBASP_FUNC_READFLASH;
|
||||
} else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
function = USBASP_FUNC_READEEPROM;
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
|
||||
while (wbytes) {
|
||||
if (wbytes > USBASP_READBLOCKSIZE) {
|
||||
blocksize = USBASP_READBLOCKSIZE;
|
||||
wbytes -= USBASP_READBLOCKSIZE;
|
||||
} else {
|
||||
blocksize = wbytes;
|
||||
wbytes = 0;
|
||||
}
|
||||
|
||||
/* set address (new mode) - if firmware on usbasp support newmode, then they use address from this command */
|
||||
unsigned char temp[4];
|
||||
memset(temp, 0, sizeof(temp));
|
||||
cmd[0] = address & 0xFF;
|
||||
cmd[1] = address >> 8;
|
||||
cmd[2] = address >> 16;
|
||||
cmd[3] = address >> 24;
|
||||
usbasp_transmit(pgm, 1, USBASP_FUNC_SETLONGADDRESS, cmd, temp, sizeof(temp));
|
||||
|
||||
/* send command with address (compatibility mode) - if firmware on
|
||||
usbasp doesn't support newmode, then they use address from this */
|
||||
cmd[0] = address & 0xFF;
|
||||
cmd[1] = address >> 8;
|
||||
// for compatibility - previous version of usbasp.c doesn't initialize this fields (firmware ignore it)
|
||||
cmd[2] = 0;
|
||||
cmd[3] = 0;
|
||||
|
||||
n = usbasp_transmit(pgm, 1, function, cmd, buffer, blocksize);
|
||||
|
||||
if (n != blocksize) {
|
||||
fprintf(stderr, "%s: error: wrong reading bytes %x\n",
|
||||
progname, n);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
buffer += blocksize;
|
||||
address += blocksize;
|
||||
|
||||
report_progress (address, n_bytes, NULL);
|
||||
}
|
||||
|
||||
return n_bytes;
|
||||
}
|
||||
|
||||
static int usbasp_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int n_bytes)
|
||||
{
|
||||
int n;
|
||||
unsigned char cmd[4];
|
||||
int address = 0;
|
||||
int wbytes = n_bytes;
|
||||
int blocksize;
|
||||
unsigned char * buffer = m->buf;
|
||||
unsigned char blockflags = USBASP_BLOCKFLAG_FIRST;
|
||||
int function;
|
||||
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
function = USBASP_FUNC_WRITEFLASH;
|
||||
} else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
function = USBASP_FUNC_WRITEEEPROM;
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
|
||||
while (wbytes) {
|
||||
if (wbytes > USBASP_WRITEBLOCKSIZE) {
|
||||
blocksize = USBASP_WRITEBLOCKSIZE;
|
||||
wbytes -= USBASP_WRITEBLOCKSIZE;
|
||||
} else {
|
||||
blocksize = wbytes;
|
||||
wbytes = 0;
|
||||
blockflags |= USBASP_BLOCKFLAG_LAST;
|
||||
}
|
||||
|
||||
/* set address (new mode) - if firmware on usbasp support newmode, then
|
||||
they use address from this command */
|
||||
unsigned char temp[4];
|
||||
memset(temp, 0, sizeof(temp));
|
||||
cmd[0] = address & 0xFF;
|
||||
cmd[1] = address >> 8;
|
||||
cmd[2] = address >> 16;
|
||||
cmd[3] = address >> 24;
|
||||
usbasp_transmit(pgm, 1, USBASP_FUNC_SETLONGADDRESS, cmd, temp, sizeof(temp));
|
||||
|
||||
/* normal command - firmware what support newmode - use address from previous command,
|
||||
firmware what doesn't support newmode - ignore previous command and use address from this command */
|
||||
|
||||
cmd[0] = address & 0xFF;
|
||||
cmd[1] = address >> 8;
|
||||
cmd[2] = page_size & 0xFF;
|
||||
cmd[3] = (blockflags & 0x0F) + ((page_size & 0xF00) >> 4); //TP: Mega128 fix
|
||||
blockflags = 0;
|
||||
|
||||
n = usbasp_transmit(pgm, 0, function, cmd, buffer, blocksize);
|
||||
|
||||
if (n != blocksize) {
|
||||
fprintf(stderr, "%s: error: wrong count at writing %x\n",
|
||||
progname, n);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
buffer += blocksize;
|
||||
address += blocksize;
|
||||
|
||||
report_progress (address, n_bytes, NULL);
|
||||
}
|
||||
|
||||
return n_bytes;
|
||||
}
|
||||
|
||||
|
||||
/* The list of SCK frequencies in kHz supported by USBasp */
|
||||
static struct sckoptions_t usbaspSCKoptions[] = {
|
||||
{ USBASP_ISP_SCK_1500, 1500 },
|
||||
{ USBASP_ISP_SCK_750, 750 },
|
||||
{ USBASP_ISP_SCK_375, 375 },
|
||||
{ USBASP_ISP_SCK_187_5, 187.5 },
|
||||
{ USBASP_ISP_SCK_93_75, 93.75 },
|
||||
{ USBASP_ISP_SCK_32, 32 },
|
||||
{ USBASP_ISP_SCK_16, 16 },
|
||||
{ USBASP_ISP_SCK_8, 8 },
|
||||
{ USBASP_ISP_SCK_4, 4 },
|
||||
{ USBASP_ISP_SCK_2, 2 },
|
||||
{ USBASP_ISP_SCK_1, 1 },
|
||||
{ USBASP_ISP_SCK_0_5, 0.5 }
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Set sck period (in seconds)
|
||||
* Find next possible sck period and write it to the programmer.
|
||||
*/
|
||||
static int usbasp_set_sck_period(PROGRAMMER *pgm, double sckperiod)
|
||||
{
|
||||
char clockoption = USBASP_ISP_SCK_AUTO;
|
||||
unsigned char res[4];
|
||||
unsigned char cmd[4];
|
||||
|
||||
memset(cmd, 0, sizeof(cmd));
|
||||
memset(res, 0, sizeof(res));
|
||||
|
||||
if (sckperiod == 0) {
|
||||
/* auto sck set */
|
||||
|
||||
if (verbose >= 1)
|
||||
fprintf(stderr, "%s: auto set sck period (because given equals null)\n", progname);
|
||||
|
||||
} else {
|
||||
|
||||
double sckfreq = 1 / sckperiod / 1000; /* sck in kHz */
|
||||
double usefreq = 0;
|
||||
|
||||
if (verbose >= 2)
|
||||
fprintf(stderr, "%s: try to set SCK period to %g s (= %g kHz)\n", progname, sckperiod, sckfreq);
|
||||
|
||||
if (sckperiod >= 1500) {
|
||||
clockoption = USBASP_ISP_SCK_1500;
|
||||
usefreq = 1500;
|
||||
|
||||
} else {
|
||||
|
||||
/* find clock option next to given clock */
|
||||
int i;
|
||||
for (i = 0; i < sizeof(usbaspSCKoptions) / sizeof(usbaspSCKoptions[0]); i++) {
|
||||
if (sckfreq >= usbaspSCKoptions[i].frequency) {
|
||||
clockoption = usbaspSCKoptions[i].id;
|
||||
usefreq = usbaspSCKoptions[i].frequency;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s: set SCK frequency to %g kHz\n", progname, usefreq);
|
||||
}
|
||||
|
||||
cmd[0] = clockoption;
|
||||
|
||||
int nbytes =
|
||||
usbasp_transmit(pgm, 1, USBASP_FUNC_SETISPSCK, cmd, res, sizeof(res));
|
||||
|
||||
if ((nbytes != 1) | (res[0] != 0)) {
|
||||
fprintf(stderr, "%s: warning: cannot set sck period. please check for usbasp firmware update.\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void usbasp_initpgm(PROGRAMMER * pgm)
|
||||
{
|
||||
strcpy(pgm->type, "usbasp");
|
||||
|
||||
/*
|
||||
* mandatory functions
|
||||
*/
|
||||
|
||||
pgm->initialize = usbasp_initialize;
|
||||
pgm->display = usbasp_display;
|
||||
pgm->enable = usbasp_enable;
|
||||
pgm->disable = usbasp_disable;
|
||||
pgm->program_enable = usbasp_program_enable;
|
||||
pgm->chip_erase = usbasp_chip_erase;
|
||||
pgm->cmd = usbasp_cmd;
|
||||
pgm->open = usbasp_open;
|
||||
pgm->close = usbasp_close;
|
||||
pgm->read_byte = avr_read_byte_default;
|
||||
pgm->write_byte = avr_write_byte_default;
|
||||
|
||||
/*
|
||||
* optional functions
|
||||
*/
|
||||
|
||||
pgm->paged_write = usbasp_paged_write;
|
||||
pgm->paged_load = usbasp_paged_load;
|
||||
pgm->setup = usbasp_setup;
|
||||
pgm->teardown = usbasp_teardown;
|
||||
pgm->set_sck_period = usbasp_set_sck_period;
|
||||
|
||||
}
|
||||
|
||||
|
||||
#else /* HAVE_LIBUSB */
|
||||
|
||||
static int usbasp_nousb_open (struct programmer_t *pgm, char * name)
|
||||
{
|
||||
fprintf(stderr, "%s: error: no usb support. please compile again with libusb installed.\n",
|
||||
progname);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void usbasp_initpgm(PROGRAMMER * pgm)
|
||||
{
|
||||
strcpy(pgm->type, "usbasp");
|
||||
|
||||
pgm->open = usbasp_nousb_open;
|
||||
}
|
||||
|
||||
#endif /* HAVE_LIBUSB */
|
||||
89
avrdude/usbasp.h
Normal file
89
avrdude/usbasp.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2006 Thomas Fischl
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef usbasp_h
|
||||
#define usbasp_h
|
||||
|
||||
#include "avrpart.h"
|
||||
|
||||
/* USB identifiers */
|
||||
#define USBASP_SHARED_VID 0x16C0 /* VOTI */
|
||||
#define USBASP_SHARED_PID 0x05DC /* Obdev's free shared PID */
|
||||
|
||||
#define USBASP_OLD_VID 0x03EB /* ATMEL */
|
||||
#define USBASP_OLD_PID 0xC7B4 /* (unoffical) USBasp */
|
||||
|
||||
/* USB function call identifiers */
|
||||
#define USBASP_FUNC_CONNECT 1
|
||||
#define USBASP_FUNC_DISCONNECT 2
|
||||
#define USBASP_FUNC_TRANSMIT 3
|
||||
#define USBASP_FUNC_READFLASH 4
|
||||
#define USBASP_FUNC_ENABLEPROG 5
|
||||
#define USBASP_FUNC_WRITEFLASH 6
|
||||
#define USBASP_FUNC_READEEPROM 7
|
||||
#define USBASP_FUNC_WRITEEEPROM 8
|
||||
#define USBASP_FUNC_SETLONGADDRESS 9
|
||||
#define USBASP_FUNC_SETISPSCK 10
|
||||
|
||||
/* Block mode flags */
|
||||
#define USBASP_BLOCKFLAG_FIRST 1
|
||||
#define USBASP_BLOCKFLAG_LAST 2
|
||||
|
||||
/* Block mode data size */
|
||||
#define USBASP_READBLOCKSIZE 200
|
||||
#define USBASP_WRITEBLOCKSIZE 200
|
||||
|
||||
/* ISP SCK speed identifiers */
|
||||
#define USBASP_ISP_SCK_AUTO 0
|
||||
#define USBASP_ISP_SCK_0_5 1 /* 500 Hz */
|
||||
#define USBASP_ISP_SCK_1 2 /* 1 kHz */
|
||||
#define USBASP_ISP_SCK_2 3 /* 2 kHz */
|
||||
#define USBASP_ISP_SCK_4 4 /* 4 kHz */
|
||||
#define USBASP_ISP_SCK_8 5 /* 8 kHz */
|
||||
#define USBASP_ISP_SCK_16 6 /* 16 kHz */
|
||||
#define USBASP_ISP_SCK_32 7 /* 32 kHz */
|
||||
#define USBASP_ISP_SCK_93_75 8 /* 93.75 kHz */
|
||||
#define USBASP_ISP_SCK_187_5 9 /* 187.5 kHz */
|
||||
#define USBASP_ISP_SCK_375 10 /* 375 kHz */
|
||||
#define USBASP_ISP_SCK_750 11 /* 750 kHz */
|
||||
#define USBASP_ISP_SCK_1500 12 /* 1.5 MHz */
|
||||
|
||||
typedef struct sckoptions_t {
|
||||
int id;
|
||||
double frequency;
|
||||
} CLOCKOPTIONS;
|
||||
|
||||
/* USB error identifiers */
|
||||
#define USB_ERROR_NOTFOUND 1
|
||||
#define USB_ERROR_ACCESS 2
|
||||
#define USB_ERROR_IO 3
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void usbasp_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* usbasp_h */
|
||||
43
avrdude/usbdevs.h
Normal file
43
avrdude/usbdevs.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2006 Joerg Wunsch
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* defines for the USB interface
|
||||
*/
|
||||
|
||||
#ifndef usbdevs_h
|
||||
#define usbdevs_h
|
||||
|
||||
#define USB_VENDOR_ATMEL 1003
|
||||
#define USB_DEVICE_JTAGICEMKII 0x2103
|
||||
#define USB_DEVICE_AVRISPMKII 0x2104
|
||||
#define USB_DEVICE_STK600 0x2106
|
||||
#define USB_DEVICE_AVRDRAGON 0x2107
|
||||
|
||||
/*
|
||||
* Should we query the endpoint number and max transfer size from USB?
|
||||
* After all, the JTAG ICE mkII docs document these values.
|
||||
*/
|
||||
#define USBDEV_BULK_EP_WRITE 0x02
|
||||
#define USBDEV_BULK_EP_READ 0x82
|
||||
#define USBDEV_MAX_XFER 64
|
||||
|
||||
#endif /* usbdevs_h */
|
||||
552
avrdude/usbtiny.c
Normal file
552
avrdude/usbtiny.c
Normal file
@@ -0,0 +1,552 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2007 Dick Streefland, adapted for 5.4 by Limor Fried
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* Driver for "usbtiny"-type programmers
|
||||
* Please see http://www.xs4all.nl/~dicks/avr/usbtiny/
|
||||
* and http://www.ladyada.net/make/usbtinyisp/
|
||||
* For example schematics and detailed documentation
|
||||
*/
|
||||
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "avr.h"
|
||||
#include "pgm.h"
|
||||
#include "usbtiny.h"
|
||||
|
||||
#if defined(HAVE_LIBUSB) // we use LIBUSB to talk to the board
|
||||
#include <usb.h>
|
||||
|
||||
#ifndef HAVE_UINT_T
|
||||
typedef unsigned int uint_t;
|
||||
#endif
|
||||
#ifndef HAVE_ULONG_T
|
||||
typedef unsigned long ulong_t;
|
||||
#endif
|
||||
|
||||
extern int avr_write_byte_default ( PROGRAMMER* pgm, AVRPART* p,
|
||||
AVRMEM* mem, ulong_t addr,
|
||||
unsigned char data );
|
||||
/*
|
||||
* Private data for this programmer.
|
||||
*/
|
||||
struct pdata
|
||||
{
|
||||
usb_dev_handle *usb_handle;
|
||||
int sck_period;
|
||||
int chunk_size;
|
||||
int retries;
|
||||
};
|
||||
|
||||
#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
static void usbtiny_setup(PROGRAMMER * pgm)
|
||||
{
|
||||
if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
|
||||
fprintf(stderr,
|
||||
"%s: usbtiny_setup(): Out of memory allocating private data\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
memset(pgm->cookie, 0, sizeof(struct pdata));
|
||||
}
|
||||
|
||||
static void usbtiny_teardown(PROGRAMMER * pgm)
|
||||
{
|
||||
free(pgm->cookie);
|
||||
}
|
||||
|
||||
// Wrapper for simple usb_control_msg messages
|
||||
static int usb_control (PROGRAMMER * pgm,
|
||||
unsigned int requestid, unsigned int val, unsigned int index )
|
||||
{
|
||||
int nbytes;
|
||||
nbytes = usb_control_msg( PDATA(pgm)->usb_handle,
|
||||
USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||
requestid,
|
||||
val, index, // 2 bytes each of data
|
||||
NULL, 0, // no data buffer in control messge
|
||||
USB_TIMEOUT ); // default timeout
|
||||
if(nbytes < 0){
|
||||
fprintf(stderr, "\n%s: error: usbtiny_transmit: %s\n", progname, usb_strerror());
|
||||
return -1;
|
||||
}
|
||||
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
// Wrapper for simple usb_control_msg messages to receive data from programmer
|
||||
static int usb_in (PROGRAMMER * pgm,
|
||||
unsigned int requestid, unsigned int val, unsigned int index,
|
||||
unsigned char* buffer, int buflen, int bitclk )
|
||||
{
|
||||
int nbytes;
|
||||
int timeout;
|
||||
int i;
|
||||
|
||||
// calculate the amout of time we expect the process to take by
|
||||
// figuring the bit-clock time and buffer size and adding to the standard USB timeout.
|
||||
timeout = USB_TIMEOUT + (buflen * bitclk) / 1000;
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
nbytes = usb_control_msg( PDATA(pgm)->usb_handle,
|
||||
USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||
requestid,
|
||||
val, index,
|
||||
(char *)buffer, buflen,
|
||||
timeout);
|
||||
if (nbytes == buflen) {
|
||||
return nbytes;
|
||||
}
|
||||
PDATA(pgm)->retries++;
|
||||
}
|
||||
fprintf(stderr, "\n%s: error: usbtiny_receive: %s (expected %d, got %d)\n",
|
||||
progname, usb_strerror(), buflen, nbytes);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Report the number of retries, and reset the counter.
|
||||
static void check_retries (PROGRAMMER * pgm, const char* operation)
|
||||
{
|
||||
if (PDATA(pgm)->retries > 0 && quell_progress < 2) {
|
||||
printf("%s: %d retries during %s\n", progname,
|
||||
PDATA(pgm)->retries, operation);
|
||||
}
|
||||
PDATA(pgm)->retries = 0;
|
||||
}
|
||||
|
||||
// Wrapper for simple usb_control_msg messages to send data to programmer
|
||||
static int usb_out (PROGRAMMER * pgm,
|
||||
unsigned int requestid, unsigned int val, unsigned int index,
|
||||
unsigned char* buffer, int buflen, int bitclk )
|
||||
{
|
||||
int nbytes;
|
||||
int timeout;
|
||||
|
||||
// calculate the amout of time we expect the process to take by
|
||||
// figuring the bit-clock time and buffer size and adding to the standard USB timeout.
|
||||
timeout = USB_TIMEOUT + (buflen * bitclk) / 1000;
|
||||
|
||||
nbytes = usb_control_msg( PDATA(pgm)->usb_handle,
|
||||
USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||
requestid,
|
||||
val, index,
|
||||
(char *)buffer, buflen,
|
||||
timeout);
|
||||
if (nbytes != buflen) {
|
||||
fprintf(stderr, "\n%s: error: usbtiny_send: %s (expected %d, got %d)\n",
|
||||
progname, usb_strerror(), buflen, nbytes);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
// Sometimes we just need to know the SPI command for the part to perform
|
||||
// a function. Here we wrap this request for an operation so that we
|
||||
// can just specify the part and operation and it'll do the right stuff
|
||||
// to get the information from AvrDude and send to the USBtiny
|
||||
static int usbtiny_avr_op (PROGRAMMER * pgm, AVRPART * p,
|
||||
int op,
|
||||
unsigned char res[4])
|
||||
{
|
||||
unsigned char cmd[4];
|
||||
|
||||
if (p->op[op] == NULL) {
|
||||
fprintf( stderr, "Operation %d not defined for this chip!\n", op );
|
||||
return -1;
|
||||
}
|
||||
memset(cmd, 0, sizeof(cmd));
|
||||
avr_set_bits(p->op[op], cmd);
|
||||
|
||||
return pgm->cmd(pgm, cmd, res);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/* Find a device with the correct VID/PID match for USBtiny */
|
||||
|
||||
static int usbtiny_open(PROGRAMMER* pgm, char* name)
|
||||
{
|
||||
struct usb_bus *bus;
|
||||
struct usb_device *dev = 0;
|
||||
|
||||
usb_init(); // initialize the libusb system
|
||||
usb_find_busses(); // have libusb scan all the usb busses available
|
||||
usb_find_devices(); // have libusb scan all the usb devices available
|
||||
|
||||
PDATA(pgm)->usb_handle = NULL;
|
||||
|
||||
// now we iterate through all the busses and devices
|
||||
for ( bus = usb_busses; bus; bus = bus->next ) {
|
||||
for ( dev = bus->devices; dev; dev = dev->next ) {
|
||||
if (dev->descriptor.idVendor == USBTINY_VENDOR
|
||||
&& dev->descriptor.idProduct == USBTINY_PRODUCT ) { // found match?
|
||||
|
||||
PDATA(pgm)->usb_handle = usb_open(dev); // attempt to connect to device
|
||||
|
||||
// wrong permissions or something?
|
||||
if (!PDATA(pgm)->usb_handle) {
|
||||
fprintf(stderr, "%s: Warning: cannot open USB device: %s\n",
|
||||
progname, usb_strerror());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!PDATA(pgm)->usb_handle) {
|
||||
fprintf( stderr, "%s: Error: Could not find USBtiny device (0x%x/0x%x)\n",
|
||||
progname, USBTINY_VENDOR, USBTINY_PRODUCT );
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0; // If we got here, we must have found a good USB device
|
||||
}
|
||||
|
||||
/* Clean up the handle for the usbtiny */
|
||||
static void usbtiny_close ( PROGRAMMER* pgm )
|
||||
{
|
||||
if (! PDATA(pgm)->usb_handle) {
|
||||
return; // not a valid handle, bail!
|
||||
}
|
||||
usb_close(PDATA(pgm)->usb_handle); // ask libusb to clean up
|
||||
PDATA(pgm)->usb_handle = NULL;
|
||||
}
|
||||
|
||||
/* A simple calculator function determines the maximum size of data we can
|
||||
shove through a USB connection without getting errors */
|
||||
static void usbtiny_set_chunk_size (PROGRAMMER * pgm, int period)
|
||||
{
|
||||
PDATA(pgm)->chunk_size = CHUNK_SIZE; // start with the maximum (default)
|
||||
while (PDATA(pgm)->chunk_size > 8 && period > 16) {
|
||||
// Reduce the chunk size for a slow SCK to reduce
|
||||
// the maximum time of a single USB transfer.
|
||||
PDATA(pgm)->chunk_size >>= 1;
|
||||
period >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Given a SCK bit-clock speed (in useconds) we verify its an OK speed and tell the
|
||||
USBtiny to update itself to the new frequency */
|
||||
static int usbtiny_set_sck_period (PROGRAMMER *pgm, double v)
|
||||
{
|
||||
PDATA(pgm)->sck_period = (int)(v * 1e6 + 0.5); // convert from us to 'int', the 0.5 is for rounding up
|
||||
|
||||
// Make sure its not 0, as that will confuse the usbtiny
|
||||
if (PDATA(pgm)->sck_period < SCK_MIN)
|
||||
PDATA(pgm)->sck_period = SCK_MIN;
|
||||
|
||||
// We can't go slower, due to the byte-size of the clock variable
|
||||
if (PDATA(pgm)->sck_period > SCK_MAX)
|
||||
PDATA(pgm)->sck_period = SCK_MAX;
|
||||
|
||||
if (verbose) {
|
||||
printf( "%s: Setting SCK period to %d usec\n", progname,
|
||||
PDATA(pgm)->sck_period );
|
||||
}
|
||||
|
||||
// send the command to the usbtiny device.
|
||||
// MEME: for at90's fix resetstate?
|
||||
if (usb_control(pgm, USBTINY_POWERUP, PDATA(pgm)->sck_period, RESET_LOW) < 0)
|
||||
return -1;
|
||||
|
||||
// with the new speed, we'll have to update how much data we send per usb transfer
|
||||
usbtiny_set_chunk_size(pgm, PDATA(pgm)->sck_period);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int usbtiny_initialize (PROGRAMMER *pgm, AVRPART *p )
|
||||
{
|
||||
unsigned char res[4]; // store the response from usbtinyisp
|
||||
|
||||
// Check for bit-clock and tell the usbtiny to adjust itself
|
||||
if (pgm->bitclock > 0.0) {
|
||||
// -B option specified: convert to valid range for sck_period
|
||||
usbtiny_set_sck_period(pgm, pgm->bitclock);
|
||||
} else {
|
||||
// -B option not specified: use default
|
||||
PDATA(pgm)->sck_period = SCK_DEFAULT;
|
||||
if (verbose) {
|
||||
printf( "%s: Using SCK period of %d usec\n",
|
||||
progname, PDATA(pgm)->sck_period );
|
||||
}
|
||||
if (usb_control(pgm, USBTINY_POWERUP,
|
||||
PDATA(pgm)->sck_period, RESET_LOW ) < 0)
|
||||
return -1;
|
||||
usbtiny_set_chunk_size(pgm, PDATA(pgm)->sck_period);
|
||||
}
|
||||
|
||||
// Let the device wake up.
|
||||
usleep(50000);
|
||||
|
||||
// Attempt to use the underlying avrdude methods to connect (MEME: is this kosher?)
|
||||
if (! usbtiny_avr_op(pgm, p, AVR_OP_PGM_ENABLE, res)) {
|
||||
// no response, RESET and try again
|
||||
if (usb_control(pgm, USBTINY_POWERUP,
|
||||
PDATA(pgm)->sck_period, RESET_HIGH) < 0 ||
|
||||
usb_control(pgm, USBTINY_POWERUP,
|
||||
PDATA(pgm)->sck_period, RESET_LOW) < 0)
|
||||
return -1;
|
||||
usleep(50000);
|
||||
if ( ! usbtiny_avr_op( pgm, p, AVR_OP_PGM_ENABLE, res)) {
|
||||
// give up
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Tell the USBtiny to release the output pins, etc */
|
||||
static void usbtiny_powerdown(PROGRAMMER * pgm)
|
||||
{
|
||||
if (!PDATA(pgm)->usb_handle) {
|
||||
return; // wasn't connected in the first place
|
||||
}
|
||||
usb_control(pgm, USBTINY_POWERDOWN, 0, 0); // Send USB control command to device
|
||||
}
|
||||
|
||||
/* Send a 4-byte SPI command to the USBtinyISP for execution
|
||||
This procedure is used by higher-level Avrdude procedures */
|
||||
static int usbtiny_cmd(PROGRAMMER * pgm, unsigned char cmd[4], unsigned char res[4])
|
||||
{
|
||||
int nbytes;
|
||||
|
||||
// Make sure its empty so we don't read previous calls if it fails
|
||||
memset(res, '\0', 4 );
|
||||
|
||||
nbytes = usb_in( pgm, USBTINY_SPI,
|
||||
(cmd[1] << 8) | cmd[0], // convert to 16-bit words
|
||||
(cmd[3] << 8) | cmd[2], // "
|
||||
res, 4, 8 * PDATA(pgm)->sck_period );
|
||||
if (nbytes < 0)
|
||||
return -1;
|
||||
check_retries(pgm, "SPI command");
|
||||
if (verbose > 1) {
|
||||
// print out the data we sent and received
|
||||
printf( "CMD: [%02x %02x %02x %02x] [%02x %02x %02x %02x]\n",
|
||||
cmd[0], cmd[1], cmd[2], cmd[3],
|
||||
res[0], res[1], res[2], res[3] );
|
||||
}
|
||||
return ((nbytes == 4) && // should have read 4 bytes
|
||||
res[2] == cmd[1]); // AVR's do a delayed-echo thing
|
||||
}
|
||||
|
||||
/* Send the chip-erase command */
|
||||
static int usbtiny_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
unsigned char res[4];
|
||||
|
||||
if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
|
||||
fprintf(stderr, "Chip erase instruction not defined for part \"%s\"\n",
|
||||
p->desc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// get the command for erasing this chip and transmit to avrdude
|
||||
if (! usbtiny_avr_op( pgm, p, AVR_OP_CHIP_ERASE, res )) {
|
||||
return -1;
|
||||
}
|
||||
usleep( p->chip_erase_delay );
|
||||
|
||||
// prepare for further instruction
|
||||
pgm->initialize(pgm, p);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// These are required functions but don't actually do anything
|
||||
static void usbtiny_enable ( PROGRAMMER* pgm ) {}
|
||||
|
||||
static void usbtiny_disable ( PROGRAMMER* pgm ) {}
|
||||
|
||||
|
||||
/* To speed up programming and reading, we do a 'chunked' read.
|
||||
* We request just the data itself and the USBtiny uses the SPI function
|
||||
* given to read in the data. Much faster than sending a 4-byte SPI request
|
||||
* per byte
|
||||
*/
|
||||
static int usbtiny_paged_load (PROGRAMMER * pgm, AVRPART * p, AVRMEM* m,
|
||||
int page_size, int n_bytes )
|
||||
{
|
||||
int i;
|
||||
int chunk;
|
||||
int function;
|
||||
|
||||
|
||||
// First determine what we're doing
|
||||
if (strcmp( m->desc, "flash" ) == 0) {
|
||||
function = USBTINY_FLASH_READ;
|
||||
} else {
|
||||
function = USBTINY_EEPROM_READ;
|
||||
}
|
||||
|
||||
for (i = 0; i < n_bytes; i += chunk) {
|
||||
chunk = PDATA(pgm)->chunk_size; // start with the maximum chunk size possible
|
||||
|
||||
// If we want to xmit less than a chunk, thats OK
|
||||
if (chunk > n_bytes-i)
|
||||
chunk = n_bytes - i;
|
||||
|
||||
// Send the chunk of data to the USBtiny with the function we want
|
||||
// to perform
|
||||
if (usb_in(pgm,
|
||||
function, // EEPROM or flash
|
||||
0, // delay between SPI commands
|
||||
i, // index
|
||||
m->buf + i, // pointer to where we store data
|
||||
chunk, // number of bytes
|
||||
32 * PDATA(pgm)->sck_period) // each byte gets turned into a 4-byte SPI cmd
|
||||
< 0) {
|
||||
// usb_in() multiplies this per byte.
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Tell avrdude how we're doing to provide user feedback
|
||||
report_progress(i + chunk, n_bytes, NULL );
|
||||
}
|
||||
|
||||
check_retries(pgm, "read");
|
||||
return n_bytes;
|
||||
}
|
||||
|
||||
/* To speed up programming and reading, we do a 'chunked' write.
|
||||
* We send just the data itself and the USBtiny uses the SPI function
|
||||
* given to write the data. Much faster than sending a 4-byte SPI request
|
||||
* per byte.
|
||||
*/
|
||||
static int usbtiny_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int n_bytes)
|
||||
{
|
||||
int i;
|
||||
int chunk; // Size of data to write at once
|
||||
int next;
|
||||
int function; // which SPI command to use
|
||||
int delay; // delay required between SPI commands
|
||||
|
||||
// First determine what we're doing
|
||||
if (strcmp( m->desc, "flash" ) == 0) {
|
||||
function = USBTINY_FLASH_WRITE;
|
||||
} else {
|
||||
function = USBTINY_EEPROM_WRITE;
|
||||
}
|
||||
|
||||
delay = 0;
|
||||
if (! m->paged) {
|
||||
// Does this chip not support paged writes?
|
||||
i = (m->readback[1] << 8) | m->readback[0];
|
||||
if (usb_control(pgm, USBTINY_POLL_BYTES, i, 0 ) < 0)
|
||||
return -1;
|
||||
delay = m->max_write_delay;
|
||||
}
|
||||
|
||||
for (i=0; i < n_bytes; i=next) {
|
||||
// start with the max chunk size
|
||||
chunk = PDATA(pgm)->chunk_size;
|
||||
|
||||
// we can only write a page at a time anyways
|
||||
if (m->paged && chunk > page_size)
|
||||
chunk = page_size;
|
||||
|
||||
// if there's less data remaining than one chunk
|
||||
if (chunk > n_bytes-i)
|
||||
chunk = n_bytes - i;
|
||||
|
||||
if (usb_out(pgm,
|
||||
function, // Flash or EEPROM
|
||||
delay, // How much to wait between each byte
|
||||
i, // Index of data
|
||||
m->buf + i, // Pointer to data
|
||||
chunk, // Number of bytes to write
|
||||
32 * PDATA(pgm)->sck_period + delay // each byte gets turned into a
|
||||
// 4-byte SPI cmd usb_out() multiplies
|
||||
// this per byte. Then add the cmd-delay
|
||||
) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
next = i + chunk; // Calculate what address we're at now
|
||||
if (m->paged
|
||||
&& ((next % page_size) == 0 || next == n_bytes) ) {
|
||||
// If we're at a page boundary, send the SPI command to flush it.
|
||||
avr_write_page(pgm, p, m, (unsigned long) i);
|
||||
}
|
||||
|
||||
report_progress( next, n_bytes, NULL );
|
||||
}
|
||||
return n_bytes;
|
||||
}
|
||||
|
||||
extern void usbtiny_initpgm ( PROGRAMMER* pgm )
|
||||
{
|
||||
strcpy(pgm->type, "USBtiny");
|
||||
|
||||
/* Mandatory Functions */
|
||||
pgm->initialize = usbtiny_initialize;
|
||||
pgm->enable = usbtiny_enable;
|
||||
pgm->disable = usbtiny_disable;
|
||||
pgm->program_enable = NULL;
|
||||
pgm->chip_erase = usbtiny_chip_erase;
|
||||
pgm->cmd = usbtiny_cmd;
|
||||
pgm->open = usbtiny_open;
|
||||
pgm->close = usbtiny_close;
|
||||
pgm->read_byte = avr_read_byte_default;
|
||||
pgm->write_byte = avr_write_byte_default;
|
||||
|
||||
/* Optional Functions */
|
||||
pgm->powerup = NULL;
|
||||
pgm->powerdown = usbtiny_powerdown;
|
||||
pgm->paged_load = usbtiny_paged_load;
|
||||
pgm->paged_write = usbtiny_paged_write;
|
||||
pgm->set_sck_period = usbtiny_set_sck_period;
|
||||
pgm->setup = usbtiny_setup;
|
||||
pgm->teardown = usbtiny_teardown;
|
||||
}
|
||||
|
||||
#else /* !HAVE_LIBUSB */
|
||||
|
||||
// Give a proper error if we were not compiled with libusb
|
||||
|
||||
static int usbtiny_nousb_open(struct programmer_t *pgm, char * name)
|
||||
{
|
||||
fprintf(stderr, "%s: error: no usb support. Please compile again with libusb installed.\n",
|
||||
progname);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void usbtiny_initpgm(PROGRAMMER * pgm)
|
||||
{
|
||||
strcpy(pgm->type, "usbtiny");
|
||||
|
||||
pgm->open = usbtiny_nousb_open;
|
||||
}
|
||||
|
||||
#endif /* HAVE_LIBUSB */
|
||||
76
avrdude/usbtiny.h
Normal file
76
avrdude/usbtiny.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2007 Limor Fried
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
#ifndef usbtiny_h
|
||||
#define usbtiny_h
|
||||
|
||||
#include "avrpart.h"
|
||||
|
||||
// these are specifically assigned to USBtiny,
|
||||
// if you need your own VID and PIDs you can get them for cheap from
|
||||
// www.mecanique.co.uk so please don't reuse these. Thanks!
|
||||
#define USBTINY_VENDOR 0x1781
|
||||
#define USBTINY_PRODUCT 0x0C9F
|
||||
|
||||
// Generic requests to the USBtiny
|
||||
#define USBTINY_ECHO 0 // echo test
|
||||
#define USBTINY_READ 1 // read byte (wIndex:address)
|
||||
#define USBTINY_WRITE 2 // write byte (wIndex:address, wValue:value)
|
||||
#define USBTINY_CLR 3 // clear bit (wIndex:address, wValue:bitno)
|
||||
#define USBTINY_SET 4 // set bit (wIndex:address, wValue:bitno)
|
||||
|
||||
// Programming requests
|
||||
#define USBTINY_POWERUP 5 // apply power (wValue:SCK-period, wIndex:RESET)
|
||||
#define USBTINY_POWERDOWN 6 // remove power from chip
|
||||
#define USBTINY_SPI 7 // issue SPI command (wValue:c1c0, wIndex:c3c2)
|
||||
#define USBTINY_POLL_BYTES 8 // set poll bytes for write (wValue:p1p2)
|
||||
#define USBTINY_FLASH_READ 9 // read flash (wIndex:address)
|
||||
#define USBTINY_FLASH_WRITE 10 // write flash (wIndex:address, wValue:timeout)
|
||||
#define USBTINY_EEPROM_READ 11 // read eeprom (wIndex:address)
|
||||
#define USBTINY_EEPROM_WRITE 12 // write eeprom (wIndex:address, wValue:timeout)
|
||||
|
||||
|
||||
|
||||
// Flags to indicate how to set RESET on power up
|
||||
#define RESET_LOW 0
|
||||
#define RESET_HIGH 1
|
||||
|
||||
// The SCK speed can be set by avrdude, to allow programming of slow-clocked parts
|
||||
#define SCK_MIN 1 // usec delay (target clock >= 4 MHz)
|
||||
#define SCK_MAX 250 // usec (target clock >= 16 KHz)
|
||||
#define SCK_DEFAULT 10 // usec (target clock >= 0.4 MHz)
|
||||
|
||||
// How much data, max, do we want to send in one USB packet?
|
||||
#define CHUNK_SIZE 128 // must be power of 2 less than 256
|
||||
|
||||
// The default USB Timeout
|
||||
#define USB_TIMEOUT 500 // msec
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void usbtiny_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* usbtiny_h */
|
||||
4
avrdude/windows/.cvsignore
Normal file
4
avrdude/windows/.cvsignore
Normal file
@@ -0,0 +1,4 @@
|
||||
.cvsignore
|
||||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
||||
@@ -37,7 +37,7 @@ EXTRA_DIST = \
|
||||
|
||||
bin_PROGRAMS = loaddrv
|
||||
|
||||
loaddrv_CFLAGS = -mno-cygwin
|
||||
loaddrv_LDFLAGS = -mno-cygwin
|
||||
|
||||
loaddrv_SOURCES = \
|
||||
loaddrv.c \
|
||||
|
||||
Reference in New Issue
Block a user