mirror of
https://github.com/mariusgreuel/avrdude.git
synced 2025-12-18 11:24:42 +00:00
Compare commits
419 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e076170551 | ||
|
|
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
|
y.tab.h
|
||||||
lexer.c
|
lexer.c
|
||||||
config_gram.c
|
config_gram.c
|
||||||
|
config_gram.h
|
||||||
.cvsignore
|
.cvsignore
|
||||||
.depend
|
.depend
|
||||||
|
.deps
|
||||||
INSTALL
|
INSTALL
|
||||||
Makefile.in
|
Makefile.in
|
||||||
|
Makefile
|
||||||
ac_cfg.h.in
|
ac_cfg.h.in
|
||||||
aclocal.m4
|
aclocal.m4
|
||||||
autom4te.cache
|
autom4te.cache
|
||||||
configure
|
configure
|
||||||
depcomp
|
depcomp
|
||||||
install-sh
|
install-sh
|
||||||
|
compile
|
||||||
missing
|
missing
|
||||||
mkinstalldirs
|
mkinstalldirs
|
||||||
stamp-h.in
|
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:
|
AVRDUDE was written by:
|
||||||
|
|
||||||
Brian S. Dean <bsd@bsdhome.com>.
|
Brian S. Dean <bsd@bdmicro.com>
|
||||||
|
|
||||||
Contributors:
|
Contributors:
|
||||||
|
|
||||||
Joerg Wunsch <j@uriah.heep.sax.de>
|
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.
|
||||||
|
|
||||||
|
|||||||
2025
avrdude/ChangeLog
2025
avrdude/ChangeLog
File diff suppressed because it is too large
Load Diff
1095
avrdude/ChangeLog-2003
Normal file
1095
avrdude/ChangeLog-2003
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
#
|
#
|
||||||
# avrdude - A Downloader/Uploader for AVR device programmers
|
# 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
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
@@ -22,10 +22,11 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
|
ChangeLog \
|
||||||
ChangeLog-2001 \
|
ChangeLog-2001 \
|
||||||
ChangeLog-2002 \
|
ChangeLog-2002 \
|
||||||
|
ChangeLog-2003 \
|
||||||
avrdude.1 \
|
avrdude.1 \
|
||||||
avrdude.pdf \
|
|
||||||
avrdude.spec \
|
avrdude.spec \
|
||||||
bootstrap
|
bootstrap
|
||||||
|
|
||||||
@@ -34,31 +35,70 @@ CLEANFILES = \
|
|||||||
config_gram.h \
|
config_gram.h \
|
||||||
lexer.c
|
lexer.c
|
||||||
|
|
||||||
SUBDIRS = doc @WINDOWS_DIRS@
|
#SUBDIRS = doc @WINDOWS_DIRS@
|
||||||
DIST_SUBDIRS = doc windows
|
#DIST_SUBDIRS = doc windows
|
||||||
|
|
||||||
|
SUBDIRS = @SUBDIRS_AC@
|
||||||
|
DIST_SUBDIRS = @DIST_SUBDIRS_AC@
|
||||||
|
|
||||||
AM_YFLAGS = -d
|
AM_YFLAGS = -d
|
||||||
|
|
||||||
AM_CPPFLAGS = -DCONFIG_DIR=\"$(sysconfdir)\"
|
avrdude_CPPFLAGS = -DCONFIG_DIR=\"$(sysconfdir)\"
|
||||||
|
|
||||||
|
avrdude_CFLAGS = @ENABLE_WARNINGS@
|
||||||
|
|
||||||
|
avrdude_LDADD = @LIBUSB@
|
||||||
|
|
||||||
bin_PROGRAMS = avrdude
|
bin_PROGRAMS = avrdude
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
avrdude_SOURCES = \
|
avrdude_SOURCES = \
|
||||||
config_gram.y \
|
config_gram.y \
|
||||||
lexer.l \
|
lexer.l \
|
||||||
avr.c \
|
avr.c \
|
||||||
avr.h \
|
avr.h \
|
||||||
|
avr910.c \
|
||||||
|
avr910.h \
|
||||||
|
avrpart.c \
|
||||||
avrpart.h \
|
avrpart.h \
|
||||||
|
bitbang.c \
|
||||||
|
bitbang.h \
|
||||||
|
butterfly.c \
|
||||||
|
butterfly.h \
|
||||||
config.c \
|
config.c \
|
||||||
config.h \
|
config.h \
|
||||||
confwin.c \
|
confwin.c \
|
||||||
confwin.h \
|
confwin.h \
|
||||||
|
crc16.c \
|
||||||
|
crc16.h \
|
||||||
fileio.c \
|
fileio.c \
|
||||||
fileio.h \
|
fileio.h \
|
||||||
|
freebsd_ppi.h \
|
||||||
|
jtagmkI.c \
|
||||||
|
jtagmkI.h \
|
||||||
|
jtagmkI_private.h \
|
||||||
|
jtagmkII.c \
|
||||||
|
jtagmkII.h \
|
||||||
|
jtagmkII_private.h \
|
||||||
linux_ppdev.h \
|
linux_ppdev.h \
|
||||||
lists.c \
|
lists.c \
|
||||||
lists.h \
|
lists.h \
|
||||||
main.c \
|
main.c \
|
||||||
|
my_ddk_hidsdi.h \
|
||||||
par.c \
|
par.c \
|
||||||
par.h \
|
par.h \
|
||||||
pgm.c \
|
pgm.c \
|
||||||
@@ -67,11 +107,30 @@ avrdude_SOURCES = \
|
|||||||
ppi.c \
|
ppi.c \
|
||||||
ppi.h \
|
ppi.h \
|
||||||
ppiwin.c \
|
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.c \
|
||||||
stk500.h \
|
stk500.h \
|
||||||
stk500_private.h \
|
stk500_private.h \
|
||||||
|
stk500v2.c \
|
||||||
|
stk500v2.h \
|
||||||
|
stk500v2_private.h \
|
||||||
|
stk500generic.c \
|
||||||
|
stk500generic.h \
|
||||||
term.c \
|
term.c \
|
||||||
term.h
|
term.h \
|
||||||
|
usbasp.c \
|
||||||
|
usbasp.h \
|
||||||
|
usbdevs.h \
|
||||||
|
usb_libusb.c
|
||||||
|
|
||||||
man_MANS = avrdude.1
|
man_MANS = avrdude.1
|
||||||
|
|
||||||
@@ -79,6 +138,9 @@ sysconf_DATA = avrdude.conf
|
|||||||
|
|
||||||
install-exec-local: backup-avrdude-conf
|
install-exec-local: backup-avrdude-conf
|
||||||
|
|
||||||
|
distclean-local:
|
||||||
|
rm -f avrdude.conf
|
||||||
|
|
||||||
# This will get run before the config file is installed.
|
# This will get run before the config file is installed.
|
||||||
backup-avrdude-conf:
|
backup-avrdude-conf:
|
||||||
@echo "Backing up avrdude.conf in ${DESTDIR}${sysconfdir}"
|
@echo "Backing up avrdude.conf in ${DESTDIR}${sysconfdir}"
|
||||||
|
|||||||
197
avrdude/NEWS
197
avrdude/NEWS
@@ -5,19 +5,206 @@ Approximate change log for AVRDUDE by version.
|
|||||||
(For more detailed changes, see the ChangeLog file.)
|
(For more detailed changes, see the ChangeLog file.)
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
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
|
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
|
* Use 'configure' scripts to tailor the code to the system avrdude
|
||||||
is getting ready to be compiled on - added by "Theodore A. Roth"
|
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 "
|
* Motorola S-Record support - submitted by "Alexey V.Levdikov "
|
||||||
<tsar@kemford.com>
|
<tsar@kemford.com>.
|
||||||
|
|
||||||
* Support parallel programming on the STK500. Introduce 'pagel' and
|
* Support parallel programming on the STK500. Introduce 'pagel' and
|
||||||
'bs2' keywords to the config file for this purpose.
|
'bs2' keywords to the config file for this purpose.
|
||||||
@@ -233,4 +420,4 @@ Version 1.3.0 :
|
|||||||
|
|
||||||
Version 1.2.2 :
|
Version 1.2.2 :
|
||||||
|
|
||||||
* Initial public release
|
* Initial public release.
|
||||||
|
|||||||
785
avrdude/avr.c
785
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
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -25,7 +25,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "avrpart.h"
|
#include "avrpart.h"
|
||||||
#include "lists.h"
|
|
||||||
#include "pgm.h"
|
#include "pgm.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -33,29 +32,10 @@
|
|||||||
extern struct avrpart parts[];
|
extern struct avrpart parts[];
|
||||||
|
|
||||||
|
|
||||||
|
int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||||
|
unsigned long addr, unsigned char * value);
|
||||||
|
|
||||||
AVRPART * avr_find_part(char * p);
|
int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
||||||
|
|
||||||
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 verbose);
|
int verbose);
|
||||||
|
|
||||||
int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||||
@@ -64,24 +44,24 @@ int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||||||
int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||||
unsigned long addr, unsigned char data);
|
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 verbose);
|
||||||
|
|
||||||
int avr_signature(PROGRAMMER * pgm, AVRPART * p);
|
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);
|
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_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);
|
||||||
|
|
||||||
|
extern void report_progress (int completed, int total, char *hdr);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
613
avrdude/avr910.c
Normal file
613
avrdude/avr910.c
Normal file
@@ -0,0 +1,613 @@
|
|||||||
|
/*
|
||||||
|
* 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$ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 <sys/time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "avr.h"
|
||||||
|
#include "pgm.h"
|
||||||
|
#include "avr910.h"
|
||||||
|
#include "serial.h"
|
||||||
|
|
||||||
|
extern char * progname;
|
||||||
|
extern int do_cycles;
|
||||||
|
extern int ovsigck;
|
||||||
|
|
||||||
|
static char has_auto_incr_addr;
|
||||||
|
|
||||||
|
|
||||||
|
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, &has_auto_incr_addr, 1);
|
||||||
|
if (has_auto_incr_addr == 'Y')
|
||||||
|
fprintf(stderr, "Programmer supports auto addr increment.\n");
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tell the programmer which part we selected.
|
||||||
|
If the user forced the selection, use the first device
|
||||||
|
type that is supported by the programmer. */
|
||||||
|
|
||||||
|
buf[0] = 'T';
|
||||||
|
buf[1] = ovsigck? devtype_1st: p->avr910_devcode;
|
||||||
|
|
||||||
|
avr910_send(pgm, buf, 2);
|
||||||
|
avr910_vfy_cmd_sent(pgm, "select device");
|
||||||
|
|
||||||
|
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_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, 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 -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
static int cached = 0;
|
||||||
|
static unsigned char cvalue;
|
||||||
|
static unsigned long caddr;
|
||||||
|
|
||||||
|
if (cached && ((caddr + 1) == addr)) {
|
||||||
|
*value = cvalue;
|
||||||
|
cached = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
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];
|
||||||
|
// cached = 1;
|
||||||
|
cvalue = buf[0];
|
||||||
|
caddr = addr;
|
||||||
|
}
|
||||||
|
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 -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 ((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 (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)
|
||||||
|
{
|
||||||
|
if (strcmp(m->desc, "flash") == 0) {
|
||||||
|
return avr910_paged_write_flash(pgm, p, m, page_size, n_bytes);
|
||||||
|
}
|
||||||
|
else if (strcmp(m->desc, "eeprom") == 0) {
|
||||||
|
return avr910_paged_write_eeprom(pgm, p, m, page_size, n_bytes);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int avr910_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||||
|
int page_size, int n_bytes)
|
||||||
|
{
|
||||||
|
char cmd;
|
||||||
|
int rd_size;
|
||||||
|
unsigned int addr = 0;
|
||||||
|
unsigned int max_addr;
|
||||||
|
char buf[2];
|
||||||
|
|
||||||
|
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 {
|
||||||
|
return -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 (has_auto_incr_addr != 'Y') {
|
||||||
|
avr910_set_addr(pgm, addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
report_progress (addr, max_addr, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return addr * rd_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
29
avrdude/avr910.h
Normal file
29
avrdude/avr910.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* 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"
|
||||||
|
|
||||||
|
void avr910_initpgm (PROGRAMMER * pgm);
|
||||||
|
|
||||||
|
#endif /* __avr910_h__ */
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" avrdude - A Downloader/Uploader for AVR device programmers
|
.\" avrdude - A Downloader/Uploader for AVR device programmers
|
||||||
.\" Copyright (C) 2001, 2002, 2003 Joerg Wunsch
|
.\" Copyright (C) 2001, 2002, 2003, 2005, 2006 Joerg Wunsch
|
||||||
.\"
|
.\"
|
||||||
.\" This program is free software; you can redistribute it and/or modify
|
.\" 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
|
.\" it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $Id$
|
.\" $Id$
|
||||||
.\"
|
.\"
|
||||||
.Dd DATE January 11, 2002
|
.Dd DATE October 26, 2006
|
||||||
.Os
|
.Os
|
||||||
.Dt AVRDUDE 1
|
.Dt AVRDUDE 1
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@@ -28,20 +28,25 @@
|
|||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
.Fl p Ar partno
|
.Fl p Ar partno
|
||||||
|
.Op Fl b Ar baudrate
|
||||||
|
.Op Fl B Ar bitclock
|
||||||
.Op Fl c Ar programmer-id
|
.Op Fl c Ar programmer-id
|
||||||
.Op Fl C Ar config-file
|
.Op Fl C Ar config-file
|
||||||
|
.Op Fl D
|
||||||
.Op Fl e
|
.Op Fl e
|
||||||
.Oo Fl E Ar exitspec Ns
|
.Oo Fl E Ar exitspec Ns
|
||||||
.Op \&, Ns Ar exitspec
|
.Op \&, Ns Ar exitspec
|
||||||
.Oc
|
.Oc
|
||||||
.Op Fl f Ar format
|
|
||||||
.Op Fl F
|
.Op Fl F
|
||||||
.Op Fl i Ar filename
|
.Op Fl i Ar delay
|
||||||
.Op Fl m Ar memtype
|
|
||||||
.Op Fl o Ar filename
|
|
||||||
.Op Fl n
|
.Op Fl n
|
||||||
|
.Op Fl O
|
||||||
.Op Fl P Ar port
|
.Op Fl P Ar port
|
||||||
|
.Op Fl q
|
||||||
|
.Op Fl s
|
||||||
.Op Fl t
|
.Op Fl t
|
||||||
|
.Op Fl u
|
||||||
|
.Op Fl U Ar memtype:op:filename:filefmt
|
||||||
.Op Fl v
|
.Op Fl v
|
||||||
.Op Fl V
|
.Op Fl V
|
||||||
.Op Fl y
|
.Op Fl y
|
||||||
@@ -51,10 +56,17 @@
|
|||||||
is a program for downloading code and data to Atmel AVR
|
is a program for downloading code and data to Atmel AVR
|
||||||
microcontrollers.
|
microcontrollers.
|
||||||
.Nm Avrdude
|
.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 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
|
programmer connected directly to a
|
||||||
.Xr ppi 4
|
.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.
|
cable connecting the respective AVR signal lines to the parallel port.
|
||||||
.Pp
|
.Pp
|
||||||
The MCU is programmed in
|
The MCU is programmed in
|
||||||
@@ -70,20 +82,56 @@ and
|
|||||||
need to be connected to the parallel port. Optionally, some otherwise
|
need to be connected to the parallel port. Optionally, some otherwise
|
||||||
unused output pins of the parallel port can be used to supply power
|
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
|
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
|
current operating state of the programmer can be connected, and a
|
||||||
signal is available to control a buffer/driver IC 74LS367 (or
|
signal is available to control a buffer/driver IC 74LS367 (or
|
||||||
74HCT367). The latter can be useful to decouple the parallel port
|
74HCT367). The latter can be useful to decouple the parallel port
|
||||||
from the MCU when in-system programming is used.
|
from the MCU when in-system programming is used.
|
||||||
.Pp
|
.Pp
|
||||||
See the file
|
A number of equally simple bit-bang programming adapters that connect
|
||||||
.Pa ${PREFIX}/share/doc/avrdude/avrdude.pdf
|
to a serial port are supported as well, among them the popular
|
||||||
for a schematic of the
|
Ponyprog serial adapter, and the DASA and DASA3 adapters that used to
|
||||||
.Xr ppi 4
|
be supported by uisp(1).
|
||||||
based programming hardware.
|
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
|
.Pp
|
||||||
Atmel's STK500 programmer is also supported and connects to a serial
|
Atmel's STK500 programmer is also supported and connects to a serial
|
||||||
port.
|
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 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 adapter is also supported, provided
|
||||||
|
.Nm avrdude
|
||||||
|
has been compiled with libusb support.
|
||||||
|
It features a simple firwmare-only USB implementation, running on
|
||||||
|
an ATmega8 (or ATmega88).
|
||||||
.Pp
|
.Pp
|
||||||
Input files can be provided, and output files can be written in
|
Input files can be provided, and output files can be written in
|
||||||
different file formats, such as raw binary files containing the data
|
different file formats, such as raw binary files containing the data
|
||||||
@@ -100,7 +148,7 @@ can program the EEPROM and flash ROM memory cells of supported AVR
|
|||||||
parts. Where supported by the serial instruction set, fuse bits and
|
parts. Where supported by the serial instruction set, fuse bits and
|
||||||
lock bits can be programmed as well. These are implemented within
|
lock bits can be programmed as well. These are implemented within
|
||||||
.Nm
|
.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
|
(see the
|
||||||
.Fl m
|
.Fl m
|
||||||
option) or from terminal mode (see the
|
option) or from terminal mode (see the
|
||||||
@@ -112,6 +160,9 @@ been code-protected previously, of course) and store the data in a
|
|||||||
file. Finally, a ``terminal'' mode is available that allows one to
|
file. Finally, a ``terminal'' mode is available that allows one to
|
||||||
interactively communicate with the MCU, and to display or program
|
interactively communicate with the MCU, and to display or program
|
||||||
individual memory cells.
|
individual memory cells.
|
||||||
|
On the STK500 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
|
.Ss Options
|
||||||
In order to control all the different operation modi, a number of options
|
In order to control all the different operation modi, a number of options
|
||||||
need to be specified to
|
need to be specified to
|
||||||
@@ -130,7 +181,9 @@ the format. Currently, the following MCU types are understood:
|
|||||||
.TS
|
.TS
|
||||||
ll.
|
ll.
|
||||||
\fBOption tag\fP \fBOfficial part name\fP
|
\fBOption tag\fP \fBOfficial part name\fP
|
||||||
t15 ATtiny15
|
c128 AT90CAN128
|
||||||
|
pwm2 AT90PWM2
|
||||||
|
pwm3 AT90PWM3
|
||||||
1200 AT90S1200
|
1200 AT90S1200
|
||||||
2313 AT90S2313
|
2313 AT90S2313
|
||||||
2333 AT90S2333
|
2333 AT90S2333
|
||||||
@@ -140,17 +193,62 @@ t15 ATtiny15
|
|||||||
4434 AT90S4434
|
4434 AT90S4434
|
||||||
8515 AT90S8515
|
8515 AT90S8515
|
||||||
8535 AT90S8535
|
8535 AT90S8535
|
||||||
m163 ATMEGA163
|
m103 ATmega103
|
||||||
m169 ATMEGA169
|
m128 ATmega128
|
||||||
m128 ATMEGA128
|
m1280 ATmega1280
|
||||||
m103 ATMEGA103
|
m1281 ATmega1281
|
||||||
m16 ATMEGA16
|
m16 ATmega16
|
||||||
m8 ATMEGA8
|
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
|
||||||
.TE
|
.TE
|
||||||
.Bl -tag -width "(*) "
|
.Bl -tag -width "(**) "
|
||||||
.It "(*)"
|
.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
|
.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
|
.It Fl c Ar programmer-id
|
||||||
Use the pin configuration specified by the argument. Pin
|
Use the pin configuration specified by the argument. Pin
|
||||||
configurations are read from the config file (see the
|
configurations are read from the config file (see the
|
||||||
@@ -175,6 +273,14 @@ submit a patch back to the author so that it can be incorporated for
|
|||||||
the next version). See the config file, located at
|
the next version). See the config file, located at
|
||||||
.Pa ${PREFIX}/etc/avrdude.conf ,
|
.Pa ${PREFIX}/etc/avrdude.conf ,
|
||||||
which contains a description of the format.
|
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.
|
||||||
.It Fl e
|
.It Fl e
|
||||||
Causes a chip erase to be executed. This will reset the contents of the
|
Causes a chip erase to be executed. This will reset the contents of the
|
||||||
flash ROM and EEPROM to the value
|
flash ROM and EEPROM to the value
|
||||||
@@ -238,26 +344,6 @@ pins of the parallel port down at program exit.
|
|||||||
Multiple
|
Multiple
|
||||||
.Ar exitspec
|
.Ar exitspec
|
||||||
arguments can be separated with commas.
|
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
|
.It Fl F
|
||||||
Normally,
|
Normally,
|
||||||
.Nm
|
.Nm
|
||||||
@@ -266,36 +352,34 @@ reasonable before continuing. Since it can happen from time to time
|
|||||||
that a device has a broken (erased or overwritten) device signature
|
that a device has a broken (erased or overwritten) device signature
|
||||||
but is otherwise operating normally, this options is provided to
|
but is otherwise operating normally, this options is provided to
|
||||||
override the check.
|
override the check.
|
||||||
.It Fl i Ar filename
|
.It Fl i Ar delay
|
||||||
Specifies the input file to be programmed into the MCU. Can be specified
|
For bitbang-type programmers, delay for approximately
|
||||||
as
|
.Ar delay
|
||||||
.Ql \&-
|
microseconds between each bit state change.
|
||||||
to use
|
If the host system is very fast, or the target runs off a slow clock
|
||||||
.Em stdin
|
(like a 32 kHz crystal, or the 128 kHz internal RC oscillator), this
|
||||||
as the input.
|
can become necessary to satisfy the requirement that the ISP clock
|
||||||
.It Fl m Ar memtype
|
frequency must not be higher than 1/4 of the CPU clock frequency.
|
||||||
Specifies which program area of the MCU to read or write; allowable
|
This is implemented as a spin-loop delay to allow even for very
|
||||||
values depend on the MCU being programmed, but most support at least
|
short delays.
|
||||||
.Em eeprom
|
On Unix-style operating systems, the spin loop is initially calibrated
|
||||||
for the EEPROM, and
|
against a system timer, so the number of microseconds might be rather
|
||||||
.Em flash
|
realistic, assuming a constant system load while
|
||||||
for the flash ROM. Use the
|
.Nm
|
||||||
.Fl v
|
is running.
|
||||||
option on the command line or the
|
On Win32 operating systems, a preconfigured number of cycles per
|
||||||
.Ar part
|
microsecond is assumed that might be off a bit for very fast or very
|
||||||
command from terminal mode to display all the memory types supported
|
slow machines.
|
||||||
by a particular device. The default is
|
|
||||||
.Em flash .
|
|
||||||
.It Fl n
|
.It Fl n
|
||||||
No-write - disables actually writing data to the MCU (useful for debugging
|
No-write - disables actually writing data to the MCU (useful for debugging
|
||||||
.Nm avrdude
|
.Nm avrdude
|
||||||
).
|
).
|
||||||
.It Fl o Ar filename
|
.It Fl O
|
||||||
Specifies the name of the output file to write, and causes the respective
|
Perform a RC oscillator run-time calibration according to Atmel
|
||||||
memory area to be read from the MCU. Can be specified as
|
application note AVR053.
|
||||||
.Ql \&-
|
This is only supported on the STK500v2, AVRISP mkII, and JTAG ICE mkII
|
||||||
to write to
|
hardware.
|
||||||
.Em stdout .
|
Note that the result will be stored in the EEPROM cell at address 0.
|
||||||
.It Fl P Ar port
|
.It Fl P Ar port
|
||||||
Use
|
Use
|
||||||
.Ar port
|
.Ar port
|
||||||
@@ -307,11 +391,189 @@ serial port, the
|
|||||||
.Pa /dev/cuaa0
|
.Pa /dev/cuaa0
|
||||||
port is the default. If you need to use a different parallel or
|
port is the default. If you need to use a different parallel or
|
||||||
serial port, use this option to specify the alternate port name.
|
serial port, use this option to specify the alternate port name.
|
||||||
|
.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
|
.It Fl t
|
||||||
Tells
|
Tells
|
||||||
.Nm
|
.Nm
|
||||||
to enter the interactive ``terminal'' mode instead of up- or downloading
|
to enter the interactive ``terminal'' mode instead of up- or downloading
|
||||||
files. See below for a detailed description of the terminal mode.
|
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
|
.It Fl v
|
||||||
Enable verbose output.
|
Enable verbose output.
|
||||||
.It Fl V
|
.It Fl V
|
||||||
@@ -384,7 +646,56 @@ does not implement the command.
|
|||||||
.It Ar sig
|
.It Ar sig
|
||||||
Display the device signature bytes.
|
Display the device signature bytes.
|
||||||
.It Ar part
|
.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 vtarg voltage
|
||||||
|
Set the target's supply voltage to
|
||||||
|
.Ar voltage
|
||||||
|
Volts.
|
||||||
|
.Em Only supported on the STK500 programmer.
|
||||||
|
.It Ar varef 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.
|
||||||
|
.Em Only supported on the STK500 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 programmer.
|
||||||
|
.It Ar fosc off
|
||||||
|
Turn the master oscillator off.
|
||||||
|
.Em Only supported on the STK500 programmer.
|
||||||
|
.It Ar sck period
|
||||||
|
.Em STK500 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 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 \&?
|
||||||
.It Ar help
|
.It Ar help
|
||||||
Give a short on-line summary of the available commands.
|
Give a short on-line summary of the available commands.
|
||||||
@@ -406,6 +717,33 @@ ll.
|
|||||||
10 MISO (from MCU)
|
10 MISO (from MCU)
|
||||||
18-25 GND
|
18-25 GND
|
||||||
.TE
|
.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.
|
||||||
.Sh FILES
|
.Sh FILES
|
||||||
.Bl -tag -offset indent -width /dev/ppi0XXX
|
.Bl -tag -offset indent -width /dev/ppi0XXX
|
||||||
.It Pa /dev/ppi0
|
.It Pa /dev/ppi0
|
||||||
@@ -423,7 +761,31 @@ library
|
|||||||
Schematic of programming hardware
|
Schematic of programming hardware
|
||||||
.El
|
.El
|
||||||
.\" .Sh EXAMPLES
|
.\" .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
|
.Sh SEE ALSO
|
||||||
.Xr avr-objcopy 1 ,
|
.Xr avr-objcopy 1 ,
|
||||||
.Xr ppi 4 ,
|
.Xr ppi 4 ,
|
||||||
@@ -441,4 +803,20 @@ This man page by
|
|||||||
.ie t J\(:org Wunsch.
|
.ie t J\(:org Wunsch.
|
||||||
.el Joerg Wunsch.
|
.el Joerg Wunsch.
|
||||||
.Sh BUGS
|
.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 in parallel programming mode.
|
||||||
|
.Pp
|
||||||
|
The USBasp driver does not offer any option to distinguish multiple
|
||||||
|
devices connected simultaneously, so effectively only a single device
|
||||||
|
is supported.
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -5,6 +5,11 @@
|
|||||||
## @configure_input@
|
## @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.
|
Summary: AVRDUDE is software for programming Atmel AVR Microcontrollers.
|
||||||
Name: avrdude
|
Name: avrdude
|
||||||
Version: @VERSION@
|
Version: @VERSION@
|
||||||
@@ -18,12 +23,14 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-root
|
|||||||
%description
|
%description
|
||||||
AVRDUDE is software for programming Atmel AVR Microcontrollers.
|
AVRDUDE is software for programming Atmel AVR Microcontrollers.
|
||||||
|
|
||||||
|
%if %{_with_docs}
|
||||||
## The avrdude-docs subpackage
|
## The avrdude-docs subpackage
|
||||||
%package docs
|
%package docs
|
||||||
Summary: Documentation for AVRDUDE.
|
Summary: Documentation for AVRDUDE.
|
||||||
Group: Documentation
|
Group: Documentation
|
||||||
%description docs
|
%description docs
|
||||||
Documentation for avrdude in html, postscript and pdf formats.
|
Documentation for avrdude in info, html, postscript and pdf formats.
|
||||||
|
%endif
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
%setup -q
|
%setup -q
|
||||||
@@ -31,7 +38,12 @@ Documentation for avrdude in html, postscript and pdf formats.
|
|||||||
%build
|
%build
|
||||||
|
|
||||||
./configure --prefix=%{_prefix} --sysconfdir=/etc --mandir=%{_mandir} \
|
./configure --prefix=%{_prefix} --sysconfdir=/etc --mandir=%{_mandir} \
|
||||||
--infodir=%{_infodir}
|
--infodir=%{_infodir} \
|
||||||
|
%if %{_with_docs}
|
||||||
|
--enable-doc=yes
|
||||||
|
%else
|
||||||
|
--enable-doc=no
|
||||||
|
%endif
|
||||||
|
|
||||||
make
|
make
|
||||||
|
|
||||||
@@ -43,36 +55,54 @@ make prefix=$RPM_BUILD_ROOT%{_prefix} \
|
|||||||
infodir=$RPM_BUILD_ROOT%{_infodir} \
|
infodir=$RPM_BUILD_ROOT%{_infodir} \
|
||||||
install
|
install
|
||||||
|
|
||||||
|
rm -rf $RPM_BUILD_ROOT%{_datadir}/doc/%{name}-%{version}
|
||||||
|
rm -f $RPM_BUILD_ROOT%{_infodir}/dir
|
||||||
|
|
||||||
%clean
|
%clean
|
||||||
rm -rf $RPM_BUILD_ROOT
|
rm -rf $RPM_BUILD_ROOT
|
||||||
|
|
||||||
%post
|
%if %{_with_docs}
|
||||||
|
%post docs
|
||||||
[ -f %{_infodir}/avrdude.info ] && \
|
[ -f %{_infodir}/avrdude.info ] && \
|
||||||
/sbin/install-info %{_infodir}/avrdude.info %{_infodir}/dir || :
|
/sbin/install-info %{_infodir}/avrdude.info %{_infodir}/dir || :
|
||||||
[ -f %{_infodir}/avrdude.info.gz ] && \
|
[ -f %{_infodir}/avrdude.info.gz ] && \
|
||||||
/sbin/install-info %{_infodir}/avrdude.info.gz %{_infodir}/dir || :
|
/sbin/install-info %{_infodir}/avrdude.info.gz %{_infodir}/dir || :
|
||||||
|
|
||||||
%preun
|
%preun docs
|
||||||
if [ $1 = 0 ]; then
|
if [ $1 = 0 ]; then
|
||||||
[ -f %{_infodir}/avrdude.info ] && \
|
[ -f %{_infodir}/avrdude.info ] && \
|
||||||
/sbin/install-info --delete %{_infodir}/avrdude.info %{_infodir}/dir || :
|
/sbin/install-info --delete %{_infodir}/avrdude.info %{_infodir}/dir || :
|
||||||
[ -f %{_infodir}/avrdude.info.gz ] && \
|
[ -f %{_infodir}/avrdude.info.gz ] && \
|
||||||
/sbin/install-info --delete %{_infodir}/avrdude.info.gz %{_infodir}/dir || :
|
/sbin/install-info --delete %{_infodir}/avrdude.info.gz %{_infodir}/dir || :
|
||||||
fi
|
fi
|
||||||
|
%endif
|
||||||
|
|
||||||
%files
|
%files
|
||||||
%defattr(-,root,root)
|
%defattr(-,root,root)
|
||||||
%{_prefix}/bin/avrdude
|
%{_prefix}/bin/avrdude
|
||||||
%{_mandir}/man1/avrdude.1.gz
|
%{_mandir}/man1/avrdude.1.gz
|
||||||
%{_infodir}/*info*
|
|
||||||
%attr(0644,root,root) %config /etc/avrdude.conf
|
%attr(0644,root,root) %config /etc/avrdude.conf
|
||||||
|
|
||||||
|
%if %{_with_docs}
|
||||||
%files 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.ps
|
||||||
%doc doc/avrdude.pdf
|
%doc doc/avrdude.pdf
|
||||||
|
%endif
|
||||||
|
|
||||||
%changelog
|
%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>
|
* Wed Mar 05 2003 Theodore A. Roth <troth@openavr.org>
|
||||||
- Add docs sub-package.
|
- Add docs sub-package.
|
||||||
- Add %post and %preun scriptlets for handling info files.
|
- Add %post and %preun scriptlets for handling info files.
|
||||||
|
|||||||
541
avrdude/avrpart.c
Normal file
541
avrdude/avrpart.c
Normal file
@@ -0,0 +1,541 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* 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 "avrpart.h"
|
||||||
|
#include "pindefs.h"
|
||||||
|
|
||||||
|
extern char * progname;
|
||||||
|
|
||||||
|
|
||||||
|
/***
|
||||||
|
*** 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void list_parts(FILE * f, char * prefix, LISTID parts)
|
||||||
|
{
|
||||||
|
LNODEID ln1;
|
||||||
|
AVRPART * p;
|
||||||
|
|
||||||
|
for (ln1=lfirst(parts); ln1; ln1=lnext(ln1)) {
|
||||||
|
p = ldata(ln1);
|
||||||
|
fprintf(f, "%s%-4s = %-15s [%s:%d]\n",
|
||||||
|
prefix, p->id, p->desc, p->config_file, p->lineno);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char * reset_disp_str(int r)
|
||||||
|
{
|
||||||
|
switch (r) {
|
||||||
|
case RESET_DEDICATED : return "dedicated";
|
||||||
|
case RESET_IO : return "possible i/o";
|
||||||
|
default : return "<invalid>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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, char * prefix, int verbose)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char * buf;
|
||||||
|
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
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -26,6 +27,9 @@
|
|||||||
|
|
||||||
#include "lists.h"
|
#include "lists.h"
|
||||||
|
|
||||||
|
|
||||||
|
extern LISTID part_list;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AVR serial programming instructions
|
* AVR serial programming instructions
|
||||||
*/
|
*/
|
||||||
@@ -38,6 +42,7 @@ enum {
|
|||||||
AVR_OP_WRITE_HI,
|
AVR_OP_WRITE_HI,
|
||||||
AVR_OP_LOADPAGE_LO,
|
AVR_OP_LOADPAGE_LO,
|
||||||
AVR_OP_LOADPAGE_HI,
|
AVR_OP_LOADPAGE_HI,
|
||||||
|
AVR_OP_LOAD_EXT_ADDR,
|
||||||
AVR_OP_WRITEPAGE,
|
AVR_OP_WRITEPAGE,
|
||||||
AVR_OP_CHIP_ERASE,
|
AVR_OP_CHIP_ERASE,
|
||||||
AVR_OP_PGM_ENABLE,
|
AVR_OP_PGM_ENABLE,
|
||||||
@@ -58,6 +63,12 @@ enum { /* these are assigned to reset_disposition of AVRPART */
|
|||||||
RESET_IO /* reset pin might be configured as an I/O pin */
|
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
|
* serial programming instruction bit specifications
|
||||||
*/
|
*/
|
||||||
@@ -75,21 +86,70 @@ typedef struct opcode {
|
|||||||
#define AVRPART_SERIALOK 0x0001 /* part supports serial programming */
|
#define AVRPART_SERIALOK 0x0001 /* part supports serial programming */
|
||||||
#define AVRPART_PARALLELOK 0x0002 /* part supports parallel programming */
|
#define AVRPART_PARALLELOK 0x0002 /* part supports parallel programming */
|
||||||
#define AVRPART_PSEUDOPARALLEL 0x0004 /* part has pseudo parallel support */
|
#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 AVR_DESCLEN 64
|
#define AVR_DESCLEN 64
|
||||||
#define AVR_IDLEN 32
|
#define AVR_IDLEN 32
|
||||||
|
#define CTL_STACK_SIZE 32
|
||||||
|
#define FLASH_INSTR_SIZE 3
|
||||||
|
#define EEPROM_INSTR_SIZE 20
|
||||||
typedef struct avrpart {
|
typedef struct avrpart {
|
||||||
char desc[AVR_DESCLEN]; /* long part name */
|
char desc[AVR_DESCLEN]; /* long part name */
|
||||||
char id[AVR_IDLEN]; /* short 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 */
|
int chip_erase_delay; /* microseconds */
|
||||||
unsigned char pagel; /* for parallel programming */
|
unsigned char pagel; /* for parallel programming */
|
||||||
unsigned char bs2; /* 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 reset_disposition; /* see RESET_ enums */
|
||||||
int retry_pulse; /* retry program enable by pulsing
|
int retry_pulse; /* retry program enable by pulsing
|
||||||
this pin (PIN_AVR_*) */
|
this pin (PIN_AVR_*) */
|
||||||
unsigned flags; /* see AVRPART_ masks */
|
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 */
|
||||||
|
|
||||||
OPCODE * op[AVR_OP_MAX]; /* opcodes */
|
OPCODE * op[AVR_OP_MAX]; /* opcodes */
|
||||||
|
|
||||||
LISTID mem; /* avr memory definitions */
|
LISTID mem; /* avr memory definitions */
|
||||||
@@ -111,8 +171,38 @@ typedef struct avrmem {
|
|||||||
back on, see errata
|
back on, see errata
|
||||||
http://www.atmel.com/atmel/acrobat/doc1280.pdf */
|
http://www.atmel.com/atmel/acrobat/doc1280.pdf */
|
||||||
unsigned char readback[2]; /* polled read-back values */
|
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 */
|
unsigned char * buf; /* pointer to memory buffer */
|
||||||
OPCODE * op[AVR_OP_MAX]; /* opcodes */
|
OPCODE * op[AVR_OP_MAX]; /* opcodes */
|
||||||
} AVRMEM;
|
} AVRMEM;
|
||||||
|
|
||||||
|
/* 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(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 list_parts(FILE * f, char * prefix, LISTID parts);
|
||||||
|
void avr_display(FILE * f, AVRPART * p, char * prefix, int verbose);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
364
avrdude/bitbang.c
Normal file
364
avrdude/bitbang.c
Normal file
@@ -0,0 +1,364 @@
|
|||||||
|
/*
|
||||||
|
* 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 "avr.h"
|
||||||
|
#include "pindefs.h"
|
||||||
|
#include "pgm.h"
|
||||||
|
#include "par.h"
|
||||||
|
#include "serbb.h"
|
||||||
|
|
||||||
|
extern char * progname;
|
||||||
|
extern int do_cycles;
|
||||||
|
extern int verbose;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
46
avrdude/bitbang.h
Normal file
46
avrdude/bitbang.h
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
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_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);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
|
|
||||||
# autoconf-2.57 is required
|
# autoconf-2.59 is required
|
||||||
|
|
||||||
: ${AUTOHEADER="autoheader${AC_VER}"}
|
: ${AUTOHEADER="autoheader${AC_VER}"}
|
||||||
: ${AUTOCONF="autoconf${AC_VER}"}
|
: ${AUTOCONF="autoconf${AC_VER}"}
|
||||||
|
|
||||||
# automake-1.7.x is required
|
# automake-1.9.x is required
|
||||||
|
|
||||||
: ${ACLOCAL="aclocal${AM_VER}"}
|
: ${ACLOCAL="aclocal${AM_VER}"}
|
||||||
: ${AUTOMAKE="automake${AM_VER}"}
|
: ${AUTOMAKE="automake${AM_VER}"}
|
||||||
@@ -14,9 +14,9 @@
|
|||||||
|
|
||||||
AUTOCONF_VER=`(${AUTOCONF} --version 2>/dev/null | head -n 1 | \
|
AUTOCONF_VER=`(${AUTOCONF} --version 2>/dev/null | head -n 1 | \
|
||||||
cut -d ' ' -f 4) 2>/dev/null`
|
cut -d ' ' -f 4) 2>/dev/null`
|
||||||
if [ "$AUTOCONF_VER" != "2.57" ]
|
if [ "$AUTOCONF_VER" != "2.59" ]
|
||||||
then
|
then
|
||||||
echo "You need to use autoconf version 2.57."
|
echo "You need to use autoconf version 2.59."
|
||||||
echo "You are using `${AUTOCONF} --version | head -n 1`."
|
echo "You are using `${AUTOCONF} --version | head -n 1`."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
@@ -25,9 +25,9 @@ fi
|
|||||||
|
|
||||||
AUTOMAKE_VER=`(${AUTOMAKE} --version | head -n 1 | \
|
AUTOMAKE_VER=`(${AUTOMAKE} --version | head -n 1 | \
|
||||||
cut -d ' ' -f 4 | cut -d '.' -f -2) 2>/dev/null`
|
cut -d ' ' -f 4 | cut -d '.' -f -2) 2>/dev/null`
|
||||||
if [ "$AUTOMAKE_VER" != "1.7" ]
|
if [ "$AUTOMAKE_VER" != "1.9" ]
|
||||||
then
|
then
|
||||||
echo "You need to use automake version 1.7 (preferrably 1.7.3)."
|
echo "You need to use automake version 1.9."
|
||||||
echo "You are using `${AUTOMAKE} --version | head -n 1`."
|
echo "You are using `${AUTOMAKE} --version | head -n 1`."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
@@ -38,6 +38,8 @@ export ACLOCAL AUTOHEADER AUTOCONF AUTOMAKE
|
|||||||
|
|
||||||
set -x
|
set -x
|
||||||
|
|
||||||
|
rm -rf autom4te.cache
|
||||||
|
|
||||||
${ACLOCAL}
|
${ACLOCAL}
|
||||||
${AUTOHEADER}
|
${AUTOHEADER}
|
||||||
${AUTOCONF}
|
${AUTOCONF}
|
||||||
|
|||||||
677
avrdude/butterfly.c
Normal file
677
avrdude/butterfly.c
Normal file
@@ -0,0 +1,677 @@
|
|||||||
|
/*
|
||||||
|
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||||
|
* Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org>
|
||||||
|
* 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$ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 "avr.h"
|
||||||
|
#include "pgm.h"
|
||||||
|
#include "butterfly.h"
|
||||||
|
#include "serial.h"
|
||||||
|
|
||||||
|
extern char * progname;
|
||||||
|
extern int do_cycles;
|
||||||
|
|
||||||
|
static char has_auto_incr_addr;
|
||||||
|
static unsigned buffersize = 0;
|
||||||
|
|
||||||
|
/* These two defines are only for debugging. Will remove them once it starts
|
||||||
|
working. */
|
||||||
|
|
||||||
|
#define show_func_info() \
|
||||||
|
fprintf(stderr, "%s: line %d: called %s()\n", \
|
||||||
|
__FILE__, __LINE__, __FUNCTION__)
|
||||||
|
|
||||||
|
#define no_show_func_info()
|
||||||
|
|
||||||
|
|
||||||
|
static int butterfly_send(PROGRAMMER * pgm, char * buf, size_t len)
|
||||||
|
{
|
||||||
|
no_show_func_info();
|
||||||
|
|
||||||
|
return serial_send(&pgm->fd, (unsigned char *)buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int butterfly_recv(PROGRAMMER * pgm, char * buf, size_t len)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
no_show_func_info();
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
no_show_func_info();
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
no_show_func_info();
|
||||||
|
|
||||||
|
/* Do nothing. */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int butterfly_err_led(PROGRAMMER * pgm, int value)
|
||||||
|
{
|
||||||
|
no_show_func_info();
|
||||||
|
|
||||||
|
/* Do nothing. */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int butterfly_pgm_led(PROGRAMMER * pgm, int value)
|
||||||
|
{
|
||||||
|
no_show_func_info();
|
||||||
|
|
||||||
|
/* Do nothing. */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int butterfly_vfy_led(PROGRAMMER * pgm, int value)
|
||||||
|
{
|
||||||
|
no_show_func_info();
|
||||||
|
|
||||||
|
/* Do nothing. */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* issue the 'chip erase' command to the butterfly board
|
||||||
|
*/
|
||||||
|
static int butterfly_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
||||||
|
{
|
||||||
|
no_show_func_info();
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
no_show_func_info();
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* apply power to the AVR processor
|
||||||
|
*/
|
||||||
|
static void butterfly_powerup(PROGRAMMER * pgm)
|
||||||
|
{
|
||||||
|
no_show_func_info();
|
||||||
|
|
||||||
|
/* Do nothing. */
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* remove power from the AVR processor
|
||||||
|
*/
|
||||||
|
static void butterfly_powerdown(PROGRAMMER * pgm)
|
||||||
|
{
|
||||||
|
no_show_func_info();
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
|
||||||
|
no_show_func_info();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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, &has_auto_incr_addr, 1);
|
||||||
|
if (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);
|
||||||
|
buffersize = (unsigned int)(unsigned char)c<<8;
|
||||||
|
butterfly_recv(pgm, &c, 1);
|
||||||
|
buffersize += (unsigned int)(unsigned char)c;
|
||||||
|
fprintf(stderr,
|
||||||
|
"Programmer supports buffered memory access with buffersize=%i bytes.\n",
|
||||||
|
buffersize);
|
||||||
|
|
||||||
|
/* Get list of devices that the programmer supports. */
|
||||||
|
|
||||||
|
butterfly_send(pgm, "t", 1);
|
||||||
|
fprintf(stderr, "\nProgrammer supports the following devices:\n");
|
||||||
|
while (1) {
|
||||||
|
butterfly_recv(pgm, &c, 1);
|
||||||
|
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. */
|
||||||
|
|
||||||
|
buf[0] = 'T';
|
||||||
|
buf[1] = p->avr910_devcode;
|
||||||
|
|
||||||
|
butterfly_send(pgm, buf, 2);
|
||||||
|
butterfly_vfy_cmd_sent(pgm, "select device");
|
||||||
|
|
||||||
|
butterfly_enter_prog_mode(pgm);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void butterfly_disable(PROGRAMMER * pgm)
|
||||||
|
{
|
||||||
|
no_show_func_info();
|
||||||
|
|
||||||
|
butterfly_leave_prog_mode(pgm);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void butterfly_enable(PROGRAMMER * pgm)
|
||||||
|
{
|
||||||
|
no_show_func_info();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int butterfly_open(PROGRAMMER * pgm, char * port)
|
||||||
|
{
|
||||||
|
no_show_func_info();
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
no_show_func_info();
|
||||||
|
|
||||||
|
/* "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, char * p)
|
||||||
|
{
|
||||||
|
no_show_func_info();
|
||||||
|
|
||||||
|
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 int butterfly_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||||
|
unsigned long addr, unsigned char value)
|
||||||
|
{
|
||||||
|
char cmd[6];
|
||||||
|
int size;
|
||||||
|
|
||||||
|
no_show_func_info();
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (cached && ((caddr + 1) == addr)) {
|
||||||
|
*value = cvalue;
|
||||||
|
cached = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
char buf[2];
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
no_show_func_info();
|
||||||
|
|
||||||
|
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 = buffersize;
|
||||||
|
|
||||||
|
if (strcmp(m->desc, "flash") && strcmp(m->desc, "eeprom"))
|
||||||
|
return -2;
|
||||||
|
|
||||||
|
if (m->desc[0] == 'e')
|
||||||
|
blocksize = 1; /* Write to eeprom single bytes only */
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/* 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 = buffersize;
|
||||||
|
|
||||||
|
cmd[0] = 'g';
|
||||||
|
cmd[3] = toupper(m->desc[0]);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
no_show_func_info();
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
no_show_func_info();
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
27
avrdude/butterfly.h
Normal file
27
avrdude/butterfly.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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__
|
||||||
|
|
||||||
|
void butterfly_initpgm (PROGRAMMER * pgm);
|
||||||
|
|
||||||
|
#endif /* __butterfly_h__ */
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -41,14 +41,13 @@ typedef struct token_t {
|
|||||||
int primary;
|
int primary;
|
||||||
VALUE value;
|
VALUE value;
|
||||||
} TOKEN;
|
} TOKEN;
|
||||||
|
typedef struct token_t *token_p;
|
||||||
|
|
||||||
|
|
||||||
extern FILE * yyin;
|
extern FILE * yyin;
|
||||||
extern PROGRAMMER * current_prog;
|
extern PROGRAMMER * current_prog;
|
||||||
extern AVRPART * current_part;
|
extern AVRPART * current_part;
|
||||||
extern AVRMEM * current_mem;
|
extern AVRMEM * current_mem;
|
||||||
extern LISTID programmers;
|
|
||||||
extern LISTID part_list;
|
|
||||||
extern int lineno;
|
extern int lineno;
|
||||||
extern char * infile;
|
extern char * infile;
|
||||||
extern LISTID string_list;
|
extern LISTID string_list;
|
||||||
@@ -60,7 +59,7 @@ extern char default_serial[];
|
|||||||
|
|
||||||
|
|
||||||
#if !defined(HAS_YYSTYPE)
|
#if !defined(HAS_YYSTYPE)
|
||||||
#define YYSTYPE struct token_t *
|
#define YYSTYPE token_p
|
||||||
#endif
|
#endif
|
||||||
extern YYSTYPE yylval;
|
extern YYSTYPE yylval;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -29,18 +30,31 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "lists.h"
|
#include "lists.h"
|
||||||
#include "par.h"
|
#include "par.h"
|
||||||
|
#include "serbb.h"
|
||||||
#include "pindefs.h"
|
#include "pindefs.h"
|
||||||
#include "ppi.h"
|
#include "ppi.h"
|
||||||
#include "pgm.h"
|
#include "pgm.h"
|
||||||
#include "stk500.h"
|
#include "stk500.h"
|
||||||
|
#include "stk500v2.h"
|
||||||
|
#include "stk500generic.h"
|
||||||
|
#include "avr910.h"
|
||||||
|
#include "butterfly.h"
|
||||||
|
#include "usbasp.h"
|
||||||
#include "avr.h"
|
#include "avr.h"
|
||||||
|
#include "jtagmkI.h"
|
||||||
|
#include "jtagmkII.h"
|
||||||
|
|
||||||
|
#if defined(WIN32NATIVE)
|
||||||
|
#define strtok_r( _s, _sep, _lasts ) \
|
||||||
|
( *(_lasts) = strtok( (_s), (_sep) ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
extern char * progname;
|
extern char * progname;
|
||||||
|
|
||||||
int yylex(void);
|
int yylex(void);
|
||||||
int yyerror(char * errmsg);
|
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 which_opcode(TOKEN * opcode);
|
||||||
static int parse_cmdbits(OPCODE * op);
|
static int parse_cmdbits(OPCODE * op);
|
||||||
|
|
||||||
@@ -54,6 +68,7 @@ static int parse_cmdbits(OPCODE * op);
|
|||||||
%token K_WRITE_HI
|
%token K_WRITE_HI
|
||||||
%token K_LOADPAGE_LO
|
%token K_LOADPAGE_LO
|
||||||
%token K_LOADPAGE_HI
|
%token K_LOADPAGE_HI
|
||||||
|
%token K_LOAD_EXT_ADDR
|
||||||
%token K_WRITEPAGE
|
%token K_WRITEPAGE
|
||||||
%token K_CHIP_ERASE
|
%token K_CHIP_ERASE
|
||||||
%token K_PGM_ENABLE
|
%token K_PGM_ENABLE
|
||||||
@@ -63,6 +78,7 @@ static int parse_cmdbits(OPCODE * op);
|
|||||||
%token K_PAGE_SIZE
|
%token K_PAGE_SIZE
|
||||||
%token K_PAGED
|
%token K_PAGED
|
||||||
|
|
||||||
|
%token K_BAUDRATE
|
||||||
%token K_BS2
|
%token K_BS2
|
||||||
%token K_BUFF
|
%token K_BUFF
|
||||||
%token K_CHIP_ERASE_DELAY
|
%token K_CHIP_ERASE_DELAY
|
||||||
@@ -72,11 +88,22 @@ static int parse_cmdbits(OPCODE * op);
|
|||||||
%token K_DEFAULT_SERIAL
|
%token K_DEFAULT_SERIAL
|
||||||
%token K_DESC
|
%token K_DESC
|
||||||
%token K_DEVICECODE
|
%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_EEPROM
|
||||||
%token K_ERRLED
|
%token K_ERRLED
|
||||||
%token K_FLASH
|
%token K_FLASH
|
||||||
%token K_ID
|
%token K_ID
|
||||||
%token K_IO
|
%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_LOADPAGE
|
||||||
%token K_MAX_WRITE_DELAY
|
%token K_MAX_WRITE_DELAY
|
||||||
%token K_MIN_WRITE_DELAY
|
%token K_MIN_WRITE_DELAY
|
||||||
@@ -97,10 +124,19 @@ static int parse_cmdbits(OPCODE * op);
|
|||||||
%token K_READMEM
|
%token K_READMEM
|
||||||
%token K_RESET
|
%token K_RESET
|
||||||
%token K_RETRY_PULSE
|
%token K_RETRY_PULSE
|
||||||
|
%token K_SERBB
|
||||||
%token K_SERIAL
|
%token K_SERIAL
|
||||||
%token K_SCK
|
%token K_SCK
|
||||||
|
%token K_SIGNATURE
|
||||||
%token K_SIZE
|
%token K_SIZE
|
||||||
%token K_STK500
|
%token K_STK500
|
||||||
|
%token K_STK500HVSP
|
||||||
|
%token K_STK500PP
|
||||||
|
%token K_STK500V2
|
||||||
|
%token K_STK500GENERIC
|
||||||
|
%token K_AVR910
|
||||||
|
%token K_USBASP
|
||||||
|
%token K_BUTTERFLY
|
||||||
%token K_TYPE
|
%token K_TYPE
|
||||||
%token K_VCC
|
%token K_VCC
|
||||||
%token K_VFYLED
|
%token K_VFYLED
|
||||||
@@ -109,9 +145,69 @@ static int parse_cmdbits(OPCODE * op);
|
|||||||
%token K_NO
|
%token K_NO
|
||||||
%token K_YES
|
%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_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_COMMA
|
||||||
%token TKN_EQUAL
|
%token TKN_EQUAL
|
||||||
%token TKN_SEMI
|
%token TKN_SEMI
|
||||||
|
%token TKN_TILDE
|
||||||
%token TKN_NUMBER
|
%token TKN_NUMBER
|
||||||
%token TKN_STRING
|
%token TKN_STRING
|
||||||
%token TKN_ID
|
%token TKN_ID
|
||||||
@@ -278,12 +374,114 @@ prog_parm :
|
|||||||
}
|
}
|
||||||
} |
|
} |
|
||||||
|
|
||||||
|
K_TYPE TKN_EQUAL K_SERBB {
|
||||||
|
{
|
||||||
|
serbb_initpgm(current_prog);
|
||||||
|
}
|
||||||
|
} |
|
||||||
|
|
||||||
K_TYPE TKN_EQUAL K_STK500 {
|
K_TYPE TKN_EQUAL K_STK500 {
|
||||||
{
|
{
|
||||||
stk500_initpgm(current_prog);
|
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_AVR910 {
|
||||||
|
{
|
||||||
|
avr910_initpgm(current_prog);
|
||||||
|
}
|
||||||
|
} |
|
||||||
|
|
||||||
|
K_TYPE TKN_EQUAL K_USBASP {
|
||||||
|
{
|
||||||
|
usbasp_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 {
|
K_DESC TKN_EQUAL TKN_STRING {
|
||||||
strncpy(current_prog->desc, $3->value.string, PGM_DESCLEN);
|
strncpy(current_prog->desc, $3->value.string, PGM_DESCLEN);
|
||||||
current_prog->desc[PGM_DESCLEN-1] = 0;
|
current_prog->desc[PGM_DESCLEN-1] = 0;
|
||||||
@@ -300,15 +498,7 @@ prog_parm :
|
|||||||
while (lsize(number_list)) {
|
while (lsize(number_list)) {
|
||||||
t = lrmv_n(number_list, 1);
|
t = lrmv_n(number_list, 1);
|
||||||
pin = t->value.number;
|
pin = t->value.number;
|
||||||
if ((pin < 2) || (pin > 9)) {
|
current_prog->pinno[PPI_AVR_VCC] |= (1 << pin);
|
||||||
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));
|
|
||||||
|
|
||||||
free_token(t);
|
free_token(t);
|
||||||
}
|
}
|
||||||
@@ -325,31 +515,40 @@ prog_parm :
|
|||||||
while (lsize(number_list)) {
|
while (lsize(number_list)) {
|
||||||
t = lrmv_n(number_list, 1);
|
t = lrmv_n(number_list, 1);
|
||||||
pin = t->value.number;
|
pin = t->value.number;
|
||||||
if ((pin < 2) || (pin > 9)) {
|
current_prog->pinno[PPI_AVR_BUFF] |= (1 << pin);
|
||||||
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));
|
|
||||||
|
|
||||||
free_token(t);
|
free_token(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} |
|
} |
|
||||||
|
|
||||||
|
K_BAUDRATE TKN_EQUAL TKN_NUMBER {
|
||||||
|
{
|
||||||
|
current_prog->baudrate = $3->value.number;
|
||||||
|
}
|
||||||
|
} |
|
||||||
|
|
||||||
K_RESET TKN_EQUAL TKN_NUMBER { free_token($1);
|
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);
|
K_SCK TKN_EQUAL TKN_NUMBER { free_token($1);
|
||||||
assign_pin(PIN_AVR_SCK, $3); } |
|
assign_pin(PIN_AVR_SCK, $3, 0); } |
|
||||||
K_MOSI TKN_EQUAL TKN_NUMBER { assign_pin(PIN_AVR_MOSI, $3); } |
|
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); } |
|
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); } |
|
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); } |
|
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); } |
|
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); }
|
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 +561,7 @@ opcode :
|
|||||||
K_WRITE_HI |
|
K_WRITE_HI |
|
||||||
K_LOADPAGE_LO |
|
K_LOADPAGE_LO |
|
||||||
K_LOADPAGE_HI |
|
K_LOADPAGE_HI |
|
||||||
|
K_LOAD_EXT_ADDR |
|
||||||
K_WRITEPAGE |
|
K_WRITEPAGE |
|
||||||
K_CHIP_ERASE |
|
K_CHIP_ERASE |
|
||||||
K_PGM_ENABLE
|
K_PGM_ENABLE
|
||||||
@@ -403,11 +603,187 @@ part_parm :
|
|||||||
|
|
||||||
K_DEVICECODE TKN_EQUAL TKN_NUMBER {
|
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);
|
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
|
K_CHIP_ERASE_DELAY TKN_EQUAL TKN_NUMBER
|
||||||
{
|
{
|
||||||
current_part->chip_erase_delay = $3->value.number;
|
current_part->chip_erase_delay = $3->value.number;
|
||||||
@@ -436,6 +812,238 @@ part_parm :
|
|||||||
free_tokens(2, $1, $3);
|
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_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_SERIAL TKN_EQUAL yesno
|
K_SERIAL TKN_EQUAL yesno
|
||||||
{
|
{
|
||||||
if ($3->primary == K_YES)
|
if ($3->primary == K_YES)
|
||||||
@@ -583,6 +1191,38 @@ mem_spec :
|
|||||||
free_token($3);
|
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 {
|
opcode TKN_EQUAL string_list {
|
||||||
{
|
{
|
||||||
int opnum;
|
int opnum;
|
||||||
@@ -614,7 +1254,7 @@ static char * vtypestr(int type)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static int assign_pin(int pinno, TOKEN * v)
|
static int assign_pin(int pinno, TOKEN * v, int invert)
|
||||||
{
|
{
|
||||||
int value;
|
int value;
|
||||||
|
|
||||||
@@ -627,6 +1267,8 @@ static int assign_pin(int pinno, TOKEN * v)
|
|||||||
progname, lineno, infile);
|
progname, lineno, infile);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
if (invert)
|
||||||
|
value |= PIN_INVERSE;
|
||||||
|
|
||||||
current_prog->pinno[pinno] = value;
|
current_prog->pinno[pinno] = value;
|
||||||
|
|
||||||
@@ -645,6 +1287,7 @@ static int which_opcode(TOKEN * opcode)
|
|||||||
case K_WRITE_HI : return AVR_OP_WRITE_HI; break;
|
case K_WRITE_HI : return AVR_OP_WRITE_HI; break;
|
||||||
case K_LOADPAGE_LO : return AVR_OP_LOADPAGE_LO; break;
|
case K_LOADPAGE_LO : return AVR_OP_LOADPAGE_LO; break;
|
||||||
case K_LOADPAGE_HI : return AVR_OP_LOADPAGE_HI; 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_WRITEPAGE : return AVR_OP_WRITEPAGE; break;
|
||||||
case K_CHIP_ERASE : return AVR_OP_CHIP_ERASE; break;
|
case K_CHIP_ERASE : return AVR_OP_CHIP_ERASE; break;
|
||||||
case K_PGM_ENABLE : return AVR_OP_PGM_ENABLE; break;
|
case K_PGM_ENABLE : return AVR_OP_PGM_ENABLE; break;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#
|
#
|
||||||
# avrdude - A Downloader/Uploader for AVR device programmers
|
# 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
|
# 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
|
# 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.
|
# Process this file with autoconf to produce a configure script.
|
||||||
|
|
||||||
AC_PREREQ(2.57)
|
AC_PREREQ(2.57)
|
||||||
AC_INIT(avrdude, 4.0.0, avrdude-dev@nongnu.org)
|
AC_INIT(avrdude, 5.3.1, avrdude-dev@nongnu.org)
|
||||||
|
|
||||||
AC_CANONICAL_BUILD
|
AC_CANONICAL_BUILD
|
||||||
AC_CANONICAL_HOST
|
AC_CANONICAL_HOST
|
||||||
@@ -32,7 +32,7 @@ AC_CANONICAL_TARGET
|
|||||||
|
|
||||||
AC_CONFIG_SRCDIR([main.c])
|
AC_CONFIG_SRCDIR([main.c])
|
||||||
AM_INIT_AUTOMAKE
|
AM_INIT_AUTOMAKE
|
||||||
AM_CONFIG_HEADER([ac_cfg.h])
|
AM_CONFIG_HEADER(ac_cfg.h)
|
||||||
|
|
||||||
# Checks for programs.
|
# Checks for programs.
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
@@ -42,11 +42,67 @@ AM_PROG_LEX
|
|||||||
|
|
||||||
# Checks for libraries.
|
# Checks for libraries.
|
||||||
AC_CHECK_LIB([termcap], [tputs])
|
AC_CHECK_LIB([termcap], [tputs])
|
||||||
|
AC_CHECK_LIB([ncurses], [tputs])
|
||||||
AC_CHECK_LIB([readline], [readline])
|
AC_CHECK_LIB([readline], [readline])
|
||||||
|
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)
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([for a Win32 HID libray])
|
||||||
|
SAVED_LIBS="${LIBS}"
|
||||||
|
case $target in
|
||||||
|
*-*-mingw32*)
|
||||||
|
LIBHID="-lhid -lsetupapi"
|
||||||
|
HIDINCLUDE="#include <ddk/hidsdi.h>"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
LIBHID="-lhid"
|
||||||
|
HIDINCLUDE='#include "my_ddk_hidsdi.h"'
|
||||||
|
;;
|
||||||
|
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}"
|
||||||
|
|
||||||
# Checks for header files.
|
# Checks for header files.
|
||||||
AC_HEADER_STDC
|
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.
|
# Checks for typedefs, structures, and compiler characteristics.
|
||||||
AC_C_CONST
|
AC_C_CONST
|
||||||
@@ -55,7 +111,7 @@ AC_HEADER_TIME
|
|||||||
# Checks for library functions.
|
# Checks for library functions.
|
||||||
AC_PROG_GCC_TRADITIONAL
|
AC_PROG_GCC_TRADITIONAL
|
||||||
AC_FUNC_MALLOC
|
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])
|
||||||
|
|
||||||
# Checks for misc stuff.
|
# Checks for misc stuff.
|
||||||
|
|
||||||
@@ -77,12 +133,49 @@ else
|
|||||||
DOC_INST_DIR='$(DESTDIR)$(datadir)/doc/avrdude'
|
DOC_INST_DIR='$(DESTDIR)$(datadir)/doc/avrdude'
|
||||||
fi
|
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])
|
||||||
|
|
||||||
|
if test "$enabled_doc" = "yes"; then
|
||||||
|
|
||||||
|
SUBDIRS_AC='doc @WINDOWS_DIRS@'
|
||||||
|
DIST_SUBDIRS_AC='doc windows'
|
||||||
|
else
|
||||||
|
|
||||||
|
SUBDIRS_AC='@WINDOWS_DIRS@'
|
||||||
|
DIST_SUBDIRS_AC='windows'
|
||||||
|
fi
|
||||||
|
|
||||||
AC_SUBST(DOC_INST_DIR, $DOC_INST_DIR)
|
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
|
# Find the parallel serial device files based on target system
|
||||||
# If a system doesn't have a PC style parallel, mark it as unknown.
|
# If a system doesn't have a PC style parallel, mark it as unknown.
|
||||||
case $target in
|
case $target in
|
||||||
i[[3456]]86-*-linux*)
|
i[[3456]]86-*-linux*|x86_64-*-linux*)
|
||||||
DEFAULT_PAR_PORT="/dev/parport0"
|
DEFAULT_PAR_PORT="/dev/parport0"
|
||||||
DEFAULT_SER_PORT="/dev/ttyS0"
|
DEFAULT_SER_PORT="/dev/ttyS0"
|
||||||
;;
|
;;
|
||||||
@@ -90,7 +183,7 @@ case $target in
|
|||||||
DEFAULT_PAR_PORT="unknown"
|
DEFAULT_PAR_PORT="unknown"
|
||||||
DEFAULT_SER_PORT="/dev/ttyS0"
|
DEFAULT_SER_PORT="/dev/ttyS0"
|
||||||
;;
|
;;
|
||||||
i[[3456]]86-*-freebsd*)
|
i[[3456]]86-*-freebsd*|amd64-*-freebsd*)
|
||||||
DEFAULT_PAR_PORT="/dev/ppi0"
|
DEFAULT_PAR_PORT="/dev/ppi0"
|
||||||
DEFAULT_SER_PORT="/dev/cuaa0"
|
DEFAULT_SER_PORT="/dev/cuaa0"
|
||||||
;;
|
;;
|
||||||
@@ -98,6 +191,10 @@ case $target in
|
|||||||
DEFAULT_PAR_PORT="unknown"
|
DEFAULT_PAR_PORT="unknown"
|
||||||
DEFAULT_SER_PORT="/dev/cuaa0"
|
DEFAULT_SER_PORT="/dev/cuaa0"
|
||||||
;;
|
;;
|
||||||
|
*-*-solaris*)
|
||||||
|
DEFAULT_PAR_PORT="/dev/printers/0"
|
||||||
|
DEFAULT_SER_PORT="/dev/term/a"
|
||||||
|
;;
|
||||||
*-*-msdos* | *-*-mingw32* | *-*-cygwin* | *-*-windows*)
|
*-*-msdos* | *-*-mingw32* | *-*-cygwin* | *-*-windows*)
|
||||||
DEFAULT_PAR_PORT="lpt1"
|
DEFAULT_PAR_PORT="lpt1"
|
||||||
DEFAULT_SER_PORT="com1"
|
DEFAULT_SER_PORT="com1"
|
||||||
@@ -108,27 +205,63 @@ case $target in
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
AC_MSG_CHECKING([for parallel device])
|
if test "$enabled_parport" = "yes"; then
|
||||||
AC_MSG_RESULT([$DEFAULT_PAR_PORT])
|
AC_MSG_CHECKING([for parallel device])
|
||||||
AC_SUBST(DEFAULT_PAR_PORT, $DEFAULT_PAR_PORT)
|
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_CHECKING([for serial device])
|
||||||
AC_MSG_RESULT([$DEFAULT_SER_PORT])
|
AC_MSG_RESULT([$DEFAULT_SER_PORT])
|
||||||
AC_SUBST(DEFAULT_SER_PORT, $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.
|
# See if we need to drop into the windows subdir.
|
||||||
case $target in
|
case $target in
|
||||||
*-*-mingw32* | *-*-cygwin* | *-*-windows*)
|
*-*-mingw32* | *-*-cygwin* | *-*-windows*)
|
||||||
WINDOWS_DIRS="windows"
|
WINDOWS_DIRS="windows"
|
||||||
|
CFLAGS="-mno-cygwin -DWIN32NATIVE"
|
||||||
|
LDFLAGS="${LDFLAGS} -static"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
AC_SUBST(WINDOWS_DIRS,$WINDOWS_DIRS)
|
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)
|
||||||
|
|
||||||
|
if test "$enabled_doc" = "yes"; then
|
||||||
|
AC_CONFIG_FILES([doc/Makefile])
|
||||||
|
fi
|
||||||
|
|
||||||
AC_CONFIG_FILES([
|
AC_CONFIG_FILES([
|
||||||
doc/Makefile
|
windows/Makefile
|
||||||
windows/Makefile
|
avrdude.spec
|
||||||
avrdude.spec
|
Makefile
|
||||||
avrdude.conf
|
|
||||||
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
|
AC_OUTPUT
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(__CYGWIN__)
|
#if defined(WIN32NATIVE)
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
@@ -30,6 +30,8 @@ static char *filename;
|
|||||||
|
|
||||||
void win_sys_config_set(char sys_config[PATH_MAX])
|
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.*/
|
/* Use Windows API call to search for the Windows default system config file.*/
|
||||||
SearchPath(NULL, "avrdude.conf", NULL, PATH_MAX, sys_config, &filename);
|
SearchPath(NULL, "avrdude.conf", NULL, PATH_MAX, sys_config, &filename);
|
||||||
return;
|
return;
|
||||||
@@ -38,6 +40,8 @@ void win_sys_config_set(char sys_config[PATH_MAX])
|
|||||||
|
|
||||||
void win_usr_config_set(char usr_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. */
|
/* Use Windows API call to search for the Windows default user config file. */
|
||||||
SearchPath(NULL, "avrdude.rc", NULL, PATH_MAX, usr_config, &filename);
|
SearchPath(NULL, "avrdude.rc", NULL, PATH_MAX, usr_config, &filename);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(__CYGWIN__)
|
#if defined(WIN32NATIVE)
|
||||||
#ifndef __confwin_h__
|
#ifndef __confwin_h__
|
||||||
#define __confwin_h__
|
#define __confwin_h__
|
||||||
|
|
||||||
|
|||||||
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 */
|
||||||
|
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);
|
||||||
|
}
|
||||||
25
avrdude/crc16.h
Normal file
25
avrdude/crc16.h
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef CRC16_H
|
||||||
|
#define CRC16_H
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
|
||||||
|
#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
|
all-local: info html ps pdf
|
||||||
|
|
||||||
html:
|
html: avrdude-html/avrdude.html
|
||||||
mkdir -p avrdude-html
|
|
||||||
|
avrdude-html/avrdude.html: $(srcdir)/$(info_TEXINFOS)
|
||||||
texi2html -split_node $(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:
|
clean-local:
|
||||||
rm -rf avrdude-html *.info
|
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:
|
- Fix "overfull \hbox" issues in building documentation.
|
||||||
- Use Windows API for stk500 serial port communications on Windows port.
|
|
||||||
This might remove dependency on Cygwin.
|
- FIXME: term.c: terminal_get_input(): strip newlines in non-readline input
|
||||||
|
code.
|
||||||
- Add ability to find all parallel port names available and base addresses
|
|
||||||
of available ports.
|
- 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
328
avrdude/fileio.c
328
avrdude/fileio.c
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -48,6 +48,7 @@ struct ihexrec {
|
|||||||
|
|
||||||
extern char * progname;
|
extern char * progname;
|
||||||
extern char progbuf[];
|
extern char progbuf[];
|
||||||
|
extern int quell_progress;
|
||||||
|
|
||||||
int b2ihex(unsigned char * inbuf, int bufsize,
|
int b2ihex(unsigned char * inbuf, int bufsize,
|
||||||
int recsize, int startaddr,
|
int recsize, int startaddr,
|
||||||
@@ -76,6 +77,10 @@ int fileio_ihex(struct fioparms * fio,
|
|||||||
int fileio_srec(struct fioparms * fio,
|
int fileio_srec(struct fioparms * fio,
|
||||||
char * filename, FILE * f, unsigned char * buf, int size);
|
char * filename, FILE * f, unsigned char * buf, int size);
|
||||||
|
|
||||||
|
int fileio_num(struct fioparms * fio,
|
||||||
|
char * filename, FILE * f, unsigned char * buf, int size,
|
||||||
|
FILEFMT fmt);
|
||||||
|
|
||||||
int fmt_autodetect(char * fname);
|
int fmt_autodetect(char * fname);
|
||||||
|
|
||||||
|
|
||||||
@@ -360,11 +365,10 @@ int b2srec(unsigned char * inbuf, int bufsize,
|
|||||||
char * outfile, FILE * outf)
|
char * outfile, FILE * outf)
|
||||||
{
|
{
|
||||||
unsigned char * buf;
|
unsigned char * buf;
|
||||||
unsigned int nextaddr, stopaddr;
|
unsigned int nextaddr;
|
||||||
int n, nbytes, addr_width;
|
int n, nbytes, addr_width;
|
||||||
int i;
|
int i;
|
||||||
unsigned char cksum;
|
unsigned char cksum;
|
||||||
unsigned char startf, stopf ,emptyf;
|
|
||||||
|
|
||||||
char * tmpl=0;
|
char * tmpl=0;
|
||||||
|
|
||||||
@@ -373,39 +377,11 @@ int b2srec(unsigned char * inbuf, int bufsize,
|
|||||||
progname, recsize);
|
progname, recsize);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nextaddr = startaddr;
|
||||||
buf = inbuf;
|
buf = inbuf;
|
||||||
nextaddr = 0;
|
nbytes = 0;
|
||||||
stopaddr = 0;
|
|
||||||
startf = 0;
|
|
||||||
stopf = 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;
|
addr_width = 0;
|
||||||
|
|
||||||
while (bufsize) {
|
while (bufsize) {
|
||||||
@@ -435,34 +411,23 @@ int b2srec(unsigned char * inbuf, int bufsize,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* skip the lines filled with 0xff */
|
fprintf(outf, tmpl, n + addr_width + 1, nextaddr);
|
||||||
emptyf = 1;
|
|
||||||
|
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++) {
|
for (i=nextaddr; i<nextaddr + n; i++) {
|
||||||
if (buf[i] != 0xff) {
|
fprintf(outf, "%02X", buf[i]);
|
||||||
emptyf=0;
|
cksum += buf[i];
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (emptyf != 1) {
|
cksum = 0xff - cksum;
|
||||||
|
fprintf(outf, "%02X\n", cksum);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
nextaddr += n;
|
nextaddr += n;
|
||||||
|
nbytes +=n;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* advance to next 'recsize' bytes */
|
/* advance to next 'recsize' bytes */
|
||||||
@@ -697,6 +662,45 @@ int srec2b(char * infile, FILE * inf,
|
|||||||
return maxaddr;
|
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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int fileio_rbin(struct fioparms * fio,
|
int fileio_rbin(struct fioparms * fio,
|
||||||
char * filename, FILE * f, unsigned char * buf, int size)
|
char * filename, FILE * f, unsigned char * buf, int size)
|
||||||
@@ -728,6 +732,49 @@ int fileio_rbin(struct fioparms * fio,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int fileio_ihex(struct fioparms * fio,
|
int fileio_ihex(struct fioparms * fio,
|
||||||
char * filename, FILE * f, unsigned char * buf, int size)
|
char * filename, FILE * f, unsigned char * buf, int size)
|
||||||
{
|
{
|
||||||
@@ -789,6 +836,78 @@ int fileio_srec(struct fioparms * fio,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
int fileio_setparms(int op, struct fioparms * fp)
|
||||||
{
|
{
|
||||||
fp->op = op;
|
fp->op = op;
|
||||||
@@ -892,8 +1011,8 @@ int fileio(int op, char * filename, FILEFMT format,
|
|||||||
char * fname;
|
char * fname;
|
||||||
unsigned char * buf;
|
unsigned char * buf;
|
||||||
struct fioparms fio;
|
struct fioparms fio;
|
||||||
int i;
|
|
||||||
AVRMEM * mem;
|
AVRMEM * mem;
|
||||||
|
int using_stdio;
|
||||||
|
|
||||||
mem = avr_locate_mem(p, memtype);
|
mem = avr_locate_mem(p, memtype);
|
||||||
if (mem == NULL) {
|
if (mem == NULL) {
|
||||||
@@ -907,6 +1026,33 @@ int fileio(int op, char * filename, FILEFMT format,
|
|||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return -1;
|
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 (strcmp(filename, "-")==0) {
|
||||||
if (fio.op == FIO_READ) {
|
if (fio.op == FIO_READ) {
|
||||||
fname = "<stdin>";
|
fname = "<stdin>";
|
||||||
@@ -916,30 +1062,22 @@ int fileio(int op, char * filename, FILEFMT format,
|
|||||||
fname = "<stdout>";
|
fname = "<stdout>";
|
||||||
f = stdout;
|
f = stdout;
|
||||||
}
|
}
|
||||||
|
using_stdio = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fname = filename;
|
fname = filename;
|
||||||
f = fopen(fname, fio.mode);
|
f = NULL;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (format == FMT_AUTO) {
|
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);
|
format = fmt_autodetect(fname);
|
||||||
if (format < 0) {
|
if (format < 0) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@@ -948,8 +1086,21 @@ int fileio(int op, char * filename, FILEFMT format,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "%s: %s file %s auto detected as %s\n",
|
if (quell_progress < 2) {
|
||||||
progname, fio.iodesc, fname, fmtstr(format));
|
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) {
|
switch (format) {
|
||||||
@@ -965,12 +1116,33 @@ int fileio(int op, char * filename, FILEFMT format,
|
|||||||
rc = fileio_rbin(&fio, fname, f, buf, size);
|
rc = fileio_rbin(&fio, fname, f, buf, size);
|
||||||
break;
|
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:
|
default:
|
||||||
fprintf(stderr, "%s: invalid %s file format: %d\n",
|
fprintf(stderr, "%s: invalid %s file format: %d\n",
|
||||||
progname, fio.iodesc, format);
|
progname, fio.iodesc, format);
|
||||||
return -1;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -26,7 +26,12 @@ typedef enum {
|
|||||||
FMT_AUTO,
|
FMT_AUTO,
|
||||||
FMT_SREC,
|
FMT_SREC,
|
||||||
FMT_IHEX,
|
FMT_IHEX,
|
||||||
FMT_RBIN
|
FMT_RBIN,
|
||||||
|
FMT_IMM,
|
||||||
|
FMT_HEX,
|
||||||
|
FMT_DEC,
|
||||||
|
FMT_OCT,
|
||||||
|
FMT_BIN
|
||||||
} FILEFMT;
|
} FILEFMT;
|
||||||
|
|
||||||
struct fioparms {
|
struct fioparms {
|
||||||
|
|||||||
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 */
|
||||||
1380
avrdude/jtagmkI.c
Normal file
1380
avrdude/jtagmkI.c
Normal file
File diff suppressed because it is too large
Load Diff
28
avrdude/jtagmkI.h
Normal file
28
avrdude/jtagmkI.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
void jtagmkI_initpgm (PROGRAMMER * pgm);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
2254
avrdude/jtagmkII.c
Normal file
2254
avrdude/jtagmkII.c
Normal file
File diff suppressed because it is too large
Load Diff
38
avrdude/jtagmkII.h
Normal file
38
avrdude/jtagmkII.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
296
avrdude/jtagmkII_private.h
Normal file
296
avrdude/jtagmkII_private.h
Normal file
@@ -0,0 +1,296 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
/* 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 */
|
||||||
|
|
||||||
|
/* (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 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_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 */
|
||||||
|
};
|
||||||
109
avrdude/lexer.l
109
avrdude/lexer.l
@@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -46,17 +47,22 @@ HEXDIGIT [0-9a-fA-F]
|
|||||||
ID [_a-zA-Z][_a-zA-Z0-9]*
|
ID [_a-zA-Z][_a-zA-Z0-9]*
|
||||||
SIGN [+-]
|
SIGN [+-]
|
||||||
|
|
||||||
%x str
|
%x strng
|
||||||
%x incl
|
%x incl
|
||||||
%x comment
|
%x comment
|
||||||
|
|
||||||
|
/* Bump resources for classic lex. */
|
||||||
|
%e2000
|
||||||
|
%p5000
|
||||||
|
%n1000
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
{SIGN}*{DIGIT}+ { yylval = number(yytext); return TKN_NUMBER; }
|
{SIGN}*{DIGIT}+ { yylval = number(yytext); return TKN_NUMBER; }
|
||||||
{SIGN}*{DIGIT}+"."{DIGIT}* { yylval = number(yytext); return TKN_NUMBER; }
|
{SIGN}*{DIGIT}+"."{DIGIT}* { yylval = number(yytext); return TKN_NUMBER; }
|
||||||
{SIGN}*"."{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; }
|
0x{HEXDIGIT}+ { yylval = hexnumber(yytext); return TKN_NUMBER; }
|
||||||
|
|
||||||
@@ -64,7 +70,7 @@ SIGN [+-]
|
|||||||
|
|
||||||
# { /* The following eats '#' style comments to end of line */
|
# { /* The following eats '#' style comments to end of line */
|
||||||
BEGIN(comment); }
|
BEGIN(comment); }
|
||||||
<comment>[^\n] /* eat comments */
|
<comment>[^\n] { /* eat comments */ }
|
||||||
<comment>\n { lineno++; BEGIN(INITIAL); }
|
<comment>\n { lineno++; BEGIN(INITIAL); }
|
||||||
|
|
||||||
|
|
||||||
@@ -99,36 +105,54 @@ SIGN [+-]
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
<str>{
|
<strng>\" { *string_buf_ptr = 0; string_buf_ptr = string_buf;
|
||||||
\" { *string_buf_ptr = 0; string_buf_ptr = string_buf;
|
yylval = string(string_buf_ptr); BEGIN(INITIAL); return TKN_STRING; }
|
||||||
yylval = string(string_buf_ptr); BEGIN(INITIAL); return TKN_STRING; }
|
<strng>\\n *string_buf_ptr++ = '\n';
|
||||||
\\n *string_buf_ptr++ = '\n';
|
<strng>\\t *string_buf_ptr++ = '\t';
|
||||||
\\t *string_buf_ptr++ = '\t';
|
<strng>\\r *string_buf_ptr++ = '\r';
|
||||||
\\r *string_buf_ptr++ = '\r';
|
<strng>\\b *string_buf_ptr++ = '\b';
|
||||||
\\b *string_buf_ptr++ = '\b';
|
<strng>\\f *string_buf_ptr++ = '\f';
|
||||||
\\f *string_buf_ptr++ = '\f';
|
<strng>\\(.|\n) *(string_buf_ptr++) = yytext[1];
|
||||||
\\(.|\n) *(string_buf_ptr++) = yytext[1];
|
<strng>[^\\\n\"]+ { char *yptr = yytext; while (*yptr)
|
||||||
[^\\\n\"]+ { char *yptr = yytext; while (*yptr)
|
|
||||||
*(string_buf_ptr++) = *(yptr++); }
|
*(string_buf_ptr++) = *(yptr++); }
|
||||||
\n { fprintf(stderr, "error at line %d: unterminated character constant\n",
|
<strng>\n { fprintf(stderr, "error at line %d: unterminated character constant\n",
|
||||||
lineno);
|
lineno);
|
||||||
exit(1); }
|
exit(1); }
|
||||||
}
|
|
||||||
|
|
||||||
|
allowfullpagebitstream { yylval=NULL; return K_ALLOWFULLPAGEBITSTREAM; }
|
||||||
|
avr910 { yylval=NULL; return K_AVR910; }
|
||||||
|
avr910_devcode { yylval=NULL; return K_AVR910_DEVCODE; }
|
||||||
|
usbasp { yylval=NULL; return K_USBASP; }
|
||||||
bank_size { yylval=NULL; return K_PAGE_SIZE; }
|
bank_size { yylval=NULL; return K_PAGE_SIZE; }
|
||||||
banked { yylval=NULL; return K_PAGED; }
|
banked { yylval=NULL; return K_PAGED; }
|
||||||
|
baudrate { yylval=NULL; return K_BAUDRATE; }
|
||||||
bs2 { yylval=NULL; return K_BS2; }
|
bs2 { yylval=NULL; return K_BS2; }
|
||||||
buff { yylval=NULL; return K_BUFF; }
|
buff { yylval=NULL; return K_BUFF; }
|
||||||
|
butterfly { yylval=NULL; return K_BUTTERFLY; }
|
||||||
chip_erase_delay { yylval=NULL; return K_CHIP_ERASE_DELAY; }
|
chip_erase_delay { yylval=NULL; return K_CHIP_ERASE_DELAY; }
|
||||||
desc { yylval=NULL; return K_DESC; }
|
desc { yylval=NULL; return K_DESC; }
|
||||||
default_parallel { yylval=NULL; return K_DEFAULT_PARALLEL; }
|
default_parallel { yylval=NULL; return K_DEFAULT_PARALLEL; }
|
||||||
default_programmer { yylval=NULL; return K_DEFAULT_PROGRAMMER; }
|
default_programmer { yylval=NULL; return K_DEFAULT_PROGRAMMER; }
|
||||||
default_serial { yylval=NULL; return K_DEFAULT_SERIAL; }
|
default_serial { yylval=NULL; return K_DEFAULT_SERIAL; }
|
||||||
devicecode { yylval=NULL; return K_DEVICECODE; }
|
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; }
|
eeprom { yylval=NULL; return K_EEPROM; }
|
||||||
|
enablepageprogramming { yylval=NULL; return K_ENABLEPAGEPROGRAMMING; }
|
||||||
errled { yylval=NULL; return K_ERRLED; }
|
errled { yylval=NULL; return K_ERRLED; }
|
||||||
flash { yylval=NULL; return K_FLASH; }
|
flash { yylval=NULL; return K_FLASH; }
|
||||||
|
has_jtag { yylval=NULL; return K_HAS_JTAG; }
|
||||||
|
has_debugwire { yylval=NULL; return K_HAS_DW; }
|
||||||
id { yylval=NULL; return K_ID; }
|
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; }
|
max_write_delay { yylval=NULL; return K_MAX_WRITE_DELAY; }
|
||||||
memory { yylval=NULL; return K_MEMORY; }
|
memory { yylval=NULL; return K_MEMORY; }
|
||||||
min_write_delay { yylval=NULL; return K_MIN_WRITE_DELAY; }
|
min_write_delay { yylval=NULL; return K_MIN_WRITE_DELAY; }
|
||||||
@@ -145,17 +169,62 @@ part { yylval=NULL; return K_PART; }
|
|||||||
pgmled { yylval=NULL; return K_PGMLED; }
|
pgmled { yylval=NULL; return K_PGMLED; }
|
||||||
programmer { yylval=NULL; return K_PROGRAMMER; }
|
programmer { yylval=NULL; return K_PROGRAMMER; }
|
||||||
pwroff_after_write { yylval=NULL; return K_PWROFF_AFTER_WRITE; }
|
pwroff_after_write { yylval=NULL; return K_PWROFF_AFTER_WRITE; }
|
||||||
|
rampz { yylval=NULL; return K_RAMPZ; }
|
||||||
rdyled { yylval=NULL; return K_RDYLED; }
|
rdyled { yylval=NULL; return K_RDYLED; }
|
||||||
readback_p1 { yylval=NULL; return K_READBACK_P1; }
|
readback_p1 { yylval=NULL; return K_READBACK_P1; }
|
||||||
readback_p2 { yylval=NULL; return K_READBACK_P2; }
|
readback_p2 { yylval=NULL; return K_READBACK_P2; }
|
||||||
retry_pulse { yylval=NULL; return K_RETRY_PULSE; }
|
retry_pulse { yylval=NULL; return K_RETRY_PULSE; }
|
||||||
|
serbb { yylval=NULL; return K_SERBB; }
|
||||||
serial { yylval=NULL; return K_SERIAL; }
|
serial { yylval=NULL; return K_SERIAL; }
|
||||||
|
signature { yylval=NULL; return K_SIGNATURE; }
|
||||||
size { yylval=NULL; return K_SIZE; }
|
size { yylval=NULL; return K_SIZE; }
|
||||||
|
spmcr { yylval=NULL; return K_SPMCR; }
|
||||||
stk500 { yylval=NULL; return K_STK500; }
|
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; }
|
||||||
type { yylval=NULL; return K_TYPE; }
|
type { yylval=NULL; return K_TYPE; }
|
||||||
vcc { yylval=NULL; return K_VCC; }
|
vcc { yylval=NULL; return K_VCC; }
|
||||||
vfyled { yylval=NULL; return K_VFYLED; }
|
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; }
|
dedicated { yylval=new_token(K_DEDICATED); return K_DEDICATED; }
|
||||||
io { yylval=new_token(K_IO); return K_IO; }
|
io { yylval=new_token(K_IO); return K_IO; }
|
||||||
@@ -172,6 +241,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; }
|
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_lo { yylval=new_token(K_LOADPAGE_LO); return K_LOADPAGE_LO; }
|
||||||
loadpage_hi { yylval=new_token(K_LOADPAGE_HI); return K_LOADPAGE_HI; }
|
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; }
|
writepage { yylval=new_token(K_WRITEPAGE); return K_WRITEPAGE; }
|
||||||
chip_erase { yylval=new_token(K_CHIP_ERASE); return K_CHIP_ERASE; }
|
chip_erase { yylval=new_token(K_CHIP_ERASE); return K_CHIP_ERASE; }
|
||||||
pgm_enable { yylval=new_token(K_PGM_ENABLE); return K_PGM_ENABLE; }
|
pgm_enable { yylval=new_token(K_PGM_ENABLE); return K_PGM_ENABLE; }
|
||||||
@@ -182,9 +252,10 @@ yes { yylval=new_token(K_YES); return K_YES; }
|
|||||||
"," { yylval = NULL; pyytext(); return TKN_COMMA; }
|
"," { yylval = NULL; pyytext(); return TKN_COMMA; }
|
||||||
"=" { yylval = NULL; pyytext(); return TKN_EQUAL; }
|
"=" { yylval = NULL; pyytext(); return TKN_EQUAL; }
|
||||||
";" { yylval = NULL; pyytext(); return TKN_SEMI; }
|
";" { yylval = NULL; pyytext(); return TKN_SEMI; }
|
||||||
|
"~" { yylval = NULL; pyytext(); return TKN_TILDE; }
|
||||||
|
|
||||||
"\n" { lineno++; }
|
"\n" { lineno++; }
|
||||||
[ \r\t]+ /* ignore whitespace */
|
[ \r\t]+ { /* ignore whitespace */ }
|
||||||
|
|
||||||
c: { fprintf(stderr, "error at %s:%d: possible old-style config file entry\n",
|
c: { fprintf(stderr, "error at %s:%d: possible old-style config file entry\n",
|
||||||
infile, lineno);
|
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
|
#define OBSOLETE__IOW _IOW
|
||||||
|
|
||||||
@@ -9,29 +30,28 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#define PPISDATA PPWDATA
|
#define ppi_claim(fd) \
|
||||||
#define PPIGDATA PPRDATA
|
if (ioctl(fd, PPCLAIM)) { \
|
||||||
|
|
||||||
#define PPISCTRL PPWCONTROL
|
|
||||||
#define PPIGCTRL PPRCONTROL
|
|
||||||
|
|
||||||
#define PPISSTATUS PPWSTATUS
|
|
||||||
#define PPIGSTATUS PPRSTATUS
|
|
||||||
|
|
||||||
#define ppi_claim(pgm) \
|
|
||||||
if (ioctl(pgm->fd, PPCLAIM)) { \
|
|
||||||
fprintf(stderr, "%s: can't claim device \"%s\": %s\n\n", \
|
fprintf(stderr, "%s: can't claim device \"%s\": %s\n\n", \
|
||||||
progname, port, strerror(errno)); \
|
progname, port, strerror(errno)); \
|
||||||
close(pgm->fd); \
|
close(fd); \
|
||||||
exit(1); \
|
exit(1); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ppi_release(pgm) \
|
#define ppi_release(fd) \
|
||||||
if (ioctl(pgm->fd, PPRELEASE)) { \
|
if (ioctl(fd, PPRELEASE)) { \
|
||||||
fprintf(stderr, "%s: can't release device: %s\n\n", \
|
fprintf(stderr, "%s: can't release device: %s\n\n", \
|
||||||
progname, strerror(errno)); \
|
progname, strerror(errno)); \
|
||||||
exit(1); \
|
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
|
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||||
* Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
|
* Copyright (C) 1990-2004 Brian S. Dean <bsd@bsdhome.com>
|
||||||
* 1998, 1999, 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -413,11 +412,6 @@ lcreat ( void * liststruct, int elements )
|
|||||||
{
|
{
|
||||||
LIST * l;
|
LIST * l;
|
||||||
|
|
||||||
if (LISTSZ != sizeof(LIST)) {
|
|
||||||
printf ( "lcreat(): warning, LISTSZ[%d] != sizeof(LIST)[%d]\n",
|
|
||||||
LISTSZ, sizeof(LIST) );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (liststruct == NULL) {
|
if (liststruct == NULL) {
|
||||||
/*--------------------------------------------------
|
/*--------------------------------------------------
|
||||||
allocate memory for the list itself
|
allocate memory for the list itself
|
||||||
@@ -1296,8 +1290,8 @@ int lprint ( FILE * f, LISTID lid )
|
|||||||
|
|
||||||
l = (LIST *)lid;
|
l = (LIST *)lid;
|
||||||
|
|
||||||
fprintf ( f, "list id 0x%08x internal data structures:\n",
|
fprintf ( f, "list id %p internal data structures:\n",
|
||||||
(unsigned int)lid );
|
lid );
|
||||||
#if CHECK_MAGIC
|
#if CHECK_MAGIC
|
||||||
if ((l->magic1 != MAGIC) || (l->magic2 != MAGIC)) {
|
if ((l->magic1 != MAGIC) || (l->magic2 != MAGIC)) {
|
||||||
fprintf ( f, " *** WARNING: LIST MAGIC IS CORRUPT ***\n" );
|
fprintf ( f, " *** WARNING: LIST MAGIC IS CORRUPT ***\n" );
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||||
* Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
|
* Copyright (C) 1990-2004 Brian S. Dean <bsd@bsdhome.com>
|
||||||
* 1998, 1999, 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -68,9 +67,6 @@ typedef void * LNODEID;
|
|||||||
#define LISTRMV(l,d) lrmv_d(l,d) /* remove from end of the list */
|
#define LISTRMV(l,d) lrmv_d(l,d) /* remove from end of the list */
|
||||||
|
|
||||||
|
|
||||||
#define LISTSZ 32 /* size of internal private LIST structure */
|
|
||||||
|
|
||||||
|
|
||||||
/* .................... Function Prototypes .................... */
|
/* .................... Function Prototypes .................... */
|
||||||
|
|
||||||
LISTID lcreat ( void * liststruct, int poolsize );
|
LISTID lcreat ( void * liststruct, int poolsize );
|
||||||
|
|||||||
1394
avrdude/main.c
1394
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
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -29,18 +29,24 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#if defined(__FreeBSD__)
|
#if defined(__FreeBSD__)
|
||||||
#include <dev/ppbus/ppi.h>
|
# include "freebsd_ppi.h"
|
||||||
#elif defined(__linux__)
|
#elif defined(__linux__)
|
||||||
#include "linux_ppdev.h"
|
# include "linux_ppdev.h"
|
||||||
|
#elif defined(__sun__) && defined(__svr4__) /* Solaris */
|
||||||
|
# include "solaris_ecpp.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "avr.h"
|
#include "avr.h"
|
||||||
#include "pindefs.h"
|
#include "pindefs.h"
|
||||||
#include "pgm.h"
|
#include "pgm.h"
|
||||||
#include "par.h"
|
|
||||||
#include "ppi.h"
|
#include "ppi.h"
|
||||||
|
#include "bitbang.h"
|
||||||
|
|
||||||
#define SLOW_TOGGLE 0
|
extern char * progname;
|
||||||
|
extern int do_cycles;
|
||||||
|
extern int verbose;
|
||||||
|
|
||||||
|
#if HAVE_PARPORT
|
||||||
|
|
||||||
struct ppipins_t {
|
struct ppipins_t {
|
||||||
int pin;
|
int pin;
|
||||||
@@ -49,7 +55,7 @@ struct ppipins_t {
|
|||||||
int inverted;
|
int inverted;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ppipins_t pins[] = {
|
static struct ppipins_t ppipins[] = {
|
||||||
{ 1, PPICTRL, 0x01, 1 },
|
{ 1, PPICTRL, 0x01, 1 },
|
||||||
{ 2, PPIDATA, 0x01, 0 },
|
{ 2, PPIDATA, 0x01, 0 },
|
||||||
{ 3, PPIDATA, 0x02, 0 },
|
{ 3, PPIDATA, 0x02, 0 },
|
||||||
@@ -69,333 +75,136 @@ static struct ppipins_t pins[] = {
|
|||||||
{ 17, PPICTRL, 0x08, 1 }
|
{ 17, PPICTRL, 0x08, 1 }
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NPINS (sizeof(pins)/sizeof(struct ppipins_t))
|
#define NPINS (sizeof(ppipins)/sizeof(struct ppipins_t))
|
||||||
|
|
||||||
|
static int par_setpin(PROGRAMMER * pgm, int pin, int value)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
|
int inverted;
|
||||||
|
|
||||||
|
inverted = pin & PIN_INVERSE;
|
||||||
|
pin &= PIN_MASK;
|
||||||
|
|
||||||
if (pin < 1 || pin > 17)
|
if (pin < 1 || pin > 17)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
pin--;
|
pin--;
|
||||||
|
|
||||||
if (pins[pin].inverted)
|
if (ppipins[pin].inverted)
|
||||||
|
inverted = !inverted;
|
||||||
|
|
||||||
|
if (inverted)
|
||||||
value = !value;
|
value = !value;
|
||||||
|
|
||||||
if (value)
|
if (value)
|
||||||
ppi_set(fd, pins[pin].reg, pins[pin].bit);
|
ppi_set(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
|
||||||
else
|
else
|
||||||
ppi_clr(fd, pins[pin].reg, pins[pin].bit);
|
ppi_clr(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
|
||||||
|
|
||||||
#if SLOW_TOGGLE
|
if (pgm->ispdelay > 1)
|
||||||
usleep(1000);
|
bitbang_delay(pgm->ispdelay);
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
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 value;
|
||||||
|
int inverted;
|
||||||
|
|
||||||
|
inverted = pin & PIN_INVERSE;
|
||||||
|
pin &= PIN_MASK;
|
||||||
|
|
||||||
if (pin < 1 || pin > 17)
|
if (pin < 1 || pin > 17)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
pin--;
|
pin--;
|
||||||
|
|
||||||
value = ppi_get(fd, pins[pin].reg, pins[pin].bit);
|
value = ppi_get(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
|
||||||
|
|
||||||
if (value)
|
if (value)
|
||||||
value = 1;
|
value = 1;
|
||||||
|
|
||||||
if (pins[pin].inverted)
|
if (ppipins[pin].inverted)
|
||||||
|
inverted = !inverted;
|
||||||
|
|
||||||
|
if (inverted)
|
||||||
value = !value;
|
value = !value;
|
||||||
|
|
||||||
return 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)
|
if (pin < 1 || pin > 17)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
pin--;
|
pin--;
|
||||||
|
|
||||||
ppi_toggle(fd, pins[pin].reg, pins[pin].bit);
|
if (ppipins[pin].inverted)
|
||||||
|
inverted = !inverted;
|
||||||
|
|
||||||
#if SLOW_TOGGLE
|
if (inverted) {
|
||||||
usleep(1000);
|
ppi_clr(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
|
||||||
#endif
|
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
|
ppi_clr(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
|
||||||
usleep(1000);
|
if (pgm->ispdelay > 1)
|
||||||
#endif
|
bitbang_delay(pgm->ispdelay);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int par_getpinmask(int pin)
|
static char * pins_to_str(unsigned int pmask)
|
||||||
{
|
{
|
||||||
if (pin < 1 || pin > 17)
|
static char buf[64];
|
||||||
return -1;
|
|
||||||
|
|
||||||
return pins[pin-1].bit;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static char vccpins_buf[64];
|
|
||||||
static char * vccpins_str(unsigned int pmask)
|
|
||||||
{
|
|
||||||
unsigned int mask;
|
|
||||||
int pin;
|
int pin;
|
||||||
char b2[8];
|
char b2[8];
|
||||||
char * b;
|
|
||||||
|
|
||||||
b = vccpins_buf;
|
buf[0] = 0;
|
||||||
|
for (pin = 1; pin <= 17; pin++) {
|
||||||
b[0] = 0;
|
if (pmask & (1 << pin)) {
|
||||||
for (pin = 2, mask = 1; mask < 0x80; mask = mask << 1, pin++) {
|
|
||||||
if (pmask & mask) {
|
|
||||||
sprintf(b2, "%d", pin);
|
sprintf(b2, "%d", pin);
|
||||||
if (b[0] != 0)
|
if (buf[0] != 0)
|
||||||
strcat(b, ",");
|
strcat(buf, ",");
|
||||||
strcat(b, b2);
|
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
|
* apply power to the AVR processor
|
||||||
*/
|
*/
|
||||||
static void par_powerup(PROGRAMMER * pgm)
|
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);
|
usleep(100000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -405,86 +214,12 @@ static void par_powerup(PROGRAMMER * pgm)
|
|||||||
*/
|
*/
|
||||||
static void par_powerdown(PROGRAMMER * pgm)
|
static void par_powerdown(PROGRAMMER * pgm)
|
||||||
{
|
{
|
||||||
ppi_clr(pgm->fd, PPIDATA, pgm->pinno[PPI_AVR_VCC]); /* power down */
|
par_setmany(pgm, pgm->pinno[PPI_AVR_VCC], 0); /* 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void par_disable(PROGRAMMER * pgm)
|
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)
|
static void par_enable(PROGRAMMER * pgm)
|
||||||
@@ -500,62 +235,119 @@ static void par_enable(PROGRAMMER * pgm)
|
|||||||
* and not via the buffer chip.
|
* 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);
|
usleep(1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* enable the 74367 buffer, if connected; this signal is active low
|
* 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 int par_open(PROGRAMMER * pgm, char * port)
|
||||||
static void par_open(PROGRAMMER * pgm, char * port)
|
|
||||||
{
|
{
|
||||||
pgm->fd = ppi_open(port);
|
int rc;
|
||||||
if (pgm->fd < 0) {
|
|
||||||
|
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",
|
fprintf(stderr, "%s: failed to open parallel port \"%s\"\n\n",
|
||||||
progname, port);
|
progname, port);
|
||||||
exit(1);
|
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)
|
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, char * p)
|
||||||
{
|
{
|
||||||
char vccpins[64];
|
char vccpins[64];
|
||||||
char buffpins[64];
|
char buffpins[64];
|
||||||
|
|
||||||
if (pgm->pinno[PPI_AVR_VCC]) {
|
if (pgm->pinno[PPI_AVR_VCC]) {
|
||||||
snprintf(vccpins, sizeof(vccpins), " = pins %s",
|
snprintf(vccpins, sizeof(vccpins), "%s",
|
||||||
vccpins_str(pgm->pinno[PPI_AVR_VCC]));
|
pins_to_str(pgm->pinno[PPI_AVR_VCC]));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
strcpy(vccpins, " (not used)");
|
strcpy(vccpins, " (not used)");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pgm->pinno[PPI_AVR_BUFF]) {
|
if (pgm->pinno[PPI_AVR_BUFF]) {
|
||||||
snprintf(buffpins, sizeof(buffpins), " = pins %s",
|
snprintf(buffpins, sizeof(buffpins), "%s",
|
||||||
vccpins_str(pgm->pinno[PPI_AVR_BUFF]));
|
pins_to_str(pgm->pinno[PPI_AVR_BUFF]));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
strcpy(buffpins, " (not used)");
|
strcpy(buffpins, " (not used)");
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"%s VCC = 0x%02x%s\n"
|
"%s VCC = %s\n"
|
||||||
"%s BUFF = 0x%02x%s\n"
|
"%s BUFF = %s\n"
|
||||||
"%s RESET = %d\n"
|
"%s RESET = %d\n"
|
||||||
"%s SCK = %d\n"
|
"%s SCK = %d\n"
|
||||||
"%s MOSI = %d\n"
|
"%s MOSI = %d\n"
|
||||||
@@ -565,8 +357,8 @@ static void par_display(PROGRAMMER * pgm, char * p)
|
|||||||
"%s PGM LED = %d\n"
|
"%s PGM LED = %d\n"
|
||||||
"%s VFY LED = %d\n",
|
"%s VFY LED = %d\n",
|
||||||
|
|
||||||
p, pgm->pinno[PPI_AVR_VCC], vccpins,
|
p, vccpins,
|
||||||
p, pgm->pinno[PPI_AVR_BUFF], buffpins,
|
p, buffpins,
|
||||||
p, pgm->pinno[PIN_AVR_RESET],
|
p, pgm->pinno[PIN_AVR_RESET],
|
||||||
p, pgm->pinno[PIN_AVR_SCK],
|
p, pgm->pinno[PIN_AVR_SCK],
|
||||||
p, pgm->pinno[PIN_AVR_MOSI],
|
p, pgm->pinno[PIN_AVR_MOSI],
|
||||||
@@ -578,27 +370,72 @@ 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)
|
void par_initpgm(PROGRAMMER * pgm)
|
||||||
{
|
{
|
||||||
strcpy(pgm->type, "PPI");
|
strcpy(pgm->type, "PPI");
|
||||||
|
|
||||||
pgm->rdy_led = par_rdy_led;
|
pgm->exit_vcc = EXIT_VCC_UNSPEC;
|
||||||
pgm->err_led = par_err_led;
|
pgm->exit_reset = EXIT_RESET_UNSPEC;
|
||||||
pgm->pgm_led = par_pgm_led;
|
|
||||||
pgm->vfy_led = par_vfy_led;
|
pgm->rdy_led = bitbang_rdy_led;
|
||||||
pgm->initialize = par_initialize;
|
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->display = par_display;
|
||||||
pgm->save = par_save;
|
|
||||||
pgm->restore = par_restore;
|
|
||||||
pgm->enable = par_enable;
|
pgm->enable = par_enable;
|
||||||
pgm->disable = par_disable;
|
pgm->disable = par_disable;
|
||||||
pgm->powerup = par_powerup;
|
pgm->powerup = par_powerup;
|
||||||
pgm->powerdown = par_powerdown;
|
pgm->powerdown = par_powerdown;
|
||||||
pgm->program_enable = par_program_enable;
|
pgm->program_enable = bitbang_program_enable;
|
||||||
pgm->chip_erase = par_chip_erase;
|
pgm->chip_erase = bitbang_chip_erase;
|
||||||
pgm->cmd = par_cmd;
|
pgm->cmd = bitbang_cmd;
|
||||||
pgm->open = par_open;
|
pgm->open = par_open;
|
||||||
pgm->close = par_close;
|
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
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -22,12 +22,8 @@
|
|||||||
#ifndef __par_h__
|
#ifndef __par_h__
|
||||||
#define __par_h__
|
#define __par_h__
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
void par_initpgm (PROGRAMMER * pgm);
|
void par_initpgm (PROGRAMMER * pgm);
|
||||||
|
|
||||||
int par_getpinmask(int pin);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
102
avrdude/pgm.c
102
avrdude/pgm.c
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -29,13 +29,37 @@
|
|||||||
|
|
||||||
extern char * progname;
|
extern char * progname;
|
||||||
|
|
||||||
int pgm_default_1 (struct programmer_t *, int);
|
static int pgm_default_2 (struct programmer_t *, AVRPART *);
|
||||||
int pgm_default_2 (struct programmer_t *, AVRPART *);
|
static int pgm_default_3 (struct programmer_t * pgm, AVRPART * p, AVRMEM * mem,
|
||||||
int pgm_default_3 (struct programmer_t *);
|
unsigned long addr, unsigned char * value);
|
||||||
void pgm_default_4 (struct programmer_t *);
|
static void pgm_default_4 (struct programmer_t *);
|
||||||
int pgm_default_5 (struct programmer_t *, unsigned char cmd[4],
|
static int pgm_default_5 (struct programmer_t * pgm, AVRPART * p, AVRMEM * mem,
|
||||||
unsigned char res[4]);
|
unsigned long addr, unsigned char data);
|
||||||
void pgm_default_6 (struct programmer_t *, char *);
|
static 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)
|
PROGRAMMER * pgm_new(void)
|
||||||
@@ -57,6 +81,7 @@ PROGRAMMER * pgm_new(void)
|
|||||||
pgm->type[0] = 0;
|
pgm->type[0] = 0;
|
||||||
pgm->config_file[0] = 0;
|
pgm->config_file[0] = 0;
|
||||||
pgm->lineno = 0;
|
pgm->lineno = 0;
|
||||||
|
pgm->baudrate = 0;
|
||||||
|
|
||||||
for (i=0; i<N_PINS; i++)
|
for (i=0; i<N_PINS; i++)
|
||||||
pgm->pinno[i] = 0;
|
pgm->pinno[i] = 0;
|
||||||
@@ -65,72 +90,79 @@ PROGRAMMER * pgm_new(void)
|
|||||||
* mandatory functions - these are called without checking to see
|
* mandatory functions - these are called without checking to see
|
||||||
* whether they are assigned or not
|
* 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->initialize = pgm_default_2;
|
||||||
pgm->display = pgm_default_6;
|
pgm->display = pgm_default_6;
|
||||||
pgm->save = pgm_default_3;
|
|
||||||
pgm->restore = pgm_default_4;
|
|
||||||
pgm->enable = pgm_default_4;
|
pgm->enable = pgm_default_4;
|
||||||
pgm->disable = pgm_default_4;
|
pgm->disable = pgm_default_4;
|
||||||
pgm->powerup = pgm_default_4;
|
pgm->powerup = pgm_default_powerup_powerdown;
|
||||||
pgm->powerdown = pgm_default_4;
|
pgm->powerdown = pgm_default_powerup_powerdown;
|
||||||
pgm->program_enable = pgm_default_2;
|
pgm->program_enable = pgm_default_2;
|
||||||
pgm->chip_erase = pgm_default_2;
|
pgm->chip_erase = pgm_default_2;
|
||||||
pgm->cmd = pgm_default_5;
|
pgm->open = pgm_default_open;
|
||||||
pgm->open = pgm_default_6;
|
|
||||||
pgm->close = pgm_default_4;
|
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
|
* optional functions - these are checked to make sure they are
|
||||||
* assigned before they are called
|
* assigned before they are called
|
||||||
*/
|
*/
|
||||||
|
pgm->cmd = NULL;
|
||||||
pgm->paged_write = NULL;
|
pgm->paged_write = NULL;
|
||||||
pgm->paged_load = 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;
|
||||||
|
|
||||||
return pgm;
|
return pgm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void pgm_default(void)
|
static void pgm_default(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s: programmer operation not supported\n", progname);
|
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();
|
pgm_default();
|
||||||
return -1;
|
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();
|
pgm_default();
|
||||||
return -1;
|
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();
|
pgm_default();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pgm_default_4 (struct programmer_t * pgm)
|
static void pgm_default_6 (struct programmer_t * pgm, char * p)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
pgm_default();
|
pgm_default();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
#include "avrpart.h"
|
#include "avrpart.h"
|
||||||
#include "lists.h"
|
#include "lists.h"
|
||||||
#include "pindefs.h"
|
#include "pindefs.h"
|
||||||
|
#include "serial.h"
|
||||||
|
|
||||||
#define ON 1
|
#define ON 1
|
||||||
#define OFF 0
|
#define OFF 0
|
||||||
@@ -35,14 +35,35 @@
|
|||||||
#define PGM_DESCLEN 80
|
#define PGM_DESCLEN 80
|
||||||
#define PGM_PORTLEN PATH_MAX
|
#define PGM_PORTLEN PATH_MAX
|
||||||
#define PGM_TYPELEN 32
|
#define PGM_TYPELEN 32
|
||||||
|
|
||||||
|
extern LISTID programmers;
|
||||||
|
|
||||||
|
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 {
|
typedef struct programmer_t {
|
||||||
LISTID id;
|
LISTID id;
|
||||||
char desc[PGM_DESCLEN];
|
char desc[PGM_DESCLEN];
|
||||||
char type[PGM_TYPELEN];
|
char type[PGM_TYPELEN];
|
||||||
char port[PGM_PORTLEN];
|
char port[PGM_PORTLEN];
|
||||||
unsigned int pinno[N_PINS];
|
unsigned int pinno[N_PINS];
|
||||||
|
exit_vcc_t exit_vcc;
|
||||||
|
exit_reset_t exit_reset;
|
||||||
int ppidata;
|
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 page_size; /* page size if the programmer supports paged write/load */
|
||||||
int (*rdy_led) (struct programmer_t * pgm, int value);
|
int (*rdy_led) (struct programmer_t * pgm, int value);
|
||||||
int (*err_led) (struct programmer_t * pgm, int value);
|
int (*err_led) (struct programmer_t * pgm, int value);
|
||||||
@@ -50,8 +71,6 @@ typedef struct programmer_t {
|
|||||||
int (*vfy_led) (struct programmer_t * pgm, int value);
|
int (*vfy_led) (struct programmer_t * pgm, int value);
|
||||||
int (*initialize) (struct programmer_t * pgm, AVRPART * p);
|
int (*initialize) (struct programmer_t * pgm, AVRPART * p);
|
||||||
void (*display) (struct programmer_t * pgm, char * p);
|
void (*display) (struct programmer_t * pgm, char * p);
|
||||||
int (*save) (struct programmer_t * pgm);
|
|
||||||
void (*restore) (struct programmer_t * pgm);
|
|
||||||
void (*enable) (struct programmer_t * pgm);
|
void (*enable) (struct programmer_t * pgm);
|
||||||
void (*disable) (struct programmer_t * pgm);
|
void (*disable) (struct programmer_t * pgm);
|
||||||
void (*powerup) (struct programmer_t * pgm);
|
void (*powerup) (struct programmer_t * pgm);
|
||||||
@@ -60,17 +79,56 @@ typedef struct programmer_t {
|
|||||||
int (*chip_erase) (struct programmer_t * pgm, AVRPART * p);
|
int (*chip_erase) (struct programmer_t * pgm, AVRPART * p);
|
||||||
int (*cmd) (struct programmer_t * pgm, unsigned char cmd[4],
|
int (*cmd) (struct programmer_t * pgm, unsigned char cmd[4],
|
||||||
unsigned char res[4]);
|
unsigned char res[4]);
|
||||||
void (*open) (struct programmer_t * pgm, char * port);
|
int (*open) (struct programmer_t * pgm, char * port);
|
||||||
void (*close) (struct programmer_t * pgm);
|
void (*close) (struct programmer_t * pgm);
|
||||||
int (*paged_write) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
|
int (*paged_write) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
|
||||||
int page_size, int n_bytes);
|
int page_size, int n_bytes);
|
||||||
int (*paged_load) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
|
int (*paged_load) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
|
||||||
int page_size, int n_bytes);
|
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, 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);
|
||||||
char config_file[PATH_MAX]; /* config file where defined */
|
char config_file[PATH_MAX]; /* config file where defined */
|
||||||
int lineno; /* config file line number */
|
int lineno; /* config file line number */
|
||||||
|
char flag; /* for private use of the programmer */
|
||||||
} PROGRAMMER;
|
} PROGRAMMER;
|
||||||
|
|
||||||
|
|
||||||
PROGRAMMER * pgm_new(void);
|
PROGRAMMER * pgm_new(void);
|
||||||
|
|
||||||
|
#if defined(WIN32NATIVE)
|
||||||
|
|
||||||
|
#include "ac_cfg.h"
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
*/
|
||||||
|
void usleep(unsigned long us);
|
||||||
|
|
||||||
|
#if !defined(HAVE_GETTIMEOFDAY)
|
||||||
|
struct timezone;
|
||||||
|
int gettimeofday(struct timeval *tv, struct timezone *tz);
|
||||||
|
#endif /* HAVE_GETTIMEOFDAY */
|
||||||
|
|
||||||
|
#endif /* __win32native_h */
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -35,6 +35,8 @@ enum {
|
|||||||
PIN_LED_VFY,
|
PIN_LED_VFY,
|
||||||
N_PINS
|
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_ON(fd,pin) ppi_setpin(fd,pin,0)
|
||||||
#define LED_OFF(fd,pin) ppi_setpin(fd,pin,1)
|
#define LED_OFF(fd,pin) ppi_setpin(fd,pin,1)
|
||||||
|
|||||||
143
avrdude/ppi.c
143
avrdude/ppi.c
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,10 +19,13 @@
|
|||||||
|
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#if defined(__FreeBSD__) || defined(__linux__)
|
|
||||||
|
#if !defined(WIN32NATIVE)
|
||||||
|
|
||||||
#include "ac_cfg.h"
|
#include "ac_cfg.h"
|
||||||
|
|
||||||
|
#if HAVE_PARPORT
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -31,9 +34,11 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#if defined(__FreeBSD__)
|
#if defined(__FreeBSD__)
|
||||||
#include <dev/ppbus/ppi.h>
|
# include "freebsd_ppi.h"
|
||||||
#elif defined(__linux__)
|
#elif defined(__linux__)
|
||||||
#include "linux_ppdev.h"
|
# include "linux_ppdev.h"
|
||||||
|
#elif defined(__sun__) && defined(__svr4__) /* Solaris */
|
||||||
|
# include "solaris_ecpp.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "avr.h"
|
#include "avr.h"
|
||||||
@@ -43,24 +48,26 @@
|
|||||||
|
|
||||||
extern char * progname;
|
extern char * progname;
|
||||||
|
|
||||||
/*
|
enum {
|
||||||
* set 'get' and 'set' appropriately for subsequent passage to ioctl()
|
PPI_READ,
|
||||||
* to get/set the specified PPI registers.
|
PPI_WRITE,
|
||||||
*/
|
PPI_SHADOWREAD
|
||||||
static int ppi_getops(int reg, unsigned long * get, unsigned long * set)
|
};
|
||||||
|
|
||||||
|
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) {
|
switch (reg) {
|
||||||
case PPIDATA:
|
case PPIDATA:
|
||||||
*set = PPISDATA;
|
shadow_num = 0;
|
||||||
*get = PPIGDATA;
|
|
||||||
break;
|
break;
|
||||||
case PPICTRL:
|
case PPICTRL:
|
||||||
*set = PPISCTRL;
|
shadow_num = 1;
|
||||||
*get = PPIGCTRL;
|
|
||||||
break;
|
break;
|
||||||
case PPISTATUS:
|
case PPISTATUS:
|
||||||
*set = PPISSTATUS;
|
shadow_num = 2;
|
||||||
*get = PPIGSTATUS;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "%s: avr_set(): invalid register=%d\n",
|
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;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set the indicated bit of the specified register.
|
* 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 char v;
|
||||||
unsigned long get, set;
|
|
||||||
int rc;
|
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)
|
if (rc)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ioctl(fd, get, &v);
|
|
||||||
v |= bit;
|
|
||||||
ioctl(fd, set, &v);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,20 +114,18 @@ int ppi_set(int fd, int reg, int bit)
|
|||||||
/*
|
/*
|
||||||
* clear the indicated bit of the specified register.
|
* 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 char v;
|
||||||
unsigned long get, set;
|
|
||||||
int rc;
|
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)
|
if (rc)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ioctl(fd, get, &v);
|
|
||||||
v &= ~bit;
|
|
||||||
ioctl(fd, set, &v);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,39 +133,35 @@ int ppi_clr(int fd, int reg, int bit)
|
|||||||
/*
|
/*
|
||||||
* get the indicated bit of the specified register.
|
* 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 char v;
|
||||||
unsigned long get, set;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = ppi_getops(reg, &get, &set);
|
rc = ppi_shadow_access(fdp, reg, &v, PPI_READ);
|
||||||
|
v &= bit;
|
||||||
|
|
||||||
if (rc)
|
if (rc)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ioctl(fd, get, &v);
|
|
||||||
v &= bit;
|
|
||||||
|
|
||||||
return v; /* v == bit */
|
return v; /* v == bit */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* toggle the indicated bit of the specified register.
|
* 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 char v;
|
||||||
unsigned long get, set;
|
|
||||||
int rc;
|
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)
|
if (rc)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ioctl(fd, get, &v);
|
|
||||||
v ^= bit;
|
|
||||||
ioctl(fd, set, &v);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,60 +169,70 @@ int ppi_toggle(int fd, int reg, int bit)
|
|||||||
/*
|
/*
|
||||||
* get all bits of the specified register.
|
* 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 char v;
|
||||||
unsigned long get, set;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = ppi_getops(reg, &get, &set);
|
rc = ppi_shadow_access(fdp, reg, &v, PPI_READ);
|
||||||
|
|
||||||
if (rc)
|
if (rc)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ioctl(fd, get, &v);
|
return v; /* v == bit */
|
||||||
|
|
||||||
return (int)v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set all bits of the specified register to val.
|
* 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 char v;
|
||||||
unsigned long get, set;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = ppi_getops(reg, &get, &set);
|
v = val;
|
||||||
|
rc = ppi_shadow_access(fdp, reg, &v, PPI_WRITE);
|
||||||
|
|
||||||
if (rc)
|
if (rc)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
v = val;
|
|
||||||
ioctl(fd, set, &v);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int ppi_open(char * port)
|
void ppi_open(char * port, union filedescriptor *fdp)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
unsigned char v;
|
||||||
|
|
||||||
fd = open(port, O_RDWR);
|
fd = open(port, O_RDWR);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
fprintf(stderr, "%s: can't open device \"%s\": %s\n",
|
fprintf(stderr, "%s: can't open device \"%s\": %s\n",
|
||||||
progname, port, strerror(errno));
|
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
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -22,8 +22,6 @@
|
|||||||
#ifndef __ppi_h__
|
#ifndef __ppi_h__
|
||||||
#define __ppi_h__
|
#define __ppi_h__
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PPI registers
|
* PPI registers
|
||||||
*/
|
*/
|
||||||
@@ -34,29 +32,22 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#if !defined(ppi_claim)
|
|
||||||
# define ppi_claim(pgm)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(ppi_release)
|
int ppi_get (union filedescriptor *fdp, int reg, int bit);
|
||||||
# define ppi_release(pgm)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int ppi_get (int fd, int reg, int bit);
|
int ppi_set (union filedescriptor *fdp, int reg, int bit);
|
||||||
|
|
||||||
int ppi_set (int fd, int reg, int bit);
|
int ppi_clr (union filedescriptor *fdp, int reg, int bit);
|
||||||
|
|
||||||
int ppi_clr (int fd, int reg, int bit);
|
int ppi_getall (union filedescriptor *fdp, int reg);
|
||||||
|
|
||||||
int ppi_getall (int fd, int reg);
|
int ppi_setall (union filedescriptor *fdp, int reg, int val);
|
||||||
|
|
||||||
int ppi_setall (int fd, int reg, int val);
|
int ppi_toggle (union filedescriptor *fdp, int reg, int bit);
|
||||||
|
|
||||||
int ppi_toggle (int fd, int reg, int bit);
|
void ppi_open (char * port, union filedescriptor *fdp);
|
||||||
|
|
||||||
int ppi_open (char * port);
|
void ppi_close (union filedescriptor *fdp);
|
||||||
|
|
||||||
void ppi_close (int fd);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
125
avrdude/ppiwin.c
125
avrdude/ppiwin.c
@@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
* 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>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -17,6 +18,7 @@
|
|||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This is the parallel port interface for Windows built using Cygwin.
|
This is the parallel port interface for Windows built using Cygwin.
|
||||||
@@ -28,9 +30,9 @@ reg = register as defined in an enum in ppi.h. This must be converted
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "ac_cfg.h"
|
||||||
|
|
||||||
|
#if defined (WIN32NATIVE)
|
||||||
#if defined(__CYGWIN__)
|
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@@ -39,10 +41,11 @@ reg = register as defined in an enum in ppi.h. This must be converted
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#include "serial.h"
|
||||||
#include "ppi.h"
|
#include "ppi.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extern char *progname;
|
extern char *progname;
|
||||||
|
|
||||||
|
|
||||||
@@ -72,7 +75,7 @@ static const winpp winports[DEVICE_MAX] =
|
|||||||
|
|
||||||
/* FUNCTION PROTOTYPES */
|
/* FUNCTION PROTOTYPES */
|
||||||
static int winnt_pp_open(void);
|
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 reg2offset(int reg);
|
||||||
static unsigned char inb(unsigned short port);
|
static unsigned char inb(unsigned short port);
|
||||||
static void outb(unsigned char value, unsigned short port);
|
static void outb(unsigned char value, unsigned short port);
|
||||||
@@ -81,7 +84,7 @@ static void outb(unsigned char value, unsigned short port);
|
|||||||
|
|
||||||
/* FUNCTION DEFINITIONS */
|
/* FUNCTION DEFINITIONS */
|
||||||
|
|
||||||
int ppi_open(char *port)
|
void ppi_open(char *port, union filedescriptor *fdp)
|
||||||
{
|
{
|
||||||
unsigned char i;
|
unsigned char i;
|
||||||
int fd;
|
int fd;
|
||||||
@@ -91,7 +94,8 @@ int ppi_open(char *port)
|
|||||||
if(fd < 0)
|
if(fd < 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s: can't open device \"giveio\"\n\n", progname);
|
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 */
|
/* Search the windows port names for a match */
|
||||||
@@ -108,10 +112,11 @@ int ppi_open(char *port)
|
|||||||
if(fd < 0)
|
if(fd < 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s: can't open device \"%s\"\n\n", progname, port);
|
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 +161,7 @@ static int winnt_pp_open(void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ppi_close(int fd)
|
void ppi_close(union filedescriptor *fdp)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -166,12 +171,12 @@ void ppi_close(int fd)
|
|||||||
/*
|
/*
|
||||||
* set the indicated bit of the specified register.
|
* 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 char v;
|
||||||
unsigned short port;
|
unsigned short port;
|
||||||
|
|
||||||
port = port_get(fd, reg);
|
port = port_get(fdp, reg);
|
||||||
v = inb(port);
|
v = inb(port);
|
||||||
v |= bit;
|
v |= bit;
|
||||||
outb(v, port);
|
outb(v, port);
|
||||||
@@ -182,12 +187,12 @@ int ppi_set(int fd, int reg, int bit)
|
|||||||
/*
|
/*
|
||||||
* clear the indicated bit of the specified register.
|
* 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 char v;
|
||||||
unsigned short port;
|
unsigned short port;
|
||||||
|
|
||||||
port = port_get(fd, reg);
|
port = port_get(fdp, reg);
|
||||||
v = inb(port);
|
v = inb(port);
|
||||||
v &= ~bit;
|
v &= ~bit;
|
||||||
outb(v, port);
|
outb(v, port);
|
||||||
@@ -199,11 +204,11 @@ int ppi_clr(int fd, int reg, int bit)
|
|||||||
/*
|
/*
|
||||||
* get the indicated bit of the specified register.
|
* 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 char v;
|
||||||
|
|
||||||
v = inb(port_get(fd, reg));
|
v = inb(port_get(fdp, reg));
|
||||||
v &= bit;
|
v &= bit;
|
||||||
|
|
||||||
return(v);
|
return(v);
|
||||||
@@ -215,12 +220,12 @@ int ppi_get(int fd, int reg, int bit)
|
|||||||
/*
|
/*
|
||||||
* toggle the indicated bit of the specified register.
|
* 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 char v;
|
||||||
unsigned short port;
|
unsigned short port;
|
||||||
|
|
||||||
port = port_get(fd, reg);
|
port = port_get(fdp, reg);
|
||||||
|
|
||||||
v = inb(port);
|
v = inb(port);
|
||||||
v ^= bit;
|
v ^= bit;
|
||||||
@@ -233,11 +238,11 @@ int ppi_toggle(int fd, int reg, int bit)
|
|||||||
/*
|
/*
|
||||||
* get all bits of the specified register.
|
* 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 char v;
|
||||||
|
|
||||||
v = inb(port_get(fd, reg));
|
v = inb(port_get(fdp, reg));
|
||||||
|
|
||||||
return((int)v);
|
return((int)v);
|
||||||
}
|
}
|
||||||
@@ -248,9 +253,9 @@ int ppi_getall(int fd, int reg)
|
|||||||
/*
|
/*
|
||||||
* set all bits of the specified register to val.
|
* 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,9 +263,9 @@ int ppi_setall(int fd, int reg, int val)
|
|||||||
|
|
||||||
|
|
||||||
/* Calculate port address to access. */
|
/* 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 +320,77 @@ static void outb(unsigned char value, unsigned short port)
|
|||||||
return;
|
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
|
||||||
|
|
||||||
|
void usleep(unsigned long 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);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
290
avrdude/safemode.c
Normal file
290
avrdude/safemode.c
Normal file
@@ -0,0 +1,290 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "ac_cfg.h"
|
||||||
|
#include "avr.h"
|
||||||
|
#include "pgm.h"
|
||||||
|
#include "safemode.h"
|
||||||
|
|
||||||
|
/* This value from ac_cfg.h */
|
||||||
|
char * progname = PACKAGE_NAME;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 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)
|
||||||
|
{
|
||||||
|
safemode_fuse = 1 + value; //failed - ensure they differ
|
||||||
|
}
|
||||||
|
if(pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
||||||
|
{
|
||||||
|
value = 1 + safemode_fuse; //failed - ensure they differ
|
||||||
|
}
|
||||||
|
if (value == safemode_fuse) {
|
||||||
|
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
||||||
|
{
|
||||||
|
value = 1 + safemode_fuse;
|
||||||
|
}
|
||||||
|
if (value == safemode_fuse)
|
||||||
|
{
|
||||||
|
fusegood = 1; /* Fuse read OK three times */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
safemode_lfuse = 1 + value;
|
||||||
|
}
|
||||||
|
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
||||||
|
{
|
||||||
|
value = safemode_lfuse + 1;
|
||||||
|
}
|
||||||
|
if (value == safemode_lfuse) {
|
||||||
|
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
||||||
|
{
|
||||||
|
value = safemode_lfuse + 1;
|
||||||
|
}
|
||||||
|
if (value == safemode_lfuse){
|
||||||
|
fusegood = 1; /* Fuse read OK three times */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
safemode_hfuse = value + 1;
|
||||||
|
}
|
||||||
|
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
||||||
|
{
|
||||||
|
value = safemode_hfuse + 1;
|
||||||
|
}
|
||||||
|
if (value == safemode_hfuse) {
|
||||||
|
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
||||||
|
{
|
||||||
|
value = safemode_hfuse + 1;
|
||||||
|
}
|
||||||
|
if (value == safemode_hfuse){
|
||||||
|
fusegood = 1; /* Fuse read OK three times */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
safemode_efuse = value + 1;
|
||||||
|
}
|
||||||
|
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
||||||
|
{
|
||||||
|
value = safemode_efuse + 1;
|
||||||
|
}
|
||||||
|
if (value == safemode_efuse) {
|
||||||
|
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
||||||
|
{
|
||||||
|
value = safemode_efuse + 1;
|
||||||
|
}
|
||||||
|
if (value == safemode_efuse){
|
||||||
|
fusegood = 1; /* Fuse read OK three times */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
39
avrdude/safemode.h
Normal file
39
avrdude/safemode.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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__
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
#endif //__safemode_h
|
||||||
648
avrdude/ser_avrdoper.c
Normal file
648
avrdude/ser_avrdoper.c
Normal file
@@ -0,0 +1,648 @@
|
|||||||
|
/*
|
||||||
|
* 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 "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
|
||||||
|
|
||||||
|
extern char *progname;
|
||||||
|
extern int verbose;
|
||||||
|
|
||||||
|
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)) */
|
||||||
490
avrdude/ser_posix.c
Normal file
490
avrdude/ser_posix.c
Normal file
@@ -0,0 +1,490 @@
|
|||||||
|
/*
|
||||||
|
* 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 "serial.h"
|
||||||
|
|
||||||
|
extern char *progname;
|
||||||
|
extern int verbose;
|
||||||
|
|
||||||
|
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 | TCSAFLUSH, &termios);
|
||||||
|
if (rc < 0) {
|
||||||
|
fprintf(stderr, "%s: ser_setspeed(): tcsetattr() failed",
|
||||||
|
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;
|
||||||
|
fd_set wfds;
|
||||||
|
int nfds;
|
||||||
|
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) {
|
||||||
|
reselect:
|
||||||
|
FD_ZERO(&wfds);
|
||||||
|
FD_SET(fd->ifd, &wfds);
|
||||||
|
|
||||||
|
nfds = select(fd->ifd + 1, NULL, &wfds, NULL, &to2);
|
||||||
|
if (nfds == 0) {
|
||||||
|
if (verbose >= 1)
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: ser_send(): programmer is not responding\n",
|
||||||
|
progname);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
else if (nfds == -1) {
|
||||||
|
if (errno == EINTR || errno == EAGAIN) {
|
||||||
|
goto reselect;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf(stderr, "%s: ser_send(): select(): %s\n",
|
||||||
|
progname, strerror(errno));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 */
|
||||||
370
avrdude/ser_win32.c
Normal file
370
avrdude/ser_win32.c
Normal file
@@ -0,0 +1,370 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(WIN32NATIVE)
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h> /* for isprint */
|
||||||
|
#include "serial.h"
|
||||||
|
|
||||||
|
extern char *progname;
|
||||||
|
extern int verbose;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 (hComPort!=INVALID_HANDLE_VALUE)
|
||||||
|
fprintf(stderr, "%s: ser_open(): \"%s\" is already open\n",
|
||||||
|
progname, port);
|
||||||
|
*/
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
size_t len = 0;
|
||||||
|
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 (len) {
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
// 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 */
|
||||||
33
avrdude/serbb.h
Normal file
33
avrdude/serbb.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
void serbb_initpgm (PROGRAMMER * pgm);
|
||||||
|
|
||||||
|
int serbb_setpin(int fd, int pin, int value);
|
||||||
|
int serbb_getpin(int fd, int pin);
|
||||||
|
int serbb_highpulsepin(int fd, int pin);
|
||||||
|
|
||||||
|
#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 "avr.h"
|
||||||
|
#include "pindefs.h"
|
||||||
|
#include "pgm.h"
|
||||||
|
#include "bitbang.h"
|
||||||
|
|
||||||
|
#undef DEBUG
|
||||||
|
|
||||||
|
extern char *progname;
|
||||||
|
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, 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 */
|
||||||
375
avrdude/serbb_win32.c
Normal file
375
avrdude/serbb_win32.c
Normal file
@@ -0,0 +1,375 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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"
|
||||||
|
|
||||||
|
extern char *progname;
|
||||||
|
extern int verbose;
|
||||||
|
|
||||||
|
/* 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, 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 */
|
||||||
68
avrdude/serial.h
Normal file
68
avrdude/serial.h
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* 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 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 */
|
||||||
793
avrdude/stk500.c
793
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
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -22,8 +22,6 @@
|
|||||||
#ifndef __stk500_h__
|
#ifndef __stk500_h__
|
||||||
#define __stk500_h__
|
#define __stk500_h__
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
void stk500_initpgm (PROGRAMMER * pgm);
|
void stk500_initpgm (PROGRAMMER * pgm);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -86,7 +86,7 @@
|
|||||||
#define Parm_STK_PARAMODE 0x94 // ' ' - TRUE or FALSE
|
#define Parm_STK_PARAMODE 0x94 // ' ' - TRUE or FALSE
|
||||||
#define Parm_STK_POLLING 0x95 // ' ' - TRUE or FALSE
|
#define Parm_STK_POLLING 0x95 // ' ' - TRUE or FALSE
|
||||||
#define Parm_STK_SELFTIMED 0x96 // ' ' - 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 ]***************************
|
// *****************[ STK status bit definitions ]***************************
|
||||||
|
|
||||||
|
|||||||
72
avrdude/stk500generic.c
Normal file
72
avrdude/stk500generic.c
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* 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 "pgm.h"
|
||||||
|
#include "stk500.h"
|
||||||
|
#include "stk500v2.h"
|
||||||
|
|
||||||
|
extern char *progname;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stk500generic_initpgm(PROGRAMMER * pgm)
|
||||||
|
{
|
||||||
|
strcpy(pgm->type, "STK500GENERIC");
|
||||||
|
|
||||||
|
pgm->open = stk500generic_open;
|
||||||
|
}
|
||||||
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
|
||||||
|
|
||||||
|
|
||||||
2576
avrdude/stk500v2.c
Normal file
2576
avrdude/stk500v2.c
Normal file
File diff suppressed because it is too large
Load Diff
36
avrdude/stk500v2.h
Normal file
36
avrdude/stk500v2.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* 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__
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
134
avrdude/stk500v2_private.h
Normal file
134
avrdude/stk500v2_private.h
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
//**** 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
|
||||||
|
|
||||||
|
|
||||||
|
// *****************[ 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
|
||||||
|
|
||||||
|
// *****************[ 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
|
||||||
|
|
||||||
|
// *****************[ 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
|
||||||
|
#define PARAM_OSC_PSCALE 0x96
|
||||||
|
#define PARAM_OSC_CMATCH 0x97
|
||||||
|
#define PARAM_SCK_DURATION 0x98
|
||||||
|
#define PARAM_TOPCARD_DETECT 0x9A
|
||||||
|
#define PARAM_STATUS 0x9C
|
||||||
|
#define PARAM_DATA 0x9D
|
||||||
|
#define PARAM_RESET_POLARITY 0x9E
|
||||||
|
#define PARAM_CONTROLLER_INIT 0x9F
|
||||||
|
|
||||||
|
// *****************[ STK answer constants ]***************************
|
||||||
|
|
||||||
|
#define ANSWER_CKSUM_ERROR 0xB0
|
||||||
|
|
||||||
182
avrdude/term.c
182
avrdude/term.c
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -21,14 +21,18 @@
|
|||||||
|
|
||||||
#include "ac_cfg.h"
|
#include "ac_cfg.h"
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
#if defined(HAVE_LIBREADLINE)
|
#if defined(HAVE_LIBREADLINE)
|
||||||
|
#if !defined(WIN32NATIVE)
|
||||||
# include <readline/readline.h>
|
# include <readline/readline.h>
|
||||||
# include <readline/history.h>
|
# include <readline/history.h>
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "avr.h"
|
#include "avr.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@@ -66,6 +70,16 @@ int cmd_quit (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
|
|||||||
|
|
||||||
int cmd_send (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
|
int cmd_send (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
|
||||||
|
|
||||||
|
int cmd_parms (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
|
||||||
|
|
||||||
|
int cmd_vtarg (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
|
||||||
|
|
||||||
|
int cmd_varef (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
|
||||||
|
|
||||||
|
int cmd_fosc (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
|
||||||
|
|
||||||
|
int cmd_sck (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
|
||||||
|
|
||||||
|
|
||||||
struct command cmd[] = {
|
struct command cmd[] = {
|
||||||
{ "dump", cmd_dump, "dump memory : %s <memtype> <addr> <N-Bytes>" },
|
{ "dump", cmd_dump, "dump memory : %s <memtype> <addr> <N-Bytes>" },
|
||||||
@@ -75,6 +89,11 @@ struct command cmd[] = {
|
|||||||
{ "sig", cmd_sig, "display device signature bytes" },
|
{ "sig", cmd_sig, "display device signature bytes" },
|
||||||
{ "part", cmd_part, "display the current part information" },
|
{ "part", cmd_part, "display the current part information" },
|
||||||
{ "send", cmd_send, "send a raw command : %s <b1> <b2> <b3> <b4>" },
|
{ "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)" },
|
||||||
{ "help", cmd_help, "help" },
|
{ "help", cmd_help, "help" },
|
||||||
{ "?", cmd_help, "help" },
|
{ "?", cmd_help, "help" },
|
||||||
{ "quit", cmd_quit, "quit" }
|
{ "quit", cmd_quit, "quit" }
|
||||||
@@ -273,7 +292,7 @@ int cmd_dump(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i<len; i++) {
|
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) {
|
if (rc != 0) {
|
||||||
fprintf(stderr, "error reading %s address 0x%05lx of part %s\n",
|
fprintf(stderr, "error reading %s address 0x%05lx of part %s\n",
|
||||||
mem->desc, addr+i, p->desc);
|
mem->desc, addr+i, p->desc);
|
||||||
@@ -380,7 +399,7 @@ int cmd_write(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
|||||||
werror = 1;
|
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]) {
|
if (b != buf[i]) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"%s (write): error writing 0x%02x at 0x%05lx cell=0x%02x\n",
|
"%s (write): error writing 0x%02x at 0x%05lx cell=0x%02x\n",
|
||||||
@@ -408,6 +427,13 @@ int cmd_send(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
|||||||
int i;
|
int i;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
|
if (pgm->cmd == NULL) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"The %s programmer does not support direct ISP commands.\n",
|
||||||
|
pgm->type);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (argc != 5) {
|
if (argc != 5) {
|
||||||
fprintf(stderr, "Usage: send <byte1> <byte2> <byte3> <byte4>\n");
|
fprintf(stderr, "Usage: send <byte1> <byte2> <byte3> <byte4>\n");
|
||||||
return -1;
|
return -1;
|
||||||
@@ -497,6 +523,152 @@ int cmd_quit(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int cmd_varef(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
double v;
|
||||||
|
char *endp;
|
||||||
|
|
||||||
|
if (argc != 2) {
|
||||||
|
fprintf(stderr, "Usage: varef <value>\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
v = strtod(argv[1], &endp);
|
||||||
|
if (endp == argv[1]) {
|
||||||
|
fprintf(stderr, "%s (varef): can't parse voltage \"%s\"\n",
|
||||||
|
progname, argv[1]);
|
||||||
|
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, v)) != 0) {
|
||||||
|
fprintf(stderr, "%s (varef): failed to set V[aref] (rc = %d)\n",
|
||||||
|
progname, rc);
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int cmd_help(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
int cmd_help(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -626,7 +798,7 @@ int do_cmd(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
|
|||||||
|
|
||||||
char * terminal_get_input(const char *prompt)
|
char * terminal_get_input(const char *prompt)
|
||||||
{
|
{
|
||||||
#if defined(HAVE_LIBREADLINE)
|
#if defined(HAVE_LIBREADLINE) && !defined(WIN32NATIVE)
|
||||||
char *input;
|
char *input;
|
||||||
input = readline(prompt);
|
input = readline(prompt);
|
||||||
if ((input != NULL) && (strlen(input) >= 1))
|
if ((input != NULL) && (strlen(input) >= 1))
|
||||||
@@ -639,7 +811,7 @@ char * terminal_get_input(const char *prompt)
|
|||||||
if (fgets(input, sizeof(input), stdin))
|
if (fgets(input, sizeof(input), stdin))
|
||||||
{
|
{
|
||||||
/* FIXME: readline strips the '\n', should this too? */
|
/* FIXME: readline strips the '\n', should this too? */
|
||||||
strdup(input);
|
return strdup(input);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -26,5 +26,6 @@
|
|||||||
#include "pgm.h"
|
#include "pgm.h"
|
||||||
|
|
||||||
int terminal_mode(PROGRAMMER * pgm, struct avrpart * p);
|
int terminal_mode(PROGRAMMER * pgm, struct avrpart * p);
|
||||||
|
char * terminal_get_input(const char *prompt);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
155
avrdude/tools/get-dw-params.xsl
Normal file
155
avrdude/tools/get-dw-params.xsl
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
<?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: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>
|
||||||
254
avrdude/tools/get-hv-params.xsl
Normal file
254
avrdude/tools/get-hv-params.xsl
Normal file
@@ -0,0 +1,254 @@
|
|||||||
|
<?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: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>
|
||||||
450
avrdude/usb_libusb.c
Normal file
450
avrdude/usb_libusb.c
Normal file
@@ -0,0 +1,450 @@
|
|||||||
|
/*
|
||||||
|
* 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 "serial.h"
|
||||||
|
#include "usbdevs.h"
|
||||||
|
|
||||||
|
extern char *progname;
|
||||||
|
extern int verbose;
|
||||||
|
|
||||||
|
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;
|
||||||
|
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->pfd = udev;
|
||||||
|
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->pfd;
|
||||||
|
|
||||||
|
(void)usb_release_interface(udev, usb_interface);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Without this reset, the AVRISP mkII seems to stall the second
|
||||||
|
* time we try to connect to it.
|
||||||
|
*/
|
||||||
|
usb_reset(udev);
|
||||||
|
|
||||||
|
usb_close(udev);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int usbdev_send(union filedescriptor *fd, unsigned char *bp, size_t mlen)
|
||||||
|
{
|
||||||
|
usb_dev_handle *udev = (usb_dev_handle *)fd->pfd;
|
||||||
|
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 rv;
|
||||||
|
|
||||||
|
rv = usb_bulk_read(udev, USBDEV_BULK_EP_READ, 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->pfd;
|
||||||
|
int i, amnt;
|
||||||
|
unsigned char * p = buf;
|
||||||
|
|
||||||
|
for (i = 0; nbytes > 0;)
|
||||||
|
{
|
||||||
|
if (buflen <= bufptr)
|
||||||
|
{
|
||||||
|
if (usb_fill_buf(udev) < 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->pfd;
|
||||||
|
int rv, n;
|
||||||
|
int i;
|
||||||
|
unsigned char * p = buf;
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
rv = usb_bulk_read(udev, USBDEV_BULK_EP_READ, 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->pfd;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
do {
|
||||||
|
rv = usb_bulk_read(udev, USBDEV_BULK_EP_READ, 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 */
|
||||||
446
avrdude/usbasp.c
Normal file
446
avrdude/usbasp.c
Normal file
@@ -0,0 +1,446 @@
|
|||||||
|
/*
|
||||||
|
* 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$ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 "avr.h"
|
||||||
|
#include "pgm.h"
|
||||||
|
#include "usbasp.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBUSB
|
||||||
|
#include <usb.h>
|
||||||
|
|
||||||
|
extern int verbose;
|
||||||
|
extern char * progname;
|
||||||
|
extern int do_cycles;
|
||||||
|
|
||||||
|
static usb_dev_handle *usbhandle;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* wrapper for usb_control_msg call
|
||||||
|
*/
|
||||||
|
static int usbasp_transmit(unsigned char receive, unsigned char functionid,
|
||||||
|
unsigned char send[4], unsigned char * buffer, int buffersize)
|
||||||
|
{
|
||||||
|
int nbytes;
|
||||||
|
nbytes = usb_control_msg(usbhandle,
|
||||||
|
USB_TYPE_VENDOR | USB_RECIP_DEVICE | (receive << 7),
|
||||||
|
functionid,
|
||||||
|
(send[1] << 8) | send[0],
|
||||||
|
(send[3] << 8) | send[2],
|
||||||
|
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(&usbhandle, USBASP_SHARED_VID, "www.fischl.de",
|
||||||
|
USBASP_SHARED_PID, "USBasp") != 0) {
|
||||||
|
|
||||||
|
/* check if device with old VID/PID is available */
|
||||||
|
if (usbOpenDevice(&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(1, USBASP_FUNC_DISCONNECT, temp, temp, sizeof(temp));
|
||||||
|
|
||||||
|
usb_close(usbhandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int usbasp_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||||
|
{
|
||||||
|
|
||||||
|
unsigned char temp[4];
|
||||||
|
memset(temp, 0, sizeof(temp));
|
||||||
|
usbasp_transmit(1, USBASP_FUNC_CONNECT, temp, temp, sizeof(temp));
|
||||||
|
|
||||||
|
usleep(100000);
|
||||||
|
|
||||||
|
pgm->program_enable(pgm, p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void usbasp_disable(PROGRAMMER * pgm)
|
||||||
|
{
|
||||||
|
/* Do nothing. */
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void usbasp_enable(PROGRAMMER * pgm)
|
||||||
|
{
|
||||||
|
/* Do nothing. */
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void usbasp_display(PROGRAMMER * pgm, char * p)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int usbasp_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
|
||||||
|
unsigned char res[4])
|
||||||
|
{
|
||||||
|
int nbytes =
|
||||||
|
usbasp_transmit(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(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd[0] = address & 0xFF;
|
||||||
|
cmd[1] = address >> 8;
|
||||||
|
|
||||||
|
n = usbasp_transmit(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#else /* HAVE_LIBUSB */
|
||||||
|
|
||||||
|
extern char * progname;
|
||||||
|
|
||||||
|
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 */
|
||||||
55
avrdude/usbasp.h
Normal file
55
avrdude/usbasp.h
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* 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"
|
||||||
|
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
|
||||||
|
#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_BLOCKFLAG_FIRST 1
|
||||||
|
#define USBASP_BLOCKFLAG_LAST 2
|
||||||
|
|
||||||
|
#define USBASP_READBLOCKSIZE 200
|
||||||
|
#define USBASP_WRITEBLOCKSIZE 200
|
||||||
|
|
||||||
|
#define USB_ERROR_NOTFOUND 1
|
||||||
|
#define USB_ERROR_ACCESS 2
|
||||||
|
#define USB_ERROR_IO 3
|
||||||
|
|
||||||
|
void usbasp_initpgm (PROGRAMMER * pgm);
|
||||||
|
|
||||||
|
#endif /* usbasp_h */
|
||||||
42
avrdude/usbdevs.h
Normal file
42
avrdude/usbdevs.h
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* 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_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 */
|
||||||
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
|
bin_PROGRAMS = loaddrv
|
||||||
|
|
||||||
loaddrv_CFLAGS = -mno-cygwin
|
loaddrv_LDFLAGS = -mno-cygwin
|
||||||
|
|
||||||
loaddrv_SOURCES = \
|
loaddrv_SOURCES = \
|
||||||
loaddrv.c \
|
loaddrv.c \
|
||||||
|
|||||||
Reference in New Issue
Block a user