Compare commits

...

1910 Commits

Author SHA1 Message Date
547abf0cf2
Switch fallthrough missing break usbdfu
usbdfu should be updated later...
2023-01-04 23:41:07 +01:00
06b21b6d82
Fixed bad libopencm3 linker file 2023-01-04 23:27:32 +01:00
dragonmux
ad1868f8d4 command: Cleaned up and refactored cmd_rtt
# Conflicts:
#	src/command.c
2022-08-11 19:56:31 -07:00
dragonmux
c712a54cbc rtt: Cleanup and fixes for the RTT over serial support as per #954 2022-08-11 19:45:58 -07:00
Koen De Vleeschauwer
a51d90ba2d rtt
# Conflicts:
#	src/gdb_main.c
2022-08-11 19:45:44 -07:00
Jason Kotzin
f67a4e421d merge fixes and selective optimizations 2022-08-11 19:28:10 -07:00
Jason Kotzin
8fc7a559b2 Merge commit '5cd430647ecfb6dab4a2ed858fb98567723de699' into stable 2022-08-11 19:15:01 -07:00
Jason Kotzin
c9a0be19cb Merge commit '5e3cadec20a5fa3ec6eef53f23520707d0db5380' into sam-update 2022-08-10 22:33:40 -07:00
Jason Kotzin
2ca08f8511 Merge commit '84311b38881ec4a0934686579fec1054feaf5394' into sam-update 2022-08-10 22:32:18 -07:00
Jason Kotzin
3ae3095499 Merge commit 'c4869a54733ae92099a7316954e34d1ab7b6097c' into sam-update 2022-08-10 22:31:16 -07:00
Jason Kotzin
2a792399ca Merge commit 'e535f53981da1fe80137504c761bc854ea8be356' into sam-update 2022-08-10 22:30:11 -07:00
Jason Kotzin
576f575871 Merge commit '7c120ecb582afb588cb391ab32614c4409a2671d' into sam-update 2022-08-10 22:28:35 -07:00
Jason Kotzin
e43b07172b Merge commit 'a3feae60aab1fb85fe44b33123e020a9d7c8e18c' into sam-update 2022-08-10 22:26:37 -07:00
Jason Kotzin
e0f1d29d41 compile fix 2022-08-10 22:26:10 -07:00
Jason Kotzin
2a00dd88ec Merge commit 'b59ca5142ad3a654dc173d598b826f5f453ae52b' into sam-update 2022-08-10 22:21:29 -07:00
Jason Kotzin
c121da06c8 Merge commit 'a0c77e216d268f2e1caa3442db02cf21f36fad91' into sam-update 2022-08-10 22:20:36 -07:00
Jason Kotzin
542c157955 Merge commit 'd9ef3ff14711457eaf0ea7152067c95b4bb45c03' into sam-update 2022-08-10 22:19:41 -07:00
Jason Kotzin
d4dd288426 Merge commit 'bba2bfdcf49695cb9b88482c7ed3db69db58b082' into sam-update 2022-08-10 22:18:39 -07:00
Jason Kotzin
b096e95488 Merge commit 'cedd9f9ac4fc02cc5ac152eb67024f714c6f95ab' into sam-update 2022-08-10 22:17:50 -07:00
Jason Kotzin
7bd7c3d0f5 Merge commit '8fb3b7b1a8d1cb2ac8b54204f452106939eb2ab7' into sam-update
# Conflicts:
#	src/target/adiv5_swdp.c
2022-08-10 22:17:33 -07:00
Jason Kotzin
82673b5e7b Merge commit '82c41cb739e3281e89319bd2fb9627d1a22c803b' into sam-update 2022-08-10 22:09:23 -07:00
Jason Kotzin
9542cd1cfb Merge commit '48c6db19635a804621c7e08e5e3c705aa50e5e9d' into sam-update 2022-08-10 22:08:46 -07:00
Jason Kotzin
328be18288 Merge commit 'd259d5c5110d5867031a9d9ceaaf3725ce242857' into sam-update 2022-08-10 22:07:38 -07:00
Jason Kotzin
03331b3fff Merge commit '4fe8fd8944ad49e40a46287e2286328af6871226' into sam-update 2022-08-10 22:06:28 -07:00
Jason Kotzin
ca1c0acb27 Merge commit '23534ab174ffadd63bbdb2e0626770753eff7c3b' into sam-update 2022-08-10 22:05:07 -07:00
Jason Kotzin
b4af0f5145 Merge commit '7d2afcff06f1ccd9fe583d562ddd81e04a17e166' into sam-update 2022-08-10 20:40:24 -07:00
Jason Kotzin
e174c5b503 Merge commit 'd594b42976e3b9640b64ef1cb2da3f74067930b8' into sam-update
# Conflicts:
#	README.md
#	src/platforms/common/cdcacm.c
#	src/target/adiv5_swdp.c
2022-08-10 20:39:54 -07:00
Jason Kotzin
c91322e38e fix stack compile warning 2022-08-10 20:37:14 -07:00
Jason Kotzin
85fc728293 Merge commit '59dc2255687436d7a21458615e4eb2e563ca64c1' into sam-update 2022-08-10 20:32:50 -07:00
Jason Kotzin
6727e74daf Merge commit '28623e6b275b90817894ddcbf915dbb8c6686433' into sam-update 2022-08-10 20:31:54 -07:00
Jason Kotzin
d7bf91d039 Merge commit '7ccbdd98c0bd18c2a672ed50aa1f96aff97dd4af' into sam-update 2022-08-10 20:31:11 -07:00
Jason Kotzin
878dc379b9 updates for merge 2022-08-10 20:30:57 -07:00
Jason Kotzin
4f97627b02 Merge commit '64f756d62791e16728e6c9d7877ce2ab620b9c1c' into sam-update 2022-08-10 20:25:30 -07:00
Jason Kotzin
56858650cb Merge commit '88cce08ce47b7b6f6f40b404fa79c6be687ab7e3' into sam-update 2022-08-10 20:24:43 -07:00
Jason Kotzin
dcbb1657b4 Merge commit 'da15cc3cb75cc2a9f604436402f6a81d42b27dce' into sam-update 2022-08-10 20:23:40 -07:00
Jason Kotzin
9dc79becc2 Merge commit '35687018eb634ea329609c86d9ed476bb79c0e91' into sam-update
# Conflicts:
#	src/platforms/common/cdcacm.c
#	src/target/adiv5_swdp.c
2022-08-10 20:19:55 -07:00
Jason Kotzin
9ec6693e4d Merge commit '2a0d608b07487300a63908baa62e73a51a11e811' into sam-update 2022-08-10 20:14:55 -07:00
Jason Kotzin
a2f6776bf8 Merge commit '8089e05a0018a040251ec5de145bccca0977bf78' into sam-update 2022-08-10 20:13:59 -07:00
Jason Kotzin
cb1ef7d616 Merge commit '1330288271bea7b6224bac5bc8e1438305eec44a' into sam-update 2022-08-10 20:09:58 -07:00
Jason Kotzin
def176b240 Merge commit '8da2dee0c41eead0c2b4f466fbc889ef413cf7e9' into sam-update 2022-08-10 20:08:13 -07:00
Jason Kotzin
d5a8717bb0 stack bug fix 2022-08-10 20:08:05 -07:00
Jason Kotzin
8acda14170 Merge commit '23f942ac8c7553f743128d9f96f0d2aa61fbc4bd' into sam-update 2022-08-10 20:07:25 -07:00
Jason Kotzin
c1e34792f4 Merge commit '04d1c9805b80b50b4f1cd33b08503b73e80c0ed3' into sam-update 2022-08-10 20:06:04 -07:00
Jason Kotzin
c5b6f066b8 Merge commit 'b6fbf86743509559fce4c56345e8fdc16df14a08' into sam-update 2022-08-10 19:55:26 -07:00
Jason Kotzin
f109bc2e98 Merge commit '61e237ec87c525876817e72fc82ce28b2a4951ae' into sam-update 2022-08-10 19:53:14 -07:00
Jason Kotzin
d36213b7d0 Merge commit 'be3bfc48a8be7cd4d84709e98c5def13259d49f6' into sam-update
# Conflicts:
#	README.md
2022-08-10 19:49:50 -07:00
Jason Kotzin
389bb03fc0 Merge commit 'db17f2caa8dcbf229670ba03b46be274656c6d72' into sam-update 2022-08-10 19:48:49 -07:00
Jason Kotzin
78837173a4 Merge commit 'e6a9a1a3665e83e25d5d4077a33aa5b0110646b8' into sam-update
# Conflicts:
#	.gitignore
2022-08-10 19:48:21 -07:00
Jason Kotzin
4328e8a4c1 Merge commit 'aa0d8f4b5de13f4fb7324a690a4bb7aa411e767f' into sam-update 2022-08-10 19:46:16 -07:00
Jason Kotzin
646fbcb21f fixes for upstream 2022-08-10 19:46:01 -07:00
Jason Kotzin
9da2d298c3 Merge commit '1ca9f234f7527396da91bfc1f98cb05c305c6472' into sam-update 2022-08-10 19:30:49 -07:00
Jason Kotzin
95a4ebf836 Merge commit '7365a44989c7c8561c583f75ff30f7277e712ff3' into sam-update 2022-08-10 19:30:16 -07:00
Jason Kotzin
3024cc1bfe minor update to libopencm3, only build samd to speed up merge 2022-08-10 19:28:12 -07:00
Jason Kotzin
7340b0065d Merge commit '93d4c659481c918b43c0068e69050ef1ad4ca91e' into sam-update 2022-08-10 19:08:37 -07:00
Jason Kotzin
dd01fe9ad3 upstream compile fixes 2022-08-10 19:08:35 -07:00
Jason Kotzin
336797363b Merge commit '98b4ec58bc566591943c9123dd4ca0c8dcfd521e' into sam-update
# Conflicts:
#	libopencm3
2022-08-10 19:08:25 -07:00
Jason Kotzin
046cc359ba Merge commit 'dd6aadc54d00cee92e14bf7538d3ece3d3ab298f' into sam-update 2022-08-10 18:37:14 -07:00
Jason Kotzin
9e02c5f0cd Merge commit 'cda83d308490738b54df0405cca3c0c048809664' into sam-update
# Conflicts:
#	src/Makefile
2022-08-10 18:36:23 -07:00
Jason Kotzin
c73329f7d4 Merge commit '59dc1b7eb4f3a0fda23d2c8624c3ecd26515fec8' into sam-update
# Conflicts:
#	src/platforms/common/cdcacm.c
2022-08-10 18:33:59 -07:00
Jason Kotzin
d90c207c50 adding cscope files to git ignore 2022-08-10 18:24:35 -07:00
Jason Kotzin
b87091a59b Merge commit 'dc8924a2bc0110287c1b289002efb52926daccb0' into sam-update
# Conflicts:
#	README.md
2022-08-10 18:24:25 -07:00
Jason Kotzin
f8aff4bf4b upstream fixes 2022-08-10 18:19:15 -07:00
Jason Kotzin
50b9a4ceb6 Merge commit '77231e8972fa22cb233354ba5aed694dff4a9e24' into sam-update 2022-08-10 17:40:26 -07:00
Jason Kotzin
93cf62d944 Merge commit '8289862b55e2a0dc658c3c7e2f6ab9878d0527fa' into sam-update
# Conflicts:
#	README.md
#	src/platforms/common/cdcacm.c
2022-08-10 17:40:24 -07:00
Jason Kotzin
09e45cea5b Merge commit 'a4cdd6b3103cdf6c1f8454fb81558ff98a8d912d' into sam-update 2022-08-10 17:36:48 -07:00
Jason Kotzin
65c95fb413 Merge commit 'f5e305e237aba0ab8bf2f42e75505ef468f47d82' into sam-update
# Conflicts:
#	README.md
2022-08-10 17:36:47 -07:00
Jason Kotzin
c643726c9d Merge commit 'da45281696b05089d694e6e9c7734968b9496865' into sam-update 2022-08-10 17:35:15 -07:00
Jason Kotzin
eda19bc28d Merge commit 'ef816e318391c64014554140be65a5cafc6c8be2' into sam-update
# Conflicts:
#	.gitignore
2022-08-10 17:34:55 -07:00
Jason Kotzin
9b145c8398 compatibility to upstream 2022-08-10 17:27:05 -07:00
Jason Kotzin
53c6821734 Merge commit '9969c984f3ca67f38677b061e2f91a1fb50cd310' into sam-update 2022-08-10 15:57:56 -07:00
Jason Kotzin
842a0b4193 compatibility with merge changes 2022-08-10 15:57:41 -07:00
Jason Kotzin
8a37449f8a Merge commit 'e34a27f72c9689850e97df74c499538d7f18518d' into sam-update
# Conflicts:
#	src/include/swdptap.h
#	src/platforms/common/swdptap.c
2022-08-10 15:57:29 -07:00
Jason Kotzin
21989d4142 Merge commit '1e10b96b03da71b1a101c108ca9511c8a613666e' into sam-update 2022-08-09 22:17:14 -07:00
Jason Kotzin
63449912e2 Merge commit 'f3790b90e5ecf44525dc05f05a4e72f74baea411' into sam-update 2022-08-09 22:11:55 -07:00
Jason Kotzin
1661396951 Merge commit '05adcd9bf5b36d099627aff6b73e463030ee417f' into sam-update 2022-08-09 22:06:01 -07:00
Jason Kotzin
fd6610bdae samd fix USB max packet size 2022-08-09 17:31:30 -07:00
Jason Kotzin
19e01abf70 Merge commit '16967b43288028dcdc2759bb2a25a53472571162' into sam-update 2022-08-09 17:25:16 -07:00
Jason Kotzin
a89b2ead47 Merge commit '541861e978ba88c80e7e2a0cbcd7ce55d574c97b' into sam-update
# Conflicts:
#	README.md
2022-08-09 17:23:48 -07:00
Jason Kotzin
81cfa0a380 Merge commit '1a83bc68920ad20ad044e9110c3599e3ac1f76c0' into sam-update
# Conflicts:
#	src/command.c
2022-08-09 17:22:19 -07:00
Jason Kotzin
41449370b4 Merge commit 'd63e870e82ecbd73af2d14e6794d2985cb9bd0ad' into sam-update 2022-08-09 17:13:06 -07:00
Jason Kotzin
73285885b3 Merge commit 'a0e42e229b99dad09f3c2eaf1455cbefc776cbe8' into sam-update 2022-08-09 17:11:21 -07:00
Jason Kotzin
b71213522a change spec to decrease code size 2022-08-08 21:14:10 -07:00
Jason Kotzin
c0c5255103 libopencm3 regression fix 2022-08-08 21:06:18 -07:00
Jason Kotzin
a2cdb32f14 Merge commit '2e185ba578cf996a9e6cd7b6a0321a2448064e52' into sam-update 2022-08-02 09:35:57 -07:00
Jason Kotzin
1930380e16 Merge commit '0b6f393d5b1ab03fc0dcd8b172261e7a52bdd3d8' into sam-update 2022-08-02 09:35:19 -07:00
Jason Kotzin
5509264a2b Merge commit 'ea779d13725f1c2c580c5c11c47267af09b6b007' into sam-update 2022-08-02 09:35:09 -07:00
Jason Kotzin
6f902bcfe7 optimization flag for jeff probe 2022-08-02 09:35:01 -07:00
Jason Kotzin
fdce017311 Merge commit 'f89542c79f6edb0d64e7dfa483501718113f45b5' into sam-update 2022-08-02 09:28:24 -07:00
Jason Kotzin
96a980b682 Merge commit '286b987822a685f6ff86f6522da3733a0c9d7757' into sam-update
# Conflicts:
#	src/command.c
2022-08-02 09:28:14 -07:00
Jason Kotzin
cedcd1a832 Merge commit '71b8a4e0818026fa25e9fa95b2cd3c0dd407b3a2' into sam-update 2022-08-02 09:21:00 -07:00
Jason Kotzin
1737788a92 Merge commit 'd1ee827b4df710a0f693f6df7808cb5d75b2530c' into sam-update 2022-08-02 09:20:50 -07:00
Jason Kotzin
f65793582d Merge commit '5704c2fb5a07bbe7982a368e6ab7762a6866988f' into sam-update
# Conflicts:
#	src/Makefile
2022-08-02 09:20:27 -07:00
Jason Kotzin
90a7ecaaf1 Merge commit 'e8bd066fe96f72c6998aea7c0d80d6de019b825d' into sam-update
# Conflicts:
#	README.md
2022-08-02 01:31:38 -07:00
Jason Kotzin
b6896898c2 Merge commit '82be49f05212d36733ab99c6f83ef93a7ff444d1' into sam-update 2022-08-02 01:31:04 -07:00
Jason Kotzin
81bb75bba6 Merge commit '443ced62d4e47d73da13746a836369d8421b4fe8' into sam-update
# Conflicts:
#	libopencm3
2022-08-02 01:23:28 -07:00
Jason Kotzin
6661871707 Merge commit 'fbf196378e5bbeffad02439fa974f6142a78d6a2' into sam-update 2022-08-01 21:46:52 -07:00
Jason Kotzin
885fdcc354 Merge commit '5107a29699904fb4e60907d1e9b2438592f6a3ff' into sam-update 2022-08-01 21:46:24 -07:00
Jason Kotzin
16261813ca Merge commit 'e29f2b4fb95601291afced3af3731385be343988' into sam-update
# Conflicts:
#	.gitignore
#	src/include/swdptap.h
#	src/target/swdptap_generic.c
2022-08-01 21:45:01 -07:00
Jason Kotzin
fcf5b74542 Merge commit '067956266c886d377231ffdd89e630e41aeb2783' into sam-update 2022-08-01 20:43:02 -07:00
Jason Kotzin
539fba02ac Merge commit '9e898cc4b8f3e1a5844a3693412a9977a65a0a63' into sam-update 2022-08-01 20:30:35 -07:00
Jason Kotzin
4a2a121e89 Merge commit 'dd3cb193f3a83e99b5a915e9942c295b9d9715d7' into sam-update 2022-08-01 20:30:04 -07:00
Jason Kotzin
16b827e4e4 Merge commit 'c44cb904b0d345753b40ac9649bb4c611855a5c4' into sam-update
# Conflicts:
#	src/target/adiv5.c
2022-08-01 20:29:58 -07:00
Jason Kotzin
a9197e67ea Merge commit '205fce20e5ade52b6331e315ccd0700293f51aac' into sam-update 2022-08-01 20:22:28 -07:00
Jason Kotzin
ab63700a80 Merge commit '9ed26645d332dbd1d725ccef64199ef13604686c' into sam-update 2022-08-01 20:22:07 -07:00
Jason Kotzin
0993a8ae28 Merge commit 'fd3af639b0f8eb816d4efc860f549e8c01454826' into sam-update 2022-08-01 20:21:48 -07:00
Jason Kotzin
a7c4a0c108 Merge commit 'bd530c8951f8393e8d799d25f233c77051b10561' into sam-update 2022-08-01 20:21:34 -07:00
Jason Kotzin
bb97e35f82 Merge commit '5aebef4f64d0fd4c19f794fb9725686c39a7e395' into sam-update 2022-08-01 20:21:13 -07:00
Jason Kotzin
cbed6c911f Merge commit 'df7458e35a67abb216d9816c59f218cad45f1c44' into sam-update 2022-08-01 20:20:38 -07:00
Jason Kotzin
272b461b3e Merge commit 'b4c680bb150b815df401c98c45f03ff45e5a231f' into sam-update 2022-08-01 20:18:49 -07:00
Jason Kotzin
a29d53cb31 Merge commit '600bc9f0294f07a5572511c98041710d80d95769' into sam-update 2022-08-01 20:18:03 -07:00
Jason Kotzin
4947f0f747 Merge commit '61e9607594586fe5018157f566b8b79a398444b7' into sam-update
# Conflicts:
#	src/Makefile
2022-08-01 20:17:24 -07:00
Jason Kotzin
a6f8944afe Merge commit '88ec55768389c6c4de69ecd6e101f6b136c25a8f' into sam-update 2022-08-01 20:10:32 -07:00
Jason Kotzin
33c0319263 Merge commit '2b4000b2b44ca629d18d96a803413c71ab7b8e52' into sam-update 2022-08-01 20:09:50 -07:00
Jason Kotzin
93cad1ca5a Merge commit 'cdb04a4214cfd1d94a7fe2fd1837b91ec099db28' into sam-update 2022-08-01 20:09:24 -07:00
Jason Kotzin
9a9fac2e83 Merge commit '02c1934c03eb86901634ed63e0cc9b13eb743fa8' into sam-update 2022-08-01 20:08:54 -07:00
Jason Kotzin
a285b2ac17 Merge commit '7032abd2b00d4548d41f7f1abbdf0837bc283def' into sam-update
# Conflicts:
#	src/Makefile
2022-08-01 20:08:51 -07:00
Jason Kotzin
4b4d0fcfcf Merge commit 'a65ce77466077b4259d99232d6f3c168b476ce79' into sam-update 2022-08-01 20:05:36 -07:00
Jason Kotzin
6b2b1aa4c3 Merge commit '525b90d4e5d07f431a1d0f4e5d2abf9e6c691e10' into sam-update 2022-08-01 20:04:51 -07:00
Jason Kotzin
fce7dd2957 Merge commit '7f947d724c552f896d5394f3ebbf6b47de9eb5a6' into sam-update 2022-08-01 20:04:01 -07:00
Jason Kotzin
6b2f0aeb63 Merge commit 'db544e9b671719e553bb6aec9e2e39294c3ee027' into sam-update 2022-08-01 20:03:40 -07:00
Jason Kotzin
4cae565ef3 Merge commit 'a988bba035824ddc97b2cf3aadc457dcd85aaad0' into sam-update 2022-08-01 20:02:30 -07:00
Jason Kotzin
d76fd844c9 Merge commit '05518094752e450708aced3397cb26146e8ce0d3' into sam-update 2022-08-01 19:59:54 -07:00
Jason Kotzin
27a099a94b Merge commit '46b681e050bbfb27acafab88a3b67bda292825ca' into sam-update 2022-08-01 19:58:15 -07:00
Jason Kotzin
9c33ce7979 Merge commit '7a7266a0f7e38a9359f84fe1fb34453e8b2b16ae' into sam-update
# Conflicts:
#	src/platforms/common/swdptap.c
2022-08-01 19:57:12 -07:00
Jason Kotzin
1612eacab2 Merge commit '5548d54626a658b65f1f963cd5af54ddaf93fbf7' into sam-update
# Conflicts:
#	src/platforms/common/swdptap.c
2022-08-01 19:56:08 -07:00
Jason Kotzin
f1f59d3c1d Merge commit '7e3fe352ad4aed89522d808d76dbe868a470412e' into sam-update
# Conflicts:
#	src/platforms/common/swdptap.c
2022-08-01 19:54:44 -07:00
Jason Kotzin
a42fc8904d Merge commit 'e54a826745ae298a4eb555f3d76dfcdd571211b9' into sam-update
# Conflicts:
#	src/platforms/common/swdptap.c
2022-08-01 19:52:55 -07:00
Jason Kotzin
f62c9db5af Merge commit 'd4d24c256c2c9a858ae6fc134ee34ba03cb65565' into sam-update 2022-08-01 19:21:49 -07:00
Jason Kotzin
1ba83f3283 Merge commit '17b817f37bca85c9b469470742ecdeedf02f7b3e' into sam-update 2022-08-01 19:21:27 -07:00
Jason Kotzin
c33a447210 Merge commit '9e365a58f77a9096b0203a5f012bb7bfb08fbc95' into sam-update 2022-08-01 19:21:10 -07:00
Jason Kotzin
81fafae68d Merge commit '44fc24e0e747293fa05b62ed7439501553829b0b' into sam-update 2022-08-01 19:20:52 -07:00
Jason Kotzin
447bdc50a0 Merge commit '66e357d51762f3bf93b549a5626554b2f8de4379' into sam-update
# Conflicts:
#	src/target/adiv5.c
2022-08-01 19:20:32 -07:00
Jason Kotzin
b91712214f Merge commit '1799ea3b7102ac1e2a86d78cdbde0f5b809b0be1' into sam-update 2022-08-01 19:03:03 -07:00
Jason Kotzin
5574a14aee Merge commit 'b7a59afc5920caf1e83cd470aee67f665d0e7197' into sam-update 2022-08-01 19:01:41 -07:00
Jason Kotzin
a82ab6a45d Merge commit '80f003ff4b6edc9d0d2b98b4ca65d610d86efc74' into sam-update 2022-08-01 19:01:18 -07:00
Jason Kotzin
40ea78d57b Merge commit '48d232807ee6096bfa839d91b1708252db0e1a59' into sam-update 2022-08-01 18:59:50 -07:00
Jason Kotzin
eab16ef39f Merge commit '0f2f1d74a2446275ee31ed582f1f4d98dff24d61' into sam-update 2022-08-01 18:57:07 -07:00
Jason Kotzin
da701aff6d Merge commit '455e0a74d2a77f2ae1f0acf53b778e41b890523e' into sam-update 2022-08-01 18:56:50 -07:00
Jason Kotzin
aece87bf3e Merge commit 'cfaa5ea9633fb8719da9455f6c04908810395abe' into sam-update 2022-08-01 18:54:48 -07:00
Jason Kotzin
2931169dd1 Merge commit '0c659f49cd03c7154bfb92c621df523aa8540f72' into sam-update 2022-08-01 18:52:34 -07:00
Jason Kotzin
95655b838e Merge commit '231d42d58172a2169d99c6e618192ac0d514d3b9' into sam-update 2022-08-01 18:50:19 -07:00
Jason Kotzin
1846795844 Merge commit '19e58a7205e2dfe849b5ac42e470ff489e4ab10d' into sam-update 2022-08-01 18:36:22 -07:00
Jason Kotzin
76c2f5e39c Merge commit 'eb46994bc95ba308f8eb96d42366abbdae7c5ab7' into sam-update 2022-08-01 18:35:43 -07:00
Jason Kotzin
51f2b79437 Merge commit '1ee1f441d581b6473526a4870f4c3aa201a18af6' into sam-update 2022-08-01 18:34:34 -07:00
Jason Kotzin
02eafe9883 Merge commit 'c7bc51d1919bce00c341b2b2e1e617adcf189be9' into sam-update 2022-08-01 18:33:40 -07:00
Jason Kotzin
05a42576c2 Merge commit 'a4bb2c6e3ea8404641325638a040e3295b7afe30' into sam-update 2022-08-01 18:33:13 -07:00
Jason Kotzin
39949eefe2 Merge commit 'fd467269eb82783c09a69763c46df4de2d494ef4' into sam-update 2022-08-01 18:32:42 -07:00
Jason Kotzin
d7afc92b5f Merge commit '539d9e14ec553c77b2c3387b4719d8f07401d6a7' into sam-update 2022-08-01 18:32:18 -07:00
Jason Kotzin
44b5eed7ca Merge commit '261be9864c8ce77c857a996784ac65ed3203b03a' into sam-update 2022-08-01 18:31:34 -07:00
Jason Kotzin
4346fb2405 Merge commit '98a4f8e31872d3f72e47aba8b01a167503144c1e' into sam-update 2022-08-01 18:31:06 -07:00
Jason Kotzin
9c95dfb712 adding adiv5 support 2022-08-01 17:45:49 -07:00
Jason Kotzin
f99fe59ce8 updating libopencm3 with samd i2c support 2022-08-01 17:45:30 -07:00
dragonmux
5cd430647e
gdb_main: Fixed a small DEBUG_GDB regression for vFlashErase and vFlashWrite debugging 2022-07-21 07:14:47 +01:00
dragonmux
fc55400aad
gdb_main: Implemented a notification to GDB that the "process" has exited when the user runs a new bus scan while attached to a target 2022-07-21 05:45:23 +01:00
dragonmux
d2370f780f
gdb_packet: Implement notification packets 2022-07-21 05:45:23 +01:00
dragonmux
f254e86511
gdb_main: Add some output in the scan commands to indicate when still attached that you aren't after the command, despite what GDB thinks 2022-07-21 05:45:22 +01:00
dragonmux
3cc6aa1236
gdb_main: Implemented qfThreadInfo and qsThreadInfo for GDB 11+ 2022-07-21 05:45:22 +01:00
dragonmux
65ac074410
gdb_main: Implemented vKill as it's required for GDB 11+ 2022-07-21 05:45:22 +01:00
dragonmux
c6d1bcb352
gdb_main: Cleaned up the naming in the 'g' and 'G' packet handlers 2022-07-21 05:45:22 +01:00
dragonmux
eb9d9893f8
hex_utils: Cleaned up and fixed the type confusion that was going on 2022-07-21 05:45:22 +01:00
dragonmux
8db1d30852
gdb_main: Reply to vAttach with TID 1 because GDB 11 and 12 are terminally broken otherwise 2022-07-21 05:45:21 +01:00
dragonmux
1f22c72634
gdb_main: Implemented support for qC queries 2022-07-21 05:45:21 +01:00
dragonmux
7322bb3ffa
gdb_main: More type confusion fixes and cleanup 2022-07-21 05:45:19 +01:00
dragonmux
17ba28c44b
gdb_main: Implemented H[m|M|g|G|c] packet support 2022-07-21 05:44:21 +01:00
dragonmux
47c84fac85
gdb_packet: Done a spring pass on the types situation and cleaned things up 2022-07-21 05:43:55 +01:00
Piotr Esden-Tempski
1cf1ba1ddb stm32f4: Fixes erase_mass command return error.
The final erase_mass command check is looking for the EOP (End of
OPeration) bit to be set. This bit is only set when the EOP interrupts
(EOPIE = 1) are enabled. We are not enabling those on the target so this
bit will never get set. As we are monitoring the BSY flag to make sure
the erase_mass operation is still ongoing and finished it is enough if
we just check the error flags.
2022-07-13 21:06:53 -07:00
dragonmux
34696c0fec
target: Make the buffers used to program a target's Flash better bounded in lifetime and memory usage 2022-07-13 22:28:33 -04:00
Piotr Esden-Tempski
a067e801d7
BMP V2.3: Fix outdated ADC reads.
We are using GD32F103 on the BMP V2.3 hardware. The GD32F103 has an
errata for the ADC where the end of conversion (EOC) bit is not reset
when reading the ADC result. This resulted in us not waiting for the new
value to be acquired and reading an old value instead. The solution for
that is resetting the EOC bit manually after reading the ADC result, so
that on the next acquisision we wait for the conversion to finish.

This patch also increases the sampling time as the GD32 have lower ADC
impedance than the STM32 and this should help us read a more accuarate
target voltage.
2022-07-13 20:54:14 -04:00
dragonmux
d01acd8030
kinetis: Clean up how kl_gen_flash_done builds the command buffers to send to ensure the security byte is OK 2022-07-11 20:17:53 -04:00
dragonmux
0dffd2ffd2
kinetis: Fixed the flash write command generation for K64 devices 2022-07-11 20:17:52 -04:00
dragonmux
0f1006bf08
kinetis: Try to be safer about our FCCOB writes so the Flash controller's less likely to get mad 2022-07-11 20:17:52 -04:00
Rafael Silva
f69ed07ba7
kinetis: macro organization and clearer function naming
Signed-off-by: Rafael Silva <perigoso@riseup.net>
2022-07-09 19:12:05 -04:00
dragonmux
9591649ec6
kinetis: Run clang-format on the code 2022-07-09 19:10:40 -04:00
dragonmux
e9abd83412
kinetis: Refactored out some common code from kinetis_probe for the S32K14 lineup 2022-07-09 19:10:39 -04:00
dragonmux
4de54fbee6
kinetis: General formatting and readability cleanup 2022-07-09 19:10:39 -04:00
dragonmux
77a83f4ffc
ch32f1: Fixed another broken debug print that made assumptions about %x and %d that are wrong 2022-06-26 17:34:22 -04:00
dragonmux
d613d29839
cortexm: Added additional debug information for part probing 2022-06-26 17:34:22 -04:00
dragonmux
c7c5f68a84
ch32f1: Re-ordered a couple of the operation in ch32f1_probe so it plays nicer with the STM32 parts 2022-06-26 17:34:22 -04:00
dragonmux
d9f4d069e6
ch32f1: Further formatting and layout cleanup 2022-06-26 17:34:22 -04:00
dragonmux
eb8bb01c57
ch32f1: Fixed the probe routine distrubing state for other parts wrt t->idcode
The CH32F1 routine now reads the IDCode into a local.
If the part number matches and appears to be the chip (based on Flash locking), it only then writes the IDCode into `t->idcode`, which is at the point we can only `return true` from the probe routine anyway.
2022-06-26 17:34:22 -04:00
dragonmux
7e91c401d3
ch32f1: formatting cleanup to bring things closer to inline with the rest of the codebase 2022-06-26 17:34:09 -04:00
Maciej Musiał
54790f032e
cortexm: fixed an issue with watchpoint handling and a register sanity check 2022-06-26 17:32:19 -04:00
dragonmux
08956eb4fb
gdb_main: Fix a formatting bug that breaks, among other things, breakpoints 2022-06-26 17:31:13 -04:00
Mikaela Szekely
289d963ba5 Complete the version string migration from 5e3cade, fixing HOSTED_BMP_ONLY 2022-06-03 14:45:16 -07:00
Piotr Esden-Tempski
5e3cadec20 Updated Copyright and Vendor strings to Black Magic Debug.
The project is not part of Black Sphere Technologies any more. It was
renamed to Black Magic Debug instead.
2022-05-30 15:09:55 -07:00
Piotr Esden-Tempski
84311b3888 docs: Corrected org in links to blackmagic-debug 2022-05-30 14:32:36 -07:00
Piotr Esden-Tempski
9b5b6fab5b upgrade: Changed copyright to BMD and allowed more vendor strings. 2022-05-30 14:30:06 -07:00
Piotr Esden-Tempski
e4d692bf7a driver: Updated vendor name to Black Magic Debug. Closes #1009 2022-05-30 14:30:00 -07:00
dragonmux
434a23b478
misc: Corrected the patreon link in FUNDING.yml 2022-05-25 18:57:38 -04:00
dragonmux
0ee03080c3
misc: Added Esden's patreon to FUNDING.yml 2022-05-25 16:31:33 -04:00
dragonmux
754d65ad54
misc: Added GitHub funding configuration for the project 2022-05-25 14:37:55 -04:00
dragonmux
29dc94c3d6 hosted: with mubes help, fixes some issues with how we talk CMSIS-DAP 2022-05-17 15:46:33 -07:00
dragonmux
c4869a5473 hosted/stlinkv2: Cleaned up the new error messages as they weren't outputting nicely 2022-04-16 18:22:14 -04:00
dragonmux
a27661cd0b hosted/platform: Formatting consistency improvements 2022-04-16 18:22:14 -04:00
dragonmux
ba8ed132a8 hosted/stlinkv2: Fix !found causing hosted to continue on anyway, and improved the error reporting from the device finder loop 2022-04-16 18:22:14 -04:00
dragonmux
4287f1ba0e hosted/stlinkv2: Rewrote the serial number readering logic to not violate the USB spec and properly handle libusb errors 2022-04-16 18:22:14 -04:00
dragonmux
94e9281404 hosted/bmp_libusb: Rewrote the string reader logic to not violate the USB spec and properly handle libusb errors 2022-04-16 18:22:14 -04:00
dragonmux
c7eba0a439 hosted/bmp_libusb: Fixed some signed/unsigned issues and UB in send_recv 2022-04-16 18:22:14 -04:00
dragonmux
c5dbf851f6 hosted/bmp_libusb: Formatting cleanup 2022-04-16 18:22:14 -04:00
Nicolas Schodet
6c700f7b6c scripts: bootprog.py: use bytes literals 2022-04-15 11:59:40 -07:00
Michal Moskal
6b465d6a77 Temporarily enable DBG clock in stm32g0_detach(); fixes #1003 2022-04-12 05:39:14 -04:00
mean
e535f53981 remove static vars 2022-04-10 23:40:44 -04:00
mean
7c120ecb58 put ch32f1 in its own file 2022-04-10 23:40:44 -04:00
mean
a3feae60aa cleanup tabs 2022-04-10 23:40:44 -04:00
mean
844ca65a8f cosmetic 2022-04-10 23:40:44 -04:00
mean
04eb33e039 rename to comply to naming scheme 2022-04-10 23:40:44 -04:00
mean
fb216a2a98 tabify 2022-04-10 23:40:44 -04:00
mean
17dca6f791 tabify 2022-04-10 23:40:44 -04:00
mean
e12939582c revert function clones_probe 2022-04-10 23:40:44 -04:00
mean
9b23265dde add support for ch32 flash write, it is a bit hackish 2022-04-10 23:40:44 -04:00
mean
733cf12663 cleanup 2022-04-10 23:40:44 -04:00
mean
83e3d9c135 disable verification 2022-04-10 23:40:44 -04:00
mean
90d15e6633 add probe for ch32 + make room for other clones 2022-04-10 23:40:44 -04:00
mean
17d7dca9ae build ch32 in its own file 2022-04-10 23:40:44 -04:00
dragonmux
be83c2861e
gdb_packet: Formatting cleanup 2022-03-31 14:11:38 -04:00
dragonmux
e424859ecb
gdb_main: Formatting cleanup 2022-03-31 14:03:29 -04:00
dragonmux
804a1a4f43
stm32f4: Attach logic cleanup by making sure we only set the extra bits needed when writing DBGMCU_CR 2022-03-31 13:46:29 -04:00
Uwe Bonnes
eed1cc81ff STM32F4: Move DBGMCU_handling to target specific code. Apply for F4 too. 2022-03-31 13:43:52 -04:00
Piotr Esden-Tempski
b59ca5142a pc hosted: Don't try to report memory usage.
When building on a pc gcc does not have that parameter and clang fails
with an error. This caused a build regression on Mac.
2022-03-29 16:45:08 -07:00
dragonmux
a0c77e216d adiv5_swdp: Changed the low-level access code to retry till timeout (partial revert of 61efe26)
Proper initialisation of the ack value also fixes a potential use-before-init UB
2022-03-29 15:33:23 -07:00
dragonmux
d9ef3ff147 adiv5_swdp: Formatting consistency cleanup 2022-03-29 15:33:23 -07:00
dragonmux
bba2bfdcf4 advi5: Raise the access timeouts as 20ms is too low in some cases 2022-03-29 15:33:23 -07:00
mean
cedd9f9ac4 follow function naming scheme 2022-03-22 10:10:33 -04:00
mean
8fb3b7b1a8 reuse exception to avoid using the stack 2022-03-22 10:10:33 -04:00
mean
82c41cb739 add putpacket2 to send two sub messages merged as one 2022-03-22 10:10:33 -04:00
mean
9007c40954 revert temp patch on platform.h 2022-03-22 10:10:33 -04:00
mean
8b52bbd9a9 fix unused var / naming 2022-03-22 10:10:33 -04:00
mean
b82ee6bc90 prototype for gdb_putpacket2 2022-03-22 10:10:33 -04:00
Mike Ditto
48c6db1963 Remove duplicate definition of USBUSART_DMA_TX_ISR 2022-03-22 10:02:52 -04:00
Piotr Esden-Tempski
e82d4f2eda native: Fixes an hw version issue with some older BMP.
The BMP with hardware version 4 and newer, use option bytes instead of
physical GPIO to encode the hardware version. In some older BMP there is
a chance that the user option byte is set to 255 (0x00FF pattern). This
can throw off the hardware version detection routine.
2022-03-15 23:45:32 -07:00
Piotr Esden-Tempski
bcba3ee4a9 native: Fixed hw6 USBUSART support. 2022-03-15 23:45:32 -07:00
Piotr Esden-Tempski
06f24d3269 native: Added blocks to the ISR templates. 2022-03-15 23:45:32 -07:00
Piotr Esden-Tempski
bb761e4b38 native: Initial addition of hw 6 support. 2022-03-15 23:45:32 -07:00
Piotr Esden-Tempski
2d63021344 native: Improved pinout legend comment block. 2022-03-15 23:45:32 -07:00
Piotr Esden-Tempski
e7982d594e native: Added HW5 AUX interface definitions. 2022-03-15 23:45:32 -07:00
Piotr Esden-Tempski
655014ac9c native: hw rev 5 has the usb vbus sense pin on PA15.
We had to move the pin to free up the SPI SCLK pin.
2022-03-15 23:45:32 -07:00
Piotr Esden-Tempski
9ffa923bc1 native: Update hwversion detection for hw rev 4 and newer.
The hw rev 4 and 5 both have the version stored in the Data1 user option
byte. This frees up the hw rev strapping pins for other uses, ie swtrace
decoding using USART1 RX, and additional peripherals on the SPI bus,
like bulk flash storage and displays.
2022-03-15 23:45:32 -07:00
Piotr Esden-Tempski
d259d5c511 build: Only build the locm3 libraries needed.
We don't need to build all the locm3 libraries. We just need those that
are required by the supported platforms.
2022-03-15 13:33:51 -07:00
Fabrice Prost-Boucle
488df7e6f7 sscanf cleanup in GDB Z packet handling function.
Tested working with arm-none-eabi-gcc 10.2.1
2022-03-15 13:18:00 -07:00
Piotr Esden-Tempski
e0619ca7d5 Added a linker flag to output memory usage. 2022-03-15 11:41:31 -07:00
Piotr Esden-Tempski
4b92415442 ghactions: Added libhidapi dependency installation. 2022-03-14 23:01:32 -07:00
Piotr Esden-Tempski
501fd09228 ghactions: Added libftdi1 dependency installation. 2022-03-14 21:55:05 -07:00
Piotr Esden-Tempski
0d97871893 The pull request github action now also builds hosted.
This will help catch some more build errors.
2022-03-14 21:46:15 -07:00
dragonmux
4fe8fd8944 samd: Fixed the hosted build as the code from #987 assumed unsigned long was 32-bit 2022-03-14 21:38:45 -07:00
dragonmux
23534ab174 target: Cleanup in target_new() for the check_error callback 2022-03-14 21:37:44 -07:00
dragonmux
7d2afcff06 Revert "jtag: Make jtag_devs argument to jtag_handler."
This reverts commit 6308506276d09cde14be2985c0c5a59adc0addc6.
2022-03-14 21:37:44 -07:00
dragonmux
e271c16f6c Removal of MFR descriptions as requested in #978 2022-03-14 21:37:44 -07:00
dragonmux
361dc9c234 Revert "adiv5_swdp_scan: If SWD scan fails, try a JTAG scan."
This reverts commit 3df692ecb247fdc7c62f3c3dc622030ad12817e6.
2022-03-14 21:37:44 -07:00
dragonmux
024152b03e Revert "jtag_scan: Deliver full idcode to the handler."
This reverts commit 1845d71f00dda59849254bbddb3c4c00f556d35c.
2022-03-14 21:37:44 -07:00
dragonmux
c30e165c1c crc32: Fix the launchpad-icdi build as that was broken 2022-03-14 21:37:44 -07:00
dragonmux
54f577a970 hosted/dap: Partial revert of 5c8e277, taking into account that division may not be available on platforms 'hosted' might see itself built 2022-03-14 21:37:44 -07:00
dragonmux
02d9a1d3cf Revert "jtag_scan: Rework chain detection"
This reverts commit 2d4a50313596081a64bd1397017985641fd8cad0.
2022-03-14 21:37:44 -07:00
dragonmux
3bb8c2bf19 jtag_scan: Cleaned up the ones array to use a more correct syntax 2022-03-14 21:37:44 -07:00
dragonmux
d1c9d94174 jtag_scan: Remove the now redundant IDCode parameter from the handlers 2022-03-14 21:37:44 -07:00
dragonmux
75e786da11 jtag_devs: Added a few more parts based on 0170aff and cleaned up the description wording for the existing ones 2022-03-14 21:37:44 -07:00
dragonmux
27c143a3a3 jtag_scan: Properly fixed the wrong IDCode getting to the handlers 2022-03-14 21:37:44 -07:00
arpadbuermen
4045406ed8 Added support for fine-grained bootloader and flash locking in samd.c
lock_flash and lock_bootprot currently support only locking the whole flash and locking the maximal leading flash chunk (32k). 
An optional numerical parameter is added. It can be specified in decimal or 0x prefixed hexadecimal. 
For samd21 'lock_bootprot 0' locks the first 32k of flash while 'lock_bootprot 6' locks the first 512 bytes. 'lock_bootprot 0' is equivalent to 'unlock_bootprot'.  
Similarly, 'lock_flash <number>' locks the flash segments corresponding to zeros in the binary representation of the given number. 
'lock_flash 0xffff' is equivalent to 'unlock_flash'. 
If the optional parameter is not given both commands work as previously.
2022-03-14 00:26:31 -07:00
Uwe Bonnes
c1a12edbe9 kinetis: Clarify arguments to kl_gen_command
gcc11 chokes on the old setup
2022-03-13 19:48:38 -07:00
Qyriad
91a63fe0e6 Upload builds on push, and test that PRs build, with GH Actions 2022-02-27 17:11:43 -08:00
Nicolas Schodet
2dd3c7bae2 scripts: gdb.py: fix error messages 2022-02-13 15:31:12 -08:00
Nicolas Schodet
de834264ab scripts: hexprog.py: minor fixes
Unused import and useless semicolon.
2022-02-13 15:31:12 -08:00
Nicolas Schodet
f8f2ab2016 scripts: stm32_mem.py: change some formatting, remove unused imports 2022-02-13 15:31:12 -08:00
Nicolas Schodet
eafc634eba scripts: more conversion to Python 3, change the shebang line 2022-02-13 15:31:12 -08:00
Nicolas Schodet
d9cce4d5e8 scripts: convert bootprog.py to Python 3
Tested with a stm32f100 bootloader.
2022-02-13 15:31:12 -08:00
Nicolas Schodet
ca9d8cd0ae scripts: fix dfu-convert.py for Python 3 and drop Python 2 support 2022-02-13 15:31:12 -08:00
Paul Mulders
ed156076a2 swlink README: correct SWO/RX2 header location for blue pill 2022-01-30 11:48:12 +01:00
Uwe Bonnes
6a9b2b8224 hosted/ftdi: Fix bad length calculation in MPSSE case of swdptap_seq_in() 2022-01-25 11:40:55 -05:00
Uwe Bonnes
266fe17461 bmp_libusb: Restrict scope of variable 2022-01-25 11:40:55 -05:00
Uwe Bonnes
e3804183f7 bmp_libusb: Fix crash with FTDI devices as outdated variable was used.
Triggered by 7b1eb6e6e3.
2022-01-25 11:40:55 -05:00
Uwe Bonnes
b1ed55a18f hosted/firmware/jtag: Fix unhandled exception introduced with da15cc3cb75cc2a9f.
Write in endianess independant way.
2022-01-22 23:46:52 -08:00
Uwe Bonnes
d594b42976 Cortexm: With connect under reset, keep the device halted until attach. 2022-01-22 14:07:42 +01:00
Piotr Esden-Tempski
d6440d716c Updated github org references to blackmagic-debug. 2022-01-21 22:09:35 -08:00
Nicolas Schodet
5c07d6170f scripts: remove import from future which imports from the past
There is no point to support Python 2.
2022-01-04 00:57:48 -08:00
Nicolas Schodet
946ccab778 scripts: stm32_mem cosmetic changes
Add a newline to avoid overwriting the last "Programming memory..."
message.

Remove inline tabs.
2022-01-04 00:57:48 -08:00
Nicolas Schodet
ad6c1eb11b scripts: fix stm32_mem.py for python 3
Python 3 does not accept a characters string where a bytes string is
needed.
2022-01-04 00:57:48 -08:00
Frank Kunz
8def28dee9 Add option bit support for STM32WLxx
Support for read/write/erase option bits.

Signed-off-by: Frank Kunz <mailinglists@kunz-im-inter.net>
2022-01-02 12:29:03 +01:00
Sean Cross
c832cb04e7 samd: add support for SAMD09
The SAMD09 CPU is used in boards such as the Adafruit Seesaw. It has a
smaller amount of memory and flash than other SAMD ports.

This was tested with an Adafruit Seesaw. These boards come with preloaded
firmware. As a test, the firmware was dumped and flash was erased. Then,
flash was verified to be all zeroes. Finally, the firmware was loaded
back in:

	(gdb) p/x *(unsigned int *)0@32
	$8 = {0x20000f88, 0x1db, 0x1d1, 0x1d9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d9, 0x0, 0x0, 0xf5, 0x1081, 0x1d9, 0x1d9, 0x1d9, 0x1d9, 0x1d9, 0x1d9, 0x1d9, 0x0, 0x1d9, 0x1d9, 0x25e9, 0x0,
	  0x0, 0x1d9, 0x1d9, 0x1d9}
	(gdb) dump ihex memory flash.ihex 0 8192
	(gdb) mon erase_mass
	Erase successful!
	(gdb) p/x *(unsigned int *)0@32
	$9 = {0xffffffff <repeats 32 times>}
	(gdb) load flash.ihex
	Loading section .sec1, size 0x2000 lma 0x0
	Start address 0x00000000, load size 8192
	Transfer rate: 5 KB/sec, 910 bytes/write.
	(gdb) p/x *(unsigned int *)0@32
	$10 = {0x20000f88, 0x1db, 0x1d1, 0x1d9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d9, 0x0, 0x0, 0xf5, 0x1081, 0x1d9, 0x1d9, 0x1d9, 0x1d9, 0x1d9, 0x1d9, 0x1d9, 0x0, 0x1d9, 0x1d9, 0x25e9, 0x0,
	  0x0, 0x1d9, 0x1d9, 0x1d9}
	(gdb)

Signed-off-by: Sean Cross <sean@xobs.io>
2021-12-29 15:25:51 +01:00
Sean Cross
d00607f71a samd: parameterize memory and flash sizes
Various SAMD devices have different amounts of memory. Up until now, all
SAMD devices have had the same amount, and therefore this value was
hardcoded to 32k of RAM and 256k of flash.

Add a parameter to the description field and set it to default to the
previous values. Use this description field when adding memories to the
target definition.

Signed-off-by: Sean Cross <sean@xobs.io>
2021-12-29 15:25:51 +01:00
Sean Cross
8039e2b26a crc32: define start_time when debug is enabled
The variable `start_time` indicates when a CRC32 operation began. This
variable is used to benchmark the speed of the CRC32 function.

Currently, this is tied to `PC_HOSTED`. However, the actual usage is
tied to `DEBUG_WARN`. This means that the variable is undefined when
`DEBUG_WARN` is defined and we're not configured for `PC_HOSTED` mode.

Add macro guards around this variable so that it is defined when
debugging is enabled, rather than only when building on `PC_HOSTED`.

Signed-off-by: Sean Cross <sean@xobs.io>
2021-12-28 00:25:31 -08:00
Mark Rages
f43101fd9f Port gdb.py and hexprog.py to Python 3.
Unfortunately, the serial data are not 7-bit clean (see write_mem()).
So getpacket() and putpacket() use bytes objects rather than strings.
2021-12-19 14:45:51 -08:00
Piotr Esden-Tempski
fcb2a609fc scripts: Updated nrf51 id script for py3 and to parse newer oocd header. 2021-12-19 14:45:51 -08:00
Piotr Esden-Tempski
728e955193 scripts: Updated bootprog to run on python3 2021-12-19 14:45:45 -08:00
Uwe Bonnes
3f28e728e9 cdcacm: Lower usage of magic numbers. 2021-12-18 21:44:18 -08:00
Uwe Bonnes
98e3858f7c bmp_libusb: Exclude Wireless class too. 2021-11-23 20:54:59 +01:00
Koen De Vleeschauwer
bb4151377f type of ‘assert’ defaults to ‘int’ 2021-11-22 19:51:10 +01:00
Koen De Vleeschauwer
d4cd81fa36 start_time undeclared if ENABLE_DEBUG=1 2021-11-21 12:57:30 +01:00
Uwe Bonnes
73b4612ec7 adiv5_swdp: Initialize a volatile variable
GCC did not warn about possibly missing initialization and so for gdb target
was not recognized.
2021-11-20 22:38:35 +01:00
Uwe Bonnes
5cb501049a adiv5_swdp/scan: Handle parity errors, seen with NRF52 with SYSTEMOFF #381/#949 2021-11-18 22:59:17 +01:00
UweBonnes
efa889156f
Merge pull request #948 from fabalthazar/STM32G0-OTP
STM32G0 OTP area programming and hosted monitor command allowed as preliminary action
2021-11-16 14:23:20 +01:00
fabalthazar
b4ac52d1f5 Hosted monitor command allowed as preliminary command 2021-11-15 21:20:38 +01:00
fabalthazar
71b67beb98 Fix: assert flashing succeeded or failed (hosted) once the last buffer has been written 2021-11-15 21:19:08 +01:00
fabalthazar
92d6056711 STM32G0 OTP area programming 2021-11-15 21:19:08 +01:00
Koen De Vleeschauwer
73624826b6 semihosting exit code 2021-11-14 12:03:33 +01:00
UweBonnes
59dc225568
Merge pull request #937 from UweBonnes/CMSIS-DAP
CMSIS-DAP/ADIv5 fixes for #936 and #925
2021-11-11 22:06:02 +01:00
Uwe Bonnes
1d0e45bdbb cmsis_dap: Transfersize of block commands needs to cope with word.
Checkme: Dragonprobe bulk hangs on transfers with 15 words.
2021-11-02 18:17:12 +01:00
Uwe Bonnes
8970160f1d cmsis_dap: Timeout and start of error handling for bulk transfers. 2021-11-02 18:17:12 +01:00
Uwe Bonnes
2bc2db1140 cmsis_da: Add timeout to bulk commands. 2021-11-02 18:17:12 +01:00
Uwe Bonnes
a4caec29b9 dap_swdptap_seq_out: Write only needed data
Dragonprobe (origin/cmsisdap-fixes, 211031) hanged on additional byes in the
SWJ_Sequence request.
2021-11-02 18:17:03 +01:00
Uwe Bonnes
181466549b adiv5: Progressive incrementing TRNCNT for the DHCSR write when trying to halt
Workaround for CMSIS-DAP/Bulk debugger orbtrace  that returns NO_ACK
with high values of TRNCNT. Perhaps only STM32F767 needs write to DHCSR
with high occupancy to catch the device in a moment not sleeping.
2021-10-31 12:55:41 +01:00
Uwe Bonnes
07b4e5726e CMSIS-DAP: Run time detect DAP_SWD_SEQUENCE
Some dongles in the making like orbtrace may not yet support.
2021-10-31 12:55:41 +01:00
Uwe Bonnes
88e44d1c12 cmsis: use exception in wait_word(). 2021-10-31 12:55:41 +01:00
Uwe Bonnes
a1d4649795 SWD: Use dp_low_write to allow multidrop scan. 2021-10-31 12:55:41 +01:00
Uwe Bonnes
4f36c1ddf8 Remove dp_low_read() and use exception protected dp_read() 2021-10-31 12:55:41 +01:00
Uwe Bonnes
f9d343af3e cmsis: AP reads are posted. Read from RDBUFF. 2021-10-31 12:55:41 +01:00
Uwe Bonnes
d4ae308f9f cmsis: implement srst_set_val() 2021-10-31 12:55:41 +01:00
Uwe Bonnes
166eb3ee3e cmsis_dap: Always transfer 65 bytes with hid_read|write()
CMSIS-DAP Dragonprobe works on some devices. E.g. it does not work
on NUCLEO-F103
2021-10-31 12:55:41 +01:00
Uwe Bonnes
b343ebe06f cmsis-dap/linux: Link against libhidapi-hidraw
libhidapi-libusb detaches a kernel module but does not reattach again.
This may wrack interaction with other programs using hidapi.
2021-10-31 12:55:41 +01:00
Uwe Bonnes
d144f9d54b adiv5: CMSIS DAP transactions are slow but work in principle
Slowness results in strange STM32F767 DHCSR implementation to nearly never
halt in the given 2 second period when F767 is sleeping most of the time.
2021-10-31 12:55:41 +01:00
Uwe Bonnes
761e0230d4 cmsis-dap: Print messages when transfers fail.
Expect signal integrity errors when using jumper cables. Often probes switch
the SWJ GPIO with highest speed, resulting in possible reflections. Additional
ground wires may help. If there is isolation between probe and targets,
additional ground wires are a must or ground shift will wrack the transfer!
2021-10-31 12:55:41 +01:00
Uwe Bonnes
39fbffd3d2 stlinkv2: Fix low access to AP registers. 2021-10-31 12:55:41 +01:00
Uwe Bonnes
c13778139f adiv5/hosted: Export the BMP_TYPE in DP. 2021-10-31 12:55:41 +01:00
Uwe Bonnes
b7e7aa3f9a adiv5: Either use only LL functions in cortexm_initial_halt or no LL at all.
Platform implementation may disturb ADIV5_AP_DRW and so low_read DHCSR may
give values other from registers
2021-10-31 12:55:41 +01:00
Uwe Bonnes
485105221e dap: Always work on a copy of the buffer when calling dbg_dap_cmd() in a loop
A better solution would use seperate buffers for dbg_dap_cmd. But as WAIT is
already handled in DAP, cahnces are low that loop re-entry is needed.
2021-10-31 12:55:41 +01:00
Uwe Bonnes
397fbd5749 cmsis: Only cmsis internal use must differentiate between HID and Bulk access
Missing DAP_SWD_SEQUENCE may eventually need a distinction visible from
outside later.
2021-10-31 12:55:41 +01:00
Uwe Bonnes
7b1eb6e6e3 bmp_libusb: reset type on every device. 2021-10-31 12:53:47 +01:00
Uwe Bonnes
80064c18a9 bmp_libusb: Fix CMSIS-DAP related memory leak. 2021-10-31 11:13:34 +01:00
Uwe Bonnes
8845a22226 stm32l4: Use targetid when available.
Fixes STM32U5 from crashing.
2021-10-31 11:13:34 +01:00
Uwe Bonnes
c4b6b42dcf stlinkv2: Read targetid on DPv2 devices. 2021-10-31 11:13:34 +01:00
Uwe Bonnes
5dafc0828c SWD: Remove excessive line resets. 2021-10-31 11:12:46 +01:00
Uwe Bonnes
e7e1bfdb53 mpsse: Fix using 60 MHz clock on fast devices. 2021-10-30 13:55:57 +02:00
Uwe Bonnes
99a5fdb6f8 bmp_remote: Better error propagation.
Negative values from platform_buffer_read are errors too!
2021-10-30 13:55:57 +02:00
Uwe Bonnes
f4117aa1b4 cdcacm: Use the USB strings. 2021-10-30 13:55:57 +02:00
Uwe Bonnes
f28f05952f stlink: Add another STLINK-V3 ID. 2021-10-30 13:55:57 +02:00
SG
7307f086c6
Support for STM32WB55 (#942)
* add STM32WB55 support
2021-10-30 13:01:06 +02:00
Uwe Bonnes
e1a928beb1 Fixes to compile with gcc11 #925
Target code changes are pure for formal correctness and not tested!
2021-10-10 15:59:57 +02:00
UweBonnes
28623e6b27
Merge pull request #939 from fabalthazar/hosted-return-val
Consistent return value and output of hosted blackmagic + HOSTED_BMP_ONLY=0 on Linux
2021-10-10 12:54:48 +02:00
fabalthazar
e2d3161442 Removed -S message as debugger selection option since it is used for reading bytes 2021-10-09 21:38:48 +02:00
fabalthazar
59282b6f66 Fixed typography 2021-10-09 21:18:52 +02:00
fabalthazar
7274f55ff4 Fixed return value of hosted blackmagic in erase mode 2021-10-09 21:17:58 +02:00
fabalthazar
3f54fba986 HOSTED_BMP_ONLY=0 by default on Linux.
The user is warned about missing dependencies.
2021-10-09 21:14:52 +02:00
Vegard Storheil Eriksen
7ccbdd98c0 hosted/dap: Copy command buffer in wait/retry loop.
The same buffer is used for both command and response, causing part of
the command to be overwritten before it’s retried. Solve this by saving
and restoring a copy of the command before retrying.
2021-10-05 23:21:07 +02:00
Jeff Lutgen
f69f29a660 f4discovery/blackpill: fix usbusart 2021-10-01 00:10:03 +02:00
Uwe Bonnes
b076d5cea1 stm32f1: Check if unlock failed and propagate error. 2021-09-22 21:41:43 +02:00
Uwe Bonnes
554e34517e Better reporting when monitor command fails. 2021-09-22 21:41:43 +02:00
Uwe Bonnes
9e98cfa220 adiv5: Remove leftover debug output. 2021-09-22 21:41:43 +02:00
Thiadmer Riemersma
64f756d627 Test voltage on VREF before enabling target power (mon tpwr), to avoid potential power conflict. 2021-09-22 20:45:18 +02:00
Uwe Bonnes
88cce08ce4 hosted: Fix "monitor version" 2021-09-22 15:16:20 +02:00
Uwe Bonnes
da15cc3cb7 remote_jtagtap: Fix memory corruption in jtagtap_tdi_tdo_seq 2021-09-22 15:16:20 +02:00
Uwe Bonnes
356325f563 ftdi_bmp: Fix bit select. 2021-09-22 15:16:20 +02:00
Uwe Bonnes
a93e57e112 ftdi: Fixed wrong direction report in DEBUG. 2021-09-22 15:16:20 +02:00
Uwe Bonnes
79066c950f bmp_libusb: Remove duplicated libusb_init.
Thanks to Red Liu for noticing
2021-09-22 15:16:20 +02:00
Uwe Bonnes
9de69bb3ab Adiv5/Initial halt: More fixes for dd28fa5743. #925
Stlink does not like low level access and aborts with STLINK_SWD_DP_ERROR.
Either our implementation still has faults or stlink can not handle

MINDP devices with BMP/Firmware also seemm not to like low level access,
either du to some hidden error in BMP or by design
2021-09-22 15:16:20 +02:00
Uwe Bonnes
9ebc44bcea Make more functions static. 2021-09-22 15:16:20 +02:00
Uwe Bonnes
db1f13db25 remote: Packets may be larger than 256 bytes. 2021-09-22 15:16:20 +02:00
Uwe Bonnes
a9854e9b37 adiv5: Fix the MINDP case introduced with dd28fa5743 #925 2021-09-16 12:39:26 +02:00
Andy Makovec
01583560cd hosted: Update Readme.md to use HOSTED_BMP_ONLY 2021-09-16 11:02:31 +02:00
dpc
f66caa0d29 add some more nxp s32k14x variants
the sdid bits correspond to s32k14x as well as s32k11x but i only have
access to the k14x variants so didn't bother w/ the k11x variants.
the memory/flash sizes also can come from the sdid bits, but the
splits still need to come from a lookup.
2021-09-13 23:01:05 +02:00
dpc
95288bcf75 fix a size format warning 2021-09-13 23:01:05 +02:00
Uwe Bonnes
e58b7d623b crc32: Abort generic_crc32 with error from target_mem_read
Use larger chunks for hosted to speed up. Send pure NULL as line keep-alive.
2021-09-07 10:57:17 +02:00
Uwe Bonnes
ff79108f66 cl_utils: Increase worksize for increased speed.
H743 reads 2 MB in ~23 vs 27 seconds
2021-09-07 10:57:17 +02:00
Uwe Bonnes
a76a559656 pc/platform_delay: Wait ms and not us! 2021-09-07 10:57:17 +02:00
Uwe Bonnes
dd28fa5743 adiv5: Tighten up loop to initial halt cortexm
Use TRNCNT when available.

Now the F767 with the NutOS 300 ms sleep example  with the one ms tick is
halted even in hosted after few ms.
2021-09-04 21:15:07 +02:00
Uwe Bonnes
a297c8c8ad hosted/Makefile.inc: Use gcc to build hosted, if not advised otherwise 2021-09-04 21:15:07 +02:00
Uwe Bonnes
698cfeb1f4 bmp_serial: Nag MACOS programmer to implement find_debuggers! 2021-09-04 21:15:07 +02:00
Thiadmer Riemersma
35687018eb Escape '*' in responses of the Remote Serial Protocol, to avoid that it is interpreted as the start of an RLE sequence 2021-08-31 15:44:17 +02:00
Jason Kotzin
a6f9701368 Adding schematic, use adobe, has a 3D step built in 2021-08-15 22:22:09 -07:00
Jason Kotzin
237d6b89f6 Updating Readme 2021-08-15 22:18:41 -07:00
Jason Kotzin
2b89a07dae samd: adding bootprotect and unlock commands 2021-08-15 21:50:54 -07:00
Uwe Bonnes
863a41daac adiv5_swdp: Initialize initial_dp with the definition 2021-08-15 16:43:29 +02:00
Uwe Bonnes
49122b50b6 hosted: Make HOSTED_BMP_ONLY the default.
Hopefully more people will use it when reporting errors!
2021-08-15 16:43:29 +02:00
Uwe Bonnes
2fcd4a878a ftdi_bmp.h: Fix error when compiling with HOSTED_BMP_ONLY=1 2021-08-15 16:43:29 +02:00
Uwe Bonnes
6308506276 jtag: Make jtag_devs argument to jtag_handler. 2021-08-15 16:43:29 +02:00
Uwe Bonnes
6dff2a9f31 target: target_error_check now defaults to not indicate error.
Remove unneeded nop_function from efm32
2021-08-15 16:43:29 +02:00
Uwe Bonnes
f7670fcd44 ftdi_bmp: Add verbosity for libftdi_jtagtap_tdi_tdo_seq() 2021-08-15 16:43:29 +02:00
Uwe Bonnes
3df692ecb2 adiv5_swdp_scan: If SWD scan fails, try a JTAG scan. 2021-08-15 16:43:29 +02:00
Uwe Bonnes
5c8e277663 hosted/dap: Fix tdi_tdo_seq. 2021-08-15 16:43:29 +02:00
Uwe Bonnes
2d4a503135 jtag_scan: Rework chain detection
Fixme: stlinkv2/hosted probably does only handle STM devices. Check if
jtag_devs.c really needed.
2021-08-15 16:43:29 +02:00
Uwe Bonnes
e1a1865de9 remote/jtagtap_tdi_tdo_seq: Split up large transactions.
FIXME: One remote transaction still can only do up to 64 ticks, leaving
room for speed enhancement with larger transactions.
Firmware assumes  (1LL << 65) == 0LL !
2021-08-15 16:43:29 +02:00
Uwe Bonnes
8084a75634 cl_utils: Allow Hardware reset from the command line 2021-08-15 16:43:29 +02:00
Uwe Bonnes
36836d0746 ftdi_bmp: Fix setting bits and FTDIJTAG srst. 2021-08-15 16:43:29 +02:00
Uwe Bonnes
cfdf55855e ftdi_bmp: Export and use reset functions. 2021-08-15 16:43:29 +02:00
Uwe Bonnes
1845d71f00 jtag_scan: Deliver full idcode to the handler. 2021-08-15 16:43:29 +02:00
Uwe Bonnes
0d78331149 remote/jtag_tdi_tdo_seq: Fix wrong bitmask calculation. 2021-08-15 16:43:29 +02:00
Thiadmer Riemersma
c7bc4b6a5d Bug fix in Flash erase function for LPC MCUs. 2021-08-13 16:18:53 +02:00
aam335
5eb43a1ddb platforms: stm32f4x1 blackpillv2 as variant of f4discovery
Compile as make PROBE_HOST=f4discovery BLACKPILL=1
2021-08-13 16:18:05 +02:00
Thiadmer Riemersma
be534a9c5e Turn error LED off after successful attach to target (error LED blinks on 'target lost'). 2021-08-13 16:10:37 +02:00
Thiadmer Riemersma
72bd825a60 Add support for NXP LPC11xx XL series, add 'readuid' command for some MCUs of the LPC11xx series where it was missing; add comments mapping Device IDs to part descriptions. 2021-07-31 16:08:34 +02:00
Uwe Bonnes
6d6a67b44b timeout: Make sure we wait at least the period requested (#900, #902)
Fixes bug introduced with last commit( Recover from bad AP access)

Let STM32 timers run at 100 Hz against 10 Hz before.

Programming STM32F103 failed random (#900) with 20 ms timeout requested
against the 100 ms timeout granularity provided up to now.

STM32 Firmware only ticked at 10 hertz, so the sequence "low_access",
"set timeout", "send out 8 bit command", "read 3 bit result" when
reading "wait" and timer increment tick happening during that sequence
will already hits the timeout even so only mininal time has elapsed
and not the requested timeout.
2021-07-27 10:59:03 +02:00
Uwe Bonnes
0c63903071 adiv5: Recover from bad AP access.
E.g. AP1 on a STM32WLE5 points to a ROM table, but access to the ROM table
via AP1 hangs forever.
- Substantial reduce timeout when wait for a response. Valid access should
  succeed fast.
- Abort AP access to free DP for other accesses
- Don't throw exception, only set dp->fault
- React on higher level
2021-07-15 15:06:54 +02:00
Uwe Bonnes
b887a8d355 stm32: Portability changes
Allow to compile on STM32F0 platform too.
2021-07-15 15:06:54 +02:00
UweBonnes
41719c5559
Merge pull request #897 from UweBonnes/fixes
bmp_libusb: Check only for cmsis_dap if no cable has been found yet.
2021-06-18 12:13:19 +02:00
Uwe Bonnes
3cfd8226ba bmp_libusb: Check only for cmsis_dap if no cable has been found yet. 2021-06-18 11:44:50 +02:00
UweBonnes
a0dbb2a787
Merge pull request #896 from RadinnAB/for-upstream
Add nRF51 erase UICR command and fix some warnings
2021-06-07 17:43:56 +02:00
fabalthazar
ea4b232996 Fix de83dbb: duplicate BMP_MODE_FLASH_VERIFY -> BMP_MODE_FLASH_WRITE_VERIFY 2021-06-07 17:29:41 +02:00
Björn Mellström
5ea01030e2 Add nRF51 command for (only) erasing the UICR registers
Original implementation by: Benjamin Vedder <benjamin@vedder.se>
2021-06-07 13:50:36 +02:00
Björn Mellström
d987a8dd8c Add define to allow platform override of debug printf function 2021-06-04 06:58:29 +02:00
Björn Mellström
4b8c4990dc Fix warning about unused variable in adiv5.c
This happens if the platform has debugging support but debugging
is not enabled.
2021-06-03 12:56:41 +02:00
Björn Mellström
711a87f7ba Fix some warnings when compiling with -Wshadow
There are still a few more places that would need to be corrected
before -Wshadow could be added by default.
2021-06-03 12:55:28 +02:00
Björn Mellström
53f022d29b Require semicolon after debug log statements
This also fixes a warning about an empty body in cortexm.c
if PLATFORM_HAS_DEBUG is defined but debugging is not enabled:

    if (platform_timeout_is_expired(&to))
        DEBUG_WARN("Reset seem to be stuck low!\n");
2021-06-03 12:52:07 +02:00
Björn Mellström
04eab8e1f8 Add guard around _GNU_SOURCE define
This avoids warnings if the define has already been set by the
build system.
2021-06-03 12:51:27 +02:00
Uwe Bonnes
2a0d608b07 hosted: Fix last commit
-Wno-format-truncation may not be understood by all systems
2021-06-01 18:42:37 +02:00
Uwe Bonnes
1b49823f64 Fix hosted compile on MacOS. hidapi-libusb has a different name 2021-06-01 16:58:25 +02:00
Uwe Bonnes
de83dbb7e2 cl-utils: Fix bug introduced with 5288eef6171b9cff194fbeb087bc942bad08d9db
Always use the file size for write and verify.
2021-06-01 16:23:19 +02:00
Uwe Bonnes
c0437e7b25 bmp_serial: Autodetect more BMP string variants. 2021-06-01 16:23:19 +02:00
Uwe Bonnes
891633322a lpc: Care for protected pages on LPC80x devices. 2021-06-01 16:23:19 +02:00
Uwe Bonnes
f7b4697280 lpc11xx/lpc8c04: Do not expose two top system flash sectors. 2021-06-01 16:23:19 +02:00
Uwe Bonnes
42ebcac329 efm32_devices: Rearrange struct efm32_device_t to save flash space. 2021-06-01 16:23:19 +02:00
Uwe Bonnes
21a702dc1e lpc: More verbosity and more definitions 2021-06-01 16:23:19 +02:00
Uwe Bonnes
6454d0bc96 bmp_libusb: Invalidate manufacturer and product in case libusb_get_string_descriptor_ascii fails.
Prevent more false detections
2021-05-20 12:06:56 +02:00
Uwe Bonnes
df575eb090 stm32_mem.py: Wait longer for device to appear. 2021-05-20 12:06:56 +02:00
Uwe Bonnes
7f1a560288 stm32/usbuart: Clear USART_ICR if provided.
Otherwise endless interrupts happened.
2021-05-20 12:06:56 +02:00
Uwe Bonnes
90534b3cf6 stm32: portability enhancements
Needed for e.g. stlinkv3
2021-05-20 12:06:56 +02:00
Uwe Bonnes
87acd99fe4 cortexm: For Cortex-M0+ devices, probe also for lpc11 to detect LPC80 #884 2021-05-18 12:24:00 +02:00
Uwe Bonnes
cb4cff2c71 hosted/ftdi: Compare only for length of the string given in the header
Devices may have added version like "Tigard V1.1" vs "Tigard"
2021-05-18 12:24:00 +02:00
Uwe Bonnes
c3fd198f0d bmp_libusb: Reject non-BMP devices with VID 1d50. 2021-05-18 12:24:00 +02:00
Uwe Bonnes
36ad6efc6f cmsis_dap.h: Fix wrong leftover argument. 2021-05-16 17:17:33 +02:00
Uwe Bonnes
f0dd8c9517 cl_utils: List -l option in the help. 2021-05-16 17:17:33 +02:00
Uwe Bonnes
517d5b5b31 rp: Show spinner only when called from monitor command. 2021-05-16 11:26:14 +02:00
James Turton
0ab10fee0b rp: Increase timeout for flash_range_program
If the RP2040 is using the ring oscilator (ROSC) rather than the crystal
oscilator (XOSC) then flashing program will take much longer. As the XOSC is not
enabled at boot we should not assume it will be enabled before the debugger is
connected (or indeed at all), thus should use the longer timeout during load
commands.
2021-05-16 11:26:14 +02:00
James Turton
ff30259354 rp: Add more debug logging during flash 2021-05-16 11:26:14 +02:00
James Turton
e453740aca rp: Increase spinner timeout to 500ms
Increasing spinner timeout to 500 means `tc_printf` is not called during
the `_flash_range_erase`. This is important as `_flash_range_erase` is
used when loading. This fixes the issue:
https://github.com/blacksphere/blackmagic/issues/875
Also adding spinner timeout counter to reduce bus traffic.
2021-05-16 11:26:14 +02:00
James Turton
67c9003522 rp: Flush cache after erase and write
The RP2040 datasheet suggests that _flash_flush_cache and _flash_enter_cmd_xip
should be called after erasing and writing to flash.
2021-05-16 11:26:14 +02:00
James Turton
f880734050 Fix compiling for native probe 2021-05-16 11:26:14 +02:00
Uwe Bonnes
e4421799ba More header cleanup 2021-05-15 12:54:51 +02:00
Uwe Bonnes
8e438b9e5f Add missing headers and remove double typedef. 2021-05-14 19:58:16 +02:00
Uwe Bonnes
cfbe9f1c94 pc/gdb_if.c: More verbosity for Error messages #873
Thanks to "pshri" for dissecting and adding messages, as  problems with
Hpyer-V and port permissions happened on Win10
2021-05-09 11:49:32 +02:00
UweBonnes
8089e05a00
Merge pull request #871 from zyp/cmsis_dap
CMSIS-DAP improvements
2021-04-30 13:06:49 +02:00
Vegard Storheil Eriksen
f121350fc9 hosted/cmsis_dap: Verify that a v2 interface has endpoints. 2021-04-27 11:39:43 +02:00
Vegard Storheil Eriksen
494524dd85 hosted/cmsis_dap: Add v2 support. 2021-04-27 10:26:06 +02:00
Vegard Storheil Eriksen
4f52a7b235 hosted/cmsis_dap: Add discovery by interface string and prepare for v2 support. 2021-04-26 21:56:24 +02:00
Vegard Storheil Eriksen
c4874fdf44 hosted/dap: Add parentheses around bitwise operator. 2021-04-26 21:54:38 +02:00
Uwe Bonnes
f9414d5826 cmsis-dap: Handle ADI DP22 devices on probes not multidrop capable. 2021-04-26 18:18:18 +02:00
Uwe Bonnes
923edc7f7e cmsis-dap: Fix wrong handling when reading data not word-aligned 2021-04-26 15:08:09 +02:00
UweBonnes
96bec7e3fb
Merge pull request #868 from UweBonnes/fixes
Revert "cmsis_dap: Always write full reportsize + 1 buffers"
2021-04-25 23:14:34 +02:00
Uwe Bonnes
877a6e694c Revert "cmsis_dap: Always write full reportsize + 1 buffers"
This reverts commit 61e237ec87c525876817e72fc82ce28b2a4951ae.
This makes a CMSIS-DAP probe with version < 1.2 work again on DP V1 devices.
Status of other combination unknown:
    DP  V1 V2 V2/Multidrop
Probe
<  1.2  ok ok --
>= 1.2   ? ?  ?
2021-04-25 22:53:40 +02:00
UweBonnes
da2fb7f210
Merge pull request #867 from UweBonnes/clean-static-from_probe
Clean static from probe

Some target probe functions used static RAM variables. This will fail if several of the same targets are in the JTAG/SWD chain and unnecessary remove RAM form the RAM pool if the target is not used. If the target needs more than one word, it allocated priv_storage is used. For a single needed word, one word has been added to the target structure as a union to allow decent naming.
2021-04-25 16:25:19 +02:00
Uwe Bonnes
1f67bab475 nxpke04: Move unsafe_enables to target bool union. 2021-04-25 16:03:23 +02:00
Uwe Bonnes
f87dff8d83 kinetis: Remove static variables, add word union to target_s.
Add a word union to target structure to hold a single word variable.
2021-04-25 16:03:23 +02:00
Uwe Bonnes
ac7c1057cc efm32/samd/samx5x: Remove static allocates strings. Allocate in priv_storage.
Static allocated variables in the different targets eat up common RAM and
will collide in chains with multiple similar targets.
2021-04-25 16:03:23 +02:00
Uwe Bonnes
cddf02f174 samx5: Verbose error reports on protected devices. 2021-04-25 16:03:23 +02:00
Uwe Bonnes
1330288271 firmware: Unify serial number handling
Use one file in dfu and server
For STM32, provide 3 ways to handle
- BMP way (8 bytes)
- DFU way (12 Bytes)
- Full unique id (24 Bytes), as with STLINK(V3) Bootloader
2021-04-25 16:02:20 +02:00
Uwe Bonnes
8c8aa980cf adiv5: Detect unprotected SAMD5x only once 2021-04-25 16:02:20 +02:00
Uwe Bonnes
f98b7274b4 hosted/stlinkv3: Detect STlinkV3 in bootloader mode. 2021-04-25 16:02:20 +02:00
Uwe Bonnes
a83700d1cf stm32/usbuart: DMA stream handling is not STM32F4 specific 2021-04-25 16:02:20 +02:00
UweBonnes
8da2dee0c4
Merge pull request #857 from UweBonnes/rp
Support the Raspberry Pico RP2040

    Implement multi-drop
    Recognize , erase, flash and usb_reset
    Attach to the rescue DP will reset but attach itself fails.
2021-04-25 15:48:35 +02:00
Uwe Bonnes
1b26ff560d rp.c: Add reset_usb_boot as monitor command 2021-04-24 14:48:58 +02:00
Uwe Bonnes
52bffa70cf rp: Handle flash.
- Beware, after reset, only a valid flash payload get mapped to XIP!
  Only 0 is read from flash when flash image is not valid
2021-04-21 21:55:03 +02:00
Uwe Bonnes
2b0e255c40 cortexm: timeout and debug for run_stub() 2021-04-21 21:50:38 +02:00
Uwe Bonnes
61efe26348 swdp_scan: Break infinite loop after Dormant->SWD transition. 2021-04-21 21:50:38 +02:00
Uwe Bonnes
fa5e69e3be RP 2040: Special handling for rescue DP
As the rescue DP provided no AP, trigger the reset with attach().
However attach will indicate failure also reset/halt has succeeded.
2021-04-21 21:50:38 +02:00
Uwe Bonnes
ea92c8b8c8 cmsis-dap: Allow to use adiv5_swdp_scan. 2021-04-21 21:50:38 +02:00
Uwe Bonnes
23f942ac8c Raspberry RP2040: Recognize. No flash handling yet. 2021-04-21 21:50:35 +02:00
Uwe Bonnes
04d1c9805b swd: Remove swd_proc and swdptap.h. 2021-04-21 21:50:04 +02:00
Uwe Bonnes
b6fbf86743 Extend ADIv5_DP_t for low level routines needed for multi-drop.
Will replace swd_proc
2021-04-21 21:50:04 +02:00
Uwe Bonnes
61e237ec87 cmsis_dap: Always write full reportsize + 1 buffers
Expect short reads and other errors else
2021-04-21 21:50:04 +02:00
Uwe Bonnes
d6ade4d94e cmsis-dap: Use SWD_SEQUENCE if available. 2021-04-21 21:50:04 +02:00
Uwe Bonnes
5abb288c7a hosted: Provide the DP functions in swd_proc. 2021-04-21 21:50:04 +02:00
Uwe Bonnes
fa561c8d66 adiv5_swdp: Starting point to handle multi-drop
- RP2040 show both DPs
- Multidrop test with STM32L552 and STM32H745 allows selection
  with "-m 0x4500041" (H7), "-m 1" (L552) or "-m 0x01002927" (RP2040)
2021-04-21 21:50:04 +02:00
Uwe Bonnes
be3bfc48a8 cortexm: M33 has up to 8 hardware breakpoints 2021-04-21 21:22:59 +02:00
Uwe Bonnes
65f08cd46d README.md(top): Mention hosted build for BMP only. 2021-04-21 21:22:59 +02:00
Uwe Bonnes
b1ac4187b9 Fix some formatting strings for 32-bit compile 2021-04-21 21:22:59 +02:00
Uwe Bonnes
637d76b585 cl_utils.c: Try jtag scan if swd scan did not give results. 2021-04-21 21:22:59 +02:00
Uwe Bonnes
5288eef617 cl_utils: With no size given, read the size of the lowest block. 2021-04-20 18:48:27 +02:00
Fabio Baltieri
beaccf2714 target: stm32l4: add support for STM32WLxx
This adds support for the STM32WL series in stm32l4.c. These parts have
the same flash registers layout as the L4 series, but a different base.
Since there are already two sets of registers in this target file, this
adds support for register maps that can be customized for each device
ID.
2021-04-20 18:42:36 +02:00
Uwe Bonnes
21b80949ff Compile with -Os as default. Change like "make OPT_FLAGS=..."
SWD/JTAG Bitbang is compiled with -O3 for good bitbang speed.
2021-04-20 18:20:41 +02:00
Fabio Baltieri
f55ad67b1b adiv5: catch timeout on adiv5_ap_read_id and abort
This adds a TRY_CATCH around the adiv5_ap_read_id() in
adiv5_component_probe() and resets the DP when that happens.
It seems like the STM32WLE5 comes with the AP of the inactive core
enabled in a way that does not make it detectable, and the current code
times out and leaves the whole device hanging.

Catching the timeout and calling adiv5_dp_abort() seems to restore the
device to a useable state.

Tested on Seed LoRa-E5 (STM32E5JC).
2021-04-19 16:57:13 +02:00
Vestrel
806787529f Use DMA for USBUSART TX/RX 2021-04-17 17:57:08 +02:00
Uwe Bonnes
cf5b4afb38 bmp_serial/linux: Honor opt_list_only (-l). 2021-04-17 16:19:57 +02:00
fabalthazar
d6b24c00c8 Fixed STM32G43x/G44x option bytes support
Previously took L4 values so FLASH_SEC1R was not applied
2021-04-17 14:44:30 +02:00
fabalthazar
99f9557cc0 Support for STM32G49x/G4Ax (category 4) 2021-04-17 14:44:30 +02:00
fabalthazar
c85c946ce3 PRIx32 fix 2021-04-17 14:44:30 +02:00
Stoyan Shopov
9ec7d05d8d Put null terminating characters when scanning for BMP probes on linux
This patch puts null terminating characters for the 'type',
'version', and 'serial' strings extracted from blackmagic probe
id strings on linux systems.
2021-04-17 14:41:28 +02:00
Uwe Bonnes
2d293ec755 travis: Use bionic instead of trusty.
No more need to compile libftdi1.
2021-04-17 13:35:21 +02:00
Uwe Bonnes
299da8627c libftdi: Remove unneeded explicit path. 2021-04-17 13:35:21 +02:00
Uwe Bonnes
a6a8606edb STM32L55: Detect, memory map, read and flash write. Options handling missing.
Only non-secure states considered!
2021-04-04 17:26:31 +02:00
UweBonnes
db17f2caa8
Merge pull request #847 from fabalthazar/bugfix-845-hosted_verify
Bugfix 845 - hosted verify right after programming
2021-04-02 16:23:50 +02:00
fabalthazar
739941dc5f Verify right after programming 2021-03-31 13:06:52 +02:00
fabalthazar
2982888b66 BMP_MODE_FLASH_WRITE_VERIFY combined operation 2021-03-31 12:07:53 +02:00
fabalthazar
f85c54be97 Prepared -w option 2021-03-31 12:07:53 +02:00
fabalthazar
6d6cfd6c98 Comprehensive STM32G03/4/5/6/7/8/B/C driver 2021-03-29 21:42:40 +02:00
UweBonnes
fb8492a7e5
Merge pull request #846 from UweBonnes/cortexm_halt
Cortexm halt
2021-03-26 20:38:31 +01:00
Uwe Bonnes
58f153e12b cortexm: Always halt and release reset before romtable scan
Only release from halt once after romtable scan
Should fix #836.
2021-03-26 17:43:11 +01:00
Uwe Bonnes
a025c9a7bd Revert "stm32f1: On ST parts there is no need to read IDCODE again."
Romtable partno is not unique for devices, e.g. in STM32F0
This reverts commit f89b07d892c6034ea68494a72e047b2c437754f7.
2021-03-26 17:35:00 +01:00
Uwe Bonnes
f89b07d892 stm32f1: On ST parts there is no need to read IDCODE again.
IDCODE is already known from the Romtable
Probably this has the same effect as #836
2021-03-12 20:45:34 +01:00
Uwe Bonnes
e6a9a1a366 cmsis-dap: Get the firmware version. 2021-03-06 13:30:09 +01:00
Uwe Bonnes
7859a2aabd adiv5_swd: Factor out creation of packet request. 2021-03-06 13:30:09 +01:00
Uwe Bonnes
cfb784d428 adiv5: Fix comments and debug output 2021-03-05 16:49:19 +01:00
Uwe Bonnes
3aa6f16964 serial_unix: Split timeout in seconds and microseconds
Macos exposed errors when tv_usec was > 1000000.
2021-03-05 16:49:19 +01:00
Uwe Bonnes
43770736f1 cl_utils: Rework Flash/Ram printout 2021-03-05 16:49:19 +01:00
Thiadmer Riemersma
560a046a22 Add support for NXP LPC802, LPC804, LPC832 and LPC834 2021-02-22 19:37:46 +01:00
Uwe Bonnes
aeae9f7cde UsingSWO: Revisit Baudrate calculation and limits.
There are more SWO frequency options than the old documents indicated
2021-02-19 18:48:02 +01:00
Uwe Bonnes
0df44e205b ADIv5: Abort Romtable scan also if CIDR0 is invalid after halting #832
STM32WLE5 has the same dual core chip as STM32WL5. For the second
core, the additional AP can be see, but access to e.g. CIDR0 for that
Romtable fails.
Aborting the scan too if again the second read of CIDR0 fails makes
sense anyways!
2021-02-19 18:48:02 +01:00
Uwe Bonnes
d70fa8c7f6 hosted: Remove restrictions when gathering information on the debugger
That way, we find RPI Pico pico-debug.
2021-02-15 17:47:29 +01:00
Uwe Bonnes
c776e7a9a6 swd_scan: Add '-m' as targetid argument to swd_scan to prepare multi-drop.
In a real multi-drop setup, the device to use must be specified.
2021-02-15 17:47:29 +01:00
Uwe Bonnes
8e2f6937d5 hosted: Run target specific monitor commands with -M "command" .
Lists available commands: "blackmagic -M help"
Quote multi argument monitor commands, e.g. STM32F1: blackmagic -M "option help"
2021-02-15 17:47:29 +01:00
Uwe Bonnes
165560edd8 cl_utils: target selection '-n' argument needs optarg.
foreach now returns the number of targets.
2021-02-15 17:47:29 +01:00
Uwe Bonnes
4eb336277c native: Remove high current draw (#814)
Special iRST_SENSE handling does not apply at least for BMP 2.1c.
On V2.1c, iRST_SENSE was set as output high and xRST high shorted
iRST_SENSE to ground via Q2
FIXME: Check for older versions!
2021-02-15 15:00:19 +01:00
Martin
3b8502c2e5 add space in USB product string (be consistent with ../stm32/dfucore.c)
This changes the USB identification from
"Black Magic Probe(STLINK/V2) v..." to
"Black Magic Probe (STLINK/V2) v..."

Signed-off-by: Martin <Ho-Ro@users.noreply.github.com>
2021-01-29 14:47:28 +01:00
Martin
d4dc3b2717 The USB CDC is no modem and does not use the AT protocol
Signed-off-by: Martin <Ho-Ro@users.noreply.github.com>
2021-01-29 14:47:28 +01:00
Alex Norman
42f590ce0b fixing some memory map errors for stm32h7, PR #821 2020-12-23 20:10:39 +01:00
Uwe Bonnes
09c000eca8 hosted: Really handle setting tpwr on remote on the command line #817
Expect the command to fail, due to old firmware or remote not implementing
the power switch.
2020-12-19 16:36:09 +01:00
Sean Cross
c49c895f39 gitattributes: add attributes file
On different platforms, line endings can differ. Git tries to
intelligently convert source code to match native line endings when
doing a checkout, unless a particular configuration flag is set.

An alternate approach is to create a `.gitattributes` file and manually
specify various types of files. This ensures files are properly handled.
It also prevents git from creating patches that consist of nothing more
than replacing line endings.

Signed-off-by: Sean Cross <sean@xobs.io>
2020-12-16 12:51:09 +01:00
Sean Cross
2b06f045c4 target: kinetis: add S32K148
This adds support for the NXP S32K148. This is an automotive-grade part
that is derived from the Kinetis line, so it has a very similar
interface to other parts in the family.

Signed-off-by: Sean Cross <sean@xobs.io>
2020-12-16 12:49:23 +01:00
Sean Cross
5f76169b95 hosted: remove ftdi include when built with BMP_ONLY #811
Signed-off-by: Sean Cross <sean@xobs.io>
2020-12-16 11:30:42 +01:00
Uwe Bonnes
98c92a6d18 hosted: Really fix the case of no serial number (#807) 2020-12-13 14:12:05 +01:00
Noah Pendleton
272a45df12 add src/artifacts to .gitignore
This folder is generated when running `make -C src all_platforms`. Add
it to ignored files.
Ignore .gdb_history too.
2020-12-12 21:40:17 +01:00
UweBonnes
aa0d8f4b5d
Merge pull request #783 from UweBonnes/frequency
Frequency
2020-12-12 19:50:53 +01:00
Noah Pendleton
020600aa56 target/lpc546xx: fix lpc546xx flash support (#801)
**Summary**
Modifications to fix flash support on the lpc546xx:

- fix IAP entrypoint to be `0x03000204`, not the value at that address
- add a reset and attach sequence before erasing flash sectors. there's
little documentation around this, but experimentally, erasing sector 0
fails when the ROM bootloader is mapped to it (on reset). stepping the
chip once and attaching is enough to snap the chip out of it, permitting
flash erase on sector 0.
- add a few test commands to the lpc546xx table (read_uid, erase/write
sector, etc).
- write the magic CRC value when writing to sector 0
(`lpc_flash_write_magic_vect`).
- move the lpc546xx probe to before the lpc43xx probe, to prevent
getting the lpc546xx into Lockup when reading an illegal memory location
during lpc43xx probing

Fixes #786.

I don't 100% understand the reset/load sequence of this part, but these
changes are sufficient to program and debug the part now.

I didn't do a detailed analysis of what pyocd (via st-link hardware
adapter) and segger jlink do to handle the same, but both of those
worked without modification, so there's some difference in the
sequence they're using.

**Testing**
Verified I can now successfully erase and write an executable in sector
0 (and other sectors).
Verified the new commands work correctly.
2020-12-12 19:48:05 +01:00
Uwe Bonnes
1ca9f234f7 Infrastructure for setting maximum SWJ frequency.
Implement for BMP/firmware on STM32.
2020-12-12 18:33:09 +01:00
Uwe Bonnes
7365a44989 hosted: Implement SWJ test mode (-T).
Continious read/write-back some core register as NOP operation to allow scope
measurement of SWJ timing.
2020-12-12 18:33:09 +01:00
Uwe Bonnes
6dbb5ff7ee Frequency: Implementing for jlink.
SWD frequency is fixed for jlink according to the docs from 2010.
2020-12-12 18:33:09 +01:00
Uwe Bonnes
fdc654cfb3 stlink: Implementation of frequency setting. 2020-12-12 18:33:09 +01:00
Uwe Bonnes
de26ba6f73 hosted: Add is_jtag to the info structure
Needed for different frequency setting procedures on some platforms.
2020-12-12 18:33:09 +01:00
Uwe Bonnes
28a966a3e6 frequency: Implement for ftdi.
For all 2232H types, use undivided 60 Mhz.
FIXME: Check FT2322C/D for unsymetric clock at 6 MHz!
2020-12-12 18:33:09 +01:00
Uwe Bonnes
13e8a262e4 SWJ Frequency: Implement for cmsis-dap 2020-12-12 18:33:09 +01:00
Uwe Bonnes
f796b774bd hosted: Fix info.serial if USB device has no serial number #807 2020-12-12 18:32:15 +01:00
Aaron Lindsay
518529a772 Support GD32E23x 2020-12-12 18:29:30 +01:00
Uwe Bonnes
14498decd9 HOSTED_BMP_ONLY/linux: Fix case when no serial device is connected #806 2020-12-12 15:06:26 +01:00
Noah Pendleton
93d4c65948 Fix building with newer GNU make(#804)
More recent versions of GNU make remove the `-` prefix from
`$(MAKEFLAGS)`, which breaks the build:

```bash
 # output truncated to interesting parts
> make -C src --trace all_platforms
set -e ;\
mkdir -p artifacts/v1.7.1-91-g98b4ec5 ;\
echo "<html><body><ul>" > artifacts/index.html ;\
for i in platforms/*/Makefile.inc ; do \
        ...\
        make w --trace --no-print-directory clean ;\
        make w --trace --no-print-directory;\
        ...\
done ;\
echo "</ul></body></html>" >> artifacts/index.html ;\
cp artifacts/*.bin artifacts/v1.7.1-91-g98b4ec5
Building for hardware platform: f4discovery
make[1]: *** No rule to make target 'w'.  Stop.
```

Per the
[documentation](https://www.gnu.org/software/make/manual/html_node/Options_002fRecursion.html),
there's no need to manually apply insert `$(MAKEFLAGS)`, it should be
automatically included when using `$(MAKE)` when recursing.

I tested on my machine (make 4.2.1) and a docker image based on
ubuntu:trusty (make 3.81), both behaved the same (directories were not
printed when recursing by default);
2020-12-12 14:39:52 +01:00
UweBonnes
3cec441833
Merge pull request #805 from UweBonnes/bmp_only
Provide a compile time option (HOSTED_BMP_ONLY=1) for easier compilation of hosted
2020-12-12 13:39:51 +01:00
Stoyan Shopov
b5172cf6df Implement the 'find_debuggers()' function for hosted BMP on windows. 2020-12-11 18:36:48 +01:00
Stoyan Shopov
01f8628aed Bugfix in detecting BMP probes by usb serial number. 2020-12-11 18:36:48 +01:00
Stoyan Shopov
170fe0c368 Remove spurious comment. 2020-12-11 18:36:16 +01:00
Uwe Bonnes
4c5ce0b16a Hosted: Handle devices w/o serial number, e.g. GigaDevices GD-Link ARM/CMSIS-DAP 2020-12-11 18:36:16 +01:00
Uwe Bonnes
0f1fe9e438 hosted/linux: Find BMP devices without libusb. 2020-12-11 18:36:09 +01:00
Uwe Bonnes
bd5f4c6ed5 hosted: Consolidate ident output. 2020-12-11 17:55:31 +01:00
Uwe Bonnes
0870b778c0 hosted: Allow to build without libusb, libftdi and hidapi with HOSTED_BMP_ONLY=1 2020-12-11 17:50:16 +01:00
Uwe Bonnes
32db38ecf2 hosted/libusb: Move platform.c libusb related functions to own file. 2020-12-11 17:35:43 +01:00
Uwe Bonnes
41788f923b ftdi/stlink/jlink: Provide dummy functions in the HOSTED_BMP_ONLY case
Do not allow multiple inclusion by not declaring the functions as static to
help keep code clean.
2020-12-11 17:31:25 +01:00
Uwe Bonnes
98b4ec58bc Update to recent libopencm3 to undo unwanted change. 2020-12-07 21:51:22 +01:00
Emilio Lopes
633c6a2e81 Recognize "J-Trace Cortex-M PRO V2" in hosted mode 2020-12-07 11:52:33 +01:00
Uwe Bonnes
dd6aadc54d jtag: Add verbosity about devices found. 2020-12-06 15:18:08 +01:00
Uwe Bonnes
e65ee7124b stm32_mem: Handle utf8 for print and compare. 2020-12-06 15:18:08 +01:00
Uwe Bonnes
0a7bfd5923 dfu_f4: Fix sector_erase. 2020-12-06 15:18:08 +01:00
Uwe Bonnes
17dfec3572 dfu/cdcacm: Consolidate usage of ST vs BMP serial number. 2020-12-06 15:18:08 +01:00
Uwe Bonnes
5c7e0eedb0 command.c: Consolidate "mon version" output 2020-12-06 15:18:08 +01:00
Uwe Bonnes
07c3699225 version.h: Remove from platform.h files
- Consolidate ident string generation
- Recompile only needed files
2020-12-06 15:18:08 +01:00
Stoyan Shopov
e318f884bf Change the type of 'cortexm_wait_timeout' to unsigned.
It makes sense that the timeout value is unsigned, it also
resolves build errors on some platforms.
2020-12-04 11:44:50 +01:00
Stoyan Shopov
c9a419e44b Correct loss of sync protocol error #787 2020-12-04 11:33:23 +01:00
mean
e3fd12ebc6 gd32f1/f3 detection and ram/flash autoset 2020-12-03 11:16:47 +01:00
Jonathan Giles
575c25e570 Add support for STM32F1 clone with new AP_DESIGNER id 2020-12-01 10:23:16 +01:00
Uwe Bonnes
48a79ff9da adiv5: More checks for a sensible DPIDR. 2020-11-29 21:11:11 +01:00
Uwe Bonnes
752bc26536 adiv5: Fix memleak with duplicated base. 2020-11-29 21:11:11 +01:00
Uwe Bonnes
acec489647 adiv5_jtagdp: Always set idcode. 2020-11-29 21:11:11 +01:00
Uwe Bonnes
9e1b7fdac0 jlink/swd_low_access: Fix data direction during response read phase. 2020-11-29 15:48:50 +01:00
Uwe Bonnes
8903026c14 jlink/swd: swd frequency is fixed, not need to set. 2020-11-29 15:48:50 +01:00
Uwe Bonnes
f45c56af83 adiv5/swdp: Check early for valid DP idcode. 2020-11-29 15:48:50 +01:00
Uwe Bonnes
3b6432912d jlink: Catch another error with no target connected. 2020-11-29 15:48:50 +01:00
Uwe Bonnes
7df314e265 Firmware/Jlink: Fix double free when debug power-up fails (#780) 2020-11-29 15:48:50 +01:00
Uwe Bonnes
e1329499de platform_adiv5_swdp_scan: Do not double free with early errors.
adiv5_dp_init() clean up itself if errors happen
2020-11-29 15:48:50 +01:00
Stefan Agner
77025d4b6b Make dfu-convert.py Python 3 capable 2020-11-29 15:45:08 +01:00
Uwe Bonnes
cda83d3084 Fix memleaks.
Happened e.g. when Stlink could not enter debug or when cortexm_prepare timed out.
2020-11-27 22:26:48 +01:00
Uwe Bonnes
bf548e92c0 swd: After write low_access, always append 8 clk to move data through SW-DP.
Especially needed when leaving the debugger or during debug unit power-up.

ARM Debug Interface Architecture Specification ADIv5.0 to ADIv5.2
tells to clock the data through SW-DP to either :
- immediate start a new transaction
- continue to drive idle cycles
- or clock at least 8 idle cycles

Implement last option to favour correctness over slight speed decrease

Implement only for adapters where we assemble the seq_out_parity in our code,
as on firmware, ftdi and jlink. Hopefully the high level adapters do it right.

Reverts 2c33cde63fe779d3019fe8f63dd4420cb960bbfe and
cde7726b8730242cd40a9974d129b46af80c68af
2020-11-27 22:26:48 +01:00
Uwe Bonnes
9ac5adfcef adiv5: Additional decoding. 2020-11-27 22:26:48 +01:00
Uwe Bonnes
139e5d7e22 f4discovery: Compile time option to compile with ST bootloader
Just to keep things active. Prepare for F72 bootloader.
2020-11-27 22:26:48 +01:00
Uwe Bonnes
d78d7838d3 stm32f1: Always read DBGMCU_IDCODE for t->idcode (#770)
At least STM32F042 has 0x440 as romtable partno vs 0x445 as DBGMCU_IDCODE.
Thanks to Andrey Melnikov(aam335) for pointing out!
2020-11-27 22:26:48 +01:00
Uwe Bonnes
636bcee355 stlink/swlink: Remove the DFU upgrade utility.
Hopefully no old bootloaders are around. If otherwise, revert to last
commit before this and update the DFU bootloader.
2020-11-27 22:26:48 +01:00
Uwe Bonnes
653d486ee2 cortexm: Store CPUID in target structure. 2020-11-27 22:26:48 +01:00
Uwe Bonnes
03a7b06eb8 Makefile: Remove no longer needed code pathes. 2020-11-27 22:26:48 +01:00
Uwe Bonnes
824a1d8abc hosted/find_debuggers: Do not check hubs. Print class of devices unable to open. 2020-11-27 22:26:48 +01:00
Uwe Bonnes
27ef4569ca stm32/dfucore.c: Use libopencm3 provided defines and functions. 2020-11-27 22:26:48 +01:00
Uwe Bonnes
e68dd25813 cl_utils: Clarify -d option is BMP/firmware only and deprecate -d. 2020-11-27 22:26:48 +01:00
Uwe Bonnes
9d55128ab8 cl_utils: Get voltage only once. 2020-11-27 22:26:48 +01:00
Uwe Bonnes
f71e18948a GPIO for SWD: Slow down edges on more platforms. 2020-11-27 22:26:48 +01:00
Uwe Bonnes
e6823f39de Hosted: Print version with "-h" and "-t" option. 2020-11-27 22:26:48 +01:00
Uwe Bonnes
80154c5c7a adiv5_swdp: Fix more memory leak. 2020-11-27 22:26:48 +01:00
Uwe Bonnes
3ee31473c6 cortexm.c: LPC15xx has designer 43b and Partno 4c3
Thanks to JojoS!
2020-11-27 22:26:48 +01:00
Uwe Bonnes
62d9f60f03 hosted/firmware: Waits for read response as long as cortexm_wait_timeout. 2020-11-27 22:26:48 +01:00
Uwe Bonnes
26a23dd1cb stlinkv2: Try harder to open an AP.
Problem seen on STM32L0 with probably long sleep periods.
2020-11-27 22:26:48 +01:00
Uwe Bonnes
19e1fddba2 adiv5: Remove unnescessary read. 2020-11-27 22:26:48 +01:00
Noah Pendleton
35bcb4f7c6 Switch on the lpc546xx target
Enable the lpc546xx target. Tested on the LPCXpresso54628 dev board,
able to flash and debug.
2020-11-24 21:32:39 +01:00
Sean Cross
e9c02296f2 target: kinetis: add S32K118
This adds support for the NXP S32K118. This is an automotive-grade part
that is derived from the Kinetis line, so it has a very similar
interface to other parts in the family.

Signed-off-by: Sean Cross <sean@xobs.io>
2020-11-14 13:06:23 +01:00
jbuonagurio
f18be6ef7a Add support for Kinetis K12 and placeholders for other K-series MCUs 2020-11-07 12:44:05 +01:00
Uwe Bonnes
2c33cde63f cortexm.c/cortexm_halt_resume: Add some clock cycles to always get CPU going (#768) 2020-11-01 21:53:23 +01:00
Uwe Bonnes
d75f3124b9 ftdi_bmp.c: Reapply fix from #715: Check for libftdi 1.5 2020-11-01 12:09:27 +01:00
Stoyan Shopov
99142d1c0e Add documentation details for building PC-hosted BMP in msys2. 2020-11-01 11:33:54 +01:00
Uwe Bonnes
59dc1b7eb4 cortex-m7: Give hint about buggy core revision. 2020-10-23 09:40:15 +02:00
Uwe Bonnes
1f7a716710 adiv5.c: Run cortexm_prepare on all suspected CortexM instances.
Gets all debug units of the second CPU of a STM32H745 visible.
2020-10-23 09:40:15 +02:00
Uwe Bonnes
976c763747 jtag remote: Start fixing handling M0 (second jtag) for LPC4322 in high-level
- LPC11: Only print none-null unknown idcodes.
2020-10-23 09:40:15 +02:00
Uwe Bonnes
18673d9a56 adiv5: Rework DP/AP refcounting.
ASAN non longer reports leaks with the STM32H745.
2020-10-23 09:40:15 +02:00
Uwe Bonnes
0995fe1288 cmsis-dap: Various fixes
- decrease report size to 64, otherwise MIMRXT10x0-EVK crashed when
  reading larger memory block
- dp_read_reg acts direct, fixing CortexM core register read.
- length of data to write with read_block.
2020-10-23 09:40:15 +02:00
Uwe Bonnes
f76a7c4e92 adiv5: Release devices after scan.
Before, scanning only kept device stopped until POR or attach/detach cycle.
2020-10-23 09:40:15 +02:00
Uwe Bonnes
f15b1d7763 cl_utils: Clip opt_flash_start only when not set. 2020-10-23 09:40:15 +02:00
Uwe Bonnes
73e6b540b2 command: When debug channel is available, print morse messages readable. 2020-10-23 09:40:15 +02:00
Uwe Bonnes
c161521c26 cortexm: Designer ARM must be in the default path when probing. 2020-10-23 09:40:15 +02:00
Uwe Bonnes
776861c6a0 Makefile: Fix version.h generation for make all_platforms
Same fix as 0ae65cc10fd2.
2020-10-23 09:40:15 +02:00
Uwe Bonnes
cdd07544d5 Cortexm: Allow pure debug on devices not yet handled for flashing
- Recognize STM32L552 and MIMXRT10XX
- Fix another PIDR
- Fix bad debug print string.
2020-10-23 09:40:15 +02:00
Uwe Bonnes
80ddafc2f8 Jtag/High Level : Transfer dp->dp_jd_index with every HL command.
- Add REMOTE_HL_VERSION, now at 1. Fall back to hosted/low-level
  when wrong version is found and give hint to user.
2020-10-23 09:40:15 +02:00
Uwe Bonnes
3270138ec2 Revert 69e577c9243ce027b628e96881ce2416213fef43
What was thought to be a typo is apsel = 0xff for a dp access.
2020-10-23 09:40:15 +02:00
Uwe Bonnes
77c4f9d702 stlink: Rework README.md
- Document flashing BMP Firmware and reverting to ST firmware
- Consistant nameing
2020-10-19 14:13:29 +02:00
Uwe Bonnes
9cd3193a89 bmp_remote.c: Fix bug introduced with 8b929c12c9e. 2020-10-17 12:49:37 +02:00
Uwe Bonnes
0ffb4f7b18 cortexm: Fix protected SAM detection
- Only run cortex_prepare() if reading cidr fails
- With Atmel DSU detected, run cortexm_probe()
2020-10-17 12:49:37 +02:00
Uwe Bonnes
5bc743d221 samd: Propagate security after setting security by chip reset. 2020-10-17 12:49:37 +02:00
UweBonnes
1d707efa47
Merge pull request #757 from UweBonnes/hosted
Hosted/Firmware: Fix Jtag high level #756
2020-10-16 20:11:12 +02:00
Uwe Bonnes
8b929c12c9 hosted/jtag: Transfer jtag_devs to firmware. 2020-10-16 20:03:03 +02:00
Uwe Bonnes
3d92b82678 jtag: Use index and not device structure for jtag_dev_write_ir and jtag_dev_shift_dr 2020-10-16 20:03:03 +02:00
Uwe Bonnes
6e2a074064 bmp_remote: Deny high level JTAG for now.
jtag_devs and jtag_dev_count needs to be known on th firmware side
and remote_dp->dev needs to be filled with jtag_dev_t.
2020-10-16 20:03:03 +02:00
Uwe Bonnes
0f5fb6b9a0 remote: Initialise dp_read and low_access with SWD_INIT.
Before "mon s" after "mon j" failed.
2020-10-16 20:03:03 +02:00
Uwe Bonnes
752d14ca3e remote.c: Add comments. 2020-10-16 20:03:03 +02:00
Uwe Bonnes
ba26adce53 remote.h: Remove typo. 2020-10-16 20:03:03 +02:00
Uwe Bonnes
7ccf0d3e03 jtag_dev_t: Make dev, idcode and desc less generic.
No codechange intended.
2020-10-16 20:03:03 +02:00
Uwe Bonnes
87b546777a nrf51: Be more verbose about the protection status. 2020-10-16 12:16:33 +02:00
Richard Meadows
4108b649c2 stm32h7: Add support for new product lines
Add support for:
* STM32H7B3/B0/A3 (RM0455)
* STM32H723/33/25/35/30 (RM0468)

Successfully tested with:
* STM32H7A3ZIT (RM0455)
* STM32H747XIH (check for regressions)
2020-10-10 22:09:34 +02:00
UweBonnes
817c62d7fd
Merge pull request #507 from UweBonnes/cortexm_romtable
Cortexm romtable
2020-10-08 10:53:17 +02:00
Uwe Bonnes
877b4be8ee cortexm: Restrict probing by using the ap_designer.
More designers need to be observed and reported by users and added.
Request users to send needed data.
2020-10-07 20:12:35 +02:00
Uwe Bonnes
91d1ef8bf6 target/stm32: Use t->idcode with probe. 2020-10-07 20:12:35 +02:00
Uwe Bonnes
44bfb62715 Adiv5: Print Designer/Partno when device is not recognized
t->idcode is now 16 bit.
2020-10-07 20:12:35 +02:00
Uwe Bonnes
c456fc7f61 adiv5: Store AP designer and partno in the AP structure. 2020-10-07 20:12:32 +02:00
Uwe Bonnes
159196c2ad Cortexm: Remove forced_halt. 2020-10-07 20:11:33 +02:00
Uwe Bonnes
9bb2807706 adiv5/romtable: Prepare CortexM devices to read the ROMTABLE
It seems, writing to DHCSR fails silent when the device is sleeping.
Reading DHCS during sleep may return nonsense.
Repeated write may at some point catch the device running and succeed.
With devices sleeping for long time and running on faster clock the
chance for a successful hotplug gets smaller.

- Try hard to halt a sleeping device
- Prepare vector catch and enable all debug units by TRACENA
- Release reset
- Apply device specific fixes
-- STM32F7: Store old value of DBGMCU_CR, enable debug in sleep in
   DBGMCU before reading PIDR and restore DBGMCU on detach.

Signed-off-by: Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de>
2020-10-07 20:11:17 +02:00
David A. Aguirre Morales
a254bc6308 Fix icdi usb error https://github.com/blacksphere/blackmagic/issues/740 https://github.com/blacksphere/blackmagic/pull/748 2020-10-07 18:08:04 +02:00
Uwe Bonnes
ceaee2a11e hosted: Hint about BMPs in bootloader mode. 2020-10-07 17:12:22 +02:00
Gareth McMullin
dc8924a2bc
stm32h7: Don't tc_printf from flash functions (#747)
* stm32h7: Don't tc_printf from flash functions

Receving an 'O' packet while flashing confuses GDB and then
weird stuff happens.

* Replace tc_printf with DEBUG_WARN
2020-10-05 10:45:18 +02:00
Uwe Bonnes
9bba3165fb swdptap: Turnaround immediate after a reading with parity.
Thanks to JojoS.
Probably mostly cosmetic, but is keeps the device from driving SWDIO
until the next commands.
2020-10-02 10:51:14 +02:00
Uwe Bonnes
4d18496a6f hosted: Allow to disable high level commands for BMP.
Useful for tracking low level problems on native with hosted.
2020-10-01 15:49:21 +02:00
Uwe Bonnes
014abf6cc9 adiv5.c: Reduce number of errors if reading cidr fails. 2020-10-01 15:33:28 +02:00
Uwe Bonnes
be40d2b851 adiv5: Check Debug Base Address early
Reduces printout when scanning the romtable
2020-10-01 15:22:17 +02:00
Uwe Bonnes
747336e927 f4discovery: Slow done JTAG pin slew rate to avoid ringing #742 2020-10-01 15:06:16 +02:00
Eivind Alexander Bergem
38bc5bbf82 Add LPC546xx support #741 #553 2020-09-30 12:56:53 +02:00
Uwe Bonnes
2fdd94adeb STM32F7: Add another missing Arch ID. 2020-09-24 16:20:34 +02:00
Uwe Bonnes
0ae65cc10f src/Makefile: Fix version.h generation.
It seems, some git behaviour change got by unnoticed.
2020-09-22 19:02:26 +02:00
Uwe Bonnes
c5a0271e4c README.md: Toolchain and OS specific remarks. 2020-09-22 18:21:48 +02:00
Uwe Bonnes
61d919c1ac libftdi: Remove no longer needed workaround for travis CI. 2020-09-20 14:10:37 +02:00
Uwe Bonnes
77231e8972 serial_no: Fix error with "mon trace" #732
launchpad-icdi: Allow to set a serial number with make
2020-09-20 13:23:52 +02:00
Uwe Bonnes
bdb351a6ea adiv5_swdp: On ACK_FAULT, error() and try again once #731
when writing CSW.
2020-09-18 20:07:32 +02:00
jxltom
a4a934f461 Add comments for hardware revision of v2.1 2020-09-17 11:54:19 +02:00
jxltom
75b5e72a00 Fix typo 2020-09-16 18:41:56 +02:00
Raghu
de01a75ca9 Fix broken link to bluepill pinout. 2020-09-15 20:58:10 +02:00
Uwe Bonnes
6d18a61b2e hosted: Make ASAN build optional.
Use ASAN=1 on the make command line to activate,
2020-09-11 15:23:13 +02:00
Damien Merenne
120b3134bb Add SAM4SD32C/B support. 2020-09-07 17:36:15 +02:00
Uwe Bonnes
8289862b55 gdb: Reset flash_mode with when erase or flash fails.
Thanks to Dave Marples <dave@marples.net>, extracted from  #607
2020-09-04 15:17:29 +02:00
Uwe Bonnes
58281ec232 SWD Timing: Enhance SWD high time with low speed loss.
On F103 no high time < 80 ns and no low time < 100 ns was seen with a scope
2020-09-04 14:45:34 +02:00
Thomas Jarosch
2641291874 stm32_mem: Fix python3 crash due to mix of tabs and spaces
Fixes this issue:

$ python3 ./stm32_mem.py blackmagic.bin
  File "./stm32_mem.py", line 199
    if (os.path.getsize(args.progfile) > 0x1f800):
                                                 ^
TabError: inconsistent use of tabs and spaces in indentation

and allows to run with python2 too.
2020-09-04 14:19:19 +02:00
Remco Stoutjesdijk
b51c9367fc Swolisten: Moving the library argument to the end of the command line #718 2020-09-04 12:35:03 +02:00
Uwe Bonnes
af3480e523 hosted: Update Readme.md 2020-09-04 11:49:13 +02:00
Uwe Bonnes
6650831243 ftdi: Get turtelizer (JTAG only FT2232D dongle) going
FT2232D seems to dislike "Set TCK/SK Divisor" or
"Set Data Bits Low Byte" as first command on a non-first run
- Add printout when garbage is found
- Add "Disconnect TDI to TDO for Loopback" as first MPSSE command
  (seemed to help!)
2020-09-04 11:49:13 +02:00
Uwe Bonnes
74b3baad1e ftdi_bmp : Another size fix and small rearrangement. 2020-09-04 11:49:13 +02:00
Uwe Bonnes
aeb97466b9 libftdi: Automatically switch to JTAG if SWD is not possible. 2020-09-04 11:49:13 +02:00
Uwe Bonnes
ae8cb8ab46 ftdi_bmp: Reject writes with no data.
Pending transfers made the MPSSE behaviour strange and unpredictable.
2020-09-04 11:49:13 +02:00
Uwe Bonnes
c41ab1738e ftdi/swdptap: Use parity builtin. Fix array width. 2020-09-04 11:49:13 +02:00
Uwe Bonnes
34d0f8a2a1 ftdi: Recognize bitbang SWDIO settings. 2020-09-04 11:49:13 +02:00
Uwe Bonnes
6ac0a25123 ftdi: Add UM232H as probe. 2020-09-04 11:49:13 +02:00
Uwe Bonnes
d73a6a3d29 platform/ftdi: Do not double initialize. 2020-09-04 11:49:13 +02:00
Uwe Bonnes
f0b0639189 ftdi: Output wire debug. 2020-09-04 11:49:13 +02:00
Uwe Bonnes
e95e5e3fba ftdijtag: Really enable TMS/TCK/TDI driver. 2020-09-04 11:49:13 +02:00
Uwe Bonnes
f4eed249eb hosted/ftdi: Allow to list supported cables. 2020-09-04 11:49:13 +02:00
Uwe Bonnes
8a2bce26f2 Hosted: Fix memory leak when platform_swdptap_init fails. 2020-09-04 11:49:13 +02:00
Uwe Bonnes
7b497302c0 hosted/ftdi: Autodetect ftdi cables with distinguishing feature. 2020-09-04 11:49:13 +02:00
Uwe Bonnes
a83e76bef9 libftdi: Add USBMATE. 2020-09-04 11:49:13 +02:00
Uwe Bonnes
c78066255d libftdi: Infrastructure to test for target voltage present. 2020-09-04 11:49:13 +02:00
Uwe Bonnes
aff624b6e0 libftfdi: Allow to specify external resistor SWD connection.
More explanations in src/platforms/hosted/Readme.md
2020-09-04 11:49:13 +02:00
Uwe Bonnes
eabf45357d libftdi: Reinitialize pins when switching JTAG/SWD. 2020-09-04 11:49:13 +02:00
Uwe Bonnes
05534e9b49 libftdi/swdptap: Provide SWD using generic MPSSE if hardware allows. 2020-09-04 11:49:13 +02:00
Uwe Bonnes
40ba261982 libftdi: Use asynchronous transfers if header indicate newer libftdi1.
This is a hack to keep travis happy. Setting up travis to use a recent
libftdi1 is a major issue.
2020-09-04 11:49:13 +02:00
Uwe Bonnes
9b6e19785e Implement SRST for libftdi.
Travis GCC needs -Wno-missing-field-initializers or will otherwise warn.
2020-09-04 11:49:13 +02:00
Matthew Skolaut
dea4be2539 Add ifdef to check for libftdi 1.5 to use ftdi_tcioflush instead of ftdi_usb_purge_buffers 2020-08-21 13:10:55 +02:00
Matthew Skolaut
7e1b0321e2 Cleanup Makefiles for hosted bmp on darwin 2020-08-21 11:28:17 +02:00
Matthew Skolaut
5908fc2da1 Add serial auto-connection to darwin target 2020-08-21 11:28:17 +02:00
Uwe Bonnes
e75eb19d78 cmsis_dap: Detect CMSIS-DAP before STLINK
Debugger may be realized with the ST USB Vendor ID.
2020-08-16 15:20:58 +02:00
Uwe Bonnes
998a9747f8 cmsis_dap: Make some errors more prominent. 2020-08-16 15:20:58 +02:00
Uwe Bonnes
c97c4a0960 hosted: Better decoding for ap_decode_access(). 2020-08-16 15:20:58 +02:00
Uwe Bonnes
badff20099 cmsis_dap.c: Fix dap_dp_read_reg. 2020-08-16 15:20:58 +02:00
David Lawrence
f65afb1588 Use correct IAP entry address for LPC84x 2020-08-14 20:00:18 +02:00
Uwe Bonnes
dd74ec8e6f stlinkv2: Detect fail mem_read on jtag too. 2020-08-05 16:20:52 +02:00
Uwe Bonnes
805cfbdcb5 Build hosted for widows with hidapi static linked. 2020-08-03 18:59:50 +02:00
Uwe Bonnes
fca8593d92 serial_win: Find BMP comport by serial number. 2020-08-03 18:59:50 +02:00
Uwe Bonnes
3eb51ce94f serial_win.c: Copy the enough of the device name. 2020-08-01 14:00:17 +02:00
Uwe Bonnes
11217f8a45 serial_win: GDB needs to handle DTR. 2020-08-01 14:00:17 +02:00
Uwe Bonnes
71e9d78210 adiv5.c: Add another ARCH_ID found STM32F205. 2020-08-01 14:00:17 +02:00
Uwe Bonnes
1b12e407fd adiv5: Add missing arch identifiers for Cortex-M7 ETM. 2020-07-31 11:53:15 +02:00
Uwe Bonnes
71e5b4d3cb hosted/stlinkv2.c: Fix bug introduced with #703 2020-07-29 13:42:07 +02:00
Uwe Bonnes
72387164eb hosted/stlinkv2.c: Handle AP_WAIT error when switching to SWD 2020-07-29 12:22:18 +02:00
Uwe Bonnes
a392480631 hosted/stlinkv2.c: Use V2 API to read coreid. 2020-07-29 12:22:18 +02:00
Francesco Valla
696daa8352 adiv5: fix debug print of dev_type
Since dev_type is an 8 bit unsigned integer, use the PRIx8 macro instead
of PRIx32.
2020-07-29 11:32:24 +02:00
Uwe Bonnes
64cf30e4cd Rework/update/add Readme.md in the platforms directories. 2020-07-29 10:32:49 +02:00
Uwe Bonnes
726d4b4496 adiv5.c: Add missing DEVTYPE and ARCHID to some existing PIDRs(#698,#699)
Probably more additions are needed.
2020-07-14 16:26:32 +02:00
Uwe Bonnes
52bfe538e3 cdcacm.c: Set bMaxPacketSize0 to 32 (#693, #697)
Smaller bMaxPacketSize0  resulted in delayed enumeration when BMP firmware
is started by the STLink bootloader.
2020-07-14 15:57:03 +02:00
Uwe Bonnes
09ceaea70f adiv5_swdp: Fix another memory leak. 2020-07-14 15:02:13 +02:00
UweBonnes
2ae62433d2
Merge pull request #690 from themadinventor/arm_v8m
Add ROM table support for Cortex-M33 and Cortex-M23
2020-07-13 10:56:03 +02:00
Aled Cuda
a673efc26b Remove extra definitions of jtag structures in the STLink hosted setup to support "gcc (GCC) 10.1.0" on Archlinux 2020-07-12 23:14:19 +02:00
Fredrik Ahlberg
7ebb94d134 cortexm: Add comment on CPUID register 2020-07-12 22:54:39 +02:00
Fredrik Ahlberg
4391851f4d adiv5: Change component descriptions from MTB to Micro Trace Buffer for consistency 2020-07-12 22:29:04 +02:00
Fredrik Ahlberg
0aadd0abce Adiv6: Add comment on DEVTYPE and ARCHID fields with references 2020-07-12 22:27:46 +02:00
Fredrik Ahlberg
fcd945a529 cortexm: Read CPUID to identify core version 2020-07-12 12:08:22 +02:00
Fredrik Ahlberg
39a20d78ff v8m: only check relevant bits in DHCSR when polling in cortexm_forced_halt 2020-07-12 12:07:12 +02:00
Fredrik Ahlberg
a35e9c8e5c Adiv6: Read DEVTYPE and ARCHID to identify Cortex-M23 and Cortex-M33 debug components 2020-07-12 12:00:31 +02:00
Uwe Bonnes
661f78033a stm32f1: Add F1 XL with dual bank handling, 2020-07-08 14:31:58 +02:00
Uwe Bonnes
fc6ca5bc06 Remote: Add procedure to test if high-level remote functions are available
Removes need for updated version string.
2020-07-08 14:15:35 +02:00
Uwe Bonnes
bfda64c656 stlink: Remove unused double defined variable "running_status"(#683) 2020-07-02 19:44:31 +02:00
Uwe Bonnes
85d35b75ce libftdi/jtagtap_tdi_tdo_seq: Remove dubious Null termination. 2020-07-02 14:56:10 +02:00
Uwe Bonnes
be6991344f README.md: Add sample session (#570) 2020-06-16 13:50:40 +02:00
Uwe Bonnes
a4cdd6b310 hosted: Report missing USB access rights only if no debugger found. 2020-06-07 16:29:19 +02:00
Uwe Bonnes
eabd69dcdb Adiv5: Protect DBG/SYSTEM Power-Up request with timeout too.
CMSIS-DAP without connected target looped infinite in that situation.
2020-06-07 13:14:32 +02:00
Uwe Bonnes
e35025d214 CMSIS_DAP: Warn when hidapi-libusb is not found. 2020-06-06 15:28:53 +02:00
Uwe Bonnes
5097a23196 jlink: Fix wrong sized array. 2020-06-06 15:28:53 +02:00
UweBonnes
dec431f869
Merge pull request #675 from UweBonnes/hydrabus
hydrabus: Disable DFU file generation untit somebody fixes dfu-conver…
2020-06-05 17:04:09 +02:00
Uwe Bonnes
4ede113ca7 hydrabus: Disable DFU file generation untit somebody fixes dfu-convert.py
This allows "make all_platforms" to succeed on python3 only systems.
2020-06-05 16:23:28 +02:00
UweBonnes
f5e305e237
Merge pull request #669 from blacksphere/v1.6.2-rc0
V1.6.2 rc0:
Unify PC-Hosted BMP

    Add CMSIS-DAP and Jlink
    Add high level BMP remote commands
    Clean up command line interface and debug messages
2020-06-05 15:57:25 +02:00
Uwe Bonnes
da45281696 GetTargetVoltage: Print info about voltage only when info is relevant. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
ef816e3183 hosted: add libftdi implementation, remove old implementation. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
9969c984f3 detour jtag primitives. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
e34a27f72c Detour swd primitives. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
1e10b96b03 Allow multiple scan routines. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
f3790b90e5 command.c: Simplify usage of serial_no serial number string. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
05adcd9bf5 remote.c: Compile only relevant functions.
Do no compile firmware functions when compiling pc-hosted.
2020-06-05 14:59:30 +02:00
Uwe Bonnes
16967b4328 adiv5: Remove only local dp_idcode used from ADIv5_DP_t struct. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
aabd07738e cl_utils: Use start of flash in memory map as default flash start. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
ab7991c3a6 hosted: Add bmp_remote, remove old pc-hosted platform. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
b0cf7d24bd adiv5.c: Fix another leak. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
966ac4036d target.c: Check for valid flash structure. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
b8b34e7b1d adiv5: remove cfg for AP structure, cfg is only used local. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
425002a38f hosted: Add -l argument to list only available debuggers and exit. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
13c3c934d2 Hosted: Add Stlink, remove old pc-stlinkv2 platform 2020-06-05 14:59:30 +02:00
Uwe Bonnes
783ec377d9 adiv5: Export extract. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
60f39f55b4 MSP432: Warn when hardware version not supported. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
dc3fd2eb06 Classify debug messages
Firmware BMP with ENABLE_DEBUG=1 will print WARN and INFO as before.
PC-Hosted BMPwill alway print to stderr. Warn is printed unconditional,
INFO, GDB, TARGET, DONGLE and WIRE will print if their appropriate bit in
cl_debuglevel is set via the -v verbose command line argument.
INFO will go to stdout with -t or -l.
2020-06-05 14:59:30 +02:00
Uwe Bonnes
09602a9e74 serial_unix: Simplify timeout setting. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
eee16cf08a platforms/tm4c/jtagtap.c: Remove unreferenced and incomplete file. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
7956fbc361 cl-utils: Print memory map when test is specified. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
c5c21bb958 README.md: Mention the PC-Hosted GDB server. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
8fea3f6baa pc/serial_xx: Change arguments for the open call. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
b5182e09d0 cl_utils: When reading from flash to file, truncate the file. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
9ade8b24f7 hosted: Add Readme.md 2020-06-05 14:59:30 +02:00
Uwe Bonnes
a09104c281 Build firmware executables as *.elf file 2020-06-05 14:59:30 +02:00
Uwe Bonnes
8db979798c cl_utils.c: Report read/write speed. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
4698a26bab common/swdptap: Slight speed increase and better setup time for write. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
dd022fcb44 platforms/pc: Add common usb utilities. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
c5d0902d4c cl_utils: Fix memory leak. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
64f3dff8a8 PC-Hosted: Better debug output. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
52739def01 Copy relevant stlink files. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
815e09bb1b cl-utils: Add more arguments 2020-06-05 14:59:30 +02:00
Valmantas Paliksa
b06c0ba8d5 bmp_remote: Use high level functions.
Based on #570 (OpenOCD HLA interface driver for Blackmagic), but now
usefull for bmp-remote.
2020-06-05 14:59:30 +02:00
Uwe Bonnes
386a4bfce7 hosted: Device detection and selection. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
921c23eb74 serial_unix: Return instead of exit in case of error. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
3290def5f8 Add empty compilable project. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
ef558eebb8 CMSIS-DAP support.
Thanks to edbg, pyocd and openocd for code and ideas.
2020-06-05 14:59:30 +02:00
Uwe Bonnes
c3d509e6c0 Clean up PLATFORM_HAS_DEBUG
Use only for firmware platforms.
2020-06-05 14:59:30 +02:00
Uwe Bonnes
4ba6afed28 Add jlink pc-hosted platform. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
9a46c6fd25 Allow BOARD_IDENT as function 2020-06-05 14:59:30 +02:00
Uwe Bonnes
efce2ae892 Do not compile jtagtap and swdptap when not needed. 2020-06-05 14:59:30 +02:00
Uwe Bonnes
563df2d354 Detour ADIv5 high-level functions. 2020-06-05 14:59:30 +02:00
Stoyan Shopov
34a13723d8 Decrease the control USB pipe size on f103 blackmagic probes to 8 bytes
Rationale:
In USB device mode, the f103 chip provides 512 bytes
of memory for USB traffic. In the 'master' branch
of the blackmagic probe, the control endpoint pipe size
is set to 64 bytes, effectively consuming a quarter
(1 'in' endpoint, 1 'out' endpoint == 2 endpoints,
2 /* endpoints */ x 64 /* bytes per endpoint */ == 128 bytes
out of 512 /* bytes of precious usb packet memory */).
The USB standard, for full speed devices, does allow
a control endpoint size of 8 bytes.

I am not too aware of all the details of the USB standard,
but the USB standard seems to allow fragmented transactions
on the control USB pipe (endpoint 0), which libopencm3
apparently supports:
libopencm3/lib/usb/usb_control.c:usb_control_send_chunk()

I am using this change (from 64, to 8 bytes)
on a windows 10 machine, on an stlink hardware
('PROBE_HOST=stlink'). It works on my machine.

This change can potentially provide other USB endpoints
in the blackmagic firmware with more memory
2020-06-05 13:58:08 +02:00
Dömötör Gulyás
69e330849d fix flash map for STM32G431, as it is a special case different from the STM32G47x and STM32G48x chips 2020-06-05 13:41:18 +02:00
Thomas Bénéteau
f9f928e9d6 Add support for LPC8N04 2020-06-05 12:33:51 +02:00
Mark Rages
34c0d5a1c9 When timeout is 0, timeout_is_expired() should return immediately. 2020-06-05 12:33:24 +02:00
Koen De Vleeschauwer
6eb1b09c1c pc-hosted semihosting 2020-05-27 12:51:29 +02:00
Koen De Vleeschauwer
541861e978 traceswo decoding 2020-05-16 15:04:35 +02:00
Koen De Vleeschauwer
54ee00b0f6 set semihosting sys_clock time origin 2020-05-13 17:50:39 +02:00
Uwe Bonnes
499309f648 stm32f1: Tell user about STM32F10(3) clone. 2020-05-13 13:07:55 +02:00
Alexey Shvetsov
1a83bc6892
Rename variant_string in efm32 samd samx5x (#659)
* Rename variant_string

Files efm32 samd samx5x uses same function name that collides during
linking (checked with gcc10)

Signed-off-by: Alexey 'Alexxy' Shvetsov <alexxyum@gmail.com>

* Also make xxx_variant_string static

Signed-off-by: Alexey 'Alexxy' Shvetsov <alexxyum@gmail.com>
2020-05-12 17:47:04 +02:00
Alexey 'Alexxy' Shvetsov
805464db23 Fix redefinition of io function
Now it should work fine with any gcc version. Old one produces error
like in #657

Signed-off-by: Alexey 'Alexxy' Shvetsov <alexxyum@gmail.com>
2020-05-10 10:58:03 +02:00
Uwe Bonnes
9b939f4a3a stm32f4: Fix option byte handling (#654)
Option bytes are not accessible with level 1 protection, so
Use FLASH_OPTCR(x)
Fix crash with "mon opt write xxxx"
Handle option manipulation better when HW Watchdog fuse is set
Allow abbreviated "mon option x<yyy>" commands
2020-05-05 12:52:32 +02:00
Sid Price
923949d5dd Fixed variable/function name clash building on Windows 2020-05-03 15:45:31 +02:00
Koen De Vleeschauwer
9f8c7be360 semihosting 2020-05-02 12:55:29 +02:00
Vegard Storheil Eriksen
d63e870e82 cdcacm: Fix UART interface OUT endpoint MPS in descriptor.
3e3e450 reduced the buffer size for the UART interface OUT endpoint to
32B, but left wMaxPacketSize at 64B. This effectively configures the
hardware to receive packets up to 32B in size while telling the host it
can send larger packets. On reception of a larger packet, the usb core
treats it as an error, drops the packet and replies with a STALL
handshake.

This commit fixes the issue by updating the descriptor to match the
buffer configuration.

Fixes #538
2020-05-01 12:39:40 +02:00
Uwe Bonnes
08bb4d5775 pc-hosted: Make JTAG work. 2020-04-27 20:30:51 +02:00
Koen De Vleeschauwer
8851504a41 new semihosting commands 2020-04-23 09:43:46 +02:00
Uwe Bonnes
ada17ada23 stm32f4/7: Always use largest flashsize for device family (#633, #635, #644)
Do not care for the FLASHSIZE register. Leave it up to the user to abuse
flash area the ST did not announce.
2020-04-21 17:04:07 +02:00
Pieter du Preez
d55cea871d Fixed overrun and formatting, when dumping data in swolisten.
The swolisten program failed to print the cbw buffer correctly while
in dump mode. As printf() is used to print the dump, it is expected
that the cbw buffer is zero-terminated, which would only be
the case, if the cbw buffer is initialized with zeros, before filling it
with new data. One could set the entire cbw buffer to zero, but it
will be more efficient to only set the size-th byte to zero.

Furthermore, if a '%' character appears in the data, printf() will
attempt to format it, causing unexpected results.

This patch fixes the above 2 problems, by:

1. using the size variable to set the size-th byte of the cbw
buffer to zero, before passing it to printf().

2. calling printf() with a "%s" formatting string, followed by the
data buffer, cbw.
2020-04-20 00:19:30 +02:00
Uwe Bonnes
164eb43f00 NRF5: Do not reset target options. 2020-04-14 19:01:43 +02:00
Uwe Bonnes
bea8436561 NRF5: Always set CORTEXM_TOPT_INHIBIT_SRST(#230)
The problem also happens with NRF52840. Set CORTEXM_TOPT_INHIBIT_SRST
for all NRF5 device.
People should be more persistent!
2020-04-14 18:11:23 +02:00
mean
d1468530bd add basic support for LPC11U68 (and maybe LPC11U68) 2020-04-06 23:36:49 +02:00
Francesco Valla
846dadcc39 lmi: add support for TM4C1294NCPDT 2020-04-03 19:42:24 +02:00
Uwe Bonnes
58a8571d5b stlink: Print Target voltage
This adds about 600 bytes.
2020-04-03 16:19:20 +02:00
Francesco Valla
8a9980cd06 pc/serial_unix: bump device path buffer size to 4096 bytes
Since dp->d_name can be up to 255 bytes long and the 'name' buffer variable is
is a superset of it, bump the size of the latter to 4096 bytes (correspoding
to PATH_MAX on Linux systems).
2020-04-03 11:05:11 +02:00
Uwe Bonnes
b4ab9f328e pc-hosted: Put serial handling in own files for unix and implement for windows.
- If host provided /dev/serial/by-id, device must not be given and
  multiple devices may be selected with -s <(partial) serial number>
- On windows, device must by specifies with -d
2020-03-31 17:02:56 +02:00
Uwe Bonnes
18ae2bb50d cl_utils.c: Include <windows.h> for windows builds that work on files. 2020-03-31 17:02:56 +02:00
Uwe Bonnes
1a0cee4e9d pc-hosted: Clean up Makefile.inc. 2020-03-31 17:02:56 +02:00
Uwe Bonnes
bd73adf9c7 bmp/pc platforms: Deduplicate code. 2020-03-31 17:02:56 +02:00
Uwe Bonnes
9ca401497c stm32/timing_stm32.c: Remove fixed constants and direct SCB access 2020-03-31 16:54:04 +02:00
Uwe Bonnes
c4d7232223 Export function to read out PIDR and use for samd and samx5x. 2020-03-26 19:05:57 +01:00
Uwe Bonnes
a0e42e229b Make more things static.
No functional change intendend.
2020-03-26 18:44:19 +01:00
Uwe Bonnes
eca3a8dd8f pc-stlinkv2: Make stlink_usb_get_rw_status static and allow to suppress errors
This helps to not overflow the console.
2020-03-26 17:56:12 +01:00
Uwe Bonnes
91d7656d86 stlink/bootloader: Really allow to detach.
- To reenumerate, rcc_periph_reset_pulse(RST_USB) seems enough.
- Document bootloader entry and exit behaviour of ST-LINK V2
- Document bootloader entry on ST-LINK V2-1
2020-03-26 17:15:32 +01:00
Uwe Bonnes
890b494290 pc-stlinkv2: Update README.md 2020-03-26 12:21:22 +01:00
Uwe Bonnes
effd43ce38 Harden cortexm_reset() and remove double reset(#601)
Thanks to Dave Marples <dave@marples.net> for input.
- Issue only one reset. Start with SRST. Only if not seen, use SYSRESETREQ
- Wait for release of DHCSR_S_RESET_ST before issuing more commands
- Add timeout to catch reset line stuck low
- Remove AP errors
2020-03-25 11:22:14 +01:00
Uwe Bonnes
bc84d803ea libopencm3: Update to Head March 25 2020 to ease windows compilation #394
Last libopencm3 upgrade resulted in problems for libopencm3 build on
windows. Cross-mingw builds where no affected. Recent changes of
libopencm3 seem unrelated to libopencm3 functionality used by BMP
2020-03-25 11:04:01 +01:00
Uwe Bonnes
2e185ba578 BMP/PC: Allow to compile with mingw64 (#615)
__USE_MINGW_ANSI_STDIO 1 must be set befor any windows specific included.
2020-03-24 17:59:13 +01:00
Uwe Bonnes
e57792c95e stm32_mem: Check file size before flashing(#614)
stm32mem is only meant to flash BMP to a STM32F103x(8|B). No need to
decipher the DFU interface string.
2020-03-22 16:40:06 +01:00
Uwe Bonnes
2b76ec0ea3 dfucore: Reject erase outside the allowed range
An illegal erase request may get emitted as the DFU program may erase
first. Checking before flashing is not enough.
2020-03-22 16:38:54 +01:00
Uwe Bonnes
a7efe7cc14 cl-utils: Display targets found.
+ other small changes in DEBUG output.
2020-03-10 17:34:30 +01:00
Uwe Bonnes
65cb886bb6 Export connect_under_reset. 2020-03-10 11:44:53 +01:00
Uwe Bonnes
2065c70888 adiv5: Split PRIx64 into two PRIx32 as nanolib does not support PRIx64. 2020-03-10 10:56:42 +01:00
Uwe Bonnes
75186f7d50 ADIv5: More CoreSight device decoding:
- MTB-M0+ (Simple Execution  Trace)
- M33: Devices need finer decoding (DEVTYPE at offset 0xfcc)
2020-03-08 22:37:59 +01:00
Uwe Bonnes
c7e7bd61b6 stlink: Do not wait for the reaction on the reset line.
pc-hosted will abort, if the reset line is held externally to some value.
As assert is either driven or driven open drain, we can assume assert
immediate. For deassert, logic levels differences between the debugger and
the debuggee may apply and other ways to check the result are needed, like
CORTEXM_DHCSR_S_RESET_ST.
2020-03-08 16:27:03 +01:00
Uwe Bonnes
e48d9ebc92 cl_utils: Allow to connect under reset. 2020-03-06 23:15:56 +01:00
Uwe Bonnes
919d9320fd Remove unrelated files. 2020-03-06 19:33:20 +01:00
Uwe Bonnes
05dc2e239e pc-hosted: Disable TPWR when blackmagic command line interaction terminates. 2020-03-06 17:16:33 +01:00
Extreme kefir
c94a03af48 STM32F1 High density devices DFU support(#587) 2020-03-05 19:58:55 +01:00
Uwe Bonnes
288620551f adiv5: Print out SYSROM PIDR.
We need to know more about what devices indicate proper PIDR and what
devices fail to do so.
2020-03-04 19:02:07 +01:00
Uwe Bonnes
8c959defca efm32: Make local functions static. 2020-03-04 18:44:40 +01:00
Uwe Bonnes
13b9fe1efc cl_utils: There is no need for a (dummy) target controller.
Fix for #593.
2020-03-04 16:57:05 +01:00
Uwe Bonnes
03d84d0d5c command line tools: Allow to set power. 2020-02-20 12:12:26 +01:00
zvova7890
7a595ead25 fixup F103x8 flash size before build dfu iface string
we handle F103x8 as F103xB with 128k flash
2020-01-22 16:01:39 +01:00
Uwe Bonnes
45fb12f9b6 cl-utils: Care for -j (JTAG) argument in test mode. 2020-01-21 11:49:45 +01:00
Sid Price
1a1cabc90b Remove explicit include of rcc.h and allow common file to steer the right file
Clean up DFU files with MCU explicit includes
2020-01-14 00:09:20 +01:00
Ondrej Mikle
2137e775a4 stlink: update docs on how ti reflash BMP back to STLink original firmware (#572)
* stlink: update docs on how ti reflash BMP back to STLink original firmware

* stlink: specify v2 in docs on reflashing back
2020-01-11 16:52:22 +01:00
Sid Price
ee553c9a50 Corrected error checking for socket functions (#577) 2020-01-11 16:47:02 +01:00
Uwe Bonnes
c3a3f7737f Hosted: Allow command line interaction. 2019-12-13 14:59:42 +01:00
Uwe Bonnes
ee316431f5 stlink for st-bootloader: Reset with platform_request_boot()
Both V2 and V21 switch to (ST) bootloader with powered reset.
2019-12-13 14:59:42 +01:00
Uwe Bonnes
470c8e8cf1 target_flash_erase: Do not crash when requesting erase of unavailable flash.
Allow to erase from command line.
2019-12-13 14:59:42 +01:00
Uwe Bonnes
b9eb467ecf Command line: Restrict verify to length of binary file. 2019-12-13 14:59:42 +01:00
Uwe Bonnes
269d38ce65 cl_utils: Allow to issue reset.
Issue reset only when flashing or when reset was requested.
2019-12-13 14:59:42 +01:00
UweBonnes
0b6f393d5b
Merge pull request #561 from UweBonnes/pc_prog
Command line interaction for pc-hosted platforms.
2019-12-08 16:57:58 +01:00
Uwe Bonnes
da5a0cd3f5 Infrastructure for command line interface to target
- Program, read and verify flash
- Test mode: Probe and attach to device and exit
2019-12-08 16:43:19 +01:00
Uwe Bonnes
ab396f9745 Allow %z specifier in windows builds. Supercedes #562. 2019-12-08 16:43:19 +01:00
Uwe Bonnes
1bef51e145 adiv5: Abort scanning APs after 8 void APs. 2019-12-08 16:43:19 +01:00
Uwe Bonnes
6d01c3c55b stlinkv2: Propagate AP errors
Needed when reading some memory region of unknown size.
2019-12-08 16:43:19 +01:00
Uwe Bonnes
bdd76de517 Erase: Fix endless erase when erase-area did not end on (page|block) boarder. 2019-12-08 16:43:19 +01:00
Uwe Bonnes
25d24e5c34 efm32: Allow to compile with -Og. 2019-12-08 16:43:19 +01:00
UweBonnes
ea779d1372
Merge pull request #567 from UweBonnes/438
Rebase EFM patch #438, compiling fine in all intermediate steps
2019-12-08 16:42:22 +01:00
Richard Meadows
5943552a6b [efm32] Probe for the EFM32 Authentication Access Port (AAP)
Supported functionality through this AP:
* Issuing a DEVICEERASE command
2019-12-08 16:21:02 +01:00
Richard Meadows
260fc88d8f [efm32] Add command to set and print bootloader enable status
This is a bit in the Lock Bit (LB) flash page, so it can only be
cleared by this routine
2019-12-08 16:17:02 +01:00
Richard Meadows
7f0d5febc3 [efm32] Print MSC Interrupt Flags to DEBUG after each flash write 2019-12-08 16:16:55 +01:00
Richard Meadows
e85df763b7 [efm32] add new devices PG12B, JG12B, GG11B, TG11B, GG12B
Rework MSC layout check
2019-12-08 15:55:12 +01:00
UweBonnes
f89542c79f
Merge pull request #203 from dlaw/master
Add LPC11xx command to read out unique ID from target. Restore Ram and registers after call.
2019-12-08 15:45:49 +01:00
Roland Ruckerbauer
5ec12e4103 Support arbitrary bit counts jtagtap_tdi_tdo_seq pc-hosted 2019-12-08 14:34:35 +01:00
Roland Ruckerbauer
d42477ebc5 Fix infinite loop in jtagtap_tdi_tdo_seq 2019-12-08 14:34:35 +01:00
Uwe Bonnes
f10ccfd83e f4discovery: Fix error with GCC9 being more picky with sizes. 2019-12-05 19:36:05 +01:00
Artur Maciuszonek
8a07f44435 Add support for the kinetis KL16Zxx devices. Tested on KL16Z128VFM4 custom hardware 2019-11-21 20:37:13 +01:00
Thiadmer Riemersma
1924aa4999 Make baudrate parameter of traceswo command mandatory for stlink/swlink, and superfluous on other platforms; change help message accordingly. 2019-11-19 20:20:13 +01:00
Uwe Bonnes
e7e34600a4 lpc11: Only print Idcode if not zero and not yet handled.
Otherwise for all Cortex-M not yet handled this LPC messages appears.
2019-11-17 13:24:39 +01:00
Ken Healy
9198c951bb Reduce flash space required for SAM D51/E5x driver
* Reuse functions that are common with the SAM D1x/D2x driver
* Only include the mbist and write8/16/32 user commands if
  SAMX5X_EXTRA_CMDS is defined
2019-11-17 12:45:49 +01:00
Ken Healy
d3c330ea1a Fix issues with Travis CI build
It appears the Travis version of gcc-arm-none-eabi doesn't allow the %x
printf format specifier for size_t arguments, in contrast with the
version I'm running on Ubuntu 18.04 (15:6.3.1+svn253039-1build1).
2019-11-17 12:45:49 +01:00
Ken Healy
26216beaab Microchip SAM D51 / E5x support
Adds a target driver for Microchip SAM D51 / E5x family.

Tested on SAMD51G19A and SAMD51J19A. According to the datasheet, the
D51 / E5x family share the same core feature set, differing only in the
addition of CAN (E51) or ethernet controllers (E53/54). All members of
the family should be equivalent from a debug and programming perspective.
2019-11-17 12:45:49 +01:00
Uwe Bonnes
5a05cedd7d pc-hosted/jtagtap.c: Handle DO as bytes (PR #552)
Fixes #540/#542
2019-11-10 17:36:58 +01:00
Kirill Zhumarin
28f0ced97e Support NXP LPC1343 2019-11-09 18:47:07 +01:00
dpslwk
67f9d26644 samd: Add support for L21 & L22 (PR #345) 2019-11-09 13:59:37 +01:00
Uwe Bonnes
04d9749f25 Makefile: Publish DFU binaries with the daily build. (#549)
Fixes #548.
2019-10-28 16:37:41 +01:00
Uwe Bonnes
76f9a6ad42 stm32: Portability changes. 2019-10-20 22:20:06 +02:00
Uwe Bonnes
b9249fe104 adiv5: Activate DP reset sequence, guarded with timeouts.
While not working on most STM32, it succeeds on STM32G474.
Thanks to Dave Marples <dave@marples.net>
2019-10-20 22:15:28 +02:00
Uwe Bonnes
c6f43cf23f Stlinkv2: Always call stlink_leave_state() first.
V2 devices after power on are in DFU mode. It is needed to leave DFU before
doing anything else.
2019-10-19 20:57:26 +02:00
Roland Ruckerbauer
58febdff79 Fixed tokenization of gdb monitor commands. 2019-10-19 13:25:26 +02:00
Daniel O'Connor
2eef202ee1 Use pkg-config to get CFLAGS & LDFLAGS for libftdi1
Pull request #535
2019-10-14 19:22:53 +02:00
Daniel O'Connor
0aedff6623 Set the accepted to socket to be blocking as that is what the code expects.
This is necessary on OSX (and probably BSDs) where they default to non blocking which causes recv() to return -1 with errno set to EAGAIN.
2019-10-14 12:45:10 +02:00
Thomas Bénéteau
4a8cba0e9c Add support for LPC1114/333 (LPC1100XL series)
This is not given in the user manual but the register immediately
following DEVICE_ID does apparently contain the correct part ID.
2019-10-13 13:01:19 +02:00
Ken Healy
5c805c7d35 Fix buffer overflow in adiv5_component_probe() 2019-10-12 11:44:08 +02:00
Dave Marples
90df8172ca Addition of pc-hosted variant and extensions to other targets to support it. 2019-10-08 19:16:12 +02:00
Uwe Bonnes
8a1d8bfba3 Stlink: Variant for Stlink V2 that works with the original ST bootloader.
Use https://github.com/jeanthom/stlink-tool.git for encrypted upload and
switch to BMP.
2019-10-08 18:18:19 +02:00
Uwe Bonnes
0ae7cea1ae Add LPC84 from UM11029, Rev. 1.4, tested on LPC845 Breakout board. 2019-10-08 18:17:43 +02:00
UweBonnes
286b987822
Merge pull request #527 from UweBonnes/fixes
Fixes
2019-09-29 16:59:54 +02:00
Uwe Bonnes
12a2659671 pc-stlinkv2: StlinkV3 seems only to work with STM devices, 2019-09-29 16:48:42 +02:00
Uwe Bonnes
0599d2161c pc-stlinkv2: Recognize another error and try to handle failing memread. 2019-09-29 16:48:31 +02:00
Uwe Bonnes
1cf0b8ac13 Make all arguments for all commands (struct *t, int argc, const char **argv).
-Wall on gcc8 otherwise warns without -Wno-cast-function-type but older
GCCs/CLang choke on that argument:
error: unknown warning option '-Wno-cast-function-type'; did you mean
 '-Wno-bad-function-cast'? [-Werror,-Wunknown-warning-option]

This adds 24 byte to the binary, as some functions are now called with
additional dummy arguments:
"Pushing and popping garbage to keep the system happy"
2019-09-29 12:44:55 +02:00
Uwe Bonnes
f010a567bd adiv5: Reject APs duplicating last AP.
Seen with TM4C129 on black MSP432R401 Launchpad. Scanning of APs is aborted,
so valid APs after duplicated APs are ignored.
2019-09-29 12:44:37 +02:00
Uwe Bonnes
fc3abf26ef stm32_mem: Fix native crashing in dfu-detach when repeatedly flashed. 2019-09-28 21:28:35 +02:00
Uwe Bonnes
afbde05cd3 Linker: Recent libopencm3 linker already sets the stack.
Thanks to Sid Price for noticing #520.
2019-09-23 22:48:21 +02:00
Uwe Bonnes
fae2966b72 Target: Default to nop-function() for all exported target functions.
Fixes #522.
2019-09-23 17:42:29 +02:00
UweBonnes
3a6947a68f
stlink: Check for baite variant. (#519)
If PC13/14 float and PB11 is pulled high, recognize as baite.
Handle as rev.1 board. Deciphered from:
http://www.avrki.ru/picture/articles/samodelniy_st_link_v2/shemf_st_link_v2.jpg
2019-09-05 20:37:16 +02:00
UweBonnes
609e6b135d
nrf51: Add nop_function as halt_poll. (#517)
Otherwise "tar  ext ...; mon s; att 2; quit", start new gdb "tar ext ..."
crashes, at least on pc-hosted platforms.
2019-09-04 13:50:13 +02:00
UweBonnes
6663da7ff5
cortexm.c: Fix DWT Mask (#516)
See #513
2019-09-04 13:28:55 +02:00
UweBonnes
00937348b3
Fixes to compile "make ENABLE_DEBUG=1 all_platforms" (#515) 2019-09-04 13:09:43 +02:00
UweBonnes
7dcb3295c6
Native: Link against nanolib. (#514)
This frees about 13 kB or 30 kB with ENABLE_DEBUG=1
2019-09-04 12:51:30 +02:00
Gareth McMullin
e6504e149b cortexm: Implement single register read/write 2019-09-01 20:38:38 +02:00
Gareth McMullin
7bcf7f4924 cortexa: Implement single register read/write 2019-09-01 20:38:38 +02:00
Gareth McMullin
20cad17ce3 target: Implement generic multi-register read/write 2019-09-01 20:38:38 +02:00
Gareth McMullin
19a8078f99 gdb: Implement 'p' and 'P' register access 2019-09-01 20:38:38 +02:00
Gareth McMullin
9f4cf4124e target: Add new methods for read/write individual regs. 2019-09-01 20:38:38 +02:00
UweBonnes
71b8a4e081
Merge pull request #511 from UweBonnes/pc-stlinkv2
Pc stlinkv2
2019-09-01 13:07:35 +02:00
Uwe Bonnes
1d868bfffb pc-stlinkv2: Detect stlink detach.
As libusb has no real async callback, we need to call libusb_handle_events()
in different places. While waiting for the gdb connection, we set the
socket to non-blocking and check additional for usb events in that loop. That
way, detach is also detected while waiting for connection. With debugger
attached, SET_IDLE_STATE ist missused for checking for usb events.
2019-09-01 12:19:14 +02:00
Uwe Bonnes
6f1cae9203 pc-stlinkv2: Wait for device attach. 2019-09-01 12:19:07 +02:00
Uwe Bonnes
86d0be9708 pc-hosted: Display morse message on controlling terminal. 2019-09-01 12:11:51 +02:00
Uwe Bonnes
80a9fd51ca Clarify STM32F103x8 Flashsize handling.
Should finally fix #471.
2019-09-01 12:11:51 +02:00
Uwe Bonnes
d39dc34382 pc-stlinkv2: Fix reg_read|write
- Fix wrong placed brace in cortexm_regs_write()
- Start writing with r0
- With register read, save only registers listed
2019-09-01 12:11:37 +02:00
Uwe Bonnes
d1ee827b4d pc-stlinkv2: STLINK_SWD_DP_ERROR seem unrecoverable. Throw exception. 2019-08-31 11:20:17 +02:00
Uwe Bonnes
0d61106f90 pc-stlinkv2: Remove redundant read of CoreID. 2019-08-31 11:20:17 +02:00
Uwe Bonnes
aef055bb6f adiv5: If setup AP0 fails, fail immediate. 2019-08-31 11:20:17 +02:00
Uwe Bonnes
a01109543e pc-stlinkv2: Return failure if STLINK_DEBUG_APIV2_INIT_AP fails. 2019-08-31 11:20:17 +02:00
Uwe Bonnes
d994565f2e pc-stlinkv2: Fix crash with serial given not matching connected devices. 2019-08-31 11:19:13 +02:00
Theodor M
052b5f830a Made script executable with python3.
Added braces for compatibility with python3, should still be valid python2 which interpretes these braces as a tuple with a single element and simplifies it to that element.
Replaced whitespaces with tabs as required by python3, since indentation must be uniform (either whitespaces or tabs).
Removed trailing whitespaces.

Tested by flashing various STM32 boards with blackmagic firmware using python3.7.
2019-08-30 15:09:35 +02:00
UweBonnes
5704c2fb5a
Merge pull request #508 from UweBonnes/swlink
swlink: Remove redundant conditional usbart_init().
2019-08-28 12:37:12 +02:00
Uwe Bonnes
2b7d4c5ade swlink: Remove redundant conditional usbart_init().
Noticed in #506.
2019-08-28 11:39:03 +02:00
Sid Price
35cb4e51e4 Windows Build Fixes GNU make 4.2.1 (#502)
After update of GNU make the tests for Windows OS are no longer needed. Note that GNU make 4.2.1 is used to build BMP under Windows OS.
Make native working

Again, the newer version of GCC make does not need the OS tests.
2019-08-28 10:45:41 +02:00
UweBonnes
e8bd066fe9
Merge pull request #505 from UweBonnes/pc-stlinkv2
Pc stlinkv2
2019-08-27 15:23:18 +02:00
Uwe Bonnes
82be49f052 Stlink: Add a README.md, mostly deprecating reflashing Stlinkv2/1. 2019-08-27 15:13:26 +02:00
Uwe Bonnes
5d59338de5 pc-stlinkv2: Try first to reset device if we read a strange version number. 2019-08-27 15:13:26 +02:00
Uwe Bonnes
5fbb3a44fd PC-STLINKV2/Libftdi: Better version string. 2019-08-27 15:13:26 +02:00
Uwe Bonnes
44f471db53 pc-stlinkv2: READMEM_8BIT needs to read 2 bytes for 1 byte requested.
Fix as seen in openocd.
SYSROM_PIDR2 has only 3 bits for the JEP106 identity code field, bits [6:4].
2019-08-27 15:13:26 +02:00
Uwe Bonnes
fa27649f87 Remove debug_bmp command on PC hosted platforms. 2019-08-27 15:13:26 +02:00
Uwe Bonnes
6bf4fd3598 pc-stlinkv2: CPU register read and write must be done with the AP set.
FIXME: Writing CPU registers on M4 of STM32H745 seems not to work.
2019-08-27 15:13:15 +02:00
Piotr Esden-Tempski
ebf3e9da04
Changed the Gitter chat link to Discord. 2019-08-26 17:22:02 -07:00
UweBonnes
e52e2f56c5
Merge pull request #500 from btashton/update_libopencm3
Target latest libopencm3 version
2019-08-15 10:16:13 +02:00
Brennan Ashton
443ced62d4 Target latest libopencm3
Required fixes:
 * use usbd_request_return_codes -- commit 54b117c5a5767df8dc114612dfd8e8cb88b72c6b
 * drop deprecated timer_reset() -- commit 034dbf20ff8c54dcbee5238390b37a0d35180f44
 * drop 48 & 120 MHz configs -- commit a9dde2832eb8039b9e0d21a50b9b991ddbfc4e2d
 * ld scripts: drop duplication of standard sections -- commit 9a05dcb6c0aef712052d337457838f6041ffd57a
2019-08-14 00:57:15 -07:00
UweBonnes
c9c8b089f7
Merge pull request #499 from smunaut/minor_enhancements
Minor enhancements
2019-08-13 19:58:26 +02:00
Sylvain Munaut
4289788e0b src: Replace sprintf with snprintf
snprintf is needed anyway, that's one less function to have :p
And it's bad practice anyway.

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
2019-08-05 15:43:33 +02:00
Sylvain Munaut
1d4152a36f target: Make sure variant_string is consistent in size
It's a global symbol and LTO will complain if the one in this file and
the one in EFM32 target are inconsistent.

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
2019-08-05 15:42:29 +02:00
Sylvain Munaut
544bcd9845 build: Allow support for .S assembly file in SRC
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
2019-08-05 15:41:46 +02:00
Sylvain Munaut
804ec24df9 build: Apply OPT_FLAGS after platform Makefile.inc include
This allows the platform to specify another optimization level than
the default (like -Os if space is limited)

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
2019-08-05 15:29:00 +02:00
Sylvain Munaut
ef372d0161 build: Use a separate NO_LIBOPENCM3 flag to disable libopencm3
This prepares to allow other architectures than pc
that don't use libopencm3.

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
2019-08-05 15:24:16 +02:00
UweBonnes
fbf196378e
Merge pull request #496 from UweBonnes/stlinkv2
Stlinkv2
2019-07-28 16:45:20 +02:00
Uwe Bonnes
06078a8a98 stlinkv2.c: Ignore zero length memory transactions. 2019-07-28 16:28:18 +02:00
Uwe Bonnes
d92635b6a3 stlinkv2: Use stlink_usb_get_rw_status() where possible. 2019-07-28 16:27:52 +02:00
UweBonnes
5107a29699
Merge pull request #495 from UweBonnes/451
Fix upgrade compiling (by extending #451)
2019-07-20 14:32:09 +02:00
Uwe Bonnes
1b3acf3b8a pc-stlinkv2: Print serial number of V20 devices readable. 2019-07-20 13:34:21 +02:00
Uwe Bonnes
6323409fec upgrade: Honnor the PROBE_HOST make argument. 2019-07-19 18:42:06 +02:00
Uwe Bonnes
d98703e022 Do not download/build/clean libopencm3 directory when compiling for PC-hosted platforms. 2019-07-19 18:41:55 +02:00
Uwe Bonnes
8f6b266c54 Upgrade: Download needs to set the address. 2019-07-19 10:51:02 +02:00
Jeremy Elson
1c5ee1f11f Add blackmagic.bin as dependency of bindata.o so that running make
in upgrade will correctly rebuild the upgrade tool if the main binary
has changed.
2019-07-19 10:51:02 +02:00
UweBonnes
c19ca20e36
Merge pull request #493 from UweBonnes/weak
Remove weak attribute for less hassle with windows compiles
2019-07-18 23:49:24 +02:00
Uwe Bonnes
e29f2b4fb9 jtag/swd: Rename defines/make variables to allow removal of weak attribute
jtagtap.c is libopencm3 generic. Move to common.
2019-07-18 20:54:10 +02:00
Uwe Bonnes
067956266c Adiv5: Remove weak attribute to ease windows compile. 2019-07-18 18:16:19 +02:00
Uwe Bonnes
9e898cc4b8 adiv5: Add more coresight part numbers found on STM32MP157c-DK2 (#492).
Only print corename if not NULL.
2019-07-18 17:39:48 +02:00
UweBonnes
5176c38491
Merge pull request #466 from UweBonnes/stlinkv2
Add a new platform, running on the USB host and talking to an unmodified StlinkV2/3
2019-07-17 17:45:56 +02:00
Uwe Bonnes
dd3cb193f3 Indicate the Core in the Target list. 2019-07-17 17:38:21 +02:00
Uwe Bonnes
c44cb904b0 adiv5.c: Format debug output more tense. 2019-07-17 17:38:21 +02:00
Uwe Bonnes
205fce20e5 stlinkv2: mem_[read|write] needs to honor AP. 2019-07-17 17:38:21 +02:00
Uwe Bonnes
b9249ca8a6 stlinkv2: Recognize V21_MSD, e.g. on STM32MP157C-DK2. 2019-07-17 17:38:21 +02:00
Uwe Bonnes
634c07c432 adiv5: Add TSGEN. 2019-07-17 17:38:21 +02:00
Uwe Bonnes
82424b100b stlinkv2: Require STLINK V3 Rev > 2 as revision 1 can not read TARGETID. 2019-07-17 17:38:21 +02:00
Uwe Bonnes
9b764534e6 stlinkv2: Recognize Stlink V3E 2019-07-17 17:38:21 +02:00
Uwe Bonnes
3388e48d92 stlinkv2: Do not loop endless when Read DP fails. 2019-07-17 17:38:21 +02:00
Uwe Bonnes
9ed26645d3 Add pc_stlinkv2 platform, running on host, talking to original StlinkV2/3.
Stlink firmware needs to be recent.
2019-07-17 17:38:01 +02:00
Uwe Bonnes
fd3af639b0 Clean up some includes.
Includes #465, noticed by Sid Price.
2019-07-17 17:26:00 +02:00
Uwe Bonnes
bd530c8951 adiv5.c: Make functions weak where high level platforms may implement different. 2019-07-17 17:26:00 +02:00
Uwe Bonnes
5aebef4f64 Makefile: Indicate high level SWD/JTAG implemenatation. 2019-07-17 17:26:00 +02:00
Uwe Bonnes
df7458e35a Build-Infrastructure: Allow a different target name. 2019-07-17 17:26:00 +02:00
Uwe Bonnes
32d2b2c4bf jtag: Move device list to it's own file to allow reuse. 2019-07-17 17:26:00 +02:00
Uwe Bonnes
3b75cb9a5a gdb-server: Allow multiple instance. 2019-07-17 17:26:00 +02:00
Uwe Bonnes
9075411c93 Move gdb_if.c for stand-alone servers to common. 2019-07-17 17:26:00 +02:00
Stephen Roe
b4c680bb15 Add STM32G4
Based on #488 Stephen Roe, done as #491.
Fixes ID of STM32G03.
2019-07-17 17:24:23 +02:00
Simon Rasmussen
5a7ffe7a40 Fixed SAM3X8C large file flashing.
The datasheet specifies the EEFC_BASE(0) is at `0x400E0A00` and EEFC_BASE(1) is at `0x400E0C00` which means they're spaced 0x200 bytes apart rather than 0x400.
2019-07-17 14:37:07 +02:00
David R. Piegdon
02b2fdb2ae fix overwriting of still-needed value (refs #487)
this fixes a bug that was introduced in blackmagic PR #475 which lead to
firmware crashes when connecting to a BMP more than once without a
power-cycle.
2019-06-24 16:45:18 +02:00
Uwe Bonnes
589d297d20 stm32l0: Fix crash when only "monitor option" was requested.
PR #485
2019-06-12 12:54:29 +02:00
Jason Kotzin
a01642e480 samd: create a copy that’s named with the version 2019-05-31 00:33:57 -07:00
Jason Kotzin
6b9b502354 tag correctly if we are on a branch 2019-05-31 00:07:20 -07:00
Alexander Zhang
880613d641 lpc_common: restore RAM and registers after IAP call
Restore the RAM and registers which are clobbered by an LPC IAP call.
This does not restore any additional RAM which might be clobbered
by a *particular* IAP call. (For example, flash programming always
clobbers the last page of RAM.)
2019-05-30 14:01:27 -04:00
David Lawrence
d3979a57b6 Add LPC command to read out unique ID from target.
This commit modifies lpc_iap_call() to work with IAP commands that
return additional data. If the "result" argument is non-null, 16
bytes of data (the maximum returned by any IAP command) are copied
to the specified address.
2019-05-30 14:01:12 -04:00
Sid Price
21434d6fbb Remove redundant include file 2019-05-26 23:27:32 +02:00
Richard Meadows
600bc9f029 Generate DEBUG warnings and return if malloc/calloc fail.
This is will make debugging earier if this does happen, rather than
dereferencing the null pointer (or passing it to memcpy, or worse).

blackmagic PR #475
2019-05-26 18:56:12 +02:00
Richard Meadows
61e9607594 [adiv5] Improvements in ADIv5
* Reference latest version of the ARM specification
* ROM tables - more debug information, including printing SYSMEM bit
* MEM-AP - reject when Debug Base Address entry is not
  present/invalid. These would only have errored in
  adiv5_component_probe.
* Fix maximum number of entries in Class 0x1 ROM Table to 960. See ARM
  IHI 0031E Table D3-1 ROM Table register summary.
* Resolve note in STM32H7 driver with explaination

blackmagic PR #474
2019-05-24 22:00:44 +02:00
Uwe Bonnes
703f88a969 gdb_main: Always release CPU when detaching.
Fixes Issue #413 and released as PR #477.
2019-05-23 13:17:54 +02:00
Richard Meadows
24a7b8b2bf [stm32h7] add revision command which reads the DBGMCU_IDC register
blackmagic PR #476
2019-05-21 23:20:13 +02:00
Richard Meadows
c336c300a3 [stm32h7,bugfix] Fix bug: target_add_flash called in attach
When `target_add_flash` or `target_add_ram` are called in an attach
function they may be added multiple times. This very much confuses
GDB. This issue has already been reported and fixed for `stm32l4` (See
Issue #455 ).

`stm32f4` and `stm32l4` are the only other cortexm drivers that
implement this pattern. These are both fine.
2019-05-21 22:38:16 +02:00
Jason Kotzin
8606b78b9e updating gitignore file 2019-05-18 14:55:31 -07:00
Ryan
cd325dfe52 samd: convert_tdio requires enable/disable 2019-05-16 13:18:05 -07:00
UweBonnes
2e1503f988
Merge pull request #467 from UweBonnes/stm32g03
Add Stm32G03 from reference manual Rev.2
2019-05-12 20:21:44 +02:00
Uwe Bonnes
984813a29d Add Stm32G03 from reference manual Rev.2
Not yet tested on a real part.
2019-04-24 12:29:58 +02:00
Ryan
c1b3d0c629 samd: bug fix on uart newlines 2019-04-10 17:38:16 -07:00
UweBonnes
7cb1858aca
Merge pull request #463 from sidprice/bmp_windows_build
Native Windows builds
2019-04-07 18:44:20 +02:00
Sid Price
2108bb7137 Native Windows builds
All except hydrabus and launchpad-icdi building in PowerShell.
2019-04-07 10:26:45 -06:00
Jason Kotzin
94238fd95b samd: ability to printout entire serial number 2019-03-29 16:34:12 -07:00
UweBonnes
302ff20a6d
Merge pull request #434 from UweBonnes/nrf5
Nrf5
2019-03-21 19:43:29 +01:00
UweBonnes
88ec557683
Merge pull request #450 from jelson/prefix-fix-2
Improve parsing of commands that require enable or disable arguments
2019-03-20 11:23:11 +01:00
Jeremy Elson
3235fa2005 Improve parsing of commands that require enable or disable arguments:
* Accept prefixes of the words 'enable' and 'disable'
* Prevent silent failures on parse errors
* Print status after flag changes
* Fix missing includes
2019-03-19 12:56:44 -07:00
Boris Sorochkin
691ada17e9 Implement read device info for NRF5x 2019-03-10 21:45:47 +01:00
Uwe Bonnes
3f89fed32e nrf51: Use buffered direct write to flash. 2019-03-10 21:45:47 +01:00
Uwe Bonnes
4ecd13a9a3 nrf51: Fix crash with not argument given to "mon read". 2019-03-10 21:45:47 +01:00
Uwe Bonnes
db2f403417 sam4l: Remove noisy debug message. 2019-03-10 21:45:47 +01:00
Uwe Bonnes
a336ac2084 NRF5: New detection scheme. 2019-03-10 21:45:47 +01:00
UweBonnes
2b4000b2b4
Merge pull request #456 from newbrain/STM32L4memmap
Correction of #445 attach-detach problem
2019-03-03 17:06:25 +01:00
newbrain
6887628eaa Correction of #445 attach-detach problem
Memory map is now completely freed and rebuilt in the separate attach
function.
It was previoulsy split beween probe and attach and never released,
causing problems when reattaching to the same target.
2019-03-03 15:55:40 +01:00
UweBonnes
da62cbaa3d
Merge pull request #449 from jelson/width-fix
Use 32-bit variable for 32-bit read
2019-02-25 13:21:55 +01:00
Jeremy Elson
86ed86c2a2 Use 32-bit variable for 32-bit read. (Also fixes DEBUG compile
error due to mismatch of format and argument.)
2019-02-24 17:49:30 -08:00
Ryan
5c835bc0f6 samd: srst_get_val now actually works 2019-02-22 18:21:13 -08:00
UweBonnes
dcd20ef08c
Merge pull request #446 from UweBonnes/stm32f730_h750
Handle STM32F730 and STM32H750.
2019-02-21 20:18:19 +01:00
Uwe Bonnes
56fb0f7766 Handle STM32F730 and STM32H750.
Flash sector calculation was wrong with small flash sizes.
2019-02-21 19:19:10 +01:00
UweBonnes
a3bbdc26c0
Merge pull request #445 from UweBonnes/#432
Fixing stm32l4 target to allow probing w/o halting. Cleaned up from #432 from anyn99.
2019-02-21 19:17:00 +01:00
anyn99
3f8c40d3f5 Fixing stm32l4 target to allow probing w/o halting 2019-02-21 18:06:38 +01:00
UweBonnes
22265243ab
Merge pull request #360 from newbrain/ke04support
Kinetis KE04: Flash and debug support
2019-02-18 13:07:32 +01:00
newbrain
8de1b45c85 Kinetis KE04: Flash and debug support
Support for Kinetis KE04 8KiB, 64KiB and 128KiB variants in nxpke04.c
Target monitor commands for sector and mass erase.
Changes to kinetis.c MDM-AP target to support KE04.
Only KE04Z8 tested in HW.
2019-02-17 22:48:23 +01:00
UweBonnes
cdb04a4214
Merge pull request #442 from r0ck3tAKATrashPanda/master
Added ability to lock and unlock boot rom for samd controllers
2019-02-14 16:15:09 +01:00
Carl
02c1934c03 Added ability to lock and unlock boot rom for samd controllers 2019-02-13 16:33:07 -08:00
Ryan
100fc2e7d4 samd: added command to toggle srst pin when not used 2019-02-11 16:15:03 -08:00
Jason Kotzin
880e977fb6 samd: custom serial string for easy opening on mac 2019-02-09 13:48:04 -08:00
Ryan
3a9b0eee7a samd: added tpwr support 2019-02-04 18:19:28 -08:00
UweBonnes
7032abd2b0
Merge pull request #433 from UweBonnes/gcc8
Makefile: Add -Wnocast-function-type for compilation on gcc8.
2019-01-28 21:25:33 +01:00
Uwe Bonnes
a6b75bb4ef Makefile: Add -Wnocast-function-type for compilation on gcc8.
Older GCC versions do not warn for disabled warnings they do not know yet.
This is needed to compile with gcc8.
2019-01-16 23:17:17 +01:00
Richard Meadows
0b28232f72 [efm32] Assume Device Identification (DI) version 1 if we don't know the OUI (#402)
* [efm32] Assume Device Identification (DI) version 1 if we don't know the OUI

Silabs are using some additional OUIs we don't know about. Reported in issue #389
These should use a DI version 1 layout, so assume version 1 layout for OUIs we don't
know. However do print a notice about this on DEBUG() as suggested by @UweBonnes

The IDCODE value is sufficient to make a positive identification of an EFM32 device.
See AN0062 Section 2.2. Therefore accepting any OUI is reasonable behaviour.
Additionally the part familiy is checked, and the target rejected if not in the
`efm32_devices` table. This commit makes that rejection explicit, although it does
not change the logical behaviour here.

Note that the important registers (part number, part family, flash size) are at the
same addresses in both layouts anyhow. Currently only `efm32_cmd_serial` and
`efm32_cmd_efm_info` functions use registers that differ between DI versions.

* [efm32] tidy format warning about portability UB

* [efm32] Simplify OUI checking

* Only read the OUI once
* Accept the device even if the OU is unknown, as silabs have been using
  a variety of OUIs
* Perform fewer register reads before checking the device family is valid
2019-01-16 09:58:59 +13:00
UweBonnes
488436c46a
Merge pull request #428 from UweBonnes/stm32g0
Stm32 functional additions and fix
2019-01-09 17:17:56 +01:00
Uwe Bonnes
7cc02867ae stm32f4: Fix problems with small flash sizes creating overflow or empty regions.
Thanks to "DerMeisteRR" for pointing out.
2019-01-09 12:23:49 +01:00
Uwe Bonnes
47fad2bf7f Add Stm32L41x. 2019-01-09 12:23:49 +01:00
Uwe Bonnes
f0c6e2bbd2 Add STM32G07x. 2019-01-09 12:23:49 +01:00
UweBonnes
a65ce77466
Merge pull request #427 from UweBonnes/mingw_ftdi
libftdi: Allow to compile with mingw and cygwin and use recent libftdi1.
2019-01-08 22:29:36 +01:00
Uwe Bonnes
0793dac2cf libftdi: Allow to compile with mingw and cygwin and use recent libftdi1.
Tested with x86_64-w64-mingw32-gcc-8.2.0 and cygwin gcc (GCC) 7.3.0.
Use libftdi1 unconditionally.
Try to convice github travis to use libftdi1.
Remove unportable "uint ". Thanks to jacereda for pointing out in #400.
2019-01-07 15:31:57 +01:00
Ingmar Jager
3f0c9ccee1 Fix support for LPC1115 and LPC1115XL devices (#415)
* Add support for LPC11U3X devices.

The DeviceID register has a different address from the LPC11XX devices.
But it is shared with the LPC8XX family.

* Fix support for LPC1115 and LPC1115XL devices

* Fix whitespace
2019-01-07 13:34:00 +13:00
Manoel Brunnen
7cfeb61399 Add udev rules 2019-01-07 13:32:58 +13:00
Josh Robson Chase
02b9d5f1ac Add delay to cortexm_reset 2019-01-07 13:32:17 +13:00
Josh Robson Chase
d7e2923990 Debug on stm32f1_flash_erase errors 2019-01-07 13:32:17 +13:00
Uwe Bonnes
525b90d4e5 cortexm: Only force halt before probe() if probe was forced. 2019-01-07 13:22:01 +13:00
Uwe Bonnes
6df793dbf0 Revert "Allow to specificy if SRST is asserted and when it is released."
This reverts commit 44fc24e0e747293fa05b62ed7439501553829b0b.
2019-01-07 13:22:01 +13:00
Uwe Bonnes
da75acf015 adiv5: Only force cortexm_probe() once. 2019-01-07 13:22:01 +13:00
Uwe Bonnes
9ce05ae67b stm32h7/f7: Store DBGMCU_CR on attach() and restore on detach().
On STM32[FH]7, DBG_SLEEP must be set for debugging.
2019-01-07 13:22:01 +13:00
Uwe Bonnes
489f24584b adiv5: Read TARGETID on DPv2 devices. 2019-01-07 13:22:01 +13:00
Uwe Bonnes
8d6092b73f cortexm_forced_halt: Only release SRST after "Halt on reset" command.
This should make life easier if program remaps JTAG/SWD pins so that
with program running, JTAG/SWD access is impossible.
2019-01-07 13:22:01 +13:00
Uwe Bonnes
cde7726b87 cortexm: detach still needs extra cycles. 2019-01-07 13:22:01 +13:00
Uwe Bonnes
3ebf049424 cortexm: Only force halt before probe if idcode is unknown and ROM TABLE unreadable. 2019-01-07 13:22:01 +13:00
Uwe Bonnes
6633f74d95 stm32h7/f7: Write DBGMCU_CR only on attach.
Split probe/attach for STM32H7.
2019-01-07 13:22:01 +13:00
Uwe Bonnes
8575d3e7a6 stm32f7/h7: Use the DPv2 provided idcode for MCU identification. 2019-01-07 13:22:01 +13:00
Jason Kotzin
6baf90ac4c samd: adding dfu bootloader, compile support, and combined image 2018-12-20 13:35:45 -08:00
Ryan
77064754ad samd: fixed first-scan failure 2018-10-17 15:08:08 -07:00
Ryan
92ed79e68e samd: button code updated for libopencm3 2018-10-04 14:24:18 -07:00
Ingmar Jager
14bedcc441 Add support for LPC11U3X devices.
The DeviceID register has a different address from the LPC11XX devices.
But it is shared with the LPC8XX family.
2018-10-04 08:53:05 -07:00
Ryan
b91a975d56 samd: button must hold for 5 seconds now 2018-10-03 16:04:32 -07:00
Benjamin Vernoux
771d81a5f0 Fix link for windows_dfu_util 2018-10-03 15:20:09 -07:00
Uwe Bonnes
d8b01ff61f swlink: Enable UART2 for SWO.
Stlink on STM8S-Disco needs additional wiring for SWO.
2018-10-03 15:19:33 -07:00
Uwe Bonnes
7cafc44bd9 swlink: Allow to enable debug on second VCOM. 2018-10-03 15:19:33 -07:00
Uwe Bonnes
0d246fb31a swlink: Measure voltage on VDD pin of Stlink/Stm8s. 2018-10-03 15:19:33 -07:00
Uwe Bonnes
184ef991bf swlink: Handle LED. 2018-10-03 15:19:33 -07:00
Uwe Bonnes
06272e0a59 swlink: Implement dfu_upgrade. 2018-10-03 15:19:33 -07:00
Uwe Bonnes
530d1e5c28 swlink: Handle force boot on bluepill. 2018-10-03 15:19:33 -07:00
Uwe Bonnes
b744d8b0c9 swlink: Implement NRST. 2018-10-03 15:19:33 -07:00
Uwe Bonnes
1263d185a6 swlink: Distinguish between Stlink on STM8-Disco and "blue pill". 2018-10-03 15:19:33 -07:00
Ryan
84b6818982 samd: convert_tdio command cleaned up 2018-09-28 14:54:31 -07:00
Ryan
4aee9fe2a3 samd: enter_bootldr command, bootldr button 2018-09-28 14:37:33 -07:00
Nikolay Dimitrov
29386aee14 scripts/stm32_mem: Fix issue with scanning USB DFU devices
While scanning the USB bus for devices, stm32_scan() can find a device that it
doesn't have permissions to access it, dfu/usb class raises an exception and
stm32_scan() stops the scan completely.

This fix resolves the scan issue, by allowing the scan loop to continue.
While at it, there are cosmetic fixes related with tabs/spaces and readability.

Signed-off-by: Nikolay Dimitrov <nikolay.dimitrov@retrohub.org>
2018-09-17 14:36:28 +12:00
Gareth McMullin
7f947d724c
Merge pull request #393 from markrages/add_id_2
Another nRF52 ID.
2018-09-14 11:21:04 +12:00
Mark Rages
91dd879dac Another nRF52 ID. 2018-09-13 16:18:29 -06:00
Gareth McMullin
3a598a0cf3
Merge pull request #384 from rikvdh/feature/readable-reset-stlink
Change the ST-Link SRST reset function
2018-09-07 08:13:48 +12:00
Gareth McMullin
f328ca5181
Merge pull request #391 from UweBonnes/swd_cycles
adiv5_swdp: Add extra idle cycles with write transactions.
2018-09-07 07:58:41 +12:00
Uwe Bonnes
f5cf6d4497 adiv5_swdp: Add extra idle cycles with write transactions.
These extra cycles are needed by some CPU, e.g. STM32L0x1 to cross the SWCLK
/HCLK domains. Revert insufficient #373 also tackling that problem.

Thanks to Thorsten von Eicken for pointing out.
2018-09-06 17:29:20 +02:00
Ryan
4847e0d1e6 samd: uart ports updated for bm-sam hw 2018-09-05 15:52:04 -07:00
Gareth McMullin
db544e9b67
Merge pull request #390 from rikvdh/feature/lpc_with_iap_down
Move the LPC17xx probe function down
2018-09-06 08:15:54 +12:00
Ryan
a599b989cf samd: TDI/O conversion, usart line coding 2018-09-05 12:10:43 -07:00
Rik van der Heijden
95053b3b4e Change the ST-Link SRST function to use libopencm3 helper functions and fix waiting for the pin-state, change init to use the SRST function for reset de-assertion 2018-09-05 20:28:02 +02:00
Rik van der Heijden
f39701c4c8 Move the LPC17xx probe function down since it performs an IAP call which can hang when performed on other devices than a LPC17xx 2018-09-05 17:40:02 +02:00
Ryan
50658a5c0a samd: small fixes to uart 2018-08-27 16:22:48 -07:00
Ryan
f828fc1ac1 samd voltage detection and line coding 2018-08-07 14:32:00 -07:00
Jason Kotzin
bd71ca2a3c Minor updates to help with speed, temporarily disabling uart 2018-08-01 19:10:01 -07:00
Ryan
2d38c9614e fixed typo in jeff/platform.h 2018-08-01 16:22:03 -07:00
Jason Kotzin
7ce265f2cf Adding queue.h file and fixing some compile errors 2018-08-01 14:26:31 -07:00
Gareth McMullin
c5c0783337
Merge pull request #378 from markrages/nordic_unlock
Add extra port for mass erasing / unprotecting nRF52 with APPROTECT set.
2018-07-28 14:56:03 +12:00
Mark Rages
d0a8ce0819 Add extra port for mass erasing / unprotecting nRF52 with APPROTECT set.
Mostly copied from the equivalent in kinetis.c and
https://devzone.nordicsemi.com/f/nordic-q-a/12484/approtect-and-dap/47301
2018-07-27 16:07:19 -06:00
Gareth McMullin
6fd3ede5c7
Merge pull request #377 from markrages/add_id_2
Another chip ID for Nordic nRF52832.
2018-07-28 09:53:00 +12:00
Gareth McMullin
8f9a9c4d71
Merge pull request #286 from UweBonnes/h7
stm32h7: Start of support.
2018-07-28 09:51:47 +12:00
Mark Rages
cb8596b0b2 Another chip ID for Nordic nRF52832. 2018-07-27 15:09:14 -06:00
Uwe Bonnes
5918608156 STM32F7: Debug does not work with WFI without DBG_SLEEP 2018-07-27 10:59:54 +02:00
Uwe Bonnes
2c1c913213 adiv5.c: Add units found on M7. 2018-07-27 10:59:54 +02:00
Uwe Bonnes
f234074099 stm32h7: Start of support.
Implement probe, memory map, erase, write, uid, crc, parallelism.
2018-07-27 10:59:54 +02:00
Gareth McMullin
a988bba035
Merge pull request #372 from richardeoin/efm32-1
[efm32] Add support for EFM32 devices with different DI and MSC layouts
2018-07-27 11:41:58 +12:00
Gareth McMullin
d7b173ab39
Merge pull request #310 from UweBonnes/stm32l4r
arget/stm32l4.c: Add stm32l4r series and clean up.
2018-07-27 10:32:00 +12:00
Gareth McMullin
833407d299
Merge pull request #376 from miek/nrf52840-qiaa-c0
Add nRF52 QIAA C0
2018-07-27 10:25:45 +12:00
Mike Walters
b4dc666aca Add nRF52 QIAA C0 2018-07-26 23:13:38 +01:00
Uwe Bonnes
4a312c7697 target/stm32l4.c: Add stm32l4r series and clean up. 2018-07-22 15:44:00 +02:00
Uwe Bonnes
7034d0bb94 stm32l4: Option byte loader must be started with flash unlocked!
Warn user that device will loose connection.
2018-07-22 15:44:00 +02:00
Uwe Bonnes
83f9655f6e stm32l4: Fix wrong default for WRP2A option halfword. 2018-07-22 15:44:00 +02:00
Gareth McMullin
0551809475
Merge pull request #373 from UweBonnes/fixes
Fixes for detach and stm32mem
2018-07-20 08:36:12 +12:00
Uwe Bonnes
139707c5c0 cortexm/detach: Add a dummy transaction after cleaning DHCSR.
This replaces the seemingly superflous swdptap_seq_out() at
the end of adiv5_swdp_low_access() needed to continue after detach.
2018-07-19 10:57:41 +02:00
Uwe Bonnes
7908ba526b stm32_mem: Guard dfu.dfu_device with try/except. 2018-07-18 23:31:55 +02:00
Richard Meadows
a7106bd346 [efm32] Add support for flashing User Data (UD) and Bootloader (BL) regions
* UD region on all devices, some devices also have BL region
* Fix page size for EZR32HG
2018-07-18 08:57:01 +00:00
Richard Meadows
55bb96cfdb [efm32] tidy compiler warning 2018-07-16 20:47:24 +00:00
Richard Meadows
98faaceb70 [efm32] Add support for EFM32 devices with different DI and MSC layouts
* DI layout is identified by attempting to read OUI from both layouts
* MSC address is passed to flashstub in r3

Retested EZR32LG230 (EZR Leopard Gecko M3)
Tested EFR32BG13P532F512GM32 (EFR Blue Gecko)

Achieves aims of PR #264 (I think) Thanks to @dholth and @ryankurte for inspiration
Fixes Issue #226
2018-07-16 20:18:36 +00:00
Jason Kotzin
638299534b samd: updates for jeff probe pcb 2018-07-13 23:48:52 -07:00
Jason Kotzin
919a005b65 debug flags only if we are debugging, speeds up firmware slightly 2018-07-12 19:19:39 -07:00
Jason Kotzin
58865ca5ec samd: uart support 2018-07-12 18:54:13 -07:00
Gareth McMullin
667cce7d17
Merge pull request #370 from sinihappo/alo-stm32f0x-option-erase-fix
Fixes option erase for STM32F070x6 STM32F070xB STM32F030xC
2018-07-11 11:51:14 +12:00
Jason Kotzin
d62d82bb2f M0 SWDIO 2x performance improvements 2018-07-10 16:18:05 -07:00
Jason Kotzin
f1ecd66283 Initial support for samd hardware and jeff ‘probe’ 2018-07-10 15:42:44 -07:00
Jason Kotzin
fd2cb4b8d2 Updating submodule to use flirc samd branch 2018-07-10 14:01:03 -07:00
Jason Kotzin
1cc3e05c11 Force USB connect 2018-07-10 13:36:00 -07:00
Jason Kotzin
d5b6d4ab12 Allow support for older chip architectures 2018-07-10 13:35:45 -07:00
Antti Louko
59d6eca8f0 Fixes option erase for STM32F070x6 STM32F070xB STM32F030xC 2018-07-10 18:44:05 +03:00
Gareth McMullin
c5713ea8d3
Merge pull request #366 from UweBonnes/f7_fix
stm32f4.c: F76x also has large sector by default.
2018-07-07 13:03:14 +12:00
Gareth McMullin
1b51c4961e
Merge pull request #363 from korken89/master
Removed debug bits for F4/F7 target, same as all other MCUs now
2018-07-07 13:01:05 +12:00
Gareth McMullin
46b681e050
Merge pull request #361 from UweBonnes/gpio_swd
Speed up bitbanging SWD/JTAG
2018-07-07 13:00:32 +12:00
Uwe Bonnes
50514ccc31 stm32f4.c: F76x also has large sector by default. 2018-07-05 13:29:43 +02:00
Emil Fresk
5e8c8cae10 Removed debug bits for F4/F7 target, same as all other MCUs now 2018-06-28 16:31:34 +02:00
Uwe Bonnes
7a7266a0f7 Speed up JTAG. 2018-06-26 19:50:14 +02:00
Uwe Bonnes
5548d54626 common/swdptap: some clean up.
Remove superfluous transaction.
Use native variable size.
2018-06-26 19:50:14 +02:00
Uwe Bonnes
7e3fe352ad adiv5_swdp.c: Use swdptap_seq_out for initialiation sequence. 2018-06-26 19:50:14 +02:00
Uwe Bonnes
e54a826745 common/swdptap.c: Speed up by "unrolling" swd.._seq_...() for GPIO.
Try to have sensible setup/hold times by evenntually duplicated or
logically useless port commands.
Loading code to RAM on a STM32L476 got up from 46 to 83 kB/sec.
2018-06-26 19:50:14 +02:00
Uwe Bonnes
59e03dea27 Keep TMS floating until scanning.
NRF5x shares nRST with SWDIO and otherwise does not run until scan is done.
2018-06-26 19:50:14 +02:00
Uwe Bonnes
97561fc5cc stlink: Decrease delay with SWD turn around for native,stlink and swlink. 2018-06-26 19:50:14 +02:00
Gareth McMullin
d4d24c256c
Merge pull request #362 from UweBonnes/fix_ftdi
libftdi/jtagtap.c: Fix error introduced with commit de33473
2018-06-26 10:36:06 -07:00
Uwe Bonnes
633af5bb85 libftdi/jtagtap.c: Fix error introduced with commit de33473
Seen when scanning e.g. Zync with mon jtag 6 4.
2018-06-26 17:43:06 +02:00
Gareth McMullin
b2defad844
Merge pull request #356 from UweBonnes/probe_halted
Probe halted
2018-06-21 10:06:56 -07:00
Gareth McMullin
1799ea3b71
Merge pull request #357 from UweBonnes/write_access_size1
Write access size1
2018-06-21 10:05:45 -07:00
Uwe Bonnes
b59bbac0b2 stm32l4: Use buffered direct write to flash. 2018-06-16 13:30:53 +02:00
Uwe Bonnes
891d6de8eb stm32f1.c: Use buffered direct write to flash with half word access. 2018-06-16 13:30:53 +02:00
Uwe Bonnes
f1752c7a1a stm32f4: Allow DWORD parallelism.
Needs external VPP!
2018-06-16 13:30:53 +02:00
Uwe Bonnes
15312eb86c stm32f4: Honor parallelism also for erase. 2018-06-16 13:30:53 +02:00
Uwe Bonnes
bfeb6f0db9 stm32f4: Use buffered direct flash write with choosen size. 2018-06-16 13:30:53 +02:00
Uwe Bonnes
54f73858f9 Provide a target function to write with given size. 2018-06-16 13:30:08 +02:00
Uwe Bonnes
17b817f37b cortexm: Allow to set timeout to wait for halt.
This allows to gain access to devices spending long time in WFI without
the need for a reset, at the expense of possible long waiting times.
Using Reset means loosing the device runtime context.
2018-06-13 14:03:50 +02:00
Uwe Bonnes
9e365a58f7 Cortex-M: Try harder to halt devices in WFI.
E.g. STM32F7 and L0 need multiple C_DEBUG and C_HALT commands to halt
the device.
2018-06-13 14:02:43 +02:00
Uwe Bonnes
44fc24e0e7 Allow to specificy if SRST is asserted and when it is released.
E.g. for STM32L0 and F7, IDCODE register can not be read while device is
under Reset.
2018-06-13 13:46:07 +02:00
Uwe Bonnes
66e357d517 Cortex-M: Probe Cortex-M even if ROM table read fails.
Rom table in some devices (e.g. STM32L0/F7) can not be read while
device is in WFI. The Cortex-M SWD signature is however available.
If we know by that signature, that we have a Cortex-M, force a
probe for Cortex-M devices.
2018-06-13 13:04:17 +02:00
newbrain
ae6f0eadc9 Support for MSP432 TI MCUs (#353)
Introduces flashing and debugging support for Texas Instruments MSP432
series of MCUs
2018-06-07 08:34:21 +12:00
Gareth McMullin
b7a59afc59
Merge pull request #349 from esden/stm32f247-strings
Setting the stm32f247 driver string on scan.
2018-06-05 10:37:25 +12:00
Piotr Esden-Tempski
077e455a94 Setting the driver string on scan.
This way swdp_scan and jtag_scan commands will show the chip that was
detected instead of the generic STM32F4 string. The generic name is
most confusing when attaching to an STM32F7 target.
2018-06-01 12:46:14 -07:00
Gareth McMullin
80f003ff4b
Merge pull request #347 from UweBonnes/ftdi
libftdi platform improvements
2018-05-31 10:16:34 +12:00
Uwe Bonnes
2657aa6fbb libftdi: Allow more flexible Swd Read/Write Switching. 2018-05-30 19:21:03 +02:00
Uwe Bonnes
df05d7ce7b libftdi: Allow device specific port/pin to read SWD bitbanged.
Gracefully abort swd scan if devices can not do SWD.
Best effort to indicated SWD capability on existing cables and
add descriptions for the cables.
2018-05-30 19:21:03 +02:00
Uwe Bonnes
fce25b9fd5 libftdi/swdptap.c: Substantial speed increase for bitbanging SWD.
Provide the swd sequences unrolled.
2018-05-30 19:21:03 +02:00
Uwe Bonnes
992ccf91a9 libftdi/swdptap.c: Use MPSSE Mode for bitbanging SWD. 2018-05-30 19:21:03 +02:00
Uwe Bonnes
f3cacba219 libftdi: Flush buffer with detach. 2018-05-30 19:21:03 +02:00
Uwe Bonnes
2ec078cfcf libftdi/jtagtap.c: Allow NULL as one DI/DO argument jtagtap_tdi_tdo_seq.
Implement jtagtap_tdi_seq() by calling jtagtap_tdi_tdo_seq().
2018-05-30 19:21:03 +02:00
Uwe Bonnes
de33473535 libftdi/jtagtap: Copy DI direct into the write buffer. 2018-05-30 19:21:03 +02:00
Uwe Bonnes
aa938c6dae libftdi/jtagtap: Try harder to initialize Ftdi MPSSE jtag mode.
After "mon s" at least the second "mon j" now succeeds again.
2018-05-30 19:21:03 +02:00
Uwe Bonnes
c548e307fe libftdi/jtagtap: Clean up code. 2018-05-30 19:21:03 +02:00
Uwe Bonnes
7d45bd4869 ibftdi/jtagtap: Remove magic numbers. 2018-05-30 19:21:03 +02:00
Uwe Bonnes
6f0a46d9c1 libftdi: Export active cable description. 2018-05-30 19:21:03 +02:00
Uwe Bonnes
68c7180376 libftdi: Add ftdiswd variant. 2018-05-30 19:21:03 +02:00
Uwe Bonnes
f4bc6f9ddd libftdi/platform.c: Issue SEND_IMMEDIATE before reading. 2018-05-30 19:21:03 +02:00
Uwe Bonnes
744deb678d libftdi/platform.c: Only set bit direction with MPSSE SET_BIT_XXXX. 2018-05-30 19:21:03 +02:00
Gareth McMullin
48d232807e
Merge pull request #337 from adamgreig/stm32f4-ram-size
Update maximum RAM sizes for F4 and F7 devices
2018-04-26 13:38:11 +12:00
Gareth McMullin
0f2f1d74a2
Merge pull request #334 from gsmcmullin/split_probe_attach
Split probe and attach
2018-04-26 13:28:08 +12:00
Adam Greig
e1cefb2031 Update maximum RAM sizes for F4 and F7 devices 2018-04-24 11:06:07 +01:00
Uwe Bonnes
93f3b14b68 stm32f1(f0): Do not read normal device registers during probe.
Device may not be halted and memory map setup may fail.
2018-04-23 11:06:08 +12:00
Uwe Bonnes
a0596a0dcc stm32l4: Build Memory Map during attach.
Reading target registers while target not halted may fail and result in
invalid memory map.
2018-04-23 11:06:08 +12:00
Uwe Bonnes
5f404cdbc0 Construct memory map on the stack
The memory map uses 1k of SRAM and is only needed during attach. Release
after use lowers pressure on SRAM.
2018-04-23 10:51:04 +12:00
Uwe Bonnes
6127a6431e stlink: Check nRST line level when setting SRST.
Problem: On some boards flashing hanged.
Cause: Releasing SRST caused a slow rise of nRST and flashing
started while the target still was in reset.
Attention: platform_delay(ms) only resolved 0.1 s.
Nucleo-P boards have SRST unconnected to target nRST by default.
2018-04-23 10:48:05 +12:00
Gareth McMullin
63967346cd stm32f4: Don't duplicate resources on reattach. 2018-04-23 10:48:05 +12:00
Gareth McMullin
00decb3718 target: Separate function to free memory map. 2018-04-23 10:48:05 +12:00
Gareth McMullin
1fd2a24c2d stm32f4: Only construct memory map at attach. 2018-04-23 10:48:05 +12:00
Uwe Bonnes
72c1498ae1 stlink: Make SWO Trace Buffer smaller.
Changes for delayed memory map setup otherwise overflow SRAM silently.
2018-04-23 10:48:05 +12:00
Gareth McMullin
455e0a74d2
Merge pull request #302 from gsmcmullin/always_buffer_flash
Only support buffered flash writes
2018-04-23 10:45:25 +12:00
Gareth McMullin
9d7925792f Merge branch 'master' into always_buffer_flash 2018-04-23 10:40:20 +12:00
Gareth McMullin
28bd4fc0ce
Merge pull request #305 from UweBonnes/swo_async
Use async SWO from the bluepill pull request.
2018-04-09 08:27:49 +12:00
Mike Walters
fa62403ee3 nrf51: Add nRF51802 device id. (#331) 2018-04-03 10:45:56 +12:00
Uwe Bonnes
29cdba0d70 SWO: Some explanations and a test program. 2018-03-27 13:40:49 +02:00
Uwe Bonnes
fc25a3339a traceswoasync: Implement async swo for stm32.
Use for stlink.
Uses dma with large buffer.
Pull up swo to provide idle level on unconnected swo pin.
2018-03-27 13:40:49 +02:00
Uwe Bonnes
93bc3a155a traceswo: Provide command option for async swo. 2018-03-27 13:40:49 +02:00
Uwe Bonnes
3e3e450408 cdcacm.c: Use less buffer for the usb_uart buffers and reallocate.
With 128 bytes for both usb_uart buffers, traceswo gives errors!
Keep the size for the receive buffer and diminisch the transmit buffer,
as there is no flow control to the device.
Probably related to https://github.com/libopencm3/libopencm3/issues/477
2018-03-27 13:40:49 +02:00
Gareth McMullin
cfaa5ea963 Merge branch 'korken89-master' 2018-03-27 13:01:06 +13:00
Gareth McMullin
76bfb4929d Use lowercase register names. 2018-03-27 13:00:39 +13:00
Gareth McMullin
90f7bdcd09 Merge branch 'konsgn-master' 2018-03-27 08:08:02 +13:00
Gareth McMullin
a3f855ce5c Merge branch 'master' of https://github.com/konsgn/blackmagic into konsgn-master 2018-03-27 08:03:03 +13:00
Christopher Woodall
31965a5bbc Added support for k64 (#301) 2018-03-25 14:43:33 -07:00
Akila Ravihansa Perera
471ce2547c Added LPC17xx support (#317) 2018-03-25 12:53:30 -07:00
Mark Rages
a41d8cb97a Another nRF52 device id. (#315) 2018-03-25 12:37:51 -07:00
Gareth McMullin
0c659f49cd
Merge pull request #322 from jrwhite/master
hexprog.hex fails due to divide-by-zero
2018-03-25 12:35:52 -07:00
Emil Fresk
1ee6d4503e Update to split 'special' into its sane parts (update from @mubes) 2018-03-24 16:44:59 +01:00
jrwhite
0ddd8b55d7 divide-by-zero fix 2018-03-11 14:35:38 -05:00
Konsgn
04fbabb299 mkl27 support 2018-01-21 23:43:01 -05:00
konsgn
1fe870b8df added MKL27<128kB support 2018-01-16 13:23:36 -05:00
Gareth McMullin
a9219c3616
Merge pull request #314 from adamheinrich/usbuart-ignore-noise
platforms/stm32: Ignore noise errors on USBUART
2018-01-15 08:29:18 +13:00
Adam Heinrich
f5cac4c78d platforms/stm32: Ignore noise errors on USBUART 2018-01-13 21:11:17 +01:00
Gareth McMullin
dd055b675e
Merge pull request #313 from UweBonnes/stm32f3_ccm
stm32f1.c: Add missing fall through statement needed by GCC7.
2017-12-18 10:33:08 -08:00
Uwe Bonnes
922f857de7 stm32f1.c: Add missing fall through statement needed by GCC7. 2017-12-18 13:56:59 +01:00
Gareth McMullin
a3484e3d3b
Merge pull request #311 from UweBonnes/f3_ccm
stm32f1.c: Export CCM RAM of F303.
2017-12-12 14:49:21 -08:00
Uwe Bonnes
1f3c235205 src/target/stm32f1.c: Add CCM Ram of STM32F303 devices. 2017-12-08 13:39:24 +01:00
Gareth McMullin
568655063f
Merge pull request #300 from gsmcmullin/m7-cache
Cache support for Cortex-M7
2017-11-07 08:44:56 +13:00
Gareth McMullin
048e8447a5 target: Only support buffered flash writes 2017-10-13 08:58:37 +13:00
Gareth McMullin
c53a12bfd1 cortexm: Better cache support for Cortex-M7
- On probe, read CTR for cache presence and minimum line length
- Make D-Cache clean a function
- Clean before memory reads
- Clean and invalidate before memory writes
- Flush all I-Cache before resume
2017-10-12 09:26:01 +13:00
Nick Downing
0e5b3ab00e Make Cortex M driver write DCCIMVAC (Data cache clean and invalidate by address to the PoC=Point of Coherency) prior to reading or writing each 32 bytes of RAM 2017-10-12 08:41:58 +13:00
Gareth McMullin
9a5b31c37b Fix fallthrough warnings on gcc 7 2017-10-09 11:07:29 +13:00
Gareth McMullin
231d42d581 Merge pull request #297 from UweBonnes/write_size
target: Fix calculation of erase size.
2017-10-06 19:40:02 +13:00
Uwe Bonnes
120a2d9378 target: Fix calculation of erase size. 2017-10-05 22:11:01 +02:00
Gareth McMullin
5950d8f56c Merge pull request #293 from UweBonnes/write_size
target: Fix wrong size calculation for write.
2017-10-05 09:07:18 +13:00
Gareth McMullin
ed8366813d Merge pull request #294 from UweBonnes/stm32_mem
stm32_mem: Really wait 5 seconds for DFU device to appear.
2017-10-05 09:03:09 +13:00
Uwe Bonnes
dc29e45606 stm32_mem: Really wait 5 seconds for DFU device to appear. 2017-10-04 21:53:53 +02:00
Uwe Bonnes
a7815fff3d target.c: No need to split write while still in same flash block. 2017-10-04 21:52:29 +02:00
Uwe Bonnes
25610e5ec5 target: Fix unconsistant use of tmplen. 2017-10-04 21:52:29 +02:00
Gareth McMullin
72c86f939e Merge pull request #296 from gsmcmullin/libftdi_tdi_tdo_fix
libftdi: Fix tdi_tdo_seq result unpacking
2017-10-05 08:32:08 +13:00
Gareth McMullin
f27f3bad5c libftdi: Fix tdi_tdo_seq result unpacking 2017-10-05 08:26:33 +13:00
Gareth McMullin
2db42ba8e5 Merge pull request #287 from gsmcmullin/update_libopencm3
Update libopencm3
2017-10-04 10:58:44 +13:00
Gareth McMullin
19e58a7205 Merge pull request #284 from UweBonnes/stm32_mem
stm32_mem.py: Print longer strings and small formatting changes.
2017-10-03 10:41:04 +13:00
Uwe Bonnes
2b2b6d8f31 stm32_mem.py: Allow to set start address. 2017-10-02 21:30:56 +02:00
Uwe Bonnes
7cc9ee9d7a stm32_mem.py: Verify after write when bootloader supports upload
This should help people using STM32F103C8 above 64 k.
2017-10-02 21:30:56 +02:00
Uwe Bonnes
613208c939 stm32_mem: Allow to switch from dfu to application without flashing. 2017-10-02 21:30:56 +02:00
Uwe Bonnes
c41dfaef9a stm32_mem.py: Run automatically after switching to DFU mode. 2017-10-02 21:30:56 +02:00
Uwe Bonnes
4f3f4cb898 stm32_mem.py: Deny to work with the STM DFU bootloader
To support the STM DFU bootloader, the interface descriptor needs to be
evaluated. Erase may only be called once per sector.
2017-10-02 21:30:56 +02:00
Uwe Bonnes
4c6f735452 stm32_mem.py: Handle multiple devices. 2017-10-02 21:30:56 +02:00
Gareth McMullin
eb7547111a Merge pull request #285 from UweBonnes/f4_rework
F4 rework
2017-10-03 07:23:52 +13:00
Uwe Bonnes
0aa47113f3 stm32f4: Fix F4 dual bank OPTCR1 to option byte mapping. 2017-10-02 16:22:14 +02:00
Uwe Bonnes
c4d3712b39 stm32f4.c: Rework flash structure recognition.
Dual bank devices do not have sectors (8)12..15 !
Dual banks devices need to MER1 set for mass erase.
F72x has different FLASHSIZE_BASE
2017-10-02 16:22:14 +02:00
Gareth McMullin
0ed66547d5 Fix libopencm3 breakage 2017-09-25 11:17:03 +13:00
Gareth McMullin
f345cd24dc Update libopencm3 pointer 2017-09-25 10:04:05 +13:00
Gareth McMullin
ad71db05b9 Merge pull request #283 from UweBonnes/rdi
Make ENABLE_DEBUG infrastucture available  and use for st- and swlink
2017-09-25 08:12:23 +13:00
Uwe Bonnes
4966168802 s[t|w]link: Implement ENABLE_DEBUG. 2017-09-23 16:40:28 +02:00
Uwe Bonnes
ce1ef6e41b stm32: Move rdi handling to common stm32 code. 2017-09-23 16:39:35 +02:00
Gareth McMullin
98ab873784 Merge pull request #281 from UweBonnes/nucleo144
stlink: Use common initialization and detect V2.1 boards.
2017-09-23 10:36:46 +12:00
Uwe Bonnes
203f6702d8 Flashsize_F103: Options for BMP on STM32F103C8 devices 2017-09-21 23:05:20 +02:00
Uwe Bonnes
963df9febc stlink: Use common initialization and detect V2.1 boards.
Factor out hardware revision detection, USB detach and power settings, as
all three program (bootloader, bmp and dfu-upgrade) need it.
2017-09-21 18:43:06 +02:00
Gareth McMullin
16f99238b1 Merge pull request #279 from gsmcmullin/cortexa-softbreak-fault-check
cortexa: Check for fault on set/clear soft breakpoint.
2017-09-20 11:30:33 +12:00
Gareth McMullin
259f1b90df cortexa: Check for fault on set/clear soft breakpoint. 2017-09-20 11:16:36 +12:00
Gareth McMullin
eaaa7d2cc2 Merge pull request #276 from gsmcmullin/cortexa-remove-ahb
cortexa: Remove problematic code for AHB access.
2017-09-20 08:13:04 +12:00
Gareth McMullin
1cb4271749 cortexa: Remove problematic code for AHB access.
The old code for 'fast' memory accesses using the AHB directly
has problems with data consitency.  Until this can be resolved, I'm
removing the affected code.
2017-09-19 09:13:22 +12:00
Gareth McMullin
eb46994bc9 Merge pull request #277 from gsmcmullin/travis_pip
Travis: Call pip with `--user`
2017-09-12 13:03:49 +12:00
Gareth McMullin
4af7a05249 Travis: Call pip with --user 2017-09-12 12:57:51 +12:00
Gareth McMullin
2df0c7d6a7 Merge pull request #261 from cpavlina/tm4c
lm3s/tm4c: add TM4C1230C3PM
2017-09-06 15:34:42 +12:00
Gareth McMullin
fd9efa2711 Merge pull request #271 from dpiegdon/master
Add nRF52840 support (PCA10056, nrf52840 PDK)
2017-09-06 15:01:13 +12:00
Gareth McMullin
a648967b9e Merge pull request #252 from UweBonnes/stm32_mem
stm32_mem.py: Set address before writing to inhibit bootloader overwr…
2017-09-06 14:49:07 +12:00
Gareth McMullin
0fe746feca Merge pull request #272 from gsmcmullin/build_update
Update CI
2017-09-06 14:44:32 +12:00
Gareth McMullin
d33a8e31b4 Run pip without sudo 2017-09-06 14:33:40 +12:00
Gareth McMullin
41025f55ea Specify Trusty for Travis build 2017-09-06 11:01:43 +12:00
David R. Piegdon
46e363393f Add nRF52840 support (PCA10056, nrf52840 PDK) 2017-09-03 23:05:29 +00:00
Gareth McMullin
11c1af542c Merge pull request #270 from carlsa/master
Added NRF51_FICR_CONFIGID for nRF51822 QFAA H2
2017-08-31 08:40:32 +12:00
Carl Sandström
37f9623de2 Added NRF51_FICR_CONFIGID for nRF51822 QFAA H2 2017-08-30 17:14:52 +02:00
Gareth McMullin
9d898f4aa2 Merge pull request #268 from UweBonnes/f03
STM32F0: Several STM32F0[3|7]0 have same ID as other STM32F0X0.
2017-08-29 09:08:10 +12:00
Uwe Bonnes
37bb86267a STM32F0: Several STM32F0[3|7]0 have same ID as other STM32F0X0. 2017-08-28 22:58:59 +02:00
Uwe Bonnes
1be9c6e9c5 stm32_mem.py: Set address before writing to inhibit bootloader overwrite. 2017-07-22 13:25:48 +02:00
Chris Pavlina
a0b0b8a716 lm3s/tm4c: add TM4C1230C3PM 2017-07-21 13:29:41 -06:00
Gareth McMullin
7663794fdf Merge pull request #247 from schodet/stm32f4-x8-x32
Allow programming STM32F4 when using a low voltage
2017-07-09 14:33:06 -07:00
Nicolas Schodet
3846ea4708 stm32f4: allow selection of flash programming parallelism 2017-07-09 23:26:49 +02:00
Gareth McMullin
09f49b469d Merge pull request #256 from nar0909/patch-1
New Device Id update - QFAA G1
2017-07-09 13:45:52 -07:00
Gareth McMullin
7d474eae7f Merge pull request #251 from therealprof/features/support-LCP1112_102
Identify and support LPC1112/102 MCU as well
2017-07-09 13:45:37 -07:00
nar0909
43ac4a04f7 New Device Id update - QFAA G1
New device Id - for NRF51822 QFAA G1 1529AM.
2017-07-04 12:32:39 +10:00
Daniel Egger
f036be8cb2 Identify and support LPC1112/102 MCU as well
Signed-off-by: Daniel Egger <daniel@eggers-club.de>
2017-06-23 21:52:13 +02:00
Gareth McMullin
984f8b3d94 Merge pull request #248 from schodet/typo
stm32f4: fix typo in target name
2017-06-22 18:35:29 -07:00
Gareth McMullin
40ac8e1004 Merge pull request #241 from gsmcmullin/no_magic_vtor
Use vector_table symbol for assignment of SCB_VTOR.
2017-06-22 16:31:09 -07:00
Gareth McMullin
e9cdd5ec56 Merge pull request #245 from schodet/stm32f469
stm32f4: add support for STM32F4[67]9
2017-06-22 14:52:19 -07:00
Nicolas Schodet
02ce5e23b6 stm32f4: fix typo in target name 2017-06-19 10:56:20 +02:00
Nicolas Schodet
680aa30d52 stm32f4: add support for STM32F4[67]9 2017-06-19 10:41:38 +02:00
Gareth McMullin
63a2e74948 Merge pull request #244 from schodet/gdb-py-fix
Fix gdb.py to program last chunk of a memory range
2017-06-18 15:02:33 -07:00
Gareth McMullin
c7bc51d191 Merge pull request #235 from UweBonnes/stm32f2_4_7
Stm32f2_4_7
2017-06-18 14:42:13 -07:00
Gordon Smith
1ee1f441d5 stm32f4: write flash using byte access 2017-06-16 14:45:16 +02:00
Nicolas Schodet
73ac700c6f Fix gdb.py to program last chunk of a memory range 2017-06-15 16:20:02 +02:00
Uwe Bonnes
408c5a9df2 stm32f4: Try to handle option bytes for more devices.
Correct the table for the OPTCRx values from errors in documentation and
error when entering the values.
2017-06-09 13:03:26 +02:00
Uwe Bonnes
8a7455f63e src/target/stm32f4.c: Add STM32F7[2|3]x. 2017-06-09 13:03:26 +02:00
Uwe Bonnes
84e036a804 target/stm32f4: Document FLASH_OPTCR(1|2) registers. 2017-06-09 13:03:26 +02:00
Uwe Bonnes
2216587b39 src/target/stm32f4.c: Remove missleading DTCM comment.
Use different command string for F74x and F76x.
2017-06-09 13:03:26 +02:00
Uwe Bonnes
dc1c7611a9 src/target/stm32f4.c: All STM32F7 devs have option bytes at 0x1fff0000. 2017-06-09 13:03:26 +02:00
Uwe Bonnes
e43017d0a6 src/target/stm32f4.c: Add STM32F412 and F413.
F413 needs its own clause, as there is memory > 1 MB but no second bank.
2017-06-09 13:03:26 +02:00
Uwe Bonnes
24ed65d6b6 src/target/stm32f4.c: Declare CCMRAM only for devices with CCMRAM. 2017-06-09 13:03:26 +02:00
Gareth McMullin
2eb2f8edd7 Use vector_table symbol for assignment of SCB_VTOR. 2017-06-09 13:07:06 +12:00
Gareth McMullin
a4bb2c6e3e Merge pull request #240 from UweBonnes/cleanup
stlink/swlink: Remove missleading comments.
2017-06-08 12:35:28 -07:00
Uwe Bonnes
a7771fa23f stlink/swlink: Remove missleading comments. 2017-06-08 18:25:43 +02:00
Gareth McMullin
aaa7b0e38e Merge pull request #217 from UweBonnes/stm32l4
Stm32l4
2017-05-23 12:22:04 -07:00
Gareth McMullin
fd467269eb Merge pull request #233 from gsmcmullin/parallel_make_fix
Fix parallel build.
2017-05-23 12:20:21 -07:00
Gareth McMullin
539d9e14ec Merge pull request #223 from gsmcmullin/nrf51_c_stub
nrf51: Replace stub with C version and pass params in registers
2017-05-23 12:00:08 -07:00
Gareth McMullin
ecc0d9807d Fix parallel build.
Add explicit dependency of command.c on version.h
Remove version.h on make clean.
2017-05-23 11:57:35 -07:00
Uwe Bonnes
91839f3aee stm32l4.c: Handle options. 2017-05-11 23:31:43 +02:00
Uwe Bonnes
289be4d9db stm32l4.c: Add STM32L43/L44/L45/L46/L49/L4A. 2017-05-11 23:31:43 +02:00
Gareth McMullin
261be9864c Merge pull request #210 from UweBonnes/f4_discovery
F4 discovery
2017-05-12 09:15:55 +12:00
Uwe Bonnes
8cc2c44dbf f4discovery: Use Magic constant in RAM for Bootloader entry. 2017-05-11 22:21:38 +02:00
Uwe Bonnes
a0e47c392b f4_discovery: Clean up platform.h and Readme. 2017-05-11 21:53:01 +02:00
Uwe Bonnes
814eb0e3a2 f4discovery: Make DFU work (again?) 2017-05-11 21:52:24 +02:00
Uwe Bonnes
f5dd3006fb STM32: Generate same serial number as internal DFU bootloader. 2017-05-11 21:52:24 +02:00
Gareth McMullin
98a4f8e318 Merge pull request #205 from UweBonnes/stlink_flashsize
stlink: Announce 124 kiB flash size in DFU to commplement #204.
2017-05-12 04:20:34 +12:00
Uwe Bonnes
b7235da97f dfucore.c: Announce no writable bootloader pages when device is read proteced
or bootloader is write protected.

Device read protection or write protection on first 4 bootloader pages
can only be removed by mass erase. Triggering mass erase with a program
running from flash is doomed for failure.
User can force bootloader update, at their own risk to brick the device.
2017-05-07 13:19:37 +02:00
Uwe Bonnes
b09a522f37 STM32F103: Use flash size from device for DFU string.
Complements #204.
STLinkV2-1 has F103CB on board! F103C8 on older Stlinks can use upper flash
with hopefully acceptable error rate.
For F103C8 devices, user has to give the force option to dfu-utils.
2017-05-07 13:19:37 +02:00
Gareth McMullin
f450b1745d Merge branch 'v1.6-branch' 2017-05-06 15:25:50 -07:00
stoyan shopov
d3a8f27fdb fixed a bug in the breakpoint removal code 2017-05-06 14:58:31 -07:00
Gareth McMullin
94c822cb62 nrf51: Replace stub with C version and pass params in registers 2017-05-03 13:10:01 -07:00
Gareth McMullin
6b592b4118 Merge pull request #218 from stoyan-shopov/breakpoint-removal-bugfix
fixed a bug in the breakpoint removal code
2017-05-03 12:11:50 -07:00
Gareth McMullin
bfce31f26a Merge pull request #219 from UweBonnes/dfu_update
dfu_f1/dfu_upgrade: Do not set read protection.
2017-05-03 10:39:13 -07:00
Uwe Bonnes
5af76a1b74 dfu_f1/dfu_upgrade: Do not set read protection.
As the first 4 pages of the bootloader will always keep write protection
once read protection is applied, with the second update of the bootloader
only the higher pages where updated effectivly.
In most cases this resulted in an inaccessible device!
2017-04-29 14:58:41 +02:00
stoyan shopov
01e3582525 fixed a bug in the breakpoint removal code 2017-04-28 13:22:59 +03:00
Gareth McMullin
b10971b19b Merge pull request #206 from UweBonnes/dfu-upload
Dfu upload
2017-04-27 10:07:37 -07:00
Gareth McMullin
146c0b83b5 Merge pull request #214 from falstaff84/const-strings-and-structs
Constify strings and constant structs
2017-04-27 10:02:53 -07:00
Stefan Agner
3c06396c8e Constify strings and constant structs 2017-04-22 13:50:04 -07:00
Gareth McMullin
2f5295ba14 Merge pull request #213 from gsmcmullin/k22f_security_hack
K22F security hack
2017-04-21 13:29:48 +12:00
Gareth McMullin
633662dbb3 Hold TMS high during reset.
This is a questionable fix for the Kinetis K22F that samples
this pin on release from reset to enable its EzPort which
makes the flash unusable and disables the rest of the micro.
2017-04-21 11:05:07 +12:00
Gareth McMullin
1140ff957e kinetis: Check/fix security byte on flash done. 2017-04-19 13:55:37 +12:00
Gareth McMullin
06bf37fe20 Merge pull request #208 from gsmcmullin/mem_packet_range_check
Add range checking on mem access packets.
2017-04-18 14:17:07 +12:00
Gareth McMullin
25f5efd06b Merge pull request #207 from gsmcmullin/stm32f4_itcm_translate
stm32f4: Translate ITCM addresses to AXIM on flash write.
2017-04-18 14:05:57 +12:00
Gareth McMullin
08c0cafa09 stm32f4: Translate ITCM addresses to AXIM on flash write. 2017-04-18 12:56:33 +12:00
Gareth McMullin
bd2cfe72f0 Add range checking on mem access packets. 2017-04-18 11:41:11 +12:00
Gareth McMullin
e5395aaba7 Merge pull request #91 from schodet/usb-vbus
Fix usage of USB_VBUS
2017-04-18 08:22:57 +12:00
Uwe Bonnes
d796571438 Implement DFU_UPLOAD. 2017-04-15 14:26:03 +02:00
Uwe Bonnes
1d8ebcd75f Handle SET_ADDRESS according to DFUSE specs. 2017-04-14 15:16:59 +02:00
Gareth McMullin
1f31099d46 Merge pull request #202 from gsmcmullin/tiva_srst_inhibit
lmi: Inhibit SRST on Tiva and add some fault checks.
2017-04-13 09:13:55 +12:00
Gareth McMullin
dacf907540 Merge pull request #204 from gsmcmullin/stlink-flash-size
Increase st-link flash allowance to 128K.
2017-04-13 09:08:55 +12:00
Gareth McMullin
394fd4894b Increase st-link flash allowance to 128K.
Although the devices are only documented to have 64K flash,
they have been obeserved to have a full 128K, although the undocumented
half may be untested and have problems.
2017-04-13 09:01:26 +12:00
Gareth McMullin
644add19a6 lmi: Add comment explaining SRST inhibit 2017-04-13 08:42:16 +12:00
Gareth McMullin
97afffed8b Merge pull request #201 from gsmcmullin/stub_check_halt_status
cortexm: Check halt reason on stub exit.
2017-04-13 08:35:20 +12:00
Gareth McMullin
00183f1a9b lmi: Inhibit SRST on Tiva and add some fault checks. 2017-04-12 15:52:09 +12:00
Gareth McMullin
e4de689a09 cortexm: Check halt reason on stub exit. 2017-04-12 11:37:42 +12:00
Gareth McMullin
8e2c2757b4 Merge pull request #195 from gsmcmullin/kinetis_work
Kinetis stuff
2017-03-28 13:58:00 +13:00
Gareth McMullin
38705dc952 Merge pull request #196 from gsmcmullin/target_order
target: Add new targets to end of list.
2017-03-28 11:24:31 +13:00
Gareth McMullin
3d2fa6d233 target: Add new targets to end of list.
This shows targets enumerated in their natural order,
rather than in reverse.
2017-03-27 14:59:54 +13:00
Gareth McMullin
0ed793fe24 kinetis: Clobber security byte with unsecure value.
May be overridden with `mon unsafe enable`.
2017-03-27 14:01:35 +13:00
Gareth McMullin
7de304d72a kinetis: Add recovery mode target. 2017-03-27 10:51:36 +13:00
Gareth McMullin
bb93af50c3 adiv5: Debug log on failure to read ROM table. 2017-03-27 09:05:37 +13:00
Gareth McMullin
a0791f9525 Merge pull request #187 from gsmcmullin/uwe_patches
More STM32L0 and STM32L4 devices
2017-02-07 09:56:35 +13:00
Uwe Bonnes
21f71fd18a More STM32L4 devices
Hello,

appended patch adds more STM32L4xx devices and was tested with L432 Nucleo.

Cheers

--
Uwe Bonnes                bon@elektron.ikp.physik.tu-darmstadt.de

Institut fuer Kernphysik  Schlossgartenstrasse 9  64289 Darmstadt
--------- Tel. 06151 1623569 ------- Fax. 06151 1623305 ---------
>From e9323a35b667659111226686221a037375a6c208 Mon Sep 17 00:00:00 2001
From: Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de>
Date: Thu, 2 Feb 2017 20:12:59 +0100
Subject: src/target/stm32l4.c: Add more devices.
2017-02-07 09:42:30 +13:00
Uwe Bonnes
41fb2a3104 More STM32L0 devices
Hello,

appended patch adds more STM32L0xx devices and was tested with L031 Nucleo.

Cheers
--
Uwe Bonnes                bon@elektron.ikp.physik.tu-darmstadt.de

Institut fuer Kernphysik  Schlossgartenstrasse 9  64289 Darmstadt
--------- Tel. 06151 1623569 ------- Fax. 06151 1623305 ---------
>From fb014dd8a90691056f10fbeffd7f21aaad196662 Mon Sep 17 00:00:00 2001
From: Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de>
Date: Fri, 27 Jan 2017 23:09:10 +0100
Subject: src/target/stm32l0.c: Add new categories.
2017-02-07 09:42:30 +13:00
Gareth McMullin
62dedb9824 Add K22F 2017-02-07 09:36:47 +13:00
Gareth McMullin
7ba2987a83 native: Fix macros for setting pin mode.
Fixes #184
2017-01-24 10:49:45 +13:00
Gareth McMullin
8c256d9e59 kinetis: Add KL03 devices. 2017-01-17 15:28:47 +13:00
Gareth McMullin
a77fb9ac1b Merge pull request #180 from paramaggarwal/patch-1
Actual pin mappings and the comment differ!
2017-01-09 14:39:06 +13:00
Gareth McMullin
334f6dac0a Merge pull request #182 from esden/bmpm21
Add BMPM V2.1 support
2017-01-09 14:38:33 +13:00
Gareth McMullin
ad552dbe3b Merge pull request #183 from gsmcmullin/volatile_crtlstat
adiv5_dp_init: make ctrlstat volatile to supress warning.
2017-01-09 09:30:03 +13:00
Gareth McMullin
cd1bef89bb adiv5_dp_init: make ctrlstat volatile to supress warning. 2017-01-09 09:13:19 +13:00
Piotr Esden-Tempski
606b73601c Added TMS/SWDIO direction pin & adjusted SRST sense.
1) This version uses a direction control level shifters. We need to control
the direction of the TMS/SWDIO pin.
2.1) Because we want to support a large voltage range for SRST we use an
external dual MOSFET for asserting and sensing the SRST line. We have
added the hardware version 3 to be handled the same way as version 0.
Meaning using separate pins for assertion and sensing of the SRST line.
2.2) The new SRST sense circuit is inverting, thus we have dedicated
code for hardware version 3 that inverts the SRST status pin on read.
2017-01-06 18:31:55 -08:00
Param Aggarwal
51ac0fe319 Actual pin mappings and the comment differ!
I was stuck trying to debug the issue why my probe would not find any attached targets. This is because I was doing the pin mapping as per the comments, and not the actual code. There is a mismatch!

This PR updates the comment to reflect the values set in code. :)
2017-01-01 14:50:58 +05:30
Gareth McMullin
d6e29774fe Merge pull request #174 from ChuckM/sam4l
Target Driver for Atmetl AT91SAM4L target
2016-12-05 10:55:24 +13:00
Chuck McManis
085c980215 Remove EXTENDED_RESET define 2016-12-04 13:51:27 -08:00
Chuck McManis
a3c2592e44 Review feedback 2016-12-04 13:15:45 -08:00
Gareth McMullin
dc9073b13e Merge pull request #175 from blacksphere/kickstarter-badge
Update README with Kickstarter
2016-12-04 10:52:41 +13:00
Gareth McMullin
fb148862ca Update README
Add a badge with a link to the Kickstarter
2016-12-04 10:47:01 +13:00
Gareth McMullin
7b02d68ab2 Update README
Add donate with Paypal button
2016-12-04 10:26:25 +13:00
Chuck McManis
469ecbf0f9 SAM4L: Add target driver for SAM4L
This commit adds a target driver for SAM4L and it depends on the
extended reset change.
2016-12-02 00:10:06 -08:00
Chuck McManis
0aef6c6774 SAM4L: Add extended reset to target interface
This adds a new function to the internal target interface
to allow the target to get control before reset is complete
so that it can do any additional work. On this target there
is a proprietary internal bit that has to be reset in some
cases to allow the core to continue operating.
2016-12-02 00:08:21 -08:00
Gareth McMullin
b745799156 Merge pull request #171 from gsmcmullin/v2_usb_uart_check
Don't enable usb uart on v2 when debugging
2016-11-22 13:20:24 +13:00
Gareth McMullin
7730d3b198 Don't enable usb uart on v2 when debugging 2016-11-22 12:45:59 +13:00
Gareth McMullin
3fa2e6163a Merge pull request #170 from gsmcmullin/happy_gecko
EFM32HP (happy gecko) support
2016-11-17 10:33:16 +13:00
Gareth McMullin
15268ac663 EFM32HP (happy gecko) support 2016-11-16 08:23:40 +13:00
Gareth McMullin
5e8794627a Merge pull request #168 from Gussy/stm32f303-targets
add STM32F303 targets
2016-11-04 01:17:12 -07:00
Angus Peart
4212d7a394 add STM32F303 targets 2016-11-03 13:44:13 -07:00
Gareth McMullin
e279844532 Merge pull request #167 from gsmcmullin/stm32l4_buffered
STM32L4: Use buffered flash model.
2016-10-31 12:06:00 -07:00
Gareth McMullin
bcf3caf20e cortexa: Disable AHB memory access to avoid issues with L2 cache. 2016-10-26 18:27:35 -07:00
Gareth McMullin
3b7edc325d Merge pull request #165 from gsmcmullin/gdb_tcp_buffering
libftdi: Disable Nagle algorithm and buffer sends internally.
2016-10-25 10:28:29 -07:00
Gareth McMullin
cebe4f8f1c Merge pull request #164 from gsmcmullin/cortexa_resume_fix
cortexa: Wait for instruction complete on resume.
2016-10-25 10:28:13 -07:00
Gareth McMullin
f40883f2b2 cortexa: Wait for instruction complete on resume, and timeout if no response. 2016-10-25 10:22:21 -07:00
Gareth McMullin
f947465fe4 libftdi: Disable Nagle algorithm and buffer sends internally.
This significantly improves performance by not waiting for TCP
timeout on transmission.
2016-10-25 10:07:04 -07:00
Gareth McMullin
917c107ded Use git-describe --always --dirty when generating version.h 2016-10-22 14:45:32 -07:00
Gareth McMullin
c9a72bf97b Add build output link to readme 2016-10-22 14:32:35 -07:00
Gareth McMullin
7c83536c14 Don't break build if no tags in history 2016-10-22 13:19:00 -07:00
Gareth McMullin
7b575bd7c6 Fix Travis deployment. 2016-10-22 13:07:42 -07:00
Gareth McMullin
d48465c527 Merge pull request #163 from gsmcmullin/travis_publish
First attempt at publishing Travis builds to Amazon S3.
2016-10-22 12:06:46 -07:00
Gareth McMullin
cbc21114c1 First attempt at publishing Travis builds to Amazon S3. 2016-10-22 11:55:15 -07:00
Gareth McMullin
39a0e26f4b Merge pull request #161 from esden/compile_fixes
Compile fixes
2016-10-19 15:12:41 -07:00
Piotr Esden-Tempski
fdeb6471a8 Added missing #include guard. 2016-10-19 14:56:52 -07:00
Piotr Esden-Tempski
4348f0d135 Fixed double const.
The way the const pointer was written caused at least the clang compiler
to complain about double cosnst. I am not sure if the way it was written
before it resulted in the intended "make everything const" goal. But the
way it is written now it adheres to the right to left reading rule.
2016-10-19 14:37:03 -07:00
Piotr Esden-Tempski
2d37de773c Fixed #include guard. 2016-10-19 14:36:27 -07:00
Gareth McMullin
fe4bae7942 Merge pull request #160 from esden/jtagtap_next_params
Corrected jtagtap_next signature.
2016-10-19 14:26:27 -07:00
Piotr Esden-Tempski
8a009ca6ae Corrected jtagtap_next signature.
The parameter is TDI (as in input) not TDO. The header signature and
comment are correct.
2016-10-19 13:53:04 -07:00
Gareth McMullin
25a6450af0 Merge pull request #158 from rogerclarkmelbourne/master
Add support for nRF51822QFAAH1
2016-10-16 08:45:44 -07:00
Roger Clark
3b74d91c69 Add support for nRF51822QFAAH1 2016-10-16 19:52:47 +11:00
Gareth McMullin
3abb4afdf6 Merge pull request #153 from gsmcmullin/restore_leds
Restore LED behaviour.
2016-10-05 10:37:36 -07:00
Gareth McMullin
2e9660910c STM32L4: Use buffered flash model. 2016-09-30 12:09:37 -07:00
Gareth McMullin
517881f551 Merge pull request #154 from gsmcmullin/cortexa_breakpoints
cortexa: Fix hardware breakpoints.
2016-09-29 21:39:04 -07:00
Gareth McMullin
1f3576928c Merge pull request #151 from gsmcmullin/self_semihost
Use semihosting for debug output if available.
2016-09-29 21:36:53 -07:00
Gareth McMullin
9a8cef04e0 Clean up debug format strings. 2016-09-29 21:31:18 -07:00
Gareth McMullin
966f360515 debug: Use semihosting if available or output via usbuart. 2016-09-29 21:31:13 -07:00
Gareth McMullin
ba8f77abf8 cortexa: Fix hardware breakpoints. 2016-09-28 22:18:24 -07:00
Gareth McMullin
40f960db4d Restore LED behaviour. 2016-09-28 22:15:15 -07:00
Gareth McMullin
45e322b9a3 Handle usart errors. 2016-08-22 09:57:52 +12:00
Gareth McMullin
ca364a889e Fix #145
Don't tc_printf in the probe.
tc_printf fixed to not crash of no controller connected.
2016-08-22 09:56:24 +12:00
Gareth McMullin
df7ad91692 Merge pull request #146 from joshgrob/nRF51/52_update
Adding new ConfigID value for nRF52832 QFAA B00
2016-08-10 07:33:28 +12:00
Gareth McMullin
779e0b5d15 Print sizes in memory map using 32-bit formatting for newlib-nano. 2016-08-08 13:42:03 +12:00
jgrob-an
fd4b8a02c0 Adding new ConfigID value for nRF52832 QFAA B00 2016-08-03 23:27:34 -04:00
Gareth McMullin
f131460168 Don't use zx format with printf. Doesn't work with newlib.
Fixes #144.
2016-07-19 10:45:46 +12:00
Gareth McMullin
de603f4bd8 Merge pull request #143 from gsmcmullin/work
Split target support from GDB server with clean interface.
2016-07-18 08:19:10 +12:00
Gareth McMullin
9a45d89b4a target: Remove target_check_error from external interface. 2016-07-13 08:31:09 +12:00
Gareth McMullin
97f3fc6155 Reorder target.h 2016-07-13 08:31:09 +12:00
Gareth McMullin
9aacc18f60 target: Restructure internal break/watch handling.
cortexa: Implement soft breakpoints.
2016-07-13 08:31:09 +12:00
Gareth McMullin
9136cf4c98 target: target_halt_wait and target_check_hw_wp replaced with target_halt_poll.
The new function returns a stop reason which must be translated in gdb server.
In the case of a watchpoint hit, the address is returned by a pointer parameter.
Simplify the extenal interface for set/clear breaki-/watchpoints.
2016-07-13 08:31:09 +12:00
Gareth McMullin
ab06243e93 target: Use size_t instead of unsigned in syscall interface. 2016-07-13 08:31:09 +12:00
Gareth McMullin
26fab877da target: Provide errno definitions and fallback for unimplemented syscalls. 2016-07-13 08:31:09 +12:00
Gareth McMullin
82cb6c8e83 target: Use target_addr for flash routines. 2016-07-13 08:31:09 +12:00
Gareth McMullin
aeaca988c3 target: Use new target_addr type consistently in external interface.
Flash routines still use uint32_t internally.
2016-07-13 08:31:09 +12:00
Gareth McMullin
f9bdaf06a4 Move flash stubs to target directory and update readme. 2016-07-13 08:31:09 +12:00
Gareth McMullin
b494279fe5 Move target files into separate directory. 2016-07-13 08:31:09 +12:00
Gareth McMullin
b644724520 Overhaul of semihosting. Remove dependence of target on gdb_packet. 2016-07-13 08:31:09 +12:00
Gareth McMullin
b03cc59bea target: Add target controller structure for indirect calls back to host. 2016-07-13 08:31:09 +12:00
Gareth McMullin
5832d8a42a Clean up common SWD stuff. 2016-07-13 08:31:09 +12:00
Gareth McMullin
9b8e2c3ad1 target: Replace all calls to gdb_out with new tc_printf. 2016-07-13 08:31:09 +12:00
Gareth McMullin
5c5f76d60e target: Remove last accesses to private structure from outside.
Only include target_internal.h from inside target files.
2016-07-13 08:31:09 +12:00
Gareth McMullin
1cd03b3fa4 Allow breakpoint and watchpoint methods to be left NULL. 2016-07-13 08:31:09 +12:00
Gareth McMullin
07f27d1b70 Hide target list internals form command.c
Remove unused support for extended target structure size.
2016-07-13 08:31:09 +12:00
Gareth McMullin
72790893ae target: move mmio routines out of public interface.
Fix crc routine to use buffered reads on stm32.
2016-07-13 08:31:09 +12:00
Gareth McMullin
e28e158721 Move *scan prototypes to target.h. 2016-07-13 08:31:09 +12:00
Gareth McMullin
4e04c1dded Split out non-public target stuff into new header.
Wrap target methods with functions instead of macros.
2016-07-13 08:31:09 +12:00
Gareth McMullin
67bd1530b7 Remove some unused includes. 2016-07-13 08:31:09 +12:00
Gareth McMullin
3c44cce935 Make generic jtagtap function weak and stop including the c file. 2016-07-13 08:31:09 +12:00
Gareth McMullin
0fc61efe7c Move STM32L[01] bit definitions to their driver and remove header. 2016-07-13 08:31:09 +12:00
Gareth McMullin
6b49fbe594 Quiet adiv5 probe. 2016-07-13 08:31:09 +12:00
Gareth McMullin
0480578391 stlink: New discovery boards support.
Patch from issue #103
2016-07-13 08:00:05 +12:00
Gareth McMullin
fec09464ac Add STM32F302C8 ID.
From issue #100
2016-07-13 08:00:05 +12:00
Gareth McMullin
24f0c38b45 Merge pull request #142 from alex31/ictm_and_stm32f76x
° add support for ITCM flash memory (in addition of DTCM) for STM…
2016-07-12 07:11:52 +12:00
Alexandre Bustico
c906a8614f ° add support for ITCM flash memory (in addition of DTCM) for STM32F7 family
° add support for STM32F76x and STM32F77x
2016-07-11 14:58:40 +02:00
Gareth McMullin
419aae4940 lpc15xx cleanup 2016-07-06 10:34:51 +12:00
Gareth McMullin
6fc49a11d8 Merge pull request #141 from dlaw/master
lpc15xx support
2016-07-06 10:27:15 +12:00
David Lawrence
4addec0a21 lpc15xx support 2016-07-05 16:53:47 -04:00
Gareth McMullin
2a5efbc1ac Merge pull request #140 from gsmcmullin/va_translation
cortexa: Virtual address translation and memory access through APB.
2016-06-30 18:23:31 +12:00
Gareth McMullin
393a8fddef Merge pull request #135 from gsmcmullin/timeout_overhaul
Timeout overhaul, improve reset spin loop on Cortex-A
2016-06-30 18:23:02 +12:00
Gareth McMullin
4596d88f72 cortexa: Use fast mode for APB mem access and allow byte access. 2016-06-30 17:56:01 +12:00
Gareth McMullin
d16aca9ae0 cortexa: Fall back to APB memory access if no AHB available. 2016-06-29 11:11:27 +12:00
Gareth McMullin
ea9c2a2030 cortexa: Catch and report faults on address translation. 2016-06-29 11:11:27 +12:00
Gareth McMullin
9e2b0a86d7 cortexa: Perform VA translation on memory access. 2016-06-29 11:11:27 +12:00
Gareth McMullin
09bb320a65 Change readme to markdown and add Travis and Gitter badges. 2016-06-29 10:25:09 +12:00
Gareth McMullin
9c5ff37bf8 Add monitor command to force SRST 2016-06-28 14:35:43 +12:00
Gareth McMullin
60c67ee156 cortexa: Flush I-Cache on detach. 2016-06-28 14:35:43 +12:00
Gareth McMullin
6b3c3d3473 cortexa: Add timeout to reset spin. 2016-06-28 14:35:43 +12:00
Gareth McMullin
8b4342394f Overhaul of timeouts so they may be nested. 2016-06-28 14:35:43 +12:00
Gareth McMullin
6b6ac1b961 First cut at building with Travis 2016-06-27 13:30:56 +12:00
Gareth McMullin
53c7fbd543 Fixes for verbose debug output. 2016-06-23 15:03:00 +12:00
Gareth McMullin
1f9fbd2d0e Merge pull request #139 from esden/pid_cid_tables
Use Product ID and Componend ID tables instead of defines.
2016-06-23 13:39:00 +12:00
Piotr Esden-Tempski
7b2309943a Use Product ID and Componend ID tables instead of defines.
This patch adds tables that allow us to decode the Product ID and
Component ID registers. Based on those tables we can decide what probe
function to use. Also this makes it possible for us to understand what
ADIv5 components the target is offering to us, even if we do not
need/use them.

The tables include a comment describing how the register bits need to be
interpreted.
2016-06-22 18:34:04 -07:00
Gareth McMullin
dcff9f9186 Merge pull request #138 from esden/debug_strings
Added black magic verbose/debug mode switch.
2016-06-23 12:55:48 +12:00
Piotr Esden-Tempski
20c994eece Added black magic verbose/debug mode switch. 2016-06-22 17:28:26 -07:00
Gareth McMullin
90c0c28327 cortexa: Redirect read of PC through r0. MCR is unpredictable for r15. 2016-06-23 12:00:04 +12:00
Gareth McMullin
eb1904247e Merge pull request #136 from funkobongrip/lpc82x
Add NXP LPC82x support
2016-06-22 10:06:58 +12:00
David Brandt
2639bdbe23 Add NXP LPC82x support 2016-06-21 10:33:34 +02:00
Gareth McMullin
f4eda28a05 Merge pull request #134 from esden/master
BMPM V2 target power control GPIO needs to be an open drain drive.
2016-06-07 10:12:02 +12:00
Piotr Esden-Tempski
9be5cdb702 BMPM V2 target power control GPIO needs to be an open drain drive.
BMPM V2 uses a biasing resistor for the true switch mosfet circuit.
Because of that the weak pull-up/down of the stm32 is not asserting the
correct gate voltage for the mosfets to fully switch through. Because of
that we need to use open drain configulation of the GPIO instead.
2016-06-06 15:01:37 -07:00
Gareth McMullin
55cea5f90a Merge pull request #132 from dlaw/kinetis
Add Kinetis KL27 support
2016-06-01 07:48:13 +12:00
Gareth McMullin
8770b4aa39 Merge pull request #133 from gsmcmullin/armv6m-fix
adiv5: Probe ARMv6M devices with Cortex-M driver.
2016-06-01 07:48:03 +12:00
Gareth McMullin
24d973e39f adiv5: Probe ARMv6M devices with Cortex-M driver. 2016-05-30 08:48:54 +12:00
David Lawrence
25a46a83f9 Add Kinetis KL27 support 2016-05-18 12:06:54 -04:00
Gareth McMullin
bcf5b1eaa3 Merge pull request #126 from gsmcmullin/cortexa
Cortex-A support
2016-04-28 10:56:43 +12:00
Gareth McMullin
13602c5d85 cortexa: Also assert SRST to reset. 2016-04-20 12:55:12 -07:00
Gareth McMullin
08c9ab54d7 adiv5: Try abort sequence if DP is stalling during scan. 2016-04-20 12:55:12 -07:00
Gareth McMullin
bed6627579 adiv5: Implement access to DP ABORT register. 2016-04-20 11:36:42 -07:00
Gareth McMullin
68bf825042 cortexa: Disable interrupts while single stepping. 2016-04-20 11:35:58 -07:00
Gareth McMullin
88bf92ac36 cortexa: Fix write back of PC and CPSR. 2016-04-20 11:35:25 -07:00
Gareth McMullin
d94f7e0c75 Remove old arm7tdmi header. 2016-04-19 22:23:19 -07:00
Gareth McMullin
0ab878dcd2 cortexa: Add short delay after reset, before reattaching.
Allows the early bootloader to configure the DDR ram.
2016-04-19 13:29:22 -07:00
Gareth McMullin
a2ec877b73 cortexa: Restore cache clean and invalidate on memory writes.
Include a small optimisation of APB access to speed up the process.
2016-04-19 13:24:05 -07:00
Gareth McMullin
49f89cfc95 cortexa: Fix detach.
Also pulls out internal register cache functions from halt/resume.
2016-04-19 13:24:05 -07:00
Gareth McMullin
f6b574e0b0 Cortex-A target support. 2016-04-19 13:24:05 -07:00
Gareth McMullin
60f3be501e Pass breakpoint length to target. 2016-04-19 13:24:05 -07:00
Gareth McMullin
459bae4ea1 ADIv5 structural changes.
- Probe ROM table
- Mem-AP no longer pretends to be a target
- AP no longer provides priv pointer
2016-04-19 13:24:05 -07:00
Gareth McMullin
8d9d6f692c Fix platform_delay 2016-04-19 13:23:04 -07:00
Gareth McMullin
da10f8a6bc Merge pull request #129 from gsmcmullin/srst_cleanup
Cleanup of SRST handling.
2016-04-19 13:20:36 -07:00
Gareth McMullin
cd1d72257f Cleanup of SRST handling.
- Remove connect_assert_srst global.
- Attach functions always release reset.
- Platforms provide a method to poll the reset pin.
- Reset on scan is all internal to command.c
- Reset is released on a failed scan.  Fixes #111
2016-04-19 13:12:16 -07:00
Gareth McMullin
e010cd763d Merge pull request #125 from bvernoux/master
Cleanup and Fix code for HydraBus
2016-04-18 13:01:00 -07:00
Gareth McMullin
0e8cbd4419 Merge pull request #127 from gsmcmullin/warning_fixes
Fix build warnings.
2016-04-18 12:32:46 -07:00
Gareth McMullin
294d93cfe3 Fix build warnings. 2016-04-18 12:25:48 -07:00
bvernoux
2e3778e772 Cleanup and Fix code for HydraBus 2016-04-18 00:48:06 +02:00
Gareth McMullin
2685906fc8 Merge pull request #124 from gsmcmullin/windows_fixes
Fixes to allow building for Windows.
2016-04-16 14:49:22 -07:00
Gareth McMullin
799ccf99f5 Merge pull request #123 from gsmcmullin/digilent_cable
Add Digilent JTAG-HS3 FTDI cable.
2016-04-15 13:06:30 -07:00
Gareth McMullin
966b21c3e1 Merge pull request #121 from esden/bmpm2_support
Bmpm2 support
2016-04-15 13:01:34 -07:00
Gareth McMullin
9141418bd4 Merge pull request #80 from gsmcmullin/hydrabus
Add HydraBus support
2016-04-15 13:00:52 -07:00
Gareth McMullin
987a926a19 Fixes to allow building for Windows. 2016-04-15 12:58:36 -07:00
Gareth McMullin
4e8b40ad5d Add Digilent JTAG-HS3 FDTI cable. 2016-04-15 12:05:43 -07:00
Piotr Esden-Tempski
8e8a53ef12 Added support for Black Magic Probe Mini V2.0e.
All BMPM2 prototypes after revision a have their LED0 and LED2 inverted.
Because of that we have bumped the hardware revision to swap the LEDs in
software. This is easier than messing up the routing of the LEDs.
2016-04-06 19:23:17 -07:00
Piotr Esden-Tempski
f2650df731 Fixed a hardware version detection glitch.
If you try to read out the GPIO immediately after setting the weak pull
on the pin it is possible that you will not read the correct value on a
floating pin. We need to use a busy wait loop instead of the
platform_delay because the platform timing is not initialized yet. We
also can not initialize the platform_delay code yet because it requires
LED gpio to be configured. A busy wait seems to do the job and is easier
than refactoring the codebase to use the platform_delay function.
2016-04-06 19:20:43 -07:00
Gareth McMullin
4d6f691f48 Merge pull request #120 from lyorak/upstream_patches
added support for KL02 family
2016-03-16 08:05:30 +13:00
Karoly Molnar
33414c3a9b added support for KL02 family 2016-03-15 17:31:24 +01:00
Gareth McMullin
cc244eb2d8 Merge pull request #108 from lbonn/upstream-patches
Some various fixes
2016-03-09 10:27:34 +13:00
Gareth McMullin
c0f92ea5a7 Merge pull request #116 from esden/flashier_dfu
[native] Make the native bootloader bit more flashy.
2016-03-09 10:26:56 +13:00
Gareth McMullin
4e23c95c53 Merge pull request #115 from esden/bmpm2
[native] Check for hardware version by pull-up and -down. Print HW Ve…
2016-03-09 10:26:43 +13:00
Gareth McMullin
53d2c74b99 Merge pull request #118 from ziutek/master
nrf51: Another undocumented version.
2016-02-26 14:10:31 +13:00
Michał Derkacz
fbc344c1cd nrf51: Another undocumented version. 2016-02-25 17:43:14 +01:00
Piotr Esden-Tempski
c0c8bade6f [native] Make the native bootloader bit more flashy.
This change has also a practical reason. When flashing and testing the
hardware this change makes it easier to make sure all the LEDs work. Now
when the DFU bootloader is idle it is scanning the LEDs making it easy
to see if one of them has an issue.

In addition to that, the bootloader now indicates when there is data
being flashed using the DFU interface. In cases when one has more than
one device connected and accidently starts flashing a wrong device this
is very useful feature to have.
2016-02-14 23:47:57 -08:00
Piotr Esden-Tempski
b7e5005679 [native] Check for hardware version by pull-up and -down. Print HW Version in mon command.
Until now the native hardware was pulling PB5-7 down and checking if
they were asserted high. BMPMV2b is pulling the pins down instead of
high. The hardware version routine now determines the hardware version
based on the fact if a pin is asserted at all. This means that if a pin
is left floating, the version number bit will be 0, and if the pin is
asserted either high or low the bit will be set to 1. While we were
already at it the "monitor version" command in GDB will now also print
the hardware version number.
2016-02-14 22:49:29 -08:00
Gareth McMullin
ac9d87635c Merge pull request #114 from markrages/master
Add nRF52 support.
2016-02-11 15:49:13 +13:00
Mark Rages
9c846d5029 Add nRF52 support. 2016-02-10 20:23:43 -07:00
Gareth McMullin
d5e263122f Increase JTAG_MAX_DEVS to 32.
Fixes #112
2016-02-02 10:04:57 +13:00
Gareth McMullin
3527880452 Merge pull request #110 from markrages/master
Update nRF51 IDs, add nRF51422 and xxAB/xxAC devices.
2016-01-04 10:39:00 +13:00
Mark Rages
7d957cbfdf Update nRF51 IDs, add nRF51422 and xxAB/xxAC devices.
There were a lot of nRF51 device ids missing. I wrote a script to pull nRF51 IDs from the openocd repository, which seems to be more up-to-date.  The script's output goes in nrf51.c.
2015-12-17 17:50:41 -07:00
Laurent Bonnans
c9d3cf71dd gdb_main.c: fix buffer overflow on large reads
When gdb issues a `m xx,200` command, the probe should respond with a
packet of size 2*0x200=1024 which is the size of the packet buffer.

However, the `hexify()` procedures writes 1025 bytes in the buffer.

During my tests, it caused the probe to hang when issuing a `dump`
command. Presumably by overwritting the `cur_target` variable.
2015-12-14 11:28:28 +01:00
Laurent Bonnans
2d7b24c566 efm32: inhibit srst
EFM32s don't seem to like to be completely resetted while being debugged
(load and break were broken)
2015-12-14 11:28:28 +01:00
Laurent Bonnans
1e5c053f4f flashstub: build efm32.stub with makefile 2015-12-14 11:28:28 +01:00
Laurent Bonnans
ff748e8fa1 flashstub: factor Makefile rules
Use target-specific variables
2015-12-14 11:28:28 +01:00
Clement Burin des Roziers
1f62fa4909 CRC32: improved computation time
Reading one byte at a time was so slow that it caused the gdb client to
timeout.
2015-12-14 11:28:28 +01:00
Gareth McMullin
61c6c767b0 Merge pull request #107 from richardeoin/efm32
[efm32] Use SW-DP IDCODE register for identification
2015-12-13 14:59:49 +13:00
Richard Meadows
544e1080a3 [efm32] Use SW-DP IDCODE register for identification
Instead of the Device ID register which isn't constant for EFM32 parts
2015-12-01 21:41:08 +00:00
Gareth McMullin
e6d388d057 Merge pull request #106 from richardeoin/efm32
Support for Silicon Labs EFM32/EZR32
2015-11-17 07:59:35 -08:00
Richard Meadows
fa7cccff23 [efm32] Formatting fixes 2015-11-14 14:56:03 +00:00
Richard Meadows
b678b83062 [efm32] oops, fixed ezr32lg probe message 2015-11-14 14:42:09 +00:00
Richard Meadows
fe3874bc82 [efm32] add extra details to probe message 2015-11-14 14:41:48 +00:00
Gareth McMullin
091adda0b4 Merge branch 'umetronics-master' 2015-11-11 12:41:57 -08:00
Gareth McMullin
600f0d27d9 Use sniprintf on newlib platforms. 2015-11-11 12:41:13 -08:00
Gareth McMullin
56b10a1255 Merge branch 'f205' of https://github.com/schodet/blackmagic into schodet-f205
Conflicts:
	src/stm32f4.c
2015-11-11 12:27:27 -08:00
Richard Meadows
07f7571dd1 Add basic support for EFM32/EZR32 chips
Tested with EZR32LG230
2015-10-23 19:58:44 +01:00
Antti Nykänen
3f9ea8250a Defined snprintf to sniprintf on launchpad-icdi 2015-10-22 19:33:45 +03:00
Antti Nykänen
2365bbe010 TI TM4C/LM4F cdc-acm fixes 2015-09-30 15:48:01 +03:00
Gareth McMullin
7e5a664df9 Merge pull request #98 from UweBonnes/stm32l4
Add STM32L4 handling. No option write handling yet.
2015-09-01 11:01:36 +12:00
Gareth McMullin
6ec35bc9ff Merge pull request #97 from UweBonnes/stm32f7
Stm32f7
2015-09-01 10:58:57 +12:00
Gareth McMullin
3aa333ee1c Merge pull request #95 from bvanheu/feature/nrf51_new_idcode
Add 0x0072 as a valid & supported idcode for NRF51
2015-09-01 10:30:55 +12:00
Uwe Bonnes
f7492d93be Cortex-M: Detect and handle flash patch revision.
According to ARM v7-M Architecture Reference Manual
ARM DDI 0403E.b (ID120114)
2015-08-22 13:01:24 +02:00
Uwe Bonnes
51e2adc6d9 Add STM32F7. 2015-08-22 13:01:24 +02:00
Uwe Bonnes
043a2d804d flashstub/stm32f4.c: Add barrier needed for STM32F7. 2015-08-22 13:01:24 +02:00
Uwe Bonnes
2336a313e4 Add STM32L4 handling. No option write handling yet. 2015-08-22 12:59:56 +02:00
Nicolas Schodet
97cb75145d Add support for STM32F2xx family
The F405 rev A uses a wrong CPUID, this patch use the core identifier to make
the distinction.

Tested with:
 - F205
 - F405 rev Z
 - F429

Unfortunately, I do not have any F405 rev A.
2015-08-17 14:35:11 +02:00
Gareth McMullin
ef574b72b1 Add support for STM32F446x family.
Tested with a custom hardware.
2015-07-31 09:05:27 -07:00
Gareth McMullin
e4bb1e8c55 Merge pull request #93 from richardeoin/stm_bugfix
[Bugfix] stm32f1_probe would always return true, breaking support for…
2015-07-31 09:02:05 -07:00
Benjamin Vanheuverzwijn
420d2c41c7 Add 0x0072 as a valid & supported idcode for NRF51 2015-07-31 00:00:00 -04:00
Richard Meadows
beacf9c85c Refactor stm32f1_probe 2015-07-30 07:58:55 +01:00
Richard Meadows
101821ae31 [Bugfix] stm32f1_probe would always return true, breaking support for all other targets
The intention of `if (t->driver)` conditional was to test if any of the cases in the preceeding switch/case were met. However t->driver was previously set to point to a default value in cortexm.c:200 and therefore this would always evaluate to true. I've replaced the broken if statement with a duplicate of the switch/case run above.

It looks like this was introduced in 09544bc7101981f2688e0a678138dc4580ea3f76 (PR #92) but 492d6c9cf8f735eea5478c99aee43608549218d7 maybe contributes to the confusion in this instance.
2015-07-12 17:32:48 +01:00
Gareth McMullin
762e54060f Merge pull request #92 from maknoll/master
Fixes #90 flashing of STM32 m0 chips
2015-06-29 19:29:57 -07:00
Nicolas Schodet
b60f5283ae Fix usage of USB_VBUS
USB_VBUS is not an alternate function, it is an additionnal function which is
always enabled.

If configured as an alternate function, it will draw current from VBUS.
2015-06-23 11:51:56 +02:00
Uwe Bonnes
c97d3f0f63 flashstub: Stubs need to run on different targets. Compile for M0. 2015-06-22 16:44:28 +02:00
Uwe Bonnes
a7f6753153 STM32f0: F07 and F09 have 2kiByte blocksize. 2015-06-22 16:44:19 +02:00
Uwe Bonnes
09544bc710 src/stm32f1.c: More verbose FO detection message. 2015-06-22 16:44:08 +02:00
Gareth McMullin
492d6c9cf8 Merge pull request #87 from gsmcmullin/new_flash
Rework flash memory driver interface.
2015-05-19 10:21:55 +12:00
Gareth McMullin
4af5c03d75 lmi: Use registers for stub parameters. 2015-04-21 20:05:41 +12:00
Gareth McMullin
ca17de6243 lpc11xx: Correctly detect LPC8xx devices. 2015-04-11 17:23:01 -07:00
Gareth McMullin
9009ed6581 cortexm: Add target option to inhibit assersion of SRST. 2015-04-11 16:08:59 -07:00
Gareth McMullin
24122aa318 lpc43xx: add chipid for LPC43S37. 2015-04-11 16:08:25 -07:00
Gareth McMullin
09b781f1c1 target: Remove old flash interface. 2015-04-11 16:05:41 -07:00
Gareth McMullin
3d8b34f180 lpc: split out common code and rewrite to use new interface. 2015-04-11 16:05:40 -07:00
Gareth McMullin
cd5d569d38 lpc: Reduce differences between lpc11xx and lpc43xx code. 2015-04-11 16:05:40 -07:00
Gareth McMullin
54eb3a719f samd: use new flash interface. 2015-04-11 16:05:40 -07:00
Gareth McMullin
d340053078 nrf51: use new flash interface. 2015-04-11 16:05:40 -07:00
Gareth McMullin
1541f1c7a8 kinetis: use new flash interface. 2015-04-11 16:05:40 -07:00
Gareth McMullin
9e09ae2e1e lmi: use new flash interface. 2015-04-11 16:05:40 -07:00
Gareth McMullin
622497f7e2 stm32f1: use new flash interface. 2015-04-11 16:05:40 -07:00
Gareth McMullin
7cd3432994 stm32f4: Add second bank for F42x/F43x. 2015-04-11 16:05:40 -07:00
Gareth McMullin
1efad1a03a stm32f4: use new flash interface. 2015-04-11 16:05:40 -07:00
Gareth McMullin
fc2f266a13 sam3x: Update to use new buffered flash interface. 2015-04-11 16:05:40 -07:00
Gareth McMullin
21c209fd8f sam3x: simplify probe function. 2015-04-11 16:05:40 -07:00
Gareth McMullin
3ed4207e8a stm32l0: Update to use new buffered flash writes. Remove old stubs. 2015-04-11 16:05:40 -07:00
Gareth McMullin
45328ea124 Add buffering support for flash drivers.
Some devices can get a significant boost in performance by writing to
flash memories one page at a time.  Generic function to do this are
provided at the target layer and may be used by flash drivers.
2015-04-11 16:05:40 -07:00
Gareth McMullin
36f749fed9 Fix flash buffer alignment in target layer. 2015-04-03 21:21:30 -07:00
Gareth McMullin
7202db5860 Add new functions to wrap flash driver erase/write/done operations. 2015-04-03 21:20:01 -07:00
Gareth McMullin
691d21989a Add function to add simple flash driver to target.
Clean up ram/flash/memory map on target destruction.
2015-04-03 21:18:16 -07:00
Gareth McMullin
0fc635b3f8 Add functions for dynamically generating the XML memory map. 2015-04-03 21:18:16 -07:00
Gareth McMullin
482070c91b Merge branch 'v1.6-branch'
Conflicts:
	src/Makefile
	src/platforms/stlink/platform.h
	src/platforms/swlink/platform.h
2015-04-03 21:02:01 -07:00
Gareth McMullin
97824b7f02 Use git describe for version in generated header file. 2015-04-03 20:21:33 -07:00
Gareth McMullin
865beaba98 Suppress warning about longjmp clobbering local variable. 2015-04-02 21:06:18 -07:00
Gareth McMullin
05f062612b Merge pull request #86 from florolf/atsam3u
sam3x: add SAM3U support
2015-04-01 20:28:37 -07:00
Florian Larysch
bc89217e3f sam3x: add SAM3U support 2015-04-01 00:04:52 +02:00
Gareth McMullin
21d464293c gdb: don't access target fields directly. 2015-03-29 18:06:13 -07:00
Gareth McMullin
c2cde32716 Improve cortexm_read/write_regs. Use more sensible return types. 2015-03-29 17:37:03 -07:00
Gareth McMullin
274b818517 Make cortexm_pc_write static. 2015-03-29 16:48:51 -07:00
Gareth McMullin
779dcf0f69 stm32l0: use cortexm_run_stub. 2015-03-29 16:47:55 -07:00
Gareth McMullin
012922ed00 nrf51: use cortexm_run_stub. 2015-03-29 16:31:38 -07:00
Gareth McMullin
810269dce1 nrf51: Use generated stub. 2015-03-29 16:28:18 -07:00
Gareth McMullin
cac286d398 lmi: Use generated stub with cortexm_run_stub. 2015-03-29 16:20:57 -07:00
Gareth McMullin
2215e33bcf lmi: Clean up magic numbers, remove adiv5 links, and doc ref. 2015-03-29 15:58:18 -07:00
Gareth McMullin
31fae032f7 cortexm: Separate stub loading from running. 2015-03-29 15:20:00 -07:00
Gareth McMullin
9f271d5cd7 Consistently use 'target *t' for target var. 2015-03-28 20:47:17 -07:00
Gareth McMullin
1e54139f4a target: Remove pc_read/pc_write methods. 2015-03-28 20:15:33 -07:00
Gareth McMullin
4313b64bbe Add a flash_done target method. 2015-03-26 20:47:57 -07:00
Gareth McMullin
f74def3552 Remove old STM32L1 driver. 2015-03-26 20:47:57 -07:00
Gareth McMullin
d9af3cca6c Remove unfinished ARM7TDMI driver. 2015-03-26 20:47:57 -07:00
Gareth McMullin
64c79e1d03 Consistently name target var 't' in cortexm. 2015-03-26 20:47:57 -07:00
Gareth McMullin
bda4279028 Send error reply and abandon target list on unhandled timeout. 2015-03-26 20:42:47 -07:00
Gareth McMullin
f5ef8671ab Merge pull request #85 from gsmcmullin/exceptions
Cleaner exception handling.
2015-03-22 20:33:57 -07:00
Gareth McMullin
68f54a3545 Remove old platform specific error handling macros. 2015-03-22 14:06:56 -07:00
Gareth McMullin
5ab8564ff6 Clean up handling of lost targets using new exceptions mechanism. 2015-03-22 14:05:12 -07:00
Gareth McMullin
588bad34ba Build with -Os for swlink. 2015-03-22 12:26:45 -07:00
Gareth McMullin
9a8dbdeff7 Fix errors when building for non-native platforms. 2015-03-22 12:26:45 -07:00
Gareth McMullin
83b83ca48f Use controlled timeout on SW/JTAG DP transactions. 2015-03-22 12:26:45 -07:00
Gareth McMullin
d0a03f55a6 Handle timeout exceptions during scans and report to the user. 2015-03-22 12:26:45 -07:00
Gareth McMullin
d6225eec76 Raise timeout exception when target is in WFI.
Ignore the exception when polling for halt, and report the exception
to the user if halting the target fails.
Remove old allow_timeout flag in DP struct that's no longer needed.
2015-03-22 12:26:45 -07:00
Gareth McMullin
fa046601a5 Add exception handling mechanism and raise exception on low-level comms failure. 2015-03-22 12:26:45 -07:00
Gareth McMullin
a497127a8d Move MIN macro to general.h 2015-03-22 12:23:03 -07:00
Gareth McMullin
c10862bff3 Merge pull request #82 from gsmcmullin/flashstubs
Generalise flash stub calls
2015-03-22 11:42:19 -07:00
Gareth McMullin
12e313dab9 Use for loop in STM32F1 stub and compile with -Os. 2015-03-19 21:49:09 -07:00
Gareth McMullin
41256e3c2a Add missing return type to stub_exit. 2015-03-19 21:49:09 -07:00
Gareth McMullin
acfd258aa7 Rewrite STM32F4 stub in C and use new interface. 2015-03-19 21:49:09 -07:00
Gareth McMullin
8ddb186b35 Allow stub to return an error code. 2015-03-19 21:49:09 -07:00
Gareth McMullin
437aedda11 Rewrote stm32f1 stub in C and call with parameters in registers. 2015-03-19 07:48:57 -07:00
Gareth McMullin
c2462a6788 Add cortexm generic stub call, and use in stm32f1 driver. 2015-03-19 07:48:47 -07:00
Gareth McMullin
e380ced517 Change STM32F1 driver to use generated stub. 2015-03-19 07:43:36 -07:00
Gareth McMullin
2223a1c925 Add a Makefile to build flash stubs. 2015-03-19 07:43:36 -07:00
Gareth McMullin
7372fca2f6 Merge pull request #83 from gsmcmullin/samd_no_ap
samd: Remove low level ADIv5 calls an favour of target_mem_write.
2015-03-18 19:07:03 -07:00
Gareth McMullin
1de685198c Flatten samd_probe. 2015-03-17 21:58:36 -07:00
Gareth McMullin
5c337c9aa7 Whitespace. 2015-03-17 21:58:36 -07:00
Richard Meadows
1366c32f89 samd: Simplified samd_flash_write further by always using manual writes.
Tested on all three devices as listed at the top of samd.c
2015-03-17 21:58:36 -07:00
Gareth McMullin
0bf7778759 samd: Remove low level ADIv5 calls an favour of target_mem_write. 2015-03-17 21:58:36 -07:00
Gareth McMullin
018d9cce80 Check vasprintf return value. 2015-03-17 21:19:02 -07:00
Gareth McMullin
f5f87bf70f Build for stlink with -Os. 2015-03-15 20:39:19 -07:00
Gareth McMullin
c3f798438a Remove abstraction of adiv5_dp_write. Both implementations were identical. 2015-03-15 17:12:31 -07:00
Gareth McMullin
2bf54f9a72 Replace adiv5_ap_mem* functions with inline wrappers to target mem*. 2015-03-15 16:02:09 -07:00
Gareth McMullin
ee3af96a73 Consolidate target_mem_read* and target_mem_write* methods.
There are now only mem_read and mem_write, that must
handle all alignments.  These methods return void, errors must be
checked with target_check_error.
2015-03-15 14:31:57 -07:00
Gareth McMullin
2e785e56fa adiv5: Encode APnDP into register definition.
Clean up magic numbers in adiv5 calls.
Removed old adiv5_dp_write_ap and adiv5_dp_read_ap.
2015-03-14 18:03:04 -07:00
Gareth McMullin
6f5b1873d7 Use size_t for sizes in flash functions. Fix all sign compare warnings. 2015-03-14 15:18:22 -07:00
Gareth McMullin
f5c856af3b Fix pointer sign warnings and remove -Wno-pointer-sign. 2015-03-13 20:35:39 -07:00
Gareth McMullin
f52a51403f stm32l0: cleanup includes. 2015-03-11 20:47:51 -07:00
Gareth McMullin
1196b03d66 stm32l0: Fix pointer/integer casting warnings. 2015-03-11 20:47:51 -07:00
Gareth McMullin
3d28c1418c Cleaned up printf/scanf for C99 integer types. 2015-03-11 20:47:42 -07:00
Gareth McMullin
4baa8aba4f cdcacm: Fix DCD for second ACM interface. 2015-03-11 20:13:38 -07:00
Gareth McMullin
7c1c19881f Reassert DCD after DTR is written. Fixes #41. 2015-03-11 05:45:43 -07:00
Gareth McMullin
f9d484d506 upgrade: Build with -mno-ms-bitfields to fix struct packing on Windows. 2015-03-10 21:58:37 -07:00
Gareth McMullin
2129210bb0 Add .exe and blackmagic_upgrade to .gitignore. 2015-03-08 19:41:42 -07:00
Gareth McMullin
3a746d199f upgrade: Rename target to blackmagic_upgrade and add a rule for .exe file. 2015-03-08 19:39:42 -07:00
Gareth McMullin
0e99f6f11c upgrade: Ignore product strings, these changed over time. 2015-03-08 19:38:59 -07:00
Gareth McMullin
a0f44e01cc uprade: Fix warning on pointer sign. 2015-03-08 19:38:33 -07:00
Gareth McMullin
51f91092e7 Merge pull request #75 from beewoolie/stm32lx-whole
STM32Lx target support.
2015-03-08 16:56:01 -07:00
Marc Singer
bf1cb71eb7 Revisions on Gareth's comments.
o Implemented byte writes to EEPROM now that the emulator has a
  byte-wide target write.
o Added comment describing the reason that mass erase doesn't work.
o Removed all unused code.
o Changed to Linux kernel indent style.
o Changed to Linux kernel function to parenthesis style.
o Stub generation doesn't use Perl, switched to sed.  Also, only
  including the instructions instead of the source and the instructions.
o Handling unaligned destination writes.
2015-03-08 16:25:22 -07:00
Marc Singer
e0a8ce5a88 STM32L0x target support.
Target support for stm32l0's and stm32l1's including option bytes and
data EEPROM.  This module will superceed the previous stm32l1 driver.

o Program flash write and erase.
o Options modification and interpretive status.
o Stubs for program flash writes and erases.  Stubs are modestly
  faster than non-stub version.   The stm32l0 will not execute stubs
  when the MCU has crashed.  A monitor option may be used to force
  non-stub flash writes.
o Stubs generated from C++ code and converted to arrays of half-words.
o Writes to data EEPROM supoprted when loading segments.
o EEPROM data monitor command to write words.
o Stubs supported on stm32l1.
2015-03-08 16:17:34 -07:00
Gareth McMullin
b6d73442cc Removed hardware design files.
They moved to their own repository.
2015-03-07 20:54:55 -08:00
Gareth McMullin
0d99e22a26 Quieten build system. 2015-03-07 11:03:50 -08:00
Gareth McMullin
1eac78b1c8 Move targets to make bin and hex files to toplevel makefile. 2015-03-07 11:03:50 -08:00
Gareth McMullin
2b774102fe Initialise git submodules automatically on make if not done already. 2015-03-07 11:03:50 -08:00
Gareth McMullin
a54e4c831c Merge pull request #81 from dlaw/master
SAM4S: Erase flash in 8K instead of 16K chunks.
2015-03-05 22:30:26 -08:00
David Lawrence
c8f469c868 SAM4S: Erase flash in 8K instead of 16K chunks. 2015-03-05 10:46:22 -05:00
Gareth McMullin
49390fee2a Fix Windows DFU instructions in the Hydrabus readme. 2015-03-04 20:22:19 -08:00
Benjamin Vernoux
9f0c29d329 Add support for HydraBus (tested with SWD with STM32F405 and SWD+JTAG with LPC4330 M0/M4) 2015-03-04 20:22:00 -08:00
Gareth McMullin
c731c6ece3 Make F4 conditionals check STM32F4, not F4DISCOVERY. 2015-03-03 21:39:29 -08:00
Gareth McMullin
2e37db2270 Error on any failure on 'make all_platforms' 2015-03-02 23:14:43 -08:00
Gareth McMullin
87b8f330f0 Add a makefile target to build all platforms. 2015-03-02 22:20:25 -08:00
Gareth McMullin
3e466f2d23 Factor out timing routines common to all STM32 targets. 2015-03-02 21:59:04 -08:00
Gareth McMullin
b07ffffcee Factor out common cdcacm.c from stm32 and tm4c.
Cleaned up interface to enter bootloader and read serial number.
2015-03-02 10:16:33 -08:00
Gareth McMullin
4d4813de87 Clean up includes everywhere.
All source files include general.h first and before anything else.
This inlcludes platform.h and platform_support.h
No header file needs to include to include any of these, but should include
any others needed for it's own declarations.
2015-03-01 22:16:04 -08:00
Gareth McMullin
9d80641261 Move common platform include to a common directory. 2015-03-01 20:15:31 -08:00
Gareth McMullin
476f83b69a Move common USB stuff out of platform header files. 2015-02-28 22:48:26 -08:00
Gareth McMullin
5eff0ab5d6 Factor out common GPIO code in STM32 platforms. 2015-02-28 22:09:50 -08:00
Gareth McMullin
48fb7ec662 Add missing includes to fix warnings. 2015-02-28 22:06:10 -08:00
Gareth McMullin
75001a4421 Factor Morse code functions out of platform code. 2015-02-28 22:05:10 -08:00
Gareth McMullin
5d136398e1 Use sensible return convention for platform_target_get_power() 2015-02-28 21:23:24 -08:00
Gareth McMullin
1b2cd547bc Merge pull request #72 from dlaw/master
Add support for SAM4 erase command
2015-01-26 10:59:32 +13:00
Gareth McMullin
1552218e8f Merge pull request #71 from maknoll/master
SAM3S support
2015-01-26 10:56:52 +13:00
Gareth McMullin
8b01a0aa0c Merge pull request #70 from richardeoin/samd
Added support for SAMD10/11/21 and SAMD Security Bit
2015-01-26 10:54:22 +13:00
David Lawrence
b771d0dcd6 Add support for SAM4 erase command 2015-01-23 16:36:12 -05:00
Martin Knoll
a7283196d1 SAM3S support 2015-01-22 16:09:01 +01:00
Richard Meadows
ea78e2d737 Complete refactor of samd20 -> samd 2015-01-18 22:40:02 +00:00
Richard Meadows
565795e168 Added support for SAMD10/11/21, and list of tested SAM D devices
This allows blackmagic to be used with the new Arduino Zero board via
the unpopulated SWD header on the east end of the board.
2015-01-18 22:35:59 +00:00
Richard Meadows
3726061773 Support for the NVMCTRL Security Bit (PROT=1) 2015-01-18 20:46:26 +00:00
Richard Meadows
e75ea64a01 Renamed nvmc control a register to match datasheet 2015-01-18 14:11:58 +00:00
Richard Meadows
1c1312b467 Added better feedback for samd erase failures 2015-01-18 13:22:41 +00:00
Gareth McMullin
a3ab9b24d1 Avoid repetition of cortexm code in stmd20 driver. 2015-01-18 12:16:17 +13:00
Gareth McMullin
f1981925b3 Merge branch 'samd20-revb-fix' of https://github.com/richardeoin/blackmagic into richardeoin-samd20-revb-fix 2015-01-18 11:03:10 +13:00
Gareth McMullin
94c3b2b3d3 Merge pull request #68 from richardeoin/vrun-check-attach
Check target_attach succeeded in vRun command, and return error if not
2015-01-18 11:01:11 +13:00
Richard Meadows
cad30cfa39 Fixed run command on SAM D20 old revision B silicon.
This appears to be related to Atmel Errata Reference 12015 (see §
35.4.1 DSU in the datasheet) but only applies to revision B silicon -
not revision C. While this is an old silicion revision (latest is
revision E as of 17 Jan 2015) I found one on a development board.
2015-01-17 18:58:00 +00:00
Richard Meadows
9072faf6ca Fixed spaces / tabs from last commit 2015-01-17 18:35:36 +00:00
Richard Meadows
c12002b636 Check target_attach succeeded in vRun command, and return error if not 2015-01-17 18:30:58 +00:00
Gareth McMullin
abcc04d4f3 Merge pull request #63 from beewoolie/static-stubs
Fix to move stubs into rodata.
2015-01-17 13:18:20 +13:00
Gareth McMullin
4e2c99a65b Merge pull request #66 from dlaw/master
SAM4S support
2015-01-17 13:03:35 +13:00
David Lawrence
985627af7e SAM4S support 2015-01-12 14:53:58 -05:00
Marc Singer
da28970c3e Fix to move stubs into rodata.
o Stubs were declared as globals which means they will be initialized
  data.  No need for this.  Now, stubs are static const and are only
  present in the program image.
2015-01-09 18:18:10 -08:00
Gareth McMullin
9c5ffd61f7 First cut at Freescale Kinetis support. 2015-01-06 22:26:00 +13:00
Uwe Bonnes
d162e75ceb stm32f4.c: Add STM32F411 ID. 2014-12-23 21:32:21 +13:00
Gareth McMullin
fdd7799304 Merge pull request #60 from themadinventor/lp-icdi-clean
Added (preliminary) support for TI TM4C123 Launchpad
2014-12-23 21:31:43 +13:00
Gareth McMullin
9c78e26c1d Merge pull request #59 from zyp/add_halfwords
Add support for halfword memory accesses.
2014-12-23 21:17:32 +13:00
Fredrik Ahlberg
346258934b Added support for TI TM4C123 Launchpad 2014-11-23 22:59:16 +01:00
Vegard Storheil Eriksen
9434299613 Add support for halfword memory accesses. 2014-10-21 00:12:50 +02:00
Gareth McMullin
fd9eef821e Revert USB double buffered OUT handling on STM32F1.
This introduced a bug where the endpoint can get stuck, forever sending NAK.
2014-10-16 13:50:56 -07:00
Gareth McMullin
f85a8c4ebb Fix build for f4discovery by defining platform_hwversion(). 2014-10-16 13:50:56 -07:00
Gareth McMullin
a5549d630c Whitespace cleanup. 2014-10-16 13:50:56 -07:00
Gareth McMullin
60626e5bbe Merge pull request #57 from aibara/dev/lpc43xx_wdt
LPC43XX: Attempt to handle case of running WDT.
2014-09-17 10:14:21 +12:00
Allen Ibara
c5abc9a0bd LPC43XX: Attempt to handle case of running WDT.
If the WDT is running, it may reset while we are trying to flash.
Since we can't disable it, we set a long period and attempt to pet it
before each IAP call.
2014-09-16 14:54:24 -07:00
Gareth McMullin
9fda010b32 Give up unwinding a fault if reading the stack fails. 2014-09-12 12:24:43 +12:00
Richard Eoin Meadows
091389b982 SAMD20 prints die revision 2014-09-03 21:17:48 +12:00
Richard Eoin Meadows
f4e20d0d04 Ooops - Semicolon from last commit :-) 2014-09-03 21:17:48 +12:00
Richard Eoin Meadows
f4474557d0 SAM D20 MBIST shouldn't fail silently 2014-09-03 21:17:48 +12:00
Richard Eoin Meadows
39a0b064af Use external access DSU range 2014-09-03 21:17:48 +12:00
Richard Eoin Meadows
2a444ab1fb Fixed SAM D20 support with reset attached.
monitor connect_srst enable can be used to connect to targets that re-use the SWCLK pin
2014-09-03 21:17:48 +12:00
Richard Eoin Meadows
e75798f201 Optimised flash write, programming speed is now approx. 2x faster 2014-09-03 21:17:48 +12:00
Richard Eoin Meadows
02812b6bf1 Added notes about the datasheet and NVMCTRL Security Bit 2014-09-03 21:17:41 +12:00
Richard Eoin Meadows
945a2802d5 Atmel SAMD20 support 2014-09-03 21:17:41 +12:00
Gareth McMullin
9d9ecb572e Assert SRST when scanning JTAG if configured. Closes #54. 2014-08-27 19:03:37 +12:00
Gareth McMullin
8a32b46f65 Fix build for non-native targets. 2014-08-08 20:22:33 +12:00
Gareth McMullin
84fc40085e Send a null packet on end of USB transfer if last data packet is full. 2014-08-06 12:38:57 +12:00
Hans Baier
d265b76001 Add support for STM32F401RE 2014-08-06 10:49:48 +12:00
Gareth McMullin
9b0c4ca51a Replace README and HACKING with references to the Github wiki. 2014-08-01 21:00:25 +12:00
Gareth McMullin
d7c30caa3e Style clean up. 2014-07-30 21:15:43 +12:00
Gareth McMullin
f06bc0fd79 Minor fixes to stm32f1 flash routines. 2014-07-30 20:27:30 +12:00
Gareth McMullin
fad6eb3c14 Fix parity support on USB UART interface. 2014-07-30 19:57:18 +12:00
Gareth McMullin
2b61bed291 Merge branch 'nrf51-uicr' of https://github.com/richardeoin/blackmagic into richardeoin-nrf51-uicr
Conflicts:
	src/nrf51.c
2014-07-30 16:55:02 +12:00
Gareth McMullin
4447fb428a Merge pull request #50 from richardeoin/nrf51-ficr
Added monitor commands for reading various nRF51 device parameters
2014-07-30 16:51:46 +12:00
Gareth McMullin
936b7460e0 Merge branch 'John-Titor-lpc11xx-flash' 2014-07-30 16:48:56 +12:00
Gareth McMullin
3daf5d7e11 Merge branch 'lpc11xx-flash' of https://github.com/John-Titor/blackmagic into John-Titor-lpc11xx-flash
Conflicts:
	src/lpc11xx.c
2014-07-30 16:45:55 +12:00
Gareth McMullin
bfe5d1168b Merge pull request #47 from richardeoin/target-power
Added monitor option to toggle target power
2014-07-30 14:19:46 +12:00
Gareth McMullin
7e396b0205 Merge pull request #30 from BuFran/pulls/l152c
[SUP] Add support for stm32l152c-discovery board
2014-07-30 14:17:51 +12:00
Gareth McMullin
5d61575ce6 Merge remote-tracking branch 'origin/lpc8xx'
Conflicts:
	src/lpc11xx.c
2014-07-30 14:11:10 +12:00
Gareth McMullin
cb1b1670d1 Merge pull request #45 from richardeoin/fatal-fix
Fixed potential Hardfault in platform_init
2014-07-30 13:56:12 +12:00
Frantisek Burian
88a80e25d5 [SUP] Add support for stm32l152c-discovery board 2014-07-09 16:35:33 +02:00
Richard Eoin Meadows
7dc18768c4 Support erasing + flashing the User Information Configuration Registers (UICRs) 2014-06-11 13:43:59 +01:00
Richard Eoin Meadows
380f128d0a Added monitor commands for reading various nRF51 device parameters 2014-06-11 13:39:06 +01:00
none
3543e560af Fix lpc11xx magic number programming when chunks overlap
In the case where the vectors are in a separate section smaller than
the chunksize, the lpc11xx magic number calculation could generate an
incorrect value.
2014-06-10 21:23:17 -07:00
Richard Eoin Meadows
c1b1d45155 TRST only exists on hardware version 0 2014-05-28 12:45:21 +01:00
Richard Eoin Meadows
42e41edfa1 Target power option is only for versions > 0 2014-05-28 12:33:43 +01:00
Richard Eoin Meadows
c9089f5851 Added monitor option to toggle target power 2014-05-28 12:25:48 +01:00
Richard Eoin Meadows
63bce97cbd PLATFORM_FATAL_ERRORs are now caught even when they happen in the
initial JTAG scan that occours during platform_init.

Previously any fatal errors that occoured during this scan caused a
hardfault.
2014-05-28 12:10:26 +01:00
Gareth McMullin
72ae78a185 Updated libopencm3. Fixes broken bootloader, issue #43. 2014-05-08 11:02:35 -07:00
Gareth McMullin
8ba0265383 Merge pull request #44 from miek/nrf51
Nordic nRF51 series support
2014-05-01 15:43:59 -07:00
Mike
34d0f64529 Nordic nRF51 series support 2014-05-01 15:09:59 +01:00
Gareth McMullin
3077472620 Unwind hardfaults in dual-stack mode. 2014-03-31 20:58:06 +13:00
Jared Boone
096e1b32c6 Add support for LPC11U14 (tested) and related U-series microcontrollers (untested). 2014-03-08 19:07:50 +13:00
Gareth McMullin
cbb85b6a45 LPC812 support 2014-03-08 18:58:39 +13:00
Frantisek Burian
12aeaad441 [locm3] Use the new clock-enabling mechanisms in locm3. 2014-02-13 18:21:16 +01:00
Frantisek Burian
690e99c6b2 Fix the STK_CTRL to the STK_CSR library change. 2014-02-13 17:52:09 +01:00
Richard Eoin Meadows
e5624a7e6d Added support for the LPC1115FBD48/303 (ID determined experimentally) 2014-01-29 08:02:04 +08:00
bon@elektron.ikp.physik.tu-darmstadt.de
d27c50c601 Add STM32F03X and STM32F07X handling. 2014-01-24 05:03:38 +08:00
bon@elektron.ikp.physik.tu-darmstadt.de
0c9d5d8166 Add dfu bootloader update application and use absolute delay for stlink
Hello,

appended 3 patches
- adds a dfu-bootloader appliaction
- uses absolute delays when waiting for pull-up delays on the STLINK
(hopefully fixes issue #30)

Updating the dfu-bootloader by additional application is helpfull for the
STLINK, as for flashing the bootloader by SWDb otherwise jumpers need to be
soldered or external SWD is not possible.
Use like:
- dfu-util -s 0x08002000:leave -D dfu_upgrade.bin
- dfu-util -s 0x08000000:leave -D blackmagic_dfu.bin
- Push reset buttom and reconnect to enter new dfu bootloader
- dfu-util -s 0x08002000:leave -D blackmagic.bin
--
Uwe Bonnes                bon@elektron.ikp.physik.tu-darmstadt.de

Institut fuer Kernphysik  Schlossgartenstrasse 9  64289 Darmstadt
--------- Tel. 06151 162516 -------- Fax. 06151 164321 ----------
>From fae5022c304a8866f056ea66660ac7ce3809dcf8 Mon Sep 17 00:00:00 2001
From: Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de>
Date: Sun, 20 Oct 2013 15:00:36 +0200
Subject: F1: Prepare to update dfu bootloader via DFU with additional
 application.
2014-01-24 04:59:09 +08:00
Gareth McMullin
ac0fc8216a Merge pull request #35 from burgrp/upstream
Fix in checksum calculation condition
2014-01-23 10:52:09 -08:00
Gareth McMullin
eb2f2afa9a Merge pull request #32 from aibara/lpc43xx_updates
Lpc43xx target support updates
2014-01-23 10:51:46 -08:00
Gareth McMullin
a7fd985cfc Merge pull request #31 from BuFran/pulls/libopencm3_update
Update to the newest libopencm3
2014-01-23 10:51:09 -08:00
Pavel Burgr
ce17cc2e2b Fix in checksum calculation condition 2014-01-22 10:35:35 +01:00
Allen Ibara
01244fc84d LPC43XX: Force target to use internal clock.
Without this, flash write timing might be incorrect.
2014-01-10 13:24:25 -08:00
Allen Ibara
2b798fa8fc LPC43XX: Make the chunk_offset logic more explicit. 2014-01-10 13:24:25 -08:00
Allen Ibara
487252150f LPC: Cleanup regs_size (in bytes).
Also use sizeof() to make it clear why we multiple and divide by 4.
2014-01-10 13:24:25 -08:00
Allen Ibara
df9c19f071 LPC43XX: Remove type cast for erase function 2014-01-10 13:24:25 -08:00
Allen Ibara
911af3b836 LPC43XX: Add reset command to do a system reset (but not the debug). 2014-01-10 13:24:25 -08:00
Allen Ibara
813622b1b6 LPC43XX: Add mkboot target command; dont make banks bootable by default.
This used to be done transparently in the write step, however that
breaks the 'verify' command. This is also more flexible for cases
where you want to write a flash bank without ever intending it to
be bootable.
2014-01-10 13:24:25 -08:00
Allen Ibara
29c7846612 LPC43XX: Make sure to align target struct to word alignment 2014-01-10 13:24:25 -08:00
Frantisek Burian
8014d434de Update to the newest libopencm3 2014-01-04 17:29:54 +01:00
Gareth McMullin
8835df1822 Merge remote-tracking branch 'origin/usbuart_highrate' 2013-12-04 16:16:08 +13:00
Gareth McMullin
42570efaf8 Revert "STM32F4: Add handling of second bank and dual boot devices."
This reverts commit 536482f8047f1ee984f362c5c5e3fe488353a1b7.
2013-10-22 07:48:06 +08:00
Uwe Bonnes
09fbe783c5 f4discovery: Limit clock to 48 MHz and stack 24 kiByte so that code can be compiled unchanged for F401Discovery too.
TODO: Bump clk up to 84 MHz as soon as libopencm3 supports that speed.
2013-10-22 07:26:35 +08:00
Uwe Bonnes
536482f804 STM32F4: Add handling of second bank and dual boot devices. 2013-10-22 07:21:35 +08:00
Uwe Bonnes
cbd73cfb8f STM32F4: Recognize F401. 2013-10-22 07:21:35 +08:00
Uwe Bonnes
5aa802969b stlink: Give the NRST check more time as otherwise some L1 discovery board stayed in the bootloader. 2013-10-22 07:18:09 +08:00
Uwe Bonnes
086f3565f0 stm32f1: Fix handling of option byte write. Write needs to happend on erased option bytes. 2013-10-20 16:14:25 +02:00
Uwe Bonnes
15e529a43a stm32f1.c: On a read protected device, deny any other option action than erase.
Otherwise the first option action triggers an error, inhibiting further option
actions.
2013-10-20 16:14:19 +02:00
Michael Tharp
c395c6f73a Configure SRST output as open-drain for BMP Mini hardware 2013-10-05 13:14:03 +08:00
Benno Leslie
3cce6f472c Add support for the SYS_WRITEC semihosting operation.
This is implemented in the same manner as QEMU semihosting
support, specifically, a SYS_WRITEC results in a single
character write to STDERR.
2013-10-05 13:14:03 +08:00
Richard Eoin Meadows
b8f9a2ed4b Bugfix: Always apply the vector table magic number correctly.
Previously when the flash write length was less than the Chunk size the 2nd chunk write would re-calculate and apply an incorrect magic number
2013-10-05 13:14:03 +08:00
Marc Singer
40820a2354 Added internal pull-up to PWR_BR.
o Prevent probe from inadvertently powering target.  If PWR_BR is
  allowed to float, the gate on Q1 (blackmagic_mini) will tend to be
  close enough to zero to turn the transistor on.  We activate the
  internal pull-up on this IO pin to force the transistor off.
2013-10-05 13:14:03 +08:00
Gareth McMullin
e5d253bf81 Merge pull request #24 from richardeoin/master
New contrib board
2013-10-04 21:33:39 -07:00
BuFran
e67192348f FIX: usbd_init compatibility fix
Updated compatibility with libopencm3 commit 113e5c22e6390ba072148315e83a5faa5ff7ce86
2013-10-05 12:23:23 +08:00
BuFran
c857165c12 FIX: FLASH_* collision with libopencm3 definitions
Resolve collision to FLASH_* from the libopencm3 by adding STM32F1_ prefix to the L1's
2013-10-05 12:23:23 +08:00
BuFran
c28350f242 FIX: u{8,16,32} -> uint{8,16,32}_t to be compatible with new library
The use of u8, u16, u32 has been deprecated in libopencm3.
Update it with standard uint8_t, uint16_t, uint32_t types
2013-10-05 12:23:23 +08:00
BuFran
f1584b266b [BUILD] Don't throw error on already cleaned output 2013-10-05 12:23:23 +08:00
BuFran
78464c8562 [LIB] Updated to newest libopencm3 2013-10-05 12:23:23 +08:00
Richard Eoin Meadows
e5e67e5740 Made assembly notes titles 2013-09-04 22:07:08 +01:00
Richard Eoin Meadows
c04ccf3ccc Tided up README, added note about board being proven 2013-09-04 22:05:14 +01:00
Richard Eoin Meadows
ead74c272a Added assembly descriptions 2013-09-04 21:11:32 +01:00
Richard Eoin Meadows
ac2bc70edc Fixed Assembly photo 2013-09-04 21:03:37 +01:00
Richard Eoin Meadows
523dbb5df9 Added photos 2013-09-04 21:01:42 +01:00
Richard Eoin Meadows
28dca4702a Added more description about the BOOT0 pin 2013-09-04 20:46:48 +01:00
Richard Eoin Meadows
1ca1c6c470 Added assembly photos 2013-09-04 20:28:22 +01:00
Richard Eoin Meadows
3ebec5609f Made all the board layers visible 2013-09-04 20:28:06 +01:00
Richard Eoin Meadows
bcea91a825 Renamed schematic PDF 2013-09-04 20:22:20 +01:00
Richard Eoin Meadows
af3f20a218 Fixed line endings in README 2013-08-19 15:41:31 +01:00
Richard Eoin Meadows
be5e9b1ff8 Spelling error! 2013-08-19 15:38:23 +01:00
Richard Eoin Meadows
682138e321 Added pdf of schematic 2013-08-19 15:37:36 +01:00
Richard Eoin Meadows
4567011603 Fixed relative link in README 2013-08-19 15:36:13 +01:00
Richard Eoin Meadows
7a6879c93d Removed mouse cursor from board image! 2013-08-19 15:34:18 +01:00
Richard Eoin Meadows
3735f263f3 Fixed image in README 2013-08-19 15:32:52 +01:00
Richard Eoin Meadows
3828bae844 Added image to README 2013-08-19 15:31:44 +01:00
Richard Eoin Meadows
73139a77b7 Fixed up README 2013-08-19 15:21:36 +01:00
Richard Eoin Meadows
7e7ebfc2be Wrote README text 2013-08-19 15:20:23 +01:00
Richard Eoin Meadows
2f59e9f3a3 Added switch on BOOT0 2013-08-19 15:04:56 +01:00
Richard Eoin Meadows
2480162c07 Changed text on the end of the board to "ARM Cortex Debug" 2013-08-19 14:26:39 +01:00
Richard Eoin Meadows
80c215627d Added links to parts list 2013-08-19 13:45:31 +01:00
Richard Eoin Meadows
1042246ee6 Fixed final list of parts list 2013-08-19 13:30:36 +01:00
Richard Eoin Meadows
e8a423972f Completed parts list 2013-08-19 13:24:03 +01:00
Richard Eoin Meadows
168a15e3ae Completed board layout 2013-08-19 12:49:54 +01:00
Richard Eoin Meadows
b3dedacbf5 Schematic provisionally complete 2013-08-19 10:41:14 +01:00
Gareth McMullin
700833f38f Use do {...} while(0) for PLATFORM_FATAL_ERROR() macro. 2013-08-19 12:27:36 +12:00
Gareth McMullin
fce43bcd98 Fixed upgrade tool to build against current libusb-win32. 2013-08-19 12:26:05 +12:00
Richard Eoin Meadows
3f6937affa Attempt to fix table 2013-08-18 22:38:52 +01:00
Richard Eoin Meadows
de22b4577d Added LEDs 2013-08-18 22:35:49 +01:00
Richard Eoin Meadows
2ac5ea1fe2 Major components added to parts list 2013-08-18 22:19:26 +01:00
Richard Eoin Meadows
f0d112c688 Majority of Components in place 2013-08-18 22:19:13 +01:00
Richard Eoin Meadows
32988b3927 Added blank parts list 2013-08-18 20:39:05 +01:00
Richard Eoin Meadows
f00c07a39f Added EAGLE temporary files to .gitignore 2013-08-18 20:38:53 +01:00
Richard Eoin Meadows
fa0d398feb Added new contrib hardware folder including README 2013-08-18 20:38:04 +01:00
Gareth McMullin
a30ef31018 Handle SW-DP fault on WDATAERR. 2013-06-19 21:06:59 +12:00
Gareth McMullin
d8f737fc53 Disable ADIv5 timeout while target is running. 2013-06-19 21:05:53 +12:00
Paul Fertser
d90e10cdba adiv5_swdp: avoid dead-loop with a sleeping target
A sleeping target continues to communicate over SWD properly but
consistently returns SWDP_ACK_WAIT.

It might be nice to be able to wait for the target to wake up on its
own but if it's not going to wake up, BMP becomes absolutely
unresponsive. Probably the timeout should be made configurable or some
other workaround invented.

Signed-off-by: Paul Fertser <fercerpav@gmail.com>
2013-06-19 19:28:16 +12:00
Gareth McMullin
27a86e244f native: Enable hard SRST signal. 2013-06-19 19:21:49 +12:00
Gareth McMullin
ccb20b4420 hardware: Correct micro part number to STM32F103CB. 2013-06-18 12:35:26 +12:00
Gareth McMullin
c05b7a1f63 Rename lpc11xx driver. 2013-06-17 16:06:03 +12:00
Gareth McMullin
3caaa28fa1 Fix warning about implicit cast. 2013-06-17 15:57:13 +12:00
Gareth McMullin
8c877d6dfa Fix trailing whitespace everywhere. 2013-06-17 15:53:32 +12:00
Gareth McMullin
2d63dd4b5b Fix register array sizes. 2013-06-17 15:52:15 +12:00
Paul Fertser
df32aad757 semihosting: improve handling of console I/O
This implements special handling for SYS_OPEN to catch requests for
":tt" which is reserved by ARM for console input/output. They're
mapped to the appropriate GDB file descriptors automatically.

An additional file handle offset is introduced because ARM doesn't
consider zero handle to be valid.

Signed-off-by: Paul Fertser <fercerpav@gmail.com>
2013-05-18 15:33:58 +12:00
Gareth McMullin
5020d1f05d Move semihosting support to cortexm.c.
Try to implement more syscalls.
2013-05-18 15:33:58 +12:00
Paul Fertser
aca421d0bb Basic semihosting support
Implement bare minimum necessary to support console IO.

This works with standard newlib builds and is based on the reference
documentation:
http://infocenter.arm.com/help/topic/com.arm.doc.dui0471c/CHDJHHDI.html

Tested using gcc-arm-none-eabi-4_7-2013q1-20130313 for both
stm32f1-based BMP and stm32f0 target.

Signed-off-by: Paul Fertser <fercerpav@gmail.com>
2013-05-18 15:33:58 +12:00
Gareth McMullin
feaf626673 Add support for Atmel SAM3N devices. 2013-05-18 15:32:06 +12:00
Paul Fertser
cdaed128c1 stlink: add support for SRST handling
This enables SRST signals in open drain mode for both stlinkv1 and
stlinkv2 hardware platforms.

Signed-off-by: Paul Fertser <fercerpav@gmail.com>
2013-05-14 12:34:53 +12:00
Paul Fertser
e0fc21a2a7 adiv5_swdp: allow to connect to a sleeping target by pulling SRST
This patch introduces a new command, "connect_srst [enable|disable]"
which allows to enable special mode in which SRST would be pulled low
before the SWD scan till attaching to a target.

Since on Cortex-Mx the SRST signal doesn't gate JTAG and SWD, it's
possible to connect to a target while holding reset, ask it to stop at
reset vector and only then deassert reset, thus allowing to attach to
the kind of firmware that goes immediately to sleep or disables
debugging by other means early on start.

Tested on an STM32VLDiscovery board with STM32F100 configured to go to
STOP mode and executing WFI in the very beginning of main().

Signed-off-by: Paul Fertser <fercerpav@gmail.com>
2013-05-14 12:32:44 +12:00
Allen Ibara
510d1c0dc8 Add support for burning flash on lpc4337. 2013-05-14 12:25:13 +12:00
Gareth McMullin
4065169caf Merge pull request #21 from fnoble/master
Python scripts shebang
2013-05-02 11:36:39 -07:00
Fergus Noble
7c3c9fdea3 Update python scripts to find user's preferred python binary through env. 2013-05-02 11:32:24 -07:00
Gareth McMullin
56f44c39d9 nxp: support the lpc1114dip28 by Rickta59 2013-04-27 20:57:20 -07:00
Gareth McMullin
e3f3171a33 usbuart: Fix build error and clean up whitespace. 2013-04-27 13:14:22 -07:00
Allen Ibara
43f7e7a3cf Changes to the USBUART to make it less likely to drop characters at higher baud rates.
USB UART seems to work fine at 115.2Kbps or 230.4Kbps, but starts to drop characters
as the data rate goes higher. This commit changes the usbuart ISR to fill a software
FIFO, and adds a low priority timer interrupt to run deferred processing to drain a
FIFO and send USB CDCACM packets, rather than calling the usb send within the UART
ISR.

Tested on native platform, up to 1.5MBps.
2013-04-27 12:56:58 -07:00
Uwe Bonnes
f1ea5ed8f9 F4Discovery: Slow Down GPIO access a little, as off-board SWD otherwise needs _very_ good ground connection. 2013-04-23 13:43:43 -07:00
Uwe Bonnes
ad151fdca8 F4 Discovery: - Unconditionally use the System Bootloader - Use PC2/4/5/6 Pins for JTAG/SWD to avoid collision with eventual STLink Uart connection - Indicate Bootloader with blue LED 2013-04-23 12:14:18 -07:00
Gareth McMullin
6659d87e9b Remove DFU bootloader self protection.
It can still be enabled by building with -DDFU_SELF_PROTECT
2013-04-16 16:54:52 -07:00
Gareth McMullin
126df7bb35 Allow extra LDFLAGS on command line. Use nano.specs for swlink. 2013-04-16 16:47:38 -07:00
Gareth McMullin
45e02360b7 native: Fix up deprecated warnings. 2013-04-16 12:47:29 -07:00
Gareth McMullin
89b908337d Add missing #includes 2013-04-16 12:36:19 -07:00
Gareth McMullin
67a96410e3 libftdi: Clean up warnings. 2013-04-16 12:33:28 -07:00
Gareth McMullin
da448ec1a6 libftdi: Add 'flossjtag' cable. 2013-04-16 12:14:37 -07:00
Uwe Bonnes
6b7babf624 stm32f4: Add option erase command
--
Uwe Bonnes                bon@elektron.ikp.physik.tu-darmstadt.de

Institut fuer Kernphysik  Schlossgartenstrasse 9  64289 Darmstadt
--------- Tel. 06151 162516 -------- Fax. 06151 164321 ----------
>From d488dffe4dab4e5188c750489006260745a9e25a Mon Sep 17 00:00:00 2001
From: Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de>
Date: Mon, 15 Apr 2013 15:26:58 +0200
Subject: stm32f4: Add option erase command
2013-04-15 10:22:17 -07:00
Paul Fertser
9c95f039cf Make code compatible with newlib-nano and use it for stlink
With gcc-arm-none-eabi-4_7-2013q1-20130313 and -O2 I get
   text    data     bss     dec     hex filename
  45744     304    2376   48424    bd28 blackmagic

With -Os the results are even more impressive:
   text    data     bss     dec     hex filename
  37900     304    2376   40580    9e84 blackmagic

Since -Os might lower the debugging speed, do not enable it yet in the
absence of real measurements.

Signed-off-by: Paul Fertser <fercerpav@gmail.com>
2013-04-14 11:48:59 -07:00
Paul Fertser
91b481731d stm32f1/stm32f4: fix hardware CRC calculation
This was real-life tested on stm32f1 hardware including computation
for odd-sized ranges.

Signed-off-by: Paul Fertser <fercerpav@gmail.com>
2013-04-14 11:35:23 -07:00
Gareth McMullin
7db6e3e00c Revert "Revert "STM32: Use hardware CRC unit""
This reverts commit 58abbf7fc7686a16ee5bdfacb1241a5adf2921ea.
2013-04-14 11:28:46 -07:00
Gareth McMullin
58abbf7fc7 Revert "STM32: Use hardware CRC unit"
This reverts commit 32b909067b2a34f475a52585b965c195de87c172.

This CRC routine doesn't work.  The bit order used by the
STM32 CRC unit is reveresed from what GDB uses.
2013-04-04 21:37:51 -07:00
Gareth McMullin
61d464bf09 dfu: Fix warnings. 2013-04-04 20:16:13 -07:00
Gareth McMullin
d4411fc51f Removed verison info from USB strings on native platform. 2013-03-31 12:18:11 -07:00
Gareth McMullin
3a70b81cce Add erase_mass command for stm32f4 devices. 2013-03-27 14:10:07 -07:00
Gareth McMullin
d7a6f0165e Accept new chip ID for stm32f4 and include flash layout for 2MiB parts.
Thanks to Mike Smith.
2013-03-27 11:24:43 -07:00
Eric Brombaugh
46898a71ce Modified BMP Mini with extra connectors 2013-03-17 15:03:20 -07:00
Gareth McMullin
2465846c0d Updated project README. 2013-03-17 10:33:19 +13:00
Gareth McMullin
44a03f31e1 Moved entropia design to contrib directory and added description. 2013-03-17 10:27:53 +13:00
Florian Larysch
6fb73e0a86 Add a version of BMP-mini optimized for manual production
This commit adds a variant of the Blackmagic Mini that uses only 0603
parts and standard connectors for better availability and easier manual
soldering.

Additionally, another voltage regulator has been used that is
cheaper, pin-compatible and has better characteristics.
2013-03-17 10:24:02 +13:00
Gareth McMullin
87dad080e1 Fix build for f4discovery host. 2013-03-17 10:17:05 +13:00
Gareth McMullin
931cd97f15 Removed stm32_can and usps_f407 platforms. 2013-03-15 20:50:55 +13:00
Uwe Bonnes
486c5de013 swlink: Add missing item to connector layout 2013-03-14 22:56:31 +01:00
Uwe Bonnes
920ced062e SWLINK: Add variant for the STM8S Discovery board 2013-03-12 12:24:10 +01:00
Gareth McMullin
e880c553fb Restore trace timer interrupt handler. 2013-03-12 19:14:11 +13:00
Gareth McMullin
7c2e994381 Split out platform specific bootloader parts to separate files. 2013-03-12 19:04:10 +13:00
Gareth McMullin
55f161208d Further split-up of DFU bootloader. 2013-03-12 15:00:15 +13:00
Gareth McMullin
14e5e8b0b6 Separated clean and dirty bootloader sections. 2013-03-12 09:57:28 +13:00
Gareth McMullin
7b10270007 Merge pull request #16 from zyp/master
Fix for broken USB flow control.
2013-03-08 15:18:12 -08:00
Vegard Storheil Eriksen
e8f9d52d2f gdb_if: Fix USB flow control.
The introduction of the double buffering broke USB flow control, causing
loss of data when a new packet arrived with the previous still present in
the double buffer.

With this patch the endpoint is kept in NAK until the double buffer is empty.
2013-03-06 20:36:49 +01:00
Gareth McMullin
530ee15153 Correct upload script for detection of F1/F4 start address. 2013-02-20 10:55:52 +13:00
Gareth McMullin
d5be7b7a50 Merge pull request #11 from aibara/master
Another small fix for adiv5, ap_mem_write_bytes double increment analogous to previous fix for ap_mem_read_bytes
2013-02-18 00:51:45 -08:00
Gareth McMullin
99ac73907f Merge pull request #9 from jeffstaley/master
Bug fixes for lpc11xx code
2013-02-18 00:50:50 -08:00
Gareth McMullin
acda4bd46c Merge pull request #12 from UweBonnes/master
Make adaption to different STM32 boards easier
2013-02-18 00:49:35 -08:00
Uwe Bonnes
ff8de39774 usbuart: Don't try to send until configured. Enumeration may hang else 2013-02-15 17:55:36 +01:00
Uwe Bonnes
dee82a0d4f Document changes between ST-Link V1 and V2 and implement needed changes 2013-02-15 17:39:27 +01:00
Uwe Bonnes
f8ea954275 STLINK: Add pointer to Discoveryboard modification instructions 2013-02-11 19:36:22 +01:00
Uwe Bonnes
71871b6bfd Merge remote-tracking branch 'upstream/master'
Conflicts:
	src/platforms/stlink/cdcacm.c
	src/platforms/stlink/platform.c
	src/platforms/stlink/platform.h
2013-02-07 12:09:51 +01:00
Uwe Bonnes
327ee49a67 usps_f407: add another platform 2013-02-03 14:22:14 +01:00
Uwe Bonnes
31f39339fd stm32/usbdfu.c: Rearrange code to clarify the tasks to be done 2013-02-03 14:14:48 +01:00
Allen Ibara
4d6ae0a1b2 Avoid double increment of dst in adiv5 write bytes function. 2013-01-31 13:39:41 -08:00
Uwe Bonnes
b1a942aca3 STM32F0/3: Handle the option bytes 2013-01-30 17:16:44 +01:00
Gareth McMullin
ef566de383 Merge pull request #10 from esden/stlink_update
Thank you.  I'm not too concerned about the LED.  Is there any way to reliably detect which stlink hardware we're running on?
2013-01-28 14:33:34 -08:00
Piotr Esden-Tempski
9819f9d5b3 Corrected the led pin for F3 and F4 discovery boards. Needs proper fixing so that it works on all platforms in the future. 2013-01-28 12:15:50 -08:00
mirage
b50b3ffa86 Error in calculating ending sector number. 2013-01-26 11:38:27 +08:00
Uwe Bonnes
96ae3886ff stm32:cdcacm/usbdfu: Print version and build information in the product string 2013-01-25 13:01:57 +01:00
Uwe Bonnes
8415fc829b stm32/cdcacm.c: remove unneeded includes 2013-01-23 17:28:34 +01:00
Uwe Bonnes
32b909067b STM32: Use hardware CRC unit 2013-01-23 16:11:17 +01:00
Uwe Bonnes
d868088d78 STM32L1: Add to the list of known JTAG IDs 2013-01-23 00:16:01 +01:00
Uwe Bonnes
6157754201 libftdi: List some know cables and allow to specify cable and serial 2013-01-23 00:16:01 +01:00
Uwe Bonnes
ce059cc8ed LIBFTDI: Propagate the command line arguments to platform_init 2013-01-23 00:15:47 +01:00
Uwe Bonnes
73d120577b usbdfu: Write protect the bootloader sector on F4 2013-01-22 19:04:51 +01:00
Uwe Bonnes
09e2d00b8e STM32F4: Add option byte handling 2013-01-22 18:49:11 +01:00
Piotr Esden-Tempski
0a91fc3b30 Updated stlink platform to the new locm3 usb api. 2013-01-21 13:43:37 -08:00
Uwe Bonnes
29fc42e419 Add note about -mfloat-abi=hard versus -mfloat-abi=soft 2013-01-21 13:52:02 +01:00
Uwe Bonnes
747cc58c2c STLINK: Unconditionally enable MCO from 8 MHz HSE to PA8 as on original firmware. F3 Discovery has has no quarz for the F3 and needs it. 2013-01-21 12:48:37 +01:00
Uwe Bonnes
ef09fb2b69 README: Add the hint about "set mem inaccessible-by-default off" from the mailing list 2013-01-21 11:02:44 +01:00
Uwe Bonnes
8033fb2529 STLINK: Allow to force bootloader by starting with the RESET button pressed 2013-01-21 11:02:44 +01:00
Uwe Bonnes
749fb318e7 gdb_if: Use a doubled buffer scheme for reading data from USB
Needed, as the OTG driver erases the data read after eventually calling the callback
2013-01-21 11:02:44 +01:00
Uwe Bonnes
1fa961841d Product and DFU String now tell the hardware they run on 2013-01-21 11:02:44 +01:00
Uwe Bonnes
04624af4e5 f4discovery: Adapt from the "native" file and add or change code where needed
- stm32_mem.py has problems with erasing the big pages, but dfu-util works
- serial GDB remote server doesn't work. It neither works for the STM32F107,
  so maybe there is a problem with the usbd_f107_driver.
2013-01-21 11:02:44 +01:00
Uwe Bonnes
e373619374 stlink: LED is connected to GPIO9. Before LED was associated with the MCO Output. 2013-01-21 11:02:44 +01:00
Uwe Bonnes
06c2d52c59 stm32_mem.py: Add exception handler for better diagnosis, as erase on STM32F407 times out 2013-01-21 11:02:44 +01:00
Uwe Bonnes
5e71ea3f60 stm32_mem: Allow to select the programmer with the serial number 2013-01-21 11:02:44 +01:00
Uwe Bonnes
8b1ec3151f usbuart, jtagtap, swdptap: Factor out GPIO setup 2013-01-21 11:02:44 +01:00
Uwe Bonnes
7e91f68efa f4discovery: Create a platforms directory for the F4 on the F4 Discovery board 2013-01-21 11:02:44 +01:00
Uwe Bonnes
15d7077115 traceswo: Move (now-constant) traceswo.c to platforms/stm32 2013-01-21 11:02:44 +01:00
Uwe Bonnes
09715e1db8 traceswo: factor out platform dependant parts 2013-01-21 11:02:44 +01:00
Uwe Bonnes
72ca77af53 stm32_can: Changes to get blackmagic to work 2013-01-21 11:02:44 +01:00
Uwe Bonnes
313a24b316 usbdfu: Allow for different, but constant flash page sizes 2013-01-21 11:02:43 +01:00
Uwe Bonnes
1eb9bfc650 platforms/stm32: Move more platform dependencies to platform.h 2013-01-21 11:02:43 +01:00
Uwe Bonnes
30d8aa1eb7 Move (now-constant) cdcacm.c to platforms/stm32 2013-01-21 11:02:43 +01:00
Uwe Bonnes
04415582bd cdcacm: move non-constant parts to platform.[hc] 2013-01-21 11:02:43 +01:00
Uwe Bonnes
533608a2f4 Move usbuart to the stm32 directory 2013-01-21 11:02:43 +01:00
Uwe Bonnes
16ac8e0478 stlink: Add DFU capability 2013-01-21 11:02:43 +01:00
Uwe Bonnes
7188a4a8cb Move usbdfu to platforms/stm32 directory 2013-01-21 11:02:43 +01:00
Uwe Bonnes
67f8176c5b stlink: Add the UART 2013-01-21 11:02:43 +01:00
Uwe Bonnes
35d6adc236 native/usbuart: Move platform dependant parts to platform.h 2013-01-21 11:02:43 +01:00
Uwe Bonnes
16b9c1e83f stlink: Update to current libopencm3 usb api. 2013-01-21 11:02:43 +01:00
Uwe Bonnes
ebb48245aa stlink: Use a seperate linker file as stlink has only 64 kByte 2013-01-21 11:02:43 +01:00
Uwe Bonnes
9a85146eba Add explanation how toi fill the libopencm3 directory 2013-01-21 11:02:43 +01:00
Uwe Bonnes
91709afcc2 More Files to ignore 2013-01-21 11:02:43 +01:00
mirage
99a23a7e1a As per the lpc11xx manual the stack pointer should be set before IAP
calls are made.  

In lpc11xx_flash_prepare() and lpc11xx_flash_erase() bug in calculating
the ending sector number.
2013-01-13 09:50:23 +08:00
Gareth McMullin
2a46994b42 Fixed magic numbers for CSW access. 2013-01-11 10:02:34 -08:00
Gareth McMullin
ad9c76e97f Update to current libopencm3 usb api. 2013-01-10 22:01:21 -08:00
Gareth McMullin
a84052915f Merge pull request #8 from aibara/master
One-liner fix for black magic firmware issue corrupting un-aligned memory reads from target.
2013-01-10 16:45:34 -08:00
Allen Ibara
83a06052f1 Don't increment src address twice in ap_mem_read_bytes function. Fixes corrupted thumb disassembly dumps in gdb. 2013-01-10 14:04:17 -08:00
Gareth McMullin
1d16d6c34c Check for 10-bit address over flow when auto-incrementing.
Clean up whitespace.
2012-11-21 09:50:50 +13:00
Vegard Storheil Eriksen
8f04241aa8 Added support for STM32F37x. 2012-11-15 18:36:32 +01:00
Gareth McMullin
2637f072a1 Probe function return bool, true if device identified.
Correctly identify LM3S3748.
2012-11-03 23:53:25 +13:00
Gareth McMullin
e1c1162a1a Recognise LPC43xx dual core devices. 2012-11-03 21:33:28 +13:00
Gareth McMullin
f526a82773 Move breakpoint packet handler out of main gdb loop.
Use gdb_putpacketz for constant strings.
2012-11-03 20:38:27 +13:00
Gareth McMullin
538f4d41b6 Clean up whitespace. 2012-11-03 19:59:01 +13:00
Gareth McMullin
dac1f60dc2 Clean up ancient bad typing and malloc madness. 2012-11-03 19:52:09 +13:00
Gareth McMullin
50b6c623d6 Check for null pointer before decalaring register array. 2012-11-03 19:04:27 +13:00
Gareth McMullin
0990c2224c Allow target attachment to timeout and report failure.
This is needed for if the target device is held in reset.
2012-11-03 16:42:46 +13:00
Vegard Storheil Eriksen
faa43fdc92 Added support for STM32L1. 2012-10-25 21:44:26 +02:00
Vegard Storheil Eriksen
dddb51ca1c Added support for STM32F0. 2012-10-24 18:08:01 +02:00
Gareth McMullin
1ce2af4819 Changed libopencm3 url to https. 2012-10-24 07:34:30 +13:00
Vegard Storheil Eriksen
cb41855d91 Added support for STM32F3. 2012-10-23 19:40:23 +02:00
Gareth McMullin
fee915bcf5 Add toplevel Makefile to build blackmagic with libopencm3. 2012-10-22 18:50:06 +13:00
Gareth McMullin
09c0fb5773 Build with libopencm3 as a submodule.
Fix incompatibilities with latest libopencm3.
2012-10-22 18:45:42 +13:00
Gareth McMullin
206237e8dd Fix support for multiple devices on the same jtag chain.
Mask out architecture version in ADIv5 JTAG IDCODE.
2012-09-04 21:50:12 +12:00
Gareth McMullin
358ef32225 Whitespace fixes. 2012-09-04 21:48:49 +12:00
Gareth McMullin
9137c2d058 Add a copy of DEMCR to Cortex-M private data to preserve over 'run'. 2012-08-10 21:07:06 +12:00
Gareth McMullin
7be4866239 Corrected upgrade tool to use our new usb ids. 2012-07-27 21:59:03 +12:00
Gareth McMullin
234d54c5a5 Correct stepping over programmed breakpoints.
Fixes issue #2.
2012-07-05 22:08:01 +12:00
Gareth McMullin
0433d3d12a cortexm: Moved all static data to the heap. 2012-07-05 21:26:26 +12:00
Gareth McMullin
0c379744e9 cortexm: Poll for S_RESET_ST in DHCSR to detect release from reset. 2012-07-05 20:12:18 +12:00
Gareth McMullin
00c4dbfb11 ADIv5 AP and DP are now allocated on the heap and reference counted.
They are unref'd and free'd automatically when the target list is
destroyed.
2012-07-05 19:23:28 +12:00
Gareth McMullin
af1ef670ba libftdi: Fixed delay function. 2012-07-05 19:10:08 +12:00
Gareth McMullin
5dff263078 Add delay after reset request.
Hopefully this fixes problems observed with failing vFlashWrite.
2012-07-01 22:40:43 +12:00
Gareth McMullin
d64cec686a Signal on halt is now returned by target_halt_wait().
Fault unwinding is now handled internally in target implementation.
GDB server doesn't need to know about it.
2012-06-30 20:29:08 +12:00
Gareth McMullin
53af978295 Allow user to specify JTAG IR lengths.
This allows the use of devices that shift out values other than 0x01
from IR.
2012-06-30 16:47:23 +12:00
Gareth McMullin
01d0390b54 Fixed build for stlink platform. 2012-06-28 20:49:32 +12:00
Gareth McMullin
22993fb5bd Clear target error on attaching.
Fixes possible lock-up on devices booting from blank flash.
2012-06-28 20:11:53 +12:00
Gareth McMullin
466bb66424 Made cur_target, last_target static in gdb_main.c.
Added target destroy notify mechanism.
2012-06-27 21:26:08 +12:00
Gareth McMullin
4581da2034 Added option byte programming commands for STM32F1. 2012-06-26 21:02:11 +12:00
Gareth McMullin
29b9e103fb Fixed crash on monitor commands with no attached target. 2012-06-26 19:48:50 +12:00
Gareth McMullin
94516329a0 Added 'erase_mass' command for STM32F1 and cleaned up some magic numbers. 2012-06-26 19:42:41 +12:00
Gareth McMullin
0e768664ac Added 'vector_catch' command to control trapped vectors on Cortex-M. 2012-06-25 21:19:09 +12:00
Gareth McMullin
b0d41d155a Made SAM3X monitor commands static. 2012-06-25 21:16:20 +12:00
Gareth McMullin
8b7c6bbaba Added monitor commands to set GPNVM bits on SAM3X. 2012-06-24 21:55:22 +12:00
Gareth McMullin
03fdd23e9c Added mechanism for target driver to add new monitor commands. 2012-06-24 21:41:32 +12:00
Gareth McMullin
a16123997b Added target.c for common target routines. 2012-06-24 19:08:49 +12:00
Gareth McMullin
8872315e82 Updated lmi, nxp and stm32f4 drivers to use adiv5_target_ap(). 2012-06-24 14:44:02 +12:00
Gareth McMullin
cb19164f2f Added flash erase function for Atmel SAM3X. 2012-06-23 21:13:08 +12:00
Gareth McMullin
c09cbe8719 First cut at an Atmel SAM3X driver. 2012-06-22 23:13:25 +12:00
Gareth McMullin
33905d7203 Check target error after target specific probes. 2012-06-21 20:54:56 +12:00
Gareth McMullin
6089a66dce Renamed target_flash_write_words to target_flash_write.
Buffer from GDB may not be aligned or integer number of words.
Corrected alignment in in STM32F1 driver.
2012-06-18 20:53:06 +12:00
Gareth McMullin
bc7e7d2112 Removed target header files containing a single prototype.
Target probe prototypes are all in target.h now.
2012-06-18 20:27:06 +12:00
Gareth McMullin
bc5a6f022b Renamed Cortex-M driver appropriately since it support M0, M3 and M4F. 2012-06-18 19:56:19 +12:00
Gareth McMullin
0599bdc5c4 Cleaned up STM32F1 driver and renamed appropriately. 2012-06-18 19:46:41 +12:00
Gareth McMullin
3a0cc44bbe Cleaned up access to ADIv5 AP in Cortex-M driver. 2012-06-18 19:28:06 +12:00
Gareth McMullin
8920864cb3 Cleaned up access to ADIv5 AP for target. 2012-06-18 19:19:13 +12:00
Gareth McMullin
77aab2d336 Updated HACKING file to new libftdi platform name. 2012-06-10 19:10:15 +12:00
Gareth McMullin
54f4467c0f Added stlink platform for Discovery boards and ST's ST-Link hardware. 2012-06-10 19:06:37 +12:00
Gareth McMullin
89bcdcc60a Moved stm32 generic platform files out of native platform dir. 2012-06-10 17:34:26 +12:00
Gareth McMullin
acff8d4497 Made jtagtap.c and swdptap.c STM32 generic. 2012-06-10 17:08:14 +12:00
Gareth McMullin
8d190cdbb9 Renamed platforms to 'native' and 'libftdi' and moved into 'platforms' dir. 2012-06-10 16:40:07 +12:00
Gareth McMullin
c825270561 Indicate UART activity on yellow LED. 2012-06-10 15:45:38 +12:00
Gareth McMullin
c1a34f3f59 Removed incorrect directory references in Makefile. 2012-06-10 15:45:38 +12:00
Gareth McMullin
eabd4654f9 Use the same LED for run/idle. Reserve spare LED for UART.
Enable AFIO to fix EXTI for USB VBUS detect.
2012-06-10 15:45:38 +12:00
Gareth McMullin
c35d0b29b3 Removed a stray printf. 2012-06-03 21:28:39 +12:00
Gareth McMullin
bad49dbb90 Added missing stm32/usbuart.h. 2012-05-27 13:02:45 +12:00
Gareth McMullin
6030ff6f26 Separated USB UART interface into separate file. 2012-05-26 22:53:29 +12:00
Gareth McMullin
3dcdc5b26f Improve USB UART handling. Fix interrupt priorities. 2012-05-26 20:57:47 +12:00
Gareth McMullin
b98d01dff8 Update Windows drivers to use new USB IDs. 2012-05-26 15:33:16 +12:00
Gareth McMullin
e533812c32 Use our new USB VID/PID. Thanks OpenMoko, Inc.
DFU now uses the same short serial number as application.
2012-05-26 15:20:23 +12:00
Gareth McMullin
01bf5e6b44 Fixed and cleaned up build for libftdi platform. 2012-05-26 15:05:37 +12:00
Gareth McMullin
09330d7fa9 HACKING: Corrected libftdi instructions. 2012-05-24 18:23:58 +12:00
Gareth McMullin
8d2c0ff9e5 Report target voltage on scan.
ADC is used on mini hardware, standard hardware reports ok/absent.
2012-05-23 21:44:39 +12:00
Gareth McMullin
40bb74cc81 Detect hardware version. Disable UART on mini h/w under debug. 2012-05-23 20:25:45 +12:00
Gareth McMullin
700f9e6ad1 DFU: Erase option bytes before writing. 2012-05-23 19:31:51 +12:00
Gareth McMullin
241bf765ec DFU: Protect bootloader sectors if needed.
Check address bounds on erase/set address.
2012-05-22 21:47:18 +12:00
Gareth McMullin
5eb3a375e0 Added Windows libusb driver for Trace port interface.
Converted windows driver inf file to utf-8 encoding.
2012-05-19 14:43:57 +12:00
Gareth McMullin
de49a9a21f Remove dependencies on make clean. 2012-05-19 11:54:22 +12:00
Gareth McMullin
32c1af05de Don't clobber watchpoints used for trace. 2012-05-19 11:53:41 +12:00
Gareth McMullin
38bea69f8a Fixed some issues with trace port capture.
Process last capture even on timeout.  Prevents last bit getting lost.
On timeout, don't allow next edge to resync decoder.
Timeout on 6 bit periods instead of 5.
Set systick interrupt to low priority.
2012-04-29 20:35:19 +12:00
Gareth McMullin
86626085d8 Fixed TRACESWO capture.
'mon traceswo' reports serial number and interface/endpoint no for libusb.
Interrupt priorities set so TIM3 for trace is highest priority.
Increased trace endpoint packet size to 64.
Buffer many trace packets into a single usb packet.  Stall on overflow.
Fixed stop bit detection in TIM3 interrupt handler.
2012-04-22 12:27:18 +12:00
Gareth McMullin
b39572e17c Correct jtag port init to not interfere with usb vbus detect. 2012-04-22 12:21:24 +12:00
Gareth McMullin
c1e9425725 Cleaned up traceswo capture routine. 2012-04-20 17:56:41 +12:00
Gareth McMullin
21ecbd23ea Added capture of SWO, passed to host over a vendor specific USB interface. 2012-04-18 19:15:44 +12:00
Gareth McMullin
9cff48dc6b Added .gitignore 2012-04-18 19:13:38 +12:00
Gareth McMullin
405570636b Added a Makefile for generation of some hardware outputs. 2012-04-12 18:47:30 +12:00
Gareth McMullin
b513799c10 hardware: Removed solder paste openings on fiducials. 2012-04-02 16:57:40 +12:00
Gareth McMullin
75a2f97a0b Added new mini hardware design. 2012-03-25 20:19:31 +13:00
Gareth McMullin
c0493ee0e8 Monitor USB VBUS to control D+ pull-up resistor. 2012-03-24 19:25:16 +13:00
Gareth McMullin
ebf15cf5e2 Windows driver now supports 64-bit. 2012-03-24 19:02:03 +13:00
Gareth McMullin
537cbcdbd8 Added Windows driver setup info for DFU interfaces.
These use libusb and work with the uploader in the upgrade dir.
2012-03-18 15:16:51 +13:00
Gareth McMullin
87c14c294b Fixed some issues in Windows DFU uploader. 2012-03-18 15:15:00 +13:00
Gareth McMullin
a43cbf65c9 Report FP registers as feature "org.gnu.gdb.arm.vfp".
This allows GDB to synthesise single precision registers S0-S32.
2012-02-12 14:59:42 +13:00
Gareth McMullin
38d8147774 Added FP register support. 2012-02-12 14:24:54 +13:00
Gareth McMullin
a08e0bdd9c Made command handlers static. 2012-02-12 14:24:18 +13:00
Gareth McMullin
35a9e10f49 Accept partial match of monitor commands. 2012-02-12 12:02:50 +13:00
Gareth McMullin
4282244fb4 stm32f4: Fixed chunk padding for flash programming. 2012-02-08 20:43:12 +13:00
Gareth McMullin
b52c62266a Fixed hexprog.py to work with current firmware 'g' packet. 2012-01-30 22:14:31 +13:00
Gareth McMullin
c17ad8f2ce Merge pull request #1 from mbolivar/master
Add note about gschem to README.
2012-01-27 16:37:15 -08:00
Marti Bolivar
86b1679dd2 Add note that schematic is created in gschem.
This will help avoid confusion about which EDA toolchain should be
used to view and edit it.

Signed-off-by: Marti Bolivar <mbolivar@leaflabs.com>
2012-01-27 19:17:15 -05:00
Gareth McMullin
f5d8bda6e6 Support DFU GET_STATUS request when in application mode. 2012-01-19 21:51:42 +13:00
Gareth McMullin
f2f5fd2fa1 Added unfinished, untested upgrade tool. 2012-01-18 20:46:35 +13:00
Piotr Esden-Tempski
a7f14e3cc0 Changed the unique id generation to be 8 characters long. This is so Mac OS X uses the the unique id for naming the device file instead of the location. 2012-01-16 22:54:37 -08:00
Gareth McMullin
53ebc6770e Configure CDC ACM packet size in a #define for easy access.
This doesn't work for >64 bytes.  Suspect bug in libopencm3.
2012-01-09 23:15:10 +13:00
Gareth McMullin
7e0de5b86b Inline GPIO functions and optimise for speed.
This gives a modest but measurable performance improvement.
2012-01-08 18:49:58 +13:00
Gareth McMullin
7c6317a426 Change driver to work as composite device with two ACM interfaces.
This works with the current firmware, but the DFU interface is orphaned:
Windows complains about no driver it.
2012-01-08 14:07:09 +13:00
Gareth McMullin
d51f93827e Added existing Windows driver.
This doesn't work with the current firmware.
2012-01-08 14:02:48 +13:00
Gareth McMullin
9663274572 Advertise that we accept SET_LINE_CODING and ignore it on GDB interface.
This fixes SetCommState failure on Windows.
2012-01-07 18:46:17 +13:00
Gareth McMullin
edaae3957a Use USB Interface Association Descriptors.
This allows windows to see it as a composite device and load different
driver for each interface.
2011-12-29 12:49:47 +13:00
Mike Smith
4f0ed8361a Update verbiage for LPC11xx support. 2011-12-26 02:56:10 -08:00
Mike Smith
af45139767 Use a single static program buffer rather than allocating several on the stack. 2011-12-26 02:54:44 -08:00
Mike Smith
00651032ad Merge commit '4e0cd081b09d9bd3d444062ca1081fa59c31fc0b'
* commit '4e0cd081b09d9bd3d444062ca1081fa59c31fc0b':
  Improved magic number garbage in cortexm3.c
  Cleaned up debug output on linux build.
  Removed #if LIGHT for unfinished hardware.
  Implement gdb 'qCRC' packet to support 'compare-sections' command.
2011-12-26 02:47:38 -08:00
Mike Smith
bc4c87e45b Add support for Cortex-M0, and specifically for the NXP LPC11xx devices. 2011-12-26 02:34:45 -08:00
Gareth McMullin
4e0cd081b0 Improved magic number garbage in cortexm3.c 2011-12-18 17:46:36 +13:00
Gareth McMullin
a73f06c147 Cleaned up debug output on linux build. 2011-12-18 17:01:10 +13:00
Gareth McMullin
8061205260 Removed #if LIGHT for unfinished hardware. 2011-12-18 16:43:02 +13:00
Gareth McMullin
c7c31d2502 Implement gdb 'qCRC' packet to support 'compare-sections' command. 2011-12-17 21:46:22 +13:00
Mike Smith
2653222d08 Tweak the flash uploader to handle unaligned start and end pointers,
padding with all-1s so that overlapping data is preserved.
2011-12-14 23:41:40 -08:00
Mike Smith
bba42ff6c9 Merge branch 'master' of git://github.com/gsmcmullin/blackmagic 2011-12-14 23:10:53 -08:00
Gareth McMullin
45eee497d0 stm32f4: Improve behaviour when a section doesn't end on a word boundary.
This may not be an acceptable fix.  It may be possible for the linker
to place another section on the remainder of the offending work.
2011-12-14 22:59:42 +13:00
Mike Smith
c9860e7716 Make it possible to build with libopencm3 installed in a nonstandard location 2011-12-05 23:01:24 -08:00
249 changed files with 44623 additions and 12082 deletions

40
.gitattributes vendored Normal file
View File

@ -0,0 +1,40 @@
# Text for humans
LICENSE text eol=lf
HACKING text eol=lf
COPYING text eol=lf
UsingSWO text eol=lf
README.* text eol=lf
# Source code
Makefile text eol=lf
*.mk text eol=lf
*.mak text eol=lf
*.inc text eol=lf
*.py text eol=lf
*.sh text eol=lf
*.c text eol=lf
*.S text eol=lf
*.s text eol=lf
*.h text eol=lf
*.ld text eol=lf
*.yml text eol=lf
*.rules text eol=lf
# Git control files
.gitattributes eol=lf
.gitignore eol=lf
.gitmodules eol=lf
# Windows source code uses CRLF
*.vcxproj text eol=crlf
*.props text eol=crlf
*.bat text eol=crlf
*.ps1 text eol=crlf
*.inf text eol=crlf
# Other binary files
*.png binary
*.jpg binary
*.bin binary
*.elf binary
*.bin binary

2
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,2 @@
github: [esden, dragonmux]
patreon: 1bitsquared

36
.github/workflows/build-and-upload.yml vendored Normal file
View File

@ -0,0 +1,36 @@
name: build and upload
# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the main branch
push:
branches: [ master ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
# Use embedded toolchain
- uses: numworks/setup-arm-toolchain@2020-q4
# Runs a single command using the runners shell
- name: Build
run: make
- name: Archive firmware build artifacts as a zip
uses: actions/upload-artifact@v2.2.4
with:
name: blackmagic-firmware.zip
path: src/blackmagic*
if-no-files-found: error

38
.github/workflows/build-pr.yml vendored Normal file
View File

@ -0,0 +1,38 @@
name: build PR
# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the main branch
pull_request:
branches: [ master ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
# Use embedded toolchain
- uses: numworks/setup-arm-toolchain@2020-q4
# Run some of the most common build types
- name: Build native fw
run: make
- name: Clean
run: make clean
- name: Install BMP PC hosted dependencies
run: sudo apt-get -y install libftdi1-dev libhidapi-dev
- name: Build PC hosted binary
run: make PROBE_HOST=hosted

25
.gitignore vendored Normal file
View File

@ -0,0 +1,25 @@
src/include/version.h
blackmagic
*.bin
*.hex
blackmagic_dfu
dfu_upgrade
mapfile
*.o
*.d
.*.swp
*~
*.pyc
tags
.gdbinit
*.s#*
*.b#*
blackmagic_upgrade
*.exe
.DS_Store
*.elf
.vscode
cscope.out
cscope.files
.gdb_history
src/artifacts/

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "libopencm3"]
path = libopencm3
url = https://github.com/flirc/libopencm3.git

27
.travis.yml Normal file
View File

@ -0,0 +1,27 @@
dist: bionic
sudo: required
before_install:
- sudo add-apt-repository -y ppa:team-gcc-arm-embedded/ppa
- sudo apt-get update -qq
- pip install --user intelhex
- sudo apt-get install -y build-essential libboost-all-dev gcc-arm-embedded libusb-1.0-0-dev libhidapi-dev libftdi1 libftdi1-dev
script:
- make -C libopencm3 lib
- make -C src all_platforms
deploy:
provider: s3
access_key_id: AKIAIDXRMRPEG5OCN5AQ
secret_access_key:
secure: AKGtHD71s7FEfmzSWkrEgW8DT3exDzKPROn4hI4kwuMcI6gYoOHqloEhzqZVi9ok8ynEkGfzzaAAcPYCNjlxOu2zmMJFgCiGegIUacrpJuzo9eknqW281pEpIlSXonrlttW9Hm0gJhl3yLKdMQYKoXvCfR7HgUkcN7QSAZxLgv297u/azMLq2z6rZdTCgZYpD2EIB3BlqChZkoepyczBYEtGOj0tMW4WF79qufIfVnUnQqWr8Lef2tQ9X9MEn7LIsHbBgGJ08TGb2yIiPTF+NyE+2ev3KmVmBdzDLdfAAV3koPtiTsTBdcstNAT51vvPsQhuIXB7gIr91xhquCel84DV285aZn2wOwgQ0KHhbFLVFXb2wv+r1saF1b4/rJTiobavDbIXIDVm/UfAs41AyM/zoclTeixAgyA8BpuhDEP+2dDYk3rehZ1Uhbaf8U9OKyQ6kYg1aFOQU5jYFjIbJmgSTlkJwntk9w3EX7lI8LSInNgdPhM8Ak6IjTCKg8NSKvtDH27X++UNVn1r2vX0eMjcusUNSPktjvilWIFMIvPw8bO2yLgj6bLDQ73WsEUC0LiiqL45r3A5KOMkMO8z1xp0TOz2f3Pxdyr1l2gXC0n/hxutoue7HaaPE2zA08giYdSCwZBxSedcoxxKA8V+E4vwfm0D/sWZS+U7vXm15LE=
bucket: builds.blacksphere.co.nz
region: us-west-2
local-dir: src/artifacts
upload-dir: blackmagic
acl: public_read
skip_cleanup: true
on:
repo: blacksphere/blackmagic
branch: master

59
HACKING
View File

@ -1,58 +1 @@
======================================== See https://github.com/blackmagic-debug/blackmagic/wiki/Hacking
The Black Magic Debug Project -- HACKING
========================================
The Black Magic Probe consists of both hardware and firmware components.
The hardware design resides in the 'hardware' directory and the firmware
resides in the 'src' directory.
Compiling for the native hardware
---------------------------------
To build the firmware for the standard hardware platform run 'make' in the
src directory. You will require a GCC cross compiler for ARM Cortex-M3
targets. You will also need to have the libopenstm32 library installed.
The default makefile assumes the target is arm-cortexm3-eabi, but
you can override this on the command line:
make CROSS_COMPILE=arm-none-eabi-
This will result in binary files:
blackmagic - ELF binary of the Black Magic debug probe.
blackmagic.bin - Flat binary of the Black Magic debug probe, load at 0x8002000.
blackmagic_dfu - ELF binary of the Black Magic DFU bootloader.
blackmagic_dfu.bin - Flat binary of the DFU bootloader, load at 0x8000000.
If you already have a JTAG/SWD debug probe that can be used to load these
binaries to your target hardware. If not the SystemMemory bootloader can
be used to load the DFU bootloader:
../scripts/bootprog.py blackmagic_dfu.bin
This requires an appropriate cable to connect the PC serial port to the probe.
See the schematic for more information.
Once the DFU bootloader is loaded, the Black Magic application can be loaded
over USB:
(First connect the probe and observe the flashing red led)
../scripts/stm32_mem.py blackmagic.bin
The device should reset and re-enumerate as a CDC-ACM device implementing
the GDB protocol.
Compiling as a Linux application using FT2232 hardware
------------------------------------------------------
The Black Magic application can also be compiled as a native Linux application
which will use an FT2232 device to implement the physical JTAG interface.
This is not the intended mode of operation, but is useful for debugging,
experimentation, and if you don't have the actual hardware.
First, get the VID/PID for your FT2232 device using 'lsusb'. Edit the file
'src/linux/platform.h' and change the VID/PID to match your hardware.
Compile the application with the command:
make HOST=linux
Running the application 'blackmagic' will start a GDB server on TCP port 2000.

39
Makefile Normal file
View File

@ -0,0 +1,39 @@
ifneq ($(V), 1)
MFLAGS += --no-print-dir
Q := @
endif
PC_HOSTED =
NO_LIBOPENCM3 =
ifeq ($(PROBE_HOST), hosted)
PC_HOSTED = true
NO_LIBOPENCM3 = true
endif
all:
ifndef NO_LIBOPENCM3
$(Q)if [ ! -f libopencm3/Makefile ]; then \
echo "Initialising git submodules..." ;\
git submodule init ;\
git submodule update ;\
fi
$(Q)$(MAKE) $(MFLAGS) -C libopencm3 lib/sam/d
endif
$(Q)$(MAKE) $(MFLAGS) -C src
all_platforms:
$(Q)$(MAKE) $(MFLAGS) -C src $@
clean:
ifndef NO_LIBOPENCM3
$(Q)$(MAKE) $(MFLAGS) -C libopencm3 $@
endif
$(Q)$(MAKE) $(MFLAGS) -C src $@
clang-tidy:
$(Q)scripts/run-clang-tidy.py -s "$(PWD)"
clang-format:
$(Q)$(MAKE) $(MFLAGS) -C src $@
.PHONY: clean all_platforms clang-tidy clang-format

47
README
View File

@ -1,47 +0,0 @@
=======================================
The Black Magic Debug Project -- README
=======================================
The Black Magic Debug Probe is gadget providing an in-application
debug capability for ARM Cortex-M3 microcontrollers. It interfaces
with the GDB, the GNU source level debugger over the USB bus, and
communicates with the target microcontroller over either a JTAG or
Serial Wire debug port.
Currently supported microcontrollers:
- ST STM32 Family
- TI/LMI Stellaris Family
Getting started
===============
The Black Magic Probe is available as a built-up product form Black
Sphere Technologies. Contact <sales@blacksphere.co.nz> should
you wish to order one. If you would like to work on the project see
the file HACKING for developer's info.
When connected via USB, the Black Magic probe will enumerate as a CDC-ACM
device which the OS should present as a tty device or serial port. The
GDB remote debugging protocol is implemented over this virtual character
stream. To connect your ARM GDB to the target device use the following
commands:
(gdb) target extended-remote /dev/ttyACM0
(gdb) mon jtag_scan
(gdb) attach 1
The command 'mon swdp_scan' may be used to use the Serial-Wire Debug Protocol
instead of JTAG to connect to the target.
Once attached, all the standard GDB commands may be used to start and control
the execution of the embedded application.
Project layout
==============
flashstub/ - Source code for flash programming stubs in target drivers.
hardware/ - Schematic and PCB layout for the Black Magic Probe
scripts/ - Python scripts useful for programming devices.
src/ - Firmware source code for the Black Magic debug probe.

54
README.md Normal file
View File

@ -0,0 +1,54 @@
Jeff Probe
==========
This is a fork of the [original Black Magic Probe](https://github.com/blacksphere/blackmagic).
The original is arguably better, faster and wider supported. However, this
project was a way to offer an affordable version and I'll rely on community
support and pull requests.
One urguably better funncton is the ability to do DEBUG and Serial communication
over a single JTAG cable when paired with a device that uses single wire JTAG.
Normally, the serial header can be used on a target for the serial port, and
shows up as the second serial device on the system, however, we can dynamically
change the pins to use the ones on the JTAG cable with the following command:
``` bash
$ mon convert_tdio enable
```
Compilation
---
Newer toolchains can cause issues. I usually work 4_9-2014q4-20141203 found [here.](https://launchpad.net/gcc-arm-embedded/4.9/4.9-2014-q4-major/+download/gcc-arm-none-eabi-4_9-2014q4-20141203-mac.tar.bz2)
the versionfollowing version
```bash
$ make clean
$ make PROBE_HOST=jeff CUSTOM_SER=1
$ dfu-util --device ,1d50:6017 -s 0x00002000:leave -D src/blackmagic.bin
```
CUSTOM OPTIONS
---
On mac, our device shows up with a serial number /dev/tty.cuJEFF123HDC
This can be annoy if we want to autocnnect with a gith script. We can override
the use of a serial number by doing a custom compliation such that our device
shows up with the following: /dev/cu.usbmodemJEFF1 and /dev/cu.usbmodemJEFF3
```bash
$ make PROBE_HOST=jeff CUSTOM_SER=1
```
More
---
More helpful information can be found on the black magic probe [readme](https://github.com/blacksphere/blackmagic/blob/master/README.md#black-magic-probe), which is relevant.
See online documentation at https://github.com/blacksphere/blackmagic/wiki
Binaries from the latest automated build can be found on the release page.

271
UsingRTT.md Normal file
View File

@ -0,0 +1,271 @@
# Using RTT
When debugging arm processors, there are three ways for the target to print debug messages on the host: Semihosting, Serial Wire Output SWO, and Real-Time Transfer RTT.
[Black Magic Probe](https://github.com/blacksphere/blackmagic) (BMP) is an open source debugger probe that already implements Semihosting and Single Wire Output. This patch adds Real-Time Transfer RTT output to usb serial port.
- RTT is implemented, not as a user program, but as a serial port device. To read RTT output, use a terminal emulator and connect to the serial port.
- A novel way to detect RTT automatically, fast and convenient.
## Use
This example uses linux as operating system. For Windows and MacOS see the *Operating Systems* section.
In one window open a terminal emulator (minicom, putty) and connect to the usb uart:
```
$ minicom -c on -D /dev/ttyBmpTarg
```
In another window open a debugger:
```
$ gdb
(gdb) target extended-remote /dev/ttyBmpGdb
(gdb) monitor swdp_scan
(gdb) attach 1
(gdb) monitor rtt
(gdb) run
^C
(gdb) monitor rtt status
rtt: on found: yes ident: off halt: off channels: auto 0 1 3
max poll ms: 256 min poll ms: 8 max errs: 10
```
The terminal emulator displays RTT output from the target,
and characters typed in the terminal emulator are sent via RTT to the target.
## gdb commands
The following new gdb commands are available:
- ``monitor rtt``
switch rtt on
- ``monitor rtt enable``
switch rtt on
- ``monitor rtt disable``
switch rtt off
- ``monitor rtt poll `` max_poll_ms min_poll_ms max_errs
sets maximum time between polls, minimum time between polls, and the maximum number of errors before RTT disconnects from the target. Times in milliseconds. It is best if max_poll_ms/min_poll_ms is a power of two. As an example, if you wish to check for RTT output between once per second to eight times per second: ``monitor rtt poll 1000 125 10``.
- ``monitor rtt status``
show status.
rtt|found|state
---|---|---
rtt: off|found: no|rtt inactive
rtt: on|found: no|searching for rtt control block
rtt: on|found: yes|rtt active
rtt: off|found: yes|corrupt rtt control block, or target memory access error
A status of `rtt: on found: no` indicates bmp is still searching for the rtt control block in target ram, but has not found anything yet. A status of `rtt: on found: yes` indicates the control block has been found and rtt is active.
- ``monitor rtt channel``
enables the first two output channels, and the first input channel. (default)
- ``monitor rtt channel number...``
enables the given RTT channel numbers. Channels are numbers from 0 to 15, inclusive. Eg. ``monitor rtt channel 0 1 4`` to enable channels 0, 1, and 4.
- ``monitor rtt ident string``
sets RTT ident to *string*. If *string* contains a space, replace the space with an underscore _. Setting ident string is optional, RTT works fine without.
- ``monitor rtt ident``
clears ident string. (default)
- ``monitor rtt cblock``
shows rtt control block data, and which channels are enabled. This is an example control block:
```
(gdb) mon rtt cb
cbaddr: 0x200000a0
ch ena cfg i/o buf@ size head@ tail@ flg
0 y y out 0x20000148 1024 0x200000c4 0x200000c8 2
1 y n out 0x00000000 0 0x200000dc 0x200000e0 0
2 n n out 0x00000000 0 0x200000f4 0x200000f8 0
3 y y in 0x20000548 16 0x2000010c 0x20000110 0
4 n n in 0x00000000 0 0x20000124 0x20000128 0
5 n n in 0x00000000 0 0x2000013c 0x20000140 0
6 n n in 0x00000000 0 0x00000000 0x00000000 0
7 n n in 0x00000000 0 0x00000000 0x00000000 0
8 n n in 0x00000000 0 0x00000000 0x00000000 0
9 n n in 0x00000000 0 0x00000000 0x00000000 0
10 n n in 0x00000000 0 0x00000000 0x00000000 0
11 n n in 0x00000000 0 0x00000000 0x00000000 0
12 n n in 0x00000000 0 0x00000000 0x00000000 0
13 n n in 0x00000000 0 0x00000000 0x00000000 0
14 n n in 0x00000000 0 0x00000000 0x00000000 0
15 n n in 0x00000000 0 0x00000000 0x00000000 0
```
Channels are listed, one channel per line. The columns are: channel, enabled, configured, input/output, buffer address, buffer size, address of head pointer, address of tail pointer, flag. Each channel is a circular buffer with head and tail pointer.
Note the columns `ena` for enabled, `cfg` for configured.
Configured channels have a non-zero buffer address and non-zero size. Configured channels are marked yes `y` in the column `cfg` . What channels are configured depends upon target software.
Channels the user wants to see are marked yes `y` in the column enabled `ena`. The user can change which channels are shown with the `monitor rtt channel` command.
Output channels are displayed, and Input channels receive keyboard input, if they are marked yes in both *enabled* and *configured*.
The control block is cached for speed. In an interrupted program, `monitor rtt` will force a reload of the control block when the program continues.
## Identifier string
It is possible to set an RTT identifier string.
As an example, if the RTT identifier is "IDENT STR":
```
$ gdb
(gdb) target extended-remote /dev/ttyBmpGdb
(gdb) monitor swdp_scan
(gdb) attach 1
(gdb) monitor rtt ident IDENT_STR
(gdb) monitor rtt
(gdb) run
^C
(gdb) monitor rtt status
rtt: on found: yes ident: "IDENT STR" halt: off channels: auto 0 1 3
max poll ms: 256 min poll ms: 8 max errs: 10
```
Note replacing space with underscore _ in *monitor rtt ident*.
Setting an identifier string is optional. RTT gives the same output at the same speed, with or without specifying identifier string.
## Operating systems
[Configuration](https://github.com/blacksphere/blackmagic/wiki/Getting-Started) instructions for windows, linux and macos.
### Windows
After configuration, Black Magic Probe shows up in Windows as two _USB Serial (CDC)_ ports.
Connect arm-none-eabi-gdb, the gnu debugger for arm processors, to the lower numbered of the two COM ports. Connect an ansi terminal emulator to the higher numbered of the two COM ports.
Sample gdb session:
```
(gdb) target extended-remote COM3
(gdb) monitor swdp_scan
(gdb) attach 1
(gdb) monitor rtt
(gdb) run
```
For COM port COM10 and higher, add the prefix `\\.\`, e.g.
```
target extended-remote \\.\COM10
```
Target RTT output will appear in the terminal, and what you type in the terminal will be sent to the RTT input of the target.
### linux
On linux, install [udev rules](https://github.com/blacksphere/blackmagic/blob/master/driver/99-blackmagic.rules). Disconnect and re-connect the BMP. Check the device shows up in /dev/ :
```
$ ls -l /dev/ttyBmp*
lrwxrwxrwx 1 root root 7 Dec 13 07:29 /dev/ttyBmpGdb -> ttyACM0
lrwxrwxrwx 1 root root 7 Dec 13 07:29 /dev/ttyBmpTarg -> ttyACM2
```
Connect terminal emulator to /dev/ttyBmpTarg and gdb to /dev/ttyBmpGdb .
In one window:
```
minicom -c on -D /dev/ttyBmpTarg
```
In another window :
```
gdb
(gdb) target extended-remote /dev/ttyBmpGdb
(gdb) monitor swdp_scan
(gdb) attach 1
(gdb) monitor rtt
(gdb) run
```
### MacOS
On MacOS the tty devices have different names than on linux. On connecting blackmagic to the computer 4 devices are created, 2 'tty' and 2 'cu' devices. Gdb connects to the first cu device (e.g.: `target extended-remote /dev/cu.usbmodemDDCEC9EC1`), while RTT is connected to the second tty device (`minicom -c on -D /dev/tty.usbmodemDDCEC9EC3`). In full:
In one Terminal window, connect a terminal emulator to /dev/tty.usbmodemDDCEC9EC3 :
```
minicom -c on -D /dev/tty.usbmodemDDCEC9EC3
```
In another Terminal window, connect gdb to /dev/cu.usbmodemDDCEC9EC1 :
```
gdb
(gdb) target extended-remote /dev/cu.usbmodemDDCEC9EC1
(gdb) monitor swdp_scan
(gdb) attach 1
(gdb) monitor rtt
(gdb) run
```
RTT input/output is in the window running _minicom_.
## Notes
- Design goal was smallest, simplest implementation that has good practical use.
- RTT code size is 3.5 kbyte - the whole debugger 110 kbyte.
- Because RTT is implemented as a serial port device, there is no need to write and maintain software for different host operating systems. A serial port works everywhere - linux, windows and mac. You can even use an Android mobile phone as RTT terminal.
- Because polling occurs between debugger probe and target, the load on the host is small. There is no constant usb traffic, there are no real-time requirements on the host.
- RTT polling frequency is adaptive and goes up and down with RTT activity. Use *monitor rtt poll* to balance response speed and target load for your use.
- Detects RTT automatically, very convenient.
- When using RTT as a terminal, sending data from host to target, you may need to change local echo, carriage return and/or line feed settings in your terminal emulator.
- Architectures such as risc-v may not allow the debugger access to target memory while the target is running. As a workaround, on these architectures RTT briefly halts the target during polling. If the target is halted during polling, `monitor rtt status` shows `halt: on`.
- Measured RTT speed.
| debugger | char/s |
| ------------------------- | ------ |
| bmp stm32f723 stlinkv3 | 49811 |
| bmp stm32f411 black pill | 50073 |
| bmp stm32f103 blue pill | 50142 |
This is the speed at which characters can be sent from target to debugger probe, in reasonable circumstances. Test target is an stm32f103 blue pill running an [Arduino sketch](https://github.com/koendv/Arduino-RTTStream/blob/main/examples/SpeedTest/SpeedTest.ino). Default *monitor rtt poll* settings on debugger. Default RTT buffer size in target and debugger. Overhead for printf() calls included.
## Compiling firmware
To compile with RTT support, add *ENABLE_RTT=1*.
Eg. for STM32F103 blue pill:
```
make clean
make PROBE_HOST=stlink ENABLE_RTT=1
```
or for the STM32F411 *[Black Pill](https://www.aliexpress.com/item/1005001456186625.html)*:
```
make clean
make PROBE_HOST=f4discovery BLACKPILL=1 ENABLE_RTT=1
```
Setting an ident string is optional. But if you wish, you can set the default RTT ident at compile time.
For STM32F103 *Blue Pill*:
```
make clean
make PROBE_HOST=stlink ENABLE_RTT=1 "RTT_IDENT=IDENT\ STR"
```
or for STM32F411 *Black Pill*:
```
make clean
make PROBE_HOST=f4discovery BLACKPILL=1 ENABLE_RTT=1 "RTT_IDENT=IDENT\ STR"
```
Note the backslash \\ before the space.
## Links
- [OpenOCD](https://openocd.org/doc/html/General-Commands.html#Real-Time-Transfer-_0028RTT_0029)
- [probe-rs](https://probe.rs/) and [rtt-target](https://github.com/mvirkkunen/rtt-target) for the _rust_ programming language.
- [RTT Stream](https://github.com/koendv/Arduino-RTTStream) for Arduino on arm processors
- [\[WIP\] RTT support - PR from katyo](https://github.com/blacksphere/blackmagic/pull/833)

260
UsingSWO Normal file
View File

@ -0,0 +1,260 @@
SWO is a datastream that comes out of a single pin when the debug interface
is in SWD mode. It can be encoded either using NRZ (UART) or RZ (Manchester)
formats. The pin is a dedicated one that would be used for TDO when the
debug interface is in JTAG mode. On the STM32 it's port PB3.
When in NRZ mode the SWO data rate that comes out of the chip _must_ match
the rate that the debugger expects. By default on BMP the baudrate is
2.25MBps but that can be changed as an optional parameter to the monitor
traceswo command, like this;
monitor traceswo 115200
....would set the swo output at the low speed of 115kbps.
We are constrained on maximum input speed by both the capabilities of the
BMP STM32F103 USART and the ability to get the packets back out over the USB
link. The UART baudrate is set by b=(72x10^6)/d...with d >= 16 or
a maximum speed of 4.5Mbps UART1 and 2.25 Mbps on UART2.
For continious streaming that turns out to be_too_ fast for the USB
link, so the next available option is the 2.25Mbps that we use. ....
You can safely use the 4.5Mbps setting if your debug data
is bursty, or if you're using a different CPU to the STM32F103 as your BMP
host, but you potentially run the risk of losing packets if you have long
runs of sending which the usb cannot flush in time (there's a 12K buffer, so
the it is a pretty long run before it becomes a problem).
Note that the baudrate equation means there are only certain speeds
available. The highest:
BRR USART1(stlink) USART2(swlink)
16 4.50 Mbps 2.25 Mbps
17 4.235 Mbps 2.118 Mbps
18 4.000 Mbps 2.0 Mbps
19 3.789 Mbps 1.895 Mbps
20 3.600 Mbps 1.8 Mbps
...
24 3.0 Mbps 1.5 Mbps
...
36 2.0 Mbps 1.0 Mbps
...the USART will cope with some timing slip, but it's advisible to stay as
close to these values as you can. As the speed comes down the spread between
each valid value so mis-timing is less of an issue. The 'monitor traceswo
<x>' command will automatically find the closest divisor to the value you
set for the speed, so be aware the error could be significant.
Depending on what you're using to wake up SWO on the target side, you may
need code to get it into the correct mode and emitting data. You can do that
via gdb direct memory accesses, or from program code.
An example for a STM32F103 for the UART (NRZ) data format that we use;
/* STM32 specific configuration to enable the TRACESWO IO pin */
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;
AFIO->MAPR |= (2 << 24); // Disable JTAG to release TRACESWO
DBGMCU->CR |= DBGMCU_CR_TRACE_IOEN; // Enable IO trace pins
TPI->ACPR = 31; // Output bits at 72000000/(31+1)=2.25MHz.
TPI->SPPR = 2; // Use Async mode (1 for RZ/Manchester)
TPI-FFCR = 0; // Disable formatter
/* Configure instrumentation trace macroblock */
ITM->LAR = 0xC5ACCE55;
ITM->TCR = 1 << ITM_TCR_TraceBusID_Pos | ITM_TCR_SYNCENA_Msk |
ITM_TCR_ITMENA_Msk;
ITM->TER = 0xFFFFFFFF; // Enable all stimulus ports
Code for the STM32L476 might look like:
#define BAUDRATE 115200
DBGMCU->CR |= DBGMCU_CR_TRACE_IOEN; /* Enable IO pins for Async trace */
uint32_t divisor, clk_frequency;
clk_frequency = NutGetCpuClock();
divisor = clk_frequency / BAUDRATE;
divisor--;
TPI->CSPSR = 1; /* port size = 1 bit */
TPI->ACPR = divisor;
TPI->SPPR = 2; /*Use Async mode pin protocol */
TPI->FFCR = 0x00; /* Bypass the TPIU formatter and send output directly*/
/* Configure Trace Port Interface Unit */
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; // Enable access to registers
DWT->CTRL = 0x400003FE; // DWT needs to provide sync for ITM
ITM->LAR = 0xC5ACCE55; // Allow access to the Control Register
ITM->TPR = 0x0000000F; // Trace access privilege from user level code, please
ITM->TCR = 0x0001000D; // ITM_TCR_TraceBusID_Msk | ITM_TCR_DWTENA_Msk | ITM_TCR_SYNCENA_Msk | ITM_TCR_ITMENA_Msk
ITM->TER = 1; // Only Enable stimulus port 1
while(1) {
for (uint32_t i = 'A'; i <= 'Z'; i++) {
ITM_SendChar(i);
NutSleep(1);
}
}
If you're using RZ mode (e.g. on a genuine BMP) then you will need the trace
output speed to be quite a lot lower...in the order of 200kHz by means of
changing the divisor to something like 359. That's because the STM32F103
doesn't have a dedicated RZ decoder so it all has to be done in
software. The advantage of RZ is that the probe can adapt to the speed of
the target, so you don't have to set the speed on the probe in the monitor
traceswo command, and it will be tolerant of different speeds.
The SWO data appears on USB Interface 5, Endpoint 5.
SWOListen
=========
A program swolisten.c is found in ./scripts which will listen to this
endpoint, decode the datastream, and output it to a set of unix fifos which
can then be used as the input to other programs (e.g. cat, or something more
sophisticated like gnuplot, octave or whatever). This program doesn't care
if the data originates from a RZ or NRZ port, or at what speed.
Note that swolisten can be used with either BMP firmware, or with a
conventional TTL serial dongle. See at the bottom of this file for
information on how to use a dongle.
The command line to build the swolisten tool may look like:
E.g. for Ubuntu
gcc -I /usr/local/include/libusb-1.0 -L /usr/local/lib swolisten.c -o swolisten -lusb-1.0
E.g. For Opensuse:
gcc -I /usr/include/libusb-1.0 swolisten.c swolisten -std=gnu99 -g -Og -lusb-1.0
...you will obviously need to change the paths to your libusb files.
Attach to BMP to your PC:
Start gdb: "arm-none-eabi-gdb"
Choose bmp as target, like:
"target extended /dev/ttyACM0(*)"
Start SWO output: "mon traceswo"
If async SWO is used, give the baudrate your device sends
out as argument. 2.25 MBaud is the default, for the STM32L476 example above
the command would be: "mon traceswo 115200(*)".
Scan the SWD "mon swdp_scan"
Attach to the device: : "attach 1"
Start the program: "r".
(*) Your milage may vary
Now start swolisten without further options.
By default the tool will create fifos for the first 32 channels in a
directory swo (which you will need to create) as follows;
>ls swo/
chan00 chan02 chan04 chan06 chan08 chan0A chan0C chan0E chan10 chan12 chan14
chan16 chan18 chan1A chan1C chan1E chan01 chan03 chan05 chan07 chan09 chan0B
chan0D chan0F chan11 chan13 chan15 chan17 chan19 chan1B chan1D chan1F
>cat swo/channel0
<<OUTPUT FROM ITM Channel 0>>
With the F103 and L476 examples above, an endless stream of
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" should be seen. During reset of the target
device, no output will appear, but with release of reset output restarts.
Information about command line options can be found with the -h option.
swolisten is specifically designed to be 'hardy' to probe and target
disconnects and restarts (y'know, like you get in the real world). The
intention being to give you streams whenever it can get them. It does _not_
require gdb to be running. For the time being traceswo is not turned on by
default in the BMP to avoid possible interactions and making the overall
thing less reliable so You do need gdb to send the initial 'monitor
traceswo' to the probe, but beyond that there's no requirement for gdb to be
present.
Reliability
===========
A whole chunk of work has gone into making sure the dataflow over the SWO
link is reliable. The TL;DR is that the link _is_ reliable. There are
factors outside of our control (i.e. the USB bus you connect to) that could
potentially break the reliabilty but there's not too much we can do about
that since the SWO link is unidirectional (no opportunity for
re-transmits). The following section provides evidence for the claim that
the link is good;
A test 'mule' sends data flat out to the link at the maximum data rate of
2.25Mbps using a loop like the one below;
while (1)
{
for (uint32_t r=0; r<26; r++)
{
for (uint32_t g=0; g<31; g++)
{
ITM_SendChar('A'+r);
}
ITM_SendChar('\n');
}
}
100MB of data (more than 200MB of actual SWO packets, due to the encoding) was sent from the mule to the BMP where the
output from swolisten chan00 was cat'ted into a file;
>cat swo/chan00 > o
....this process was interrupted once the file had grown to 100MB. The first
and last lines were removed from it (these represent previously buffered
data and an incomplete packet at the point where the capture was
interrupted) and the resulting file analysed for consistency;
> sort o | uniq -c
The output was;
126462 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
126462 BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
126462 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
126462 DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
126461 EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
126461 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
126461 GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
126461 HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
126461 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
126461 JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
126461 KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
126461 LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
126461 MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
126461 NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
126461 OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
126461 PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
126461 QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
126461 RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
126461 SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
126461 TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
126461 UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
126461 VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
126461 WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
126461 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
126461 YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
126461 ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
(On inspection, the last line of recorded data was indeed a 'D' line).
Swolisten, using a TTL Serial Dongle
====================================
The NRZ data that comes out of the SWO is just UART formatted, but in a
frame. swolisten has been extended to accomodate TTL Serial Dongles that
can pick this up. Success has been had with CP2102 dongles at up to 921600
baud.
To use this mode just connect SWO to the RX pin of your dongle, and start
swolisten with parameters representing the speed and port. An example;
>./swolisten -p /dev/cu.SLAB_USBtoUART -v -b swo/ -s 921600
Any individual dongle will only support certain baudrates (Generally
multiples of 115200) so you may have to experiment to find the best
supported ones. For the CP2102 dongle 1.3824Mbps wasn't supported and
1.8432Mbps returned corrupted data.
Please email dave@marples.net with information about dongles you find work
well and at what speed.
Further information
===================
SWO is a wide field. Read e.g. the blogs around SWD on
http://shadetail.com/blog/swo-starting-the-steroids/
An open source program suite for SWO under active development is
https://github.com/mubes/orbuculum

View File

@ -0,0 +1,8 @@
# Black Magic Probe
# there are two connections, one for GDB and one for UART debugging
# copy this to /etc/udev/rules.d/99-blackmagic.rules
# and run /usr/sbin/udevadm control --reload-rules
SUBSYSTEM=="tty", ACTION=="add", ATTRS{interface}=="Black Magic GDB Server", SYMLINK+="ttyBmpGdb"
SUBSYSTEM=="tty", ACTION=="add", ATTRS{interface}=="Black Magic UART Port", SYMLINK+="ttyBmpTarg"
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="1d50", ATTR{idProduct}=="6017", MODE="0666"
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="1d50", ATTR{idProduct}=="6018", MODE="0666"

89
driver/blackmagic.inf Normal file
View File

@ -0,0 +1,89 @@
; Windows USB CDC ACM driver setup file.
; Copyright (C) 2004 Al Borchers (alborchers@steinerpoint.com)
; Taken from Linux documentation, modified for Black Magic debug probe
; by Gareth McMullin <gareth@blacksphere.co.nz>
; This provides the driver information for the GDB and UART interfaces to
; be presented as virtual serial ports in Windows.
; Common to Windows 32- and 64-bit systems
[Version]
Signature="$Windows NT$"
Class=Ports
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
Provider=%BLACKMAGIC%
DriverVer=28/12/2011,0.0.1.1
[Manufacturer]
%VendorName%=DeviceList, NTamd64
[Strings]
VendorName = "Black Magic Debug"
BLACKMAGICGDB = "Black Magic GDB Server"
BLACKMAGICUART = "Black Magic UART Port"
BLACKMAGIC_DISPLAY_NAME = "Black Magic Probe Driver"
[DeviceList]
%BLACKMAGICGDB%=DriverInstall, USB\VID_1d50&PID_6018&Rev_0100&MI_00
%BLACKMAGICUART%=DriverInstall, USB\VID_1d50&PID_6018&Rev_0100&MI_02
[DeviceList.NTamd64]
%BLACKMAGICGDB%=DriverInstall, USB\VID_1d50&PID_6018&Rev_0100&MI_00
%BLACKMAGICUART%=DriverInstall, USB\VID_1d50&PID_6018&Rev_0100&MI_02
[DestinationDirs]
DefaultDestDir=10,System32\Drivers
; Windows 32-bit sections
;~~~~~~~~~~~~~~~~~~~~~~~~~
[DriverInstall.nt]
CopyFiles=DriverCopyFiles.nt
AddReg=DriverInstall.nt.AddReg
[DriverCopyFiles.nt]
usbser.sys,,,0x20
[DriverInstall.nt.AddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,usbser.sys
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
[DriverInstall.nt.Services]
AddService = usbser,0x0002,DriverService.nt
[DriverService.nt]
DisplayName = %BLACKMAGIC_DISPLAY_NAME%
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
StartType = 3 ; SERVICE_DEMAND_START
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
ServiceBinary = %10%\System32\Drivers\usbser.sys
LoadOrderGroup = Base
; Windows 64-bit sections
;~~~~~~~~~~~~~~~~~~~~~~~~~
[DriverInstall.NTamd64]
CopyFiles=DriverCopyFiles.NTamd64
AddReg=DriverInstall.NTamd64.AddReg
[DriverCopyFiles.NTamd64]
usbser.sys,,,0x20
[DriverInstall.NTamd64.AddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,usbser.sys
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
[DriverInstall.NTamd64.Services]
AddService = usbser,0x0002,DriverService.NTamd64
[DriverService.NTamd64]
DisplayName = %BLACKMAGIC_DISPLAY_NAME%
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
StartType = 3 ; SERVICE_DEMAND_START
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
ServiceBinary = %10%\System32\Drivers\usbser.sys
LoadOrderGroup = Base

View File

@ -0,0 +1,161 @@
; blackmagic_upgrade.inf
; Copyright (c) 2010 libusb-win32 (GNU LGPL)
[Strings]
DeviceName = "Black Magic Firmware Upgrade"
DeviceNameDFU = "Black Magic Probe (Upgrade)"
DeviceNameTPA = "Black Magic Trace Capture"
VendorName = "Black Magic Debug"
SourceName = "Black Magic Firmware Upgrade Install Disk"
DeviceID = "VID_1d50&PID_6018&Rev_0100&MI_04"
DeviceIDDFU= "VID_1d50&PID_6017&Rev_0100"
DeviceIDTPA= "VID_1d50&PID_6018&Rev_0100&MI_05"
DeviceIDDFUold= "VID_0483&PID_df11&Rev_0200"
[Version]
Signature = "$Windows NT$"
Class = "libusb-win32 devices"
ClassGuid = {EB781AAF-9C70-4523-A5DF-642A87ECA567}
Provider = "libusb-win32"
CatalogFile = blackmagic_upgrade.cat
DriverVer = 01/18/2012, 1.2.6.0
[ClassInstall32]
Addreg = libusb_class_install_add_reg
[libusb_class_install_add_reg]
HKR,,,0,"libusb-win32 devices"
HKR,,Icon,,-20
[Manufacturer]
%VendorName% = Devices, NT, NTAMD64, NTIA64
;--------------------------------------------------------------------------
; libusb-win32 files
;--------------------------------------------------------------------------
[SourceDisksNames]
1 = %SourceName%
[SourceDisksFiles.x86]
libusb0.sys = 1,x86
libusb0_x86.dll = 1,x86
[SourceDisksFiles.amd64]
libusb0.sys = 1,amd64
libusb0.dll = 1,amd64
libusb0_x86.dll = 1,x86
[SourceDisksFiles.ia64]
libusb0.sys = 1,ia64
libusb0.dll = 1,ia64
libusb0_x86.dll = 1,x86
[DestinationDirs]
libusb_files_sys = 10,system32\drivers
libusb_files_dll = 10,system32
libusb_files_dll_wow64 = 10,syswow64
libusb_files_dll_x86 = 10,system32
[libusb_files_sys]
libusb0.sys
[libusb_files_dll]
libusb0.dll
[libusb_files_dll_x86]
libusb0.dll, libusb0_x86.dll
[libusb_files_dll_wow64]
libusb0.dll, libusb0_x86.dll
;--------------------------------------------------------------------------
; libusb-win32 device driver
;--------------------------------------------------------------------------
[LIBUSB_WIN32_DEV.NT]
CopyFiles = libusb_files_sys, libusb_files_dll_x86
[LIBUSB_WIN32_DEV.NTAMD64]
CopyFiles = libusb_files_sys, libusb_files_dll, libusb_files_dll_wow64
[LIBUSB_WIN32_DEV.NTIA64]
CopyFiles = libusb_files_sys, libusb_files_dll, libusb_files_dll_wow64
[LIBUSB_WIN32_DEV.NT.HW]
DelReg = libusb_del_reg_hw
AddReg = libusb_add_reg_hw
[LIBUSB_WIN32_DEV.NTAMD64.HW]
DelReg = libusb_del_reg_hw
AddReg = libusb_add_reg_hw
[LIBUSB_WIN32_DEV.NTIA64.HW]
DelReg = libusb_del_reg_hw
AddReg = libusb_add_reg_hw
[LIBUSB_WIN32_DEV.NT.Services]
AddService = libusb0, 0x00000002, libusb_add_service
[LIBUSB_WIN32_DEV.NTAMD64.Services]
AddService = libusb0, 0x00000002, libusb_add_service
[LIBUSB_WIN32_DEV.NTIA64.Services]
AddService = libusb0, 0x00000002, libusb_add_service
; Older versions of this .inf file installed filter drivers. They are not
; needed any more and must be removed
[libusb_del_reg_hw]
HKR,,LowerFilters
HKR,,UpperFilters
; libusb-win32 device properties
[libusb_add_reg_hw]
HKR,,SurpriseRemovalOK,0x00010001,1
; (Optional) the usb configuration value to select when this device
; is started. If this key does not exist the first config is selected.
;HKR,,InitialConfigValue,0x00010001,<your config value>
;--------------------------------------------------------------------------
; libusb-win32 service
;--------------------------------------------------------------------------
[libusb_add_service]
DisplayName = "libusb-win32 - Kernel Driver 01/18/2012 1.2.6.0"
ServiceType = 1
StartType = 3
ErrorControl = 0
ServiceBinary = %12%\libusb0.sys
;--------------------------------------------------------------------------
; libusb-win32 devices
;--------------------------------------------------------------------------
; Hardware IDs in a 'Devices' section can be installed by libusb-win32
; using usb_install_driver_np(), usb_install_driver_np_rundll(), or the
; inf-wizard utility.
;
[Devices]
%DeviceName% = LIBUSB_WIN32_DEV, USB\%DeviceID%
%DeviceNameDFU% = LIBUSB_WIN32_DEV, USB\%DeviceIDDFU%
%DeviceNameTPA% = LIBUSB_WIN32_DEV, USB\%DeviceIDTPA%
%DeviceNameDFU% = LIBUSB_WIN32_DEV, USB\%DeviceIDDFUold%
[Devices.NT]
%DeviceName% = LIBUSB_WIN32_DEV.NT, USB\%DeviceID%
%DeviceNameDFU% = LIBUSB_WIN32_DEV.NT, USB\%DeviceIDDFU%
%DeviceNameTPA% = LIBUSB_WIN32_DEV.NT, USB\%DeviceIDTPA%
%DeviceNameDFU% = LIBUSB_WIN32_DEV.NT, USB\%DeviceIDDFUold%
[Devices.NTAMD64]
%DeviceName% = LIBUSB_WIN32_DEV.NTAMD64, USB\%DeviceID%
%DeviceNameDFU% = LIBUSB_WIN32_DEV.NTAMD64, USB\%DeviceIDDFU%
%DeviceNameTPA% = LIBUSB_WIN32_DEV.NTAMD64, USB\%DeviceIDTPA%
%DeviceNameDFU% = LIBUSB_WIN32_DEV.NTAMD64, USB\%DeviceIDDFUold%
[Devices.NTIA64]
%DeviceName% = LIBUSB_WIN32_DEV.NTIA64, USB\%DeviceID%
%DeviceNameDFU% = LIBUSB_WIN32_DEV.NTIA64, USB\%DeviceIDDFU%
%DeviceNameTPA% = LIBUSB_WIN32_DEV.NTIA64, USB\%DeviceIDTPA%
%DeviceNameDFU% = LIBUSB_WIN32_DEV.NTIA64, USB\%DeviceIDDFUold%

View File

@ -1,5 +0,0 @@
These are the assembler routines for executing a flash write
on the supported targets. They are kept here for reference, but
are not used, as the compiled binary code is included in the
target drivers.

View File

@ -1,42 +0,0 @@
_start:
ldr r0, _flashbase
ldr r1, _addr
mov r2, pc
add r2, #(_data - . - 2)
ldr r3, _size
ldr r5, _flash_write_cmd
_next:
cbz r3, _done
@ Write address to FMA
str r1, [r0]
@ Write data to FMD
ldr r4, [r2]
str r4, [r0, #4]
@ Write WRITE bit to FMC
str r5, [r0, #8]
_wait: @ Wait for WRITE bit to clear
ldr r4, [r0, #8]
mov r6, #1
tst r4, r6
bne _wait
sub r3, #1
add r1, #4
add r2, #4
b _next
_done:
bkpt
@.align 4
.org 0x28
_flashbase:
.word 0x400FD000
_flash_write_cmd:
.word 0xA4420001
_addr:
.word 0
_size:
.word 4
_data:
.string "Hello World!\n\0\0\0"

View File

@ -1,42 +0,0 @@
.global _start
_start:
ldr r0, _flashbase
ldr r1, _addr
mov r2, pc
add r2, #(_data - . - 2)
ldr r3, _size
mov r5, #1
_next:
cbz r3, _done
@ Write PG command to FLASH_CR
str r5, [r0, #0x10]
@ Write data to flash (half-word)
ldrh r4, [r2]
strh r4, [r1]
_wait: @ Wait for BSY bit to clear
ldr r4, [r0, #0x0C]
mov r6, #1
tst r4, r6
bne _wait
sub r3, #2
add r1, #2
add r2, #2
b _next
_done:
bkpt
@.align 4
.org 0x28
_flashbase:
.word 0x40022000
_addr:
.word 0
_size:
.word 12
_data:
.word 0xAAAAAAAA
.word 0xBBBBBBBB
.word 0xCCCCCCCC

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1
libopencm3 Submodule

@ -0,0 +1 @@
Subproject commit 63573143ef7e1b037d1f0c5baedc5264e12562b8

BIN
schematic/bm-sam-a04.pdf Normal file

Binary file not shown.

View File

@ -1,4 +1,4 @@
#!/usr/bin/python #!/usr/bin/env python3
# #
# bootprog.py: STM32 SystemMemory Production Programmer -- version 1.1 # bootprog.py: STM32 SystemMemory Production Programmer -- version 1.1
# Copyright (C) 2011 Black Sphere Technologies # Copyright (C) 2011 Black Sphere Technologies
@ -23,107 +23,105 @@ from time import sleep
class stm32_boot: class stm32_boot:
def __init__(self, port, baud=115200): def __init__(self, port, baud=115200):
self.serial = serial.Serial(port, baud, 8, 'E', 1, self.serial = serial.Serial(port, baud, 8, 'E', 1,
timeout=1) timeout=1)
# Turn on target device in SystemMemory boot mode # Turn on target device in SystemMemory boot mode
self.serial.setDTR(1) self.serial.setDTR(1)
sleep(0.1); sleep(0.1)
self._sync() self._sync()
def _sync(self): def _sync(self):
# Send sync byte # Send sync byte
#print "sending sync byte" #print("sending sync byte")
self.serial.write("\x7F") self.serial.write(b"\x7f")
self._checkack() self._checkack()
def _sendcmd(self, cmd): def _sendcmd(self, cmd):
if type(cmd) == int: cmd = ord(cmd)
cmd = chr(cmd) cmd = bytes((cmd, cmd ^ 0xff))
cmd += chr(ord(cmd) ^ 0xff) #print("sendcmd:", repr(cmd))
#print "sendcmd:", repr(cmd)
self.serial.write(cmd) self.serial.write(cmd)
def _send(self, data): def _send(self, data):
csum = 0 csum = 0
for c in data: csum ^= ord(c) for c in data: csum ^= c
data = data + chr(csum) data = data + bytes((csum,))
#print "sending:", repr(data) #print("sending:", repr(data))
self.serial.write(data) self.serial.write(data)
def _checkack(self): def _checkack(self):
ACK = "\x79" ACK = b"\x79"
b = self.serial.read(1) b = self.serial.read(1)
if b != ACK: raise Exception("Invalid ack: %r" % b) if b != ACK: raise Exception("Invalid ack: %r" % b)
#print "got ack!" #print("got ack!")
def get(self): def get(self):
self._sendcmd("\x00") self._sendcmd(b"\x00")
self._checkack() self._checkack()
num = ord(self.serial.read(1)) num = self.serial.read(1)[0]
data = self.serial.read(num+1) data = self.serial.read(num+1)
self._checkack() self._checkack()
return data return data
def eraseall(self): def eraseall(self):
# Send erase cmd # Send erase cmd
self._sendcmd("\x43") self._sendcmd(b"\x43")
self._checkack() self._checkack()
# Global erase # Global erase
self._sendcmd("\xff") self._sendcmd(b"\xff")
self._checkack() self._checkack()
def read(self, addr, len): def read(self, addr, len):
# Send read cmd # Send read cmd
self._sendcmd("\x11") self._sendcmd(b"\x11")
self._checkack() self._checkack()
# Send address # Send address
self._send(struct.pack(">L", addr)) self._send(struct.pack(">L", addr))
self._checkack() self._checkack()
# Send length # Send length
self._sendcmd(chr(len-1)) self._sendcmd(bytes((len-1,)))
self._checkack() self._checkack()
return self.serial.read(len) return self.serial.read(len)
def write(self, addr, data): def write(self, addr, data):
# Send write cmd # Send write cmd
self._sendcmd("\x31") self._sendcmd(b"\x31")
self._checkack() self._checkack()
# Send address # Send address
self._send(struct.pack(">L", addr)) self._send(struct.pack(">L", addr))
self._checkack() self._checkack()
# Send data # Send data
self._send(chr(len(data)-1) + data) self._send(bytes((len(data)-1,)) + data)
self._checkack() self._checkack()
def write_protect(self, sectors): def write_protect(self, sectors):
# Send WP cmd # Send WP cmd
self._sendcmd("\x63") self._sendcmd(b"\x63")
self._checkack() self._checkack()
# Send sector list # Send sector list
self._send(chr(len(sectors)-1) + "".join(chr(i) for i in sectors)) self._send(bytes((len(sectors)-1,)) + bytes(sectors))
self._checkack() self._checkack()
# Resync after system reset # Resync after system reset
self._sync() self._sync()
def write_unprotect(self): def write_unprotect(self):
self._sendcmd("\x73") self._sendcmd(b"\x73")
self._checkack() self._checkack()
self._checkack() self._checkack()
self._sync() self._sync()
def read_protect(self): def read_protect(self):
self._sendcmd("\x82") self._sendcmd(b"\x82")
self._checkack() self._checkack()
self._checkack() self._checkack()
self._sync() self._sync()
def read_unprotect(self): def read_unprotect(self):
self._sendcmd("\x92") self._sendcmd(b"\x92")
self._checkack() self._checkack()
self._checkack() self._checkack()
self._sync() self._sync()
@ -133,12 +131,12 @@ if __name__ == "__main__":
from sys import stdout, argv, platform from sys import stdout, argv, platform
from getopt import getopt from getopt import getopt
if platform == "linux2": if platform == "linux":
print "\x1b\x5b\x48\x1b\x5b\x32\x4a" # clear terminal screen print("\x1b\x5b\x48\x1b\x5b\x32\x4a") # clear terminal screen
print "STM32 SystemMemory Production Programmer -- version 1.1" print("STM32 SystemMemory Production Programmer -- version 1.1")
print "Copyright (C) 2011 Black Sphere Technologies" print("Copyright (C) 2011 Black Sphere Technologies")
print "License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>" print("License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>")
print print()
dev = "COM1" if platform == "win32" else "/dev/ttyUSB0" dev = "COM1" if platform == "win32" else "/dev/ttyUSB0"
baud = 115200 baud = 115200
@ -152,38 +150,38 @@ if __name__ == "__main__":
progfile = args[0] progfile = args[0]
except: except:
print "Usage %s [-d <dev>] [-b <baudrate>] [-a <address>] <filename>" % argv[0] print("Usage %s [-d <dev>] [-b <baudrate>] [-a <address>] <filename>" % argv[0])
print "\t-d : Use target on interface <dev> (default: %s)" % dev print("\t-d : Use target on interface <dev> (default: %s)" % dev)
print "\t-b : Set device baudrate (default: %d)" % baud print("\t-b : Set device baudrate (default: %d)" % baud)
print "\t-a : Set programming address (default: 0x%X)" % addr print("\t-a : Set programming address (default: 0x%X)" % addr)
print print()
exit(-1) exit(-1)
prog = open(progfile, "rb").read() prog = open(progfile, "rb").read()
boot = stm32_boot(dev, baud) boot = stm32_boot(dev, baud)
cmds = boot.get() cmds = boot.get()
print "Target bootloader version: %d.%d\n" % (ord(cmds[0]) >> 4, ord(cmds[0]) % 0xf) print("Target bootloader version: %d.%d\n" % (cmds[0] >> 4, cmds[0] % 0xf))
print "Removing device protection..." print("Removing device protection...")
boot.read_unprotect() boot.read_unprotect()
boot.write_unprotect() boot.write_unprotect()
print "Erasing target device..." print("Erasing target device...")
boot.eraseall() boot.eraseall()
addr = 0x8000000 addr = 0x8000000
while prog: while prog:
print ("Programming address 0x%08X..0x%08X...\r" % (addr, addr + min(len(prog), 255))), print("Programming address 0x%08X..0x%08X...\r" % (addr, addr + min(len(prog), 255)), end=' ')
stdout.flush(); stdout.flush()
boot.write(addr, prog[:256]) boot.write(addr, prog[:256])
addr += 256 addr += 256
prog = prog[256:] prog = prog[256:]
print print
print "Enabling device protection..." print("Enabling device protection...")
boot.write_protect(range(0,2)) boot.write_protect(range(0,2))
#boot.read_protect() #boot.read_protect()
print "All operations completed." print("All operations completed.")
print print

149
scripts/dfu-convert.py Executable file
View File

@ -0,0 +1,149 @@
#!/usr/bin/env python3
# Written by Antonio Galea - 2010/11/18
# Distributed under Gnu LGPL 3.0
# see http://www.gnu.org/licenses/lgpl-3.0.txt
import sys,struct,zlib,os
from optparse import OptionParser
from intelhex import IntelHex
DEFAULT_DEVICE="0x0483:0xdf11"
def named(tuple,names):
return dict(zip(names.split(),tuple))
def consume(fmt,data,names):
n = struct.calcsize(fmt)
return named(struct.unpack(fmt,data[:n]),names),data[n:]
def cstring(string):
return string.split(b'\0',1)[0]
def compute_crc(data):
return 0xFFFFFFFF & -zlib.crc32(data) -1
def parse(file,dump_images=False):
print('File: "%s"' % file)
data = open(file,'rb').read()
crc = compute_crc(data[:-4])
prefix, data = consume('<5sBIB',data,'signature version size targets')
print('%(signature)r v%(version)d, image size: %(size)d, targets: %(targets)d' % prefix)
for t in range(prefix['targets']):
tprefix, data = consume('<6sBI255s2I',data,'signature altsetting named name size elements')
tprefix['num'] = t
if tprefix['named']:
tprefix['name'] = cstring(tprefix['name'])
else:
tprefix['name'] = b''
print('%(signature)r %(num)d, alt setting: %(altsetting)r, name: %(name)r, size: %(size)d, elements: %(elements)d' % tprefix)
tsize = tprefix['size']
target, data = data[:tsize], data[tsize:]
for e in range(tprefix['elements']):
eprefix, target = consume('<2I',target,'address size')
eprefix['num'] = e
print(' %(num)d, address: 0x%(address)08x, size: %(size)d' % eprefix)
esize = eprefix['size']
image, target = target[:esize], target[esize:]
if dump_images:
out = '%s.target%d.image%d.bin' % (file,t,e)
open(out,'wb').write(image)
print(' DUMPED IMAGE TO "%s"' % out)
if len(target):
print("target %d: PARSE ERROR" % t)
suffix = named(struct.unpack('<4H3sBI',data[:16]),'device product vendor dfu ufd len crc')
print('usb: %(vendor)04x:%(product)04x, device: 0x%(device)04x, dfu: 0x%(dfu)04x, %(ufd)r, %(len)d, 0x%(crc)08x' % suffix)
if crc != suffix['crc']:
print("CRC ERROR: computed crc32 is 0x%08x" % crc)
data = data[16:]
if data:
print("PARSE ERROR")
def build(file,targets,device=DEFAULT_DEVICE):
data = b''
for t,target in enumerate(targets):
tdata = b''
for image in target:
tdata += struct.pack('<2I',image['address'],len(image['data']))+image['data']
trgt = b'Target'
st = b'ST...'
tdata = struct.pack('<6sBI255s2I',trgt,0,1,st,len(tdata),len(target)) + tdata
data += tdata
dfu_se = b'DfuSe'
ufd = b'UFD'
data = struct.pack('<5sBIB',dfu_se,1,len(data)+11,len(targets)) + data
v,d=map(lambda x: int(x,0) & 0xFFFF, device.split(':',1))
data += struct.pack('<4H3sB',0,d,v,0x011a,ufd,16)
crc = compute_crc(data)
data += struct.pack('<I',crc)
open(file,'wb').write(data)
if __name__=="__main__":
usage = """
%prog [-d|--dump] infile.dfu
%prog {-b|--build} address:file.bin [-b address:file.bin ...] [{-D|--device}=vendor:device] outfile.dfu
%prog {-i|--ihex} file.hex [-i file.hex ...] [{-D|--device}=vendor:device] outfile.dfu"""
parser = OptionParser(usage=usage)
parser.add_option("-b", "--build", action="append", dest="binfiles",
help="build a DFU file from given BINFILES", metavar="BINFILES")
parser.add_option("-i", "--ihex", action="append", dest="hexfiles",
help="build a DFU file from given HEXFILES", metavar="HEXFILES")
parser.add_option("-D", "--device", action="store", dest="device",
help="build for DEVICE, defaults to %s" % DEFAULT_DEVICE, metavar="DEVICE")
parser.add_option("-d", "--dump", action="store_true", dest="dump_images",
default=False, help="dump contained images to current directory")
(options, args) = parser.parse_args()
if (options.binfiles or options.hexfiles) and len(args)==1:
target = []
if options.binfiles:
for arg in options.binfiles:
try:
address,binfile = arg.split(':',1)
except ValueError:
print("Address:file couple '%s' invalid." % arg)
sys.exit(1)
try:
address = int(address,0) & 0xFFFFFFFF
except ValueError:
print("Address %s invalid." % address)
sys.exit(1)
if not os.path.isfile(binfile):
print("Unreadable file '%s'." % binfile)
sys.exit(1)
target.append({ 'address': address, 'data': open(binfile,'rb').read() })
if options.hexfiles:
for hex in options.hexfiles:
ih = IntelHex(hex)
address = ih.minaddr()
data = ih.tobinstr()
try:
address = address & 0xFFFFFFFF
except ValueError:
print("Address %s invalid." % address)
sys.exit(1)
target.append({ 'address': address, 'data': data })
outfile = args[0]
device = DEFAULT_DEVICE
if options.device:
device=options.device
try:
v,d=map(lambda x: int(x,0) & 0xFFFF, device.split(':',1))
except:
print("Invalid device '%s'." % device)
sys.exit(1)
build(outfile,[target],device)
elif len(args)==1:
infile = args[0]
if not os.path.isfile(infile):
print("Unreadable file '%s'." % infile)
sys.exit(1)
parse(infile, dump_images=options.dump_images)
else:
parser.print_help()
sys.exit(1)

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python3
# #
# dfu.py: Access USB DFU class devices # dfu.py: Access USB DFU class devices
# Copyright (C) 2009 Black Sphere Technologies # Copyright (C) 2009 Black Sphere Technologies
# Written by Gareth McMullin <gareth@blacksphere.co.nz> # Written by Gareth McMullin <gareth@blacksphere.co.nz>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
@ -17,12 +17,12 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import usb import usb
DFU_DETACH_TIMEOUT = 1000 DFU_DETACH_TIMEOUT = 1000
# DFU Requests # DFU Requests
DFU_DETACH = 0x00 DFU_DETACH = 0x00
DFU_DNLOAD = 0x01 DFU_DNLOAD = 0x01
DFU_UPLOAD = 0x02 DFU_UPLOAD = 0x02
@ -62,7 +62,7 @@ DFU_STATUS_ERROR_POR = 0x0d
DFU_STATUS_ERROR_UNKNOWN = 0x0e DFU_STATUS_ERROR_UNKNOWN = 0x0e
DFU_STATUS_ERROR_STALLEDPKT = 0x0f DFU_STATUS_ERROR_STALLEDPKT = 0x0f
class dfu_status(object): class dfu_status:
def __init__(self, buf): def __init__(self, buf):
self.bStatus = buf[0] self.bStatus = buf[0]
self.bwPollTimeout = buf[1] + (buf[2]<<8) + (buf[3]<<16) self.bwPollTimeout = buf[1] + (buf[2]<<8) + (buf[3]<<16)
@ -70,7 +70,7 @@ class dfu_status(object):
self.iString = buf[5] self.iString = buf[5]
class dfu_device(object): class dfu_device:
def __init__(self, dev, conf, iface): def __init__(self, dev, conf, iface):
self.dev = dev self.dev = dev
self.conf = conf self.conf = conf
@ -84,41 +84,43 @@ class dfu_device(object):
self.index = self.iface.interfaceNumber self.index = self.iface.interfaceNumber
else: self.index = self.iface else: self.index = self.iface
def release(self):
self.handle.releaseInterface()
def detach(self, wTimeout=255): def detach(self, wTimeout=255):
self.handle.controlMsg(usb.ENDPOINT_OUT | usb.TYPE_CLASS | self.handle.controlMsg(usb.ENDPOINT_OUT | usb.TYPE_CLASS |
usb.RECIP_INTERFACE, DFU_DETACH, usb.RECIP_INTERFACE, DFU_DETACH,
None, value=wTimeout, index=self.index) None, value=wTimeout, index=self.index)
def download(self, wBlockNum, data): def download(self, wBlockNum, data):
self.handle.controlMsg(usb.ENDPOINT_OUT | usb.TYPE_CLASS | self.handle.controlMsg(usb.ENDPOINT_OUT | usb.TYPE_CLASS |
usb.RECIP_INTERFACE, DFU_DNLOAD, usb.RECIP_INTERFACE, DFU_DNLOAD,
data, value=wBlockNum, index=self.index) data, value=wBlockNum, index=self.index)
def upload(self, wBlockNum, length): def upload(self, wBlockNum, length):
return self.handle.controlMsg(usb.ENDPOINT_IN | return self.handle.controlMsg(usb.ENDPOINT_IN |
usb.TYPE_CLASS | usb.RECIP_INTERFACE, DFU_UPLOAD, usb.TYPE_CLASS | usb.RECIP_INTERFACE, DFU_UPLOAD,
length, value=wBlockNum, index=self.index) length, value=wBlockNum, index=self.index)
def get_status(self): def get_status(self):
buf = self.handle.controlMsg(usb.ENDPOINT_IN | buf = self.handle.controlMsg(usb.ENDPOINT_IN |
usb.TYPE_CLASS | usb.RECIP_INTERFACE, DFU_GETSTATUS, usb.TYPE_CLASS | usb.RECIP_INTERFACE, DFU_GETSTATUS,
6, index=self.index) 6, index=self.index)
return dfu_status(buf) return dfu_status(buf)
def clear_status(self): def clear_status(self):
self.handle.controlMsg(usb.ENDPOINT_OUT | usb.TYPE_CLASS | self.handle.controlMsg(usb.ENDPOINT_OUT | usb.TYPE_CLASS |
usb.RECIP_INTERFACE, DFU_CLRSTATUS, usb.RECIP_INTERFACE, DFU_CLRSTATUS,
"", index=0) "", index=0)
def get_state(self): def get_state(self):
buf = self.handle.controlMsg(usb.ENDPOINT_IN | buf = self.handle.controlMsg(usb.ENDPOINT_IN |
usb.TYPE_CLASS | usb.RECIP_INTERFACE, DFU_GETSTATE, usb.TYPE_CLASS | usb.RECIP_INTERFACE, DFU_GETSTATE,
1, index=self.index) 1, index=self.index)
return buf[0] return buf[0]
def abort(self): def abort(self):
self.handle.controlMsg(usb.ENDPOINT_OUT | usb.TYPE_CLASS | self.handle.controlMsg(usb.ENDPOINT_OUT | usb.TYPE_CLASS |
usb.RECIP_INTERFACE, DFU_ABORT, usb.RECIP_INTERFACE, DFU_ABORT,
None, index=self.index) None, index=self.index)
@ -136,7 +138,7 @@ class dfu_device(object):
if status.bState == STATE_DFU_IDLE: if status.bState == STATE_DFU_IDLE:
return True return True
if ((status.bState == STATE_DFU_DOWNLOAD_SYNC) or if ((status.bState == STATE_DFU_DOWNLOAD_SYNC) or
(status.bState == STATE_DFU_DOWNLOAD_IDLE) or (status.bState == STATE_DFU_DOWNLOAD_IDLE) or
(status.bState == STATE_DFU_MANIFEST_SYNC) or (status.bState == STATE_DFU_MANIFEST_SYNC) or
(status.bState == STATE_DFU_UPLOAD_IDLE) or (status.bState == STATE_DFU_UPLOAD_IDLE) or
@ -155,7 +157,7 @@ class dfu_device(object):
if ((status.bState == STATE_APP_DETACH) or if ((status.bState == STATE_APP_DETACH) or
(status.bState == STATE_DFU_MANIFEST_WAIT_RESET)): (status.bState == STATE_DFU_MANIFEST_WAIT_RESET)):
usb.reset(self.handle) usb.reset(self.handle)
return False return False
raise Exception raise Exception
@ -176,16 +178,16 @@ def finddevs():
if __name__ == "__main__": if __name__ == "__main__":
devs = finddevs() devs = finddevs()
if not devs: if not devs:
print "No devices found!" print("No devices found!")
exit(-1) exit(-1)
for dfu in devs: for dfu in devs:
handle = dfu[0].open() handle = dfu[0].open()
man = handle.getString(dfu[0].iManufacturer, 30) man = handle.getString(dfu[0].iManufacturer, 30)
product = handle.getString(dfu[0].iProduct, 30) product = handle.getString(dfu[0].iProduct, 30)
print "Device %s: ID %04x:%04x %s - %s" % (dfu[0].filename, print("Device %s: ID %04x:%04x %s - %s" % (dfu[0].filename,
dfu[0].idVendor, dfu[0].idProduct, man, product) dfu[0].idVendor, dfu[0].idProduct, man, product))
print "%r, %r" % (dfu[1], dfu[2]) print("%r, %r" % (dfu[1], dfu[2]))

View File

@ -1,9 +1,9 @@
#!/usr/bin/python #!/usr/bin/env python3
# #
# gdb.py: Python module for low level GDB protocol implementation # gdb.py: Python module for low level GDB protocol implementation
# Copyright (C) 2009 Black Sphere Technologies # Copyright (C) 2009 Black Sphere Technologies
# Written by Gareth McMullin <gareth@blacksphere.co.nz> # Written by Gareth McMullin <gareth@blacksphere.co.nz>
# #
# 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
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
@ -24,24 +24,18 @@ import struct
import time import time
def hexify(s): def hexify(s):
"""Convert a binary string into hex representation""" """Convert a bytes object into hex bytes representation"""
ret = '' return s.hex().encode()
for c in s:
ret += "%02X" % ord(c)
return ret
def unhexify(s): def unhexify(s):
"""Convert a hex string into binary representation""" """Convert a hex-encoded bytes into bytes object"""
ret = '' return bytes.fromhex(s.decode())
for i in range(0, len(s), 2):
ret += chr(int(s[i:i+2], 16))
return ret
class FakeSocket: class FakeSocket:
"""Emulate socket functions send and recv on a file object""" """Emulate socket functions send and recv on a file object"""
def __init__(self, file): def __init__(self, file):
self.file = file self.file = file
def send(self, data): def send(self, data):
self.file.write(data) self.file.write(data)
@ -52,148 +46,186 @@ class Target:
def __init__(self, sock): def __init__(self, sock):
if "send" in dir(sock): if "send" in dir(sock):
self.sock = sock self.sock = sock
else: else:
self.sock = FakeSocket(sock) self.sock = FakeSocket(sock)
self.PacketSize=0x100 # default
def getpacket(self): def getpacket(self):
"""Return the first correctly received packet from GDB target""" """Return the first correctly received packet from GDB target"""
while True: while True:
while self.sock.recv(1) != '$': pass while self.sock.recv(1) != b'$':
pass
csum = 0 csum = 0
packet = '' packet = [] # list-of-small-int
while True: while True:
c = self.sock.recv(1) c, = self.sock.recv(1)
if c == '#': break if c == ord('#'):
break
if c == '$': if c == ord('$'):
packet = '' packet = []
csum = 0 csum = 0
continue continue
if c == '}': if c == ord('}'):
c = self.sock.recv(1) c, = self.sock.recv(1)
csum += ord(c) + ord('}') csum += c + ord('}')
packet += chr(ord(c) ^ 0x20) packet.append(c ^ 0x20)
continue continue
packet += c packet.append(c)
csum += ord(c) csum += c
if (csum & 0xFF) == int(self.sock.recv(2),16): break if (csum & 0xFF) == int(self.sock.recv(2),16):
break
self.sock.send('-') self.sock.send(b'-')
self.sock.send('+')
return packet
self.sock.send(b'+')
return bytes(packet)
def putpacket(self, packet): def putpacket(self, packet):
"""Send packet to GDB target and wait for acknowledge""" """Send packet to GDB target and wait for acknowledge
packet is bytes or string"""
if type(packet) == str:
packet = packet.encode()
while True: while True:
self.sock.send('$') out = []
csum = 0
for c in packet: for c in packet:
if (c == '$') or (c == '#') or (c == '}'): if (c in b'$#}'):
self.sock.send('}') out.append(ord('}'))
self.sock.send(chr(ord(c) ^ 0x20)) out.append(c ^ 0x20)
csum += (ord(c) ^ 0x20) + ord('}')
else: else:
self.sock.send(c) out.append(c)
csum += ord(c)
self.sock.send('#') csum = sum(out)
self.sock.send("%02X" % (csum & 0xFF)) outb = b'$'+bytes(out)+b'#%02X' % (csum & 0xff)
if self.sock.recv(1) == '+': break
self.sock.send(outb)
if self.sock.recv(1) == b'+':
break
def monitor(self, cmd): def monitor(self, cmd):
"""Send gdb "monitor" command to target""" """Send gdb "monitor" command to target"""
if type(cmd) == str:
cmd = cmd.encode()
ret = [] ret = []
self.putpacket("qRcmd," + hexify(cmd)) self.putpacket(b"qRcmd," + hexify(cmd))
while True: while True:
s = self.getpacket() s = self.getpacket()
if s == '': return None
if s == 'OK': return ret if s == b'':
if s.startswith('O'): ret.append(unhexify(s[1:])) return None
if s == b'OK':
return ret
if s.startswith(b'O'):
ret.append(unhexify(s[1:]))
else: else:
raise Exception('Invalid GDB stub response') raise Exception('Invalid GDB stub response %r'%s.decode())
def attach(self, pid): def attach(self, pid):
"""Attach to target process (gdb "attach" command)""" """Attach to target process (gdb "attach" command)"""
self.putpacket("vAttach;%08X" % pid) self.putpacket(b"vAttach;%08X" % pid)
reply = self.getpacket() reply = self.getpacket()
if (len(reply) == 0) or (reply[0] == 'E'): if (reply == b'') or (reply[:1] == b'E'):
raise Exception('Failed to attach to remote pid %d' % pid) raise Exception('Failed to attach to remote pid %d' % pid)
def detach(self): def detach(self):
"""Detach from target process (gdb "detach" command)""" """Detach from target process (gdb "detach" command)"""
self.putpacket("D") self.putpacket(b"D")
if self.getpacket() != 'OK': if self.getpacket() != b'OK':
raise Exception("Failed to detach from remote process") raise Exception("Failed to detach from remote process")
def reset(self): def reset(self):
"""Reset the target system""" """Reset the target system"""
self.putpacket("r") self.putpacket(b"r")
def read_mem(self, addr, length): def read_mem(self, addr, length):
"""Read length bytes from target at address addr""" """Read length bytes from target at address addr"""
self.putpacket("m%08X,%08X" % (addr, length)) ret = b''
reply = self.getpacket() while length:
if (len(reply) == 0) or (reply[0] == 'E'): # print("Read")
raise Exception('Error reading memory at 0x%08X' % addr) packlen = min(length,self.PacketSize//2)
try: self.putpacket(b"m%08X,%08X" % (addr, packlen))
data = unhexify(reply) reply = self.getpacket()
except Excpetion: if (reply == b'') or (reply[:1] == b'E'):
raise Exception('Invalid response to memory read packet: %r' % reply) raise Exception('Error reading memory at 0x%08X' % addr)
return data try:
data = unhexify(reply)
except Exception:
raise Exception('Invalid response to memory read packet: %r' % reply)
ret += data
length -= packlen
addr += packlen
return ret
def write_mem(self, addr, data): def write_mem(self, addr, data):
"""Write data to target at address addr""" """Write data to target at address addr"""
self.putpacket("X%08X,%08X:%s" % (addr, len(data), data)) data = bytes(data)
if self.getpacket() != 'OK':
raise Exception('Error writing to memory at 0x%08X' % addr) while data:
d = data[:self.PacketSize-44]
data = data[len(d):]
#print("Writing %d bytes at 0x%X" % (len(d), addr))
pack = b"X%08X,%08X:%s" % (addr, len(d), d)
self.putpacket(pack)
if self.getpacket() != b'OK':
raise Exception('Error writing to memory at 0x%08X' % addr)
addr += len(d)
def read_regs(self): def read_regs(self):
"""Read target core registers""" """Read target core registers"""
self.putpacket("g") self.putpacket(b"g")
reply = self.getpacket() reply = self.getpacket()
if (len(reply) == 0) or (reply[0] == 'E'): if (reply == b'') or (reply[:1] == b'E'):
raise Exception('Error reading memory at 0x%08X' % addr) raise Exception('Error reading target core registers')
try: try:
data = unhexify(reply) data = unhexify(reply)
except Excpetion: except Exception:
raise Exception('Invalid response to memory read packet: %r' % reply) raise Exception('Invalid response to registers read packet: %r' % reply)
return struct.unpack("=16L", data) ret = array.array('I',data)
return ret
def write_regs(self, *regs): def write_regs(self, *regs):
"""Write target core registers""" """Write target core registers"""
data = struct.pack("=%dL" % len(regs), *regs) data = struct.pack("=%dL" % len(regs), *regs)
self.putpacket("G" + hexify(data)) self.putpacket(b"G" + hexify(data))
if self.getpacket() != 'OK': if self.getpacket() != b'OK':
raise Exception('Error writing to target core registers') raise Exception('Error writing to target core registers')
def memmap_read(self): def memmap_read(self):
"""Read the XML memory map from target""" """Read the XML memory map from target"""
offset = 0 offset = 0
ret = '' ret = b''
while True: while True:
self.putpacket("qXfer:memory-map:read::%08X,%08X" % (offset, 512)) self.putpacket(b"qXfer:memory-map:read::%08X,%08X" % (offset, 512))
reply = self.getpacket() reply = self.getpacket()
if (reply[0] == 'm') or (reply[0] == 'l'): if (reply[0] in b'ml'):
offset += len(reply) - 1 offset += len(reply) - 1
ret += reply[1:] ret += reply[1:]
else: else:
raise Exception("Invalid GDB stub response") raise Exception('Invalid GDB stub response %r'%reply)
if reply[:1] == b'l':
return ret
if reply[0] == 'l': return ret
def resume(self): def resume(self):
"""Resume target execution""" """Resume target execution"""
self.putpacket("c") self.putpacket(b'c')
def interrupt(self): def interrupt(self):
"""Interrupt target execution""" """Interrupt target execution"""
self.sock.send("\x03") self.sock.send(b'\x03')
def run_stub(self, stub, address, *args): def run_stub(self, stub, address, *args):
"""Execute a binary stub at address, passing args in core registers.""" """Execute a binary stub at address, passing args in core registers."""
@ -205,11 +237,19 @@ class Target:
regs[15] = address regs[15] = address
self.write_regs(*regs) self.write_regs(*regs)
self.resume() self.resume()
reply = self.getpacket() reply = None
while not reply: while not reply:
reply = self.getpacket() reply = self.getpacket()
if not reply.startswith("T05"): if not reply.startswith(b"T05"):
raise Exception("Invalid stop response: %r" % reply) message = "Invalid stop response: %r" % reply
try:
message += {'T02':' (SIGINT)',
'T05':' (SIGTRAP)',
'T0B':' (SIGSEGV)',
'T1D':' (SIGLOST)'}[reply]
except KeyError:
pass
raise Exception(message)
class FlashMemory: class FlashMemory:
def __init__(self, target, offset, length, blocksize): def __init__(self, target, offset, length, blocksize):
@ -217,65 +257,70 @@ class Target:
self.offset = offset self.offset = offset
self.length = length self.length = length
self.blocksize = blocksize self.blocksize = blocksize
self.blocks = list(None for i in range(length / blocksize)) self.blocks = list(None for i in range(length // blocksize))
def prog(self, offset, data): def prog(self, offset, data):
assert ((offset >= self.offset) and assert type(data)==bytes
assert ((offset >= self.offset) and
(offset + len(data) <= self.offset + self.length)) (offset + len(data) <= self.offset + self.length))
while data: while data:
index = (offset - self.offset) / self.blocksize index = (offset - self.offset) // self.blocksize
bloffset = (offset - self.offset) % self.blocksize bloffset = (offset - self.offset) % self.blocksize
bldata = data[:self.blocksize-bloffset] bldata = data[:self.blocksize-bloffset]
data = data[len(bldata):]; offset += len(bldata) data = data[len(bldata):]; offset += len(bldata)
if self.blocks[index] is None: # Initialize a clear block if self.blocks[index] is None: # Initialize a clear block
self.blocks[index] = "".join(chr(0xff) for i in range(self.blocksize)) self.blocks[index] = bytes(0xff for i in range(self.blocksize))
self.blocks[index] = (self.blocks[index][:bloffset] + bldata + self.blocks[index] = (self.blocks[index][:bloffset] + bldata +
self.blocks[index][bloffset+len(bldata):]) self.blocks[index][bloffset+len(bldata):])
def commit(self, progress_cb=None): def commit(self, progress_cb=None):
totalblocks = 0 totalblocks = 0
for b in self.blocks: for b in self.blocks:
if b is not None: totalblocks += 1 if b is not None:
totalblocks += 1
block = 0 block = 0
for i in range(len(self.blocks)): for i in range(len(self.blocks)):
block += 1 block += 1
if callable(progress_cb): if callable(progress_cb) and totalblocks > 0:
progress_cb(block*100/totalblocks) progress_cb(block*100/totalblocks)
# Erase the block # Erase the block
data = self.blocks[i] data = self.blocks[i]
addr = self.offset + self.blocksize * i addr = self.offset + self.blocksize * i
if data is None: continue if data is None:
#print "Erasing flash at 0x%X" % (self.offset + self.blocksize*i) continue
self.target.putpacket("vFlashErase:%08X,%08X" % #print("Erasing flash at 0x%X" % (self.offset + self.blocksize*i))
self.target.putpacket(b"vFlashErase:%08X,%08X" %
(self.offset + self.blocksize*i, self.blocksize)) (self.offset + self.blocksize*i, self.blocksize))
if self.target.getpacket() != 'OK': if self.target.getpacket() != b'OK':
raise Exception("Failed to erase flash") raise Exception("Failed to erase flash")
while data: while data:
d = data[0:980] d = data[0:980]
data = data[len(d):] data = data[len(d):]
#print "Writing %d bytes at 0x%X" % (len(d), addr) #print("Writing %d bytes at 0x%X" % (len(d), addr))
self.target.putpacket("vFlashWrite:%08X:%s" % (addr, d)) self.target.putpacket(b"vFlashWrite:%08X:%s" % (addr, d))
addr += len(d) addr += len(d)
if self.target.getpacket() != 'OK': if self.target.getpacket() != b'OK':
raise Exception("Failed to write flash") raise Exception("Failed to write flash")
self.target.putpacket("vFlashDone") self.target.putpacket(b"vFlashDone")
if self.target.getpacket() != 'OK': if self.target.getpacket() != b'OK':
raise Exception("Failed to commit") raise Exception("Failed to commit")
self.blocks = list(None for i in range(self.length / self.blocksize)) self.blocks = list(None for i in range(self.length // self.blocksize))
def flash_probe(self): def flash_probe(self):
self.mem = [] self.mem = []
xmldom = parseString(self.memmap_read()) xmldom = parseString(self.memmap_read())
for memrange in xmldom.getElementsByTagName("memory"): for memrange in xmldom.getElementsByTagName("memory"):
if memrange.getAttribute("type") != "flash": continue if memrange.getAttribute("type") != "flash":
continue
offset = eval(memrange.getAttribute("start")) offset = eval(memrange.getAttribute("start"))
length = eval(memrange.getAttribute("length")) length = eval(memrange.getAttribute("length"))
for property in memrange.getElementsByTagName("property"): for property in memrange.getElementsByTagName("property"):
@ -291,11 +336,9 @@ class Target:
def flash_write_prepare(self, address, data): def flash_write_prepare(self, address, data):
for m in self.mem: for m in self.mem:
if (address >= m.offset) and (address + len(data) < m.offset + m.length): if (address >= m.offset) and (address + len(data) <= m.offset + m.length):
m.prog(address, data) m.prog(address, data)
def flash_commit(self, progress_cb=None): def flash_commit(self, progress_cb=None):
for m in self.mem: for m in self.mem:
m.commit(progress_cb) m.commit(progress_cb)

View File

@ -0,0 +1,56 @@
#!/usr/bin/env python3
"""Pulls nRF51 IDs from openocd's nrf51.c in a form suitable for
pasting into blackmagic's nrf51.c
"""
import subprocess
import re
import io
cmd = 'git archive --remote=git://git.code.sf.net/p/openocd/code HEAD src/flash/nor/nrf5.c | tar -xO'
class Spec():
def __repr__(self):
return "0x%04X: /* %s %s %s */"%(self.hwid,self.comment, self.variant,self.build_code)
proc = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE)
specdict = {}
specs = []
spec = Spec()
for line in io.TextIOWrapper(proc.stdout, encoding="utf-8"):
m = re.search(r'/\*(.*)\*/',line)
if m:
lastcomment=m.group(1)
m = re.search(r'NRF51_DEVICE_DEF\((0x[0-9A-F]*),\s*"(.*)",\s*"(.*)",\s*"(.*)",\s*([0-9]*)\s*\),', line)
if m:
spec.hwid = int(m.group(1), base=0)
spec.variant = m.group(3)
spec.build_code = m.group(4)
spec.flash_size_kb = int(m.group(5), base=0)
ram, flash = {'AA':(16,256),
'AB':(16,128),
'AC':(32,256)}[spec.variant[-2:]]
assert flash == spec.flash_size_kb
spec.ram_size_kb = ram
nicecomment = lastcomment.strip().replace('IC ','').replace('Devices ','').replace('.','')
spec.comment = nicecomment
specdict.setdefault((ram,flash),[]).append(spec)
specs.append(spec)
spec=Spec()
for (ram,flash),specs in specdict.items():
specs.sort(key=lambda x:x.hwid)
for spec in specs:
print("\tcase",spec)
print('\t\tt->driver = "Nordic nRF51";')
print('\t\ttarget_add_ram(t, 0x20000000, 0x%X);'%(1024*ram))
print('\t\tnrf51_add_flash(t, 0x00000000, 0x%X, NRF51_PAGE_SIZE);'%(1024*flash))
print('\t\tnrf51_add_flash(t, NRF51_UICR, 0x100, 0x100);')
print('\t\ttarget_add_commands(t, nrf51_cmd_list, "nRF51");')
print('\t\treturn true;')

View File

@ -1,9 +1,9 @@
#!/usr/bin/python #!/usr/bin/env python3
# hexprog.py: Python application to flash a target with an Intel hex file # hexprog.py: Python application to flash a target with an Intel hex file
# Copyright (C) 2011 Black Sphere Technologies # Copyright (C) 2011 Black Sphere Technologies
# Written by Gareth McMullin <gareth@blacksphere.co.nz> # Written by Gareth McMullin <gareth@blacksphere.co.nz>
# #
# 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
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
@ -18,7 +18,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import gdb import gdb
import struct
import time import time
# Microcode sequence to erase option bytes # Microcode sequence to erase option bytes
@ -31,15 +30,16 @@ def flash_write_hex(target, hexfile, progress_cb=None):
f = open(hexfile) f = open(hexfile)
addrhi = 0 addrhi = 0
for line in f: for line in f:
if line[0] != ':': raise Exception("Error in hex file") if line[0] != ':':
raise Exception("Error in hex file")
reclen = int(line[1:3], 16) reclen = int(line[1:3], 16)
addrlo = int(line[3:7], 16) addrlo = int(line[3:7], 16)
rectype = int(line[7:9], 16); rectype = int(line[7:9], 16)
if sum(ord(x) for x in gdb.unhexify(line[1:11+reclen*2])) & 0xff != 0: if sum(x for x in bytes.fromhex(line[1:11+reclen*2])) & 0xff != 0:
raise Exception("Checksum error in hex file") raise Exception("Checksum error in hex file")
if rectype == 0: # Data record if rectype == 0: # Data record
addr = (addrhi << 16) + addrlo addr = (addrhi << 16) + addrlo
data = gdb.unhexify(line[9:9+reclen*2]) data = bytes.fromhex(line[9:9+reclen*2])
target.flash_write_prepare(addr, data) target.flash_write_prepare(addr, data)
pass pass
elif rectype == 4: # High address record elif rectype == 4: # High address record
@ -48,27 +48,27 @@ def flash_write_hex(target, hexfile, progress_cb=None):
elif rectype == 5: # Entry record elif rectype == 5: # Entry record
pass pass
elif rectype == 1: # End of file record elif rectype == 1: # End of file record
break break
else: else:
raise Exception("Invalid record in hex file") raise Exception("Invalid record in hex file")
try: try:
target.flash_commit(progress_cb) target.flash_commit(progress_cb)
except: except:
print "Flash write failed! Is device protected?\n" print("Flash write failed! Is device protected?\n")
exit(-1) exit(-1)
if __name__ == "__main__": if __name__ == "__main__":
from serial import Serial, SerialException from serial import Serial, SerialException
from sys import argv, platform, stdout from sys import argv, platform, stdout
from getopt import getopt from getopt import getopt
if platform == "linux2": if platform == "linux":
print ("\x1b\x5b\x48\x1b\x5b\x32\x4a") # clear terminal screen print("\x1b\x5b\x48\x1b\x5b\x32\x4a") # clear terminal screen
print("Black Magic Probe -- Target Production Programming Tool -- version 1.0") print("Black Magic Probe -- Target Production Programming Tool -- version 1.0")
print "Copyright (C) 2011 Black Sphere Technologies" print("Copyright (C) 2011 Black Sphere Technologies")
print "License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>" print("License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>")
print("") print("")
dev = "COM1" if platform == "win32" else "/dev/ttyACM0" dev = "COM1" if platform == "win32" else "/dev/ttyACM0"
@ -80,13 +80,20 @@ if __name__ == "__main__":
try: try:
opts, args = getopt(argv[1:], "sd:b:t:rR") opts, args = getopt(argv[1:], "sd:b:t:rR")
for opt in opts: for opt in opts:
if opt[0] == "-s": scan = "swdp_scan" if opt[0] == "-s":
elif opt[0] == "-b": baud = int(opt[1]) scan = "swdp_scan"
elif opt[0] == "-d": dev = opt[1] elif opt[0] == "-b":
elif opt[0] == "-t": targetno = int(opt[1]) baud = int(opt[1])
elif opt[0] == "-r": unprot = True elif opt[0] == "-d":
elif opt[0] == "-R": prot = True dev = opt[1]
else: raise Exception() elif opt[0] == "-t":
targetno = int(opt[1])
elif opt[0] == "-r":
unprot = True
elif opt[0] == "-R":
prot = True
else:
raise Exception()
hexfile = args[0] hexfile = args[0]
except: except:
@ -101,39 +108,44 @@ if __name__ == "__main__":
exit(-1) exit(-1)
try: try:
s = Serial(dev, baud, timeout=3) s = Serial(dev) #, baud, timeout=0.1)
s.setDTR(1) #s.setDTR(1)
while s.read(1024): #s.flushInput()
pass
#while s.read(1024):
# pass
target = gdb.Target(s) target = gdb.Target(s)
except SerialException, e: except SerialException as e:
print("FATAL: Failed to open serial device!\n%s\n" % e[0]) print("FATAL: Failed to open serial device!\n%s\n" % e[0])
exit(-1) exit(-1)
try: try:
r = target.monitor("version") r = target.monitor("version")
for s in r: print s, for s in r:
except SerialException, e: print(s.decode(), end=' ')
except SerialException as e:
print("FATAL: Serial communication failure!\n%s\n" % e[0]) print("FATAL: Serial communication failure!\n%s\n" % e[0])
exit(-1) exit(-1)
except: pass #except: pass
print "Target device scan:" print("Target device scan:")
targetlist = None targetlist = None
r = target.monitor(scan) r = target.monitor(scan)
for s in r: for s in r:
print s, print(s.decode(), end=' ')
print print()
r = target.monitor("targets") r = target.monitor("targets")
for s in r: for s in r:
if s.startswith("No. Att Driver"): targetlist = [] if s.startswith(b"No. Att Driver"):
targetlist = []
try: try:
if type(targetlist) is list: if type(targetlist) is list:
targetlist.append(int(s[:2])) targetlist.append(int(s[:2]))
except: pass except:
pass
#if not targetlist: #if not targetlist:
# print("FATAL: No usable targets found!\n") # print("FATAL: No usable targets found!\n")
@ -161,7 +173,7 @@ if __name__ == "__main__":
print("FLASH memory -- Offset: 0x%X BlockSize:0x%X\n" % (m.offset, m.blocksize)) print("FLASH memory -- Offset: 0x%X BlockSize:0x%X\n" % (m.offset, m.blocksize))
def progress(percent): def progress(percent):
print ("Progress: %d%%\r" % percent), print("Progress: %d%%\r" % percent, end=' ')
stdout.flush() stdout.flush()
print("Programming target") print("Programming target")
@ -179,4 +191,3 @@ if __name__ == "__main__":
target.detach() target.detach()
print("\nAll operations complete!\n") print("\nAll operations complete!\n")

View File

@ -1,82 +0,0 @@
#!/bin/sh
#
# This scripts adds local version information from the version
# control systems git, mercurial (hg) and subversion (svn).
#
# If something goes wrong, send a mail the kernel build mailinglist
# (see MAINTAINERS) and CC Nico Schottelius
# <nico-linuxsetlocalversion -at- schottelius.org>.
#
#
usage() {
echo "Usage: $0 [srctree]" >&2
exit 1
}
cd "${1:-.}" || usage
# Check for git and a git repo.
if head=`git rev-parse --verify --short HEAD 2>/dev/null`; then
# If we are at a tagged commit (like "v2.6.30-rc6"), we ignore it,
# because this version is defined in the top level Makefile.
if [ -z "`git describe --exact-match 2>/dev/null`" ]; then
# If we are past a tagged commit (like "v2.6.30-rc5-302-g72357d5"),
# we pretty print it.
if atag="`git describe 2>/dev/null`"; then
echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}'
# If we don't have a tag at all we print -g{commitish}.
else
printf '%s%s' -g $head
fi
fi
# Is this git on svn?
if git config --get svn-remote.svn.url >/dev/null; then
printf -- '-svn%s' "`git svn find-rev $head`"
fi
# Update index only on r/w media
[ -w . ] && git update-index --refresh --unmerged > /dev/null
# Check for uncommitted changes
if git diff-index --name-only HEAD | grep -v "^scripts/package" \
| read dummy; then
printf '%s' -dirty
fi
# All done with git
exit
fi
# Check for mercurial and a mercurial repo.
if hgid=`hg id 2>/dev/null`; then
tag=`printf '%s' "$hgid" | cut -d' ' -f2`
# Do we have an untagged version?
if [ -z "$tag" -o "$tag" = tip ]; then
id=`printf '%s' "$hgid" | sed 's/[+ ].*//'`
printf '%s%s' -hg "$id"
fi
# Are there uncommitted changes?
# These are represented by + after the changeset id.
case "$hgid" in
*+|*+\ *) printf '%s' -dirty ;;
esac
# All done with mercurial
exit
fi
# Check for svn and a svn repo.
if rev=`svn info 2>/dev/null | grep '^Last Changed Rev'`; then
rev=`echo $rev | awk '{print $NF}'`
printf -- '-svn%s' "$rev"
# All done with svn
exit
fi

View File

@ -1,7 +1,8 @@
#!/usr/bin/python #!/usr/bin/env python3
# #
# stm32_mem.py: STM32 memory access using USB DFU class # stm32_mem.py: STM32 memory access using USB DFU class
# Copyright (C) 2011 Black Sphere Technologies # Copyright (C) 2011 Black Sphere Technologies
# Copyright (C) 2017, 2020 Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.de)
# Written by Gareth McMullin <gareth@blacksphere.co.nz> # Written by Gareth McMullin <gareth@blacksphere.co.nz>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
@ -19,14 +20,15 @@
from time import sleep from time import sleep
import struct import struct
from sys import stdout, argv import os
from sys import stdout
import usb import argparse
import dfu import dfu
CMD_GETCOMMANDS = 0x00 CMD_GETCOMMANDS = 0x00
CMD_SETADDRESSPOINTER = 0x21 CMD_SETADDRESSPOINTER = 0x21
CMD_ERASE = 0x41 CMD_ERASE = 0x41
def stm32_erase(dev, addr): def stm32_erase(dev, addr):
erase_cmd = struct.pack("<BL", CMD_ERASE, addr) erase_cmd = struct.pack("<BL", CMD_ERASE, addr)
@ -38,6 +40,16 @@ def stm32_erase(dev, addr):
if status.bState == dfu.STATE_DFU_DOWNLOAD_IDLE: if status.bState == dfu.STATE_DFU_DOWNLOAD_IDLE:
break break
def stm32_set_address(dev, addr):
set_address_cmd = struct.pack("<BL", CMD_SETADDRESSPOINTER, addr)
dev.download(0, set_address_cmd)
while True:
status = dev.get_status()
if status.bState == dfu.STATE_DFU_DOWNLOAD_BUSY:
sleep(status.bwPollTimeout / 1000.0)
if status.bState == dfu.STATE_DFU_DOWNLOAD_IDLE:
break
def stm32_write(dev, data): def stm32_write(dev, data):
dev.download(2, data) dev.download(2, data)
while True: while True:
@ -46,9 +58,19 @@ def stm32_write(dev, data):
sleep(status.bwPollTimeout / 1000.0) sleep(status.bwPollTimeout / 1000.0)
if status.bState == dfu.STATE_DFU_DOWNLOAD_IDLE: if status.bState == dfu.STATE_DFU_DOWNLOAD_IDLE:
break break
def stm32_read(dev):
data = dev.upload(2, 1024)
while True:
status = dev.get_status()
if status.bState == dfu.STATE_DFU_DOWNLOAD_BUSY:
sleep(status.bwPollTimeout / 1000.0)
if status.bState == dfu.STATE_DFU_UPLOAD_IDLE:
break
return data
def stm32_manifest(dev): def stm32_manifest(dev):
dev.download(0, "") dev.download(0, b"")
while True: while True:
try: try:
status = dev.get_status() status = dev.get_status()
@ -58,52 +80,182 @@ def stm32_manifest(dev):
if status.bState == dfu.STATE_DFU_MANIFEST: if status.bState == dfu.STATE_DFU_MANIFEST:
break break
if __name__ == "__main__": def stm32_scan(args, test):
print
print "USB Device Firmware Upgrade - Host Utility -- version 1.1"
print "Copyright (C) 2011 Black Sphere Technologies"
print "License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>"
print
devs = dfu.finddevs() devs = dfu.finddevs()
bmp_devs = []
bmp = 0
if not devs: if not devs:
print "No devices found!" if test:
return
print("No DFU devices found!")
exit(-1) exit(-1)
for dev in devs: for dev in devs:
dfudev = dfu.dfu_device(*dev) try:
dfudev = dfu.dfu_device(*dev)
except:
# Exceptions are raised when current user doesn't have permissions
# for the specified USB device, but the device scan needs to
# continue
continue
man = dfudev.handle.getString(dfudev.dev.iManufacturer, 30) man = dfudev.handle.getString(dfudev.dev.iManufacturer, 30)
product = dfudev.handle.getString(dfudev.dev.iProduct, 30) if man == b"Black Sphere Technologies":
if man == "Black Sphere Technologies": break bmp = bmp + 1
if man == "STMicroelectronics": break bmp_devs.append(dev)
print "Device %s: ID %04x:%04x %s - %s" % (dfudev.dev.filename, if bmp == 0:
dfudev.dev.idVendor, dfudev.dev.idProduct, man, product) if test:
return
print("No compatible device found\n")
exit(-1)
if bmp > 1 and not args.serial_target:
if test:
return
print("Found multiple devices:\n")
for dev in bmp_devs:
dfudev = dfu.dfu_device(*dev)
man = dfudev.handle.getString(dfudev.dev.iManufacturer, 30).decode('utf8')
product = dfudev.handle.getString(dfudev.dev.iProduct, 96).decode('utf8')
serial_no = dfudev.handle.getString(dfudev.dev.iSerialNumber, 30).decode('utf8')
print("Device ID:\t %04x:%04x" % (dfudev.dev.idVendor, dfudev.dev.idProduct))
print("Manufacturer:\t %s" % man)
print("Product:\t %s" % product)
print("Serial:\t\t %s\n" % serial_no)
print("Select device with serial number!")
exit(-1)
for dev in bmp_devs:
dfudev = dfu.dfu_device(*dev)
man = dfudev.handle.getString(dfudev.dev.iManufacturer, 30).decode('utf8')
product = dfudev.handle.getString(dfudev.dev.iProduct, 96).decode('utf8')
serial_no = dfudev.handle.getString(dfudev.dev.iSerialNumber, 30).decode('utf8')
if args.serial_target:
if man == "Black Sphere Technologies" and serial_no == args.serial_target:
break
else:
if man == "Black Sphere Technologies":
break
print("Device ID:\t %04x:%04x" % (dfudev.dev.idVendor, dfudev.dev.idProduct))
print("Manufacturer:\t %s" % man)
print("Product:\t %s" % product)
print("Serial:\t\t %s" % serial_no)
if args.serial_target and serial_no != args.serial_target:
print("Serial number doesn't match %s vs %s!\n" % (serial_no, args.serial_target))
exit(-2)
return dfudev
if __name__ == "__main__":
print("-")
print("USB Device Firmware Upgrade - Host Utility -- version 1.2")
print("Copyright (C) 2011 Black Sphere Technologies")
print("License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>")
print("-")
parser = argparse.ArgumentParser()
parser.add_argument("progfile", help="Binary file to program")
parser.add_argument("-s", "--serial_target", help="Match Serial Number")
parser.add_argument("-a", "--address", help="Start address for firmware")
parser.add_argument("-m", "--manifest", help="Start application, if in DFU mode", action='store_true')
args = parser.parse_args()
dfudev = stm32_scan(args, False)
try: try:
state = dfudev.get_state() state = dfudev.get_state()
except: except:
print "Failed to read device state! Assuming APP_IDLE" if args.manifest: exit(0)
print("Failed to read device state! Assuming APP_IDLE")
state = dfu.STATE_APP_IDLE state = dfu.STATE_APP_IDLE
if state == dfu.STATE_APP_IDLE: if state == dfu.STATE_APP_IDLE:
dfudev.detach() try:
print "Run again to upgrade firmware." dfudev.detach()
except:
pass
dfudev.release()
print("Invoking DFU Device")
timeout = 0
while True:
sleep(1)
timeout = timeout + 0.5
dfudev = stm32_scan(args, True)
if dfudev: break
if timeout > 5:
print("Error: DFU device did not appear")
exit(-1)
if args.manifest:
stm32_manifest(dfudev)
print("Invoking Application Device")
exit(0) exit(0)
dfudev.make_idle() dfudev.make_idle()
file = open(args.progfile, "rb")
if (os.path.getsize(args.progfile) > 0x1f800):
print("File too large")
exit(0)
bin = open(argv[1], "rb").read() bin = file.read()
addr = 0x8002000 product = dfudev.handle.getString(dfudev.dev.iProduct, 64).decode('utf8')
if args.address:
start = int(args.address, 0)
else:
if "F4" in product or "STLINK-V3" in product:
start = 0x8004000
else:
start = 0x8002000
addr = start
while bin: while bin:
print ("Programming memory at 0x%08X\r" % addr), print("Programming memory at 0x%08X" % addr, end="\r")
stdout.flush() stdout.flush()
stm32_erase(dfudev, addr) try:
# STM DFU bootloader erases always.
# BPM Bootloader only erases once per sector
# To support the STM DFU bootloader, the interface descriptor must
# get evaluated and erase called only once per sector!
stm32_erase(dfudev, addr)
except:
print("\nErase Timed out\n")
break
try:
stm32_set_address(dfudev, addr)
except:
print("\nSet Address Timed out\n")
break
stm32_write(dfudev, bin[:1024]) stm32_write(dfudev, bin[:1024])
bin = bin[1024:] bin = bin[1024:]
addr += 1024 addr += 1024
file.seek(0)
bin = file.read()
len = len(bin)
addr = start
print("\n-")
while bin:
try:
stm32_set_address(dfudev, addr)
data = stm32_read(dfudev)
except:
# Abort silent if bootloader does not support upload
break
print("Verifying memory at 0x%08X" % addr, end="\r")
stdout.flush()
if len > 1024:
size = 1024
else:
size = len
if bin[:size] != bytearray(data[:size]):
print("\nMismatch in block at 0x%08X" % addr)
break
bin = bin[1024:]
addr += 1024
len -= 1024
if len <= 0:
print("\nVerified!")
stm32_manifest(dfudev) stm32_manifest(dfudev)
print "\nAll operations complete!\n" print("All operations complete!\n")

547
scripts/swolisten.c Normal file
View File

@ -0,0 +1,547 @@
/*
* SWO Splitter for Blackmagic Probe and others.
* =============================================
*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2017 Dave Marples <dave@marples.net>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <stdio.h>
#include <string.h>
#include <libusb.h>
#include <stdint.h>
#include <limits.h>
#include <termios.h>
#include <signal.h>
#define VID (0x1d50)
#define PID (0x6018)
#define INTERFACE (5)
#define ENDPOINT (0x85)
#define TRANSFER_SIZE (64)
#define NUM_FIFOS 32
#define MAX_FIFOS 128
#define CHANNELNAME "chan"
#define BOOL char
#define FALSE (0)
#define TRUE (!FALSE)
// Record for options, either defaults or from command line
struct
{
BOOL verbose;
BOOL dump;
int nChannels;
char *chanPath;
char *port;
int speed;
} options = {.nChannels=NUM_FIFOS, .chanPath="", .speed=115200};
// Runtime state
struct
{
int fifo[MAX_FIFOS];
} _r;
// ====================================================================================================
// ====================================================================================================
// ====================================================================================================
// Internals
// ====================================================================================================
// ====================================================================================================
// ====================================================================================================
static BOOL _runFifo(int portNo, int listenHandle, char *fifoName)
{
int pid,fifo;
int readDataLen, writeDataLen;
if (mkfifo(fifoName,0666)<0)
{
return FALSE;
}
pid=fork();
if (pid==0)
{
char rxdata[TRANSFER_SIZE];
int fifo;
/* Don't kill this sub-process when any reader or writer evaporates */
signal(SIGPIPE, SIG_IGN);
while (1)
{
/* This is the child */
fifo=open(fifoName,O_WRONLY);
while (1)
{
readDataLen=read(listenHandle,rxdata,TRANSFER_SIZE);
if (readDataLen<=0)
{
exit(0);
}
writeDataLen=write(fifo,rxdata,readDataLen);
if (writeDataLen<=0)
{
break;
}
}
close(fifo);
}
}
else if (pid<0)
{
/* The fork failed */
return FALSE;
}
return TRUE;
}
// ====================================================================================================
static BOOL _makeFifoTasks(void)
/* Create each sub-process that will handle a port */
{
char fifoName[PATH_MAX];
int f[2];
for (int t=0; t<options.nChannels; t++)
{
if (pipe(f)<0)
return FALSE;
fcntl(f[1],F_SETFL,O_NONBLOCK);
_r.fifo[t]=f[1];
sprintf(fifoName,"%s%s%02X",options.chanPath,CHANNELNAME,t);
if (!_runFifo(t,f[0],fifoName))
{
return FALSE;
}
}
return TRUE;
}
// ====================================================================================================
static void _removeFifoTasks(void)
/* Destroy the per-port sub-processes */
{
int statloc;
int remainingProcesses=0;
char fifoName[PATH_MAX];
for (int t=0; t<options.nChannels; t++)
{
if (_r.fifo[t]>0)
{
close(_r.fifo[t]);
sprintf(fifoName,"%s%s%02X",options.chanPath,CHANNELNAME,t);
unlink(fifoName);
remainingProcesses++;
}
}
while (remainingProcesses--)
{
waitpid(-1,&statloc,0);
}
}
// ====================================================================================================
// ====================================================================================================
// ====================================================================================================
// Handlers for each message type
// ====================================================================================================
// ====================================================================================================
// ====================================================================================================
void _handleSWIT(uint8_t addr, uint8_t length, uint8_t *d)
{
if (addr<options.nChannels)
write(_r.fifo[addr],d,length);
// if (addr==0)
// fprintf(stdout,"%c",*d);
}
// ====================================================================================================
void _handleTS(uint8_t length, uint8_t *d)
{
}
// ====================================================================================================
// ====================================================================================================
// ====================================================================================================
// Protocol pump for decoding messages
// ====================================================================================================
// ====================================================================================================
// ====================================================================================================
enum _protoState {ITM_IDLE, ITM_SYNCING, ITM_TS, ITM_SWIT};
#ifdef PRINT_TRANSITIONS
static char *_protoNames[]={"IDLE", "SYNCING","TS","SWIT"};
#endif
void _protocolPump(uint8_t *c)
{
static enum _protoState p;
static int targetCount, currentCount, srcAddr;
static uint8_t rxPacket[5];
#ifdef PRINT_TRANSITIONS
printf("%02x %s --> ",*c,_protoNames[p]);
#endif
switch (p)
{
// -----------------------------------------------------
case ITM_IDLE:
if (*c==0b01110000)
{
/* This is an overflow packet */
if (options.verbose)
fprintf(stderr,"Overflow!\n");
break;
}
// **********
if (*c==0)
{
/* This is a sync packet - expect to see 4 more 0's followed by 0x80 */
targetCount=4;
currentCount=0;
p=ITM_SYNCING;
break;
}
// **********
if (!(*c&0x0F))
{
currentCount=1;
/* This is a timestamp packet */
rxPacket[0]=*c;
if (!(*c&0x80))
{
/* A one byte output */
_handleTS(currentCount,rxPacket);
}
else
{
p=ITM_TS;
}
break;
}
// **********
if ((*c&0x0F) == 0x04)
{
/* This is a reserved packet */
break;
}
// **********
if (!(*c&0x04))
{
/* This is a SWIT packet */
if ((targetCount=*c&0x03)==3)
targetCount=4;
srcAddr=(*c&0xF8)>>3;
currentCount=0;
p=ITM_SWIT;
break;
}
// **********
if (options.verbose)
fprintf(stderr,"Illegal packet start in IDLE state\n");
break;
// -----------------------------------------------------
case ITM_SWIT:
rxPacket[currentCount]=*c;
currentCount++;
if (currentCount>=targetCount)
{
p=ITM_IDLE;
_handleSWIT(srcAddr, targetCount, rxPacket);
}
break;
// -----------------------------------------------------
case ITM_TS:
rxPacket[currentCount++]=*c;
if (!(*c&0x80))
{
/* We are done */
_handleTS(currentCount,rxPacket);
}
else
{
if (currentCount>4)
{
/* Something went badly wrong */
p=ITM_IDLE;
}
break;
}
// -----------------------------------------------------
case ITM_SYNCING:
if ((*c==0) && (currentCount<targetCount))
{
currentCount++;
}
else
{
if (*c==0x80)
{
p=ITM_IDLE;
}
else
{
/* This should really be an UNKNOWN state */
p=ITM_IDLE;
}
}
break;
// -----------------------------------------------------
}
#ifdef PRINT_TRANSITIONS
printf("%s\n",_protoNames[p]);
#endif
}
// ====================================================================================================
void intHandler(int dummy)
{
exit(0);
}
// ====================================================================================================
void _printHelp(char *progName)
{
printf("Useage: %s <dhnv> <b basedir> <p port> <s speed>\n",progName);
printf(" b: <basedir> for channels\n");
printf(" h: This help\n");
printf(" d: Dump received data without further processing\n");
printf(" n: <Number> of channels to populate\n");
printf(" p: <serialPort> to use\n");
printf(" s: <serialSpeed> to use\n");
printf(" v: Verbose mode\n");
}
// ====================================================================================================
int _processOptions(int argc, char *argv[])
{
int c;
while ((c = getopt (argc, argv, "vdn:b:hp:s:")) != -1)
switch (c)
{
case 'v':
options.verbose = 1;
break;
case 'd':
options.dump = 1;
break;
case 'p':
options.port=optarg;
break;
case 's':
options.speed=atoi(optarg);
break;
case 'h':
_printHelp(argv[0]);
return FALSE;
case 'n':
options.nChannels=atoi(optarg);
if ((options.nChannels<1) || (options.nChannels>MAX_FIFOS))
{
fprintf(stderr,"Number of channels out of range (1..%d)\n",MAX_FIFOS);
return FALSE;
}
break;
case 'b':
options.chanPath = optarg;
break;
case '?':
if (optopt == 'b')
fprintf (stderr, "Option '%c' requires an argument.\n", optopt);
else if (!isprint (optopt))
fprintf (stderr,"Unknown option character `\\x%x'.\n", optopt);
return FALSE;
default:
return FALSE;
}
if (options.verbose)
{
fprintf(stdout,"Verbose: TRUE\nBasePath: %s\n",options.chanPath);
if (options.port)
{
fprintf(stdout,"Serial Port: %s\nSerial Speed: %d\n",options.port,options.speed);
}
}
return TRUE;
}
// ====================================================================================================
int usbFeeder(void)
{
unsigned char cbw[TRANSFER_SIZE];
libusb_device_handle *handle;
libusb_device *dev;
int size;
while (1)
{
if (libusb_init(NULL) < 0)
{
fprintf(stderr,"Failed to initalise USB interface\n");
return (-1);
}
while (!(handle = libusb_open_device_with_vid_pid(NULL, VID, PID)))
{
usleep(500000);
}
if (!(dev = libusb_get_device(handle)))
continue;
if (libusb_claim_interface (handle, INTERFACE)<0)
continue;
while (0==libusb_bulk_transfer(handle, ENDPOINT, cbw, TRANSFER_SIZE, &size, 10))
{
unsigned char *c=cbw;
if (options.dump)
{
cbw[size] = 0;
printf("%s", (char*)cbw);
}
else
while (size--)
_protocolPump(c++);
}
libusb_close(handle);
}
}
// ====================================================================================================
int serialFeeder(void)
{
int f;
unsigned char cbw[TRANSFER_SIZE];
ssize_t t;
struct termios settings;
while (1)
{
while ((f=open(options.port,O_RDONLY))<0)
{
if (options.verbose)
{
fprintf(stderr,"Can't open serial port\n");
}
usleep(500000);
}
if (options.verbose)
{
fprintf(stderr,"Port opened\n");
}
if (tcgetattr(f, &settings) <0)
{
perror("tcgetattr");
return(-3);
}
if (cfsetspeed(&settings, options.speed)<0)
{
perror("Setting input speed");
return -3;
}
settings.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
settings.c_cflag &= ~PARENB; /* no parity */
settings.c_cflag &= ~CSTOPB; /* 1 stop bit */
settings.c_cflag &= ~CSIZE;
settings.c_cflag |= CS8 | CLOCAL; /* 8 bits */
settings.c_oflag &= ~OPOST; /* raw output */
if (tcsetattr(f, TCSANOW, &settings)<0)
{
fprintf(stderr,"Unsupported baudrate\n");
exit(-3);
}
tcflush(f, TCOFLUSH);
while ((t=read(f,cbw,TRANSFER_SIZE))>0)
{
unsigned char *c=cbw;
while (t--)
_protocolPump(c++);
}
if (options.verbose)
{
fprintf(stderr,"Read failed\n");
}
close(f);
}
}
// ====================================================================================================
int main(int argc, char *argv[])
{
if (!_processOptions(argc,argv))
{
exit(-1);
}
atexit(_removeFifoTasks);
/* This ensures the atexit gets called */
signal(SIGINT, intHandler);
if (!_makeFifoTasks())
{
fprintf(stderr,"Failed to make channel devices\n");
exit(-1);
}
/* Using the exit construct rather than return ensures the atexit gets called */
if (!options.port)
exit(usbFeeder());
else
exit(serialFeeder());
fprintf(stderr,"Returned\n");
exit(0);
}
// ====================================================================================================

View File

@ -1,44 +1,203 @@
ifndef PROBE_HOST PROBE_HOST ?= native
PROBE_HOST = stm32 PLATFORM_DIR = platforms/$(PROBE_HOST)
VPATH += $(PLATFORM_DIR) target
ENABLE_DEBUG ?=
ifneq ($(V), 1)
MAKEFLAGS += --no-print-dir
Q := @
endif endif
VPATH += $(PROBE_HOST) CFLAGS += -Wall -Wextra -Werror -Wno-char-subscripts \
-std=gnu99 -MD -I./target \
-I. -Iinclude -I$(PLATFORM_DIR)
BUILDDATE := `date +"%Y%m%d"` ifeq ($(ENABLE_DEBUG), 1)
CFLAGS += -DENABLE_DEBUG
endif
CFLAGS += -Wall -Wextra -Wno-pointer-sign -Wno-char-subscripts\ SRC = \
-O0 -std=gnu99 -g3 -DBUILDDATE=\"$(BUILDDATE)\"\
-I. -Iinclude -I$(PROBE_HOST) \
-DVERSION_SUFFIX=\"`../scripts/setlocalversion`\"
SRC = gdb_if.c \
gdb_packet.c \
gdb_main.c \
hex_utils.c \
jtagtap.c \
swdptap.c \
adiv5.c \ adiv5.c \
adiv5_swdp.c \
cortexm3.c \
stm32_tgt.c \
main.c \
platform.c \
command.c \
jtag_scan.c \
adiv5_jtagdp.c \ adiv5_jtagdp.c \
adiv5_swdp.c \
command.c \
cortexa.c \
cortexm.c \
crc32.c \
efm32.c \
exception.c \
gdb_if.c \
gdb_main.c \
gdb_hostio.c \
gdb_packet.c \
hex_utils.c \
jtag_devs.c \
jtag_scan.c \
lmi.c \ lmi.c \
arm7tdmi.c \ lpc_common.c \
lpc11xx.c \
lpc17xx.c \
lpc15xx.c \
lpc43xx.c \
lpc546xx.c \
kinetis.c \
main.c \
morse.c \
msp432.c \
nrf51.c \
nxpke04.c \
platform.c \
remote.c \
rp.c \
sam3x.c \
sam4l.c \
samd.c \
samx5x.c \
stm32f1.c \
ch32f1.c \
stm32f4.c \ stm32f4.c \
stm32h7.c \
stm32l0.c \
stm32l4.c \
stm32g0.c \
target.c \
include $(PROBE_HOST)/Makefile.inc
OBJ = $(SRC:.c=.o) include $(PLATFORM_DIR)/Makefile.inc
blackmagic: $(OBJ) OPT_FLAGS ?= -Os
$(CC) -o $@ $^ $(LDFLAGS) CFLAGS += $(OPT_FLAGS)
LDFLAGS += $(OPT_FLAGS)
.PHONY: clean host_clean ifndef TARGET
ifdef PC_HOSTED
TARGET = blackmagic
else
TARGET = blackmagic.elf
endif
endif
ifdef NO_OWN_LL
SRC += jtagtap_generic.c swdptap_generic.c
endif
ifdef PC_HOSTED
CFLAGS += -DPC_HOSTED=1
else
SRC += swdptap.c jtagtap.c
CFLAGS += -DPC_HOSTED=0
VPATH += platforms/common
CFLAGS += -Iplatforms/common
endif
ifeq ($(ENABLE_RTT), 1)
CFLAGS += -DENABLE_RTT
SRC += rtt.c rtt_if.c
endif
ifdef RTT_IDENT
CFLAGS += -DRTT_IDENT=$(RTT_IDENT)
endif
OBJ = $(patsubst %.S,%.o,$(patsubst %.c,%.o,$(SRC)))
OPTIMIZE := swdptap.o jtagtap.o \
adiv5_jtagdp.o adiv5_swdp.o adiv5.o \
cortexa.o cortexm.o \
gdb_if.o gdb_main.o gdb_hostio.o gdb_packet.o \
jtag_devs.o jtag_scan.o \
crc32.o main.o \
cdcacm.o jeff.o timing.o traceswo.o usbuart.o \
$(OPTIMIZE):: CFLAGS := $(filter-out -Os, $(CFLAGS))
$(OPTIMIZE):: CFLAGS += -O3
$(TARGET): include/version.h $(OBJ)
@echo " LD $@"
$(Q)$(CC) -o $@ $(OBJ) $(LDFLAGS)
%.o: %.c
@echo " CC $<"
$(Q)$(CC) $(CFLAGS) -c $< -o $@
%.o: %.S
@echo " AS $<"
$(Q)$(CC) $(CFLAGS) -c $< -o $@
ifndef PC_HOSTED
%.bin: %.elf
@echo " OBJCOPY $@"
$(Q)$(OBJCOPY) $(OBJCOPY_FLAGS) -O binary $^ $@
%.hex: %.elf
@echo " OBJCOPY $@"
$(Q)$(OBJCOPY) -O ihex $^ $@
endif
.PHONY: clean host_clean all_platforms clang-format FORCE
clean: host_clean clean: host_clean
$(RM) *.o *~ blackmagic $(HOSTFILES) $(Q)echo " CLEAN"
-$(Q)$(RM) *.o *.d *.elf *~ $(TARGET) $(HOSTFILES)
-$(Q)$(RM) platforms/*/*.o platforms/*/*.d mapfile include/version.h
all_platforms:
$(Q)if [ ! -f ../libopencm3/Makefile ]; then \
echo "Initialising git submodules..." ;\
git submodule init ;\
git submodule update ;\
fi
$(Q)$(MAKE) $(MFLAGS) -C ../libopencm3 lib/stm32/f1 lib/stm32/f4 lib/lm4f
$(Q)set -e ;\
mkdir -p artifacts/$(shell git describe --always --dirty --tags) ;\
echo "<html><body><ul>" > artifacts/index.html ;\
$(MAKE) clean ;\
for i in platforms/*/Makefile.inc ; do \
export DIRNAME=`dirname $$i` ;\
export PROBE_HOST=`basename $$DIRNAME` ;\
export CFLAGS=-Werror ;\
echo "Building for hardware platform: $$PROBE_HOST" ;\
$(MAKE);\
if [ -f blackmagic ]; then \
mv blackmagic artifacts/blackmagic-$$PROBE_HOST ;\
echo "<li><a href='blackmagic-$$PROBE_HOST'>$$PROBE_HOST</a></li>"\
>> artifacts/index.html ;\
fi ;\
if [ -f blackmagic.bin ]; then \
mv blackmagic.bin artifacts/blackmagic-$$PROBE_HOST.bin ;\
echo "<li><a href='blackmagic-$$PROBE_HOST.bin'>$$PROBE_HOST</a></li>"\
>> artifacts/index.html ;\
fi ;\
if [ -f blackmagic_dfu.bin ]; then \
mv blackmagic_dfu.bin artifacts/blackmagic_dfu-$$PROBE_HOST.bin ;\
echo "<li><a href='blackmagic_dfu-$$PROBE_HOST.bin'>$$PROBE_HOST DFU</a></li>"\
>> artifacts/index.html ;\
fi ;\
$(MAKE) clean ;\
done ;\
echo "</ul></body></html>" >> artifacts/index.html ;\
cp artifacts/blackmagic* artifacts/$(shell git describe --always --dirty --tags)
command.c: include/version.h
GIT_VERSION := $(shell git describe --always --dirty --tags)
VERSION_HEADER := \#define FIRMWARE_VERSION "$(GIT_VERSION)"
include/version.h: FORCE
@# If git isn't found then GIT_VERSION will be an empty string.
ifeq ($(GIT_VERSION),)
@echo Git not found, assuming up to date include/version.h
else
@# Note that when we echo the version to the header file, echo writes a final newline
@# to the file. This is fine and probably makes the file more human-readable, but
@# also means we have to account for that newline in this comparison.
$(Q)if [ ! -f $@ ] || [ "$$(cat $@)" != "$$(echo '$(VERSION_HEADER)\n')" ]; then \
echo " GEN $@"; \
echo '$(VERSION_HEADER)' > $@; \
fi
endif
clang-format:
$(Q)clang-format -i *.c */*.c */*/*.c *.h */*.h */*/*.h
-include *.d

View File

@ -1,288 +0,0 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2011 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* This file implements the transport generic functions of the
* ARM Debug Interface v5 Architecure Specification, ARM doc IHI0031A.
*
* Issues:
* Currently doesn't use ROM table for introspection, just assumes
* the device is Cortex-M3.
*/
#include <stdio.h>
#include <stdlib.h>
#include "general.h"
#include "jtag_scan.h"
#include "gdb_packet.h"
#include "adiv5.h"
#include "target.h"
#include "cortexm3.h"
#ifndef DO_RESET_SEQ
#define DO_RESET_SEQ 0
#endif
/* This belongs elsewhere... */
target *target_list = NULL;
target *cur_target = NULL;
target *last_target = NULL;
static const char adiv5_driver_str[] = "ARM ADIv5 MEM-AP";
ADIv5_DP_t *adiv5_dp_list;
ADIv5_AP_t adiv5_aps[5];
int adiv5_ap_count;
static int ap_check_error(struct target_s *target);
static int ap_mem_read_words(struct target_s *target, uint32_t *dest, uint32_t src, int len);
static int ap_mem_write_words(struct target_s *target, uint32_t dest, const uint32_t *src, int len);
static int ap_mem_read_bytes(struct target_s *target, uint8_t *dest, uint32_t src, int len);
static int ap_mem_write_bytes(struct target_s *target, uint32_t dest, const uint8_t *src, int len);
void adiv5_free_all(void)
{
ADIv5_DP_t *dp;
while(adiv5_dp_list) {
dp = adiv5_dp_list->next;
free(adiv5_dp_list);
adiv5_dp_list = dp;
}
adiv5_ap_count = 0;
}
void adiv5_dp_init(ADIv5_DP_t *dp)
{
uint32_t ctrlstat;
dp->next = adiv5_dp_list;
adiv5_dp_list = dp;
ctrlstat = adiv5_dp_read(dp, ADIV5_DP_CTRLSTAT);
/* Write request for system and debug power up */
adiv5_dp_write(dp, ADIV5_DP_CTRLSTAT,
ctrlstat |= ADIV5_DP_CTRLSTAT_CSYSPWRUPREQ |
ADIV5_DP_CTRLSTAT_CDBGPWRUPREQ);
/* Wait for acknowledge */
while(((ctrlstat = adiv5_dp_read(dp, ADIV5_DP_CTRLSTAT)) &
(ADIV5_DP_CTRLSTAT_CSYSPWRUPACK | ADIV5_DP_CTRLSTAT_CDBGPWRUPACK)) !=
(ADIV5_DP_CTRLSTAT_CSYSPWRUPACK | ADIV5_DP_CTRLSTAT_CDBGPWRUPACK));
if(DO_RESET_SEQ) {
/* This AP reset logic is described in ADIv5, but fails to work
* correctly on STM32. CDBGRSTACK is never asserted, and we
* just wait forever.
*/
/* Write request for debug reset */
adiv5_dp_write(dp, ADIV5_DP_CTRLSTAT,
ctrlstat |= ADIV5_DP_CTRLSTAT_CDBGRSTREQ);
/* Wait for acknowledge */
while(!((ctrlstat = adiv5_dp_read(dp, ADIV5_DP_CTRLSTAT)) &
ADIV5_DP_CTRLSTAT_CDBGRSTACK));
/* Write request for debug reset release */
adiv5_dp_write(dp, ADIV5_DP_CTRLSTAT,
ctrlstat &= ~ADIV5_DP_CTRLSTAT_CDBGRSTREQ);
/* Wait for acknowledge */
while(adiv5_dp_read(dp, ADIV5_DP_CTRLSTAT) &
ADIV5_DP_CTRLSTAT_CDBGRSTACK);
}
/* Probe for APs on this DP */
for(int i = 0; i < 256; i++) {
ADIv5_AP_t *ap = &adiv5_aps[adiv5_ap_count];
target *t;
/* Assume valid and try to read IDR */
ap->dp = dp;
ap->apsel = i;
ap->idr = adiv5_ap_read(ap, ADIV5_AP_IDR);
if(!ap->idr) /* IDR Invalid - Should we not continue here? */
break;
/* We have a valid AP, adding to list */
ap->cfg = adiv5_ap_read(ap, ADIV5_AP_CFG);
ap->base = adiv5_ap_read(ap, ADIV5_AP_BASE);
/* Should probe further here... */
/* Prepend to target list... */
t = (void*)calloc(1, sizeof(struct target_ap_s));
t->next = target_list;
target_list = t;
((struct target_ap_s *)t)->ap = ap;
t->driver = adiv5_driver_str;
t->check_error = ap_check_error;
t->mem_read_words = ap_mem_read_words;
t->mem_write_words = ap_mem_write_words;
t->mem_read_bytes = ap_mem_read_bytes;
t->mem_write_bytes = ap_mem_write_bytes;
/* The rest sould only be added after checking ROM table */
cm3_probe(t);
adiv5_ap_count++;
}
}
void adiv5_dp_write_ap(ADIv5_DP_t *dp, uint8_t addr, uint32_t value)
{
adiv5_dp_low_access(dp, ADIV5_LOW_AP, ADIV5_LOW_WRITE, addr, value);
}
uint32_t adiv5_dp_read_ap(ADIv5_DP_t *dp, uint8_t addr)
{
uint32_t ret;
adiv5_dp_low_access(dp, ADIV5_LOW_AP, ADIV5_LOW_READ, addr, 0);
ret = adiv5_dp_low_access(dp, ADIV5_LOW_DP, ADIV5_LOW_READ,
ADIV5_DP_RDBUFF, 0);
return ret;
}
static int
ap_check_error(struct target_s *target)
{
struct target_ap_s *t = (void *)target;
return adiv5_dp_error(t->ap->dp);
}
static int
ap_mem_read_words(struct target_s *target, uint32_t *dest, uint32_t src, int len)
{
struct target_ap_s *t = (void *)target;
len >>= 2;
adiv5_ap_write(t->ap, ADIV5_AP_CSW, 0xA2000052);
adiv5_dp_low_access(t->ap->dp, ADIV5_LOW_AP, ADIV5_LOW_WRITE,
ADIV5_AP_TAR, src);
adiv5_dp_low_access(t->ap->dp, ADIV5_LOW_AP, ADIV5_LOW_READ,
ADIV5_AP_DRW, 0);
while(--len)
*dest++ = adiv5_dp_low_access(t->ap->dp, ADIV5_LOW_AP,
ADIV5_LOW_READ, ADIV5_AP_DRW, 0);
*dest++ = adiv5_dp_low_access(t->ap->dp, ADIV5_LOW_DP, ADIV5_LOW_READ,
ADIV5_DP_RDBUFF, 0);
return 0;
}
static int
ap_mem_read_bytes(struct target_s *target, uint8_t *dest, uint32_t src, int len)
{
struct target_ap_s *t = (void *)target;
uint32_t tmp = src;
adiv5_ap_write(t->ap, ADIV5_AP_CSW, 0xA2000050);
adiv5_dp_low_access(t->ap->dp, ADIV5_LOW_AP, ADIV5_LOW_WRITE,
ADIV5_AP_TAR, src);
adiv5_dp_low_access(t->ap->dp, ADIV5_LOW_AP, ADIV5_LOW_READ,
ADIV5_AP_DRW, 0);
while(--len) {
tmp = adiv5_dp_low_access(t->ap->dp, 1, 1, ADIV5_AP_DRW, 0);
*dest++ = (tmp >> ((src++ & 0x3) << 3) & 0xFF);
}
tmp = adiv5_dp_low_access(t->ap->dp, 0, 1, ADIV5_DP_RDBUFF, 0);
*dest++ = (tmp >> ((src++ & 0x3) << 3) & 0xFF);
return 0;
}
static int
ap_mem_write_words(struct target_s *target, uint32_t dest, const uint32_t *src, int len)
{
struct target_ap_s *t = (void *)target;
len >>= 2;
adiv5_ap_write(t->ap, ADIV5_AP_CSW, 0xA2000052);
adiv5_dp_low_access(t->ap->dp, ADIV5_LOW_AP, ADIV5_LOW_WRITE,
ADIV5_AP_TAR, dest);
while(len--)
adiv5_dp_low_access(t->ap->dp, ADIV5_LOW_AP, ADIV5_LOW_WRITE,
ADIV5_AP_DRW, *src++);
return 0;
}
static int
ap_mem_write_bytes(struct target_s *target, uint32_t dest, const uint8_t *src, int len)
{
struct target_ap_s *t = (void *)target;
uint32_t tmp;
adiv5_ap_write(t->ap, ADIV5_AP_CSW, 0xA2000050);
adiv5_dp_low_access(t->ap->dp, ADIV5_LOW_AP, ADIV5_LOW_WRITE,
ADIV5_AP_TAR, dest);
while(len--) {
tmp = (uint32_t)*src++ << ((dest++ & 3) << 3);
adiv5_dp_low_access(t->ap->dp, ADIV5_LOW_AP, ADIV5_LOW_WRITE,
ADIV5_AP_DRW, tmp);
}
return 0;
}
uint32_t adiv5_ap_mem_read(ADIv5_AP_t *ap, uint32_t addr)
{
adiv5_ap_write(ap, ADIV5_AP_CSW, 0xA2000052);
adiv5_ap_write(ap, ADIV5_AP_TAR, addr);
return adiv5_ap_read(ap, ADIV5_AP_DRW);
}
void adiv5_ap_mem_write(ADIv5_AP_t *ap, uint32_t addr, uint32_t value)
{
adiv5_ap_write(ap, ADIV5_AP_CSW, 0xA2000052);
adiv5_ap_write(ap, ADIV5_AP_TAR, addr);
adiv5_ap_write(ap, ADIV5_AP_DRW, value);
}
void adiv5_ap_write(ADIv5_AP_t *ap, uint8_t addr, uint32_t value)
{
adiv5_dp_write(ap->dp, ADIV5_DP_SELECT,
((uint32_t)ap->apsel << 24)|(addr & 0xF0));
adiv5_dp_write_ap(ap->dp, addr, value);
}
uint32_t adiv5_ap_read(ADIv5_AP_t *ap, uint8_t addr)
{
uint32_t ret;
adiv5_dp_write(ap->dp, ADIV5_DP_SELECT,
((uint32_t)ap->apsel << 24)|(addr & 0xF0));
ret = adiv5_dp_read_ap(ap->dp, addr);
return ret;
}

View File

@ -1,107 +0,0 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2011 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* This file implements the JTAG-DP specific functions of the
* ARM Debug Interface v5 Architecure Specification, ARM doc IHI0031A.
*/
#include "general.h"
#include "platform.h"
#include "adiv5.h"
#include "jtag_scan.h"
#include "jtagtap.h"
#include <stdlib.h>
#define JTAGDP_ACK_OK 0x02
#define JTAGDP_ACK_WAIT 0x01
/* 35-bit registers that control the ADIv5 DP */
#define IR_ABORT 0x8
#define IR_DPACC 0xA
#define IR_APACC 0xB
static void adiv5_jtagdp_write(ADIv5_DP_t *dp, uint8_t addr, uint32_t value);
static uint32_t adiv5_jtagdp_read(ADIv5_DP_t *dp, uint8_t addr);
static uint32_t adiv5_jtagdp_error(ADIv5_DP_t *dp);
static uint32_t adiv5_jtagdp_low_access(ADIv5_DP_t *dp, uint8_t APnDP, uint8_t RnW,
uint8_t addr, uint32_t value);
void adiv5_jtag_dp_handler(jtag_dev_t *dev)
{
ADIv5_DP_t *dp = (void*)calloc(1, sizeof(ADIv5_DP_t));
dp->dev = dev;
dp->idcode = dev->idcode;
dp->dp_write = adiv5_jtagdp_write;
dp->dp_read = adiv5_jtagdp_read;
dp->error = adiv5_jtagdp_error;
dp->low_access = adiv5_jtagdp_low_access;
adiv5_dp_init(dp);
}
static void adiv5_jtagdp_write(ADIv5_DP_t *dp, uint8_t addr, uint32_t value)
{
adiv5_jtagdp_low_access(dp, ADIV5_LOW_DP, ADIV5_LOW_WRITE, addr, value);
}
static uint32_t adiv5_jtagdp_read(ADIv5_DP_t *dp, uint8_t addr)
{
adiv5_jtagdp_low_access(dp, ADIV5_LOW_DP, ADIV5_LOW_READ, addr, 0);
return adiv5_jtagdp_low_access(dp, ADIV5_LOW_DP, ADIV5_LOW_READ,
ADIV5_DP_RDBUFF, 0);
}
static uint32_t adiv5_jtagdp_error(ADIv5_DP_t *dp)
{
adiv5_jtagdp_low_access(dp, ADIV5_LOW_DP, ADIV5_LOW_READ,
ADIV5_DP_CTRLSTAT, 0);
return adiv5_jtagdp_low_access(dp, ADIV5_LOW_DP, ADIV5_LOW_WRITE,
ADIV5_DP_CTRLSTAT, 0xF0000032) & 0x32;
}
static uint32_t adiv5_jtagdp_low_access(ADIv5_DP_t *dp, uint8_t APnDP, uint8_t RnW,
uint8_t addr, uint32_t value)
{
uint64_t request, response;
uint8_t ack;
request = ((uint64_t)value << 3) | ((addr >> 1) & 0x06) | (RnW?1:0);
jtag_dev_write_ir(dp->dev, APnDP?IR_APACC:IR_DPACC);
do {
jtag_dev_shift_dr(dp->dev, (uint8_t*)&response, (uint8_t*)&request, 35);
ack = response & 0x07;
} while(ack == JTAGDP_ACK_WAIT);
if((ack != JTAGDP_ACK_OK)) {
/* Fatal error if invalid ACK response */
PLATFORM_FATAL_ERROR(1);
}
return (uint32_t)(response >> 3);
}

View File

@ -1,160 +0,0 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2011 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* This file implements the SW-DP specific functions of the
* ARM Debug Interface v5 Architecure Specification, ARM doc IHI0031A.
*/
#include "general.h"
#include "platform.h"
#include "adiv5.h"
#include "swdptap.h"
#include "command.h"
#include <stdlib.h>
#define SWDP_ACK_OK 0x01
#define SWDP_ACK_WAIT 0x02
#define SWDP_ACK_FAULT 0x04
static void adiv5_swdp_write(ADIv5_DP_t *dp, uint8_t addr, uint32_t value);
static uint32_t adiv5_swdp_read(ADIv5_DP_t *dp, uint8_t addr);
static uint32_t adiv5_swdp_error(ADIv5_DP_t *dp);
static uint32_t adiv5_swdp_low_access(ADIv5_DP_t *dp, uint8_t APnDP, uint8_t RnW,
uint8_t addr, uint32_t value);
int adiv5_swdp_scan(void)
{
ADIv5_DP_t *dp;
uint8_t ack;
TARGET_LIST_FREE();
#warning "These should be elsewhere!"
adiv5_free_all();
dp = (void*)calloc(1, sizeof(ADIv5_DP_t));
swdptap_init();
/* Read the SW-DP IDCODE register to syncronise */
/* This could be done with adiv_swdp_low_access(), but this doesn't
* allow the ack to be checked here. */
swdptap_seq_out(0xA5, 8);
ack = swdptap_seq_in(3);
if((ack != SWDP_ACK_OK) || swdptap_seq_in_parity(&dp->idcode, 32)) {
DEBUG("\n");
morse("NO TARGETS.", 1);
free(dp);
return -1;
}
dp->dp_write = adiv5_swdp_write;
dp->dp_read = adiv5_swdp_read;
dp->error = adiv5_swdp_error;
dp->low_access = adiv5_swdp_low_access;
adiv5_dp_init(dp);
if(!target_list) morse("NO TARGETS.", 1);
else morse(NULL, 0);
return target_list?1:0;
}
static void adiv5_swdp_write(ADIv5_DP_t *dp, uint8_t addr, uint32_t value)
{
adiv5_swdp_low_access(dp, ADIV5_LOW_DP, ADIV5_LOW_WRITE, addr, value);
}
static uint32_t adiv5_swdp_read(ADIv5_DP_t *dp, uint8_t addr)
{
return adiv5_swdp_low_access(dp, ADIV5_LOW_DP, ADIV5_LOW_READ, addr, 0);
}
static uint32_t adiv5_swdp_error(ADIv5_DP_t *dp)
{
uint32_t err, clr = 0;
err = adiv5_swdp_read(dp, ADIV5_DP_CTRLSTAT) &
(ADIV5_DP_CTRLSTAT_STICKYORUN | ADIV5_DP_CTRLSTAT_STICKYCMP |
ADIV5_DP_CTRLSTAT_STICKYERR);
if(err & ADIV5_DP_CTRLSTAT_STICKYORUN)
clr |= ADIV5_DP_ABORT_ORUNERRCLR;
if(err & ADIV5_DP_CTRLSTAT_STICKYCMP)
clr |= ADIV5_DP_ABORT_STKCMPCLR;
if(err & ADIV5_DP_CTRLSTAT_STICKYERR)
clr |= ADIV5_DP_ABORT_STKERRCLR;
adiv5_swdp_write(dp, ADIV5_DP_ABORT, clr);
dp->fault = 0;
return err;
}
static uint32_t adiv5_swdp_low_access(ADIv5_DP_t *dp, uint8_t APnDP, uint8_t RnW,
uint8_t addr, uint32_t value)
{
uint8_t request = 0x81;
uint32_t response;
uint8_t ack;
if(APnDP && dp->fault) return 0;
if(APnDP) request ^= 0x22;
if(RnW) request ^= 0x24;
addr &= 0xC;
request |= (addr << 1) & 0x18;
if((addr == 4) || (addr == 8))
request ^= 0x20;
do {
swdptap_seq_out(request, 8);
ack = swdptap_seq_in(3);
} while(ack == SWDP_ACK_WAIT);
if(ack == SWDP_ACK_FAULT) {
dp->fault = 1;
return 0;
}
if(ack != SWDP_ACK_OK) {
/* Fatal error if invalid ACK response */
PLATFORM_FATAL_ERROR(1);
}
if(RnW) {
if(swdptap_seq_in_parity(&response, 32)) /* Give up on parity error */
PLATFORM_FATAL_ERROR(1);
} else {
swdptap_seq_out_parity(value, 32);
}
/* REMOVE THIS */
swdptap_seq_out(0, 8);
return response;
}

View File

@ -1,295 +0,0 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2011 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* This file implements the ARM7TDMI target support using the JTAG
* interface as described in ARM7TDMI Technical Reference Manual,
* ARM Document DDI 0210C
*/
#include "general.h"
#include "platform.h"
#include "target.h"
#include "jtag_scan.h"
#include "jtagtap.h"
#include <stdlib.h>
#include <string.h>
/* TODO:
* Skeleton target.
* EmbeddedICE registers, halt/resume target.
* Check target mode on halt, switch to ARM if needed.
* Read registers on halt, restore on resume. Give GDB cached copy.
* System speed access, read/write memory.
* Misaligned/byte memory access.
* Breakpoint support.
* Watchpoint support.
* Funnies: abort on breakpointed instruction, etc.
* Flash programming for STR73x and LPC2xxx.
*/
static const char arm7_driver_str[] = "ARM7TDMI";
/* ARM7 JTAG IR values */
#define ARM7_IR_EXTEST 0x0
#define ARM7_IR_SCAN_N 0x2
#define ARM7_IR_SAMPLE_PRELOAD 0x3
#define ARM7_IR_RESTART 0x4
#define ARM7_IR_CLAMP 0x5
#define ARM7_IR_HIGHZ 0x7
#define ARM7_IR_CLAMPZ 0x9
#define ARM7_IR_INTEST 0xC
#define ARM7_IR_IDCODE 0xE
#define ARM7_IR_BYPASS 0xF
/* ARM7 SCAN_N scan chain values */
#define ARM7_SCANN_BOUNDARY 0
#define ARM7_SCANN_DBUS 1
#define ARM7_SCANN_EICE 2
/* EmbeddedICE-RT Register addresses */
#define ARM7_EICE_DEBUG_CTRL 0x00
#define ARM7_EICE_DEBUG_STAT 0x01
#define ARM7_EICE_ABORT_STAT 0x02
#define ARM7_EICE_COMMS_CTRL 0x04
#define ARM7_EICE_COMMS_DATA 0x05
#define ARM7_EICE_WATCH_ADDR(x) (0x08 + (8 * (x))
#define ARM7_EICE_WATCH_ADDR_MASK(x) (0x09 + (8 * (x))
#define ARM7_EICE_WATCH_DATA(x) (0x0A + (8 * (x))
#define ARM7_EICE_WATCH_DATA_MASK(x) (0x0B + (8 * (x))
#define ARM7_EICE_WATCH_CTRL(x) (0x0C + (8 * (x))
#define ARM7_EICE_WATCH_CTRL_MASK(x) (0x0D + (8 * (x))
/* Read/write bit in EmbeddedICE-RT scan chain */
#define ARM7_EICE_READ (0uLL << 37)
#define ARM7_EICE_WRITE (1uLL << 37)
/* Debug Control Register bits */
#define ARM7_EICE_DEBUG_CTRL_EICE_DISABLE (1 << 5)
#define ARM7_EICE_DEBUG_CTRL_MONITOR (1 << 4)
/* Bit 3 - Reserved */
#define ARM7_EICE_DEBUG_CTRL_INTDIS (1 << 2)
#define ARM7_EICE_DEBUG_CTRL_DBGRQ (1 << 1)
#define ARM7_EICE_DEBUG_CTRL_DBGACK (1 << 0)
/* Debug Status Register bits */
#define ARM7_EICE_DEBUG_STAT_TBIT (1 << 4)
#define ARM7_EICE_DEBUG_STAT_NMREQ (1 << 3)
#define ARM7_EICE_DEBUG_STAT_INTDIS (1 << 2)
#define ARM7_EICE_DEBUG_STAT_DBGRQ (1 << 1)
#define ARM7_EICE_DEBUG_STAT_DBGACK (1 << 0)
#define ARM7_OP_NOP 0xE1A00000
struct target_arm7_s {
target t;
jtag_dev_t *jtag;
uint32_t reg_cache[16];
};
/* FIXME: Remove: */
static void do_nothing(void)
{
}
static void arm7_attach(struct target_s *target);
static int arm7_regs_read(struct target_s *target, void *data);
static int arm7_regs_write(struct target_s *target, const void *data);
static void arm7_halt_request(struct target_s *target);
static int arm7_halt_wait(struct target_s *target);
static void arm7_halt_resume(struct target_s *target, uint8_t step);
void arm7tdmi_jtag_handler(jtag_dev_t *dev)
{
struct target_arm7_s *tj = calloc(1, sizeof(*tj));
target *t = (target *)tj;
t->driver = arm7_driver_str;
tj->jtag = dev;
/* Setup mandatory virtual methods */
t->attach = arm7_attach;
t->detach = (void *)do_nothing;
t->check_error = (void *)do_nothing;
t->mem_read_words = (void *)do_nothing;
t->mem_write_words = (void *)do_nothing;
t->mem_read_bytes = (void *)do_nothing;
t->mem_write_bytes = (void *)do_nothing;
t->regs_size = 16 * 4;
t->regs_read = (void *)arm7_regs_read;
t->regs_write = (void *)arm7_regs_write;
t->pc_write = (void *)do_nothing;
t->reset = (void *)do_nothing;
t->halt_request = arm7_halt_request;
t->halt_wait = arm7_halt_wait;
t->halt_resume = arm7_halt_resume;
/* TODO: Breakpoint and watchpoint functions. */
/* TODO: Fault unwinder. */
/* TODO: Memory map / Flash programming. */
t->next = target_list;
target_list = t;
}
static void arm7_select_scanchain(struct target_arm7_s *target, uint8_t chain)
{
jtag_dev_write_ir(target->jtag, ARM7_IR_SCAN_N);
jtag_dev_shift_dr(target->jtag, NULL, &chain, 4);
jtag_dev_write_ir(target->jtag, ARM7_IR_INTEST);
}
static void arm7_eice_write(struct target_arm7_s *target,
uint8_t addr, uint32_t value)
{
uint64_t val = ((uint64_t)addr << 32) | value | ARM7_EICE_WRITE;
arm7_select_scanchain(target, ARM7_SCANN_EICE);
jtag_dev_shift_dr(target->jtag, NULL, (uint8_t *)&val, 38);
DEBUG("eice_write(%d, 0x%08X)\n", addr, value);
}
static uint32_t arm7_eice_read(struct target_arm7_s *target, uint8_t addr)
{
uint64_t val = ((uint64_t)addr << 32) | ARM7_EICE_READ;
arm7_select_scanchain(target, ARM7_SCANN_EICE);
jtag_dev_shift_dr(target->jtag, NULL, (uint8_t *)&val, 38);
jtag_dev_shift_dr(target->jtag, (uint8_t *)&val, (uint8_t *)&val, 38);
DEBUG("eice_read(%d, 0x%08X)\n", addr, (uint32_t)val);
return (uint32_t)val;
}
/* Execute a single instruction at debug speed.
* Performs datalen data bus accesses after the op to capture data.
*/
static void arm7_op_debug(struct target_arm7_s *t, uint32_t op, uint32_t *data,
int datalen)
{
uint64_t tmp;
/* FIXME: This routine is broken.
* This process isn't very well documented. Maybe NOPs need to
* be shifted into pipeline before data is read out.
*/
DEBUG("op_debug(0x%08X)\n", op);
arm7_select_scanchain(t, ARM7_SCANN_DBUS);
tmp = op;
jtag_dev_shift_dr(t->jtag, NULL, (const uint8_t*)&tmp, 33);
while(datalen--) {
tmp = *data;
jtag_dev_shift_dr(t->jtag, (uint8_t*)&tmp, (uint8_t*)&tmp, 33);
*data = (uint32_t)tmp;
DEBUG("\t0x%08X\n", *data);
data++;
}
}
/* Execute a single instruction at system speed. */
static void arm7_op_system(struct target_arm7_s *t, uint32_t op)
{
uint64_t tmp;
arm7_select_scanchain(t, ARM7_SCANN_DBUS);
tmp = op | (1uLL << 32);
jtag_dev_shift_dr(t->jtag, NULL, (const uint8_t*)&tmp, 33);
}
static void arm7_halt_request(struct target_s *target)
{
struct target_arm7_s *t = (struct target_arm7_s *)target;
arm7_eice_write(t, ARM7_EICE_DEBUG_CTRL, ARM7_EICE_DEBUG_CTRL_DBGRQ);
}
static int arm7_halt_wait(struct target_s *target)
{
struct target_arm7_s *t = (struct target_arm7_s *)target;
int stat = arm7_eice_read(t, ARM7_EICE_DEBUG_STAT);
if(!(stat & ARM7_EICE_DEBUG_STAT_DBGACK))
return 0;
/* We are halted, so switch to ARM mode if needed. */
if(stat & ARM7_EICE_DEBUG_STAT_TBIT) {
/* This sequence switches to ARM mode:
* 6000 STR R0, [R0] ; Save R0 before use
* 4678 MOV R0, PC ; Copy PC into R0
* 6000 STR R0, [R0] ; Now save the PC in R0
* 4778 BX PC ; Jump into ARM state
* 46c0 MOV R8, R8 ; NOP
* 46c0 MOV R8, R8 ; NOP
*/
/* FIXME: Switch to ARM mode. */
}
/* Fetch core register values */
/* E880FFFF STM R0, {R0-R15} */
arm7_op_debug(t, 0xE880FFFF, t->reg_cache, 16);
return 1;
}
static void arm7_halt_resume(struct target_s *target, uint8_t step)
{
struct target_arm7_s *t = (struct target_arm7_s *)target;
if(step) {
/* FIXME: Set breakpoint on any instruction to single step. */
}
/* Restore core registers. */
/* E890FFFF LDM R0, {R0-R15} */
arm7_op_debug(t, 0xE890FFFF, t->reg_cache, 16);
/* Release DBGRQ */
arm7_eice_write(t, ARM7_EICE_DEBUG_CTRL, 0);
/* This sequence restores PC if no other instructions issued in
* debug mode...
* 0 E1A00000; MOV R0, R0
* 1 E1A00000; MOV R0, R0
* 0 EAFFFFFA; B -6
* FIXME: Add adjustment for other opcodes.
*/
arm7_op_debug(t, ARM7_OP_NOP, NULL, 0);
arm7_op_system(t, ARM7_OP_NOP);
arm7_op_debug(t, 0xEAFFFFF8, NULL, 0);
jtag_dev_write_ir(t->jtag, ARM7_IR_RESTART);
}
static void arm7_attach(struct target_s *target)
{
target_halt_request(target);
while(!target_halt_wait(target));
}
static int arm7_regs_read(struct target_s *target, void *data)
{
struct target_arm7_s *t = (struct target_arm7_s *)target;
memcpy(data, t->reg_cache, target->regs_size);
return 0;
}
static int arm7_regs_write(struct target_s *target, const void *data)
{
struct target_arm7_s *t = (struct target_arm7_s *)target;
memcpy(t->reg_cache, data, target->regs_size);
return 0;
}

View File

@ -3,6 +3,8 @@
* *
* Copyright (C) 2011 Black Sphere Technologies Ltd. * Copyright (C) 2011 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz> * Written by Gareth McMullin <gareth@blacksphere.co.nz>
* Copyright (C) 2021 Uwe Bonnes
* (bon@elektron.ikp.physik.tu-darmstadt.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
@ -20,140 +22,648 @@
/* This file implements a basic command interpreter for GDB 'monitor' /* This file implements a basic command interpreter for GDB 'monitor'
* commands. * commands.
*
* TODO: Add a mechanism for target driver so register new commands.
*/ */
#include <stdlib.h>
#include <string.h>
#include "general.h" #include "general.h"
#include "exception.h"
#include "command.h" #include "command.h"
#include "gdb_packet.h" #include "gdb_packet.h"
#include "jtag_scan.h"
#include "target.h" #include "target.h"
#include "target_internal.h"
#include "morse.h"
#include "version.h"
#include "serialno.h"
#include "adiv5.h" #ifdef ENABLE_RTT
#include "rtt.h"
#endif
void cmd_version(void); #ifdef PLATFORM_HAS_TRACESWO
void cmd_help(void); # include "traceswo.h"
#endif
void cmd_jtag_scan(void); static bool cmd_version(target *t, int argc, char **argv);
void cmd_swdp_scan(void); #ifdef PLATFORM_HAS_PRINTSERIAL
void cmd_targets(void); static bool cmd_serial(target *t, int argc, char **argv);
void cmd_morse(void); #endif
static bool cmd_help(target *t, int argc, char **argv);
static bool cmd_jtag_scan(target *t, int argc, char **argv);
static bool cmd_swdp_scan(target *t, int argc, char **argv);
static bool cmd_frequency(target *t, int argc, char **argv);
static bool cmd_targets(target *t, int argc, char **argv);
static bool cmd_morse(target *t, int argc, char **argv);
static bool cmd_halt_timeout(target *t, int argc, const char **argv);
static bool cmd_connect_srst(target *t, int argc, const char **argv);
static bool cmd_hard_srst(target *t, int argc, const char **argv);
#ifdef PLATFORM_HAS_POWER_SWITCH
static bool cmd_target_power(target *t, int argc, const char **argv);
#endif
#ifdef PLATFORM_HAS_TRACESWO
static bool cmd_traceswo(target *t, int argc, const char **argv);
#endif
static bool cmd_heapinfo(target *t, int argc, const char **argv);
#ifdef ENABLE_RTT
static bool cmd_rtt(target *t, int argc, const char **argv);
#endif
#if defined(PLATFORM_HAS_DEBUG) && (PC_HOSTED == 0)
static bool cmd_debug_bmp(target *t, int argc, const char **argv);
#endif
#ifdef PLATFORM_HAS_UART_WHEN_SWDP
static bool cmd_convert_tdio(target *t, int argc, const char **argv);
static bool cmd_set_srst(target *t, int argc, const char **argv);
#endif
#ifdef PLATFORM_HAS_BOOTLOADER
static bool cmd_enter_bootldr(target *t, int argc, const char **argv);
#endif
const struct command_s cmd_list[] = { const struct command_s cmd_list[] = {
{"version", (cmd_handler)cmd_version, "Display firmware version info"}, {"version", (cmd_handler)cmd_version, "Display firmware version info"},
#ifdef PLATFORM_HAS_PRINTSERIAL
{"serial", (cmd_handler)cmd_serial, "Display firmware serial number"},
#endif
{"help", (cmd_handler)cmd_help, "Display help for monitor commands"}, {"help", (cmd_handler)cmd_help, "Display help for monitor commands"},
{"jtag_scan", (cmd_handler)cmd_jtag_scan, "Scan JTAG chain for devices" }, {"jtag_scan", (cmd_handler)cmd_jtag_scan, "Scan JTAG chain for devices" },
{"swdp_scan", (cmd_handler)cmd_swdp_scan, "Scan SW-DP for devices" }, {"swdp_scan", (cmd_handler)cmd_swdp_scan, "Scan SW-DP for devices" },
{"frequency", (cmd_handler)cmd_frequency, "set minimum high and low times" },
{"targets", (cmd_handler)cmd_targets, "Display list of available targets" }, {"targets", (cmd_handler)cmd_targets, "Display list of available targets" },
{"morse", (cmd_handler)cmd_morse, "Display morse error message" }, {"morse", (cmd_handler)cmd_morse, "Display morse error message" },
{"halt_timeout", (cmd_handler)cmd_halt_timeout, "Timeout (ms) to wait until Cortex-M is halted: (Default 2000)" },
{"connect_srst", (cmd_handler)cmd_connect_srst, "Configure connect under SRST: (enable|disable)" },
{"hard_srst", (cmd_handler)cmd_hard_srst, "Force a pulse on the hard SRST line - disconnects target" },
#ifdef PLATFORM_HAS_POWER_SWITCH
{"tpwr", (cmd_handler)cmd_target_power, "Supplies power to the target: (enable|disable)"},
#endif
#ifdef ENABLE_RTT
{"rtt", (cmd_handler)cmd_rtt, "enable|disable|status|channel 0..15|ident (str)|cblock|poll maxms minms maxerr" },
#endif
#ifdef PLATFORM_HAS_TRACESWO
#if defined TRACESWO_PROTOCOL && TRACESWO_PROTOCOL == 2
{"traceswo", (cmd_handler)cmd_traceswo, "Start trace capture, NRZ mode: (baudrate) (decode channel ...)" },
#else
{"traceswo", (cmd_handler)cmd_traceswo, "Start trace capture, Manchester mode: (decode channel ...)" },
#endif
#endif
{"heapinfo", (cmd_handler)cmd_heapinfo, "Set semihosting heapinfo" },
#if defined(PLATFORM_HAS_DEBUG) && (PC_HOSTED == 0)
{"debug_bmp", (cmd_handler)cmd_debug_bmp, "Output BMP \"debug\" strings to the second vcom: (enable|disable)"},
#endif
#ifdef PLATFORM_HAS_UART_WHEN_SWDP
{"convert_tdio", (cmd_handler)cmd_convert_tdio,"Switch TDI/O pins to UART TX/RX functions"},
{"set_srst", (cmd_handler)cmd_set_srst,"Set output state of SRST pin (enable|disable)"},
#endif
#ifdef PLATFORM_HAS_BOOTLOADER
{"enter_bootldr", (cmd_handler)cmd_enter_bootldr,"Force BMP into bootloader mode"},
#endif
{NULL, NULL, NULL} {NULL, NULL, NULL}
}; };
bool connect_assert_srst;
#if defined(PLATFORM_HAS_DEBUG) && (PC_HOSTED == 0)
bool debug_bmp;
#endif
unsigned cortexm_wait_timeout = 2000; /* Timeout to wait for Cortex to react on halt command. */
int command_process(char *cmd) int command_process(target *t, char *cmd)
{ {
const struct command_s *c; const struct command_s *c;
int argc = 0; int argc = 1;
const char **argv; const char **argv;
const char *part;
/* Initial estimate for argc */ /* Initial estimate for argc */
for(char *s = cmd; *s; s++) for(char *s = cmd; *s; s++)
if((*s == ' ') || (*s == '\t')) argc++; if((*s == ' ') || (*s == '\t')) argc++;
argv = alloca(sizeof(const char *) * argc); argv = alloca(sizeof(const char *) * argc);
/* Tokenize cmd to find argv */ /* Tokenize cmd to find argv */
for(argc = 0, argv[argc] = strtok(cmd, " \t"); argc = 0;
argv[argc]; argv[++argc] = strtok(NULL, " \t")); for (part = strtok(cmd, " \t"); part; part = strtok(NULL, " \t"))
argv[argc++] = part;
/* Look for match and call handler */ /* Look for match and call handler */
for(c = cmd_list; c->cmd; c++) { for(c = cmd_list; c->cmd; c++) {
if(!strcmp(argv[0], c->cmd)) { /* Accept a partial match as GDB does.
c->handler(argc, argv); * So 'mon ver' will match 'monitor version'
return 0; */
} if ((argc == 0) || !strncmp(argv[0], c->cmd, strlen(argv[0])))
return !c->handler(t, argc, argv);
} }
return -1; if (!t)
return -1;
return target_command(t, argc, argv);
} }
void cmd_version(void) #define BOARD_IDENT "Black Magic Probe" PLATFORM_IDENT FIRMWARE_VERSION
bool cmd_version(target *t, int argc, char **argv)
{ {
gdb_out("Black Magic Probe (Firmware 1.5" VERSION_SUFFIX ", build " BUILDDATE ")\n"); (void)t;
gdb_out("Copyright (C) 2011 Black Sphere Technologies Ltd.\n"); (void)argc;
(void)argv;
#if PC_HOSTED == 1
char ident[256];
gdb_ident(ident, sizeof(ident));
DEBUG_WARN("%s\n", ident);
#else
gdb_out(BOARD_IDENT);
gdb_outf(", Hardware Version %d\n", platform_hwversion());
gdb_out("Copyright (C) 2022 Black Magic Debug Project\n");
gdb_out("License GPLv3+: GNU GPL version 3 or later " gdb_out("License GPLv3+: GNU GPL version 3 or later "
"<http://gnu.org/licenses/gpl.html>\n\n"); "<http://gnu.org/licenses/gpl.html>\n\n");
#endif
return true;
} }
void cmd_help(void) bool cmd_help(target *t, int argc, char **argv)
{ {
(void)argc;
(void)argv;
const struct command_s *c; const struct command_s *c;
for(c = cmd_list; c->cmd; c++) if (!t || t->tc->destroy_callback) {
gdb_outf("%s -- %s\n", c->cmd, c->help); gdb_out("General commands:\n");
} for(c = cmd_list; c->cmd; c++)
gdb_outf("\t%s -- %s\n", c->cmd, c->help);
void cmd_jtag_scan(void)
{
int devs = jtag_scan();
if(devs < 0) {
gdb_out("JTAG device scan failed!\n");
return;
}
if(devs == 0) {
gdb_out("JTAG scan found no devices!\n");
return;
}
gdb_outf("Device IR Len IDCODE Description\n");
for(int i = 0; i < jtag_dev_count; i++)
gdb_outf("%d\t%d\t0x%08lX %s\n", i,
jtag_devs[i].ir_len, jtag_devs[i].idcode,
jtag_devs[i].descr);
gdb_out("\n");
cmd_targets();
}
void cmd_swdp_scan(void)
{
if(adiv5_swdp_scan() < 0) {
gdb_out("SW-DP scan failed!\n");
return;
}
gdb_outf("SW-DP detected IDCODE: 0x%08X\n", adiv5_dp_list->idcode);
cmd_targets();
}
void cmd_targets(void)
{
struct target_s *t;
int i;
if(!target_list) {
gdb_out("No usable targets found.\n");
return;
} }
if (!t)
return -1;
target_command_help(t);
return true;
}
static bool cmd_jtag_scan(target *t, int argc, char **argv)
{
(void)t;
uint8_t irlens[argc];
if (platform_target_voltage())
gdb_outf("Target voltage: %s\n", platform_target_voltage());
if (argc > 1) {
/* Accept a list of IR lengths on command line */
for (int i = 1; i < argc; i++)
irlens[i-1] = atoi(argv[i]);
irlens[argc-1] = 0;
}
if(connect_assert_srst)
platform_srst_set_val(true); /* will be deasserted after attach */
int devs = -1;
volatile struct exception e;
TRY_CATCH (e, EXCEPTION_ALL) {
#if PC_HOSTED == 1
devs = platform_jtag_scan(argc > 1 ? irlens : NULL);
#else
devs = jtag_scan(argc > 1 ? irlens : NULL);
#endif
}
switch (e.type) {
case EXCEPTION_TIMEOUT:
gdb_outf("Timeout during scan. Is target stuck in WFI?\n");
break;
case EXCEPTION_ERROR:
gdb_outf("Exception: %s\n", e.msg);
break;
}
if(devs <= 0) {
platform_srst_set_val(false);
gdb_out("JTAG device scan failed!\n");
return false;
}
cmd_targets(NULL, 0, NULL);
morse(NULL, false);
return true;
}
bool cmd_swdp_scan(target *t, int argc, char **argv)
{
(void)t;
volatile uint32_t targetid = 0;
if (argc > 1)
targetid = strtol(argv[1], NULL, 0);
if (platform_target_voltage())
gdb_outf("Target voltage: %s\n", platform_target_voltage());
if(connect_assert_srst)
platform_srst_set_val(true); /* will be deasserted after attach */
int devs = -1;
volatile struct exception e;
TRY_CATCH (e, EXCEPTION_ALL) {
#if PC_HOSTED == 1
devs = platform_adiv5_swdp_scan(targetid);
#else
devs = adiv5_swdp_scan(targetid);
#endif
}
switch (e.type) {
case EXCEPTION_TIMEOUT:
gdb_outf("Timeout during scan. Is target stuck in WFI?\n");
break;
case EXCEPTION_ERROR:
gdb_outf("Exception: %s\n", e.msg);
break;
}
if(devs <= 0) {
platform_srst_set_val(false);
gdb_out("SW-DP scan failed!\n");
return false;
}
cmd_targets(NULL, 0, NULL);
morse(NULL, false);
return true;
}
bool cmd_frequency(target *t, int argc, char **argv)
{
(void)t;
if (argc == 2) {
char *p;
uint32_t frequency = strtol(argv[1], &p, 10);
switch(*p) {
case 'k':
frequency *= 1000;
break;
case 'M':
frequency *= 1000*1000;
break;
}
platform_max_frequency_set(frequency);
}
uint32_t freq = platform_max_frequency_get();
if (freq == FREQ_FIXED)
gdb_outf("SWJ freq fixed\n");
else
gdb_outf("Max SWJ freq %08" PRIx32 "\n", freq);
return true;
}
static void display_target(int i, target *t, void *context)
{
(void)context;
if (!strcmp(target_driver_name(t), "ARM Cortex-M")) {
gdb_outf("***%2d%sUnknown %s Designer %3x Partno %3x %s\n",
i, target_attached(t)?" * ":" ",
target_driver_name(t),
target_designer(t),
target_idcode(t),
(target_core_name(t)) ? target_core_name(t): "");
} else {
gdb_outf("%2d %c %s %s\n", i, target_attached(t)?'*':' ',
target_driver_name(t),
(target_core_name(t)) ? target_core_name(t): "");
}
}
bool cmd_targets(target *t, int argc, char **argv)
{
(void)t;
(void)argc;
(void)argv;
gdb_out("Available Targets:\n"); gdb_out("Available Targets:\n");
gdb_out("No. Att Driver\n"); gdb_out("No. Att Driver\n");
for(t = target_list, i = 1; t; t = t->next, i++) if (!target_foreach(display_target, NULL)) {
gdb_outf("%2d %c %s\n", i, t==cur_target?'*':' ', gdb_out("No usable targets found.\n");
t->driver); return false;
}
return true;
} }
void cmd_morse(void) bool cmd_morse(target *t, int argc, char **argv)
{ {
if(morse_msg) (void)t;
(void)argc;
(void)argv;
if(morse_msg) {
gdb_outf("%s\n", morse_msg); gdb_outf("%s\n", morse_msg);
DEBUG_WARN("%s\n", morse_msg);
}
return true;
} }
bool parse_enable_or_disable(const char *s, bool *out) {
if (strlen(s) == 0) {
gdb_outf("'enable' or 'disable' argument must be provided\n");
return false;
} else if (!strncmp(s, "enable", strlen(s))) {
*out = true;
return true;
} else if (!strncmp(s, "disable", strlen(s))) {
*out = false;
return true;
} else {
gdb_outf("Argument '%s' not recognized as 'enable' or 'disable'\n", s);
return false;
}
}
static bool cmd_connect_srst(target *t, int argc, const char **argv)
{
(void)t;
bool print_status = false;
if (argc == 1) {
print_status = true;
} else if (argc == 2) {
if (parse_enable_or_disable(argv[1], &connect_assert_srst)) {
print_status = true;
}
} else {
gdb_outf("Unrecognized command format\n");
}
if (print_status) {
gdb_outf("Assert SRST during connect: %s\n",
connect_assert_srst ? "enabled" : "disabled");
}
return true;
}
static bool cmd_halt_timeout(target *t, int argc, const char **argv)
{
(void)t;
if (argc > 1)
cortexm_wait_timeout = atol(argv[1]);
gdb_outf("Cortex-M timeout to wait for device haltes: %d\n",
cortexm_wait_timeout);
return true;
}
static bool cmd_hard_srst(target *t, int argc, const char **argv)
{
(void)t;
(void)argc;
(void)argv;
target_list_free();
platform_srst_set_val(true);
platform_srst_set_val(false);
return true;
}
#ifdef PLATFORM_HAS_POWER_SWITCH
static bool cmd_target_power(target *t, int argc, const char **argv)
{
(void)t;
if (argc == 1) {
gdb_outf("Target Power: %s\n",
platform_target_get_power() ? "enabled" : "disabled");
} else if (argc == 2) {
bool want_enable = false;
if (parse_enable_or_disable(argv[1], &want_enable)) {
if (want_enable
&& !platform_target_get_power()
&& platform_target_voltage_sense() > POWER_CONFLICT_THRESHOLD) {
/* want to enable target power, but VREF > 0.5V sensed -> cancel */
gdb_outf("Target already powered (%s)\n", platform_target_voltage());
} else {
platform_target_set_power(want_enable);
gdb_outf("%s target power\n", want_enable ? "Enabling" : "Disabling");
}
}
} else {
gdb_outf("Unrecognized command format\n");
}
return true;
}
#endif
#ifdef ENABLE_RTT
static const char *on_or_off(const bool value)
{
return value ? "on" : "off";
}
static bool cmd_rtt(target *t, int argc, const char **argv)
{
(void)t;
const size_t command_len = strlen(argv[1]);
if (argc == 1 || (argc == 2 && !strncmp(argv[1], "enabled", command_len))) {
rtt_enabled = true;
rtt_found = false;
} else if ((argc == 2) && !strncmp(argv[1], "disabled", command_len)) {
rtt_enabled = false;
rtt_found = false;
} else if ((argc == 2) && !strncmp(argv[1], "status", command_len)) {
gdb_outf("rtt: %s found: %s ident: \"%s\"", on_or_off(rtt_enabled), rtt_found ? "yes" : "no",
rtt_ident[0] == '\0' ? "off" : rtt_ident);
gdb_outf(" halt: %s", on_or_off(target_no_background_memory_access(t)));
gdb_out(" channels: ");
if (rtt_auto_channel)
gdb_out("auto ");
for (size_t i = 0; i < MAX_RTT_CHAN; i++) {
if (rtt_channel[i].is_enabled)
gdb_outf("%d ", i);
}
gdb_outf(
"\nmax poll ms: %u min poll ms: %u max errs: %u\n", rtt_max_poll_ms, rtt_min_poll_ms, rtt_max_poll_errs);
} else if (argc >= 2 && !strncmp(argv[1], "channel", command_len)) {
/* mon rtt channel switches to auto rtt channel selection
mon rtt channel number... selects channels given */
for (size_t i = 0; i < MAX_RTT_CHAN; i++)
rtt_channel[i].is_enabled = false;
if (argc == 2)
rtt_auto_channel = true;
else {
rtt_auto_channel = false;
for (size_t i = 2; i < (size_t)argc; ++i) {
const uint32_t channel = strtoul(argv[i], NULL, 0);
if (channel < MAX_RTT_CHAN)
rtt_channel[channel].is_enabled = true;
}
}
} else if (argc == 2 && !strncmp(argv[1], "ident", command_len))
rtt_ident[0] = '\0';
else if (argc == 2 && !strncmp(argv[1], "poll", command_len))
gdb_outf("%u %u %u\n", rtt_max_poll_ms, rtt_min_poll_ms, rtt_max_poll_errs);
else if (argc == 2 && !strncmp(argv[1], "cblock", command_len)) {
gdb_outf("cbaddr: 0x%x\n", rtt_cbaddr);
gdb_out("ch ena cfg i/o buf@ size head@ tail@ flg\n");
for (size_t i = 0; i < MAX_RTT_CHAN; ++i) {
gdb_outf("%2zu %c %c %s 0x%08x %5d 0x%08x 0x%08x %d\n", i, rtt_channel[i].is_enabled ? 'y' : 'n',
rtt_channel[i].is_configured ? 'y' : 'n', rtt_channel[i].is_output ? "out" : "in ",
rtt_channel[i].buf_addr, rtt_channel[i].buf_size, rtt_channel[i].head_addr, rtt_channel[i].tail_addr,
rtt_channel[i].flag);
}
} else if (argc == 3 && !strncmp(argv[1], "ident", command_len)) {
strncpy(rtt_ident, argv[2], sizeof(rtt_ident));
rtt_ident[sizeof(rtt_ident) - 1] = '\0';
for (size_t i = 0; i < sizeof(rtt_ident); i++) {
if (rtt_ident[i] == '_')
rtt_ident[i] = ' ';
}
} else if (argc == 5 && !strncmp(argv[1], "poll", command_len)) {
/* set polling params */
rtt_max_poll_ms = strtoul(argv[2], NULL, 0);
rtt_min_poll_ms = strtoul(argv[3], NULL, 0);
rtt_max_poll_errs = strtoul(argv[4], NULL, 0);
} else
gdb_out("what?\n");
return true;
}
#endif
#ifdef PLATFORM_HAS_TRACESWO
static bool cmd_traceswo(target *t, int argc, const char **argv)
{
char serial_no[DFU_SERIAL_LENGTH];
(void)t;
#if TRACESWO_PROTOCOL == 2
uint32_t baudrate = SWO_DEFAULT_BAUD;
#endif
uint32_t swo_channelmask = 0; /* swo decoding off */
uint8_t decode_arg = 1;
#if TRACESWO_PROTOCOL == 2
/* argument: optional baud rate for async mode */
if ((argc > 1) && (*argv[1] >= '0') && (*argv[1] <= '9')) {
baudrate = atoi(argv[1]);
if (baudrate == 0) baudrate = SWO_DEFAULT_BAUD;
decode_arg = 2;
}
#endif
/* argument: 'decode' literal */
if((argc > decode_arg) && !strncmp(argv[decode_arg], "decode", strlen(argv[decode_arg]))) {
swo_channelmask = 0xFFFFFFFF; /* decoding all channels */
/* arguments: channels to decode */
if (argc > decode_arg + 1) {
swo_channelmask = 0x0;
for (int i = decode_arg+1; i < argc; i++) { /* create bitmask of channels to decode */
int channel = atoi(argv[i]);
if ((channel >= 0) && (channel <= 31))
swo_channelmask |= (uint32_t)0x1 << channel;
}
}
}
#if defined(PLATFORM_HAS_DEBUG) && (PC_HOSTED == 0) && defined(ENABLE_DEBUG)
if (debug_bmp) {
#if TRACESWO_PROTOCOL == 2
gdb_outf("baudrate: %lu ", baudrate);
#endif
gdb_outf("channel mask: ");
for (int8_t i=31;i>=0;i--) {
uint8_t bit = (swo_channelmask >> i) & 0x1;
gdb_outf("%u", bit);
}
gdb_outf("\n");
}
#endif
#if TRACESWO_PROTOCOL == 2
traceswo_init(baudrate, swo_channelmask);
#else
traceswo_init(swo_channelmask);
#endif
serial_no_read(serial_no);
gdb_outf("%s:%02X:%02X\n", serial_no, 5, 0x85);
return true;
}
#endif
#if defined(PLATFORM_HAS_DEBUG) && (PC_HOSTED == 0)
static bool cmd_debug_bmp(target *t, int argc, const char **argv)
{
(void)t;
bool print_status = false;
if (argc == 1) {
print_status = true;
} else if (argc == 2) {
if (parse_enable_or_disable(argv[1], &debug_bmp)) {
print_status = true;
}
} else {
gdb_outf("Unrecognized command format\n");
}
if (print_status) {
gdb_outf("Debug mode is %s\n",
debug_bmp ? "enabled" : "disabled");
}
return true;
}
#endif
#ifdef PLATFORM_HAS_UART_WHEN_SWDP
static bool cmd_convert_tdio(target *t, int argc, const char **argv)
{
(void)t;
uint8_t val;
if (argc > 1) {
val = (!strcmp(argv[1], "enable")) ? true : false;
usbuart_convert_tdio(val);
} else {
gdb_outf("Convert_tdio: %s\n",(usbuart_convert_tdio_enabled()) ?
"enabled" : "disabled");
}
return true;
}
static bool cmd_set_srst(target *t, int argc, const char **argv)
{
(void) t;
uint8_t val;
if (argc > 1) {
val = (!strcmp(argv[1], "enable")) ? true : false;
platform_srst_set_val(val);
} else {
gdb_outf("SRST: %s\n",(platform_srst_get_val()) ?
"enabled" : "disabled");
}
return true;
}
#endif
#ifdef PLATFORM_HAS_BOOTLOADER
static bool cmd_enter_bootldr(target *t, int argc, const char **argv)
{
(void) t;
(void) argc;
(void) argv;
scb_reset_system();
return true;
}
#endif
#ifdef PLATFORM_HAS_PRINTSERIAL
bool cmd_serial(target *t, int argc, char **argv)
{
(void) t;
(void) argc;
(void) argv;
print_serial();
return true;
}
#endif
static bool cmd_heapinfo(target *t, int argc, const char **argv)
{
if (t == NULL) gdb_out("not attached\n");
else if (argc == 5) {
target_addr heap_base = strtoul(argv[1], NULL, 16);
target_addr heap_limit = strtoul(argv[2], NULL, 16);
target_addr stack_base = strtoul(argv[3], NULL, 16);
target_addr stack_limit = strtoul(argv[4], NULL, 16);
gdb_outf("heapinfo heap_base: %p heap_limit: %p stack_base: %p stack_limit: %p\n",
heap_base, heap_limit, stack_base, stack_limit);
target_set_heapinfo(t, heap_base, heap_limit, stack_base, stack_limit);
} else gdb_outf("heapinfo heap_base heap_limit stack_base stack_limit\n");
return true;
}

View File

@ -1,643 +0,0 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2011 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* This file implements debugging functionality specific to ARM
* the Cortex-M3 core. This should be generic to ARMv7-M as it is
* implemented according to the "ARMv7-M Architectue Reference Manual",
* ARM doc DDI0403C.
*
* Issues:
* There are way too many magic numbers used here.
*/
#include <stdio.h>
#include "general.h"
#include "jtagtap.h"
#include "jtag_scan.h"
#include "adiv5.h"
#include "target.h"
#include "cortexm3.h"
#include "lmi.h"
#include "stm32_tgt.h"
static char cm3_driver_str[] = "ARM Cortex-M3";
/* Private peripheral bus base address */
#define CM3_PPB_BASE 0xE0000000
#define CM3_SCS_BASE (CM3_PPB_BASE + 0xE000)
#define CM3_AIRCR (CM3_SCS_BASE + 0xD0C)
#define CM3_CFSR (CM3_SCS_BASE + 0xD28)
#define CM3_HFSR (CM3_SCS_BASE + 0xD2C)
#define CM3_DFSR (CM3_SCS_BASE + 0xD30)
#define CM3_DHCSR (CM3_SCS_BASE + 0xDF0)
#define CM3_DCRSR (CM3_SCS_BASE + 0xDF4)
#define CM3_DCRDR (CM3_SCS_BASE + 0xDF8)
#define CM3_DEMCR (CM3_SCS_BASE + 0xDFC)
#define CM3_FPB_BASE (CM3_PPB_BASE + 0x2000)
/* ARM Literature uses FP_*, we use CM3_FPB_* consistently */
#define CM3_FPB_CTRL (CM3_FPB_BASE + 0x000)
#define CM3_FPB_REMAP (CM3_FPB_BASE + 0x004)
#define CM3_FPB_COMP(i) (CM3_FPB_BASE + 0x008 + (4*(i)))
#define CM3_DWT_BASE (CM3_PPB_BASE + 0x1000)
#define CM3_DWT_CTRL (CM3_DWT_BASE + 0x000)
#define CM3_DWT_COMP(i) (CM3_DWT_BASE + 0x020 + (0x10*(i)))
#define CM3_DWT_MASK(i) (CM3_DWT_BASE + 0x024 + (0x10*(i)))
#define CM3_DWT_FUNC(i) (CM3_DWT_BASE + 0x028 + (0x10*(i)))
/* Application Interrupt and Reset Control Register (AIRCR) */
#define CM3_AIRCR_VECTKEY (0x05FA << 16)
/* Bits 31:16 - Read as VECTKETSTAT, 0xFA05 */
#define CM3_AIRCR_ENDIANESS (1 << 15)
/* Bits 15:11 - Unused, reserved */
#define CM3_AIRCR_PRIGROUP (7 << 8)
/* Bits 7:3 - Unused, reserved */
#define CM3_AIRCR_SYSRESETREQ (1 << 2)
#define CM3_AIRCR_VECTCLRACTIVE (1 << 1)
#define CM3_AIRCR_VECTRESET (1 << 0)
/* HardFault Status Register (HFSR) */
#define CM3_HFSR_DEBUGEVT (1 << 31)
#define CM3_HFSR_FORCED (1 << 30)
/* Bits 29:2 - Not specified */
#define CM3_HFSR_VECTTBL (1 << 1)
/* Bits 0 - Reserved */
/* Debug Fault Status Register (DFSR) */
/* Bits 31:5 - Reserved */
#define CM3_DFSR_RESETALL 0x1F
#define CM3_DFSR_EXTERNAL (1 << 4)
#define CM3_DFSR_VCATCH (1 << 3)
#define CM3_DFSR_DWTTRAP (1 << 2)
#define CM3_DFSR_BKPT (1 << 1)
#define CM3_DFSR_HALTED (1 << 0)
/* Debug Halting Control and Status Register (DHCSR) */
/* This key must be written to bits 31:16 for write to take effect */
#define CM3_DHCSR_DBGKEY 0xA05F0000
/* Bits 31:26 - Reserved */
#define CM3_DHCSR_S_RESET_ST (1 << 25)
#define CM3_DHCSR_S_RETIRE_ST (1 << 24)
/* Bits 23:20 - Reserved */
#define CM3_DHCSR_S_LOCKUP (1 << 19)
#define CM3_DHCSR_S_SLEEP (1 << 18)
#define CM3_DHCSR_S_HALT (1 << 17)
#define CM3_DHCSR_S_REGRDY (1 << 16)
/* Bits 15:6 - Reserved */
#define CM3_DHCSR_C_SNAPSTALL (1 << 5)
/* Bit 4 - Reserved */
#define CM3_DHCSR_C_MASKINTS (1 << 3)
#define CM3_DHCSR_C_STEP (1 << 2)
#define CM3_DHCSR_C_HALT (1 << 1)
#define CM3_DHCSR_C_DEBUGEN (1 << 0)
/* Debug Core Register Selector Register (DCRSR) */
#define CM3_DCRSR_REGSEL_MASK 0x0000001F
#define CM3_DCRSR_REGSEL_XPSR 0x00000010
#define CM3_DCRSR_REGSEL_MSP 0x00000011
#define CM3_DCRSR_REGSEL_PSP 0x00000012
/* Debug Exception and Monitor Control Register (DEMCR) */
/* Bits 31:25 - Reserved */
#define CM3_DEMCR_TRCENA (1 << 24)
/* Bits 23:20 - Reserved */
#define CM3_DEMCR_MON_REQ (1 << 19)
#define CM3_DEMCR_MON_STEP (1 << 18)
#define CM3_DEMCR_VC_MON_PEND (1 << 17)
#define CM3_DEMCR_VC_MON_EN (1 << 16)
/* Bits 15:11 - Reserved */
#define CM3_DEMCR_VC_HARDERR (1 << 10)
#define CM3_DEMCR_VC_INTERR (1 << 9)
#define CM3_DEMCR_VC_BUSERR (1 << 8)
#define CM3_DEMCR_VC_STATERR (1 << 7)
#define CM3_DEMCR_VC_CHKERR (1 << 6)
#define CM3_DEMCR_VC_NOCPERR (1 << 5)
#define CM3_DEMCR_VC_MMERR (1 << 4)
/* Bits 3:1 - Reserved */
#define CM3_DEMCR_VC_CORERESET (1 << 0)
/* Flash Patch and Breakpoint Control Register (FP_CTRL) */
/* Bits 32:15 - Reserved */
/* Bits 14:12 - NUM_CODE2 */
/* Bits 11:8 - NUM_LIT */
/* Bits 7:4 - NUM_CODE1 */
/* Bits 3:2 - Unspecified */
#define CM3_FPB_CTRL_KEY (1 << 1)
#define CM3_FPB_CTRL_ENABLE (1 << 0)
/* Data Watchpoint and Trace Mask Register (DWT_MASKx) */
#define CM3_DWT_MASK_BYTE (0 << 0)
#define CM3_DWT_MASK_HALFWORD (1 << 0)
#define CM3_DWT_MASK_WORD (3 << 0)
/* Data Watchpoint and Trace Function Register (DWT_FUNCTIONx) */
#define CM3_DWT_FUNC_MATCHED (1 << 24)
#define CM3_DWT_FUNC_DATAVSIZE_WORD (2 << 10)
#define CM3_DWT_FUNC_FUNC_READ (5 << 0)
#define CM3_DWT_FUNC_FUNC_WRITE (6 << 0)
#define CM3_DWT_FUNC_FUNC_ACCESS (7 << 0)
static void cm3_attach(struct target_s *target);
static void cm3_detach(struct target_s *target);
static int cm3_regs_read(struct target_s *target, void *data);
static int cm3_regs_write(struct target_s *target, const void *data);
static int cm3_pc_write(struct target_s *target, const uint32_t val);
static void cm3_reset(struct target_s *target);
static void cm3_halt_resume(struct target_s *target, uint8_t step);
static int cm3_halt_wait(struct target_s *target);
static void cm3_halt_request(struct target_s *target);
static int cm3_fault_unwind(struct target_s *target);
static int cm3_set_hw_bp(struct target_s *target, uint32_t addr);
static int cm3_clear_hw_bp(struct target_s *target, uint32_t addr);
static int cm3_set_hw_wp(struct target_s *target, uint8_t type, uint32_t addr, uint8_t len);
static int cm3_clear_hw_wp(struct target_s *target, uint8_t type, uint32_t addr, uint8_t len);
static int cm3_check_hw_wp(struct target_s *target, uint32_t *addr);
/* Watchpoint unit status */
static struct wp_unit_s {
uint32_t addr;
uint8_t type;
uint8_t size;
} hw_watchpoint[4];
/* Breakpoint unit status */
static uint32_t hw_breakpoint[6];
/* Register number tables */
static uint32_t regnum_v7m[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* standard r0-r15 */
0x10, /* xpsr */
0x11, /* msp */
0x12, /* psp */
0x14 /* special */
};
#if 0
/* XXX: need some way for a specific CPU to indicate it has FP registers */
static uint32_t regnum_v7mf[] = {
0x21, /* fpscr */
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* s0-s7 */
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* s8-s15 */
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* s16-s23 */
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* s24-s31 */
};
#endif
static const char tdesc_armv7m[] =
"<?xml version=\"1.0\"?>"
"<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
"<target>"
" <architecture>arm</architecture>"
" <feature name=\"org.gnu.gdb.arm.m-profile\">"
" <reg name=\"r0\" bitsize=\"32\"/>"
" <reg name=\"r1\" bitsize=\"32\"/>"
" <reg name=\"r2\" bitsize=\"32\"/>"
" <reg name=\"r3\" bitsize=\"32\"/>"
" <reg name=\"r4\" bitsize=\"32\"/>"
" <reg name=\"r5\" bitsize=\"32\"/>"
" <reg name=\"r6\" bitsize=\"32\"/>"
" <reg name=\"r7\" bitsize=\"32\"/>"
" <reg name=\"r8\" bitsize=\"32\"/>"
" <reg name=\"r9\" bitsize=\"32\"/>"
" <reg name=\"r10\" bitsize=\"32\"/>"
" <reg name=\"r11\" bitsize=\"32\"/>"
" <reg name=\"r12\" bitsize=\"32\"/>"
" <reg name=\"sp\" bitsize=\"32\" type=\"data_ptr\"/>"
" <reg name=\"lr\" bitsize=\"32\" type=\"code_ptr\"/>"
" <reg name=\"pc\" bitsize=\"32\" type=\"code_ptr\"/>"
" <reg name=\"xpsr\" bitsize=\"32\"/>"
" <reg name=\"msp\" bitsize=\"32\" save-restore=\"no\" type=\"data_ptr\"/>"
" <reg name=\"psp\" bitsize=\"32\" save-restore=\"no\" type=\"data_ptr\"/>"
" <reg name=\"special\" bitsize=\"32\" save-restore=\"no\"/>"
" </feature>"
"</target>";
int
cm3_probe(struct target_s *target)
{
target->driver = cm3_driver_str;
target->attach = cm3_attach;
target->detach = cm3_detach;
/* Should probe here to make sure it's Cortex-M3 */
target->tdesc = tdesc_armv7m;
target->regs_read = cm3_regs_read;
target->regs_write = cm3_regs_write;
target->pc_write = cm3_pc_write;
target->reset = cm3_reset;
target->halt_request = cm3_halt_request;
target->halt_wait = cm3_halt_wait;
target->halt_resume = cm3_halt_resume;
target->fault_unwind = cm3_fault_unwind;
target->regs_size = sizeof(regnum_v7m); /* XXX: detect FP extension */
if(stm32_probe(target) == 0) return 0;
if(stm32f4_probe(target) == 0) return 0;
/* if not STM32 try LMI which I don't know how to detect reliably */
lmi_probe(target);
return 0;
}
static void
cm3_attach(struct target_s *target)
{
struct target_ap_s *t = (void *)target;
int i;
target_halt_request(target);
while(!target_halt_wait(target));
/* Request halt on reset */
adiv5_ap_mem_write(t->ap, CM3_DEMCR,
CM3_DEMCR_TRCENA | CM3_DEMCR_VC_HARDERR |
CM3_DEMCR_VC_CORERESET);
/* Reset DFSR flags */
adiv5_ap_mem_write(t->ap, CM3_DFSR, CM3_DFSR_RESETALL);
/* Clear any stale breakpoints */
for(i = 0; i < 6; i++) {
adiv5_ap_mem_write(t->ap, CM3_FPB_COMP(i), 0);
hw_breakpoint[i] = 0;
}
/* Clear any stale watchpoints */
for(i = 0; i < 4; i++) {
adiv5_ap_mem_write(t->ap, CM3_DWT_FUNC(i), 0);
hw_watchpoint[i].type = 0;
}
/* Flash Patch Control Register: set ENABLE */
adiv5_ap_mem_write(t->ap, CM3_FPB_CTRL,
CM3_FPB_CTRL_KEY | CM3_FPB_CTRL_ENABLE);
target->set_hw_bp = cm3_set_hw_bp;
target->clear_hw_bp = cm3_clear_hw_bp;
/* Data Watchpoint and Trace */
target->set_hw_wp = cm3_set_hw_wp;
target->clear_hw_wp = cm3_clear_hw_wp;
target->check_hw_wp = cm3_check_hw_wp;
}
static void
cm3_detach(struct target_s *target)
{
struct target_ap_s *t = (void *)target;
int i;
/* Clear any stale breakpoints */
for(i = 0; i < 6; i++)
adiv5_ap_mem_write(t->ap, CM3_FPB_COMP(i), 0);
/* Clear any stale watchpoints */
for(i = 0; i < 4; i++)
adiv5_ap_mem_write(t->ap, CM3_DWT_FUNC(i), 0);
/* Disable debug */
adiv5_ap_mem_write(t->ap, CM3_DHCSR, CM3_DHCSR_DBGKEY);
}
static int
cm3_regs_read(struct target_s *target, void *data)
{
struct target_ap_s *t = (void *)target;
uint32_t *regs = data;
unsigned i;
/* FIXME: Describe what's really going on here */
adiv5_ap_write(t->ap, 0x00, 0xA2000052);
/* Map the banked data registers (0x10-0x1c) to the
* debug registers DHCSR, DCRSR, DCRDR and DEMCR respectively */
adiv5_dp_low_access(t->ap->dp, 1, 0, 0x04, CM3_DHCSR);
/* Walk the regnum_v7m array, reading the registers it
* calls out. */
adiv5_ap_write(t->ap, 0x14, regnum_v7m[0]); /* Required to switch banks */
*regs++ = adiv5_dp_read_ap(t->ap->dp, 0x18);
for(i = 1; i < sizeof(regnum_v7m) / 4; i++) {
adiv5_dp_low_access(t->ap->dp, 1, 0, 0x14, regnum_v7m[i]);
*regs++ = adiv5_dp_read_ap(t->ap->dp, 0x18);
}
return 0;
}
static int
cm3_regs_write(struct target_s *target, const void *data)
{
struct target_ap_s *t = (void *)target;
const uint32_t *regs = data;
int i;
/* FIXME: Describe what's really going on here */
adiv5_ap_write(t->ap, 0x00, 0xA2000052);
/* Map the banked data registers (0x10-0x1c) to the
* debug registers DHCSR, DCRSR, DCRDR and DEMCR respectively */
adiv5_dp_low_access(t->ap->dp, 1, 0, 0x04, CM3_DHCSR);
/* Walk the regnum_v7m array, writing the registers it
* calls out. */
adiv5_ap_write(t->ap, 0x18, *regs++); /* Required to switch banks */
adiv5_dp_low_access(t->ap->dp, 1, 0, 0x14, 0x10000 | regnum_v7m[0]);
for(i = 1; i < sizeof(regnum_v7m) / 4; i++) {
adiv5_dp_low_access(t->ap->dp, 1, 0, 0x18, *regs++);
adiv5_dp_low_access(t->ap->dp, 1, 0, 0x14, 0x10000 | regnum_v7m[i]);
}
return 0;
}
static int
cm3_pc_write(struct target_s *target, const uint32_t val)
{
struct target_ap_s *t = (void *)target;
adiv5_ap_write(t->ap, 0x00, 0xA2000052);
adiv5_dp_low_access(t->ap->dp, 1, 0, 0x04, 0xE000EDF0);
adiv5_ap_write(t->ap, 0x18, val); /* Required to switch banks */
adiv5_dp_low_access(t->ap->dp, 1, 0, 0x14, 0x1000F);
return 0;
}
/* The following three routines implement target halt/resume
* using the core debug registers in the NVIC. */
static void
cm3_reset(struct target_s *target)
{
struct target_ap_s *t = (void *)target;
jtagtap_srst();
/* Request system reset from NVIC: SRST doesn't work correctly */
/* This could be VECTRESET: 0x05FA0001 (reset only core)
* or SYSRESETREQ: 0x05FA0004 (system reset)
*/
adiv5_ap_mem_write(t->ap, CM3_AIRCR,
CM3_AIRCR_VECTKEY | CM3_AIRCR_SYSRESETREQ);
/* Poll for release from reset */
while(adiv5_ap_mem_read(t->ap, CM3_AIRCR) &
(CM3_AIRCR_VECTRESET | CM3_AIRCR_SYSRESETREQ));
/* Reset DFSR flags */
adiv5_ap_mem_write(t->ap, CM3_DFSR, CM3_DFSR_RESETALL);
}
static void
cm3_halt_request(struct target_s *target)
{
struct target_ap_s *t = (void *)target;
adiv5_ap_mem_write(t->ap, CM3_DHCSR,
CM3_DHCSR_DBGKEY | CM3_DHCSR_C_HALT | CM3_DHCSR_C_DEBUGEN);
}
static int
cm3_halt_wait(struct target_s *target)
{
struct target_ap_s *t = (void *)target;
return adiv5_ap_mem_read(t->ap, CM3_DHCSR) & CM3_DHCSR_S_HALT;
}
static void
cm3_halt_resume(struct target_s *target, uint8_t step)
{
struct target_ap_s *t = (void *)target;
static uint8_t old_step = 0;
uint32_t dhcsr = CM3_DHCSR_DBGKEY | CM3_DHCSR_C_DEBUGEN;
if(step) dhcsr |= CM3_DHCSR_C_STEP | CM3_DHCSR_C_MASKINTS;
/* Disable interrupts while single stepping... */
if(step != old_step) {
adiv5_ap_mem_write(t->ap, CM3_DHCSR, dhcsr | CM3_DHCSR_C_HALT);
old_step = step;
}
adiv5_ap_mem_write(t->ap, CM3_DHCSR, dhcsr);
}
static int cm3_fault_unwind(struct target_s *target)
{
struct target_ap_s *t = (void *)target;
uint32_t dfsr = adiv5_ap_mem_read(t->ap, CM3_DFSR);
uint32_t hfsr = adiv5_ap_mem_read(t->ap, CM3_HFSR);
uint32_t cfsr = adiv5_ap_mem_read(t->ap, CM3_CFSR);
adiv5_ap_mem_write(t->ap, CM3_DFSR, dfsr);/* write back to reset */
adiv5_ap_mem_write(t->ap, CM3_HFSR, hfsr);/* write back to reset */
adiv5_ap_mem_write(t->ap, CM3_CFSR, cfsr);/* write back to reset */
/* We check for FORCED in the HardFault Status Register or
* for a configurable fault to avoid catching core resets */
if((dfsr & CM3_DFSR_VCATCH) && ((hfsr & CM3_HFSR_FORCED) || cfsr)) {
/* Unwind exception */
uint32_t regs[target->regs_size];
uint32_t stack[8];
uint32_t retcode, framesize;
/* Read registers for post-exception stack pointer */
target_regs_read(target, regs);
/* save retcode currently in lr */
retcode = regs[14];
/* Read stack for pre-exception registers */
target_mem_read_words(target, stack, regs[13], sizeof(stack));
regs[14] = stack[5]; /* restore LR to pre-exception state */
regs[15] = stack[6]; /* restore PC to pre-exception state */
/* adjust stack to pop exception state */
framesize = (retcode & (1<<4)) ? 0x68 : 0x20; /* check for basic vs. extended frame */
if (stack[7] & (1<<9)) /* check for stack alignment fixup */
framesize += 4;
regs[13] += framesize;
/* FIXME: stack[7] contains xPSR when this is supported */
/* although, if we caught the exception it will be unchanged */
/* Reset exception state to allow resuming from restored
* state.
*/
adiv5_ap_mem_write(t->ap, CM3_AIRCR,
CM3_AIRCR_VECTKEY | CM3_AIRCR_VECTCLRACTIVE);
/* Write pre-exception registers back to core */
target_regs_write(target, regs);
return 1;
}
return 0;
}
/* The following routines implement hardware breakpoints.
* The Flash Patch and Breakpoint (FPB) system is used. */
static int
cm3_set_hw_bp(struct target_s *target, uint32_t addr)
{
struct target_ap_s *t = (void *)target;
uint32_t val = addr & 0x1FFFFFFC;
int i;
val |= (addr & 2)?0x80000000:0x40000000;
val |= 1;
for(i = 0; i < 6; i++)
if((hw_breakpoint[i] & 1) == 0) break;
if(i == 6) return -1;
hw_breakpoint[i] = addr | 1;
adiv5_ap_mem_write(t->ap, CM3_FPB_COMP(i), val);
return 0;
}
static int
cm3_clear_hw_bp(struct target_s *target, uint32_t addr)
{
struct target_ap_s *t = (void *)target;
int i;
for(i = 0; i < 6; i++)
if((hw_breakpoint[i] & ~1) == addr) break;
if(i == 6) return -1;
hw_breakpoint[i] = 0;
adiv5_ap_mem_write(t->ap, CM3_FPB_COMP(i), 0);
return 0;
}
/* The following routines implement hardware watchpoints.
* The Data Watch and Trace (DWT) system is used. */
static int
cm3_set_hw_wp(struct target_s *target, uint8_t type, uint32_t addr, uint8_t len)
{
struct target_ap_s *t = (void *)target;
int i;
switch(len) { /* Convert bytes size to mask size */
case 1: len = CM3_DWT_MASK_BYTE; break;
case 2: len = CM3_DWT_MASK_HALFWORD; break;
case 4: len = CM3_DWT_MASK_WORD; break;
default:
return -1;
}
switch(type) { /* Convert gdb type to function type */
case 2: type = CM3_DWT_FUNC_FUNC_WRITE; break;
case 3: type = CM3_DWT_FUNC_FUNC_READ; break;
case 4: type = CM3_DWT_FUNC_FUNC_ACCESS; break;
default:
return -1;
}
for(i = 0; i < 4; i++)
if((hw_watchpoint[i].type) == 0) break;
if(i == 4) return -2;
hw_watchpoint[i].type = type;
hw_watchpoint[i].addr = addr;
hw_watchpoint[i].size = len;
adiv5_ap_mem_write(t->ap, CM3_DWT_COMP(i), addr);
adiv5_ap_mem_write(t->ap, CM3_DWT_MASK(i), len);
adiv5_ap_mem_write(t->ap, CM3_DWT_FUNC(i),
CM3_DWT_FUNC_DATAVSIZE_WORD | type);
return 0;
}
static int
cm3_clear_hw_wp(struct target_s *target, uint8_t type, uint32_t addr, uint8_t len)
{
struct target_ap_s *t = (void *)target;
int i;
switch(len) {
case 1: len = CM3_DWT_MASK_BYTE; break;
case 2: len = CM3_DWT_MASK_HALFWORD; break;
case 4: len = CM3_DWT_MASK_WORD; break;
default:
return -1;
}
switch(type) {
case 2: type = CM3_DWT_FUNC_FUNC_WRITE; break;
case 3: type = CM3_DWT_FUNC_FUNC_READ; break;
case 4: type = CM3_DWT_FUNC_FUNC_ACCESS; break;
default:
return -1;
}
for(i = 0; i < 4; i++)
if((hw_watchpoint[i].addr == addr) &&
(hw_watchpoint[i].type == type) &&
(hw_watchpoint[i].size == len)) break;
if(i == 4) return -2;
hw_watchpoint[i].type = 0;
adiv5_ap_mem_write(t->ap, CM3_DWT_FUNC(i), 0);
return 0;
}
static int
cm3_check_hw_wp(struct target_s *target, uint32_t *addr)
{
struct target_ap_s *t = (void *)target;
int i;
for(i = 0; i < 4; i++)
/* if SET and MATCHED then break */
if(hw_watchpoint[i].type &&
(adiv5_ap_mem_read(t->ap, CM3_DWT_FUNC(i)) &
CM3_DWT_FUNC_MATCHED))
break;
if(i == 4) return 0;
*addr = hw_watchpoint[i].addr;
return 1;
}

190
src/crc32.c Normal file
View File

@ -0,0 +1,190 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2011 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "general.h"
#include "target.h"
#include "gdb_if.h"
#if !defined(STM32F0) && !defined(STM32F1) && !defined(STM32F2) && \
!defined(STM32F3) && !defined(STM32F4) && !defined(STM32F7) && \
!defined(STM32L0) && !defined(STM32L1) && !defined(STM32F4) && \
!defined(STM32G0) && !defined(STM32G4)
static const uint32_t crc32_table[] = {
0x00000000, 0x04C11DB7, 0x09823B6E, 0x0D4326D9,
0x130476DC, 0x17C56B6B, 0x1A864DB2, 0x1E475005,
0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6, 0x2B4BCB61,
0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD,
0x4C11DB70, 0x48D0C6C7, 0x4593E01E, 0x4152FDA9,
0x5F15ADAC, 0x5BD4B01B, 0x569796C2, 0x52568B75,
0x6A1936C8, 0x6ED82B7F, 0x639B0DA6, 0x675A1011,
0x791D4014, 0x7DDC5DA3, 0x709F7B7A, 0x745E66CD,
0x9823B6E0, 0x9CE2AB57, 0x91A18D8E, 0x95609039,
0x8B27C03C, 0x8FE6DD8B, 0x82A5FB52, 0x8664E6E5,
0xBE2B5B58, 0xBAEA46EF, 0xB7A96036, 0xB3687D81,
0xAD2F2D84, 0xA9EE3033, 0xA4AD16EA, 0xA06C0B5D,
0xD4326D90, 0xD0F37027, 0xDDB056FE, 0xD9714B49,
0xC7361B4C, 0xC3F706FB, 0xCEB42022, 0xCA753D95,
0xF23A8028, 0xF6FB9D9F, 0xFBB8BB46, 0xFF79A6F1,
0xE13EF6F4, 0xE5FFEB43, 0xE8BCCD9A, 0xEC7DD02D,
0x34867077, 0x30476DC0, 0x3D044B19, 0x39C556AE,
0x278206AB, 0x23431B1C, 0x2E003DC5, 0x2AC12072,
0x128E9DCF, 0x164F8078, 0x1B0CA6A1, 0x1FCDBB16,
0x018AEB13, 0x054BF6A4, 0x0808D07D, 0x0CC9CDCA,
0x7897AB07, 0x7C56B6B0, 0x71159069, 0x75D48DDE,
0x6B93DDDB, 0x6F52C06C, 0x6211E6B5, 0x66D0FB02,
0x5E9F46BF, 0x5A5E5B08, 0x571D7DD1, 0x53DC6066,
0x4D9B3063, 0x495A2DD4, 0x44190B0D, 0x40D816BA,
0xACA5C697, 0xA864DB20, 0xA527FDF9, 0xA1E6E04E,
0xBFA1B04B, 0xBB60ADFC, 0xB6238B25, 0xB2E29692,
0x8AAD2B2F, 0x8E6C3698, 0x832F1041, 0x87EE0DF6,
0x99A95DF3, 0x9D684044, 0x902B669D, 0x94EA7B2A,
0xE0B41DE7, 0xE4750050, 0xE9362689, 0xEDF73B3E,
0xF3B06B3B, 0xF771768C, 0xFA325055, 0xFEF34DE2,
0xC6BCF05F, 0xC27DEDE8, 0xCF3ECB31, 0xCBFFD686,
0xD5B88683, 0xD1799B34, 0xDC3ABDED, 0xD8FBA05A,
0x690CE0EE, 0x6DCDFD59, 0x608EDB80, 0x644FC637,
0x7A089632, 0x7EC98B85, 0x738AAD5C, 0x774BB0EB,
0x4F040D56, 0x4BC510E1, 0x46863638, 0x42472B8F,
0x5C007B8A, 0x58C1663D, 0x558240E4, 0x51435D53,
0x251D3B9E, 0x21DC2629, 0x2C9F00F0, 0x285E1D47,
0x36194D42, 0x32D850F5, 0x3F9B762C, 0x3B5A6B9B,
0x0315D626, 0x07D4CB91, 0x0A97ED48, 0x0E56F0FF,
0x1011A0FA, 0x14D0BD4D, 0x19939B94, 0x1D528623,
0xF12F560E, 0xF5EE4BB9, 0xF8AD6D60, 0xFC6C70D7,
0xE22B20D2, 0xE6EA3D65, 0xEBA91BBC, 0xEF68060B,
0xD727BBB6, 0xD3E6A601, 0xDEA580D8, 0xDA649D6F,
0xC423CD6A, 0xC0E2D0DD, 0xCDA1F604, 0xC960EBB3,
0xBD3E8D7E, 0xB9FF90C9, 0xB4BCB610, 0xB07DABA7,
0xAE3AFBA2, 0xAAFBE615, 0xA7B8C0CC, 0xA379DD7B,
0x9B3660C6, 0x9FF77D71, 0x92B45BA8, 0x9675461F,
0x8832161A, 0x8CF30BAD, 0x81B02D74, 0x857130C3,
0x5D8A9099, 0x594B8D2E, 0x5408ABF7, 0x50C9B640,
0x4E8EE645, 0x4A4FFBF2, 0x470CDD2B, 0x43CDC09C,
0x7B827D21, 0x7F436096, 0x7200464F, 0x76C15BF8,
0x68860BFD, 0x6C47164A, 0x61043093, 0x65C52D24,
0x119B4BE9, 0x155A565E, 0x18197087, 0x1CD86D30,
0x029F3D35, 0x065E2082, 0x0B1D065B, 0x0FDC1BEC,
0x3793A651, 0x3352BBE6, 0x3E119D3F, 0x3AD08088,
0x2497D08D, 0x2056CD3A, 0x2D15EBE3, 0x29D4F654,
0xC5A92679, 0xC1683BCE, 0xCC2B1D17, 0xC8EA00A0,
0xD6AD50A5, 0xD26C4D12, 0xDF2F6BCB, 0xDBEE767C,
0xE3A1CBC1, 0xE760D676, 0xEA23F0AF, 0xEEE2ED18,
0xF0A5BD1D, 0xF464A0AA, 0xF9278673, 0xFDE69BC4,
0x89B8FD09, 0x8D79E0BE, 0x803AC667, 0x84FBDBD0,
0x9ABC8BD5, 0x9E7D9662, 0x933EB0BB, 0x97FFAD0C,
0xAFB010B1, 0xAB710D06, 0xA6322BDF, 0xA2F33668,
0xBCB4666D, 0xB8757BDA, 0xB5365D03, 0xB1F740B4,
};
static uint32_t crc32_calc(uint32_t crc, uint8_t data)
{
return (crc << 8) ^ crc32_table[((crc >> 24) ^ data) & 255];
}
int generic_crc32(target *t, uint32_t *crc_res, uint32_t base, size_t len)
{
uint32_t crc = -1;
#if PC_HOSTED == 1
/* Reading a 2 MByte on a H743 takes about 80 s@128, 28s @ 1k,
* 22 s @ 4k and 21 s @ 64k
*/
uint8_t bytes[0x1000];
#else
uint8_t bytes[128];
#endif
#if defined(ENABLE_DEBUG)
uint32_t start_time = platform_time_ms();
#endif
uint32_t last_time = platform_time_ms();
while (len) {
uint32_t actual_time = platform_time_ms();
if ( actual_time > last_time + 1000) {
last_time = actual_time;
gdb_if_putchar(0, true);
}
size_t read_len = MIN(sizeof(bytes), len);
if (target_mem_read(t, bytes, base, read_len)) {
DEBUG_WARN("generic_crc32 error around address 0x%08" PRIx32 "\n",
base);
return -1;
}
for (unsigned i = 0; i < read_len; i++)
crc = crc32_calc(crc, bytes[i]);
base += read_len;
len -= read_len;
}
DEBUG_WARN("%" PRIu32 " ms\n", platform_time_ms() - start_time);
*crc_res = crc;
return 0;
}
#else
#include <libopencm3/stm32/crc.h>
int generic_crc32(target *t, uint32_t *crc_res, uint32_t base, size_t len)
{
uint8_t bytes[128];
uint32_t crc;
CRC_CR |= CRC_CR_RESET;
uint32_t last_time = platform_time_ms();
while (len > 3) {
uint32_t actual_time = platform_time_ms();
if ( actual_time > last_time + 1000) {
last_time = actual_time;
gdb_if_putchar(0, true);
}
size_t read_len = MIN(sizeof(bytes), len) & ~3;
if (target_mem_read(t, bytes, base, read_len)) {
DEBUG_WARN("generic_crc32 error around address 0x%08" PRIx32 "\n",
base);
return -1;
}
for (unsigned i = 0; i < read_len; i += 4)
CRC_DR = __builtin_bswap32(*(uint32_t*)(bytes+i));
base += read_len;
len -= read_len;
}
crc = CRC_DR;
if (target_mem_read(t, bytes, base, len)) {
DEBUG_WARN("generic_crc32 error around address 0x%08" PRIx32 "\n",
base);
return -1;
}
uint8_t *data = bytes;
while (len--) {
crc ^= *data++ << 24;
for (int i = 0; i < 8; i++) {
if (crc & 0x80000000)
crc = (crc << 1) ^ 0x4C11DB7;
else
crc <<= 1;
}
}
*crc_res = crc;
return 0;
}
#endif

View File

@ -1,7 +1,7 @@
/* /*
* This file is part of the Black Magic Debug project. * This file is part of the Black Magic Debug project.
* *
* Copyright (C) 2011 Black Sphere Technologies Ltd. * Copyright (C) 2015 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz> * Written by Gareth McMullin <gareth@blacksphere.co.nz>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -18,22 +18,23 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __SWDPTAP_H
#define __SWDPTAP_H
#include "general.h" #include "general.h"
#include "exception.h"
int swdptap_init(void); struct exception *innermost_exception;
void swdptap_reset(void);
void swdptap_turnaround(uint8_t dir); void raise_exception(uint32_t type, const char *msg)
uint8_t swdptap_bit_in(void); {
void swdptap_bit_out(uint8_t val); struct exception *e;
for (e = innermost_exception; e; e = e->outer) {
uint32_t swdptap_seq_in(int ticks); if (e->mask & type) {
uint8_t swdptap_seq_in_parity(uint32_t *data, int ticks); e->type = type;
void swdptap_seq_out(uint32_t MS, int ticks); e->msg = msg;
void swdptap_seq_out_parity(uint32_t MS, int ticks); innermost_exception = e->outer;
longjmp(e->jmpbuf, type);
#endif }
}
DEBUG_WARN("Unhandled exception: %s\n", msg);
abort();
}

132
src/gdb_hostio.c Normal file
View File

@ -0,0 +1,132 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2016 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "general.h"
#include "target.h"
#include "gdb_main.h"
#include "gdb_hostio.h"
#include "gdb_packet.h"
int gdb_main_loop(struct target_controller *, bool in_syscall);
int hostio_reply(struct target_controller *tc, char *pbuf, int len)
{
(void)len;
int retcode, items, errno_;
char c, *p;
if (pbuf[1] == '-')
p = &pbuf[2];
else
p = &pbuf[1];
items = sscanf(p, "%x,%x,%c", &retcode, &errno_, &c);
if (pbuf[1] == '-')
retcode = -retcode;
/* if break is requested */
tc->interrupted = items == 3 && c == 'C';
tc->errno_ = errno_;
return retcode;
}
/* Interface to host system calls */
int hostio_open(struct target_controller *tc,
target_addr path, size_t path_len,
enum target_open_flags flags, mode_t mode)
{
gdb_putpacket_f("Fopen,%08X/%X,%08X,%08X", path, path_len, flags, mode);;;;
return gdb_main_loop(tc, true);
}
int hostio_close(struct target_controller *tc, int fd)
{
gdb_putpacket_f("Fclose,%08X", fd);
return gdb_main_loop(tc, true);
}
int hostio_read(struct target_controller *tc,
int fd, target_addr buf, unsigned int count)
{
gdb_putpacket_f("Fread,%08X,%08X,%08X", fd, buf, count);
return gdb_main_loop(tc, true);
}
int hostio_write(struct target_controller *tc,
int fd, target_addr buf, unsigned int count)
{
gdb_putpacket_f("Fwrite,%08X,%08X,%08X", fd, buf, count);
return gdb_main_loop(tc, true);
}
long hostio_lseek(struct target_controller *tc,
int fd, long offset, enum target_seek_flag flag)
{
gdb_putpacket_f("Flseek,%08X,%08X,%08X", fd, offset, flag);
return gdb_main_loop(tc, true);
}
int hostio_rename(struct target_controller *tc,
target_addr oldpath, size_t old_len,
target_addr newpath, size_t new_len)
{
gdb_putpacket_f("Frename,%08X/%X,%08X/%X",
oldpath, old_len, newpath, new_len);
return gdb_main_loop(tc, true);
}
int hostio_unlink(struct target_controller *tc,
target_addr path, size_t path_len)
{
gdb_putpacket_f("Funlink,%08X/%X", path, path_len);
return gdb_main_loop(tc, true);
}
int hostio_stat(struct target_controller *tc,
target_addr path, size_t path_len, target_addr buf)
{
gdb_putpacket_f("Fstat,%08X/%X,%08X", path, path_len, buf);
return gdb_main_loop(tc, true);
}
int hostio_fstat(struct target_controller *tc, int fd, target_addr buf)
{
gdb_putpacket_f("Ffstat,%X,%08X", fd, buf);
return gdb_main_loop(tc, true);
}
int hostio_gettimeofday(struct target_controller *tc,
target_addr tv, target_addr tz)
{
gdb_putpacket_f("Fgettimeofday,%08X,%08X", tv, tz);
return gdb_main_loop(tc, true);
}
int hostio_isatty(struct target_controller *tc, int fd)
{
gdb_putpacket_f("Fisatty,%08X", fd);
return gdb_main_loop(tc, true);
}
int hostio_system(struct target_controller *tc,
target_addr cmd, size_t cmd_len)
{
gdb_putpacket_f("Fsystem,%08X/%X", cmd, cmd_len);
return gdb_main_loop(tc, true);
}

53
src/gdb_hostio.h Normal file
View File

@ -0,0 +1,53 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2016 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GDB_SYSCALLS_H
#define __GDB_SYSCALLS_H
#include "target.h"
int hostio_reply(struct target_controller *tc, char *packet, int len);
/* Interface to host system calls */
int hostio_open(struct target_controller *,
target_addr path, size_t path_len,
enum target_open_flags flags, mode_t mode);
int hostio_close(struct target_controller *, int fd);
int hostio_read(struct target_controller *,
int fd, target_addr buf, unsigned int count);
int hostio_write(struct target_controller *,
int fd, target_addr buf, unsigned int count);
long hostio_lseek(struct target_controller *,
int fd, long offset, enum target_seek_flag flag);
int hostio_rename(struct target_controller *,
target_addr oldpath, size_t old_len,
target_addr newpath, size_t new_len);
int hostio_unlink(struct target_controller *,
target_addr path, size_t path_len);
int hostio_stat(struct target_controller *,
target_addr path, size_t path_len, target_addr buf);
int hostio_fstat(struct target_controller *, int fd, target_addr buf);
int hostio_gettimeofday(struct target_controller *,
target_addr tv, target_addr tz);
int hostio_isatty(struct target_controller *, int fd);
int hostio_system(struct target_controller *,
target_addr cmd, size_t cmd_len);
#endif

View File

@ -19,417 +19,673 @@
*/ */
/* This file implements the GDB Remote Serial Debugging protocol as /* This file implements the GDB Remote Serial Debugging protocol as
* described in "Debugging with GDB" build from GDB source. * described in "Debugging with GDB" build from GDB source.
* *
* Originally written for GDB 6.8, updated and tested with GDB 7.2. * Originally written for GDB 6.8, updated and tested with GDB 7.2.
*/ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "platform.h"
#include "general.h" #include "general.h"
#include "ctype.h"
#include "hex_utils.h" #include "hex_utils.h"
#include "gdb_if.h" #include "gdb_if.h"
#include "gdb_packet.h" #include "gdb_packet.h"
#include "gdb_main.h" #include "gdb_main.h"
#include "gdb_hostio.h"
#include "jtagtap.h"
#include "jtag_scan.h"
#include "adiv5.h"
#include "target.h" #include "target.h"
#include "command.h" #include "command.h"
#include "crc32.h"
#include "morse.h"
#ifdef ENABLE_RTT
#include "rtt.h"
#endif
#define BUF_SIZE 1024 enum gdb_signal {
GDB_SIGINT = 2,
GDB_SIGTRAP = 5,
GDB_SIGSEGV = 11,
GDB_SIGLOST = 29,
};
#define BUF_SIZE 1024U
#define ERROR_IF_NO_TARGET() \ #define ERROR_IF_NO_TARGET() \
if(!cur_target) { gdb_putpacketz("EFF"); break; } if(!cur_target) { gdb_putpacketz("EFF"); break; }
static unsigned char pbuf[BUF_SIZE]; typedef struct
static void handle_q_packet(char *packet, int len);
static void handle_v_packet(char *packet, int len);
void
gdb_main(void)
{ {
int size; const char *cmd_prefix;
static uint8_t single_step = 0; void (*func)(const char *packet, size_t len);
} cmd_executer;
static char pbuf[BUF_SIZE + 1U];
static target *cur_target;
static target *last_target;
static bool gdb_needs_detach_notify = false;
static void handle_q_packet(char *packet, size_t len);
static void handle_v_packet(char *packet, size_t len);
static void handle_z_packet(char *packet, size_t len);
static void handle_kill_target(void);
static void gdb_target_destroy_callback(struct target_controller *tc, target *t)
{
(void)tc;
if (cur_target == t) {
gdb_put_notificationz("%Stop:W00");
gdb_out("You are now detached from the previous target.\n");
cur_target = NULL;
gdb_needs_detach_notify = true;
}
if (last_target == t)
last_target = NULL;
}
static void gdb_target_printf(struct target_controller *tc,
const char *fmt, va_list ap)
{
(void)tc;
gdb_voutf(fmt, ap);
}
static struct target_controller gdb_controller = {
.destroy_callback = gdb_target_destroy_callback,
.printf = gdb_target_printf,
.open = hostio_open,
.close = hostio_close,
.read = hostio_read,
.write = hostio_write,
.lseek = hostio_lseek,
.rename = hostio_rename,
.unlink = hostio_unlink,
.stat = hostio_stat,
.fstat = hostio_fstat,
.gettimeofday = hostio_gettimeofday,
.isatty = hostio_isatty,
.system = hostio_system,
};
int gdb_main_loop(struct target_controller *tc, bool in_syscall)
{
bool single_step = false;
DEBUG("Entring GDB protocol main loop\n");
/* GDB protocol main loop */ /* GDB protocol main loop */
while(1) { while (1) {
SET_IDLE_STATE(1); SET_IDLE_STATE(1);
size = gdb_getpacket(pbuf, BUF_SIZE); size_t size = gdb_getpacket(pbuf, BUF_SIZE);
SET_IDLE_STATE(0); SET_IDLE_STATE(0);
DEBUG("%s\n", pbuf); switch (pbuf[0]) {
switch(pbuf[0]) { /* Implementation of these is mandatory! */
/* Implementation of these is mandatory! */ case 'g': { /* 'g': Read general registers */
case 'g': { /* 'g': Read general registers */
uint32_t arm_regs[cur_target->regs_size];
ERROR_IF_NO_TARGET(); ERROR_IF_NO_TARGET();
target_regs_read(cur_target, (void*)arm_regs); uint8_t gp_regs[target_regs_size(cur_target)];
gdb_putpacket(hexify(pbuf, (void*)arm_regs, cur_target->regs_size), cur_target->regs_size * 2); target_regs_read(cur_target, gp_regs);
gdb_putpacket(hexify(pbuf, gp_regs, sizeof(gp_regs)), sizeof(gp_regs) * 2U);
break; break;
} }
case 'm': { /* 'm addr,len': Read len bytes from addr */ case 'm': { /* 'm addr,len': Read len bytes from addr */
unsigned long addr, len; uint32_t addr, len;
char *mem;
ERROR_IF_NO_TARGET(); ERROR_IF_NO_TARGET();
sscanf(pbuf, "m%08lX,%08lX", &addr, &len); sscanf(pbuf, "m%" SCNx32 ",%" SCNx32, &addr, &len);
DEBUG("m packet: addr = %08lX, len = %08lX\n", addr, len); if (len > sizeof(pbuf) / 2) {
mem = malloc(len); gdb_putpacketz("E02");
if(!mem) break; break;
if(((addr & 3) == 0) && ((len & 3) == 0)) }
target_mem_read_words(cur_target, (void*)mem, addr, len); DEBUG_GDB("m packet: addr = %" PRIx32 ", len = %" PRIx32 "\n",
addr, len);
uint8_t mem[len];
if (target_mem_read(cur_target, mem, addr, len))
gdb_putpacketz("E01");
else else
target_mem_read_bytes(cur_target, (void*)mem, addr, len); gdb_putpacket(hexify(pbuf, mem, len), len * 2U);
if(target_check_error(cur_target))
gdb_putpacket("E01", 3);
else
gdb_putpacket(hexify(pbuf, mem, len), len*2);
free(mem);
break; break;
} }
case 'G': { /* 'G XX': Write general registers */ case 'G': { /* 'G XX': Write general registers */
uint32_t arm_regs[cur_target->regs_size];
ERROR_IF_NO_TARGET(); ERROR_IF_NO_TARGET();
unhexify((void*)arm_regs, &pbuf[1], cur_target->regs_size); uint8_t gp_regs[target_regs_size(cur_target)];
target_regs_write(cur_target, arm_regs); unhexify(gp_regs, &pbuf[1], sizeof(gp_regs));
gdb_putpacket("OK", 2); target_regs_write(cur_target, gp_regs);
gdb_putpacketz("OK");
break; break;
} }
case 'M': { /* 'M addr,len:XX': Write len bytes to addr */ case 'M': { /* 'M addr,len:XX': Write len bytes to addr */
unsigned long addr, len; uint32_t addr = 0;
uint32_t len = 0;
int hex; int hex;
char *mem;
ERROR_IF_NO_TARGET(); ERROR_IF_NO_TARGET();
sscanf(pbuf, "M%08lX,%08lX:%n", &addr, &len, &hex); sscanf(pbuf, "M%" SCNx32 ",%" SCNx32 ":%n", &addr, &len, &hex);
DEBUG("M packet: addr = %08lX, len = %08lX\n", addr, len); if (len > (unsigned)(size - hex) / 2) {
mem = malloc(len); gdb_putpacketz("E02");
break;
}
DEBUG_GDB("M packet: addr = %" PRIx32 ", len = %" PRIx32 "\n",
addr, len);
uint8_t mem[len];
unhexify(mem, pbuf + hex, len); unhexify(mem, pbuf + hex, len);
if(((addr & 3) == 0) && ((len & 3) == 0)) if (target_mem_write(cur_target, addr, mem, len))
target_mem_write_words(cur_target, addr, (void*)mem, len); gdb_putpacketz("E01");
else
target_mem_write_bytes(cur_target, addr, (void*)mem, len);
if(target_check_error(cur_target))
gdb_putpacket("E01", 3);
else else
gdb_putpacket("OK", 2); gdb_putpacketz("OK");
free(mem);
break; break;
} }
case 's': /* 's [addr]': Single step [start at addr] */ /* '[m|M|g|G|c][thread-id]' : Set the thread ID for the given subsequent operation
single_step = 1; * (we don't actually care which as we only care about the TID for whether to send OK or an error)
// Fall through to resume target */
case 'c': /* 'c [addr]': Continue [at addr] */ case 'H': {
if(!cur_target) { char operation = 0;
uint32_t thread_id = 0;
sscanf(pbuf, "H%c%" SCNx32, &operation, &thread_id);
if (thread_id <= 1)
gdb_putpacketz("OK");
else
gdb_putpacketz("E01");
break;
}
case 's': /* 's [addr]': Single step [start at addr] */
single_step = true;
/* fall through */
case 'c': /* 'c [addr]': Continue [at addr] */
if (!cur_target) {
gdb_putpacketz("X1D"); gdb_putpacketz("X1D");
break; break;
} }
target_halt_resume(cur_target, single_step); target_halt_resume(cur_target, single_step);
SET_RUN_STATE(1); SET_RUN_STATE(1);
single_step = 0; single_step = false;
// Fall through to wait for target halt /* fall through */
case '?': { /* '?': Request reason for target halt */ case '?': { /* '?': Request reason for target halt */
/* This packet isn't documented as being mandatory, /* This packet isn't documented as being mandatory,
* but GDB doesn't work without it. */ * but GDB doesn't work without it. */
int sent_int = 0; target_addr watch;
uint32_t watch_addr; enum target_halt_reason reason;
if(!cur_target) { if (!cur_target) {
/* Report "target exited" if no target */ /* Report "target exited" if no target */
gdb_putpacketz("W00"); gdb_putpacketz("W00");
break; break;
} }
/* Wait for target halt */ /* Wait for target halt */
while(!target_halt_wait(cur_target)) { while(!(reason = target_halt_poll(cur_target, &watch))) {
unsigned char c = gdb_if_getchar_to(0); char c = (char)gdb_if_getchar_to(0);
if((c == '\x03') || (c == '\x04')) { if(c == '\x03' || c == '\x04') {
target_halt_request(cur_target); target_halt_request(cur_target);
sent_int = 1;
} }
#ifdef ENABLE_RTT
if (rtt_enabled) poll_rtt(cur_target);
#endif
} }
SET_RUN_STATE(0); SET_RUN_STATE(0);
/* Report reason for halt */
if(target_check_hw_wp(cur_target, &watch_addr)) { /* Translate reason to GDB signal */
/* Watchpoint hit */ switch (reason) {
gdb_putpacket_f("T05watch:%08X;", watch_addr); case TARGET_HALT_ERROR:
} else if(target_fault_unwind(cur_target)) { gdb_putpacket_f("X%02X", GDB_SIGLOST);
gdb_putpacketz("T0b"); morse("TARGET LOST.", true);
} else if(sent_int) { break;
/* Target interrupted */ case TARGET_HALT_REQUEST:
gdb_putpacketz("T02"); gdb_putpacket_f("T%02X", GDB_SIGINT);
} else { break;
gdb_putpacketz("T05"); case TARGET_HALT_WATCHPOINT:
gdb_putpacket_f("T%02Xwatch:%08X;", GDB_SIGTRAP, watch);
break;
case TARGET_HALT_FAULT:
gdb_putpacket_f("T%02X", GDB_SIGSEGV);
break;
default:
gdb_putpacket_f("T%02X", GDB_SIGTRAP);
} }
break; break;
} }
/* Optional GDB packet support */ /* Optional GDB packet support */
case '!': /* Enable Extended GDB Protocol. */ case 'p': { /* Read single register */
/* This doesn't do anything, we support the extended ERROR_IF_NO_TARGET();
* protocol anyway, but GDB will never send us a 'R' uint32_t reg;
* packet unless we answer 'OK' here. sscanf(pbuf, "p%" SCNx32, &reg);
*/ uint8_t val[8];
gdb_putpacket("OK", 2); size_t s = target_reg_read(cur_target, reg, val, sizeof(val));
if (s > 0)
gdb_putpacket(hexify(pbuf, val, s), s * 2);
else
gdb_putpacketz("EFF");
break;
}
case 'P': { /* Write single register */
ERROR_IF_NO_TARGET();
uint32_t reg;
int n;
sscanf(pbuf, "P%" SCNx32 "=%n", &reg, &n);
// TODO: FIXME, VLAs considered harmful.
uint8_t val[strlen(&pbuf[n]) / 2];
unhexify(val, pbuf + n, sizeof(val));
if (target_reg_write(cur_target, reg, val, sizeof(val)) > 0)
gdb_putpacketz("OK");
else
gdb_putpacketz("EFF");
break;
}
case 'F': /* Semihosting call finished */
if (in_syscall)
return hostio_reply(tc, pbuf, size);
else {
DEBUG_GDB("*** F packet when not in syscall! '%s'\n", pbuf);
gdb_putpacketz("");
}
break; break;
case 0x04: case '!': /* Enable Extended GDB Protocol. */
case 'D': /* GDB 'detach' command. */ /* This doesn't do anything, we support the extended
if(cur_target) * protocol anyway, but GDB will never send us a 'R'
* packet unless we answer 'OK' here.
*/
gdb_putpacketz("OK");
break;
case 0x04:
case 'D': /* GDB 'detach' command. */
if(cur_target) {
SET_RUN_STATE(1);
target_detach(cur_target); target_detach(cur_target);
}
last_target = cur_target; last_target = cur_target;
cur_target = NULL; cur_target = NULL;
gdb_putpacket("OK", 2); gdb_putpacketz("OK");
break; break;
case 'k': /* Kill the target */ case 'k': /* Kill the target */
if(cur_target) { handle_kill_target();
target_reset(cur_target);
target_detach(cur_target);
last_target = cur_target;
cur_target = NULL;
}
break; break;
case 'r': /* Reset the target system */ case 'r': /* Reset the target system */
case 'R': /* Restart the target program */ case 'R': /* Restart the target program */
if(cur_target) if(cur_target)
target_reset(cur_target); target_reset(cur_target);
else if(last_target) { else if(last_target) {
cur_target = last_target; cur_target = target_attach(last_target,
target_attach(cur_target); &gdb_controller);
if(cur_target)
morse(NULL, false);
target_reset(cur_target); target_reset(cur_target);
} }
break; break;
case 'X': { /* 'X addr,len:XX': Write binary data to addr */ case 'X': { /* 'X addr,len:XX': Write binary data to addr */
unsigned long addr, len; uint32_t addr, len;
int bin; int bin;
ERROR_IF_NO_TARGET(); ERROR_IF_NO_TARGET();
sscanf(pbuf, "X%08lX,%08lX:%n", &addr, &len, &bin); sscanf(pbuf, "X%" SCNx32 ",%" SCNx32 ":%n", &addr, &len, &bin);
DEBUG("X packet: addr = %08lX, len = %08lX\n", addr, len); if (len > (unsigned)(size - bin)) {
if(((addr & 3) == 0) && ((len & 3) == 0)) gdb_putpacketz("E02");
target_mem_write_words(cur_target, addr, (void*)pbuf+bin, len); break;
else }
target_mem_write_bytes(cur_target, addr, (void*)pbuf+bin, len); DEBUG_GDB("X packet: addr = %" PRIx32 ", len = %" PRIx32 "\n",
if(target_check_error(cur_target)) addr, len);
gdb_putpacket("E01", 3); if (target_mem_write(cur_target, addr, pbuf + bin, len))
gdb_putpacketz("E01");
else else
gdb_putpacket("OK", 2); gdb_putpacketz("OK");
break; break;
} }
case 'q': /* General query packet */ case 'q': /* General query packet */
handle_q_packet(pbuf, size); handle_q_packet(pbuf, size);
break; break;
case 'v': /* General query packet */ case 'v': /* Verbose command packet */
handle_v_packet(pbuf, size); handle_v_packet(pbuf, size);
break; break;
/* These packet implement hardware break-/watchpoints */ /* These packet implement hardware break-/watchpoints */
case 'Z': /* Z type,addr,len: Set breakpoint packet */ case 'Z': /* Z type,addr,len: Set breakpoint packet */
case 'z': { /* z type,addr,len: Clear breakpoint packet */ case 'z': /* z type,addr,len: Clear breakpoint packet */
uint8_t set = (pbuf[0]=='Z')?1:0;
int type, len;
unsigned long addr;
int ret;
ERROR_IF_NO_TARGET(); ERROR_IF_NO_TARGET();
/* I have no idea why this doesn't work. Seems to work handle_z_packet(pbuf, size);
* with real sscanf() though... */
//sscanf(pbuf, "%*[zZ]%hhd,%08lX,%hhd", &type, &addr, &len);
type = pbuf[1] - '0';
sscanf(pbuf + 2, ",%08lX,%d", &addr, &len);
switch(type) {
case 1: /* Hardware breakpoint */
if(!cur_target->set_hw_bp) { /* Not supported */
gdb_putpacket("", 0);
break;
}
if(set) ret = target_set_hw_bp(cur_target, addr);
else ret = target_clear_hw_bp(cur_target, addr);
if(!ret) gdb_putpacket("OK", 2);
else gdb_putpacket("E01", 3);
break;
case 2:
case 3:
case 4:
if(!cur_target->set_hw_wp) { /* Not supported */
gdb_putpacket("", 0);
break;
}
if(set) ret = target_set_hw_wp(cur_target, type, addr, len);
else ret = target_clear_hw_wp(cur_target, type, addr, len);
if(!ret) gdb_putpacket("OK", 2);
else gdb_putpacket("E01", 3);
break;
default:
gdb_putpacket("", 0);
}
break; break;
}
default: /* Packet not implemented */ default: /* Packet not implemented */
DEBUG("Unsupported packet: %s\n", pbuf); DEBUG_GDB("*** Unsupported packet: %s\n", pbuf);
gdb_putpacket("", 0); gdb_putpacketz("");
} }
} }
} }
static void static bool exec_command(char *packet, const size_t length, const cmd_executer *exec)
handle_q_string_reply(const char *str, const char *param)
{ {
unsigned long addr, len; while (exec->cmd_prefix) {
const size_t prefix_length = strlen(exec->cmd_prefix);
if (sscanf(param, "%08lX,%08lX", &addr, &len) != 2) { if (!strncmp(packet, exec->cmd_prefix, prefix_length)) {
exec->func(packet + prefix_length, length - prefix_length);
return true;
}
++exec;
}
return false;
}
static void exec_q_rcmd(const char *packet, const size_t length)
{
/* calculate size and allocate buffer for command */
const size_t datalen = length / 2U;
char *data = alloca(datalen + 1);
/* dehexify command */
unhexify(data, packet, datalen);
data[datalen] = 0; /* add terminating null */
const int c = command_process(cur_target, data);
if (c < 0)
gdb_putpacketz("");
else if (c == 0)
gdb_putpacketz("OK");
else
gdb_putpacket(hexify(pbuf, "Failed\n", strlen("Failed\n")),
2 * strlen("Failed\n"));
}
static void handle_q_string_reply(const char *reply, const char *param)
{
const size_t reply_length = strlen(reply);
uint32_t addr = 0;
uint32_t len = 0;
if (sscanf(param, "%08" PRIx32 ",%08" PRIx32, &addr, &len) != 2) {
gdb_putpacketz("E01"); gdb_putpacketz("E01");
return; return;
} }
if (addr < strlen (str)) { if (addr > reply_length) {
uint8_t reply[len+2];
reply[0] = 'm';
strncpy (reply + 1, &str[addr], len);
if(len > strlen(&str[addr]))
len = strlen(&str[addr]);
gdb_putpacket(reply, len + 1);
} else if (addr == strlen (str)) {
gdb_putpacketz("l");
} else
gdb_putpacketz("E01"); gdb_putpacketz("E01");
return;
}
if (addr == reply_length) {
gdb_putpacketz("l");
return;
}
size_t output_len = reply_length - addr;
if (output_len > len)
output_len = len;
gdb_putpacket2("m", 1U, reply + addr, output_len);
} }
static void static void exec_q_supported(const char *packet, const size_t length)
handle_q_packet(char *packet, int len)
{ {
/* These 'monitor' commands only available on the real deal */ (void)packet;
if(!strncmp(packet, "qRcmd,", 6)) { (void)length;
unsigned char *data; gdb_putpacket_f("PacketSize=%X;qXfer:memory-map:read+;qXfer:features:read+", BUF_SIZE);
int datalen; }
/* calculate size and allocate buffer for command */ static void exec_q_memory_map(const char *packet, const size_t length)
datalen = (len - 6) / 2; {
data = alloca(datalen+1); (void)packet;
/* dehexify command */ (void)length;
unhexify(data, packet+6, datalen); /* Read target XML memory map */
data[datalen] = 0; /* add terminating null */ if ((!cur_target) && last_target) {
/* Attach to last target if detached. */
cur_target = target_attach(last_target,
&gdb_controller);
}
if (!cur_target) {
gdb_putpacketz("E01");
return;
}
char buf[1024];
target_mem_map(cur_target, buf, sizeof(buf)); /* Fixme: Check size!*/
handle_q_string_reply(buf, packet);
}
if(command_process(data) < 0) static void exec_q_feature_read(const char *packet, const size_t length)
gdb_putpacket("", 0); {
else gdb_putpacket("OK", 2); (void)length;
/* Read target description */
if ((!cur_target) && last_target) {
/* Attach to last target if detached. */
cur_target = target_attach(last_target, &gdb_controller);
}
if (!cur_target) {
gdb_putpacketz("E01");
return;
}
handle_q_string_reply(target_tdesc(cur_target), packet);
}
} else if (!strncmp (packet, "qSupported", 10)) { static void exec_q_crc(const char *packet, const size_t length)
/* Query supported protocol features */ {
gdb_putpacket_f("PacketSize=%X;qXfer:memory-map:read+;qXfer:features:read+", BUF_SIZE); (void)length;
uint32_t addr;
} else if (strncmp (packet, "qXfer:memory-map:read::", 23) == 0) { uint32_t addr_length;
/* Read target XML memory map */ if (sscanf(packet, "%" PRIx32 ",%" PRIx32, &addr, &addr_length) == 2) {
if((!cur_target) && last_target) { if (!cur_target) {
/* Attach to last target if detached. */
cur_target = last_target;
target_attach(cur_target);
}
if((!cur_target) || (!cur_target->xml_mem_map)) {
gdb_putpacketz("E01"); gdb_putpacketz("E01");
return; return;
} }
handle_q_string_reply(cur_target->xml_mem_map, packet + 23); uint32_t crc;
if (generic_crc32(cur_target, &crc, addr, addr_length))
} else if (strncmp (packet, "qXfer:features:read:target.xml:", 31) == 0) { gdb_putpacketz("E03");
/* Read target description */ else
if((!cur_target) && last_target) { gdb_putpacket_f("C%lx", crc);
/* Attach to last target if detached. */ }
cur_target = last_target;
target_attach(cur_target);
}
if((!cur_target) || (!cur_target->tdesc)) {
gdb_putpacketz("E01");
return;
}
handle_q_string_reply(cur_target->tdesc, packet + 31);
} else gdb_putpacket("", 0);
} }
static void /*
handle_v_packet(char *packet, int plen) * qC queries are for the current thread. We don't support threads but GDB 11 and 12 require this,
* so we always answer that the current thread is thread 1.
*/
static void exec_q_c(const char *packet, const size_t length)
{ {
unsigned long addr, len; (void)packet;
(void)length;
gdb_putpacketz("QC1");
}
/*
* qfThreadInfo queries are required in GDB 11 and 12 as these GDBs require the server to support
* threading even when there's only the possiblity for one thread to exist. In this instance,
* we have to tell GDB that there is a single active thread so it doesn't think the "thread" died.
* qsThreadInfo will always follow qfThreadInfo when we reply as we have to specify 'l' at the
* end to terminate the list.. GDB doesn't like this not happening.
*/
static void exec_q_thread_info(const char *packet, const size_t length)
{
(void)length;
if (packet[-11] == 'f')
gdb_putpacketz("m1");
else
gdb_putpacketz("l");
}
static const cmd_executer q_commands[]=
{
{"qRcmd,", exec_q_rcmd},
{"qSupported", exec_q_supported},
{"qXfer:memory-map:read::", exec_q_memory_map},
{"qXfer:features:read:target.xml:",exec_q_feature_read},
{"qCRC:", exec_q_crc},
{"qC", exec_q_c},
{"qfThreadInfo", exec_q_thread_info},
{"qsThreadInfo", exec_q_thread_info},
{NULL, NULL},
};
static void handle_kill_target(void)
{
if (cur_target) {
target_reset(cur_target);
target_detach(cur_target);
last_target = cur_target;
cur_target = NULL;
}
}
static void handle_q_packet(char *packet, const size_t length)
{
if (exec_command(packet, length, q_commands))
return;
DEBUG_GDB("*** Unsupported packet: %s\n", packet);
gdb_putpacket("", 0);
}
static void handle_v_packet(char *packet, const size_t plen)
{
uint32_t addr = 0;
uint32_t len = 0;
int bin; int bin;
static uint8_t flash_mode = 0; static uint8_t flash_mode = 0;
if (sscanf(packet, "vAttach;%08lX", &addr) == 1) { if (sscanf(packet, "vAttach;%08" PRIx32, &addr) == 1) {
/* Attach to remote target processor */ /* Attach to remote target processor */
target *t; cur_target = target_attach_n(addr, &gdb_controller);
uint32_t i; if(cur_target) {
for(t = target_list, i = 1; t; t = t->next, i++) morse(NULL, false);
if(i == addr) { /*
cur_target = t; * We don't actually support threads, but GDB 11 and 12 can't work without
target_attach(t); * us saying we attached to thread 1.. see the following for the low-down of this:
gdb_putpacketz("T05"); * https://sourceware.org/bugzilla/show_bug.cgi?id=28405
break; * https://sourceware.org/bugzilla/show_bug.cgi?id=28874
} * https://sourceware.org/pipermail/gdb-patches/2021-December/184171.html
if(!cur_target) /* Failed to attach */ * https://sourceware.org/pipermail/gdb-patches/2022-April/188058.html
* https://sourceware.org/pipermail/gdb-patches/2022-July/190869.html
*/
gdb_putpacketz("T05thread:1;");
} else
gdb_putpacketz("E01"); gdb_putpacketz("E01");
} else if (!strcmp(packet, "vRun;")) { } else if (!strncmp(packet, "vKill;", 6)) {
/* Kill the target - we don't actually care about the PID that follows "vKill;" */
handle_kill_target();
gdb_putpacketz("OK");
} else if (!strncmp(packet, "vRun", 4)) {
/* Parse command line for get_cmdline semihosting call */
char cmdline[83];
char *pcmdline = cmdline;
char *tok = packet + 4;
if (*tok == ';')
++tok;
cmdline[0] = '\0';
while(*tok != '\0') {
if (strlen(cmdline) + 3 >= sizeof(cmdline))
break;
if (*tok == ';') {
*pcmdline++ = ' ';
pcmdline[0] = '\0';
tok++;
continue;
}
if (isxdigit(tok[0]) && isxdigit(tok[1])) {
unhexify(pcmdline, tok, 2);
if ((*pcmdline == ' ') || (*pcmdline == '\\')) {
pcmdline[1] = *pcmdline;
*pcmdline++ = '\\';
}
pcmdline++;
tok += 2;
pcmdline[0] = '\0';
continue;
}
break;
}
#ifdef ENABLE_RTT
/* force searching rtt control block */
rtt_found = false;
#endif
/* Run target program. For us (embedded) this means reset. */ /* Run target program. For us (embedded) this means reset. */
if(cur_target) { if (cur_target) {
target_set_cmdline(cur_target, cmdline);
target_reset(cur_target); target_reset(cur_target);
gdb_putpacketz("T05"); gdb_putpacketz("T05");
} else if(last_target) { } else if (last_target) {
cur_target = last_target; cur_target = target_attach(last_target,
target_attach(cur_target); &gdb_controller);
target_reset(cur_target);
gdb_putpacketz("T05");
} else gdb_putpacketz("E01");
} else if (sscanf(packet, "vFlashErase:%08lX,%08lX", &addr, &len) == 2) { /* If we were able to attach to the target again */
if (cur_target) {
target_set_cmdline(cur_target, cmdline);
target_reset(cur_target);
morse(NULL, false);
gdb_putpacketz("T05");
} else
gdb_putpacketz("E01");
} else
gdb_putpacketz("E01");
} else if (sscanf(packet, "vFlashErase:%08" PRIx32 ",%08" PRIx32, &addr, &len) == 2) {
/* Erase Flash Memory */ /* Erase Flash Memory */
DEBUG("Flash Erase %08lX %08lX\n", addr, len); DEBUG_GDB("Flash Erase %08" PRIX32 " %08" PRIX32 "\n", addr, len);
if(!cur_target) { gdb_putpacketz("EFF"); return; } if (!cur_target) {
gdb_putpacketz("EFF");
return;
}
if(!flash_mode) { if (!flash_mode) {
/* Reset target if first flash command! */ /* Reset target if first flash command! */
/* This saves us if we're interrupted in IRQ context */ /* This saves us if we're interrupted in IRQ context */
target_reset(cur_target); target_reset(cur_target);
flash_mode = 1; flash_mode = 1;
} }
if(target_flash_erase(cur_target, addr, len) == 0) if (target_flash_erase(cur_target, addr, len) == 0)
gdb_putpacketz("OK"); gdb_putpacketz("OK");
else else {
flash_mode = 0;
gdb_putpacketz("EFF"); gdb_putpacketz("EFF");
}
} else if (sscanf(packet, "vFlashWrite:%08lX:%n", &addr, &bin) == 1) { } else if (sscanf(packet, "vFlashWrite:%08" PRIx32 ":%n", &addr, &bin) == 1) {
/* Write Flash Memory */ /* Write Flash Memory */
len = plen - bin; const uint32_t count = plen - bin;
DEBUG("Flash Write %08lX %08lX\n", addr, len); DEBUG_GDB("Flash Write %08" PRIX32 " %08" PRIX32 "\n", addr, count);
if(cur_target && target_flash_write_words(cur_target, addr, (void*)packet + bin, len) == 0) if (cur_target && target_flash_write(cur_target, addr, (void*)packet + bin, count) == 0)
gdb_putpacketz("OK"); gdb_putpacketz("OK");
else else {
flash_mode = 0;
gdb_putpacketz("EFF"); gdb_putpacketz("EFF");
}
} else if (!strcmp(packet, "vFlashDone")) { } else if (!strcmp(packet, "vFlashDone")) {
/* Commit flash operations. */ /* Commit flash operations. */
gdb_putpacketz("OK"); gdb_putpacketz(target_flash_done(cur_target) ? "EFF" : "OK");
flash_mode = 0; flash_mode = 0;
} else } else if (!strcmp(packet, "vStopped")) {
if (gdb_needs_detach_notify) {
gdb_putpacketz("W00");
gdb_needs_detach_notify = false;
} else
gdb_putpacketz("OK");
} else {
DEBUG_GDB("*** Unsupported packet: %s\n", packet);
gdb_putpacket("", 0); gdb_putpacket("", 0);
}
} }
static void handle_z_packet(char *packet, const size_t plen)
{
(void)plen;
uint32_t type;
uint32_t len;
uint32_t addr;
sscanf(packet, "%*[zZ]%" PRIu32 ",%08" PRIx32 ",%" PRIu32, &type, &addr, &len);
int ret = 0;
if (packet[0] == 'Z')
ret = target_breakwatch_set(cur_target, type, addr, len);
else
ret = target_breakwatch_clear(cur_target, type, addr, len);
if (ret < 0)
gdb_putpacketz("E01");
else if (ret > 0)
gdb_putpacketz("");
else
gdb_putpacketz("OK");
}
void gdb_main(void)
{
gdb_main_loop(&gdb_controller, false);
}

View File

@ -22,98 +22,207 @@
* reception and transmission as well as some convenience functions. * reception and transmission as well as some convenience functions.
*/ */
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "general.h" #include "general.h"
#include "gdb_if.h" #include "gdb_if.h"
#include "gdb_packet.h" #include "gdb_packet.h"
#include "hex_utils.h" #include "hex_utils.h"
#include "remote.h"
int #include <stdarg.h>
gdb_getpacket(unsigned char *packet, int size)
size_t gdb_getpacket(char *packet, size_t size)
{ {
unsigned char c;
unsigned char csum; unsigned char csum;
char recv_csum[3]; char recv_csum[3];
int i; size_t offset = 0;
while(1) { while (1) {
/* Wait for packet start */ /* Wait for packet start */
while((packet[0] = gdb_if_getchar()) != '$') do {
if(packet[0] == 0x04) return 1; /* Spin waiting for a start of packet character - either a gdb
* start ('$') or a BMP remote packet start ('!').
*/
do {
/* Smells like bad code */
packet[0] = (char)gdb_if_getchar();
if (packet[0] == 0x04)
return 1;
} while ((packet[0] != '$') && (packet[0] != REMOTE_SOM));
#if PC_HOSTED == 0
if (packet[0] == REMOTE_SOM) {
/* This is probably a remote control packet
* - get and handle it */
offset = 0;
bool gettingRemotePacket = true;
while (gettingRemotePacket) {
/* Smells like bad code */
const char c = (char)gdb_if_getchar();
switch (c) {
case REMOTE_SOM: /* Oh dear, packet restarts */
offset = 0;
break;
i = 0; csum = 0; case REMOTE_EOM: /* Complete packet for processing */
/* Capture packet data into buffer */ packet[offset] = 0;
while((c = gdb_if_getchar()) != '#') { remotePacketProcess(offset, packet);
gettingRemotePacket = false;
break;
if(i == size) break; /* Oh shit */ case '$': /* A 'real' gdb packet, best stop squatting now */
packet[0] = '$';
gettingRemotePacket = false;
break;
if(c == '$') { /* Restart capture */ default:
i = 0; if (offset < size) {
csum = 0; packet[offset++] = c;
continue; } else {
/* Who knows what is going on...return to normality */
gettingRemotePacket = false;
}
break;
}
}
/* Reset the packet buffer start character to zero, because function
* 'remotePacketProcess()' above overwrites this buffer, and
* an arbitrary character may have been placed there. If this is a '$'
* character, this will cause this loop to be terminated, which is wrong.
*/
packet[0] = 0;
} }
if(c == '}') { /* escaped char */ #endif
} while (packet[0] != '$');
offset = 0;
csum = 0;
char c;
/* Capture packet data into buffer */
while ((c = (char)gdb_if_getchar()) != '#') {
/* If we run out of buffer space, exit early */
if (offset == size)
break;
if (c == '$') { /* Restart capture */
offset = 0;
csum = 0;
continue;
}
if (c == '}') { /* escaped char */
c = gdb_if_getchar(); c = gdb_if_getchar();
csum += c + '}'; csum += c + '}';
packet[i++] = c ^ 0x20; packet[offset++] = c ^ 0x20;
continue; continue;
} }
csum += c; csum += c;
packet[i++] = c; packet[offset++] = c;
} }
recv_csum[0] = gdb_if_getchar(); recv_csum[0] = (char)gdb_if_getchar();
recv_csum[1] = gdb_if_getchar(); recv_csum[1] = (char)gdb_if_getchar();
recv_csum[2] = 0; recv_csum[2] = 0;
/* return packet if checksum matches */ /* return packet if checksum matches */
if(csum == strtol(recv_csum, NULL, 16)) break; if (csum == strtol(recv_csum, NULL, 16))
break;
/* get here if checksum fails */ /* get here if checksum fails */
gdb_if_putchar('-', 1); /* send nack */ gdb_if_putchar('-', 1); /* send nack */
} }
gdb_if_putchar('+', 1); /* send ack */ gdb_if_putchar('+', 1); /* send ack */
packet[i] = 0; packet[offset] = 0;
return i;
#if PC_HOSTED == 1
DEBUG_GDB_WIRE("%s : ", __func__);
for (size_t j = 0; j < offset; j++) {
const char c = packet[j];
if (c >= ' ' && c < 0x7F)
DEBUG_GDB_WIRE("%c", c);
else
DEBUG_GDB_WIRE("\\x%02X", c);
}
DEBUG_GDB_WIRE("\n");
#endif
return offset;
} }
void gdb_putpacket(unsigned char *packet, int size) static void gdb_next_char(char c, unsigned char *csum)
{
#if PC_HOSTED == 1
if ((c >= 32) && (c < 127))
DEBUG_GDB_WIRE("%c", c);
else
DEBUG_GDB_WIRE("\\x%02X", c);
#endif
if ((c == '$') || (c == '#') || (c == '}') || (c == '*')) {
gdb_if_putchar('}', 0);
gdb_if_putchar(c ^ 0x20, 0);
*csum += '}' + (c ^ 0x20);
}
else {
gdb_if_putchar(c, 0);
*csum += c;
}
}
void gdb_putpacket2(const char *packet1, size_t size1, const char *packet2, size_t size2)
{ {
int i;
unsigned char csum;
unsigned char c;
char xmit_csum[3]; char xmit_csum[3];
int tries = 0; size_t tries = 0;
do { do {
csum = 0; DEBUG_GDB_WIRE("%s: ", __func__);
unsigned char csum = 0;
gdb_if_putchar('$', 0); gdb_if_putchar('$', 0);
for(i = 0; i < size; i++) {
c = packet[i]; for (size_t i = 0; i < size1; ++i)
if((c == '$') || (c == '#') || (c == '}')) { gdb_next_char(packet1[i], &csum);
gdb_if_putchar('}', 0); for (size_t i = 0; i < size2; ++i)
gdb_if_putchar(c ^ 0x20, 0); gdb_next_char(packet2[i], &csum);
csum += '}' + (c ^ 0x20);
} else {
gdb_if_putchar(c, 0);
csum += c;
}
}
gdb_if_putchar('#', 0); gdb_if_putchar('#', 0);
sprintf(xmit_csum, "%02X", csum); snprintf(xmit_csum, sizeof(xmit_csum), "%02X", csum);
gdb_if_putchar(xmit_csum[0], 0); gdb_if_putchar(xmit_csum[0], 0);
gdb_if_putchar(xmit_csum[1], 1); gdb_if_putchar(xmit_csum[1], 1);
DEBUG_GDB_WIRE("\n");
} while((gdb_if_getchar_to(2000) != '+') && (tries++ < 3)); } while (gdb_if_getchar_to(2000) != '+' && tries++ < 3);
} }
void gdb_putpacket_f(const unsigned char *fmt, ...) void gdb_putpacket(const char *packet, size_t size)
{
char xmit_csum[3];
size_t tries = 0;
do {
DEBUG_GDB_WIRE("%s: ", __func__);
unsigned char csum = 0;
gdb_if_putchar('$', 0);
for (size_t i = 0; i < size; ++i)
gdb_next_char(packet[i], &csum);
gdb_if_putchar('#', 0);
snprintf(xmit_csum, sizeof(xmit_csum), "%02X", csum);
gdb_if_putchar(xmit_csum[0], 0);
gdb_if_putchar(xmit_csum[1], 1);
DEBUG_GDB_WIRE("\n");
} while (gdb_if_getchar_to(2000) != '+' && tries++ < 3);
}
void gdb_put_notification(const char *const packet, const size_t size)
{
char xmit_csum[3];
DEBUG_GDB_WIRE("%s: ", __func__);
uint8_t csum = 0;
gdb_if_putchar('%', 0);
for (size_t i = 0; i < size; ++i)
gdb_next_char(packet[i], &csum);
gdb_if_putchar('#', 0);
snprintf(xmit_csum, sizeof(xmit_csum), "%02X", csum);
gdb_if_putchar(xmit_csum[0], 0);
gdb_if_putchar(xmit_csum[1], 1);
DEBUG_GDB_WIRE("\n");
}
void gdb_putpacket_f(const char *fmt, ...)
{ {
va_list ap; va_list ap;
char *buf; char *buf;
@ -128,24 +237,30 @@ void gdb_putpacket_f(const unsigned char *fmt, ...)
void gdb_out(const char *buf) void gdb_out(const char *buf)
{ {
char *hexdata; int l = strlen(buf);
int i; char *hexdata = calloc(1, 2 * l + 1);
if (!hexdata)
return;
hexify(hexdata, buf, l);
gdb_putpacket2("O", 1, hexdata, 2 * l);
free(hexdata);
}
hexdata = alloca((i = strlen(buf)*2 + 1) + 1); void gdb_voutf(const char *fmt, va_list ap)
hexdata[0] = 'O'; {
hexify(hexdata+1, buf, strlen(buf)); char *buf;
gdb_putpacket(hexdata, i);
if (vasprintf(&buf, fmt, ap) < 0)
return;
gdb_out(buf);
free(buf);
} }
void gdb_outf(const char *fmt, ...) void gdb_outf(const char *fmt, ...)
{ {
va_list ap; va_list ap;
char *buf;
va_start(ap, fmt); va_start(ap, fmt);
vasprintf(&buf, fmt, ap); gdb_voutf(fmt, ap);
gdb_out(buf);
free(buf);
va_end(ap); va_end(ap);
} }

View File

@ -18,25 +18,24 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/* Convenience function to convert to/from ascii strings of hex digits. /* Convenience function to convert to/from ascii strings of hex digits.
*/ */
#include <stdio.h> #include "general.h"
#include <stdint.h>
#include "hex_utils.h" #include "hex_utils.h"
static char hexdigits[] = "0123456789abcdef"; static const char hexdigits[] = "0123456789abcdef";
char * hexify(char *hex, const unsigned char *buf, int size) char *hexify(char *hex, const void *buf, const size_t size)
{ {
char *tmp = hex; char *dst = hex;
const uint8_t *const src = buf;
while(size--) { for (size_t idx = 0; idx < size; ++idx) {
*tmp++ = hexdigits[*buf >> 4]; *dst++ = hexdigits[src[idx] >> 4];
*tmp++ = hexdigits[*buf++ & 0xF]; *dst++ = hexdigits[src[idx] & 0xF];
} }
*tmp++ = 0; *dst++ = 0;
return hex; return hex;
} }
@ -44,19 +43,18 @@ char * hexify(char *hex, const unsigned char *buf, int size)
static uint8_t unhex_digit(char hex) static uint8_t unhex_digit(char hex)
{ {
uint8_t tmp = hex - '0'; uint8_t tmp = hex - '0';
if(tmp > 9) if (tmp > 9)
tmp -= 'A' - '0' - 10; tmp -= 'A' - '0' - 10;
if(tmp > 16) if (tmp > 16)
tmp -= 'a' - 'A'; tmp -= 'a' - 'A';
return tmp; return tmp;
} }
char * unhexify(unsigned char *buf, const char *hex, int size) char *unhexify(void *buf, const char *hex, const size_t size)
{ {
while(size--) { uint8_t *const dst = buf;
*buf = unhex_digit(*hex++) << 4; for (size_t idx = 0; idx < size; ++idx, hex += 2) {
*buf++ |= unhex_digit(*hex++); dst[idx] = (unhex_digit(hex[0]) << 4) | unhex_digit(hex[1]);
} }
return buf; return buf;
} }

View File

@ -1,178 +0,0 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2011 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __ADIV5_H
#define __ADIV5_H
#include "general.h"
#include "jtag_scan.h"
#include "target.h"
/* ADIv5 DP Register addresses */
#define ADIV5_DP_IDCODE 0x0
#define ADIV5_DP_ABORT 0x0
#define ADIV5_DP_CTRLSTAT 0x4
#define ADIV5_DP_SELECT 0x8
#define ADIV5_DP_RDBUFF 0xC
/* AP Abort Register (ABORT) */
/* Bits 31:5 - Reserved */
#define ADIV5_DP_ABORT_ORUNERRCLR (1 << 4)
#define ADIV5_DP_ABORT_WDERRCLR (1 << 3)
#define ADIV5_DP_ABORT_STKERRCLR (1 << 2)
#define ADIV5_DP_ABORT_STKCMPCLR (1 << 1)
/* Bits 5:1 - SW-DP only, reserved in JTAG-DP */
#define ADIV5_DP_ABORT_DAPABORT (1 << 0)
/* Control/Status Register (CTRLSTAT) */
#define ADIV5_DP_CTRLSTAT_CSYSPWRUPACK (1u << 31)
#define ADIV5_DP_CTRLSTAT_CSYSPWRUPREQ (1u << 30)
#define ADIV5_DP_CTRLSTAT_CDBGPWRUPACK (1u << 29)
#define ADIV5_DP_CTRLSTAT_CDBGPWRUPREQ (1u << 28)
#define ADIV5_DP_CTRLSTAT_CDBGRSTACK (1u << 27)
#define ADIV5_DP_CTRLSTAT_CDBGRSTREQ (1u << 26)
/* Bits 25:24 - Reserved */
/* Bits 23:12 - TRNCNT */
#define ADIV5_DP_CTRLSTAT_TRNCNT
/* Bits 11:8 - MASKLANE */
#define ADIV5_DP_CTRLSTAT_MASKLANE
/* Bits 7:6 - Reserved in JTAG-DP */
#define ADIV5_DP_CTRLSTAT_WDATAERR (1u << 7)
#define ADIV5_DP_CTRLSTAT_READOK (1u << 6)
#define ADIV5_DP_CTRLSTAT_STICKYERR (1u << 5)
#define ADIV5_DP_CTRLSTAT_STICKYCMP (1u << 4)
#define ADIV5_DP_CTRLSTAT_TRNMODE_MASK (3u << 2)
#define ADIV5_DP_CTRLSTAT_STICKYORUN (1u << 1)
#define ADIV5_DP_CTRLSTAT_ORUNDETECT (1u << 0)
/* ADIv5 MEM-AP Registers */
#define ADIV5_AP_CSW 0x00
#define ADIV5_AP_TAR 0x04
/* 0x08 - Reserved */
#define ADIV5_AP_DRW 0x0C
#define ADIV5_AP_DB(x) (0x10 + (4*(x)))
/* 0x20:0xF0 - Reserved */
#define ADIV5_AP_CFG 0xF4
#define ADIV5_AP_BASE 0xF8
#define ADIV5_AP_IDR 0xFC
/* AP Control and Status Word (CSW) */
#define ADIV5_AP_CSW_DBGSWENABLE (1u << 31)
/* Bits 30:24 - Prot, Implementation defined, for Cortex-M3: */
#define ADIV5_AP_CSW_MASTERTYPE_DEBUG (1u << 29)
#define ADIV5_AP_CSW_HPROT1 (1u << 25)
#define ADIV5_AP_CSW_SPIDEN (1u << 23)
/* Bits 22:12 - Reserved */
/* Bits 11:8 - Mode, must be zero */
#define ADIV5_AP_CSW_TRINPROG (1u << 7)
#define ADIV5_AP_CSW_DEVICEEN (1u << 6)
#define ADIV5_AP_CSW_ADDRINC_NONE (0u << 4)
#define ADIV5_AP_CSW_ADDRINC_SINGLE (1u << 4)
#define ADIV5_AP_CSW_ADDRINC_PACKED (2u << 4)
#define ADIV5_AP_CSW_ADDRINC_MASK (3u << 4)
/* Bit 3 - Reserved */
#define ADIV5_AP_CSW_SIZE_BYTE (0u << 0)
#define ADIV5_AP_CSW_SIZE_HALFWORD (1u << 0)
#define ADIV5_AP_CSW_SIZE_WORD (2u << 0)
#define ADIV5_AP_CSW_SIZE_MASK (7u << 0)
/* Constants to make RnW and APnDP parameters more clear in code */
#define ADIV5_LOW_WRITE 0
#define ADIV5_LOW_READ 1
#define ADIV5_LOW_DP 0
#define ADIV5_LOW_AP 1
/* Try to keep this somewhat absract for later adding SW-DP */
typedef struct ADIv5_DP_s {
struct ADIv5_DP_s *next;
uint32_t idcode;
void (*dp_write)(struct ADIv5_DP_s *dp, uint8_t addr, uint32_t value);
uint32_t (*dp_read)(struct ADIv5_DP_s *dp, uint8_t addr);
uint32_t (*error)(struct ADIv5_DP_s *dp);
uint32_t (*low_access)(struct ADIv5_DP_s *dp, uint8_t APnDP, uint8_t RnW,
uint8_t addr, uint32_t value);
union {
jtag_dev_t *dev;
uint8_t fault;
};
} ADIv5_DP_t;
static inline void adiv5_dp_write(ADIv5_DP_t *dp, uint8_t addr, uint32_t value)
{
dp->dp_write(dp, addr, value);
}
static inline uint32_t adiv5_dp_read(ADIv5_DP_t *dp, uint8_t addr)
{
return dp->dp_read(dp, addr);
}
static inline uint32_t adiv5_dp_error(ADIv5_DP_t *dp)
{
return dp->error(dp);
}
static inline uint32_t adiv5_dp_low_access(struct ADIv5_DP_s *dp, uint8_t APnDP,
uint8_t RnW, uint8_t addr, uint32_t value)
{
return dp->low_access(dp, APnDP, RnW, addr, value);
}
extern ADIv5_DP_t *adiv5_dp_list;
typedef struct ADIv5_AP_s {
ADIv5_DP_t *dp;
uint8_t apsel;
uint32_t idr;
uint32_t cfg;
uint32_t base;
} ADIv5_AP_t;
struct target_ap_s {
target t;
ADIv5_AP_t *ap;
};
extern ADIv5_AP_t adiv5_aps[5];
extern int adiv5_ap_count;
void adiv5_free_all(void);
void adiv5_dp_init(ADIv5_DP_t *dp);
void adiv5_dp_write_ap(ADIv5_DP_t *dp, uint8_t addr, uint32_t value);
uint32_t adiv5_dp_read_ap(ADIv5_DP_t *dp, uint8_t addr);
uint32_t adiv5_ap_mem_read(ADIv5_AP_t *ap, uint32_t addr);
void adiv5_ap_mem_write(ADIv5_AP_t *ap, uint32_t addr, uint32_t value);
void adiv5_ap_write(ADIv5_AP_t *ap, uint8_t addr, uint32_t value);
uint32_t adiv5_ap_read(ADIv5_AP_t *ap, uint8_t addr);
void adiv5_jtag_dp_handler(jtag_dev_t *dev);
int adiv5_swdp_scan(void);
#endif

View File

@ -21,17 +21,19 @@
#ifndef __COMMAND_H #ifndef __COMMAND_H
#define __COMMAND_H #define __COMMAND_H
#include "general.h" #include <stdbool.h>
int command_process(char *cmd); #include "target.h"
typedef void (*cmd_handler)(int argc, const char **argv);
struct command_s { int command_process(target *t, char *cmd);
const char *cmd;
cmd_handler handler;
const char *help; /*
}; * Attempts to parse a string as either being "enable" or "disable".
* If the parse is successful, returns true and sets the out param to
* indicate what was parsed. If not successful, emits a warning to the
* gdb port, returns false and leaves out untouched.
*/
bool parse_enable_or_disable(const char *s, bool *out);
#endif #endif

View File

@ -18,12 +18,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __CORTEXM3_H #ifndef __CRC32_H
#define __CORTEXM3_H #define __CRC32_H
#include "target.h" int generic_crc32(target *t, uint32_t *crc, uint32_t base, int len);
int cm3_probe(struct target_s *target);
#endif #endif

74
src/include/exception.h Normal file
View File

@ -0,0 +1,74 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2015 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Exception handling to escape deep nesting.
* Used for the case of communicaiton failure and timeouts.
*/
/* Example usage:
*
* volatile struct exception e;
* TRY_CATCH (e, EXCEPTION_TIMEOUT) {
* ...
* raise_exception(EXCEPTION_TIMEOUT, "Timeout occurred");
* ...
* }
* if (e.type == EXCEPTION_TIMEOUT) {
* printf("timeout: %s\n", e.msg);
* }
*/
/* Limitations:
* Can't use break, return, goto, etc from inside the TRY_CATCH block.
*/
#ifndef __EXCEPTION_H
#define __EXCEPTION_H
#include <setjmp.h>
#include <stdint.h>
#define EXCEPTION_ERROR 0x01
#define EXCEPTION_TIMEOUT 0x02
#define EXCEPTION_ALL -1
struct exception {
uint32_t type;
const char *msg;
/* private */
uint32_t mask;
jmp_buf jmpbuf;
struct exception *outer;
};
extern struct exception *innermost_exception;
#define TRY_CATCH(e, type_mask) \
(e).type = 0; \
(e).mask = (type_mask); \
(e).outer = innermost_exception; \
innermost_exception = (void*)&(e); \
if (setjmp(innermost_exception->jmpbuf) == 0) \
for (;innermost_exception == &(e); innermost_exception = (e).outer)
void raise_exception(uint32_t type, const char *msg);
#endif

View File

@ -21,9 +21,16 @@
#ifndef __GDB_IF_H #ifndef __GDB_IF_H
#define __GDB_IF_H #define __GDB_IF_H
#if PC_HOSTED == 0
#include <libopencm3/usb/usbd.h>
void gdb_usb_out_cb(usbd_device *dev, uint8_t ep);
#endif
int gdb_if_init(void); int gdb_if_init(void);
unsigned char gdb_if_getchar(void); unsigned char gdb_if_getchar(void);
unsigned char gdb_if_getchar_to(int timeout); unsigned char gdb_if_getchar_to(int timeout);
/* sending gdb_if_putchar(0, true) seems to work as keep alive */
void gdb_if_putchar(unsigned char c, int flush); void gdb_if_putchar(unsigned char c, int flush);
#endif #endif

View File

@ -21,16 +21,19 @@
#ifndef __GDB_PACKET_H #ifndef __GDB_PACKET_H
#define __GDB_PACKET_H #define __GDB_PACKET_H
#include <string.h> #include <stddef.h>
#include <stdarg.h>
int gdb_getpacket(unsigned char *packet, int size); size_t gdb_getpacket(char *packet, size_t size);
void gdb_putpacket(unsigned char *packet, int size); void gdb_putpacket(const char *packet, size_t size);
void gdb_putpacket2(const char *packet1, size_t size1, const char *packet2, size_t size2);
#define gdb_putpacketz(packet) gdb_putpacket((packet), strlen(packet)) #define gdb_putpacketz(packet) gdb_putpacket((packet), strlen(packet))
void gdb_putpacket_f(const unsigned char *packet, ...); void gdb_putpacket_f(const char *packet, ...);
void gdb_put_notification(const char *packet, size_t size);
#define gdb_put_notificationz(packet) gdb_put_notification((packet), strlen(packet))
void gdb_out(const char *buf); void gdb_out(const char *buf);
void gdb_voutf(const char *fmt, va_list);
void gdb_outf(const char *fmt, ...); void gdb_outf(const char *fmt, ...);
#endif #endif

View File

@ -21,14 +21,154 @@
#ifndef __GENERAL_H #ifndef __GENERAL_H
#define __GENERAL_H #define __GENERAL_H
#include "platform.h" #if !defined(_GNU_SOURCE)
# define _GNU_SOURCE
#ifndef DEBUG #endif
#include <stdio.h> #if !defined(__USE_MINGW_ANSI_STDIO)
#define DEBUG printf # define __USE_MINGW_ANSI_STDIO 1
#endif #endif
#include <stdint.h> #include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stddef.h>
#include <inttypes.h>
#include <sys/types.h>
#include "platform.h"
#include "platform_support.h"
extern uint32_t delay_cnt;
enum BMP_DEBUG {
BMP_DEBUG_NONE = 0,
BMP_DEBUG_INFO = 1,
BMP_DEBUG_GDB = 2,
BMP_DEBUG_TARGET = 4,
BMP_DEBUG_PROBE = 8,
BMP_DEBUG_WIRE = 0x10,
BMP_DEBUG_MAX = 0x20,
BMP_DEBUG_STDOUT = 0x8000,
};
#define FREQ_FIXED 0xffffffff
#if PC_HOSTED == 0
/* For BMP debug output on a firmware BMP platform, using
* BMP PC-Hosted is the preferred way. Printing DEBUG_WARN
* and DEBUG_INFO is kept for comptibiluty.
*/
# if !defined(PLATFORM_PRINTF)
# define PLATFORM_PRINTF printf
# endif
# if defined(ENABLE_DEBUG)
# define DEBUG_WARN PLATFORM_PRINTF
# define DEBUG_INFO PLATFORM_PRINTF
# else
# define DEBUG_WARN(...) do {} while(0)
# define DEBUG_INFO(...) do {} while(0)
# endif
# define DEBUG_GDB(...) do {} while(0)
# define DEBUG_TARGET(...) do {} while(0)
# define DEBUG_PROBE(...) do {} while(0)
# define DEBUG_WIRE(...) do {} while(0)
# define DEBUG_GDB_WIRE(...) do {} while(0)
#else
# include <stdarg.h>
extern int cl_debuglevel;
static inline void DEBUG_WARN(const char *format, ...)
{
va_list ap;
va_start(ap, format);
vfprintf(stderr, format, ap);
va_end(ap);
return;
}
static inline void DEBUG_INFO(const char *format, ...)
{
if (~cl_debuglevel & BMP_DEBUG_INFO)
return;
va_list ap;
va_start(ap, format);
if (cl_debuglevel & BMP_DEBUG_STDOUT)
vfprintf(stdout, format, ap);
else
vfprintf(stderr, format, ap);
va_end(ap);
return;
}
static inline void DEBUG_GDB(const char *format, ...)
{
if (~cl_debuglevel & BMP_DEBUG_GDB)
return;
va_list ap;
va_start(ap, format);
vfprintf(stderr, format, ap);
va_end(ap);
return;
}
static inline void DEBUG_GDB_WIRE(const char *format, ...)
{
if ((cl_debuglevel & (BMP_DEBUG_GDB | BMP_DEBUG_WIRE)) !=
(BMP_DEBUG_GDB | BMP_DEBUG_WIRE))
return;
va_list ap;
va_start(ap, format);
vfprintf(stderr, format, ap);
va_end(ap);
return;
}
static inline void DEBUG_TARGET(const char *format, ...)
{
if (~cl_debuglevel & BMP_DEBUG_TARGET)
return;
va_list ap;
va_start(ap, format);
vfprintf(stderr, format, ap);
va_end(ap);
return;
}
static inline void DEBUG_PROBE(const char *format, ...)
{
if (~cl_debuglevel & BMP_DEBUG_PROBE)
return;
va_list ap;
va_start(ap, format);
vfprintf(stderr, format, ap);
va_end(ap);
return;
}
static inline void DEBUG_WIRE(const char *format, ...)
{
if (~cl_debuglevel & BMP_DEBUG_WIRE)
return;
va_list ap;
va_start(ap, format);
vfprintf(stderr, format, ap);
va_end(ap);
return;
}
#endif
#define ALIGN(x, n) (((x) + (n) - 1) & ~((n) - 1))
#undef MIN
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#undef MAX
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#if !defined(SYSTICKHZ)
# define SYSTICKHZ 100
#endif
#define SYSTICKMS (1000 / SYSTICKHZ)
#define MORSECNT ((SYSTICKHZ / 10) - 1)
#endif #endif

View File

@ -21,9 +21,8 @@
#ifndef __HEX_UTILS_H #ifndef __HEX_UTILS_H
#define __HEX_UTILS_H #define __HEX_UTILS_H
char * hexify(char *hex, const unsigned char *buf, int size); char * hexify(char *hex, const void *buf, size_t size);
char * unhexify(void *buf, const char *hex, size_t size);
char * unhexify(unsigned char *buf, const char *hex, int size);
#endif #endif

View File

@ -21,17 +21,12 @@
#ifndef __JTAGTAP_H #ifndef __JTAGTAP_H
#define __JTAGTAP_H #define __JTAGTAP_H
#include "general.h" typedef struct jtag_proc_s {
/* Note: Signal names are as for the device under test. */ /* Note: Signal names are as for the device under test. */
int jtagtap_init(void); void (*jtagtap_reset)(void);
void jtagtap_reset(void); uint8_t (*jtagtap_next)(const uint8_t TMS, const uint8_t TDI);
void jtagtap_srst(void);
uint8_t jtagtap_next(const uint8_t TMS, const uint8_t TDI);
/* tap_next executes one state transision in the JTAG TAP state machine: /* tap_next executes one state transision in the JTAG TAP state machine:
* - Ensure TCK is low * - Ensure TCK is low
* - Assert the values of TMS and TDI * - Assert the values of TMS and TDI
@ -40,30 +35,39 @@ uint8_t jtagtap_next(const uint8_t TMS, const uint8_t TDI);
* - Release TCK. * - Release TCK.
*/ */
void jtagtap_tms_seq(uint32_t MS, int ticks); void (*jtagtap_tms_seq)(uint32_t MS, int ticks);
void jtagtap_tdi_tdo_seq(uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int ticks); void (*jtagtap_tdi_tdo_seq)
void jtagtap_tdi_seq(const uint8_t final_tms, const uint8_t *DI, int ticks); (uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int ticks);
/* Shift out a sequence on MS and DI, capture data to DO. /* Shift out a sequence on MS and DI, capture data to DO.
* - This is not endian safe: First byte will always be first shifted out. * - This is not endian safe: First byte will always be first shifted out.
* - DO may be NULL to ignore captured data. * - DO may be NULL to ignore captured data.
* - DO may be point to the same address as DI. * - DO may be point to the same address as DI.
*/ */
void (*jtagtap_tdi_seq)
(const uint8_t final_tms, const uint8_t *DI, int ticks);
} jtag_proc_t;
extern jtag_proc_t jtag_proc;
/* generic soft reset: 1, 1, 1, 1, 1, 0 */ /* generic soft reset: 1, 1, 1, 1, 1, 0 */
#define jtagtap_soft_reset() \ #define jtagtap_soft_reset() \
jtagtap_tms_seq(0x1F, 6) jtag_proc.jtagtap_tms_seq(0x1F, 6)
/* Goto Shift-IR: 1, 1, 0, 0 */ /* Goto Shift-IR: 1, 1, 0, 0 */
#define jtagtap_shift_ir() \ #define jtagtap_shift_ir() \
jtagtap_tms_seq(0x03, 4) jtag_proc.jtagtap_tms_seq(0x03, 4)
/* Goto Shift-DR: 1, 0, 0 */ /* Goto Shift-DR: 1, 0, 0 */
#define jtagtap_shift_dr() \ #define jtagtap_shift_dr() \
jtagtap_tms_seq(0x01, 3) jtag_proc.jtagtap_tms_seq(0x01, 3)
/* Goto Run-test/Idle: 1, 1, 0 */ /* Goto Run-test/Idle: 1, 1, 0 */
#define jtagtap_return_idle() \ #define jtagtap_return_idle() \
jtagtap_tms_seq(0x01, 2) jtag_proc.jtagtap_tms_seq(0x01, 2)
# if PC_HOSTED == 1
int platform_jtagtap_init(void);
# else
int jtagtap_init(void);
# endif
#endif #endif

30
src/include/morse.h Normal file
View File

@ -0,0 +1,30 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2015 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __MORSE_H
#define __MORSE_H
extern const char *morse_msg;
void morse(const char *msg, char repeat);
bool morse_update(void);
#endif

View File

@ -0,0 +1,54 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2015 Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __PLATFORM_SUPPORT_H
#define __PLATFORM_SUPPORT_H
#ifndef __GENERAL_H
# error "Include 'general.h' instead"
#endif
#include "target.h"
#if PC_HOSTED == 1
void platform_init(int argc, char **argv);
#else
void platform_init(void);
#endif
typedef struct platform_timeout platform_timeout;
void platform_timeout_set(platform_timeout *t, uint32_t ms);
bool platform_timeout_is_expired(platform_timeout *t);
void platform_delay(uint32_t ms);
#define POWER_CONFLICT_THRESHOLD 5 /* in 0.1V, so 5 stands for 0.5V */
extern bool connect_assert_srst;
uint32_t platform_target_voltage_sense(void);
const char *platform_target_voltage(void);
int platform_hwversion(void);
void platform_srst_set_val(bool assert);
bool platform_srst_get_val(void);
bool platform_target_get_power(void);
void platform_target_set_power(bool power);
void platform_request_boot(void);
void platform_max_frequency_set(uint32_t frequency);
uint32_t platform_max_frequency_get(void);
#endif

85
src/include/queue.h Normal file
View File

@ -0,0 +1,85 @@
/*
* Copyright 2018 Robert C. Curtis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY ROBERT C. CURTIS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ROBERT C. CURTIS OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* The views and conclusions contained in the software and documentation
* are those of the authors and should not be interpreted as representing
* official policies, either expressed or implied, of Robert C. Curtis.
*/
/** @file util/queue.h
* Static queue primitives.
*
* This file contains a set of static queue primitives that are common among
* all of the low level queue implementations. The primitives are inline
* functions, and will be optimal if size is a constant power of 2.
*/
#ifndef I__QUEUE_H__
#define I__QUEUE_H__
/** Increment a queue index.
* @param[in] idx Queue index
* @param[in] size Queue size
* @returns The new queue index value
*/
static inline size_t qinc(size_t idx, size_t size)
{
return ((idx + 1) % size);
}
/** Decrement a queue index.
* @param[in] idx Queue index
* @param[in] size Queue size
* @returns The new queue index value
*/
static inline size_t qdec(size_t idx, size_t size)
{
return ((idx - 1) % size);
}
/** Tests if a queue is full.
* @param[in] head Head index
* @param[in] tail Tail index
* @param[in] size Queue size
*/
static inline int qfull(size_t head, size_t tail, size_t size)
{
size_t next_head = qinc(head, size);
return (next_head == tail);
}
/** Tests if a queue is empty.
* @param[in] head Head index
* @param[in] tail Tail index
*/
static inline int qempty(size_t head, size_t tail)
{
return (head == tail);
}
#endif /* I__QUEUE_H__ */

34
src/include/rtt.h Normal file
View File

@ -0,0 +1,34 @@
#ifndef RTT_H
#define RTT_H
#include <target.h>
#define MAX_RTT_CHAN 16
extern char rtt_ident[16]; // string
extern bool rtt_enabled; // rtt on/off
extern bool rtt_found; // control block found
extern uint32_t rtt_cbaddr; // control block address
extern uint32_t rtt_min_poll_ms; // min time between polls (ms)
extern uint32_t rtt_max_poll_ms; // max time between polls (ms)
extern uint32_t rtt_max_poll_errs; // max number of errors before disconnect
extern bool rtt_auto_channel; // manual or auto channel selection
extern bool rtt_flag_skip; // skip if host-to-target fifo full
extern bool rtt_flag_block; // block if host-to-target fifo full
struct rtt_channel_struct {
bool is_enabled; // does user want to see this channel?
bool is_configured; // is channel configured in control block?
bool is_output;
uint32_t buf_addr;
uint32_t buf_size;
uint32_t head_addr;
uint32_t tail_addr;
uint32_t flag;
};
extern struct rtt_channel_struct rtt_channel[MAX_RTT_CHAN];
// true if target memory access does not work when target running
extern bool target_no_background_memory_access(target *cur_target);
extern void poll_rtt(target *cur_target);
#endif

36
src/include/rtt_if.h Normal file
View File

@ -0,0 +1,36 @@
#ifndef RTT_IF_H
#define RTT_IF_H
/* rtt i/o to terminal */
/* default buffer sizes, 8 bytes added to up buffer for alignment and padding */
/* override RTT_UP_BUF_SIZE and RTT_DOWN_BUF_SIZE in platform.h if needed */
#if !defined(RTT_UP_BUF_SIZE) || !defined(RTT_DOWN_BUF_SIZE)
#if (PC_HOSTED == 1)
#define RTT_UP_BUF_SIZE (4096 + 8)
#define RTT_DOWN_BUF_SIZE (512)
#elif defined(STM32F7)
#define RTT_UP_BUF_SIZE (4096 + 8)
#define RTT_DOWN_BUF_SIZE (2048)
#elif defined(STM32F4)
#define RTT_UP_BUF_SIZE (2048 + 8)
#define RTT_DOWN_BUF_SIZE (256)
#else /* stm32f103 */
#define RTT_UP_BUF_SIZE (1024 + 8)
#define RTT_DOWN_BUF_SIZE (256)
#endif
#endif
/* hosted initialisation */
extern int rtt_if_init(void);
/* hosted teardown */
extern int rtt_if_exit(void);
/* target to host: write len bytes from the buffer starting at buf. return number bytes written */
extern uint32_t rtt_write(const char *buf, uint32_t len);
/* host to target: read one character, non-blocking. return character, -1 if no character */
extern int32_t rtt_getchar();
/* host to target: true if no characters available for reading */
extern bool rtt_nodata();
#endif

26
src/include/serialno.h Normal file
View File

@ -0,0 +1,26 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2015 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __SERIALNO_H
#define __SERIALNO_H
char *serial_no_read(char *s);
#endif

View File

@ -1,7 +1,7 @@
/* /*
* This file is part of the Black Magic Debug project. * This file is part of the Black Magic Debug project.
* *
* Copyright (C) 2011 Black Sphere Technologies Ltd. * Copyright (C) 2016 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz> * Written by Gareth McMullin <gareth@blacksphere.co.nz>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -25,153 +25,158 @@
#ifndef __TARGET_H #ifndef __TARGET_H
#define __TARGET_H #define __TARGET_H
/* Halt/resume functions */ #include <stdarg.h>
#define target_attach(target) \ #include <stdbool.h>
(target)->attach(target) #include <stdint.h>
#include <sys/types.h>
#define target_detach(target) \ typedef struct target_s target;
(target)->detach(target) typedef uint32_t target_addr;
struct target_controller;
#define target_check_error(target) \ #if PC_HOSTED == 1
(target)->check_error(target) int platform_adiv5_swdp_scan(uint32_t targetid);
int platform_jtag_scan(const uint8_t *lrlens);
#endif
int adiv5_swdp_scan(uint32_t targetid);
int jtag_scan(const uint8_t *lrlens);
int target_foreach(void (*cb)(int i, target *t, void *context), void *context);
void target_list_free(void);
/* Attach/detach functions */
target *target_attach(target *t, struct target_controller *);
target *target_attach_n(int n, struct target_controller *);
void target_detach(target *t);
bool target_attached(target *t);
const char *target_driver_name(target *t);
const char *target_core_name(target *t);
unsigned int target_designer(target *t);
unsigned int target_idcode(target *t);
/* Memory access functions */ /* Memory access functions */
#define target_mem_read_words(target, dest, src, len) \ bool target_mem_map(target *t, char *buf, size_t len);
(target)->mem_read_words((target), (dest), (src), (len)) int target_mem_read(target *t, void *dest, target_addr src, size_t len);
int target_mem_write(target *t, target_addr dest, const void *src, size_t len);
#define target_mem_write_words(target, dest, src, len) \ /* Flash memory access functions */
(target)->mem_write_words((target), (dest), (src), (len)) int target_flash_erase(target *t, target_addr addr, size_t len);
int target_flash_write(target *t, target_addr dest, const void *src, size_t len);
#define target_mem_read_bytes(target, dest, src, len) \ int target_flash_done(target *t);
(target)->mem_read_bytes((target), (dest), (src), (len))
#define target_mem_write_bytes(target, dest, src, len) \
(target)->mem_write_bytes((target), (dest), (src), (len))
/* Register access functions */ /* Register access functions */
#define target_regs_read(target, data) \ size_t target_regs_size(target *t);
(target)->regs_read((target), (data)) const char *target_tdesc(target *t);
void target_regs_read(target *t, void *data);
#define target_regs_write(target, data) \ void target_regs_write(target *t, const void *data);
(target)->regs_write((target), (data)) ssize_t target_reg_read(target *t, int reg, void *data, size_t max);
ssize_t target_reg_write(target *t, int reg, const void *data, size_t size);
#define target_pc_read(target) \
(target)->pc_read((target))
#define target_pc_write(target, val) \
(target)->pc_write((target), (val))
/* Halt/resume functions */ /* Halt/resume functions */
#define target_reset(target) \ enum target_halt_reason {
(target)->reset(target) TARGET_HALT_RUNNING = 0, /* Target not halted */
TARGET_HALT_ERROR, /* Failed to read target status */
TARGET_HALT_REQUEST,
TARGET_HALT_STEPPING,
TARGET_HALT_BREAKPOINT,
TARGET_HALT_WATCHPOINT,
TARGET_HALT_FAULT,
};
#define target_halt_request(target) \ void target_reset(target *t);
(target)->halt_request(target) void target_halt_request(target *t);
enum target_halt_reason target_halt_poll(target *t, target_addr *watch);
#define target_halt_wait(target) \ void target_halt_resume(target *t, bool step);
(target)->halt_wait(target) void target_set_cmdline(target *t, char *cmdline);
void target_set_heapinfo(target *t, target_addr heap_base, target_addr heap_limit,
#define target_halt_resume(target, step) \ target_addr stack_base, target_addr stack_limit);
(target)->halt_resume((target), (step))
#define target_fault_unwind(target) \
((target)->fault_unwind?(target)->fault_unwind((target)):0)
/* Break-/watchpoint functions */ /* Break-/watchpoint functions */
#define target_set_hw_bp(target, addr) \ enum target_breakwatch {
(target)->set_hw_bp((target), (addr)) TARGET_BREAK_SOFT,
TARGET_BREAK_HARD,
TARGET_WATCH_WRITE,
TARGET_WATCH_READ,
TARGET_WATCH_ACCESS,
};
int target_breakwatch_set(target *t, enum target_breakwatch, target_addr, size_t);
int target_breakwatch_clear(target *t, enum target_breakwatch, target_addr, size_t);
#define target_clear_hw_bp(target, addr) \ /* Command interpreter */
(target)->clear_hw_bp((target), (addr)) void target_command_help(target *t);
int target_command(target *t, int argc, const char *argv[]);
/* keep target_errno in sync with errno values in gdb/include/gdb/fileio.h */
enum target_errno {
TARGET_EPERM = 1,
TARGET_ENOENT = 2,
TARGET_EINTR = 4,
TARGET_EIO = 5,
TARGET_EBADF = 9,
TARGET_EACCES = 13,
TARGET_EFAULT = 14,
TARGET_EBUSY = 16,
TARGET_EEXIST = 17,
TARGET_ENODEV = 19,
TARGET_ENOTDIR = 20,
TARGET_EISDIR = 21,
TARGET_EINVAL = 22,
TARGET_ENFILE = 23,
TARGET_EMFILE = 24,
TARGET_EFBIG = 27,
TARGET_ENOSPC = 28,
TARGET_ESPIPE = 29,
TARGET_EROFS = 30,
TARGET_ENOSYS = 88,
TARGET_ENAMETOOLONG = 91,
TARGET_EUNKNOWN = 9999,
};
#define target_set_hw_wp(target, type, addr, len) \ enum target_open_flags {
(target)->set_hw_wp((target), (type), (addr), (len)) TARGET_O_RDONLY = 0,
TARGET_O_WRONLY = 1,
TARGET_O_RDWR = 2,
TARGET_O_APPEND = 0x008,
TARGET_O_CREAT = 0x200,
TARGET_O_TRUNC = 0x400,
};
#define target_clear_hw_wp(target, type, addr, len) \ enum target_seek_flag {
(target)->clear_hw_wp((target), (type), (addr), (len)) TARGET_SEEK_SET = 0,
TARGET_SEEK_CUR = 1,
TARGET_SEEK_END = 2,
};
struct target_controller {
void (*destroy_callback)(struct target_controller *, target *t);
void (*printf)(struct target_controller *, const char *fmt, va_list);
#define target_check_hw_wp(target, addr) \ /* Interface to host system calls */
((target)->check_hw_wp?(target)->check_hw_wp((target), (addr)):0) int (*open)(struct target_controller *,
target_addr path, size_t path_len,
enum target_open_flags flags, mode_t mode);
/* Flash memory access functions */ int (*close)(struct target_controller *, int fd);
#define target_flash_erase(target, addr, len) \ int (*read)(struct target_controller *,
(target)->flash_erase((target), (addr), (len)) int fd, target_addr buf, unsigned int count);
int (*write)(struct target_controller *,
#define target_flash_write_words(target, dest, src, len) \ int fd, target_addr buf, unsigned int count);
(target)->flash_write_words((target), (dest), (src), (len)) long (*lseek)(struct target_controller *,
int fd, long offset, enum target_seek_flag flag);
int (*rename)(struct target_controller *,
#define TARGET_LIST_FREE() { \ target_addr oldpath, size_t old_len,
while(target_list) { \ target_addr newpath, size_t new_len);
target *t = target_list->next; \ int (*unlink)(struct target_controller *,
free(target_list); \ target_addr path, size_t path_len);
target_list = t; \ int (*stat)(struct target_controller *,
} \ target_addr path, size_t path_len, target_addr buf);
last_target = cur_target = NULL; \ int (*fstat)(struct target_controller *, int fd, target_addr buf);
} int (*gettimeofday)(struct target_controller *,
target_addr tv, target_addr tz);
int (*isatty)(struct target_controller *, int fd);
typedef struct target_s { int (*system)(struct target_controller *,
/* Attach/Detach funcitons */ target_addr cmd, size_t cmd_len);
void (*attach)(struct target_s *target); enum target_errno errno_;
void (*detach)(struct target_s *target); bool interrupted;
int (*check_error)(struct target_s *target); };
/* Memory access functions */
int (*mem_read_words)(struct target_s *target, uint32_t *dest, uint32_t src,
int len);
int (*mem_write_words)(struct target_s *target, uint32_t dest,
const uint32_t *src, int len);
int (*mem_read_bytes)(struct target_s *target, uint8_t *dest, uint32_t src,
int len);
int (*mem_write_bytes)(struct target_s *target, uint32_t dest,
const uint8_t *src, int len);
/* Register access functions */
int regs_size;
const char *tdesc;
int (*regs_read)(struct target_s *target, void *data);
int (*regs_write)(struct target_s *target, const void *data);
uint32_t (*pc_read)(struct target_s *target);
int (*pc_write)(struct target_s *target, const uint32_t val);
/* Halt/resume functions */
void (*reset)(struct target_s *target);
void (*halt_request)(struct target_s *target);
int (*halt_wait)(struct target_s *target);
void (*halt_resume)(struct target_s *target, uint8_t step);
int (*fault_unwind)(struct target_s *target);
/* Break-/watchpoint functions */
int (*set_hw_bp)(struct target_s *target, uint32_t addr);
int (*clear_hw_bp)(struct target_s *target, uint32_t addr);
int (*set_hw_wp)(struct target_s *target, uint8_t type, uint32_t addr, uint8_t len);
int (*clear_hw_wp)(struct target_s *target, uint8_t type, uint32_t addr, uint8_t len);
int (*check_hw_wp)(struct target_s *target, uint32_t *addr);
/* Flash memory access functions */
const char *xml_mem_map;
int (*flash_erase)(struct target_s *target, uint32_t addr, int len);
int (*flash_write_words)(struct target_s *target, uint32_t dest,
const uint32_t *src, int len);
const char *driver;
int size;
struct target_s *next;
} target;
extern target *target_list, *cur_target, *last_target;
#endif #endif

30
src/include/timing.h Normal file
View File

@ -0,0 +1,30 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2016 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __TIMING_H
#define __TIMING_H
struct platform_timeout {
uint32_t time;
};
extern int32_t swj_delay_cnt;
uint32_t platform_time_ms(void);
#endif /* __TIMING_H */

View File

@ -1,238 +0,0 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2011 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* This file implements JTAG protocol support. Provides functionality
* to detect devices on the scan chain and read their IDCODEs.
* It depends on the low-level function provided by the platform's jtagtap.c.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "general.h"
#include "jtagtap.h"
#include "jtag_scan.h"
#include "gdb_packet.h"
#include "adiv5.h"
#include "arm7tdmi.h"
struct jtag_dev_s jtag_devs[JTAG_MAX_DEVS+1];
int jtag_dev_count;
static struct jtag_dev_descr_s {
uint32_t idcode;
uint32_t idmask;
char *descr;
void (*handler)(jtag_dev_t *dev);
} dev_descr[] = {
{.idcode = 0x0BA00477, .idmask = 0x0FFFFFFF,
.descr = "ARM Limited: ADIv5 JTAG-DP port.",
.handler = adiv5_jtag_dp_handler},
{.idcode = 0x3F0F0F0F, .idmask = 0xFFFFFFFF,
.descr = "ST Microelectronics: STR730",
.handler = arm7tdmi_jtag_handler},
{.idcode = 0x06410041, .idmask = 0x0FFFFFFF,
.descr = "ST Microelectronics: STM32, Medium density."},
{.idcode = 0x06412041, .idmask = 0x0FFFFFFF,
.descr = "ST Microelectronics: STM32, Low density."},
{.idcode = 0x06414041, .idmask = 0x0FFFFFFF,
.descr = "ST Microelectronics: STM32, High density."},
{.idcode = 0x06418041, .idmask = 0x0FFFFFFF,
.descr = "ST Microelectronics: STM32, Connectivity Line."},
{.idcode = 0x06420041, .idmask = 0x0FFFFFFF,
.descr = "ST Microelectronics: STM32, Value Line."},
{.idcode = 0x06428041, .idmask = 0x0FFFFFFF,
.descr = "ST Microelectronics: STM32, Value Line, High density."},
{.idcode = 0x06411041, .idmask = 0xFFFFFFFF,
.descr = "ST Microelectronics: STM32F2xx."},
{.idcode = 0x06413041 , .idmask = 0xFFFFFFFF,
.descr = "ST Microelectronics: STM32F4xx."},
/* Just for fun, unsupported */
{.idcode = 0x8940303F, .idmask = 0xFFFFFFFF, .descr = "ATMEL: ATMega16."},
{.idcode = 0x0792603F, .idmask = 0xFFFFFFFF, .descr = "ATMEL: AT91SAM9261."},
{.idcode = 0x20270013, .idmask = 0xFFFFFFFF, .descr = "Intel: i80386ex."},
{.idcode = 0, .idmask = 0, .descr = "Unknown"},
};
/* bucket of ones for don't care TDI */
static const char ones[] = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF";
/* Scan JTAG chain for devices, store IR length and IDCODE (if present).
* Reset TAP state machine.
* Select Shift-IR state.
* Each device is assumed to shift out IR at 0x01. (this may not always be true)
* Shift in ones until we read two consecutive ones, then we have shifted out the
* IRs of all devices.
*
* After this process all the IRs are loaded with the BYPASS command.
* Select Shift-DR state.
* Shift in ones and count zeros shifted out. Should be one for each device.
* Check this against device count obtained by IR scan above.
*
* Reset the TAP state machine again. This should load all IRs with IDCODE.
* For each device, shift out one bit. If this is zero IDCODE isn't present,
* continue to next device. If this is one shift out the remaining 31 bits
* of the IDCODE register.
*/
int jtag_scan(void)
{
int i;
uint32_t j;
TARGET_LIST_FREE();
jtag_dev_count = 0;
memset(&jtag_devs, 0, sizeof(jtag_devs));
#warning "These should be elsewhere!"
adiv5_free_all();
/* Run throught the SWD to JTAG sequence for the case where an attached SWJ-DP is
* in SW-DP mode.
*/
DEBUG("Resetting TAP\n");
jtagtap_init();
jtagtap_reset();
DEBUG("Change state to Shift-IR\n");
jtagtap_shift_ir();
DEBUG("Scanning out IRs\n");
if(!jtagtap_next(0, 1)) {
DEBUG("jtag_scan: Sanity check failed: IR[0] shifted out as 0\n");
jtag_dev_count = -1;
return -1; /* must be 1 */
}
jtag_devs[0].ir_len = 1; j = 1;
while((jtag_dev_count <= JTAG_MAX_DEVS) &&
(jtag_devs[jtag_dev_count].ir_len <= JTAG_MAX_IR_LEN)) {
if(jtagtap_next(0, 1)) {
if(jtag_devs[jtag_dev_count].ir_len == 1) break;
jtag_devs[++jtag_dev_count].ir_len = 1;
jtag_devs[jtag_dev_count].ir_prescan = j;
jtag_devs[jtag_dev_count].dev = jtag_dev_count;
} else jtag_devs[jtag_dev_count].ir_len++;
j++;
}
if(jtag_dev_count > JTAG_MAX_DEVS) {
DEBUG("jtag_scan: Maximum device count exceeded\n");
jtag_dev_count = -1;
return -1;
}
if(jtag_devs[jtag_dev_count].ir_len > JTAG_MAX_IR_LEN) {
DEBUG("jtag_scan: Maximum IR length exceeded\n");
jtag_dev_count = -1;
return -1;
}
DEBUG("Return to Run-Test/Idle\n");
jtagtap_next(1, 1);
jtagtap_return_idle();
/* All devices should be in BYPASS now */
/* Count device on chain */
DEBUG("Change state to Shift-DR\n");
jtagtap_shift_dr();
for(i = 0; (jtagtap_next(0, 1) == 0) && (i <= jtag_dev_count); i++)
jtag_devs[i].dr_postscan = jtag_dev_count - i - 1;
if(i != jtag_dev_count) {
DEBUG("jtag_scan: Sanity check failed: "
"BYPASS dev count doesn't match IR scan\n");
jtag_dev_count = -1;
return -1;
}
DEBUG("Return to Run-Test/Idle\n");
jtagtap_next(1, 1);
jtagtap_return_idle();
if(!jtag_dev_count) {
morse("NO TARGETS.", 1);
return 0;
}
/* Fill in the ir_postscan fields */
for(i = jtag_dev_count - 1; i; i--)
jtag_devs[i-1].ir_postscan = jtag_devs[i].ir_postscan +
jtag_devs[i].ir_len;
/* Reset jtagtap: should take all devs to IDCODE */
jtagtap_reset();
jtagtap_shift_dr();
for(i = 0; i < jtag_dev_count; i++) {
if(!jtagtap_next(0, 1)) continue;
jtag_devs[i].idcode = 1;
for(j = 2; j; j <<= 1)
if(jtagtap_next(0, 1)) jtag_devs[i].idcode |= j;
}
DEBUG("Return to Run-Test/Idle\n");
jtagtap_next(1, 1);
jtagtap_return_idle();
/* Check for known devices and handle accordingly */
for(i = 0; i < jtag_dev_count; i++)
for(j = 0; dev_descr[j].idcode; j++)
if((jtag_devs[i].idcode & dev_descr[j].idmask) ==
dev_descr[j].idcode) {
jtag_devs[i].current_ir = -1;
/* Save description in table */
jtag_devs[i].descr = dev_descr[j].descr;
/* Call handler to initialise/probe device further */
if(dev_descr[j].handler)
dev_descr[j].handler(&jtag_devs[i]);
break;
}
if(!target_list) morse("NO TARGETS.", 1);
else morse(NULL, 0);
return jtag_dev_count;
}
void jtag_dev_write_ir(jtag_dev_t *d, uint32_t ir)
{
if(ir == d->current_ir) return;
d->current_ir = ir;
jtagtap_shift_ir();
jtagtap_tdi_seq(0, ones, d->ir_prescan);
jtagtap_tdi_seq(d->ir_postscan?0:1, (void*)&ir, d->ir_len);
jtagtap_tdi_seq(1, ones, d->ir_postscan);
jtagtap_return_idle();
}
void jtag_dev_shift_dr(jtag_dev_t *d, uint8_t *dout, const uint8_t *din, int ticks)
{
jtagtap_shift_dr();
jtagtap_tdi_seq(0, ones, d->dr_prescan);
if(dout)
jtagtap_tdi_tdo_seq((void*)dout, d->dr_postscan?0:1, (void*)din, ticks);
else
jtagtap_tdi_seq(d->dr_postscan?0:1, (void*)din, ticks);
jtagtap_tdi_seq(1, ones, d->dr_postscan);
jtagtap_return_idle();
}

View File

@ -1 +0,0 @@
LDFLAGS += -lftdi -lusb

View File

@ -1,114 +0,0 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2011 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* This file implements a transparent channel over which the GDB Remote
* Serial Debugging protocol is implemented. This implementation for Linux
* uses a TCP server on port 2000.
*/
#include <stdio.h>
#ifndef WIN32
# include <sys/socket.h>
# include <netinet/in.h>
# include <sys/select.h>
#else
# include <windows.h>
# include <ws2tcpip.h>
#endif
#include <assert.h>
#include "general.h"
#include "gdb_if.h"
static int gdb_if_serv, gdb_if_conn;
int gdb_if_init(void)
{
#ifdef WIN32
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif
struct sockaddr_in addr;
int opt;
addr.sin_family = AF_INET;
addr.sin_port = htons(2000);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
assert((gdb_if_serv = socket(PF_INET, SOCK_STREAM, 0)) != -1);
opt = 1;
assert(setsockopt(gdb_if_serv, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) != -1);
assert(bind(gdb_if_serv, (void*)&addr, sizeof(addr)) != -1);
assert(listen(gdb_if_serv, 1) != -1);
DEBUG("Listening on TCP:2000\n");
return 0;
}
unsigned char gdb_if_getchar(void)
{
unsigned char ret;
int i = 0;
while(i <= 0) {
if(gdb_if_conn <= 0) {
gdb_if_conn = accept(gdb_if_serv, NULL, NULL);
DEBUG("Got connection\n");
}
i = recv(gdb_if_conn, &ret, 1, 0);
if(i <= 0) {
gdb_if_conn = -1;
DEBUG("Dropped broken connection\n");
/* Return '+' in case we were waiting for an ACK */
return '+';
}
}
return ret;
}
unsigned char gdb_if_getchar_to(int timeout)
{
fd_set fds;
struct timeval tv;
if(gdb_if_conn == -1) return -1;
tv.tv_sec = timeout / 1000;
tv.tv_usec = (timeout % 1000) * 1000;
FD_ZERO(&fds);
FD_SET(gdb_if_conn, &fds);
if(select(gdb_if_conn+1, &fds, NULL, NULL, &tv) > 0)
return gdb_if_getchar();
return -1;
}
void gdb_if_putchar(unsigned char c, int flush)
{
if(gdb_if_conn > 0)
send(gdb_if_conn, &c, 1, 0);
}

View File

@ -1,221 +0,0 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2008 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Low level JTAG implementation using FT2232 with libftdi.
*
* Issues:
* This code is old, rotten and unsupported.
* Magic numbers everywhere.
* Should share interface with swdptap.c or at least clean up...
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <ftdi.h>
#include "general.h"
#define PROVIDE_GENERIC_TAP_SEQ
//#define PROVIDE_GENERIC_TAP_TMS_SEQ
//#define PROVIDE_GENERIC_TAP_TDI_TDO_SEQ
//#define PROVIDE_GENERIC_TAP_TDI_SEQ
#include "jtagtap.h"
#define ALL_ZERO 0xA0
#define TCK 0x01
#define TDI 0x02
#define TDO 0x04
#define TMS 0x08
#define nSRST 0x20
int jtagtap_init(void)
{
int err;
assert(ftdic != NULL);
if((err = ftdi_set_bitmode(ftdic, 0xAB, BITMODE_MPSSE)) != 0) {
fprintf(stderr, "ftdi_set_bitmode: %d: %s\n",
err, ftdi_get_error_string(ftdic));
abort();
}
assert(ftdi_write_data(ftdic, "\x86\x00\x00\x80\xA8\xAB", 6) == 6);
/* Go to JTAG mode for SWJ-DP */
for(int i = 0; i <= 50; i++) jtagtap_next(1, 0); /* Reset SW-DP */
jtagtap_tms_seq(0xE73C, 16); /* SWD to JTAG sequence */
jtagtap_soft_reset();
return 0;
}
void jtagtap_reset(void)
{
jtagtap_soft_reset();
}
void jtagtap_srst(void)
{
platform_buffer_flush();
//ftdi_write_data(ftdic, "\x80\x88\xAB", 3);
//usleep(1000);
//ftdi_write_data(ftdic, "\x80\xA8\xAB", 3);
}
#ifndef PROVIDE_GENERIC_TAP_TMS_SEQ
void
jtagtap_tms_seq(uint32_t MS, int ticks)
{
uint8_t tmp[3] = "\x4B";
while(ticks >= 0) {
//jtagtap_next(MS & 1, 1);
tmp[1] = ticks<7?ticks-1:6;
tmp[2] = 0x80 | (MS & 0x7F);
// assert(ftdi_write_data(ftdic, tmp, 3) == 3);
platform_buffer_write(tmp, 3);
MS >>= 7; ticks -= 7;
}
}
#endif
#ifndef PROVIDE_GENERIC_TAP_TDI_SEQ
void
jtagtap_tdi_seq(const uint8_t final_tms, const uint8_t *DI, int ticks)
{
char *tmp;
int index = 0;
int rticks;
if(!ticks) return;
if(final_tms) ticks--;
rticks = ticks & 7;
ticks >>= 3;
tmp = alloca(ticks + 9);
if(ticks) {
tmp[index++] = 0x19;
tmp[index++] = ticks - 1;
tmp[index++] = 0;
while(ticks--) tmp[index++] = *DI++;
}
if(rticks) {
tmp[index++] = 0x1B;
tmp[index++] = rticks - 1;
tmp[index++] = *DI;
}
if(final_tms) {
tmp[index++] = 0x4B;
tmp[index++] = 0;
tmp[index++] = (*DI)>>rticks?0x81:0x01;
}
// assert(ftdi_write_data(ftdic, tmp, index) == index);
platform_buffer_write(tmp, index);
}
#endif
#ifndef PROVIDE_GENERIC_TAP_TDI_TDO_SEQ
void
jtagtap_tdi_tdo_seq(uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int ticks)
{
uint8_t *tmp;
int index = 0, rsize;
int rticks;
if(!ticks) return;
// printf("ticks: %d\n", ticks);
if(final_tms) ticks--;
rticks = ticks & 7;
ticks >>= 3;
tmp = alloca(ticks + 9);
rsize = ticks;
if(ticks) {
tmp[index++] = 0x39;
tmp[index++] = ticks - 1;
tmp[index++] = 0;
while(ticks--) tmp[index++] = *DI++;
}
if(rticks) {
rsize++;
tmp[index++] = 0x3B;
tmp[index++] = rticks - 1;
tmp[index++] = *DI;
}
if(final_tms) {
rsize++;
tmp[index++] = 0x6B;
tmp[index++] = 0;
tmp[index++] = (*DI)>>rticks?0x81:0x01;
}
// assert(ftdi_write_data(ftdic, tmp, index) == index);
platform_buffer_write(tmp, index);
// index = 0;
// while((index += ftdi_read_data(ftdic, tmp + index, rsize-index)) != rsize);
platform_buffer_read(tmp, rsize);
/*for(index = 0; index < rsize; index++)
printf("%02X ", tmp[index]);
printf("\n");*/
index = 0;
if(final_tms) rsize--;
while(rsize--) {
/*if(rsize) printf("%02X ", tmp[index]);*/
*DO++ = tmp[index++];
}
if(final_tms) {
rticks++;
*(--DO) >>= 1;
*DO |= tmp[index] & 0x80;
} else DO--;
if(rticks) {
*DO >>= (8-rticks);
}
/*printf("%02X\n", *DO);*/
}
#endif
uint8_t jtagtap_next(uint8_t dTMS, uint8_t dTDO)
{
uint8_t ret;
uint8_t tmp[3] = "\x6B\x00\x00";
tmp[2] = (dTDO?0x80:0) | (dTMS?0x01:0);
// assert(ftdi_write_data(ftdic, tmp, 3) == 3);
// while(ftdi_read_data(ftdic, &ret, 1) != 1);
platform_buffer_write(tmp, 3);
platform_buffer_read(&ret, 1);
ret &= 0x80;
// DEBUG("jtagtap_next(TMS = %d, TDO = %d) = %02X\n", dTMS, dTDO, ret);
return ret;
}

View File

@ -1,123 +0,0 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2011 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "platform.h"
#include "gdb_if.h"
#include "jtag_scan.h"
#include <stdio.h>
#include <string.h>
#include <assert.h>
struct ftdi_context *ftdic;
#define BUF_SIZE 4096
static uint8_t outbuf[BUF_SIZE];
static uint16_t bufptr = 0;
int platform_init(void)
{
int err;
if(ftdic) {
ftdi_usb_close(ftdic);
ftdi_free(ftdic);
ftdic = NULL;
}
if((ftdic = ftdi_new()) == NULL) {
fprintf(stderr, "ftdi_new: %s\n",
ftdi_get_error_string(ftdic));
abort();
}
if((err = ftdi_set_interface(ftdic, INTERFACE_A)) != 0) {
fprintf(stderr, "ftdi_set_interface: %d: %s\n",
err, ftdi_get_error_string(ftdic));
abort();
}
if((err = ftdi_usb_open(ftdic, FT2232_VID, FT2232_PID)) != 0) {
fprintf(stderr, "unable to open ftdi device: %d (%s)\n",
err, ftdi_get_error_string(ftdic));
abort();
}
if((err = ftdi_set_latency_timer(ftdic, 1)) != 0) {
fprintf(stderr, "ftdi_set_latency_timer: %d: %s\n",
err, ftdi_get_error_string(ftdic));
abort();
}
if((err = ftdi_set_baudrate(ftdic, 1000000)) != 0) {
fprintf(stderr, "ftdi_set_baudrate: %d: %s\n",
err, ftdi_get_error_string(ftdic));
abort();
}
if((err = ftdi_usb_purge_buffers(ftdic)) != 0) {
fprintf(stderr, "ftdi_set_baudrate: %d: %s\n",
err, ftdi_get_error_string(ftdic));
abort();
}
if((err = ftdi_write_data_set_chunksize(ftdic, BUF_SIZE)) != 0) {
fprintf(stderr, "ftdi_write_data_set_chunksize: %d: %s\n",
err, ftdi_get_error_string(ftdic));
abort();
}
assert(gdb_if_init() == 0);
jtag_scan();
return 0;
}
void platform_buffer_flush(void)
{
assert(ftdi_write_data(ftdic, outbuf, bufptr) == bufptr);
// printf("FT2232 platform_buffer flush: %d bytes\n", bufptr);
bufptr = 0;
}
int platform_buffer_write(const uint8_t *data, int size)
{
if((bufptr + size) / BUF_SIZE > 0) platform_buffer_flush();
memcpy(outbuf + bufptr, data, size);
bufptr += size;
return size;
}
int platform_buffer_read(uint8_t *data, int size)
{
int index = 0;
platform_buffer_flush();
while((index += ftdi_read_data(ftdic, data + index, size-index)) != size);
return size;
}
#ifdef WIN32
#warning "This vasprintf() is dubious!"
int vasprintf(char **strp, const char *fmt, va_list ap)
{
int size = 128, ret = 0;
*strp = malloc(size);
while(*strp && ((ret = vsnprintf(*strp, size, fmt, ap)) == size))
*strp = realloc(*strp, size <<= 1);
return ret;
}
#endif

View File

@ -1,172 +0,0 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2011 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Quick hack for bit-banging SW-DP interface over FT2232.
* Intended as proof of concept, not for production.
*/
#include <stdio.h>
#include <assert.h>
#include <ftdi.h>
#include "platform.h"
#include "swdptap.h"
int swdptap_init(void)
{
int err;
assert(ftdic != NULL);
if((err = ftdi_set_bitmode(ftdic, 0xAB, BITMODE_BITBANG)) != 0) {
fprintf(stderr, "ftdi_set_bitmode: %d: %s\n",
err, ftdi_get_error_string(ftdic));
abort();
}
assert(ftdi_write_data(ftdic, "\xAB\xA8", 2) == 2);
/* This must be investigated in more detail.
* As described in STM32 Reference Manual... */
swdptap_seq_out(0xFFFF, 16);
swdptap_reset();
swdptap_seq_out(0xE79E, 16); /* 0b0111100111100111 */
swdptap_reset();
swdptap_seq_out(0, 16);
return 0;
}
void swdptap_reset(void)
{
swdptap_turnaround(0);
/* 50 clocks with TMS high */
for(int i = 0; i < 50; i++) swdptap_bit_out(1);
}
void swdptap_turnaround(uint8_t dir)
{
static uint8_t olddir = 0;
//DEBUG("%s", dir ? "\n-> ":"\n<- ");
platform_buffer_flush();
if(dir == olddir) return;
olddir = dir;
if(dir) /* SWDIO goes to input */
assert(ftdi_set_bitmode(ftdic, 0xA3, BITMODE_BITBANG) == 0);
/* One clock cycle */
ftdi_write_data(ftdic, "\xAB\xA8", 2);
if(!dir) /* SWDIO goes to output */
assert(ftdi_set_bitmode(ftdic, 0xAB, BITMODE_BITBANG) == 0);
}
uint8_t swdptap_bit_in(void)
{
uint8_t ret;
//ftdi_read_data(ftdic, &ret, 1);
ftdi_read_pins(ftdic, &ret);
ret &= 0x08;
ftdi_write_data(ftdic, "\xA1\xA0", 2);
//DEBUG("%d", ret?1:0);
return ret;
}
void swdptap_bit_out(uint8_t val)
{
uint8_t buf[3] = "\xA0\xA1\xA0";
//DEBUG("%d", val);
if(val) {
for(int i = 0; i < 3; i++)
buf[i] |= 0x08;
}
//ftdi_write_data(ftdic, buf, 3);
platform_buffer_write(buf, 3);
}
uint32_t swdptap_seq_in(int ticks)
{
uint32_t index = 1;
uint32_t ret = 0;
swdptap_turnaround(1);
while (ticks--) {
if (swdptap_bit_in())
ret |= index;
index <<= 1;
}
return ret;
}
uint8_t swdptap_seq_in_parity(uint32_t *ret, int ticks)
{
uint32_t index = 1;
uint8_t parity = 0;
*ret = 0;
swdptap_turnaround(1);
while (ticks--) {
if (swdptap_bit_in()) {
*ret |= index;
parity ^= 1;
}
index <<= 1;
}
if (swdptap_bit_in())
parity ^= 1;
return parity;
}
void swdptap_seq_out(uint32_t MS, int ticks)
{
swdptap_turnaround(0);
while (ticks--) {
swdptap_bit_out(MS & 1);
MS >>= 1;
}
}
void swdptap_seq_out_parity(uint32_t MS, int ticks)
{
uint8_t parity = 0;
swdptap_turnaround(0);
while (ticks--) {
swdptap_bit_out(MS & 1);
parity ^= MS;
MS >>= 1;
}
swdptap_bit_out(parity & 1);
}

153
src/lmi.c
View File

@ -1,153 +0,0 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2011 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* This file implements TI/LMI LM3S target specific functions providing
* the XML memory map and Flash memory programming.
*
* Issues:
* No detection of the target device.
* Add reference to documentation.
* Flash erase is very slow.
*/
#include <stdlib.h>
#include <string.h>
#include "general.h"
#include "adiv5.h"
#include "target.h"
static int lmi_flash_erase(struct target_s *target, uint32_t addr, int len);
static int lmi_flash_write_words(struct target_s *target, uint32_t dest,
const uint32_t *src, int len);
static const char lmi_driver_str[] = "LuminaryMicro Stellaris";
static const char lmi_xml_memory_map[] = "<?xml version=\"1.0\"?>"
/* "<!DOCTYPE memory-map "
" PUBLIC \"+//IDN gnu.org//DTD GDB Memory Map V1.0//EN\""
" \"http://sourceware.org/gdb/gdb-memory-map.dtd\">"*/
"<memory-map>"
" <memory type=\"flash\" start=\"0\" length=\"0x20000\">"
" <property name=\"blocksize\">0x400</property>"
" </memory>"
" <memory type=\"ram\" start=\"0x20000000\" length=\"0x10000\"/>"
"</memory-map>";
uint16_t lmi_flash_write_stub[] = {
// _start:
0x4809, // ldr r0, [pc, #36] // _flashbase
0x490b, // ldr r1, [pc, #44] // _addr
0x467a, // mov r2, pc
0x3230, // adds r2, #48
0x4b0a, // ldr r3, [pc, #40] // _size
0x4d08, // ldr r5, [pc, #32] // _flash_write_cmd
// _next:
0xb15b, // cbz r3, _done
0x6001, // str r1, [r0, #0]
0x6814, // ldr r4, [r2]
0x6044, // str r4, [r0, #4]
0x6085, // str r5, [r0, #8]
// _wait:
0x6884, // ldr r4, [r0, #8]
0x2601, // movs r6, #1
0x4234, // tst r4, r6
0xd1fb, // bne _wait
0x3b01, // subs r3, #1
0x3104, // adds r1, #4
0x3204, // adds r2, #4
0xe7f2, // b _next
// _done:
0xbe00, // bkpt
// _flashbase:
0xd000, 0x400f, // .word 0x400fd000
// _flash_write_cmd:
0x0001, 0xa442, // .word 0xa4420001
// _addr:
// 0x0000, 0x0000,
// _size:
// 0x0000, 0x0000,
// _data:
// ...
};
int lmi_probe(struct target_s *target)
{
/* How do we really probe the LMI device??? */
target->driver = lmi_driver_str;
target->xml_mem_map = lmi_xml_memory_map;
target->flash_erase = lmi_flash_erase;
target->flash_write_words = lmi_flash_write_words;
return 0;
}
int lmi_flash_erase(struct target_s *target, uint32_t addr, int len)
{
struct target_ap_s *t = (void *)target;
uint32_t tmp;
addr &= 0xFFFFFC00;
len &= 0xFFFFFC00;
/* setup word access */
adiv5_ap_write(t->ap, 0x00, 0xA2000052);
/* select Flash Control */
adiv5_dp_low_access(t->ap->dp, 1, 0, 0x04, 0x400FD000);
while(len) {
/* write address to FMA */
adiv5_ap_write(t->ap, 0x10, addr); /* Required to switch banks */
/* set ERASE bit in FMC */
adiv5_dp_low_access(t->ap->dp, 1, 0, 0x08, 0xA4420002);
/* Read FMC to poll for ERASE bit */
adiv5_dp_low_access(t->ap->dp, 1, 1, 0x08, 0);
do {
tmp = adiv5_dp_low_access(t->ap->dp, 1, 1, 0x08, 0);
} while (tmp & 2);
len -= 0x400;
addr += 0x400;
}
return 0;
}
int lmi_flash_write_words(struct target_s *target, uint32_t dest,
const uint32_t *src, int len)
{
uint32_t data[(len>>2)+2];
data[0] = dest;
data[1] = len >> 2;
memcpy(&data[2], src, len);
DEBUG("Sending stub\n");
target_mem_write_words(target, 0x20000000, (void*)lmi_flash_write_stub, 0x30);
DEBUG("Sending data\n");
target_mem_write_words(target, 0x20000030, data, len + 8);
DEBUG("Running stub\n");
target_pc_write(target, 0x20000000);
target_halt_resume(target, 0);
DEBUG("Waiting for halt\n");
while(!target_halt_wait(target));
return 0;
}

View File

@ -18,29 +18,40 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/* Provides main entry point. Initialise subsystems and enter GDB /* Provides main entry point. Initialise subsystems and enter GDB
* protocol loop. * protocol loop.
*/ */
#include <stdio.h> #include "general.h"
#include <stdlib.h>
#include <assert.h>
#include "gdb_if.h" #include "gdb_if.h"
#include "gdb_main.h" #include "gdb_main.h"
#include "jtagtap.h"
#include "jtag_scan.h"
#include "target.h" #include "target.h"
#include "exception.h"
#include "gdb_packet.h"
#include "morse.h"
int int
main(void) main(int argc, char **argv)
{ {
assert(platform_init() == 0); #if PC_HOSTED == 1
platform_init(argc, argv);
#else
(void) argc;
(void) argv;
platform_init();
#endif
PLATFORM_SET_FATAL_ERROR_RECOVERY(); while (true) {
volatile struct exception e;
gdb_main(); TRY_CATCH(e, EXCEPTION_ALL) {
gdb_main();
}
if (e.type) {
gdb_putpacketz("EFF");
target_list_free();
morse("TARGET LOST.", 1);
}
}
/* Should never get here */ /* Should never get here */
return 0; return 0;

106
src/morse.c Normal file
View File

@ -0,0 +1,106 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2015 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "general.h"
#include "morse.h"
/* Morse code patterns and lengths */
static const struct {
uint16_t code;
uint8_t bits;
} morse_letter[] = {
{ 0b00011101, 8}, // 'A' .-
{ 0b000101010111, 12}, // 'B' -...
{ 0b00010111010111, 14}, // 'C' -.-.
{ 0b0001010111, 10}, // 'D' -..
{ 0b0001, 4}, // 'E' .
{ 0b000101110101, 12}, // 'F' ..-.
{ 0b000101110111, 12}, // 'G' --.
{ 0b0001010101, 10}, // 'H' ....
{ 0b000101, 6}, // 'I' ..
{0b0001110111011101, 16}, // 'J' .---
{ 0b000111010111, 12}, // 'K' -.-
{ 0b000101011101, 12}, // 'L' .-..
{ 0b0001110111, 10}, // 'M' --
{ 0b00010111, 8}, // 'N' -.
{ 0b00011101110111, 14}, // 'O' ---
{ 0b00010111011101, 14}, // 'P' .--.
{0b0001110101110111, 16}, // 'Q' --.-
{ 0b0001011101, 10}, // 'R' .-.
{ 0b00010101, 8}, // 'S' ...
{ 0b000111, 6}, // 'T' -
{ 0b0001110101, 10}, // 'U' ..-
{ 0b000111010101, 12}, // 'V' ...-
{ 0b000111011101, 12}, // 'W' .--
{ 0b00011101010111, 14}, // 'X' -..-
{0b0001110111010111, 16}, // 'Y' -.--
{ 0b00010101110111, 14}, // 'Z' --..
};
const char *morse_msg;
static const char * volatile morse_ptr;
static char morse_repeat;
void morse(const char *msg, char repeat)
{
#if PC_HOSTED == 1
if (msg)
DEBUG_WARN("%s\n", msg);
(void) repeat;
#else
morse_msg = morse_ptr = msg;
morse_repeat = repeat;
#endif
}
bool morse_update(void)
{
static uint16_t code;
static uint8_t bits;
if (!morse_ptr)
return false;
if (!bits) {
char c = *morse_ptr++;
if (!c) {
if(morse_repeat) {
morse_ptr = morse_msg;
c = *morse_ptr++;
} else {
morse_ptr = 0;
return false;
}
}
if ((c >= 'A') && (c <= 'Z')) {
c -= 'A';
code = morse_letter[c].code;
bits = morse_letter[c].bits;
} else {
code = 0; bits = 4;
}
}
bool ret = code & 1;
code >>= 1;
bits--;
return ret;
}

23
src/platforms/Readme.md Normal file
View File

@ -0,0 +1,23 @@
# Platforms and platform support files
This directory contains the implementation of platforms and support file
used by (multiple) platforms.
## Implementation directories
native : Firmware for original Black Magic Probe<br>
stlink : Firmware for STLINK-V2 and V21<br>
swlink : Firmware for STLINK-V1 and Bluepill<br>
hydrabus : Firmware https://hydrabus.com/ <br>
f4discovery : Firmware for STM32F407DISCO<br>
launchpad-icdi :<br>
tm4c: <br>
hosted: PC-hosted BMP running as PC application talking to firmware BMPs,
STLINK-V2/21/3, FTDI MPSSE probes, CMSIS-DAP and JLINK
## Support directories
common: libopencm3 based support for firmware BMPs<br>
stm32: STM32 specific libopencm3 based support for firmware BMPs<br>
pc: Support for PC-hosted BMPs.<br>

View File

@ -0,0 +1,591 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2011 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* This file implements a the USB Communications Device Class - Abstract
* Control Model (CDC-ACM) as defined in CDC PSTN subclass 1.2.
* A Device Firmware Upgrade (DFU 1.1) class interface is provided for
* field firmware upgrade.
*
* The device's unique id is used as the USB serial number string.
*
* Endpoint Usage
*
* 0 Control Endpoint
* IN 1 GDB CDC DATA
* OUT 1 GDB CDC DATA
* IN 2 GDB CDC CTR
* IN 3 UART CDC DATA
* OUT 3 UART CDC DATA
* OUT 4 UART CDC CTRL
* In 5 Trace Capture
*
*/
#include "general.h"
#include "gdb_if.h"
#include "cdcacm.h"
#if defined(PLATFORM_HAS_TRACESWO)
# include "traceswo.h"
#endif
#include "usbuart.h"
#include "serialno.h"
#include "version.h"
#include <libopencm3/cm3/nvic.h>
#include <libopencm3/usb/usbd.h>
#include <libopencm3/usb/cdc.h>
#include <libopencm3/cm3/scb.h>
#include <libopencm3/usb/dfu.h>
#define GDB_IF_NO 0
#define UART_IF_NO 2
#define DFU_IF_NO 4
#if defined(PLATFORM_HAS_TRACESWO)
# define TRACE_IF_NO 5
# define TOTAL_INTERFACES 6
#else
# define TOTAL_INTERFACES 5
#endif
usbd_device * usbdev;
static int configured;
static int cdcacm_gdb_dtr = 1;
static void cdcacm_set_modem_state(usbd_device *dev, int iface, bool dsr, bool dcd);
static const struct usb_device_descriptor dev_desc = {
.bLength = USB_DT_DEVICE_SIZE,
.bDescriptorType = USB_DT_DEVICE,
.bcdUSB = 0x0200,
.bDeviceClass = 0xEF, /* Miscellaneous Device */
.bDeviceSubClass = 2, /* Common Class */
.bDeviceProtocol = 1, /* Interface Association */
#if defined(SAMD21E17) || defined(LM4F)
.bMaxPacketSize0 = 64, /*Fixed for icdi*/
#else
.bMaxPacketSize0 = 32,
#endif
.idVendor = 0x1D50,
.idProduct = 0x6018,
.bcdDevice = 0x0100,
.iManufacturer = 1,
.iProduct = 2,
.iSerialNumber = 3,
.bNumConfigurations = 1,
};
/* This notification endpoint isn't implemented. According to CDC spec its
* optional, but its absence causes a NULL pointer dereference in Linux cdc_acm
* driver. */
static const struct usb_endpoint_descriptor gdb_comm_endp[] = {{
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = (CDCACM_GDB_ENDPOINT + 1) | USB_REQ_TYPE_IN,
.bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
.wMaxPacketSize = 16,
.bInterval = 255,
}};
static const struct usb_endpoint_descriptor gdb_data_endp[] = {{
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = CDCACM_GDB_ENDPOINT,
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
.wMaxPacketSize = CDCACM_PACKET_SIZE,
.bInterval = 1,
}, {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = CDCACM_GDB_ENDPOINT | USB_REQ_TYPE_IN,
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
.wMaxPacketSize = CDCACM_PACKET_SIZE,
.bInterval = 1,
}};
static const struct {
struct usb_cdc_header_descriptor header;
struct usb_cdc_call_management_descriptor call_mgmt;
struct usb_cdc_acm_descriptor acm;
struct usb_cdc_union_descriptor cdc_union;
} __attribute__((packed)) gdb_cdcacm_functional_descriptors = {
.header = {
.bFunctionLength = sizeof(struct usb_cdc_header_descriptor),
.bDescriptorType = CS_INTERFACE,
.bDescriptorSubtype = USB_CDC_TYPE_HEADER,
.bcdCDC = 0x0110,
},
.call_mgmt = {
.bFunctionLength =
sizeof(struct usb_cdc_call_management_descriptor),
.bDescriptorType = CS_INTERFACE,
.bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT,
.bmCapabilities = 0,
.bDataInterface = GDB_IF_NO + 1,
},
.acm = {
.bFunctionLength = sizeof(struct usb_cdc_acm_descriptor),
.bDescriptorType = CS_INTERFACE,
.bDescriptorSubtype = USB_CDC_TYPE_ACM,
.bmCapabilities = 2, /* SET_LINE_CODING supported */
},
.cdc_union = {
.bFunctionLength = sizeof(struct usb_cdc_union_descriptor),
.bDescriptorType = CS_INTERFACE,
.bDescriptorSubtype = USB_CDC_TYPE_UNION,
.bControlInterface = GDB_IF_NO,
.bSubordinateInterface0 = GDB_IF_NO + 1,
}
};
static const struct usb_interface_descriptor gdb_comm_iface[] = {{
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = 0,
.bAlternateSetting = 0,
.bNumEndpoints = 1,
.bInterfaceClass = USB_CLASS_CDC,
.bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
.bInterfaceProtocol = USB_CDC_PROTOCOL_NONE,
.iInterface = 4,
.endpoint = gdb_comm_endp,
.extra = &gdb_cdcacm_functional_descriptors,
.extralen = sizeof(gdb_cdcacm_functional_descriptors)
}};
static const struct usb_interface_descriptor gdb_data_iface[] = {{
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = GDB_IF_NO + 1,
.bAlternateSetting = 0,
.bNumEndpoints = 2,
.bInterfaceClass = USB_CLASS_DATA,
.bInterfaceSubClass = 0,
.bInterfaceProtocol = 0,
.iInterface = 0,
.endpoint = gdb_data_endp,
}};
static const struct usb_iface_assoc_descriptor gdb_assoc = {
.bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE,
.bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
.bFirstInterface = GDB_IF_NO,
.bInterfaceCount = 2,
.bFunctionClass = USB_CLASS_CDC,
.bFunctionSubClass = USB_CDC_SUBCLASS_ACM,
.bFunctionProtocol = USB_CDC_PROTOCOL_NONE,
.iFunction = 4,
};
/* Serial ACM interface */
static const struct usb_endpoint_descriptor uart_comm_endp[] = {{
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = (CDCACM_UART_ENDPOINT + 1) | USB_REQ_TYPE_IN,
.bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
.wMaxPacketSize = 16,
.bInterval = 255,
}};
static const struct usb_endpoint_descriptor uart_data_endp[] = {{
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = CDCACM_UART_ENDPOINT,
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
.wMaxPacketSize = CDCACM_PACKET_SIZE / 2,
.bInterval = 1,
}, {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = CDCACM_UART_ENDPOINT | USB_REQ_TYPE_IN,
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
.wMaxPacketSize = CDCACM_PACKET_SIZE,
.bInterval = 1,
}};
static const struct {
struct usb_cdc_header_descriptor header;
struct usb_cdc_call_management_descriptor call_mgmt;
struct usb_cdc_acm_descriptor acm;
struct usb_cdc_union_descriptor cdc_union;
} __attribute__((packed)) uart_cdcacm_functional_descriptors = {
.header = {
.bFunctionLength = sizeof(struct usb_cdc_header_descriptor),
.bDescriptorType = CS_INTERFACE,
.bDescriptorSubtype = USB_CDC_TYPE_HEADER,
.bcdCDC = 0x0110,
},
.call_mgmt = {
.bFunctionLength =
sizeof(struct usb_cdc_call_management_descriptor),
.bDescriptorType = CS_INTERFACE,
.bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT,
.bmCapabilities = 0,
.bDataInterface = UART_IF_NO + 1,
},
.acm = {
.bFunctionLength = sizeof(struct usb_cdc_acm_descriptor),
.bDescriptorType = CS_INTERFACE,
.bDescriptorSubtype = USB_CDC_TYPE_ACM,
.bmCapabilities = 2, /* SET_LINE_CODING supported*/
},
.cdc_union = {
.bFunctionLength = sizeof(struct usb_cdc_union_descriptor),
.bDescriptorType = CS_INTERFACE,
.bDescriptorSubtype = USB_CDC_TYPE_UNION,
.bControlInterface = UART_IF_NO,
.bSubordinateInterface0 = UART_IF_NO + 1,
}
};
static const struct usb_interface_descriptor uart_comm_iface[] = {{
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = UART_IF_NO,
.bAlternateSetting = 0,
.bNumEndpoints = 1,
.bInterfaceClass = USB_CLASS_CDC,
.bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
.bInterfaceProtocol = USB_CDC_PROTOCOL_NONE,
.iInterface = 5,
.endpoint = uart_comm_endp,
.extra = &uart_cdcacm_functional_descriptors,
.extralen = sizeof(uart_cdcacm_functional_descriptors)
}};
static const struct usb_interface_descriptor uart_data_iface[] = {{
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = UART_IF_NO + 1,
.bAlternateSetting = 0,
.bNumEndpoints = 2,
.bInterfaceClass = USB_CLASS_DATA,
.bInterfaceSubClass = 0,
.bInterfaceProtocol = 0,
.iInterface = 0,
.endpoint = uart_data_endp,
}};
static const struct usb_iface_assoc_descriptor uart_assoc = {
.bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE,
.bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
.bFirstInterface = UART_IF_NO,
.bInterfaceCount = 2,
.bFunctionClass = USB_CLASS_CDC,
.bFunctionSubClass = USB_CDC_SUBCLASS_ACM,
.bFunctionProtocol = USB_CDC_PROTOCOL_NONE,
.iFunction = 5,
};
const struct usb_dfu_descriptor dfu_function = {
.bLength = sizeof(struct usb_dfu_descriptor),
.bDescriptorType = DFU_FUNCTIONAL,
.bmAttributes = USB_DFU_CAN_DOWNLOAD | USB_DFU_WILL_DETACH,
.wDetachTimeout = 255,
.wTransferSize = 1024,
.bcdDFUVersion = 0x011A,
};
const struct usb_interface_descriptor dfu_iface = {
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = DFU_IF_NO,
.bAlternateSetting = 0,
.bNumEndpoints = 0,
.bInterfaceClass = 0xFE,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 1,
.iInterface = 6,
.extra = &dfu_function,
.extralen = sizeof(dfu_function),
};
static const struct usb_iface_assoc_descriptor dfu_assoc = {
.bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE,
.bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
.bFirstInterface = DFU_IF_NO,
.bInterfaceCount = 1,
.bFunctionClass = 0xFE,
.bFunctionSubClass = 1,
.bFunctionProtocol = 1,
.iFunction = 6,
};
#if defined(PLATFORM_HAS_TRACESWO)
static const struct usb_endpoint_descriptor trace_endp[] = {{
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = TRACE_ENDPOINT | USB_REQ_TYPE_IN,
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
.wMaxPacketSize = 64,
.bInterval = 0,
}};
const struct usb_interface_descriptor trace_iface = {
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = TRACE_IF_NO,
.bAlternateSetting = 0,
.bNumEndpoints = 1,
.bInterfaceClass = 0xFF,
.bInterfaceSubClass = 0xFF,
.bInterfaceProtocol = 0xFF,
.iInterface = 7,
.endpoint = trace_endp,
};
static const struct usb_iface_assoc_descriptor trace_assoc = {
.bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE,
.bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
.bFirstInterface = TRACE_IF_NO,
.bInterfaceCount = 1,
.bFunctionClass = 0xFF,
.bFunctionSubClass = 0xFF,
.bFunctionProtocol = 0xFF,
.iFunction = 7,
};
#endif
static const struct usb_interface ifaces[] = {{
.num_altsetting = 1,
.iface_assoc = &gdb_assoc,
.altsetting = gdb_comm_iface,
}, {
.num_altsetting = 1,
.altsetting = gdb_data_iface,
}, {
.num_altsetting = 1,
.iface_assoc = &uart_assoc,
.altsetting = uart_comm_iface,
}, {
.num_altsetting = 1,
.altsetting = uart_data_iface,
}, {
.num_altsetting = 1,
.iface_assoc = &dfu_assoc,
.altsetting = &dfu_iface,
#if defined(PLATFORM_HAS_TRACESWO)
}, {
.num_altsetting = 1,
.iface_assoc = &trace_assoc,
.altsetting = &trace_iface,
#endif
}};
static const struct usb_config_descriptor config = {
.bLength = USB_DT_CONFIGURATION_SIZE,
.bDescriptorType = USB_DT_CONFIGURATION,
.wTotalLength = 0,
.bNumInterfaces = TOTAL_INTERFACES,
.bConfigurationValue = 1,
.iConfiguration = 0,
.bmAttributes = 0x80,
.bMaxPower = 0x32,
.interface = ifaces,
};
static char serial_no[DFU_SERIAL_LENGTH];
#define BOARD_IDENT "Black Magic Probe " PLATFORM_IDENT FIRMWARE_VERSION
static const char *usb_strings[] = {
"Black Magic Debug",
BOARD_IDENT,
serial_no,
"Black Magic GDB Server",
"Black Magic UART Port",
"Black Magic DFU",
#if defined(PLATFORM_HAS_TRACESWO)
"Black Magic Trace Capture",
#endif
};
static void dfu_detach_complete(usbd_device *dev, struct usb_setup_data *req)
{
(void)dev;
(void)req;
platform_request_boot();
/* Reset core to enter bootloader */
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
scb_reset_core();
#else
scb_reset_system();
#endif
}
static enum usbd_request_return_codes cdcacm_control_request(usbd_device *dev,
struct usb_setup_data *req, uint8_t **buf, uint16_t *len,
void (**complete)(usbd_device *dev, struct usb_setup_data *req))
{
(void)dev;
(void)complete;
(void)buf;
(void)len;
switch(req->bRequest) {
case USB_CDC_REQ_SET_CONTROL_LINE_STATE:
cdcacm_set_modem_state(dev, req->wIndex, true, true);
/* Ignore if not for GDB interface */
if(req->wIndex != GDB_IF_NO)
return USBD_REQ_HANDLED;
cdcacm_gdb_dtr = req->wValue & 1;
return USBD_REQ_HANDLED;
case USB_CDC_REQ_SET_LINE_CODING:
if(*len < sizeof(struct usb_cdc_line_coding))
return USBD_REQ_NOTSUPP;
switch(req->wIndex) {
case UART_IF_NO:
usbuart_set_line_coding((struct usb_cdc_line_coding*)*buf);
return USBD_REQ_HANDLED;
case GDB_IF_NO:
return USBD_REQ_HANDLED; /* Ignore on GDB Port */
default:
return USBD_REQ_NOTSUPP;
}
case DFU_GETSTATUS:
if(req->wIndex == DFU_IF_NO) {
(*buf)[0] = DFU_STATUS_OK;
(*buf)[1] = 0;
(*buf)[2] = 0;
(*buf)[3] = 0;
(*buf)[4] = STATE_APP_IDLE;
(*buf)[5] = 0; /* iString not used here */
*len = 6;
return USBD_REQ_HANDLED;
}
return USBD_REQ_NOTSUPP;
case DFU_DETACH:
if(req->wIndex == DFU_IF_NO) {
*complete = dfu_detach_complete;
return USBD_REQ_HANDLED;
}
return USBD_REQ_NOTSUPP;
}
return USBD_REQ_NOTSUPP;
}
int cdcacm_get_config(void)
{
return configured;
}
int cdcacm_get_dtr(void)
{
return cdcacm_gdb_dtr;
}
static void cdcacm_set_modem_state(usbd_device *dev, int iface, bool dsr, bool dcd)
{
char buf[10];
struct usb_cdc_notification *notif = (void*)buf;
/* We echo signals back to host as notification */
notif->bmRequestType = 0xA1;
notif->bNotification = USB_CDC_NOTIFY_SERIAL_STATE;
notif->wValue = 0;
notif->wIndex = iface;
notif->wLength = 2;
buf[8] = (dsr ? 2 : 0) | (dcd ? 1 : 0);
buf[9] = 0;
/* FIXME: Remove magic numbers */
usbd_ep_write_packet(dev, 0x82 + iface, buf, 10);
}
static void cdcacm_set_config(usbd_device *dev, uint16_t wValue)
{
configured = wValue;
/* GDB interface */
#if defined(STM32F4) || defined(LM4F) || defined(SAMD)
usbd_ep_setup(dev, CDCACM_GDB_ENDPOINT, USB_ENDPOINT_ATTR_BULK,
CDCACM_PACKET_SIZE, gdb_usb_out_cb);
#else
usbd_ep_setup(dev, CDCACM_GDB_ENDPOINT, USB_ENDPOINT_ATTR_BULK,
CDCACM_PACKET_SIZE, NULL);
#endif
usbd_ep_setup(dev, CDCACM_GDB_ENDPOINT | USB_REQ_TYPE_IN,
USB_ENDPOINT_ATTR_BULK, CDCACM_PACKET_SIZE, NULL);
usbd_ep_setup(dev, (CDCACM_GDB_ENDPOINT + 1) | USB_REQ_TYPE_IN,
USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
/* Serial interface */
usbd_ep_setup(dev, CDCACM_UART_ENDPOINT, USB_ENDPOINT_ATTR_BULK,
CDCACM_PACKET_SIZE / 2, usbuart_usb_out_cb);
usbd_ep_setup(dev, CDCACM_UART_ENDPOINT | USB_REQ_TYPE_IN,
USB_ENDPOINT_ATTR_BULK,
CDCACM_PACKET_SIZE, usbuart_usb_in_cb);
usbd_ep_setup(dev, (CDCACM_UART_ENDPOINT + 1) | USB_REQ_TYPE_IN,
USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
#if defined(PLATFORM_HAS_TRACESWO)
/* Trace interface */
usbd_ep_setup(dev, TRACE_ENDPOINT | USB_REQ_TYPE_IN, USB_ENDPOINT_ATTR_BULK,
64, trace_buf_drain);
#endif
usbd_register_control_callback(dev,
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
cdcacm_control_request);
/* Notify the host that DCD is asserted.
* Allows the use of /dev/tty* devices on *BSD/MacOS
*/
cdcacm_set_modem_state(dev, GDB_IF_NO, true, true);
cdcacm_set_modem_state(dev, UART_IF_NO, true, true);
}
/* We need a special large control buffer for this device: */
uint8_t usbd_control_buffer[256];
void cdcacm_init(void)
{
void exti15_10_isr(void);
serial_no_read(serial_no);
usbdev = usbd_init(&USB_DRIVER, &dev_desc, &config, usb_strings,
sizeof(usb_strings)/sizeof(char *),
usbd_control_buffer, sizeof(usbd_control_buffer));
usbd_register_set_config_callback(usbdev, cdcacm_set_config);
nvic_set_priority(USB_IRQ, IRQ_PRI_USB);
nvic_enable_irq(USB_IRQ);
usbd_disconnect(usbdev, false);
}
void USB_ISR(void)
{
usbd_poll(usbdev);
}

View File

@ -0,0 +1,46 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2015 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* This file implements a the USB Communications Device Class - Abstract
* Control Model (CDC-ACM) as defined in CDC PSTN subclass 1.2.
* A Device Firmware Upgrade (DFU 1.1) class interface is provided for
* field firmware upgrade.
*
* The device's unique id is used as the USB serial number string.
*/
#ifndef __CDCACM_H
#define __CDCACM_H
#include <libopencm3/usb/usbd.h>
#define CDCACM_PACKET_SIZE 64
#define CDCACM_GDB_ENDPOINT 1
#define CDCACM_UART_ENDPOINT 3
#define TRACE_ENDPOINT 5
extern usbd_device *usbdev;
void cdcacm_init(void);
/* Returns current usb configuration, or 0 if not configured. */
int cdcacm_get_config(void);
int cdcacm_get_dtr(void);
#endif

View File

@ -0,0 +1,199 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2011 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* This file implements the low-level JTAG TAP interface. */
#include <stdio.h>
#include "general.h"
#include "jtagtap.h"
#include "gdb_packet.h"
jtag_proc_t jtag_proc;
static void jtagtap_reset(void);
static void jtagtap_tms_seq(uint32_t MS, int ticks);
static void jtagtap_tdi_tdo_seq(
uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int ticks);
static void jtagtap_tdi_seq(
const uint8_t final_tms, const uint8_t *DI, int ticks);
static uint8_t jtagtap_next(uint8_t dTMS, uint8_t dTDI);
int jtagtap_init()
{
TMS_SET_MODE();
jtag_proc.jtagtap_reset = jtagtap_reset;
jtag_proc.jtagtap_next =jtagtap_next;
jtag_proc.jtagtap_tms_seq = jtagtap_tms_seq;
jtag_proc.jtagtap_tdi_tdo_seq = jtagtap_tdi_tdo_seq;
jtag_proc.jtagtap_tdi_seq = jtagtap_tdi_seq;
/* Go to JTAG mode for SWJ-DP */
for(int i = 0; i <= 50; i++) jtagtap_next(1, 0); /* Reset SW-DP */
jtagtap_tms_seq(0xE73C, 16); /* SWD to JTAG sequence */
jtagtap_soft_reset();
return 0;
}
static void jtagtap_reset(void)
{
#ifdef TRST_PORT
if (platform_hwversion() == 0) {
volatile int i;
gpio_clear(TRST_PORT, TRST_PIN);
for(i = 0; i < 10000; i++) asm("nop");
gpio_set(TRST_PORT, TRST_PIN);
}
#endif
jtagtap_soft_reset();
}
static uint8_t jtagtap_next(uint8_t dTMS, uint8_t dTDI)
{
uint16_t ret;
register volatile int32_t cnt;
gpio_set_val(TMS_PORT, TMS_PIN, dTMS);
gpio_set_val(TDI_PORT, TDI_PIN, dTDI);
gpio_set(TCK_PORT, TCK_PIN);
for(cnt = swd_delay_cnt -2 ; cnt > 0; cnt--);
ret = gpio_get(TDO_PORT, TDO_PIN);
gpio_clear(TCK_PORT, TCK_PIN);
for(cnt = swd_delay_cnt - 2; cnt > 0; cnt--);
//DEBUG("jtagtap_next(TMS = %d, TDI = %d) = %d\n", dTMS, dTDI, ret);
return ret != 0;
}
static void jtagtap_tms_seq(uint32_t MS, int ticks)
{
gpio_set_val(TDI_PORT, TDI_PIN, 1);
int data = MS & 1;
register volatile int32_t cnt;
if (swd_delay_cnt) {
while(ticks) {
gpio_set_val(TMS_PORT, TMS_PIN, data);
gpio_set(TCK_PORT, TCK_PIN);
for(cnt = swd_delay_cnt -2 ; cnt > 0; cnt--);
MS >>= 1;
data = MS & 1;
ticks--;
gpio_clear(TCK_PORT, TCK_PIN);
for(cnt = swd_delay_cnt -2 ; cnt > 0; cnt--);
}
} else {
while(ticks) {
gpio_set_val(TMS_PORT, TMS_PIN, data);
gpio_set(TCK_PORT, TCK_PIN);
MS >>= 1;
data = MS & 1;
ticks--;
gpio_clear(TCK_PORT, TCK_PIN);
}
}
}
static void jtagtap_tdi_tdo_seq(
uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int ticks)
{
uint8_t index = 1;
gpio_set_val(TMS_PORT, TMS_PIN, 0);
uint8_t res = 0;
register volatile int32_t cnt;
if (swd_delay_cnt) {
while(ticks > 1) {
gpio_set_val(TDI_PORT, TDI_PIN, *DI & index);
gpio_set(TCK_PORT, TCK_PIN);
for(cnt = swd_delay_cnt -2 ; cnt > 0; cnt--);
if (gpio_get(TDO_PORT, TDO_PIN)) {
res |= index;
}
if(!(index <<= 1)) {
*DO = res;
res = 0;
index = 1;
DI++; DO++;
}
ticks--;
gpio_clear(TCK_PORT, TCK_PIN);
for(cnt = swd_delay_cnt -2 ; cnt > 0; cnt--);
}
} else {
while(ticks > 1) {
gpio_set_val(TDI_PORT, TDI_PIN, *DI & index);
gpio_set(TCK_PORT, TCK_PIN);
if (gpio_get(TDO_PORT, TDO_PIN)) {
res |= index;
}
if(!(index <<= 1)) {
*DO = res;
res = 0;
index = 1;
DI++; DO++;
}
ticks--;
gpio_clear(TCK_PORT, TCK_PIN);
}
}
gpio_set_val(TMS_PORT, TMS_PIN, final_tms);
gpio_set_val(TDI_PORT, TDI_PIN, *DI & index);
gpio_set(TCK_PORT, TCK_PIN);
for(cnt = swd_delay_cnt -2 ; cnt > 0; cnt--);
if (gpio_get(TDO_PORT, TDO_PIN)) {
res |= index;
}
*DO = res;
gpio_clear(TCK_PORT, TCK_PIN);
for(cnt = swd_delay_cnt -2 ; cnt > 0; cnt--);
}
static void jtagtap_tdi_seq(const uint8_t final_tms, const uint8_t *DI, int ticks)
{
uint8_t index = 1;
register volatile int32_t cnt;
if (swd_delay_cnt) {
while(ticks--) {
gpio_set_val(TMS_PORT, TMS_PIN, ticks? 0 : final_tms);
gpio_set_val(TDI_PORT, TDI_PIN, *DI & index);
gpio_set(TCK_PORT, TCK_PIN);
for(cnt = swd_delay_cnt -2 ; cnt > 0; cnt--);
if(!(index <<= 1)) {
index = 1;
DI++;
}
gpio_clear(TCK_PORT, TCK_PIN);
for(cnt = swd_delay_cnt -2 ; cnt > 0; cnt--);
}
} else {
while(ticks--) {
gpio_set_val(TMS_PORT, TMS_PIN, ticks? 0 : final_tms);
gpio_set_val(TDI_PORT, TDI_PIN, *DI & index);
gpio_set(TCK_PORT, TCK_PIN);
if(!(index <<= 1)) {
index = 1;
DI++;
}
gpio_clear(TCK_PORT, TCK_PIN);
}
}
}

View File

@ -0,0 +1,215 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2011 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* This file implements the SW-DP interface. */
#include "general.h"
#include "timing.h"
#include "adiv5.h"
enum {
SWDIO_STATUS_FLOAT = 0,
SWDIO_STATUS_DRIVE
};
static void swdptap_turnaround(int dir) __attribute__ ((optimize(3)));
static uint32_t swdptap_seq_in(int ticks) __attribute__ ((optimize(3)));
static bool swdptap_seq_in_parity(uint32_t *ret, int ticks)
__attribute__ ((optimize(3)));
static void swdptap_seq_out(uint32_t MS, int ticks)
__attribute__ ((optimize(3)));
static void swdptap_seq_out_parity(uint32_t MS, int ticks)
__attribute__ ((optimize(3)));
static void swdptap_turnaround(int dir)
{
static int olddir = SWDIO_STATUS_FLOAT;
register volatile int32_t cnt;
/* Don't turnaround if direction not changing */
if(dir == olddir) return;
olddir = dir;
#ifdef DEBUG_SWD_BITS
DEBUG("%s", dir ? "\n-> ":"\n<- ");
#endif
if(dir == SWDIO_STATUS_FLOAT)
SWDIO_MODE_FLOAT();
gpio_set(SWCLK_PORT, SWCLK_PIN);
for(cnt = swd_delay_cnt; --cnt > 0;);
gpio_clear(SWCLK_PORT, SWCLK_PIN);
for(cnt = swd_delay_cnt; --cnt > 0;);
if(dir == SWDIO_STATUS_DRIVE)
SWDIO_MODE_DRIVE();
}
static uint32_t swdptap_seq_in(int ticks)
{
uint32_t index = 1;
uint32_t ret = 0;
int len = ticks;
register volatile int32_t cnt;
swdptap_turnaround(SWDIO_STATUS_FLOAT);
if (swd_delay_cnt) {
while (len--) {
int res;
res = gpio_get(SWDIO_PORT, SWDIO_PIN);
gpio_set(SWCLK_PORT, SWCLK_PIN);
for(cnt = swd_delay_cnt; --cnt > 0;);
ret |= (res) ? index : 0;
index <<= 1;
gpio_clear(SWCLK_PORT, SWCLK_PIN);
for(cnt = swd_delay_cnt; --cnt > 0;);
}
} else {
volatile int res;
while (len--) {
res = gpio_get(SWDIO_PORT, SWDIO_PIN);
gpio_set(SWCLK_PORT, SWCLK_PIN);
ret |= (res) ? index : 0;
index <<= 1;
gpio_clear(SWCLK_PORT, SWCLK_PIN);
}
}
#ifdef DEBUG_SWD_BITS
for (int i = 0; i < len; i++)
DEBUG("%d", (ret & (1 << i)) ? 1 : 0);
#endif
return ret;
}
static bool swdptap_seq_in_parity(uint32_t *ret, int ticks)
{
uint32_t index = 1;
uint32_t res = 0;
bool bit;
int len = ticks;
register volatile int32_t cnt;
swdptap_turnaround(SWDIO_STATUS_FLOAT);
if (swd_delay_cnt) {
while (len--) {
bit = gpio_get(SWDIO_PORT, SWDIO_PIN);
gpio_set(SWCLK_PORT, SWCLK_PIN);
for(cnt = swd_delay_cnt; --cnt > 0;);
res |= (bit) ? index : 0;
index <<= 1;
gpio_clear(SWCLK_PORT, SWCLK_PIN);
for(cnt = swd_delay_cnt; --cnt > 0;);
}
} else {
while (len--) {
bit = gpio_get(SWDIO_PORT, SWDIO_PIN);
gpio_set(SWCLK_PORT, SWCLK_PIN);
res |= (bit) ? index : 0;
index <<= 1;
gpio_clear(SWCLK_PORT, SWCLK_PIN);
}
}
int parity = __builtin_popcount(res);
bit = gpio_get(SWDIO_PORT, SWDIO_PIN);
gpio_set(SWCLK_PORT, SWCLK_PIN);
for(cnt = swd_delay_cnt; --cnt > 0;);
parity += (bit) ? 1 : 0;
gpio_clear(SWCLK_PORT, SWCLK_PIN);
for(cnt = swd_delay_cnt; --cnt > 0;);
#ifdef DEBUG_SWD_BITS
for (int i = 0; i < len; i++)
DEBUG("%d", (res & (1 << i)) ? 1 : 0);
#endif
*ret = res;
/* Terminate the read cycle now */
swdptap_turnaround(SWDIO_STATUS_DRIVE);
return (parity & 1);
}
static void swdptap_seq_out(uint32_t MS, int ticks)
{
#ifdef DEBUG_SWD_BITS
for (int i = 0; i < ticks; i++)
DEBUG("%d", (MS & (1 << i)) ? 1 : 0);
#endif
register volatile int32_t cnt;
swdptap_turnaround(SWDIO_STATUS_DRIVE);
gpio_set_val(SWDIO_PORT, SWDIO_PIN, MS & 1);
if (swd_delay_cnt) {
while (ticks--) {
gpio_set(SWCLK_PORT, SWCLK_PIN);
for(cnt = swd_delay_cnt; --cnt > 0;);
MS >>= 1;
gpio_set_val(SWDIO_PORT, SWDIO_PIN, MS & 1);
gpio_clear(SWCLK_PORT, SWCLK_PIN);
for(cnt = swd_delay_cnt; --cnt > 0;);
}
} else {
while (ticks--) {
gpio_set(SWCLK_PORT, SWCLK_PIN);
MS >>= 1;
gpio_set_val(SWDIO_PORT, SWDIO_PIN, MS & 1);
gpio_clear(SWCLK_PORT, SWCLK_PIN);
}
}
}
static void swdptap_seq_out_parity(uint32_t MS, int ticks)
{
int parity = __builtin_popcount(MS);
#ifdef DEBUG_SWD_BITS
for (int i = 0; i < ticks; i++)
DEBUG("%d", (MS & (1 << i)) ? 1 : 0);
#endif
register volatile int32_t cnt;
swdptap_turnaround(SWDIO_STATUS_DRIVE);
gpio_set_val(SWDIO_PORT, SWDIO_PIN, MS & 1);
MS >>= 1;
if (swd_delay_cnt) {
while (ticks--) {
gpio_set(SWCLK_PORT, SWCLK_PIN);
for(cnt = swd_delay_cnt; --cnt > 0;);
gpio_set_val(SWDIO_PORT, SWDIO_PIN, MS & 1);
MS >>= 1;
gpio_clear(SWCLK_PORT, SWCLK_PIN);
for(cnt = swd_delay_cnt; --cnt > 0;);
}
} else {
while (ticks--) {
gpio_set(SWCLK_PORT, SWCLK_PIN);
gpio_set_val(SWDIO_PORT, SWDIO_PIN, MS & 1);
MS >>= 1;
gpio_clear(SWCLK_PORT, SWCLK_PIN);
}
}
gpio_set_val(SWDIO_PORT, SWDIO_PIN, parity & 1);
gpio_set(SWCLK_PORT, SWCLK_PIN);
for(cnt = swd_delay_cnt; --cnt > 0;);
gpio_clear(SWCLK_PORT, SWCLK_PIN);
for(cnt = swd_delay_cnt; --cnt > 0;);
}
int swdptap_init(ADIv5_DP_t *dp)
{
dp->seq_in = swdptap_seq_in;
dp->seq_in_parity = swdptap_seq_in_parity;
dp->seq_out = swdptap_seq_out;
dp->seq_out_parity = swdptap_seq_out_parity;
return 0;
}

View File

@ -1,7 +1,7 @@
/* /*
* This file is part of the Black Magic Debug project. * This file is part of the Black Magic Debug project.
* *
* Copyright (C) 2011 Black Sphere Technologies Ltd. * Copyright (C) 2012 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz> * Written by Gareth McMullin <gareth@blacksphere.co.nz>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -17,39 +17,26 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __TRACESWO_H
#define __TRACESWO_H
#ifndef __PLATFORM_H #include <libopencm3/usb/usbd.h>
#define __PLATFORM_H
#include <stdint.h> #if defined TRACESWO_PROTOCOL && TRACESWO_PROTOCOL == 2
#include <ftdi.h> /* Default line rate, used as default for a request without baudrate */
#define SWO_DEFAULT_BAUD (2250000)
#ifndef WIN32 void traceswo_init(uint32_t baudrate, uint32_t swo_chan_bitmask);
# include <alloca.h>
#else #else
# define alloca __builtin_alloca void traceswo_init(uint32_t swo_chan_bitmask);
#endif #endif
#define FT2232_VID 0x0403 void trace_buf_drain(usbd_device *dev, uint8_t ep);
#define FT2232_PID 0x6010
#define SET_RUN_STATE(state) /* set bitmask of swo channels to be decoded */
#define SET_IDLE_STATE(state) void traceswo_setmask(uint32_t mask);
#define SET_ERROR_STATE(state)
#define PLATFORM_FATAL_ERROR(error) abort() /* print decoded swo packet on usb serial */
#define PLATFORM_SET_FATAL_ERROR_RECOVERY() uint16_t traceswo_decode(usbd_device *usbd_dev, uint8_t addr,
const void *buf, uint16_t len);
#define morse(x, y) do {} while(0)
#define morse_msg 0
extern struct ftdi_context *ftdic;
int platform_init(void);
void platform_buffer_flush(void);
int platform_buffer_write(const uint8_t *data, int size);
int platform_buffer_read(uint8_t *data, int size);
#endif #endif

View File

@ -0,0 +1,32 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2012 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __USBUART_H
#define __USBUART_H
#include <libopencm3/usb/usbd.h>
#include <libopencm3/usb/cdc.h>
void usbuart_init(void);
void usbuart_set_line_coding(struct usb_cdc_line_coding *coding);
void usbuart_usb_out_cb(usbd_device *dev, uint8_t ep);
void usbuart_usb_in_cb(usbd_device *dev, uint8_t ep);
#endif

View File

@ -0,0 +1,57 @@
CROSS_COMPILE ?= arm-none-eabi-
BMP_BOOTLOADER ?=
CC = $(CROSS_COMPILE)gcc
OBJCOPY = $(CROSS_COMPILE)objcopy
CFLAGS += -Istm32/include -mcpu=cortex-m4 -mthumb \
-mfloat-abi=hard -mfpu=fpv4-sp-d16 \
-DSTM32F4 -I../libopencm3/include \
-Iplatforms/stm32
ifeq ($(BLACKPILL), 1)
LINKER_SCRIPT=platforms/stm32/blackpillv2.ld
CFLAGS += -DBLACKPILL=1
else
LINKER_SCRIPT=platforms/stm32/f4discovery.ld
endif
LDFLAGS_BOOT = -lopencm3_stm32f4 \
-Wl,-T,$(LINKER_SCRIPT) -nostartfiles -lc -lnosys \
-Wl,-Map=mapfile -mthumb -mcpu=cortex-m4 -Wl,-gc-sections \
-mfloat-abi=hard -mfpu=fpv4-sp-d16 \
-L../libopencm3/lib
ifeq ($(BMP_BOOTLOADER), 1)
$(info Load address 0x08004000 for BMPBootloader)
LDFLAGS = $(LDFLAGS_BOOT) -Wl,-Ttext=0x8004000
CFLAGS += -DDFU_SERIAL_LENGTH=9
else
LDFLAGS += $(LDFLAGS_BOOT)
CFLAGS += -DDFU_SERIAL_LENGTH=13
endif
VPATH += platforms/stm32
SRC += cdcacm.c \
traceswodecode.c \
traceswo.c \
usbuart.c \
serialno.c \
timing.c \
timing_stm32.c \
ifneq ($(BMP_BOOTLOADER), 1)
all: blackmagic.bin
else
all: blackmagic.bin blackmagic_dfu.bin blackmagic_dfu.hex
blackmagic_dfu: usbdfu.o dfucore.o dfu_f4.o serialno.o
$(CC) $^ -o $@ $(LDFLAGS_BOOT)
blackmagic_dfu.bin: blackmagic_dfu
$(OBJCOPY) -O binary $^ $@
blackmagic_dfu.hex: blackmagic_dfu
$(OBJCOPY) -O ihex $^ $@
endif
host_clean:
-$(Q)$(RM) blackmagic.bin

View File

@ -0,0 +1,65 @@
# Firmware BMP for STM32F407 DISCO boards
Kept for historical reasons to load BMP bootloader to the STM32F103 of the onboard STLINK or external STLINKs. As stlink-tool now allows to load BMP firmware via the original STLINK bootloader is no longer really needed.
## Connections:
PC2: TDI<br>
PC4: TMS/SWDIO<br>
PC5: TCK/SWCLK<br>
PC6: TDO/TRACESWO<br>
PC1: TRST<br>
PC8: SRST<br>
# Alternate build for stm32f401 stm32f411 MiniF4 aka BlackPillV2 boards.
https://github.com/WeActTC/MiniSTM32F4x1
## Connections:
* JTAG/SWD
* PA1: TDI
* PA13: TMS/SWDIO
* PA14: TCK/SWCLK
* PB3: TDO/TRACESWO
* PB5: TRST
* PB4: SRST
* USB USART
* PB6: USART1 TX (usbuart_xxx)
* PB7: USART1 RX (usbuart_xxx)
* +3V3.
* PB8 - turn on IRLML5103 transistor
How to Build
========================================
```
cd blackmagic
make clean
make PROBE_HOST=f4discovery BLACKPILL=1
```
How to Flash with dfu
========================================
* After build:
* 1) `apt install dfu-util`
* 2) Force the F4 into system bootloader mode by jumpering "BOOT0" to "3V3" and "PB2/BOOT1" to "GND" and reset (RESET button). System bootloader should appear.
* 3) `dfu-util -a 0 --dfuse-address 0x08000000 -D blackmagic.bin`
To exit from dfu mode press a "key" and "reset", release reset. BMP firmware should appear
10 pin male from pins
========================================
| PB3/TDO | PB7/RX | PB6/TX | X | PA1/TDI |
| -------- | ----------- | ---------- | ---------- | ------- |
| PB4/SRST | +3V3/PB8 SW | PA13/SWDIO | PA14/SWCLK | GND |
SWJ frequency setting
====================================
https://github.com/blackmagic-debug/blackmagic/pull/783#issue-529197718
`mon freq 900k` helps at most

View File

@ -0,0 +1,160 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2011 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* This file implements the platform specific functions for the STM32
* implementation.
*/
#include "general.h"
#include "cdcacm.h"
#include "usbuart.h"
#include "morse.h"
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/cm3/scb.h>
#include <libopencm3/cm3/nvic.h>
#include <libopencm3/stm32/exti.h>
#include <libopencm3/stm32/usart.h>
#include <libopencm3/stm32/syscfg.h>
#include <libopencm3/usb/usbd.h>
#include <libopencm3/cm3/systick.h>
#include <libopencm3/cm3/cortex.h>
#ifdef BLACKPILL
#include <libopencm3/usb/dwc/otg_fs.h>
#endif
jmp_buf fatal_error_jmpbuf;
extern char _ebss[];
void platform_init(void)
{
volatile uint32_t *magic = (uint32_t *)_ebss;
/* Enable GPIO peripherals */
rcc_periph_clock_enable(RCC_GPIOA);
rcc_periph_clock_enable(RCC_GPIOC);
#ifdef BLACKPILL
rcc_periph_clock_enable(RCC_GPIOB);
#else
rcc_periph_clock_enable(RCC_GPIOD);
#endif
/* Check the USER button*/
if (gpio_get(GPIOA, GPIO0) ||
((magic[0] == BOOTMAGIC0) && (magic[1] == BOOTMAGIC1)))
{
magic[0] = 0;
magic[1] = 0;
/* Assert blue LED as indicator we are in the bootloader */
gpio_mode_setup(LED_PORT, GPIO_MODE_OUTPUT,
GPIO_PUPD_NONE, LED_BOOTLOADER);
gpio_set(LED_PORT, LED_BOOTLOADER);
/* Jump to the built in bootloader by mapping System flash.
As we just come out of reset, no other deinit is needed!*/
rcc_periph_clock_enable(RCC_SYSCFG);
SYSCFG_MEMRM &= ~3;
SYSCFG_MEMRM |= 1;
scb_reset_core();
}
#ifdef BLACKPILL
rcc_clock_setup_pll(&rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_84MHZ]);
#else
rcc_clock_setup_pll(&rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_168MHZ]);
#endif
/* Enable peripherals */
rcc_periph_clock_enable(RCC_OTGFS);
rcc_periph_clock_enable(RCC_CRC);
/* Set up USB Pins and alternate function*/
gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO9 | GPIO11 | GPIO12);
gpio_set_af(GPIOA, GPIO_AF10, GPIO9 | GPIO10 | GPIO11 | GPIO12);
#ifdef BLACKPILL
GPIOA_OSPEEDR &= 0x3C00000C;
GPIOA_OSPEEDR |= 0x28000008;
#else
GPIOC_OSPEEDR &= ~0xF30;
GPIOC_OSPEEDR |= 0xA20;
#endif
gpio_mode_setup(JTAG_PORT, GPIO_MODE_OUTPUT,
GPIO_PUPD_NONE,
TCK_PIN | TDI_PIN);
gpio_mode_setup(JTAG_PORT, GPIO_MODE_INPUT,
GPIO_PUPD_NONE, TMS_PIN);
gpio_set_output_options(JTAG_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ,
TCK_PIN | TDI_PIN | TMS_PIN);
gpio_mode_setup(TDO_PORT, GPIO_MODE_INPUT,
GPIO_PUPD_NONE,
TDO_PIN);
gpio_set_output_options(TDO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ,
TDO_PIN | TMS_PIN);
gpio_mode_setup(LED_PORT, GPIO_MODE_OUTPUT,
GPIO_PUPD_NONE,
LED_IDLE_RUN | LED_ERROR | LED_BOOTLOADER);
gpio_mode_setup(LED_PORT_UART, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_UART);
#ifdef PLATFORM_HAS_POWER_SWITCH
gpio_set(PWR_BR_PORT, PWR_BR_PIN);
gpio_mode_setup(PWR_BR_PORT, GPIO_MODE_OUTPUT,
GPIO_PUPD_NONE,
PWR_BR_PIN);
#endif
platform_timing_init();
usbuart_init();
cdcacm_init();
#ifdef BLACKPILL
// https://github.com/libopencm3/libopencm3/pull/1256#issuecomment-779424001
OTG_FS_GCCFG |= OTG_GCCFG_NOVBUSSENS | OTG_GCCFG_PWRDWN;
OTG_FS_GCCFG &= ~(OTG_GCCFG_VBUSBSEN | OTG_GCCFG_VBUSASEN);
#endif
}
void platform_srst_set_val(bool assert) { (void)assert; }
bool platform_srst_get_val(void) { return false; }
const char *platform_target_voltage(void)
{
return NULL;
}
void platform_request_boot(void)
{
uint32_t *magic = (uint32_t *)&_ebss;
magic[0] = BOOTMAGIC0;
magic[1] = BOOTMAGIC1;
scb_reset_system();
}
#ifdef PLATFORM_HAS_POWER_SWITCH
bool platform_target_get_power(void)
{
return !gpio_get(PWR_BR_PORT, PWR_BR_PIN);
}
void platform_target_set_power(bool power)
{
gpio_set_val(PWR_BR_PORT, PWR_BR_PIN, !power);
}
#endif

View File

@ -0,0 +1,264 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2011 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* This file implements the platform specific functions for the STM32
* implementation.
*/
#ifndef __PLATFORM_H
#define __PLATFORM_H
#include "gpio.h"
#include "timing.h"
#include "timing_stm32.h"
#include <setjmp.h>
#define PLATFORM_HAS_TRACESWO
#ifdef BLACKPILL
#define PLATFORM_IDENT "(F4Discovery/BlackPillV2) "
/* Important pin mappings for STM32 implementation:
* JTAG/SWD
* PA1: TDI<br>
* PA13: TMS/SWDIO<br>
* PA14: TCK/SWCLK<br>
* PB3: TDO/TRACESWO<br>
* PB5: TRST<br>
* PB4: SRST<br>
* USB USART
* PB6: USART1 TX
* PB7: USART1 RX
* +3V3
* PB8 - turn on IRLML5103 transistor
* Force DFU mode button: PA0
*/
/* Hardware definitions... */
#define JTAG_PORT GPIOA
#define TDI_PORT JTAG_PORT
#define TMS_PORT JTAG_PORT
#define TCK_PORT JTAG_PORT
#define TDO_PORT GPIOB
#define TDI_PIN GPIO1
#define TMS_PIN GPIO13
#define TCK_PIN GPIO14
#define TDO_PIN GPIO3
#define SWDIO_PORT JTAG_PORT
#define SWCLK_PORT JTAG_PORT
#define SWDIO_PIN TMS_PIN
#define SWCLK_PIN TCK_PIN
#define TRST_PORT GPIOB
#define TRST_PIN GPIO5
#define SRST_PORT GPIOB
#define SRST_PIN GPIO4
#define PWR_BR_PORT GPIOB
#define PWR_BR_PIN GPIO8
#define LED_PORT GPIOC
#define LED_PORT_UART GPIOA
#define LED_UART GPIO1
#define LED_IDLE_RUN GPIO15
#define LED_ERROR GPIO14
#define LED_BOOTLOADER GPIO13
#define USBUSART USART1
#define USBUSART_CR1 USART1_CR1
#define USBUSART_DR USART1_DR
#define USBUSART_IRQ NVIC_USART1_IRQ
#define USBUSART_CLK RCC_USART1
#define USBUSART_PORT GPIOB
#define USBUSART_TX_PIN GPIO6
#define USBUSART_RX_PIN GPIO7
#define USBUSART_ISR(x) usart1_isr(x)
#define USBUSART_DMA_BUS DMA2
#define USBUSART_DMA_CLK RCC_DMA2
#define USBUSART_DMA_TX_CHAN DMA_STREAM7
#define USBUSART_DMA_TX_IRQ NVIC_DMA2_STREAM7_IRQ
#define USBUSART_DMA_TX_ISR(x) dma2_stream7_isr(x)
#define USBUSART_DMA_RX_CHAN DMA_STREAM5
#define USBUSART_DMA_RX_IRQ NVIC_DMA2_STREAM5_IRQ
#define USBUSART_DMA_RX_ISR(x) dma2_stream5_isr(x)
/* For STM32F4 DMA trigger source must be specified */
#define USBUSART_DMA_TRG DMA_SxCR_CHSEL_4
#else
#define PLATFORM_IDENT "(F4Discovery) "
/* Important pin mappings for STM32 implementation:
*
* LED0 = PD12 (Green LED : Running)
* LED1 = PD13 (Orange LED : Idle)
* LED2 = PD12 (Red LED : Error)
* LED3 = PD15 (Blue LED : Bootloader active)
*
* nTRST = PC1
* SRST_OUT = PC8
* TDI = PC2
* TMS = PC4 (input for SWDP)
* TCK = PC5/SWCLK
* TDO = PC6 (input for TRACESWO
* nSRST =
*
* Force DFU mode button: PA0
*/
/* Hardware definitions... */
#define JTAG_PORT GPIOC
#define TDI_PORT JTAG_PORT
#define TMS_PORT JTAG_PORT
#define TCK_PORT JTAG_PORT
#define TDO_PORT GPIOC
#define TDI_PIN GPIO2
#define TMS_PIN GPIO4
#define TCK_PIN GPIO5
#define TDO_PIN GPIO6
#define SWDIO_PORT JTAG_PORT
#define SWCLK_PORT JTAG_PORT
#define SWDIO_PIN TMS_PIN
#define SWCLK_PIN TCK_PIN
#define TRST_PORT GPIOC
#define TRST_PIN GPIO1
#define SRST_PORT GPIOC
#define SRST_PIN GPIO8
#define LED_PORT GPIOD
#define LED_PORT_UART GPIOD
#define LED_UART GPIO12
#define LED_IDLE_RUN GPIO13
#define LED_ERROR GPIO14
#define LED_BOOTLOADER GPIO15
#define USBUSART USART3
#define USBUSART_CR1 USART3_CR1
#define USBUSART_DR USART3_DR
#define USBUSART_IRQ NVIC_USART3_IRQ
#define USBUSART_CLK RCC_USART3
#define USBUSART_PORT GPIOD
#define USBUSART_TX_PIN GPIO8
#define USBUSART_RX_PIN GPIO9
#define USBUSART_ISR(x) usart3_isr(x)
#define USBUSART_DMA_BUS DMA1
#define USBUSART_DMA_CLK RCC_DMA1
#define USBUSART_DMA_TX_CHAN DMA_STREAM3
#define USBUSART_DMA_TX_IRQ NVIC_DMA1_STREAM3_IRQ
#define USBUSART_DMA_TX_ISR(x) dma1_stream3_isr(x)
#define USBUSART_DMA_RX_CHAN DMA_STREAM1
#define USBUSART_DMA_RX_IRQ NVIC_DMA1_STREAM1_IRQ
#define USBUSART_DMA_RX_ISR(x) dma1_stream1_isr(x)
/* For STM32F4 DMA trigger source must be specified */
#define USBUSART_DMA_TRG DMA_SxCR_CHSEL_4
#endif
#define BOOTMAGIC0 0xb007da7a
#define BOOTMAGIC1 0xbaadfeed
#define TMS_SET_MODE() \
gpio_mode_setup(TMS_PORT, GPIO_MODE_OUTPUT, \
GPIO_PUPD_NONE, TMS_PIN);
#define SWDIO_MODE_FLOAT() \
gpio_mode_setup(SWDIO_PORT, GPIO_MODE_INPUT, \
GPIO_PUPD_NONE, SWDIO_PIN);
#define SWDIO_MODE_DRIVE() \
gpio_mode_setup(SWDIO_PORT, GPIO_MODE_OUTPUT, \
GPIO_PUPD_NONE, SWDIO_PIN);
#define UART_PIN_SETUP() do { \
gpio_mode_setup(USBUSART_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, \
USBUSART_TX_PIN); \
gpio_set_output_options(USBUSART_PORT, GPIO_OTYPE_PP, \
GPIO_OSPEED_100MHZ, USBUSART_TX_PIN); \
gpio_set_af(USBUSART_PORT, GPIO_AF7, USBUSART_TX_PIN); \
gpio_mode_setup(USBUSART_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, \
USBUSART_RX_PIN); \
gpio_set_output_options(USBUSART_PORT, GPIO_OTYPE_OD, \
GPIO_OSPEED_100MHZ, USBUSART_RX_PIN); \
gpio_set_af(USBUSART_PORT, GPIO_AF7, USBUSART_RX_PIN); \
} while(0)
#define USB_DRIVER stm32f107_usb_driver
#define USB_IRQ NVIC_OTG_FS_IRQ
#define USB_ISR(x) otg_fs_isr(x)
/* Interrupt priorities. Low numbers are high priority.
* TIM3 is used for traceswo capture and must be highest priority.
*/
#define IRQ_PRI_USB (1 << 4)
#define IRQ_PRI_USBUSART (2 << 4)
#define IRQ_PRI_USBUSART_DMA (2 << 4)
#define IRQ_PRI_TRACE (0 << 4)
#define TRACE_TIM TIM3
#define TRACE_TIM_CLK_EN() rcc_periph_clock_enable(RCC_TIM3)
#define TRACE_IRQ NVIC_TIM3_IRQ
#define TRACE_ISR(x) tim3_isr(x)
#define gpio_set_val(port, pin, val) do { \
if(val) \
gpio_set((port), (pin)); \
else \
gpio_clear((port), (pin)); \
} while(0)
#define SET_RUN_STATE(state) {running_status = (state);}
#define SET_IDLE_STATE(state) {gpio_set_val(LED_PORT, LED_IDLE_RUN, state);}
#define SET_ERROR_STATE(state) {gpio_set_val(LED_PORT, LED_ERROR, state);}
static inline int platform_hwversion(void)
{
return 0;
}
/*
* Use newlib provided integer only stdio functions
*/
/* sscanf */
#ifdef sscanf
#undef sscanf
#define sscanf siscanf
#else
#define sscanf siscanf
#endif
/* sprintf */
#ifdef sprintf
#undef sprintf
#define sprintf siprintf
#else
#define sprintf siprintf
#endif
/* vasprintf */
#ifdef vasprintf
#undef vasprintf
#define vasprintf vasiprintf
#else
#define vasprintf vasiprintf
#endif
/* snprintf */
#ifdef snprintf
#undef snprintf
#define snprintf sniprintf
#else
#define snprintf sniprintf
#endif
#endif

View File

@ -0,0 +1,73 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2013 Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include <libopencm3/cm3/systick.h>
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/cm3/scb.h>
#include "usbdfu.h"
#include "general.h"
#include "platform.h"
uint32_t app_address = 0x08004000;
extern char _ebss[];
void dfu_detach(void)
{
scb_reset_system();
}
int main(void)
{
volatile uint32_t *magic = (uint32_t *)_ebss;
rcc_periph_clock_enable(RCC_GPIOA);
if (gpio_get(GPIOA, GPIO0) ||
((magic[0] == BOOTMAGIC0) && (magic[1] == BOOTMAGIC1))) {
magic[0] = 0;
magic[1] = 0;
} else {
dfu_jump_app_if_valid();
}
rcc_clock_setup_pll(&rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_168MHZ]);
/* Assert blue LED as indicator we are in the bootloader */
rcc_periph_clock_enable(RCC_GPIOD);
gpio_mode_setup(LED_PORT, GPIO_MODE_OUTPUT,
GPIO_PUPD_NONE, LED_BOOTLOADER);
gpio_set(LED_PORT, LED_BOOTLOADER);
/* Enable peripherals */
rcc_periph_clock_enable(RCC_OTGFS);
/* Set up USB Pins and alternate function*/
gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO11 | GPIO12);
gpio_set_af(GPIOA, GPIO_AF10, GPIO11 | GPIO12);
dfu_protect(false);
dfu_init(&USB_DRIVER);
dfu_main();
}
void dfu_event(void)
{
}

View File

@ -0,0 +1,85 @@
CC ?= gcc
SYS = $(shell $(CC) -dumpmachine)
CFLAGS += -DENABLE_DEBUG -DPLATFORM_HAS_DEBUG
CFLAGS +=-I ./target -I./platforms/pc
# Define HOSTED_BMP_ONLY to '0' in order to build the hosted blackmagic
# executable with support for other probes beside BMP. Default HOSTED_BMP_ONLY
# == 1 on Windows makes linking against the libftdi and libusb libraries
# unnecessary.
# This can be useful to minimize external dependencies, and make building on
# windows systems easier and is default now.
ifneq (, $(findstring linux, $(SYS)))
HOSTED_BMP_ONLY ?= 0
else
HOSTED_BMP_ONLY ?= 1
endif
CFLAGS += -DHOSTED_BMP_ONLY=$(HOSTED_BMP_ONLY)
ifneq (, $(findstring linux, $(SYS)))
SRC += serial_unix.c
HIDAPILIB = hidapi-hidraw
ifeq ($(ASAN), 1)
CFLAGS += -fsanitize=address -Wno-format-truncation
LDFLAGS += -lasan
endif
else ifneq (, $(findstring mingw, $(SYS)))
# Build for windows versions Vista, and above, where the
# 'SetupDiGetDevicePropertyW()' function is available
CFLAGS += -D_WIN32_WINNT=0x600
SRC += serial_win.c
LDFLAGS += -lws2_32
LDFLAGS += -lsetupapi
else ifneq (, $(findstring cygwin, $(SYS)))
# Build for windows versions Vista, and above, where the
# 'SetupDiGetDevicePropertyW()' function is available
CFLAGS += -D_WIN32_WINNT=0x600
SRC += serial_win.c
LDFLAGS += -lws2_32
LDFLAGS += -lsetupapi
#https://github.com/dmlc/xgboost/issues/1945 indicates macosx as indicator
else ifneq (filter, macosx darwin, $(SYS))
SRC += serial_unix.c
LDFLAGS += -lhidapi
LDFLAGS += -framework CoreFoundation
CFLAGS += -Ihidapi/hidapi
HIDAPILIB = hidapi
endif
ifneq ($(HOSTED_BMP_ONLY), 1)
$(shell pkg-config --exists libftdi1)
ifneq ($(.SHELLSTATUS), 0)
$(error Please install libftdi1 dependency or set HOSTED_BMP_ONLY to 1)
endif
LDFLAGS += -lusb-1.0
CFLAGS += $(shell pkg-config --cflags libftdi1)
LDFLAGS += $(shell pkg-config --libs libftdi1)
CFLAGS += -Wno-missing-field-initializers
endif
ifneq ($(HOSTED_BMP_ONLY), 1)
CFLAGS += -DCMSIS_DAP
SRC += cmsis_dap.c dap.c
ifneq (, $(findstring mingw, $(SYS)))
SRC += hid.c
else
$(shell pkg-config --exists $(HIDAPILIB))
ifneq ($(.SHELLSTATUS), 0)
$(error Please install $(HIDAPILIB) dependency or set HOSTED_BMP_ONLY to 1)
endif
CFLAGS += $(shell pkg-config --cflags $(HIDAPILIB))
LDFLAGS += $(shell pkg-config --libs $(HIDAPILIB))
endif
endif
VPATH += platforms/pc
SRC += timing.c cl_utils.c utils.c
SRC += bmp_remote.c remote_swdptap.c remote_jtagtap.c
ifneq ($(HOSTED_BMP_ONLY), 1)
SRC += bmp_libusb.c stlinkv2.c
SRC += ftdi_bmp.c libftdi_swdptap.c libftdi_jtagtap.c
SRC += jlink.c jlink_adiv5_swdp.c jlink_jtagtap.c
else
SRC += bmp_serial.c
endif
PC_HOSTED = 1

View File

@ -0,0 +1,177 @@
# PC-Hosted BMP
Compile in src with "make PROBE_HOST=hosted". This needs minimal external
support. "make PROBE_HOST=hosted HOSTED_BMP_ONLY=0" will compile support for FTDI,
STLink, CMSIS-DAP and JLINK probes, but requires external libraries.
## Description
PC-hosted BMP run on the PC and compiles as "blackmagic". When started,
it either presents a list of available probes or starts the BMP process
if either only one probe is attached to the PC or enough information is
given on the command line to select one of several probes.
When started without any other argument beside the probe selection, a
GDB server is started on port 2000 and up. Connect to the server as you would
connect to the BMP with the CDCACM GDB serial server. GDB functionality
is the same, monitor option may vary.
More arguments allow to
### Print information on the connected target
```
blackmagic -t
```
### Directly flash a binary file at lowest flash address
```
blackmagic <file.bin>
```
or with the -S argument at some other address
```
blackmagic -S 0x08002000 <file.bin>
```
### Read flash to binary file
```
blackmagic -r <file>.bin
```
### Verify flash against binary file
```
blackmagic -V <file>.bin
```
### Show more options
```
blackmagic -h
```
### Show available monitor commands
```
blackmagic -M help
```
### Show available monitor commands on second target
```
blackmagic -n 2 -M help
```
### Monitor commands with multiple arguments, e.g.Stm32F1:
```
blackmagic -M "option help"
```
## Used shared libraries:
### libusb
### libftdi, for FTDI support
## Other used libraries:
### hidapi-libusb, for CMSIS-DAP support
## Compiling on windows
You can crosscompile blackmagic for windows with mingw or on windows
with cygwin. For suppport of other probes beside BMP, headers for libftdi1 and
libusb-1.0 are needed. For running, libftdi1.dll and libusb-1.0.dll are needed
and the executable must be able to find them. Mingw on cygwin does not provide
a libftdi package yet.
PC-hosted BMP for windows can also be built with [MSYS2](https://www.msys2.org/),
in windows. Make sure to use the `mingw64` shell from msys2, otherwise,
you may get compilation errors. You will need to install the libusb
and libftdi libraries, and have the correct mingw compiler.
You can use these commands to install dependencies, and build PC-hosted BMP
from a mingw64 shell, from within the `src` directory:
```
pacman -S mingw-w64-x86_64-libusb --needed
pacman -S mingw-w64-x86_64-libftdi --needed
pacman -S mingw-w64-x86_64-gcc --needed
PROBE_HOST=hosted make
```
For suppport of other probes beside BMP, libusb access is needed. To prepare
libusb access to the ftdi/stlink/jlink/cmsis-dap devices, run zadig
https://zadig.akeo.ie/. Choose WinUSB(libusb-1.0).
Running cygwin/blackmagic in a cygwin console, the program does not react
on ^C. In another console, run "ps ax" to find the WINPID of the process
and then "taskkill /F ?PID (WINPID)".
## Supported debuggers
REMOTE_BMP is a "normal" BMP usb connected
| Debugger | Speed | Remarks
| ------------ | ----- | ------
| REMOTE_BMP | +++ | Requires recent firmware for decent speed
Probes below only when compiled with HOSTED_BMP_ONLY=0
| ST-Link V3 | ++++ | Requires recent firmware, Only STM32 devices supported!
| ST-Link V2 | +++ | Requires recent firmware, No CDCACM uart! Cortex only!
| ST-Link V2/1 | +++ | Requires recent firmware, Cortex only!
| CMSIS-DAP | +++ | Speed varies with MCU implementing CMSIS-DAP
| FTDI MPSSE | ++ | Requires a device descrition
| JLINK | - | Usefull to add BMP support for MCUs with built-in JLINK
## Device matching
As other USB dongles already connected to the host PC may use FTDI chips,
cable descriptions must be provided to match with the dongle.
To match the dongle, at least USB VID/PID that must match.
If a description is given, the USB device must provide that string. If a
serial number string is given on the command line, that number must match
with serial number in the USB descriptor of the device.
## FTDI connection possibilities:
| Direct Connection |
| ----------------------|
| MPSSE_SK --> JTAG_TCK |
| MPSSE_DO --> JTAG_TDI |
| MPSSE_DI <-- JTAG_TDO |
| MPSSE_CS <-> JTAG_TMS |
\+ JTAG and bitbanging SWD is possible<br>
\- No level translation, no buffering, no isolation<br>
Example: [Flossjtag](https://randomprojects.org/wiki/Floss-JTAG).
| Resistor SWD |
|------------------------|
| MPSSE_SK ---> JTAG_TCK |
| MPSSE_DO -R-> JTAG_TMS |
| MPSSE_DI <--- JTAG_TMS |
BMP would allow direct MPSSE_DO ->JTAG_TMS connections as BMP tristates DO
when reading. Resistor defeats contentions anyways. R is typical choosen
in the range of 470R
\+ MPSSE SWD possible<br>
\- No Jtag, no level translation, no buffering, no isolation<br>
|Direct buffered Connection|
|--------------------------|
| MPSSE_SK -B-> JTAG_TCK |
| MPSSE_DO -B-> JTAG_TDI |
| MPSSE_DI <-B- JTAG_TDO |
| MPSSE_CS -B-> JTAG_TMS |
\+ Only Jtag, buffered, possible level translation and isolation<br>
\- No SWD<br>
Example: [Turtelizer]http://www.ethernut.de/en/hardware/turtelizer/index.html)
[schematics](http://www.ethernut.de/pdf/turtelizer20c-schematic.pdf)
The 'r' command line arguments allows to specify an external SWD
resistor connection added to some existing cable. Jtag is not possible
together with the 'r' argument.
### Many variants possible
As the FTDI has more pins, these pins may be used to control
enables of buffers and multiplexer selection in many variants.
### FTDI SWD speed
SWD read needs two USB round trip, one for the acknowledge and one
round-trip after the data phase, while JTAG only needs one round-trip.
For that, SWD read speed is about half the JTAG read speed.
### Reset, Target voltage readback etc
The additional pins may also control Reset functionality, provide
information if target voltage is applied. etc.
### Cable descriptions
Please help to verify the cable description and give feedback on the
cables already listed and propose other cable. A link to the schematics
is welcome.
## Feedback
### Issues and Pull request on https://github.com/blackmagic-debug/blackmagic/
### Discussions on Discord.
You can find the Discord link here: https://1bitsquared.com/pages/chat
### Blackmagic mailing list http://sourceforge.net/mail/?group_id=407419

View File

@ -0,0 +1,52 @@
#if !defined(__BMP_LIBUSB_H)
#define __BMP_LIBUSB_H
#include "cl_utils.h"
#if HOSTED_BMP_ONLY != 1
# include <libusb-1.0/libusb.h>
struct trans_ctx {
#define TRANS_FLAGS_IS_DONE (1 << 0)
#define TRANS_FLAGS_HAS_ERROR (1 << 1)
volatile unsigned long flags;
};
typedef struct usb_link_s {
libusb_context *ul_libusb_ctx;
libusb_device_handle *ul_libusb_device_handle;
unsigned char ep_tx;
unsigned char ep_rx;
struct libusb_transfer* req_trans;
struct libusb_transfer* rep_trans;
void *priv;
} usb_link_t;
int send_recv(usb_link_t *link, uint8_t *txbuf, size_t txsize,
uint8_t *rxbuf, size_t rxsize);
#endif
typedef struct bmp_info_s {
bmp_type_t bmp_type;
char dev;
char serial[64];
char manufacturer[512];
char product[256];
char version[256];
bool is_jtag;
#if HOSTED_BMP_ONLY != 1
libusb_context *libusb_ctx;
struct ftdi_context *ftdic;
usb_link_t *usb_link;
unsigned int vid;
unsigned int pid;
uint8_t interface_num;
uint8_t in_ep;
uint8_t out_ep;
#endif
} bmp_info_t;
extern bmp_info_t info;
void bmp_ident(bmp_info_t *info);
int find_debuggers(BMP_CL_OPTIONS_t *cl_opts,bmp_info_t *info);
void libusb_exit_function(bmp_info_t *info);
#endif

View File

@ -0,0 +1,473 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright(C) 2020 - 2022 Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Find all known usb connected debuggers */
#include "general.h"
#include "libusb-1.0/libusb.h"
#include "cl_utils.h"
#include "ftdi_bmp.h"
#include "version.h"
#define NO_SERIAL_NUMBER "<no serial number>"
void bmp_ident(bmp_info_t *info)
{
DEBUG_INFO("BMP hosted %s\n for ST-Link V2/3, CMSIS_DAP, JLINK and "
"LIBFTDI/MPSSE\n", FIRMWARE_VERSION);
if (info && info->vid && info->pid)
DEBUG_INFO("Using %04x:%04x %s %s\n %s\n", info->vid, info->pid,
(info->serial[0]) ? info->serial : NO_SERIAL_NUMBER,
info->manufacturer,
info->product);
}
void libusb_exit_function(bmp_info_t *info)
{
if (!info->usb_link)
return;
libusb_free_transfer(info->usb_link->req_trans);
libusb_free_transfer(info->usb_link->rep_trans);
if (info->usb_link->ul_libusb_device_handle) {
libusb_release_interface (
info->usb_link->ul_libusb_device_handle, 0);
libusb_close(info->usb_link->ul_libusb_device_handle);
}
}
static bmp_type_t find_cmsis_dap_interface(libusb_device *dev,bmp_info_t *info) {
bmp_type_t type = BMP_TYPE_NONE;
struct libusb_config_descriptor *conf;
char interface_string[128];
int res = libusb_get_active_config_descriptor(dev, &conf);
if (res < 0) {
DEBUG_WARN( "WARN: libusb_get_active_config_descriptor() failed: %s",
libusb_strerror(res));
return type;
}
libusb_device_handle *handle;
res = libusb_open(dev, &handle);
if (res != LIBUSB_SUCCESS) {
DEBUG_INFO("INFO: libusb_open() failed: %s\n",
libusb_strerror(res));
libusb_free_config_descriptor(conf);
return type;
}
for (int i = 0; i < conf->bNumInterfaces; i++) {
const struct libusb_interface_descriptor *interface = &conf->interface[i].altsetting[0];
if (!interface->iInterface) {
continue;
}
res = libusb_get_string_descriptor_ascii(
handle, interface->iInterface, (uint8_t*)interface_string,
sizeof(interface_string));
if (res < 0) {
DEBUG_WARN( "WARN: libusb_get_string_descriptor_ascii() failed: %s\n",
libusb_strerror(res));
continue;
}
if (!strstr(interface_string, "CMSIS")) {
continue;
}
type = BMP_TYPE_CMSIS_DAP;
if (interface->bInterfaceClass == 0xff && interface->bNumEndpoints == 2) {
info->interface_num = interface->bInterfaceNumber;
for (int j = 0; j < interface->bNumEndpoints; j++) {
uint8_t n = interface->endpoint[j].bEndpointAddress;
if (n & 0x80) {
info->in_ep = n;
} else {
info->out_ep = n;
}
}
/* V2 is preferred, return early. */
break;
}
}
libusb_free_config_descriptor(conf);
return type;
}
int find_debuggers(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info)
{
libusb_device **devs;
int res = libusb_init(&info->libusb_ctx);
if (res) {
DEBUG_WARN( "Fatal: Failed to get USB context: %s\n",
libusb_strerror(res));
exit(-1);
}
if (cl_opts->opt_cable) {
if (!strcmp(cl_opts->opt_cable, "list") ||
!strcmp(cl_opts->opt_cable, "l")) {
cable_desc_t *cable = cable_desc;
DEBUG_WARN("Available cables:\n");
for (; cable->name; ++cable) {
DEBUG_WARN("\t%s\n", cable->name);
}
exit(0);
}
info->bmp_type = BMP_TYPE_LIBFTDI;
}
int n_devs = libusb_get_device_list(info->libusb_ctx, &devs);
if (n_devs < 0) {
DEBUG_WARN( "WARN:libusb_get_device_list() failed");
return -1;
}
bool report = false;
int found_debuggers;
struct libusb_device_descriptor desc;
char serial[64];
char manufacturer[128];
char product[128];
bool access_problems = false;
char *active_cable = NULL;
bool ftdi_unknown = false;
rescan:
found_debuggers = 0;
serial[0] = 0;
manufacturer[0] = 0;
product[0] = 0;
access_problems = false;
active_cable = NULL;
ftdi_unknown = false;
for (size_t i = 0; devs[i]; ++i) {
bmp_type_t type = BMP_TYPE_NONE;
libusb_device *dev = devs[i];
int res = libusb_get_device_descriptor(dev, &desc);
if (res < 0) {
DEBUG_WARN( "WARN: libusb_get_device_descriptor() failed: %s",
libusb_strerror(res));
libusb_free_device_list(devs, 1);
continue;
}
/* Exclude hubs from testing. Probably more classes could be excluded here!*/
switch (desc.bDeviceClass) {
case LIBUSB_CLASS_HUB:
case LIBUSB_CLASS_WIRELESS:
continue;
}
libusb_device_handle *handle = NULL;
res = libusb_open(dev, &handle);
if (res != LIBUSB_SUCCESS) {
if (!access_problems) {
DEBUG_INFO("INFO: Open USB %04x:%04x class %2x failed\n",
desc.idVendor, desc.idProduct, desc.bDeviceClass);
access_problems = true;
}
continue;
}
/* If the device even has a serial number string, fetch it */
if (desc.iSerialNumber) {
res = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber,
(uint8_t *)serial, sizeof(serial));
/* If the call fails and it's not because the device gave us STALL, continue to the next one */
if (res < 0 && res != LIBUSB_ERROR_PIPE) {
libusb_close(handle);
continue;
}
/* Device has no serial and that's ok. */
else if (res <= 0)
serial[0] = '\0';
}
else
serial[0] = '\0';
if (cl_opts->opt_serial && !strstr(serial, cl_opts->opt_serial)) {
libusb_close(handle);
continue;
}
/* Attempt to get the manufacturer string */
if (desc.iManufacturer) {
res = libusb_get_string_descriptor_ascii(handle, desc.iManufacturer,
(uint8_t *)manufacturer, sizeof(manufacturer));
/* If the call fails and it's not because the device gave us STALL, continue to the next one */
if (res < 0 && res != LIBUSB_ERROR_PIPE) {
DEBUG_WARN("WARN: libusb_get_string_descriptor_ascii() call to fetch manufacturer string failed: %s\n",
libusb_strerror(res));
libusb_close(handle);
continue;
}
/* Device has no manufacturer string and that's ok. */
else if (res <= 0)
manufacturer[0] = '\0';
}
else
manufacturer[0] = '\0';
/* Attempt to get the product string */
if (desc.iProduct) {
res = libusb_get_string_descriptor_ascii(handle, desc.iProduct,
(uint8_t *)product, sizeof(product));
/* If the call fails and it's not because the device gave us STALL, continue to the next one */
if (res < 0 && res != LIBUSB_ERROR_PIPE) {
DEBUG_WARN("WARN: libusb_get_string_descriptor_ascii() call to fetch product string failed: %s\n",
libusb_strerror(res));
libusb_close(handle);
continue;
}
/* Device has no product string and that's ok. */
else if (res <= 0)
product[0] = '\0';
}
else
product[0] = '\0';
libusb_close(handle);
if (cl_opts->opt_ident_string) {
char *match_manu = NULL;
char *match_product = NULL;
match_manu = strstr(manufacturer, cl_opts->opt_ident_string);
match_product = strstr(product, cl_opts->opt_ident_string);
if (!match_manu && !match_product)
continue;
}
/* Either serial and/or ident_string match or are not given.
* Check type.*/
if (desc.idVendor == VENDOR_ID_BMP) {
if (desc.idProduct == PRODUCT_ID_BMP)
type = BMP_TYPE_BMP;
else {
if (desc.idProduct == PRODUCT_ID_BMP_BL)
DEBUG_WARN("BMP in bootloader mode found. Restart or reflash!\n");
continue;
}
} else if (type == BMP_TYPE_NONE &&
(type = find_cmsis_dap_interface(dev, info)) != BMP_TYPE_NONE) {
/* find_cmsis_dap_interface has set valid type*/
} else if (strstr(manufacturer, "CMSIS") || strstr(product, "CMSIS"))
type = BMP_TYPE_CMSIS_DAP;
else if (desc.idVendor == VENDOR_ID_STLINK) {
if (desc.idProduct == PRODUCT_ID_STLINKV2 ||
desc.idProduct == PRODUCT_ID_STLINKV21 ||
desc.idProduct == PRODUCT_ID_STLINKV21_MSD ||
desc.idProduct == PRODUCT_ID_STLINKV3_NO_MSD ||
desc.idProduct == PRODUCT_ID_STLINKV3_BL ||
desc.idProduct == PRODUCT_ID_STLINKV3 ||
desc.idProduct == PRODUCT_ID_STLINKV3E)
type = BMP_TYPE_STLINKV2;
else {
if (desc.idProduct == PRODUCT_ID_STLINKV1)
DEBUG_WARN( "INFO: STLINKV1 not supported\n");
continue;
}
} else if (desc.idVendor == VENDOR_ID_SEGGER)
type = BMP_TYPE_JLINK;
else {
cable_desc_t *cable = cable_desc;
for (; cable->name; ++cable) {
bool found = false;
if (cable->vendor != desc.idVendor || cable->product != desc.idProduct)
continue; /* VID/PID do not match*/
if (cl_opts->opt_cable) {
if (strncmp(cable->name, cl_opts->opt_cable, strlen(cable->name)))
continue; /* cable names do not match*/
else
found = true;
}
if (cable->description) {
if (strncmp(cable->description, product, strlen(cable->description)))
continue; /* discriptions do not match*/
else
found = true;
} else { /* VID/PID fits, but no cl_opts->opt_cable and no description*/
if (cable->vendor == 0x0403 && /* FTDI*/
(cable->product == 0x6010 || /* FT2232C/D/H*/
cable->product == 0x6011 || /* FT4232H Quad HS USB-UART/FIFO IC */
cable->product == 0x6014)) { /* FT232H Single HS USB-UART/FIFO IC */
ftdi_unknown = true;
continue; /* Cable name is needed */
}
}
if (found) {
active_cable = cable->name;
type = BMP_TYPE_LIBFTDI;
break;
}
}
if (!cable->name)
continue;
}
if (report) {
DEBUG_WARN("%2d: %s, %s, %s\n", found_debuggers + 1,
serial[0] ? serial : NO_SERIAL_NUMBER,
manufacturer,product);
}
info->vid = desc.idVendor;
info->pid = desc.idProduct;
info->bmp_type = type;
strncpy(info->serial, serial, sizeof(info->serial));
strncpy(info->product, product, sizeof(info->product));
strncpy(info->manufacturer, manufacturer, sizeof(info->manufacturer));
if (cl_opts->opt_position &&
cl_opts->opt_position == found_debuggers + 1) {
found_debuggers = 1;
break;
} else
++found_debuggers;
}
if (found_debuggers == 0 && ftdi_unknown)
DEBUG_WARN("Generic FTDI MPSSE VID/PID found. Please specify exact type with \"-c <cable>\" !\n");
if (found_debuggers == 1 && !cl_opts->opt_cable && info->bmp_type == BMP_TYPE_LIBFTDI)
cl_opts->opt_cable = active_cable;
if (!found_debuggers && cl_opts->opt_list_only)
DEBUG_WARN("No usable debugger found\n");
if (found_debuggers > 1 ||
(found_debuggers == 1 && cl_opts->opt_list_only)) {
if (!report) {
if (found_debuggers > 1)
DEBUG_WARN("%d debuggers found!\nSelect with -P <pos> "
"or -s <(partial)serial no.>\n",
found_debuggers);
report = true;
goto rescan;
} else {
if (found_debuggers > 0)
access_problems = false;
found_debuggers = 0;
}
}
if (!found_debuggers && access_problems)
DEBUG_WARN(
"No debugger found. Please check access rights to USB devices!\n");
libusb_free_device_list(devs, 1);
return found_debuggers == 1 ? 0 : -1;
}
static void LIBUSB_CALL on_trans_done(struct libusb_transfer *trans)
{
struct trans_ctx * const ctx = trans->user_data;
if (trans->status != LIBUSB_TRANSFER_COMPLETED)
{
DEBUG_WARN("on_trans_done: ");
if (trans->status == LIBUSB_TRANSFER_TIMED_OUT)
DEBUG_WARN(" Timeout\n");
else if (trans->status == LIBUSB_TRANSFER_CANCELLED)
DEBUG_WARN(" cancelled\n");
else if (trans->status == LIBUSB_TRANSFER_NO_DEVICE)
DEBUG_WARN(" no device\n");
else
DEBUG_WARN(" unknown\n");
ctx->flags |= TRANS_FLAGS_HAS_ERROR;
}
ctx->flags |= TRANS_FLAGS_IS_DONE;
}
static int submit_wait(usb_link_t *link, struct libusb_transfer *trans) {
struct trans_ctx trans_ctx;
enum libusb_error error;
trans_ctx.flags = 0;
/* brief intrusion inside the libusb interface */
trans->callback = on_trans_done;
trans->user_data = &trans_ctx;
if ((error = libusb_submit_transfer(trans))) {
DEBUG_WARN("libusb_submit_transfer(%d): %s\n", error,
libusb_strerror(error));
exit(-1);
}
uint32_t start_time = platform_time_ms();
while (trans_ctx.flags == 0) {
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
if (libusb_handle_events_timeout(link->ul_libusb_ctx, &timeout)) {
DEBUG_WARN("libusb_handle_events()\n");
return -1;
}
uint32_t now = platform_time_ms();
if (now - start_time > 1000) {
libusb_cancel_transfer(trans);
DEBUG_WARN("libusb_handle_events() timeout\n");
return -1;
}
}
if (trans_ctx.flags & TRANS_FLAGS_HAS_ERROR) {
DEBUG_WARN("libusb_handle_events() | has_error\n");
return -1;
}
return 0;
}
/* One USB transaction */
int send_recv(usb_link_t *link,
uint8_t *txbuf, size_t txsize,
uint8_t *rxbuf, size_t rxsize)
{
int res = 0;
if (txsize) {
libusb_fill_bulk_transfer(link->req_trans,
link->ul_libusb_device_handle,
link->ep_tx | LIBUSB_ENDPOINT_OUT,
txbuf, txsize,
NULL, NULL, 0);
size_t i = 0;
DEBUG_WIRE(" Send (%3zu): ", txsize);
for (; i < txsize; ++i) {
DEBUG_WIRE("%02x", txbuf[i]);
if ((i & 7U) == 7U)
DEBUG_WIRE(".");
if ((i & 31U) == 31U)
DEBUG_WIRE("\n ");
}
if (!(i & 31U))
DEBUG_WIRE("\n");
if (submit_wait(link, link->req_trans)) {
libusb_clear_halt(link->ul_libusb_device_handle, link->ep_tx);
return -1;
}
}
/* send_only */
if (rxsize != 0) {
/* read the response */
libusb_fill_bulk_transfer(link->rep_trans, link->ul_libusb_device_handle,
link->ep_rx | LIBUSB_ENDPOINT_IN,
rxbuf, rxsize, NULL, NULL, 0);
if (submit_wait(link, link->rep_trans)) {
DEBUG_WARN("clear 1\n");
libusb_clear_halt(link->ul_libusb_device_handle, link->ep_rx);
return -1;
}
res = link->rep_trans->actual_length;
if (res > 0) {
const size_t rxlen = (size_t)res;
DEBUG_WIRE(" Rec (%zu/%zu)", rxsize, rxlen);
for (size_t i = 0; i < rxlen && i < 32 ; ++i) {
if (i && ((i & 7U) == 0U))
DEBUG_WIRE(".");
DEBUG_WIRE("%02x", rxbuf[i]);
}
}
}
DEBUG_WIRE("\n");
return res;
}

View File

@ -0,0 +1,404 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2011 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
* Additions by Dave Marples <dave@marples.net>
* Modifications (C) 2020 Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "general.h"
#include "gdb_if.h"
#include "version.h"
#include "remote.h"
#include "target.h"
#include "bmp_remote.h"
#include "cl_utils.h"
#include "hex_utils.h"
#include <assert.h>
#include <sys/time.h>
#include <sys/time.h>
#include <errno.h>
#include "adiv5.h"
int remote_init(void)
{
char construct[REMOTE_MAX_MSG_SIZE];
int c = snprintf(construct, REMOTE_MAX_MSG_SIZE, "%s", REMOTE_START_STR);
platform_buffer_write((uint8_t *)construct, c);
c = platform_buffer_read((uint8_t *)construct, REMOTE_MAX_MSG_SIZE);
if ((c < 1) || (construct[0] == REMOTE_RESP_ERR)) {
DEBUG_WARN("Remote Start failed, error %s\n",
c ? (char *)&(construct[1]) : "unknown");
return -1;
}
DEBUG_PROBE("Remote is %s\n", &construct[1]);
return 0;
}
bool remote_target_get_power(void)
{
uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s;
s=snprintf((char *)construct, REMOTE_MAX_MSG_SIZE, "%s",
REMOTE_PWR_GET_STR);
platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((s < 1) || (construct[0] == REMOTE_RESP_ERR)) {
DEBUG_WARN(" platform_target_get_power failed, error %s\n",
s ? (char *)&(construct[1]) : "unknown");
exit (-1);
}
return (construct[1] == '1');
}
bool remote_target_set_power(bool power)
{
uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s;
s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE,REMOTE_PWR_SET_STR,
power ? '1' : '0');
platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((s < 1) || (construct[0] == REMOTE_RESP_ERR)) {
DEBUG_WARN("platform_target_set_power failed, error %s\n",
s ? (char *)&(construct[1]) : "unknown");
return false;
}
return true;
}
void remote_srst_set_val(bool assert)
{
uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s;
s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE, REMOTE_SRST_SET_STR,
assert ? '1' : '0');
platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((s < 1) || (construct[0] == REMOTE_RESP_ERR)) {
DEBUG_WARN("platform_srst_set_val failed, error %s\n",
s ? (char *)&(construct[1]) : "unknown");
exit(-1);
}
}
bool remote_srst_get_val(void)
{
uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s;
s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE,"%s",
REMOTE_SRST_GET_STR);
platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((s < 1) || (construct[0] == REMOTE_RESP_ERR)) {
DEBUG_WARN("platform_srst_set_val failed, error %s\n",
s ? (char *)&(construct[1]) : "unknown");
exit(-1);
}
return (construct[1] == '1');
}
void remote_max_frequency_set(uint32_t freq)
{
uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s;
s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE, REMOTE_FREQ_SET_STR,
freq);
platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((s < 1) || (construct[0] == REMOTE_RESP_ERR)) {
DEBUG_WARN("Update Firmware to allow to set max SWJ frequency\n");
}
}
uint32_t remote_max_frequency_get(void)
{
uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s;
s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE,"%s",
REMOTE_FREQ_GET_STR);
platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((s < 1) || (construct[0] == REMOTE_RESP_ERR))
return FREQ_FIXED;
uint32_t freq[1];
unhexify(freq, (const char*)&construct[1], 4);
return freq[0];
}
const char *remote_target_voltage(void)
{
static uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s;
s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE," %s",
REMOTE_VOLTAGE_STR);
platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((s < 1) || (construct[0] == REMOTE_RESP_ERR)) {
DEBUG_WARN("platform_target_voltage failed, error %s\n",
s ? (char *)&(construct[1]) : "unknown");
exit(- 1);
}
return (char *)&construct[1];
}
static uint32_t remote_adiv5_dp_read(ADIv5_DP_t *dp, uint16_t addr)
{
(void)dp;
uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE, REMOTE_DP_READ_STR,
dp->dp_jd_index, addr);
platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((s < 1) || (construct[0] == REMOTE_RESP_ERR)) {
DEBUG_WARN("%s error %d\n", __func__, s);
}
uint32_t dest[1];
unhexify(dest, (const char*)&construct[1], 4);
DEBUG_PROBE("dp_read addr %04x: %08" PRIx32 "\n", dest[0]);
return dest[0];
}
static uint32_t remote_adiv5_low_access(
ADIv5_DP_t *dp, uint8_t RnW, uint16_t addr, uint32_t value)
{
(void)dp;
uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE,
REMOTE_LOW_ACCESS_STR, dp->dp_jd_index, RnW, addr, value);
platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((s < 1) || (construct[0] == REMOTE_RESP_ERR)) {
DEBUG_WARN("%s error %d\n", __func__, s);
}
uint32_t dest[1];
unhexify(dest, (const char*)&construct[1], 4);
return dest[0];
}
static uint32_t remote_adiv5_ap_read(ADIv5_AP_t *ap, uint16_t addr)
{
uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE,REMOTE_AP_READ_STR,
ap->dp->dp_jd_index, ap->apsel, addr);
platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((s < 1) || (construct[0] == REMOTE_RESP_ERR)) {
DEBUG_WARN("%s error %d\n", __func__, s);
}
uint32_t dest[1];
unhexify(dest, (const char*)&construct[1], 4);
return dest[0];
}
static void remote_adiv5_ap_write(ADIv5_AP_t *ap, uint16_t addr, uint32_t value)
{
uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE,REMOTE_AP_WRITE_STR,
ap->dp->dp_jd_index, ap->apsel, addr, value);
platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((s < 1) || (construct[0] == REMOTE_RESP_ERR)) {
DEBUG_WARN("%s error %d\n", __func__, s);
}
return;
}
#if 0
static void remote_mem_read(
ADIv5_AP_t *ap, void *dest, uint32_t src, size_t len)
{
(void)ap;
if (len == 0)
return;
DEBUG_WIRE("memread @ %" PRIx32 " len %ld, start: \n",
src, len);
uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s;
int batchsize = (REMOTE_MAX_MSG_SIZE - 32) / 2;
while(len) {
int count = len;
if (count > batchsize)
count = batchsize;
s = snprintf(construct, REMOTE_MAX_MSG_SIZE,
REMOTE_MEM_READ_STR, src, count);
platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((s > 0) && (construct[0] == REMOTE_RESP_OK)) {
unhexify(dest, (const char*)&construct[1], count);
src += count;
dest += count;
len -= count;
continue;
} else {
if(construct[0] == REMOTE_RESP_ERR) {
ap->dp->fault = 1;
DEBUG_WARN("%s returned REMOTE_RESP_ERR at addr: 0x%08x\n",
__func__, src);
break;
} else {
DEBUG_WARN("%s error %d\n", __func__, s);
break;
}
}
}
}
#endif
static void remote_ap_mem_read(
ADIv5_AP_t *ap, void *dest, uint32_t src, size_t len)
{
(void)ap;
if (len == 0)
return;
char construct[REMOTE_MAX_MSG_SIZE];
int batchsize = (REMOTE_MAX_MSG_SIZE - 0x20) / 2;
while(len) {
int s;
int count = len;
if (count > batchsize)
count = batchsize;
s = snprintf(construct, REMOTE_MAX_MSG_SIZE,
REMOTE_AP_MEM_READ_STR, ap->dp->dp_jd_index, ap->apsel, ap->csw, src, count);
platform_buffer_write((uint8_t*)construct, s);
s = platform_buffer_read((uint8_t*)construct, REMOTE_MAX_MSG_SIZE);
if ((s > 0) && (construct[0] == REMOTE_RESP_OK)) {
unhexify(dest, (const char*)&construct[1], count);
src += count;
dest += count;
len -= count;
continue;
} else {
if(construct[0] == REMOTE_RESP_ERR) {
ap->dp->fault = 1;
DEBUG_WARN("%s returned REMOTE_RESP_ERR at apsel %d, "
"addr: 0x%08" PRIx32 "\n", __func__, ap->apsel, src);
break;
} else {
DEBUG_WARN("%s error %d around 0x%08" PRIx32 "\n",
__func__, s, src);
break;
}
}
}
}
static void remote_ap_mem_write_sized(
ADIv5_AP_t *ap, uint32_t dest, const void *src, size_t len,
enum align align)
{
(void)ap;
if (len == 0)
return;
char construct[REMOTE_MAX_MSG_SIZE];
/* (5 * 1 (char)) + (2 * 2 (bytes)) + (3 * 8 (words)) */
int batchsize = (REMOTE_MAX_MSG_SIZE - 0x30) / 2;
while (len) {
int count = len;
if (count > batchsize)
count = batchsize;
int s = snprintf(construct, REMOTE_MAX_MSG_SIZE,
REMOTE_AP_MEM_WRITE_SIZED_STR,
ap->dp->dp_jd_index, ap->apsel, ap->csw, align, dest, count);
char *p = construct + s;
hexify(p, src, count);
p += 2 * count;
src += count;
dest += count;
len -= count;
*p++ = REMOTE_EOM;
*p = 0;
platform_buffer_write((uint8_t*)construct, p - construct);
s = platform_buffer_read((uint8_t*)construct, REMOTE_MAX_MSG_SIZE);
if ((s > 0) && (construct[0] == REMOTE_RESP_OK))
continue;
if ((s > 0) && (construct[0] == REMOTE_RESP_ERR)) {
ap->dp->fault = 1;
DEBUG_WARN("%s returned REMOTE_RESP_ERR at apsel %d, "
"addr: 0x%08x\n", __func__, ap->apsel, dest);
} else {
DEBUG_WARN("%s error %d around address 0x%08" PRIx32 "\n",
__func__, s, dest);
break;
}
}
}
void remote_adiv5_dp_defaults(ADIv5_DP_t *dp)
{
uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE, "%s",
REMOTE_HL_CHECK_STR);
platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
if ((s < 1) || (construct[0] == REMOTE_RESP_ERR) ||
((construct[1] - '0') < REMOTE_HL_VERSION)) {
DEBUG_WARN(
"Please update BMP firmware for substantial speed increase!\n");
return;
}
dp->low_access = remote_adiv5_low_access;
dp->dp_read = remote_adiv5_dp_read;
dp->ap_write = remote_adiv5_ap_write;
dp->ap_read = remote_adiv5_ap_read;
dp->mem_read = remote_ap_mem_read;
dp->mem_write_sized = remote_ap_mem_write_sized;
}
void remote_add_jtag_dev(int i, const jtag_dev_t *jtag_dev)
{
uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE,
REMOTE_JTAG_ADD_DEV_STR,
i,
jtag_dev->dr_prescan,
jtag_dev->dr_postscan,
jtag_dev->ir_len,
jtag_dev->ir_prescan,
jtag_dev->ir_postscan,
jtag_dev->current_ir);
platform_buffer_write(construct, s);
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
/* No check for error here. Done in remote_adiv5_dp_defaults!*/
}

View File

@ -0,0 +1,45 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2020 Uwe Bonnes
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined(__BMP_REMOTE_H_)
#define __BMP_REMOTE_H_
#include "jtagtap.h"
#include "adiv5.h"
#include "target.h"
#include "target_internal.h"
#define REMOTE_MAX_MSG_SIZE (1024)
int platform_buffer_write(const uint8_t *data, int size);
int platform_buffer_read(uint8_t *data, int size);
int remote_init(void);
int remote_swdptap_init(ADIv5_DP_t *dp);
int remote_jtagtap_init(jtag_proc_t *jtag_proc);
bool remote_target_get_power(void);
const char *remote_target_voltage(void);
bool remote_target_set_power(bool power);
void remote_srst_set_val(bool assert);
bool remote_srst_get_val(void);
void remote_max_frequency_set(uint32_t freq);
uint32_t remote_max_frequency_get(void);
const char *platform_target_voltage(void);
void remote_adiv5_dp_defaults(ADIv5_DP_t *dp);
void remote_add_jtag_dev(int i, const jtag_dev_t *jtag_dev);
#define __BMP_REMOTE_H_
#endif

View File

@ -0,0 +1,296 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2020 Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Find all known serial connected debuggers */
#include "general.h"
#include <dirent.h>
#include <errno.h>
#include "bmp_hosted.h"
#include "version.h"
void bmp_ident(bmp_info_t *info)
{
if (!info)
return;
DEBUG_INFO("BMP hosted (BMP Only) %s\n", FIRMWARE_VERSION);
DEBUG_INFO("Using:\n %s %s %s\n", info->manufacturer, info->version, info->serial);
}
void libusb_exit_function(bmp_info_t *info) {(void)info;};
#ifdef __APPLE__
int find_debuggers(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info)
{
DEBUG_WARN("Please implement find_debuggers for MACOS!\n");
(void)cl_opts;
(void)info;
return -1;
}
#elif defined(__WIN32__) || defined(__CYGWIN__)
/* This source has been used as an example:
* https://stackoverflow.com/questions/3438366/setupdigetdeviceproperty-usage-example */
#include <windows.h>
#include <setupapi.h>
#include <cfgmgr32.h> // for MAX_DEVICE_ID_LEN, CM_Get_Parent and CM_Get_Device_ID
#include <tchar.h>
#include <stdio.h>
/* include DEVPKEY_Device_BusReportedDeviceDesc from WinDDK\7600.16385.1\inc\api\devpropdef.h */
#ifdef DEFINE_DEVPROPKEY
#undef DEFINE_DEVPROPKEY
#endif
#define DEFINE_DEVPROPKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) const DEVPROPKEY DECLSPEC_SELECTANY name = { { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }, pid }
/* include DEVPKEY_Device_BusReportedDeviceDesc from WinDDK\7600.16385.1\inc\api\devpkey.h */
DEFINE_DEVPROPKEY(DEVPKEY_Device_BusReportedDeviceDesc, 0x540b947e, 0x8b40, 0x45bc, 0xa8, 0xa2, 0x6a, 0x0b, 0x89, 0x4c, 0xbd, 0xa2, 4); // DEVPROP_TYPE_STRING
/* List all USB devices with some additional information.
* Unfortunately, this code is quite ugly. */
int find_debuggers(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info)
{
unsigned i;
DWORD dwSize;
DEVPROPTYPE ulPropertyType;
CONFIGRET status;
HDEVINFO hDevInfo;
SP_DEVINFO_DATA DeviceInfoData;
TCHAR szDeviceInstanceID [MAX_DEVICE_ID_LEN];
WCHAR busReportedDeviceSesc[4096];
int probes_found = 0;
bool is_printing_probes_info = cl_opts->opt_list_only != 0;
info->bmp_type = BMP_TYPE_BMP;
hDevInfo = SetupDiGetClassDevs (0, "USB", NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT);
if (hDevInfo == INVALID_HANDLE_VALUE)
return -1;
print_probes_info:
for (i = 0; ; i++) {
char serial_number[sizeof info->serial];
DeviceInfoData.cbSize = sizeof (DeviceInfoData);
if (!SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData))
break;
status = CM_Get_Device_ID(DeviceInfoData.DevInst, szDeviceInstanceID , MAX_PATH, 0);
if (status != CR_SUCCESS)
continue;
if (!sscanf(szDeviceInstanceID, "USB\\VID_1D50&PID_6018\\%s", serial_number))
continue;
if (SetupDiGetDevicePropertyW (hDevInfo, &DeviceInfoData, &DEVPKEY_Device_BusReportedDeviceDesc,
&ulPropertyType, (BYTE*)busReportedDeviceSesc, sizeof busReportedDeviceSesc, &dwSize, 0))
{
probes_found ++;
if (is_printing_probes_info)
{
DEBUG_WARN("%2d: %s, %ls\n", probes_found,
serial_number, busReportedDeviceSesc);
}
else
{
bool probe_identified = true;
if ((cl_opts->opt_serial && strstr(serial_number, cl_opts->opt_serial)) ||
(cl_opts->opt_position && cl_opts->opt_position == probes_found) ||
/* Special case for the very first probe found. */
(probe_identified = false, probes_found == 1)) {
strncpy(info->serial, serial_number, sizeof info->serial);
strncpy(info->manufacturer, "BMP", sizeof info->manufacturer);
snprintf(info->product, sizeof info->product, "%ls", busReportedDeviceSesc);
/* Don't bother to parse the version string. It is a part of the
* product description string. It seems that at the moment it
* is only being used to print a version string in response
* to the 'monitor version' command, so it doesn't really matter
* if the version string is printed as a part of the product string,
* or as a separate string, the result is pretty much the same. */
info->version[0] = 0;
if (probe_identified)
return 0;
}
}
}
}
if (is_printing_probes_info)
return 1;
if (probes_found == 1)
/* Exactly one probe found. Its information has already been filled
* in the detection loop, so use this probe. */
return 0;
if (probes_found < 1) {
DEBUG_WARN("No BMP probe found\n");
return -1;
}
/* Otherwise, if this line is reached, then more than one probe has been found,
* and no probe was identified as selected by the user.
* Restart the identification loop, this time printing the probe information,
* and then return. */
DEBUG_WARN("%d debuggers found!\nSelect with -P <pos>, or "
"-s <(partial)serial no.>\n",
probes_found);
probes_found = 0;
is_printing_probes_info = true;
goto print_probes_info;
}
#else
/* Old ID: Black_Sphere_Technologies_Black_Magic_Probe_BFE4D6EC-if00
* Recent: Black_Sphere_Technologies_Black_Magic_Probe_v1.7.1-212-g212292ab_7BAE7AB8-if00
* usb-Black_Sphere_Technologies_Black_Magic_Probe__SWLINK__v1.7.1-155-gf55ad67b-dirty_DECB8811-if00
*/
#define BMP_IDSTRING_BLACKSPHERE "usb-Black_Sphere_Technologies_Black_Magic_Probe"
#define BMP_IDSTRING_BLACKMAGIC "usb-Black_Magic_Debug_Black_Magic_Probe"
#define BMP_IDSTRING_1BITSQUARED "usb-1BitSquared_Black_Magic_Probe"
#define DEVICE_BY_ID "/dev/serial/by-id/"
/*
* Extract type, version and serial from /dev/serial/by_id
* Return 0 on success
*
* Old versions have different strings. Try to cope!
*/
static int scan_linux_id(char *name, char *type, char *version, char *serial)
{
name += strlen(BMP_IDSTRING_BLACKSPHERE) + 1;
while (*name == '_')
name++;
if (!*name) {
DEBUG_WARN("Unexpected end\n");
return -1;
}
char *p = name;
char *delims[4] = {0,0,0,0};
int underscores = 0;
while (*p) {
if (*p == '_') {
while (p[1] == '_')
p++; /* remove multiple underscores */
if (underscores > 2)
return -1;
delims[underscores] = p;
underscores ++;
}
p++;
}
if (underscores == 0) { /* Old BMP native */
int res;
res = sscanf(name, "%8s-if00", serial);
if (res != 1)
return -1;
strcpy(type, "Native");
strcpy(version, "Unknown");
} else if (underscores == 2) {
strncpy(type, name, delims[0] - name - 1);
strncpy(version, delims[0] + 1, delims[1] - delims[0] - 1);
int res = sscanf(delims[1] + 1, "%8s-if00", serial);
if (!res)
return -1;
} else {
int res = sscanf(delims[0] + 1, "%8s-if00", serial);
if (!res)
return -1;
if (name[0] == 'v') {
strcpy(type, "Unknown");
strncpy(version, name, delims[0] - name - 1);
} else {
strncpy(type, name, delims[0] - name);
strcpy(type, "Unknown");
}
}
return 0;
}
int find_debuggers(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info)
{
if (cl_opts->opt_device)
return 1;
info->bmp_type = BMP_TYPE_BMP;
DIR *dir = opendir(DEVICE_BY_ID);
if (!dir) /* No serial device connected!*/
return 0;
int found_bmps = 0;
struct dirent *dp;
int i = 0;
while ((dp = readdir(dir)) != NULL) {
if ((strstr(dp->d_name, BMP_IDSTRING_BLACKMAGIC) ||
strstr(dp->d_name, BMP_IDSTRING_BLACKSPHERE) ||
strstr(dp->d_name, BMP_IDSTRING_1BITSQUARED)) &&
(strstr(dp->d_name, "-if00"))) {
i++;
char type[256], version[256], serial[256];
if (scan_linux_id(dp->d_name, type, version, serial)) {
DEBUG_WARN("Unexpected device name found \"%s\"\n",
dp->d_name);
}
if ((cl_opts->opt_serial && strstr(serial, cl_opts->opt_serial)) ||
(cl_opts->opt_position && cl_opts->opt_position == i)) {
/* With serial number given and partial match, we are done!*/
strncpy(info->serial, serial, sizeof(info->serial));
int res = snprintf(info->manufacturer, sizeof(info->manufacturer), "Black Magic Probe (%s)", type);
if (res)
DEBUG_WARN("Overflow\n");
strncpy(info->version, version, sizeof(info->version));
found_bmps = 1;
break;
} else {
found_bmps++;
}
}
}
closedir(dir);
if (found_bmps < 1) {
DEBUG_WARN("No BMP probe found\n");
return -1;
} else if ((found_bmps > 1) || cl_opts->opt_list_only) {
DEBUG_WARN("Available Probes:\n");
}
dir = opendir(DEVICE_BY_ID);
i = 0;
while ((dp = readdir(dir)) != NULL) {
if ((strstr(dp->d_name, BMP_IDSTRING_BLACKMAGIC) ||
strstr(dp->d_name, BMP_IDSTRING_BLACKSPHERE) ||
strstr(dp->d_name, BMP_IDSTRING_1BITSQUARED)) &&
(strstr(dp->d_name, "-if00"))) {
i++;
char type[256], version[256], serial[256];
if (scan_linux_id(dp->d_name, type, version, serial)) {
DEBUG_WARN("Unexpected device name found \"%s\"\n",
dp->d_name);
} else if ((found_bmps == 1) && (!cl_opts->opt_list_only)) {
strncpy(info->serial, serial, sizeof(info->serial));
found_bmps = 1;
strncpy(info->serial, serial, sizeof(info->serial));
snprintf(info->manufacturer, sizeof(info->manufacturer), "Black Magic Probe (%s)", type);
strncpy(info->version, version, sizeof(info->version));
break;
} else if (found_bmps > 0) {
DEBUG_WARN("%2d: %s, Black Magic Debug, Black Magic "
"Probe (%s), %s\n", i, serial, type, version);
}
}
}
closedir(dir);
return (found_bmps == 1 && !cl_opts->opt_list_only) ? 0 : 1;
}
#endif

View File

@ -0,0 +1,470 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2019-2021 Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Modified from edbg.c
* Links between bmp and edbg
*
* https://arm-software.github.io/CMSIS_5/DAP/html/index.html
*/
#include "general.h"
#include "gdb_if.h"
#include "adiv5.h"
#include <assert.h>
#include <unistd.h>
#include <signal.h>
#include <ctype.h>
#include <sys/time.h>
#include <hidapi.h>
#include <wchar.h>
#include "bmp_hosted.h"
#include "dap.h"
#include "cmsis_dap.h"
#include "cl_utils.h"
#include "target.h"
#include "target_internal.h"
uint8_t dap_caps;
uint8_t mode;
typedef enum cmsis_type_s {
CMSIS_TYPE_NONE = 0,
CMSIS_TYPE_HID,
CMSIS_TYPE_BULK
} cmsis_type_t;
/*- Variables ---------------------------------------------------------------*/
static cmsis_type_t type;
static libusb_device_handle *usb_handle = NULL;
static uint8_t in_ep;
static uint8_t out_ep;
static hid_device *handle = NULL;
static uint8_t buffer[1024 + 1];
static int report_size = 64 + 1; // TODO: read actual report size
static bool has_swd_sequence = false;
/* LPC845 Breakout Board Rev. 0 report invalid response with > 65 bytes */
int dap_init(bmp_info_t *info)
{
type = (info->in_ep && info->out_ep) ? CMSIS_TYPE_BULK : CMSIS_TYPE_HID;
int size;
if (type == CMSIS_TYPE_HID) {
DEBUG_INFO("Using hid transfer\n");
if (hid_init())
return -1;
size = strlen(info->serial);
wchar_t serial[64] = {0}, *wc = serial;
for (int i = 0; i < size; i++)
*wc++ = info->serial[i];
*wc = 0;
/* Blacklist devices that do not work with 513 byte report length
* FIXME: Find a solution to decipher from the device.
*/
if ((info->vid == 0x1fc9) && (info->pid == 0x0132)) {
DEBUG_WARN("Blacklist\n");
report_size = 64 + 1;
}
handle = hid_open(info->vid, info->pid, (serial[0]) ? serial : NULL);
if (!handle) {
DEBUG_WARN("hid_open failed\n");
return -1;
}
} else if (type == CMSIS_TYPE_BULK) {
DEBUG_INFO("Using bulk transfer\n");
usb_handle = libusb_open_device_with_vid_pid(info->libusb_ctx, info->vid, info->pid);
if (!usb_handle) {
DEBUG_WARN("WARN: libusb_open_device_with_vid_pid() failed\n");
return -1;
}
if (libusb_claim_interface(usb_handle, info->interface_num) < 0) {
DEBUG_WARN("WARN: libusb_claim_interface() failed\n");
return -1;
}
in_ep = info->in_ep;
out_ep = info->out_ep;
}
dap_disconnect();
size = dap_info(DAP_INFO_FW_VER, buffer, sizeof(buffer));
if (size) {
DEBUG_INFO("Ver %s, ", buffer);
int major = -1, minor = -1, sub = -1;
if (sscanf((const char *)buffer, "%d.%d.%d",
&major, &minor, &sub)) {
if (sub == -1) {
if (minor >= 10) {
minor /= 10;
sub = 0;
}
}
has_swd_sequence = ((major > 1 ) || ((major > 0 ) && (minor > 1)));
}
}
size = dap_info(DAP_INFO_CAPABILITIES, buffer, sizeof(buffer));
dap_caps = buffer[0];
DEBUG_INFO("Cap (0x%2x): %s%s%s", dap_caps,
(dap_caps & 1)? "SWD" : "",
((dap_caps & 3) == 3) ? "/" : "",
(dap_caps & 2)? "JTAG" : "");
if (dap_caps & 4)
DEBUG_INFO(", SWO_UART");
if (dap_caps & 8)
DEBUG_INFO(", SWO_MANCHESTER");
if (dap_caps & 0x10)
DEBUG_INFO(", Atomic Cmds");
if (has_swd_sequence)
DEBUG_INFO(", DAP_SWD_Sequence");
DEBUG_INFO("\n");
return 0;
}
void dap_srst_set_val(bool assert)
{
dap_reset_pin(!assert);
}
static void dap_dp_abort(ADIv5_DP_t *dp, uint32_t abort)
{
/* DP Write to Reg 0.*/
dap_write_reg(dp, ADIV5_DP_ABORT, abort);
}
static uint32_t dap_dp_error(ADIv5_DP_t *dp)
{
/* Not used for SWD debugging, so no TARGETID switch needed!*/
uint32_t ctrlstat = dap_read_reg(dp, ADIV5_DP_CTRLSTAT);
uint32_t err = ctrlstat &
(ADIV5_DP_CTRLSTAT_STICKYORUN | ADIV5_DP_CTRLSTAT_STICKYCMP |
ADIV5_DP_CTRLSTAT_STICKYERR | ADIV5_DP_CTRLSTAT_WDATAERR);
uint32_t clr = 0;
if(err & ADIV5_DP_CTRLSTAT_STICKYORUN)
clr |= ADIV5_DP_ABORT_ORUNERRCLR;
if(err & ADIV5_DP_CTRLSTAT_STICKYCMP)
clr |= ADIV5_DP_ABORT_STKCMPCLR;
if(err & ADIV5_DP_CTRLSTAT_STICKYERR)
clr |= ADIV5_DP_ABORT_STKERRCLR;
if(err & ADIV5_DP_CTRLSTAT_WDATAERR)
clr |= ADIV5_DP_ABORT_WDERRCLR;
dap_write_reg(dp, ADIV5_DP_ABORT, clr);
dp->fault = 0;
return err;
}
static uint32_t dap_dp_low_access(struct ADIv5_DP_s *dp, uint8_t RnW,
uint16_t addr, uint32_t value)
{
bool APnDP = addr & ADIV5_APnDP;
uint32_t res = 0;
uint8_t reg = (addr & 0xc) | ((APnDP)? 1 : 0);
if (RnW) {
res = dap_read_reg(dp, reg);
}
else {
dap_write_reg(dp, reg, value);
}
return res;
}
static uint32_t dap_dp_read_reg(ADIv5_DP_t *dp, uint16_t addr)
{
uint32_t res = dap_dp_low_access(dp, ADIV5_LOW_READ, addr, 0);
DEBUG_PROBE("dp_read %04x %08" PRIx32 "\n", addr, res);
return res;
}
void dap_exit_function(void)
{
if (type == CMSIS_TYPE_HID) {
if (handle) {
dap_disconnect();
hid_close(handle);
}
} else if (type == CMSIS_TYPE_BULK) {
if (usb_handle) {
dap_disconnect();
libusb_close(usb_handle);
}
}
}
int dbg_get_report_size(void)
{
return report_size;
}
int dbg_dap_cmd(uint8_t *data, int size, int rsize)
{
char cmd = data[0];
int res = -1;
memset(buffer, 0xff, report_size + 1);
buffer[0] = 0x00; // Report ID??
memcpy(&buffer[1], data, rsize);
DEBUG_WIRE("cmd : ");
for(int i = 0; (i < 32) && (i < rsize + 1); i++)
DEBUG_WIRE("%02x.", buffer[i]);
DEBUG_WIRE("\n");
if (type == CMSIS_TYPE_HID) {
res = hid_write(handle, buffer, 65);
if (res < 0) {
DEBUG_WARN( "Error: %ls\n", hid_error(handle));
exit(-1);
}
res = hid_read_timeout(handle, buffer, 65, 1000);
if (res < 0) {
DEBUG_WARN( "debugger read(): %ls\n", hid_error(handle));
exit(-1);
} else if (res == 0) {
DEBUG_WARN( "timeout\n");
exit(-1);
}
} else if (type == CMSIS_TYPE_BULK) {
int transferred = 0;
res = libusb_bulk_transfer(usb_handle, out_ep, data, rsize, &transferred, 500);
if (res < 0) {
DEBUG_WARN("OUT error: %d\n", res);
return res;
}
res = libusb_bulk_transfer(usb_handle, in_ep, buffer, report_size, &transferred, 500);
if (res < 0) {
DEBUG_WARN("IN error: %d\n", res);
return res;
}
res = transferred;
}
DEBUG_WIRE("cmd res:");
for(int i = 0; (i < 16) && (i < size + 1); i++)
DEBUG_WIRE("%02x.", buffer[i]);
DEBUG_WIRE("\n");
if (buffer[0] != cmd) {
DEBUG_WARN("cmd %02x not implemented\n", cmd);
buffer[1] = 0xff /*DAP_ERROR*/;
}
if (size)
memcpy(data, &buffer[1], (size < res) ? size : res);
return res;
}
#define ALIGNOF(x) (((x) & 3) == 0 ? ALIGN_WORD : \
(((x) & 1) == 0 ? ALIGN_HALFWORD : ALIGN_BYTE))
static void dap_mem_read(ADIv5_AP_t *ap, void *dest, uint32_t src, size_t len)
{
if (len == 0)
return;
enum align align = MIN(ALIGNOF(src), ALIGNOF(len));
DEBUG_WIRE("memread @ %" PRIx32 " len %ld, align %d , start: \n",
src, len, align);
if (((unsigned)(1 << align)) == len)
return dap_read_single(ap, dest, src, align);
/* One word transfer for every byte/halfword/word
* Total number of bytes in transfer*/
unsigned int max_size = ((dbg_get_report_size() - 6) >> (2 - align)) & ~3;
while (len) {
dap_ap_mem_access_setup(ap, src, align);
/* Calculate length until next access setup is needed */
unsigned int blocksize = (src | 0x3ff) - src + 1;
if (blocksize > len)
blocksize = len;
while (blocksize) {
unsigned int transfersize = blocksize;
if (transfersize > max_size)
transfersize = max_size;
unsigned int res = dap_read_block(ap, dest, src, transfersize,
align);
if (res) {
DEBUG_WIRE("mem_read failed %02x\n", res);
ap->dp->fault = 1;
return;
}
blocksize -= transfersize;
len -= transfersize;
dest += transfersize;
src += transfersize;
}
}
DEBUG_WIRE("memread res last data %08" PRIx32 "\n", ((uint32_t*)dest)[-1]);
}
static void dap_mem_write_sized(
ADIv5_AP_t *ap, uint32_t dest, const void *src,
size_t len, enum align align)
{
if (len == 0)
return;
DEBUG_WIRE("memwrite @ %" PRIx32 " len %ld, align %d , %08x start: \n",
dest, len, align, *(uint32_t *)src);
if (((unsigned)(1 << align)) == len)
return dap_write_single(ap, dest, src, align);
unsigned int max_size = ((dbg_get_report_size() - 6) >> (2 - align) & ~3);
while (len) {
dap_ap_mem_access_setup(ap, dest, align);
unsigned int blocksize = (dest | 0x3ff) - dest + 1;
if (blocksize > len)
blocksize = len;
while (blocksize) {
unsigned int transfersize = blocksize;
if (transfersize > max_size)
transfersize = max_size;
unsigned int res = dap_write_block(ap, dest, src, transfersize,
align);
if (res) {
DEBUG_WARN("mem_write failed %02x\n", res);
ap->dp->fault = 1;
return;
}
blocksize -= transfersize;
len -= transfersize;
dest += transfersize;
src += transfersize;
}
}
DEBUG_WIRE("memwrite done\n");
}
void dap_adiv5_dp_defaults(ADIv5_DP_t *dp)
{
if ((mode == DAP_CAP_JTAG) && dap_jtag_configure())
return;
dp->ap_read = dap_ap_read;
dp->ap_write = dap_ap_write;
dp->mem_read = dap_mem_read;
dp->mem_write_sized = dap_mem_write_sized;
}
static void cmsis_dap_jtagtap_reset(void)
{
jtagtap_soft_reset();
/* Is there a way to know if TRST is available?*/
}
static void cmsis_dap_jtagtap_tms_seq(uint32_t MS, int ticks)
{
uint8_t TMS[4] = {MS & 0xff, (MS >> 8) & 0xff, (MS >> 16) & 0xff,
(MS >> 24) & 0xff};
dap_jtagtap_tdi_tdo_seq(NULL, false, TMS, NULL, ticks);
DEBUG_PROBE("tms_seq DI %08x %d\n", MS, ticks);
}
static void cmsis_dap_jtagtap_tdi_tdo_seq(uint8_t *DO, const uint8_t final_tms,
const uint8_t *DI, int ticks)
{
dap_jtagtap_tdi_tdo_seq(DO, (final_tms), NULL, DI, ticks);
DEBUG_PROBE("jtagtap_tdi_tdo_seq %d, %02x-> %02x\n", ticks, DI[0], (DO)? DO[0] : 0);
}
static void cmsis_dap_jtagtap_tdi_seq(const uint8_t final_tms,
const uint8_t *DI, int ticks)
{
dap_jtagtap_tdi_tdo_seq(NULL, (final_tms), NULL, DI, ticks);
DEBUG_PROBE("jtagtap_tdi_seq %d, %02x\n", ticks, DI[0]);
}
static uint8_t cmsis_dap_jtagtap_next(uint8_t dTMS, uint8_t dTDI)
{
uint8_t tdo[1];
dap_jtagtap_tdi_tdo_seq(tdo, false, &dTMS, &dTDI, 1);
DEBUG_PROBE("next tms %02x tdi %02x tdo %02x\n", dTMS, dTDI, tdo[0]);
return (tdo[0] & 1);
}
int cmsis_dap_jtagtap_init(jtag_proc_t *jtag_proc)
{
DEBUG_PROBE("jtap_init\n");
if (!(dap_caps & DAP_CAP_JTAG))
return -1;
mode = DAP_CAP_JTAG;
dap_disconnect();
dap_connect(true);
dap_reset_link(true);
jtag_proc->jtagtap_reset = cmsis_dap_jtagtap_reset;
jtag_proc->jtagtap_next = cmsis_dap_jtagtap_next;
jtag_proc->jtagtap_tms_seq = cmsis_dap_jtagtap_tms_seq;
jtag_proc->jtagtap_tdi_tdo_seq = cmsis_dap_jtagtap_tdi_tdo_seq;
jtag_proc->jtagtap_tdi_seq = cmsis_dap_jtagtap_tdi_seq;
return 0;
}
int dap_jtag_dp_init(ADIv5_DP_t *dp)
{
dp->dp_read = dap_dp_read_reg;
dp->error = dap_dp_error;
dp->low_access = dap_dp_low_access;
dp->abort = dap_dp_abort;
return true;
}
#define SWD_SEQUENCE_IN 0x80
#define DAP_SWD_SEQUENCE 0x1d
static bool dap_dp_low_write(ADIv5_DP_t *dp, uint16_t addr, const uint32_t data)
{
DEBUG_PROBE("dap_dp_low_write %08" PRIx32 "\n", data);
(void)dp;
unsigned int paket_request = make_packet_request(ADIV5_LOW_WRITE, addr);
uint8_t buf[32] = {
DAP_SWD_SEQUENCE,
5,
8,
paket_request,
4 + SWD_SEQUENCE_IN, /* one turn-around + read 3 bit ACK */
1, /* one bit turn around to drive SWDIO */
0,
32, /* write 32 bit data */
(data >> 0) & 0xff,
(data >> 8) & 0xff,
(data >> 16) & 0xff,
(data >> 24) & 0xff,
1, /* write parity biT */
__builtin_parity(data)
};
dbg_dap_cmd(buf, sizeof(buf), 14);
if (buf[0])
DEBUG_WARN("dap_dp_low_write failed\n");
uint32_t ack = (buf[1] >> 1) & 7;
return (ack != SWDP_ACK_OK);
}
int dap_swdptap_init(ADIv5_DP_t *dp)
{
if (!(dap_caps & DAP_CAP_SWD))
return 1;
mode = DAP_CAP_SWD;
dap_transfer_configure(2, 128, 128);
dap_swd_configure(0);
dap_connect(false);
dap_led(0, 1);
dap_reset_link(false);
if ((has_swd_sequence) && dap_sequence_test()) {
/* DAP_SWD_SEQUENCE does not do auto turnaround, use own!*/
dp->dp_low_write = dap_dp_low_write;
} else {
dp->dp_low_write = NULL;
}
dp->seq_out = dap_swdptap_seq_out;
dp->dp_read = dap_dp_read_reg;
/* For error() use the TARGETID switching firmware_swdp_error */
dp->low_access = dap_dp_low_access;
dp->abort = dap_dp_abort;
return 0;
}

View File

@ -0,0 +1,56 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2019 - 2021 Uwe Bonnes(bon@elektron.ikp.physik.tu-darmstadt.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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined(__CMSIS_DAP_H_)
#define __CMSIS_DAP_H_
#include "adiv5.h"
#include "cl_utils.h"
#if defined(CMSIS_DAP)
int dap_init(bmp_info_t *info);
void dap_exit_function(void);
void dap_adiv5_dp_defaults(ADIv5_DP_t *dp);
int cmsis_dap_jtagtap_init(jtag_proc_t *jtag_proc);
int dap_swdptap_init(ADIv5_DP_t *dp);
int dap_jtag_dp_init(ADIv5_DP_t *dp);
uint32_t dap_swj_clock(uint32_t clock);
void dap_swd_configure(uint8_t cfg);
void dap_srst_set_val(bool assert);
#else
int dap_init(bmp_info_t *info)
{
DEBUG_WARN("FATAL: Missing hidapi-libusb\n");
(void)info;
return -1;
}
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wunused-parameter"
uint32_t dap_swj_clock(uint32_t clock) {return 0;}
void dap_exit_function(void) {};
void dap_adiv5_dp_defaults(ADIv5_DP_t *dp) {};
int cmsis_dap_jtagtap_init(jtag_proc_t *jtag_proc) {return -1;}
int dap_swdptap_init(ADIv5_DP_t *dp) {return -1;}
int dap_jtag_dp_init(ADIv5_DP_t *dp) {return -1;}
void dap_swd_configure(uint8_t cfg) {};
void dap_srst_set_val(bool assert) {};
# pragma GCC diagnostic pop
#endif
#endif

849
src/platforms/hosted/dap.c Normal file
View File

@ -0,0 +1,849 @@
/*
* Copyright (c) 2013-2015, Alex Taradov <alex@taradov.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/* Modified for Blackmagic Probe
* Copyright (c) 2020-21 Uwe Bonnes bon@elektron.ikp.physik.tu-darmstadt.de
*/
/*- Includes ----------------------------------------------------------------*/
#include <general.h>
#include "exception.h"
#include "dap.h"
#include "jtag_scan.h"
/*- Definitions -------------------------------------------------------------*/
enum
{
ID_DAP_INFO = 0x00,
ID_DAP_LED = 0x01,
ID_DAP_CONNECT = 0x02,
ID_DAP_DISCONNECT = 0x03,
ID_DAP_TRANSFER_CONFIGURE = 0x04,
ID_DAP_TRANSFER = 0x05,
ID_DAP_TRANSFER_BLOCK = 0x06,
ID_DAP_TRANSFER_ABORT = 0x07,
ID_DAP_WRITE_ABORT = 0x08,
ID_DAP_DELAY = 0x09,
ID_DAP_RESET_TARGET = 0x0a,
ID_DAP_SWJ_PINS = 0x10,
ID_DAP_SWJ_CLOCK = 0x11,
ID_DAP_SWJ_SEQUENCE = 0x12,
ID_DAP_SWD_CONFIGURE = 0x13,
ID_DAP_JTAG_SEQUENCE = 0x14,
ID_DAP_JTAG_CONFIGURE = 0x15,
ID_DAP_JTAG_IDCODE = 0x16,
ID_DAP_SWD_SEQUENCE = 0x1D,
};
enum
{
DAP_TRANSFER_APnDP = 1 << 0,
DAP_TRANSFER_RnW = 1 << 1,
DAP_TRANSFER_A2 = 1 << 2,
DAP_TRANSFER_A3 = 1 << 3,
DAP_TRANSFER_MATCH_VALUE = 1 << 4,
DAP_TRANSFER_MATCH_MASK = 1 << 5,
};
enum
{
DAP_TRANSFER_INVALID = 0,
DAP_TRANSFER_OK = 1 << 0,
DAP_TRANSFER_WAIT = 1 << 1,
DAP_TRANSFER_FAULT = 1 << 2,
DAP_TRANSFER_ERROR = 1 << 3,
DAP_TRANSFER_MISMATCH = 1 << 4,
DAP_TRANSFER_NO_TARGET = 7,
};
enum
{
DAP_SWJ_SWCLK_TCK = 1 << 0,
DAP_SWJ_SWDIO_TMS = 1 << 1,
DAP_SWJ_TDI = 1 << 2,
DAP_SWJ_TDO = 1 << 3,
DAP_SWJ_nTRST = 1 << 5,
DAP_SWJ_nRESET = 1 << 7,
};
enum
{
DAP_OK = 0x00,
DAP_ERROR = 0xff,
};
enum
{
DAP_JTAG_TMS = 1 << 6,
DAP_JTAG_TDO_CAPTURE = 1 << 7,
};
enum
{
SWD_DP_R_IDCODE = 0x00,
SWD_DP_W_ABORT = 0x00,
SWD_DP_R_CTRL_STAT = 0x04,
SWD_DP_W_CTRL_STAT = 0x04, // When CTRLSEL == 0
SWD_DP_W_WCR = 0x04, // When CTRLSEL == 1
SWD_DP_R_RESEND = 0x08,
SWD_DP_W_SELECT = 0x08,
SWD_DP_R_RDBUFF = 0x0c,
};
enum
{
SWD_AP_CSW = 0x00 | DAP_TRANSFER_APnDP,
SWD_AP_TAR = 0x04 | DAP_TRANSFER_APnDP,
SWD_AP_DRW = 0x0c | DAP_TRANSFER_APnDP,
SWD_AP_DB0 = 0x00 | DAP_TRANSFER_APnDP, // 0x10
SWD_AP_DB1 = 0x04 | DAP_TRANSFER_APnDP, // 0x14
SWD_AP_DB2 = 0x08 | DAP_TRANSFER_APnDP, // 0x18
SWD_AP_DB3 = 0x0c | DAP_TRANSFER_APnDP, // 0x1c
SWD_AP_CFG = 0x04 | DAP_TRANSFER_APnDP, // 0xf4
SWD_AP_BASE = 0x08 | DAP_TRANSFER_APnDP, // 0xf8
SWD_AP_IDR = 0x0c | DAP_TRANSFER_APnDP, // 0xfc
};
#define DP_ABORT_DAPABORT (1 << 0)
#define DP_ABORT_STKCMPCLR (1 << 1)
#define DP_ABORT_STKERRCLR (1 << 2)
#define DP_ABORT_WDERRCLR (1 << 3)
#define DP_ABORT_ORUNERRCLR (1 << 4)
#define DP_CST_ORUNDETECT (1 << 0)
#define DP_CST_STICKYORUN (1 << 1)
#define DP_CST_TRNMODE_NORMAL (0 << 2)
#define DP_CST_TRNMODE_VERIFY (1 << 2)
#define DP_CST_TRNMODE_COMPARE (2 << 2)
#define DP_CST_STICKYCMP (1 << 4)
#define DP_CST_STICKYERR (1 << 5)
#define DP_CST_READOK (1 << 6)
#define DP_CST_WDATAERR (1 << 7)
#define DP_CST_MASKLANE(x) ((x) << 8)
#define DP_CST_TRNCNT(x) ((x) << 12)
#define DP_CST_CDBGRSTREQ (1 << 26)
#define DP_CST_CDBGRSTACK (1 << 27)
#define DP_CST_CDBGPWRUPREQ (1 << 28)
#define DP_CST_CDBGPWRUPACK (1 << 29)
#define DP_CST_CSYSPWRUPREQ (1 << 30)
#define DP_CST_CSYSPWRUPACK (1 << 31)
#define DP_SELECT_CTRLSEL (1 << 0)
#define DP_SELECT_APBANKSEL(x) ((x) << 4)
#define DP_SELECT_APSEL(x) ((x) << 24)
#define AP_CSW_SIZE_BYTE (0 << 0)
#define AP_CSW_SIZE_HALF (1 << 0)
#define AP_CSW_SIZE_WORD (2 << 0)
#define AP_CSW_ADDRINC_OFF (0 << 4)
#define AP_CSW_ADDRINC_SINGLE (1 << 4)
#define AP_CSW_ADDRINC_PACKED (2 << 4)
#define AP_CSW_DEVICEEN (1 << 6)
#define AP_CSW_TRINPROG (1 << 7)
#define AP_CSW_SPIDEN (1 << 23)
#define AP_CSW_PROT(x) ((x) << 24)
#define AP_CSW_DBGSWENABLE (1 << 31)
/*- Implementations ---------------------------------------------------------*/
//-----------------------------------------------------------------------------
void dap_led(int index, int state)
{
uint8_t buf[3];
buf[0] = ID_DAP_LED;
buf[1] = index;
buf[2] = state;
dbg_dap_cmd(buf, sizeof(buf), 3);
}
//-----------------------------------------------------------------------------
void dap_connect(bool jtag)
{
uint8_t buf[2];
buf[0] = ID_DAP_CONNECT;
buf[1] = (jtag) ? DAP_CAP_JTAG : DAP_CAP_SWD;
dbg_dap_cmd(buf, sizeof(buf), 2);
}
//-----------------------------------------------------------------------------
void dap_disconnect(void)
{
uint8_t buf[65];
buf[0] = ID_DAP_DISCONNECT;
dbg_dap_cmd(buf, sizeof(buf), 1);
}
static uint32_t swj_clock;
/* Set/Get JTAG/SWD clock frequency
*
* With clock == 0, return last set value.
*/
uint32_t dap_swj_clock(uint32_t clock)
{
if (clock == 0)
return swj_clock;
uint8_t buf[5];
buf[0] = ID_DAP_SWJ_CLOCK;
buf[1] = clock & 0xff;
buf[2] = (clock >> 8) & 0xff;
buf[3] = (clock >> 16) & 0xff;
buf[4] = (clock >> 24) & 0xff;
dbg_dap_cmd(buf, sizeof(buf), 5);
if (buf[0])
DEBUG_WARN("dap_swj_clock failed\n");
else
swj_clock = clock;
return swj_clock;
}
//-----------------------------------------------------------------------------
void dap_transfer_configure(uint8_t idle, uint16_t count, uint16_t retry)
{
uint8_t buf[6];
buf[0] = ID_DAP_TRANSFER_CONFIGURE;
buf[1] = idle;
buf[2] = count & 0xff;
buf[3] = (count >> 8) & 0xff;
buf[4] = retry & 0xff;
buf[5] = (retry >> 8) & 0xff;
dbg_dap_cmd(buf, sizeof(buf), 6);
}
//-----------------------------------------------------------------------------
void dap_swd_configure(uint8_t cfg)
{
uint8_t buf[2];
buf[0] = ID_DAP_SWD_CONFIGURE;
buf[1] = cfg;
dbg_dap_cmd(buf, sizeof(buf), 2);
}
//-----------------------------------------------------------------------------
int dap_info(int info, uint8_t *data, int size)
{
uint8_t buf[256];
int rsize;
buf[0] = ID_DAP_INFO;
buf[1] = info;
dbg_dap_cmd(buf, sizeof(buf), 2);
rsize = (size < buf[0]) ? size : buf[0];
memcpy(data, &buf[1], rsize);
if (rsize < size)
data[rsize] = 0;
return rsize;
}
void dap_reset_pin(int state)
{
uint8_t buf[7];
buf[0] = ID_DAP_SWJ_PINS;
buf[1] = state ? DAP_SWJ_nRESET : 0; // Value
buf[2] = DAP_SWJ_nRESET; // Select
buf[3] = 0; // Wait
buf[4] = 0; // Wait
buf[5] = 0; // Wait
buf[6] = 0; // Wait
dbg_dap_cmd(buf, sizeof(buf), 7);
}
void dap_trst_reset(void)
{
uint8_t buf[7];
buf[0] = ID_DAP_SWJ_PINS;
buf[1] = DAP_SWJ_nTRST;
buf[2] = 0;
buf[3] = 0;
buf[4] = 4; /* ~ 1 ms*/
buf[5] = 0;
buf[6] = 0;
dbg_dap_cmd(buf, sizeof(buf), 7);
buf[0] = ID_DAP_SWJ_PINS;
buf[1] = DAP_SWJ_nTRST;
buf[2] = DAP_SWJ_nTRST;
dbg_dap_cmd(buf, sizeof(buf), 7);
}
static void dap_line_reset(void)
{
uint8_t buf[] = {
ID_DAP_SWJ_SEQUENCE,
64,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0
};
dbg_dap_cmd(buf, sizeof(buf), 10);
if (buf[0])
DEBUG_WARN("line reset failed\n");
}
static uint32_t wait_word(uint8_t *buf, int size, int len, uint8_t *dp_fault)
{
uint8_t cmd_copy[len];
memcpy(cmd_copy, buf, len);
do {
memcpy(buf, cmd_copy, len);
dbg_dap_cmd(buf, size, len);
if (buf[1] < DAP_TRANSFER_WAIT)
break;
} while (buf[1] == DAP_TRANSFER_WAIT);
if(buf[1] == SWDP_ACK_FAULT) {
*dp_fault = 1;
return 0;
}
if(buf[1] != SWDP_ACK_OK)
raise_exception(EXCEPTION_ERROR, "SWDP invalid ACK");
uint32_t res =
((uint32_t)buf[5] << 24) | ((uint32_t)buf[4] << 16) |
((uint32_t)buf[3] << 8) | (uint32_t)buf[2];
return res;
}
//-----------------------------------------------------------------------------
uint32_t dap_read_reg(ADIv5_DP_t *dp, uint8_t reg)
{
uint8_t buf[8];
uint8_t dap_index = 0;
dap_index = dp->dp_jd_index;
buf[0] = ID_DAP_TRANSFER;
buf[1] = dap_index;
buf[2] = 0x01; // Request size
buf[3] = reg | DAP_TRANSFER_RnW;
uint32_t res = wait_word(buf, 8, 4, &dp->fault);
DEBUG_WIRE("\tdap_read_reg %02x %08x\n", reg, res);
return res;
}
//-----------------------------------------------------------------------------
void dap_write_reg(ADIv5_DP_t *dp, uint8_t reg, uint32_t data)
{
uint8_t buf[8];
DEBUG_PROBE("\tdap_write_reg %02x %08x\n", reg, data);
buf[0] = ID_DAP_TRANSFER;
uint8_t dap_index = 0;
dap_index = dp->dp_jd_index;
buf[1] = dap_index;
buf[2] = 0x01; // Request size
buf[3] = reg & ~DAP_TRANSFER_RnW;;
buf[4] = data & 0xff;
buf[5] = (data >> 8) & 0xff;
buf[6] = (data >> 16) & 0xff;
buf[7] = (data >> 24) & 0xff;
uint8_t cmd_copy[8];
memcpy(cmd_copy, buf, 8);
do {
memcpy(buf, cmd_copy, 8);
dbg_dap_cmd(buf, sizeof(buf), 8);
if (buf[1] < DAP_TRANSFER_WAIT)
break;
} while (buf[1] == DAP_TRANSFER_WAIT);
if (buf[1] > DAP_TRANSFER_WAIT) {
DEBUG_WARN("dap_write_reg %02x data %08x:fault\n", reg, data);
dp->fault = 1;
}
if (buf[1] == DAP_TRANSFER_ERROR) {
DEBUG_WARN("dap_write_reg %02x data %08x: protocoll error\n",
reg, data);
dap_line_reset();
}
}
unsigned int dap_read_block(ADIv5_AP_t *ap, void *dest, uint32_t src,
size_t len, enum align align)
{
uint8_t buf[1024];
unsigned int sz = len >> align;
uint8_t dap_index = 0;
dap_index = ap->dp->dp_jd_index;
buf[0] = ID_DAP_TRANSFER_BLOCK;
buf[1] = dap_index;
buf[2] = sz & 0xff;
buf[3] = (sz >> 8) & 0xff;
buf[4] = SWD_AP_DRW | DAP_TRANSFER_RnW;
dbg_dap_cmd(buf, 1023, 5);
unsigned int transferred = buf[0] + (buf[1] << 8);
if (buf[2] >= DAP_TRANSFER_FAULT) {
DEBUG_WARN("dap_read_block @ %08" PRIx32 " fault -> line reset\n", src);
dap_line_reset();
}
if (sz != transferred) {
return 1;
} else if (align > ALIGN_HALFWORD) {
memcpy(dest, &buf[3], len);
} else {
uint32_t *p = (uint32_t *)&buf[3];
while(sz) {
dest = extract(dest, src, *p, align);
p++;
src += (1 << align);
sz--;
}
}
return (buf[2] > DAP_TRANSFER_WAIT) ? 1 : 0;
}
unsigned int dap_write_block(ADIv5_AP_t *ap, uint32_t dest, const void *src,
size_t len, enum align align)
{
uint8_t buf[1024];
unsigned int sz = len >> align;
uint8_t dap_index = 0;
dap_index = ap->dp->dp_jd_index;
buf[0] = ID_DAP_TRANSFER_BLOCK;
buf[1] = dap_index;
buf[2] = sz & 0xff;
buf[3] = (sz >> 8) & 0xff;
buf[4] = SWD_AP_DRW;
if (align > ALIGN_HALFWORD) {
memcpy(&buf[5], src, len);
} else {
unsigned int size = len;
uint32_t *p = (uint32_t *)&buf[5];
while (size) {
uint32_t tmp = 0;
/* Pack data into correct data lane */
if (align == ALIGN_BYTE) {
tmp = ((uint32_t)*(uint8_t *)src) << ((dest & 3) << 3);
} else {
tmp = ((uint32_t)*(uint16_t *)src) << ((dest & 2) << 3);
}
src = src + (1 << align);
dest += (1 << align);
size--;
*p++ = tmp;
}
}
dbg_dap_cmd(buf, 1023, 5 + (sz << 2));
if (buf[2] > DAP_TRANSFER_FAULT) {
dap_line_reset();
}
return (buf[2] > DAP_TRANSFER_WAIT) ? 1 : 0;
}
//-----------------------------------------------------------------------------
void dap_reset_link(bool jtag)
{
uint8_t buf[128], *p = buf;
//-------------
*p++ = ID_DAP_SWJ_SEQUENCE;
p++;
*p++ = 0xff;
*p++ = 0xff;
*p++ = 0xff;
*p++ = 0xff;
*p++ = 0xff;
*p++ = 0xff;
*p++ = 0xff;
if (jtag) {
*p++ = 0x3c;
*p++ = 0xe7;
*p++ = 0x1f;
buf[1] = ((p - &buf[2]) * 8) - 2;
} else {
*p++ = 0x9e;
*p++ = 0xe7;
*p++ = 0xff;
*p++ = 0xff;
*p++ = 0xff;
*p++ = 0xff;
*p++ = 0xff;
*p++ = 0xff;
*p++ = 0xff;
*p++ = 0x00;
buf[1] = (p - &buf[2]) * 8;
}
dbg_dap_cmd(buf, sizeof(buf), p - buf);
if (!jtag) {
//-------------
buf[0] = ID_DAP_TRANSFER;
buf[1] = 0; // DAP index
buf[2] = 1; // Request size
buf[3] = SWD_DP_R_IDCODE | DAP_TRANSFER_RnW;
dbg_dap_cmd(buf, sizeof(buf), 4);
}
}
//-----------------------------------------------------------------------------
uint32_t dap_read_idcode(ADIv5_DP_t *dp)
{
return dap_read_reg(dp, SWD_DP_R_IDCODE);
}
static uint8_t *mem_access_setup(ADIv5_AP_t *ap, uint8_t *p,
uint32_t addr, enum align align)
{
uint32_t csw = ap->csw | ADIV5_AP_CSW_ADDRINC_SINGLE;
switch (align) {
case ALIGN_BYTE:
csw |= ADIV5_AP_CSW_SIZE_BYTE;
break;
case ALIGN_HALFWORD:
csw |= ADIV5_AP_CSW_SIZE_HALFWORD;
break;
case ALIGN_DWORD:
case ALIGN_WORD:
csw |= ADIV5_AP_CSW_SIZE_WORD;
break;
}
uint8_t dap_index = 0;
dap_index = ap->dp->dp_jd_index;
*p++ = ID_DAP_TRANSFER;
*p++ = dap_index;
*p++ = 3; /* Nr transfers */
*p++ = SWD_DP_W_SELECT;
*p++ = ADIV5_AP_CSW & 0xF0;
*p++ = 0;
*p++ = 0;
*p++ = ap->apsel & 0xff;
*p++ = SWD_AP_CSW;
*p++ = (csw >> 0) & 0xff;
*p++ = (csw >> 8) & 0xff;
*p++ = (csw >> 16) & 0xff;
*p++ = (csw >> 24) & 0xff;
*p++ = SWD_AP_TAR ;
*p++ = (addr >> 0) & 0xff;
*p++ = (addr >> 8) & 0xff;
*p++ = (addr >> 16) & 0xff;
*p++ = (addr >> 24) & 0xff;
return p;
}
void dap_ap_mem_access_setup(ADIv5_AP_t *ap, uint32_t addr, enum align align)
{
uint8_t buf[63];
uint8_t *p = mem_access_setup(ap, buf, addr, align);
dbg_dap_cmd(buf, sizeof(buf), p - buf);
}
uint32_t dap_ap_read(ADIv5_AP_t *ap, uint16_t addr)
{
DEBUG_PROBE("dap_ap_read_start addr %x\n", addr);
uint8_t buf[63], *p = buf;
buf[0] = ID_DAP_TRANSFER;
uint8_t dap_index = 0;
dap_index = ap->dp->dp_jd_index;
*p++ = ID_DAP_TRANSFER;
*p++ = dap_index;
*p++ = 2; /* Nr transfers */
*p++ = SWD_DP_W_SELECT;
*p++ = (addr & 0xF0);
*p++ = 0;
*p++ = 0;
*p++ = ap->apsel & 0xff;
*p++ = (addr & 0x0c) | DAP_TRANSFER_RnW |
((addr & 0x100) ? DAP_TRANSFER_APnDP : 0);
uint32_t res = wait_word(buf, 63, p - buf, &ap->dp->fault);
if ((buf[0] != 2) || (buf[1] != 1)) {
DEBUG_WARN("dap_ap_read error %x\n", buf[1]);
}
return res;
}
void dap_ap_write(ADIv5_AP_t *ap, uint16_t addr, uint32_t value)
{
DEBUG_PROBE("dap_ap_write addr %04x value %08x\n", addr, value);
uint8_t buf[63], *p = buf;
uint8_t dap_index = 0;
dap_index = ap->dp->dp_jd_index;
*p++ = ID_DAP_TRANSFER;
*p++ = dap_index;
*p++ = 2; /* Nr transfers */
*p++ = SWD_DP_W_SELECT;
*p++ = (addr & 0xF0);
*p++ = 0;
*p++ = 0;
*p++ = ap->apsel & 0xff;
*p++ = (addr & 0x0c) | ((addr & 0x100) ? DAP_TRANSFER_APnDP : 0);
*p++ = (value >> 0) & 0xff;
*p++ = (value >> 8) & 0xff;
*p++ = (value >> 16) & 0xff;
*p++ = (value >> 24) & 0xff;
dbg_dap_cmd(buf, sizeof(buf), p - buf);
if ((buf[0] != 2) || (buf[1] != 1)) {
DEBUG_WARN("dap_ap_write error %x\n", buf[1]);
}
}
void dap_read_single(ADIv5_AP_t *ap, void *dest, uint32_t src, enum align align)
{
uint8_t buf[63];
uint8_t *p = mem_access_setup(ap, buf, src, align);
*p++ = SWD_AP_DRW | DAP_TRANSFER_RnW;
*p++ = SWD_DP_R_RDBUFF | DAP_TRANSFER_RnW;
buf[2] = 5;
uint32_t tmp = wait_word(buf, 63, p - buf, &ap->dp->fault);
dest = extract(dest, src, tmp, align);
}
void dap_write_single(ADIv5_AP_t *ap, uint32_t dest, const void *src,
enum align align)
{
uint8_t buf[63];
uint8_t *p = mem_access_setup(ap, buf, dest, align);
*p++ = SWD_AP_DRW;
uint32_t tmp = 0;
/* Pack data into correct data lane */
switch (align) {
case ALIGN_BYTE:
tmp = ((uint32_t)*(uint8_t *)src) << ((dest & 3) << 3);
break;
case ALIGN_HALFWORD:
tmp = ((uint32_t)*(uint16_t *)src) << ((dest & 2) << 3);
break;
case ALIGN_DWORD:
case ALIGN_WORD:
tmp = *(uint32_t *)src;
break;
}
*p++ = (tmp >> 0) & 0xff;
*p++ = (tmp >> 8) & 0xff;
*p++ = (tmp >> 16) & 0xff;
*p++ = (tmp >> 24) & 0xff;
buf[2] = 4;
dbg_dap_cmd(buf, sizeof(buf), p - buf);
}
void dap_jtagtap_tdi_tdo_seq(uint8_t *DO, bool final_tms, const uint8_t *TMS,
const uint8_t *DI, int ticks)
{
DEBUG_PROBE("dap_jtagtap_tdi_tdo_seq %s %d ticks\n",
(final_tms) ? "final" : "", ticks);
uint8_t buf[64];
const uint8_t *din = DI;
uint8_t *dout = DO;
if (!TMS) {
int last_byte = last_byte = (ticks - 1) >> 3;
int last_bit = (ticks - 1) & 7;
if (final_tms)
ticks --;
while (ticks) {
int transfers = ticks;
if (transfers > 64)
transfers = 64;
uint8_t *p = buf;
*p++ = ID_DAP_JTAG_SEQUENCE;
*p++ = 1;
*p++ = ((transfers == 64) ? 0 : transfers) |
((DO) ? DAP_JTAG_TDO_CAPTURE : 0);
int n_di_bytes = (transfers + 7) >> 3;
if (din) {
p = memcpy(p, din, n_di_bytes);
din += n_di_bytes;
} else {
p = memset(p, 0xff, n_di_bytes);
}
p += n_di_bytes;
dbg_dap_cmd(buf, sizeof(buf), p - buf);
if (buf[0] != DAP_OK)
DEBUG_WARN("dap_jtagtap_tdi_tdo_seq failed %02x\n", buf[0]);
if (dout) {
memcpy(dout, &buf[1], (transfers + 7) >> 3);
dout += (transfers + 7) >> 3;
}
ticks -= transfers;
}
if (final_tms) {
uint8_t *p = buf;
*p++ = ID_DAP_JTAG_SEQUENCE;
*p++ = 1;
*p++ = 1 | ((dout) ? DAP_JTAG_TDO_CAPTURE : 0) | DAP_JTAG_TMS;
if (din) {
*p++ = ((DI[last_byte] & (1 << last_bit)) ? 1 : 0);
} else {
*p++ = 0;
}
dbg_dap_cmd(buf, sizeof(buf), p - buf);
if (buf[0] == DAP_ERROR)
DEBUG_WARN("dap_jtagtap_tdi_tdo_seq failed %02x\n", buf[0]);
if (dout) {
if (buf[1] & 1)
DO[last_byte] |= (1 << last_bit);
else
DO[last_byte] &= ~(1 << last_bit);
}
}
} else {
while(ticks) {
uint8_t *p = buf;
int transfers = ticks;
if (transfers > 64)
transfers = 64;
p = buf;
*p++ = ID_DAP_JTAG_SEQUENCE;
*p++ = transfers;
for (int i = 0; i < transfers; i++) {
*p++ = 1 | ((DO) ? DAP_JTAG_TDO_CAPTURE : 0) |
((TMS[i >> 3] & (1 << (i & 7))) ? DAP_JTAG_TMS : 0);
if (DI)
*p++ = (DI[i >> 3] & (1 << (i & 7))) ? 1 : 0;
else
*p++ = 1;
}
dbg_dap_cmd(buf, sizeof(buf), p - buf);
if (buf[0] == DAP_ERROR)
DEBUG_WARN("dap_jtagtap_tdi_tdo_seq failed %02x\n", buf[0]);
if (DO) {
for (int i = 0; i < transfers; i++) {
if (buf[i + 1])
DO[i >> 3] |= (1 << (i & 7));
else
DO[i >> 3] &= ~(1 << (i & 7));
}
}
ticks -= transfers;
}
}
}
int dap_jtag_configure(void)
{
uint8_t buf[64], *p = &buf[2];
int i = 0;
for (; i < jtag_dev_count; i++) {
struct jtag_dev_s *jtag_dev = &jtag_devs[i];
*p++ = jtag_dev->ir_len;
DEBUG_PROBE("irlen %d\n", jtag_dev->ir_len);
}
if ((!i || i >= JTAG_MAX_DEVS))
return -1;
buf[0] = 0x15;
buf[1] = i;
dbg_dap_cmd(buf, sizeof(buf), p - buf);
if (buf[0] != DAP_OK)
DEBUG_WARN("dap_jtag_configure Failed %02x\n", buf[0]);
return 0;
}
void dap_swdptap_seq_out(uint32_t MS, int ticks)
{
uint8_t buf[64] = {
ID_DAP_SWJ_SEQUENCE,
ticks,
(MS >> 0) & 0xff,
(MS >> 8) & 0xff,
(MS >> 16) & 0xff,
(MS >> 24) & 0xff
};
dbg_dap_cmd(buf, 64, 2 + ((ticks +7) >> 3));
if (buf[0])
DEBUG_WARN("dap_swdptap_seq_out error\n");
}
void dap_swdptap_seq_out_parity(uint32_t MS, int ticks)
{
uint8_t buf[] = {
ID_DAP_SWJ_SEQUENCE,
ticks + 1,
(MS >> 0) & 0xff,
(MS >> 8) & 0xff,
(MS >> 16) & 0xff,
(MS >> 24) & 0xff,
__builtin_parity(MS) & 1
};
dbg_dap_cmd(buf, 1, sizeof(buf));
if (buf[0])
DEBUG_WARN("dap_swdptap_seq_out error\n");
}
bool dap_sequence_test(void)
{
uint8_t buf[4] = {
ID_DAP_SWD_SEQUENCE,
0x1,
0x81, /* Read one bit */
0 /* one idle cycle */
};
dbg_dap_cmd(buf, sizeof(buf), 3);
return (buf[0] == DAP_OK);
}
#define SWD_SEQUENCE_IN 0x80
uint32_t dap_swdptap_seq_in(int ticks)
{
uint8_t buf[5] = {
ID_DAP_SWD_SEQUENCE,
1,
ticks + SWD_SEQUENCE_IN
};
dbg_dap_cmd(buf, 2 + ((ticks + 7) >> 3), 3);
uint32_t res = 0;
int len = (ticks + 7) >> 3;
while (len--) {
res <<= 8;
res += buf[len + 1];
}
return res;
}
bool dap_swdptap_seq_in_parity(uint32_t *ret, int ticks)
{
(void)ticks;
uint8_t buf[8] = {
ID_DAP_SWD_SEQUENCE,
1,
33 + SWD_SEQUENCE_IN,
};
dbg_dap_cmd(buf, 7, 4);
uint32_t res = 0;
int len = 4;
while (len--) {
res <<= 8;
res += buf[len + 1];
}
*ret = res;
unsigned int parity = __builtin_parity(res) & 1;
parity ^= (buf[5] % 1);
DEBUG_WARN("Res %08" PRIx32" %d\n", *ret, parity & 1);
return (!(parity & 1));
}

View File

@ -0,0 +1,97 @@
/*
* Copyright (c) 2013-2015, Alex Taradov <alex@taradov.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _DAP_H_
#define _DAP_H_
/*- Includes ----------------------------------------------------------------*/
#include <stdint.h>
#include <stdbool.h>
#include "adiv5.h"
/*- Definitions -------------------------------------------------------------*/
enum
{
DAP_INFO_VENDOR = 0x01,
DAP_INFO_PRODUCT = 0x02,
DAP_INFO_SER_NUM = 0x03,
DAP_INFO_FW_VER = 0x04,
DAP_INFO_DEVICE_VENDOR = 0x05,
DAP_INFO_DEVICE_NAME = 0x06,
DAP_INFO_CAPABILITIES = 0xf0,
DAP_INFO_TDT = 0xf1,
DAP_INFO_SWO_BUF_SIZE = 0xfd,
DAP_INFO_PACKET_COUNT = 0xfe,
DAP_INFO_PACKET_SIZE = 0xff,
};
enum
{
DAP_CAP_SWD = (1 << 0),
DAP_CAP_JTAG = (1 << 1),
DAP_CAP_SWO_UART = (1 << 2),
DAP_CAP_SWO_MANCHESTER = (1 << 3),
DAP_CAP_ATOMIC_CMD = (1 << 4),
DAP_CAP_TDT = (1 << 5),
DAP_CAP_SWO_STREAMING = (1 << 6),
};
/*- Prototypes --------------------------------------------------------------*/
void dap_led(int index, int state);
void dap_connect(bool jtag);
void dap_disconnect(void);
void dap_transfer_configure(uint8_t idle, uint16_t count, uint16_t retry);
void dap_swd_configure(uint8_t cfg);
int dap_info(int info, uint8_t *data, int size);
void dap_reset_target(void);
void dap_srst_set_val(bool assert);
void dap_trst_reset(void);
void dap_reset_target_hw(int state);
void dap_reset_pin(int state);
uint32_t dap_read_reg(ADIv5_DP_t *dp, uint8_t reg);
void dap_write_reg(ADIv5_DP_t *dp, uint8_t reg, uint32_t data);
void dap_reset_link(bool jtag);
uint32_t dap_read_idcode(ADIv5_DP_t *dp);
unsigned int dap_read_block(ADIv5_AP_t *ap, void *dest, uint32_t src,
size_t len, enum align align);
unsigned int dap_write_block(ADIv5_AP_t *ap, uint32_t dest, const void *src,
size_t len, enum align align);
void dap_ap_mem_access_setup(ADIv5_AP_t *ap, uint32_t addr, enum align align);
uint32_t dap_ap_read(ADIv5_AP_t *ap, uint16_t addr);
void dap_ap_write(ADIv5_AP_t *ap, uint16_t addr, uint32_t value);
void dap_read_single(ADIv5_AP_t *ap, void *dest, uint32_t src, enum align align);
void dap_write_single(ADIv5_AP_t *ap, uint32_t dest, const void *src,
enum align align);
int dbg_dap_cmd(uint8_t *data, int size, int rsize);
void dap_jtagtap_tdi_tdo_seq(uint8_t *DO, bool final_tms, const uint8_t *TMS,
const uint8_t *DI, int ticks);
int dap_jtag_configure(void);
void dap_swdptap_seq_out(uint32_t MS, int ticks);
void dap_swdptap_seq_out_parity(uint32_t MS, int ticks);
bool dap_sequence_test(void);
#endif // _DAP_H_

View File

@ -0,0 +1,661 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2011 Black Sphere Technologies Ltd.
* Copyright (C) 2018 Uwe Bonnes(bon@elektron.ikp.physik.tu-darmstadt.de)
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "general.h"
#include "gdb_if.h"
#include "target.h"
#include <assert.h>
#include <unistd.h>
#include <sys/time.h>
#include "ftdi_bmp.h"
#include <ftdi.h>
struct ftdi_context *ftdic;
#define BUF_SIZE 4096
static uint8_t outbuf[BUF_SIZE];
static uint16_t bufptr = 0;
cable_desc_t *active_cable;
data_desc_t active_state;
cable_desc_t cable_desc[] = {
{
/* Direct connection from FTDI to Jtag/Swd.
Pin 6 direct connected to RST.*/
.vendor = 0x0403,
.product = 0x6014,
.interface = INTERFACE_A,
// No explicit reset
.bb_swdio_in_port_cmd = GET_BITS_LOW,
.bb_swdio_in_pin = MPSSE_CS,
.description = "UM232H",
.name = "um232h"
},
{
/* Direct connection from FTDI to Jtag/Swd.
Pin 6 direct connected to RST.*/
.vendor = 0x0403,
.product = 0x6010,
.interface = INTERFACE_A,
.init.data_low = PIN6, /* PULL nRST high*/
.bb_swdio_in_port_cmd = GET_BITS_LOW,
.bb_swdio_in_pin = MPSSE_CS,
.assert_srst.data_low = ~PIN6,
.assert_srst.ddr_low = PIN6,
.deassert_srst.data_low = PIN6,
.deassert_srst.ddr_low = ~PIN6,
.description = "FLOSS-JTAG",
.name = "flossjtag"
},
{
/* MPSSE_SK (DB0) ----------- SWDCK/JTCK
* MPSSE-DO (DB1) -- 470 R -- SWDIO/JTMS
* MPSSE-DI (DB2) ----------- SWDIO/JTMS
* DO is tristated with SWD read, so
* resistor is not necessary, but protects
* from contentions in case of errors.
* JTAG not possible
* PIN6 (DB6) ----------- NRST */
.vendor = 0x0403,
.product = 0x6010,/*FT2232H*/
.interface = INTERFACE_B,
.init.data_low = PIN4, /* Pull up pin 4 */
.init.ddr_low = PIN4, /* Pull up pin 4 */
.mpsse_swd_read.set_data_low = MPSSE_DO,
.mpsse_swd_write.set_data_low = MPSSE_DO,
.assert_srst.data_low = ~PIN6,
.assert_srst.ddr_low = PIN6,
.deassert_srst.data_low = PIN6,
.deassert_srst.ddr_low = ~PIN6,
.target_voltage_cmd = GET_BITS_LOW,
.target_voltage_pin = PIN4, /* Always read as target voltage present.*/
.description = "USBMATE",
.name = "usbmate"
},
{
/* MPSSE_SK (DB0) ----------- SWDCK/JTCK
* MPSSE-DO (DB1) -- 470 R -- SWDIO/JTMS
* MPSSE-DI (DB2) ----------- SWDIO/JTMS
* DO is tristated with SWD read, so
* resistor is not necessary, but protects
* from contentions in case of errors.
* JTAG not possible.*/
.vendor = 0x0403,
.product = 0x6014,/*FT232H*/
.interface = INTERFACE_A,
.mpsse_swd_read.set_data_low = MPSSE_DO,
.mpsse_swd_write.set_data_low = MPSSE_DO,
.name = "ft232h_resistor_swd"
},
{
/* Buffered connection from FTDI to Jtag/Swd.
* TCK and TMS not independant switchable!
* SWD not possible.
* PIN4 low enables buffers
* PIN5 Low indicates VRef applied
* PIN6 reads back SRST
* CBUS PIN1 Sets SRST
* CBUS PIN2 low drives SRST
*/
.vendor = 0x0403,
.product = 0x6010,
.interface = INTERFACE_A,
.init.ddr_low = PIN4,
.init.data_high = PIN4 | PIN3 | PIN2,
.init.ddr_high = PIN4 | PIN3 | PIN2 | PIN1 | PIN0,
.assert_srst.data_high = ~PIN3,
.deassert_srst.data_high = PIN3,
.srst_get_port_cmd = GET_BITS_LOW,
.srst_get_pin = PIN6,
.description = "FTDIJTAG",
.name = "ftdijtag"
},
{
/* UART/SWO on Interface A
* JTAG and control on INTERFACE_B
* Bit 5 high selects SWD-WRITE (TMS routed to MPSSE_DI)
* Bit 6 high selects JTAG vs SWD (TMS routed to MPSSE_CS)
* BCBUS 1 (Output) N_SRST
* BCBUS 2 (Input/ Internal Pull Up) V_ISO available
*
* For bitbanged SWD, set Bit 5 low and select SWD read with
* Bit 6 low. Read Connector TMS as MPSSE_DI.
*
* TDO is routed to Interface 0 RXD as SWO or with Uart
* Connector pin 10 pulled to ground will connect Interface 0 RXD
* to UART connector RXD
*/
.vendor = 0x0403,
.product = 0x6010,
.interface = INTERFACE_B,
.init.data_low = PIN6 | PIN5,
.init.ddr_low = PIN6 | PIN5,
.init.data_high = PIN1 | PIN2,
.assert_srst.data_high = ~PIN1,
.assert_srst.ddr_high = PIN1,
.deassert_srst.data_high = PIN1,
.deassert_srst.ddr_high = ~PIN1,
.mpsse_swd_read.clr_data_low = PIN5 | PIN6,
.mpsse_swd_write.set_data_low = PIN5,
.mpsse_swd_write.clr_data_low = PIN6,
.jtag.set_data_low = PIN6,
.target_voltage_cmd = GET_BITS_HIGH,
.target_voltage_pin = ~PIN2,
.name = "ftdiswd",
.description = "FTDISWD"
},
{
.vendor = 0x15b1,
.product = 0x0003,
.interface = INTERFACE_A,
.init.ddr_low = PIN5,
.name = "olimex"
},
{
/* Buffered connection from FTDI to Jtag/Swd.
* TCK and TMS not independant switchable!
* => SWD not possible.
* DBUS PIN4 / JTAGOE low enables buffers
* DBUS PIN5 / TRST high drives nTRST low OC
* DBUS PIN6 / RST high drives nSRST low OC
* CBUS PIN0 reads back SRST
*/
.vendor = 0x0403,
.product = 0xbdc8,
.interface = INTERFACE_A,
/* Drive low to activate JTAGOE and deassert TRST/RST.*/
.init.data_low = 0,
.init.ddr_low = PIN6 | PIN5 | PIN4,
.init.ddr_high = PIN2, /* ONE LED */
.assert_srst.data_low = PIN6,
.deassert_srst.data_low = ~PIN6,
.srst_get_port_cmd = GET_BITS_HIGH,
.srst_get_pin = PIN0,
.name = "turtelizer",
.description = "Turtelizer JTAG/RS232 Adapter"
},
{
/* https://reference.digilentinc.com/jtag_hs1/jtag_hs1
* No schmeatics available.
* Buffered from FTDI to Jtag/Swd announced
* Independant switch for TMS not known
* => SWD not possible. */
.vendor = 0x0403,
.product = 0xbdc8,
.interface = INTERFACE_A,
.name = "jtaghs1"
},
{
/* Direct connection from FTDI to Jtag/Swd assumed.*/
.vendor = 0x0403,
.product = 0xbdc8,
.interface = INTERFACE_A,
.init.data_low = MPSSE_CS | MPSSE_DO | MPSSE_DI,
.init.ddr_low = MPSSE_CS | MPSSE_DO | MPSSE_SK,
.bb_swdio_in_port_cmd = GET_BITS_LOW,
.bb_swdio_in_pin = MPSSE_CS,
.name = "ftdi"
},
{
/* Product name not unique! Assume SWD not possible.*/
.vendor = 0x0403,
.product = 0x6014,
.interface = INTERFACE_A,
.init.data_low = PIN7,
.init.ddr_low = PIN7,
.init.data_high = PIN5,
.init.ddr_high = PIN5 | PIN4 | PIN3 | PIN2 | PIN1 | PIN0,
.name = "digilent"
},
{
/* Direct connection from FTDI to Jtag/Swd assumed.*/
.vendor = 0x0403,
.product = 0x6014,
.interface = INTERFACE_A,
.init.data_low = MPSSE_CS | MPSSE_DO | MPSSE_DI,
.init.ddr_low = MPSSE_CS | MPSSE_DO | MPSSE_SK,
.bb_swdio_in_port_cmd = GET_BITS_LOW,
.bb_swdio_in_pin = MPSSE_CS,
.name = "ft232h"
},
{
/* Direct connection from FTDI to Jtag/Swd assumed.*/
.vendor = 0x0403,
.product = 0x6011,
.interface = INTERFACE_A,
.bb_swdio_in_port_cmd = GET_BITS_LOW,
.bb_swdio_in_pin = MPSSE_CS,
.name = "ft4232h"
},
{
/* http://www.olimex.com/dev/pdf/ARM-USB-OCD.pdf.
* DBUS 4 global enables JTAG Buffer.
* => TCK and TMS not independant switchable!
* => SWD not possible. */
.vendor = 0x15ba,
.product = 0x002b,
.interface = INTERFACE_A,
.init.ddr_low = PIN4,
.init.data_high = PIN3 | PIN1 | PIN0,
.init.ddr_high = PIN4 | PIN3 | PIN1 | PIN0,
.name = "arm-usb-ocd-h"
},
{
}
};
int ftdi_bmp_init(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info)
{
int err;
cable_desc_t *cable = &cable_desc[0];
for(; cable->name; cable++) {
if (strncmp(cable->name, cl_opts->opt_cable, strlen(cable->name)) == 0)
break;
}
if (!cable->name ) {
DEBUG_WARN( "No cable matching found for %s\n", cl_opts->opt_cable);
return -1;
}
active_cable = cable;
memcpy(&active_state, &active_cable->init, sizeof(data_desc_t));
/* If swd_(read|write) is not given for the selected cable and
the 'e' command line argument is give, assume resistor SWD
connection.*/
if (cl_opts->external_resistor_swd &&
(active_cable->mpsse_swd_read.set_data_low == 0) &&
(active_cable->mpsse_swd_read.clr_data_low == 0) &&
(active_cable->mpsse_swd_read.set_data_high == 0) &&
(active_cable->mpsse_swd_read.clr_data_high == 0) &&
(active_cable->mpsse_swd_write.set_data_low == 0) &&
(active_cable->mpsse_swd_write.clr_data_low == 0) &&
(active_cable->mpsse_swd_write.set_data_high == 0) &&
(active_cable->mpsse_swd_write.clr_data_high == 0)) {
DEBUG_INFO("Using external resistor SWD\n");
active_cable->mpsse_swd_read.set_data_low = MPSSE_DO;
active_cable->mpsse_swd_write.set_data_low = MPSSE_DO;
} else if (!libftdi_swd_possible(NULL, NULL) &&
!cl_opts->opt_usejtag) {
DEBUG_WARN("SWD with cable not possible, trying JTAG\n");
cl_opts->opt_usejtag = true;
}
if(ftdic) {
ftdi_usb_close(ftdic);
ftdi_free(ftdic);
ftdic = NULL;
}
if((ftdic = ftdi_new()) == NULL) {
DEBUG_WARN( "ftdi_new: %s\n",
ftdi_get_error_string(ftdic));
abort();
}
info->ftdic = ftdic;
if((err = ftdi_set_interface(ftdic, active_cable->interface)) != 0) {
DEBUG_WARN( "ftdi_set_interface: %d: %s\n",
err, ftdi_get_error_string(ftdic));
goto error_1;
}
if((err = ftdi_usb_open_desc(
ftdic, active_cable->vendor, active_cable->product,
active_cable->description, cl_opts->opt_serial)) != 0) {
DEBUG_WARN( "unable to open ftdi device: %d (%s)\n",
err, ftdi_get_error_string(ftdic));
goto error_1;
}
if((err = ftdi_set_latency_timer(ftdic, 1)) != 0) {
DEBUG_WARN( "ftdi_set_latency_timer: %d: %s\n",
err, ftdi_get_error_string(ftdic));
goto error_2;
}
if((err = ftdi_set_baudrate(ftdic, 1000000)) != 0) {
DEBUG_WARN( "ftdi_set_baudrate: %d: %s\n",
err, ftdi_get_error_string(ftdic));
goto error_2;
}
if((err = ftdi_write_data_set_chunksize(ftdic, BUF_SIZE)) != 0) {
DEBUG_WARN( "ftdi_write_data_set_chunksize: %d: %s\n",
err, ftdi_get_error_string(ftdic));
goto error_2;
}
assert(ftdic != NULL);
#ifdef _Ftdi_Pragma
err = ftdi_tcioflush(ftdic);
#else
err = ftdi_usb_purge_buffers(ftdic);
#endif
if (err != 0) {
DEBUG_WARN("ftdi_tcioflush(ftdi_usb_purge_buffer): %d: %s\n",
err, ftdi_get_error_string(ftdic));
goto error_2;
}
/* Reset MPSSE controller. */
err = ftdi_set_bitmode(ftdic, 0, BITMODE_RESET);
if (err != 0) {
DEBUG_WARN("ftdi_set_bitmode: %d: %s\n",
err, ftdi_get_error_string(ftdic));
goto error_2;
}
/* Enable MPSSE controller. Pin directions are set later.*/
err = ftdi_set_bitmode(ftdic, 0, BITMODE_MPSSE);
if (err != 0) {
DEBUG_WARN("ftdi_set_bitmode: %d: %s\n",
err, ftdi_get_error_string(ftdic));
goto error_2;
}
uint8_t ftdi_init[16];
/* Test for pending garbage.*/
int garbage = ftdi_read_data(ftdic, ftdi_init, sizeof(ftdi_init));
if (garbage > 0) {
DEBUG_WARN("FTDI init garbage at start:");
for (int i = 0; i < garbage; i++)
DEBUG_WARN(" %02x", ftdi_init[i]);
DEBUG_WARN("\n");
}
int index = 0;
ftdi_init[index++]= LOOPBACK_END; /* FT2232D gets upset otherwise*/
switch(ftdic->type) {
case TYPE_2232H:
case TYPE_4232H:
case TYPE_232H:
ftdi_init[index++] = DIS_DIV_5;
break;
case TYPE_2232C:
break;
default:
DEBUG_WARN("FTDI Chip has no MPSSE\n");
goto error_2;
}
ftdi_init[index++]= TCK_DIVISOR;
/* Use CLK/2 for about 50 % SWDCLK duty cycle on FT2232c.*/
ftdi_init[index++]= 1;
ftdi_init[index++]= 0;
ftdi_init[index++]= SET_BITS_LOW;
ftdi_init[index++]= active_state.data_low;
ftdi_init[index++]= active_state.ddr_low;
ftdi_init[index++]= SET_BITS_HIGH;
ftdi_init[index++]= active_state.data_high;
ftdi_init[index++]= active_state.ddr_high;
libftdi_buffer_write(ftdi_init, index);
libftdi_buffer_flush();
garbage = ftdi_read_data(ftdic, ftdi_init, sizeof(ftdi_init));
if (garbage > 0) {
DEBUG_WARN("FTDI init garbage at end:");
for (int i = 0; i < garbage; i++)
DEBUG_WARN(" %02x", ftdi_init[i]);
DEBUG_WARN("\n");
} return 0;
error_2:
ftdi_usb_close(ftdic);
error_1:
ftdi_free(ftdic);
return -1;
}
static void libftdi_set_data(data_desc_t* data)
{
uint8_t cmd[6];
int index = 0;
if ((data->data_low) || (data->ddr_low)) {
if (data->data_low > 0)
active_state.data_low |= (data->data_low & 0xff);
else if (data->data_low < 0)
active_state.data_low &= (data->data_low & 0xff);
if (data->ddr_low > 0)
active_state.ddr_low |= (data->ddr_low & 0xff);
else if (data->ddr_low < 0)
active_state.ddr_low &= (data->ddr_low & 0xff);
cmd[index++] = SET_BITS_LOW;
cmd[index++] = active_state.data_low;
cmd[index++] = active_state.ddr_low;
}
if ((data->data_high) || (data->ddr_high)) {
if (data->data_high > 0)
active_state.data_high |= (data->data_high & 0xff);
else if (data->data_high < 0)
active_state.data_high &= (data->data_high & 0xff);
if (data->ddr_high > 0)
active_state.ddr_high |= (data->ddr_high & 0xff);
else if (data->ddr_high < 0)
active_state.ddr_high &= (data->ddr_high & 0xff);
cmd[index++] = SET_BITS_HIGH;
cmd[index++] = active_state.data_high;
cmd[index++] = active_state.ddr_high;
}
if (index) {
libftdi_buffer_write(cmd, index);
libftdi_buffer_flush();
}
}
void libftdi_srst_set_val(bool assert)
{
if (assert)
libftdi_set_data(&active_cable->assert_srst);
else
libftdi_set_data(&active_cable->deassert_srst);
}
bool libftdi_srst_get_val(void)
{
uint8_t cmd[1] = {0};
uint8_t pin = 0;
if (active_cable->srst_get_port_cmd && active_cable->srst_get_pin) {
cmd[0]= active_cable->srst_get_port_cmd;
pin = active_cable->srst_get_pin;
} else if (active_cable->assert_srst.data_low &&
active_cable->assert_srst.ddr_low) {
cmd[0]= GET_BITS_LOW;
pin = active_cable->assert_srst.data_low;
} else if (active_cable->assert_srst.data_high &&
active_cable->assert_srst.ddr_high) {
cmd[0]= GET_BITS_HIGH;
pin = active_cable->assert_srst.data_high;
}else {
return false;
}
libftdi_buffer_write(cmd, 1);
uint8_t data[1];
libftdi_buffer_read(data, 1);
bool res = false;
if (((pin < 0x7f) || (pin == PIN7)))
res = data[0] & pin;
else
res = !(data[0] & ~pin);
return res;
}
void libftdi_buffer_flush(void)
{
if (!bufptr)
return;
DEBUG_WIRE("Flush %d\n", bufptr);
#if defined(USE_USB_VERSION_BIT)
static struct ftdi_transfer_control *tc_write = NULL;
if (tc_write)
ftdi_transfer_data_done(tc_write);
tc_write = ftdi_write_data_submit(ftdic, outbuf, bufptr);
#else
assert(ftdi_write_data(ftdic, outbuf, bufptr) == bufptr);
DEBUG_WIRE("FT2232 libftdi_buffer flush: %d bytes\n", bufptr);
#endif
bufptr = 0;
}
int libftdi_buffer_write(const uint8_t *data, int size)
{
if((bufptr + size) / BUF_SIZE > 0) libftdi_buffer_flush();
DEBUG_WIRE("Write %d bytes:", size);
for (int i = 0; i < size; i++) {
DEBUG_WIRE(" %02x", data[i]);
if (i && ((i & 0xf) == 0xf))
DEBUG_WIRE("\n\t");
}
DEBUG_WIRE("\n");
memcpy(outbuf + bufptr, data, size);
bufptr += size;
return size;
}
int libftdi_buffer_read(uint8_t *data, int size)
{
#if defined(USE_USB_VERSION_BIT)
struct ftdi_transfer_control *tc;
outbuf[bufptr++] = SEND_IMMEDIATE;
libftdi_buffer_flush();
tc = ftdi_read_data_submit(ftdic, data, size);
ftdi_transfer_data_done(tc);
#else
int index = 0;
const uint8_t cmd[1] = {SEND_IMMEDIATE};
libftdi_buffer_write(cmd, 1);
libftdi_buffer_flush();
while((index += ftdi_read_data(ftdic, data + index, size-index)) != size);
#endif
DEBUG_WIRE("Read %d bytes:", size);
for (int i = 0; i < size; i++) {
DEBUG_WIRE(" %02x", data[i]);
if (i && ((i & 0xf) == 0xf))
DEBUG_WIRE("\n\t");
}
DEBUG_WIRE("\n");
return size;
}
void libftdi_jtagtap_tdi_tdo_seq(
uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int ticks)
{
int rsize, rticks;
if(!ticks) return;
if (!DI && !DO) return;
DEBUG_WIRE("libftdi_jtagtap_tdi_tdo_seq %s ticks: %d\n",
(DI && DO) ? "read/write" : ((DI) ? "write" : "read"), ticks);
if(final_tms) ticks--;
rticks = ticks & 7;
ticks >>= 3;
uint8_t data[8];
uint8_t cmd = ((DO)? MPSSE_DO_READ : 0) |
((DI)? (MPSSE_DO_WRITE | MPSSE_WRITE_NEG) : 0) | MPSSE_LSB;
rsize = ticks;
if(ticks) {
data[0] = cmd;
data[1] = ticks - 1;
data[2] = 0;
libftdi_buffer_write(data, 3);
if (DI)
libftdi_buffer_write(DI, ticks);
}
int index = 0;
if(rticks) {
rsize++;
data[index++] = cmd | MPSSE_BITMODE;
data[index++] = rticks - 1;
if (DI)
data[index++] = DI[ticks];
}
if(final_tms) {
rsize++;
data[index++] = MPSSE_WRITE_TMS | ((DO)? MPSSE_DO_READ : 0) |
MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG;
data[index++] = 0;
if (DI)
data[index++] = (DI[ticks] & (1 << rticks)) ? 0x81 : 0x01;
}
if (index)
libftdi_buffer_write(data, index);
if (DO) {
int index = 0;
uint8_t *tmp = alloca(rsize);
libftdi_buffer_read(tmp, rsize);
if(final_tms) rsize--;
while(rsize--) {
*DO++ = tmp[index++];
}
if (rticks == 0)
*DO++ = 0;
if(final_tms) {
rticks++;
*(--DO) >>= 1;
*DO |= tmp[index] & 0x80;
} else DO--;
if(rticks) {
*DO >>= (8-rticks);
}
}
}
const char *libftdi_target_voltage(void)
{
uint8_t pin = active_cable->target_voltage_pin;
if (active_cable->target_voltage_cmd && pin) {
libftdi_buffer_write(&active_cable->target_voltage_cmd, 1);
uint8_t data[1];
libftdi_buffer_read(data, 1);
bool res = false;
if (((pin < 0x7f) || (pin == PIN7)))
res = data[0] & pin;
else
res = !(data[0] & ~pin);
if (res)
return "Present";
else
return "Absent";
}
return NULL;
}
static uint16_t divisor;
void libftdi_max_frequency_set(uint32_t freq)
{
uint32_t clock;
if (ftdic->type == TYPE_2232C)
clock = 12 * 1000 * 1000;
else
/* Undivided clock set during startup*/
clock = 60 * 1000 * 1000;
uint32_t div = (clock + 2 * freq - 1)/ freq;
if ((div < 4) && (ftdic->type = TYPE_2232C))
div = 4; /* Avoid bad unsymetrict FT2232C clock at 6 MHz*/
divisor = div / 2 - 1;
uint8_t buf[3];
buf[0] = TCK_DIVISOR;
buf[1] = divisor & 0xff;
buf[2] = (divisor >> 8) & 0xff;
libftdi_buffer_write(buf, 3);
}
uint32_t libftdi_max_frequency_get(void)
{
uint32_t clock;
if (ftdic->type == TYPE_2232C)
clock = 12 * 1000 * 1000;
else
/* Undivided clock set during startup*/
clock = 60 * 1000 * 1000;
return clock/ ( 2 *(divisor + 1));
}

View File

@ -0,0 +1,155 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2011 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
* Copyright (C) 2018 Uwe Bonnes (non@elektron.ikp.physik.tu-darmstadt.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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __FTDI_BMP_H
#define __FTDI_BMP_H
#include "cl_utils.h"
#include "jtagtap.h"
#include "bmp_hosted.h"
typedef struct data_desc_s {
int16_t data_low;
int16_t ddr_low;
int16_t data_high;
int16_t ddr_high;
}data_desc_t;
typedef struct pin_settings_s {
uint8_t set_data_low;
uint8_t clr_data_low;
uint8_t set_data_high;
uint8_t clr_data_high;
}pin_settings_t;
typedef struct cable_desc_s {
int vendor;
int product;
int interface;
/* Initial (C|D)(Bus|Ddr) values for additional pins.
* MPSSE_CS|DI|DO|SK are initialized accordig to mode.*/
data_desc_t init;
/* MPSSE command to read TMS/SWDIO in bitbanging SWD.
* In many cases this is the TMS port, so then use "GET_PIN_LOW".*/
uint8_t bb_swdio_in_port_cmd;
/* bus bit to read TMS/SWDIO in bitbanging SWD.
* In many cases this is the TMS port, so then use "MPSSE_CS".*/
uint8_t bb_swdio_in_pin;
/* Bus data to allow bitbanging switched SWD read.
* TMS is routed to bb_swdio_in_port/pin.*/
pin_settings_t bb_swd_read;
/* Bus data to allow bitbanging switched SWD write.
* TMS is routed to MPSSE_CS.*/
pin_settings_t bb_swd_write;
/* dbus_data, dbus_ddr, cbus_data, cbus_ddr value to assert SRST.
* E.g. with CBUS Pin 1 low,
* give data_high = ~PIN1, ddr_high = PIN1 */
data_desc_t assert_srst;
/* Bus_data, dbus_ddr, cbus_data, cbus_ddr value to release SRST.
* E.g. with CBUS Pin 1 floating with internal pull up,
* give data_high = PIN1, ddr_high = ~PIN1 */
data_desc_t deassert_srst;
/* Command to read back SRST. If 0, port from assert_srst is used*/
uint8_t srst_get_port_cmd;
/* PIN to read back as SRST. if 0 port from assert_srst is ised.
* Use PINX if active high, use Complement (~PINX) if active low*/
uint8_t srst_get_pin;
/* Bbus data for pure MPSSE SWD read.
* Use together with swd_write if by some bits on DBUS,
* SWDIO can be routed to TDI and TDO.
* If both mpsse_swd_read|write and
* bitbang_swd_dbus_read_data/bitbang_tms_in_port_cmd/bitbang_tms_in_pin
* are provided, pure MPSSE SWD is choosen.
* If neither a complete set of swd_read|write or
* bitbang_swd_dbus_read_data/bitbang_tms_in_port_cmd/bitbang_tms_in_pin
* are provided, SWD can not be done.
* swd_read.set_data_low == swd_write.set_data_low == MPSSE_DO
* indicated resistor SWD and inhibits Jtag.*/
pin_settings_t mpsse_swd_read;
/* dbus data for pure MPSSE SWD write.*/
pin_settings_t mpsse_swd_write;
/* dbus data for jtag.*/
pin_settings_t jtag;
/* Command to read port to check target voltage.*/
uint8_t target_voltage_cmd;
/* Pin to check target voltage.*/
uint8_t target_voltage_pin;
/* USB readable description of the device.*/
char *description;
/* Command line argument to -c option to select this device.*/
char * name;
}cable_desc_t;
#if HOSTED_BMP_ONLY == 1
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wunused-parameter"
int ftdi_bmp_init(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info) {return -1;};
int libftdi_swdptap_init(ADIv5_DP_t *dp) {return -1;};
int libftdi_jtagtap_init(jtag_proc_t *jtag_proc) {return 0;};
void libftdi_buffer_flush(void) {};
int libftdi_buffer_write(const uint8_t *data, int size) {return size;};
int libftdi_buffer_read(uint8_t *data, int size) {return size;};
const char *libftdi_target_voltage(void) {return "ERROR";};
void libftdi_jtagtap_tdi_tdo_seq(
uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int ticks) {};
bool libftdi_swd_possible(bool *do_mpsse, bool *direct_bb_swd) {return false;};
void libftdi_max_frequency_set(uint32_t freq) {};
uint32_t libftdi_max_frequency_get(void) {return 0;};
void libftdi_srst_set_val(bool assert){};
bool libftdi_srst_get_val(void) { return false;};
# pragma GCC diagnostic pop
#else
#include <ftdi.h>
extern cable_desc_t cable_desc[];
extern cable_desc_t *active_cable;
extern struct ftdi_context *ftdic;
extern data_desc_t active_state;
int ftdi_bmp_init(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info);
int libftdi_swdptap_init(ADIv5_DP_t *dp);
int libftdi_jtagtap_init(jtag_proc_t *jtag_proc);
void libftdi_buffer_flush(void);
int libftdi_buffer_write(const uint8_t *data, int size);
int libftdi_buffer_read(uint8_t *data, int size);
const char *libftdi_target_voltage(void);
void libftdi_jtagtap_tdi_tdo_seq(
uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int ticks);
bool libftdi_swd_possible(bool *do_mpsse, bool *direct_bb_swd);
void libftdi_max_frequency_set(uint32_t freq);
uint32_t libftdi_max_frequency_get(void);
void libftdi_srst_set_val(bool assert);
bool libftdi_srst_get_val(void);
#endif
#define MPSSE_SK 1
#define PIN0 1
#define MPSSE_DO 2
#define PIN1 2
#define MPSSE_DI 4
#define PIN2 4
#define MPSSE_CS 8
#define PIN3 8
#define PIN4 0x10
#define PIN5 0x20
#define PIN6 0x40
#define PIN7 0x80
#endif

View File

@ -0,0 +1,271 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2020 Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Base on code from git://repo.or.cz/libjaylink.git
* and https://github.com/afaerber/jlink.git*/
#include "general.h"
#include "gdb_if.h"
#include "adiv5.h"
#include "exception.h"
#include <assert.h>
#include <unistd.h>
#include <signal.h>
#include <ctype.h>
#include <sys/time.h>
#include "cl_utils.h"
#include "jlink.h"
#define USB_PID_SEGGER 0x1366
/* Only two devices PIDS tested so long */
#define USB_VID_SEGGER_0101 0x0101
#define USB_VID_SEGGER_0105 0x0105
#define USB_VID_SEGGER_1020 0x1020
static uint32_t emu_caps;
static uint32_t emu_speed_kHz;
static uint16_t emu_min_divisor;
static uint16_t emu_current_divisor;
static void jlink_print_caps(bmp_info_t *info)
{
uint8_t cmd[1] = {CMD_GET_CAPS};
uint8_t res[4];
send_recv(info->usb_link, cmd, 1, res, sizeof(res));
emu_caps = res[0] | (res[1] << 8) | (res[2] << 16) | (res[3] << 24);
DEBUG_INFO("Caps %" PRIx32 "\n", emu_caps);
if (emu_caps & JLINK_CAP_GET_HW_VERSION) {
uint8_t cmd[1] = {CMD_GET_HW_VERSION};
send_recv(info->usb_link, cmd, 1, NULL, 0);
send_recv(info->usb_link, NULL, 0, res, sizeof(res));
DEBUG_INFO("HW: Type %d, Major %d, Minor %d, Rev %d\n",
res[3], res[2], res[1], res[0]);
}
}
static void jlink_print_speed(bmp_info_t *info)
{
uint8_t cmd[1] = {CMD_GET_SPEEDS};
uint8_t res[6];
send_recv(info->usb_link, cmd, 1, res, sizeof(res));
emu_speed_kHz = (res[0] | (res[1] << 8) | (res[2] << 16) | (res[3] << 24)) /
1000;
emu_min_divisor = res[4] | (res[5] << 8);
DEBUG_INFO("Emulator speed %d kHz, Mindiv %d%s\n", emu_speed_kHz,
emu_min_divisor,
(emu_caps & JLINK_CAP_GET_SPEEDS) ? "" : ", fixed");
}
static void jlink_print_version(bmp_info_t *info)
{
uint8_t cmd[1] = {CMD_GET_VERSION};
uint8_t len_str[2];
send_recv(info->usb_link, cmd, 1, len_str, sizeof(len_str));
uint8_t version[0x70];
send_recv(info->usb_link, NULL, 0, version, sizeof(version));
DEBUG_INFO("%s\n", version );
}
static void jlink_print_interfaces(bmp_info_t *info)
{
uint8_t cmd[2] = {CMD_GET_SELECT_IF, JLINK_IF_GET_ACTIVE};
uint8_t res[4];
send_recv(info->usb_link, cmd, 2, res, sizeof(res));
cmd[1] = JLINK_IF_GET_AVAILABLE;
uint8_t res1[4];
send_recv(info->usb_link, cmd, 2, res1, sizeof(res1));
DEBUG_INFO("%s active", (res[0] == SELECT_IF_SWD) ? "SWD":
(res[0] == SELECT_IF_JTAG) ? "JTAG" : "NONE");
uint8_t other_interface = res1[0] - (res[0] + 1);
if (other_interface)
DEBUG_INFO(", %s available\n",
(other_interface == JLINK_IF_SWD) ? "SWD": "JTAG");
else
DEBUG_INFO(", %s not available\n",
((res[0] + 1) == JLINK_IF_SWD) ? "JTAG": "SWD");
}
static void jlink_info(bmp_info_t *info)
{
jlink_print_version(info);
jlink_print_caps(info);
jlink_print_speed(info);
jlink_print_interfaces(info);
}
/* On success endpoints are set and return 0, !0 else */
static int initialize_handle(bmp_info_t *info, libusb_device *dev)
{
struct libusb_config_descriptor *config;
int ret = libusb_get_active_config_descriptor(dev, &config);
if (ret != LIBUSB_SUCCESS) {
DEBUG_WARN( "Failed to get configuration descriptor: %s.",
libusb_error_name(ret));
return -1;
}
const struct libusb_interface *interface;
bool found_interface = false;
const struct libusb_interface_descriptor *desc;
for (int i = 0; i < config->bNumInterfaces; i++) {
interface = &config->interface[i];
desc = &interface->altsetting[0];
if (desc->bInterfaceClass != LIBUSB_CLASS_VENDOR_SPEC)
continue;
if (desc->bInterfaceSubClass != LIBUSB_CLASS_VENDOR_SPEC)
continue;
if (desc->bNumEndpoints < 2)
continue;
found_interface = true;
if (libusb_claim_interface (
info->usb_link->ul_libusb_device_handle, i)) {
DEBUG_WARN( " Can not claim handle\n");
found_interface = false;
}
break;
}
if (!found_interface) {
DEBUG_WARN( "No suitable interface found.");
libusb_free_config_descriptor(config);
return -1;
}
for (int i = 0; i < desc->bNumEndpoints; i++) {
const struct libusb_endpoint_descriptor *epdesc = &desc->endpoint[i];
if (epdesc->bEndpointAddress & LIBUSB_ENDPOINT_IN) {
info->usb_link->ep_rx = epdesc->bEndpointAddress;
} else {
info->usb_link->ep_tx = epdesc->bEndpointAddress;
}
}
libusb_free_config_descriptor(config);
return 0;
}
/* Return 0 if single J-Link device connected or
* serial given matches one of several J-Link devices.
*/
int jlink_init(bmp_info_t *info)
{
usb_link_t *jl = calloc(1, sizeof(usb_link_t));
if (!jl)
return -1;
info->usb_link = jl;
jl->ul_libusb_ctx = info->libusb_ctx;
int ret = -1;
libusb_device **devs;
if (libusb_get_device_list(info->libusb_ctx, &devs) < 0) {
DEBUG_WARN( "libusb_get_device_list() failed");
return ret;
}
int i = 0;
for (; devs[i]; i++) {
libusb_device *dev = devs[i];
struct libusb_device_descriptor desc;
if (libusb_get_device_descriptor(dev, &desc) < 0) {
DEBUG_WARN( "libusb_get_device_descriptor() failed");
goto error;;
}
if (desc.idVendor != USB_PID_SEGGER)
continue;
if ((desc.idProduct != USB_VID_SEGGER_0101) &&
(desc.idProduct != USB_VID_SEGGER_0105) &&
(desc.idProduct != USB_VID_SEGGER_1020))
continue;
int res = libusb_open(dev, &jl->ul_libusb_device_handle);
if (res != LIBUSB_SUCCESS)
continue;
char buf[32];
res = libusb_get_string_descriptor_ascii(jl->ul_libusb_device_handle,
desc.iSerialNumber, (uint8_t*) buf, sizeof(buf));
if ((res <= 0) || (!strstr(buf, info->serial))) {
libusb_close(jl->ul_libusb_device_handle);
continue;
}
break;
}
if (!devs[i])
goto error;
if (initialize_handle(info, devs[i]))
goto error;
jl->req_trans = libusb_alloc_transfer(0);
jl->rep_trans = libusb_alloc_transfer(0);
if (!jl->req_trans || !jl->rep_trans ||
!jl->ep_tx || !jl->ep_rx) {
DEBUG_WARN("Device setup failed\n");
goto error;
}
libusb_free_device_list(devs, 1);
jlink_info(info);
return 0;
error:
libusb_free_device_list(devs, 1);
return -1;
}
const char *jlink_target_voltage(bmp_info_t *info)
{
uint8_t cmd[1] = {CMD_GET_HW_STATUS};
uint8_t res[8];
send_recv(info->usb_link, cmd, 1, res, sizeof(res));
uint16_t mVolt = res[0] | (res[1] << 8);
static char ret[7];
sprintf(ret, "%2d.%03d", mVolt / 1000, mVolt % 1000);
return ret;
}
static bool srst_status = false;
void jlink_srst_set_val(bmp_info_t *info, bool assert)
{
uint8_t cmd[1];
cmd[0]= (assert)? CMD_HW_RESET0: CMD_HW_RESET1;
send_recv(info->usb_link, cmd, 1, NULL, 0);
platform_delay(2);
srst_status = assert;
}
bool jlink_srst_get_val(bmp_info_t *info) {
uint8_t cmd[1] = {CMD_GET_HW_STATUS};
uint8_t res[8];
send_recv(info->usb_link, cmd, 1, res, sizeof(res));
return !(res[6]);
}
void jlink_max_frequency_set(bmp_info_t *info, uint32_t freq)
{
if (!(emu_caps & JLINK_CAP_GET_SPEEDS))
return;
if (!info->is_jtag)
return;
uint16_t freq_kHz = freq /1000;
uint16_t divisor = (emu_speed_kHz + freq_kHz - 1) / freq_kHz;
if (divisor < emu_min_divisor)
divisor = emu_min_divisor;
emu_current_divisor = divisor;
uint16_t speed_kHz = emu_speed_kHz / divisor;
uint8_t cmd[3] = {CMD_SET_SPEED, speed_kHz & 0xff, speed_kHz >> 8};
DEBUG_WARN("Set Speed %d\n", speed_kHz);
send_recv(info->usb_link, cmd, 3, NULL, 0);
}
uint32_t jlink_max_frequency_get(bmp_info_t *info)
{
if ((emu_caps & JLINK_CAP_GET_SPEEDS) && (info->is_jtag))
return (emu_speed_kHz * 1000L)/ emu_current_divisor;
return FREQ_FIXED;
}

View File

@ -0,0 +1,108 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2019 Uwe Bonnes
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined(__JLINK_H_)
#define __JLINK_H_
#include "bmp_hosted.h"
#include "jtagtap.h"
/** @cond PRIVATE */
#define CMD_GET_VERSION 0x01
#define CMD_SET_SPEED 0x05
#define CMD_GET_HW_STATUS 0x07
#define CMD_GET_SPEEDS 0xc0
#define CMD_GET_SELECT_IF 0xc7
#define CMD_HW_JTAG3 0xcf
#define CMD_HW_RESET0 0xdc
#define CMD_HW_RESET1 0xdd
#define CMD_GET_CAPS 0xe8
#define CMD_GET_EXT_CAPS 0xed
#define CMD_GET_HW_VERSION 0xf0
#define JLINK_IF_GET_ACTIVE 0xfe
#define JLINK_IF_GET_AVAILABLE 0xff
#define JLINK_CAP_GET_SPEEDS (1 << 9)
#define JLINK_CAP_GET_HW_VERSION (1 << 1)
#define JLINK_IF_JTAG 1
#define JLINK_IF_SWD 2
#define SELECT_IF_JTAG 0
#define SELECT_IF_SWD 1
#if HOSTED_BMP_ONLY == 1
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wunused-parameter"
int jlink_init(bmp_info_t *info) {return -1;};
int jlink_swdp_scan(bmp_info_t *info) {return 0;};
int jlink_jtagtap_init(bmp_info_t *info, jtag_proc_t *jtag_proc) {return 0;};
const char *jlink_target_voltage(bmp_info_t *info) {return "ERROR";};
void jlink_srst_set_val(bmp_info_t *info, bool assert) {};
bool jlink_srst_get_val(bmp_info_t *info) {return true;};
void jlink_max_frequency_set(bmp_info_t *info, uint32_t freq) {};
uint32_t jlink_max_frequency_get(bmp_info_t *info) {return 0;};
# pragma GCC diagnostic pop
#else
/** Device capabilities. (from openocd*/
enum jaylink_device_capability {
/** Device supports retrieval of the hardware version. */
JAYLINK_DEV_CAP_GET_HW_VERSION = 1,
/** Device supports adaptive clocking. */
JAYLINK_DEV_CAP_ADAPTIVE_CLOCKING = 3,
/** Device supports reading configuration data. */
JAYLINK_DEV_CAP_READ_CONFIG = 4,
/** Device supports writing configuration data. */
JAYLINK_DEV_CAP_WRITE_CONFIG = 5,
/** Device supports retrieval of target interface speeds. */
JAYLINK_DEV_CAP_GET_SPEEDS = 9,
/** Device supports retrieval of free memory size. */
JAYLINK_DEV_CAP_GET_FREE_MEMORY = 11,
/** Device supports retrieval of hardware information. */
JAYLINK_DEV_CAP_GET_HW_INFO = 12,
/** Device supports the setting of the target power supply. */
JAYLINK_DEV_CAP_SET_TARGET_POWER = 13,
/** Device supports target interface selection. */
JAYLINK_DEV_CAP_SELECT_TIF = 17,
/** Device supports retrieval of counter values. */
JAYLINK_DEV_CAP_GET_COUNTERS = 19,
/** Device supports capturing of SWO trace data. */
JAYLINK_DEV_CAP_SWO = 23,
/** Device supports file I/O operations. */
JAYLINK_DEV_CAP_FILE_IO = 26,
/** Device supports registration of connections. */
JAYLINK_DEV_CAP_REGISTER = 27,
/** Device supports retrieval of extended capabilities. */
JAYLINK_DEV_CAP_GET_EXT_CAPS = 31,
/** Device supports EMUCOM. */
JAYLINK_DEV_CAP_EMUCOM = 33,
/** Device supports ethernet connectivity. */
JAYLINK_DEV_CAP_ETHERNET = 38
};
int jlink_init(bmp_info_t *info);
int jlink_swdp_scan(bmp_info_t *info);
int jlink_jtagtap_init(bmp_info_t *info, jtag_proc_t *jtag_proc);
const char *jlink_target_voltage(bmp_info_t *info);
void jlink_srst_set_val(bmp_info_t *info, bool assert);
bool jlink_srst_get_val(bmp_info_t *info);
void jlink_max_frequency_set(bmp_info_t *info, uint32_t freq);
uint32_t jlink_max_frequency_get(bmp_info_t *info);
#endif
#endif

View File

@ -0,0 +1,327 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2011 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
* Copyright (C) 2019 - 2021 Uwe Bonnes
* (bon@elektron.ikp.physik.tu-darmstadt.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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* This file implements the SW-DP specific functions of the
* ARM Debug Interface v5 Architecure Specification, ARM doc IHI0031A.
*/
#include "general.h"
#include "exception.h"
#include "target.h"
#include "target_internal.h"
#include "adiv5.h"
#include "jlink.h"
#include "cl_utils.h"
#define SWDP_ACK_OK 0x01
#define SWDP_ACK_WAIT 0x02
#define SWDP_ACK_FAULT 0x04
static uint32_t jlink_adiv5_swdp_read(ADIv5_DP_t *dp, uint16_t addr);
static uint32_t jlink_adiv5_swdp_error(ADIv5_DP_t *dp);
static uint32_t jlink_adiv5_swdp_low_access(ADIv5_DP_t *dp, uint8_t RnW,
uint16_t addr, uint32_t value);
static void jlink_adiv5_swdp_abort(ADIv5_DP_t *dp, uint32_t abort);
enum {
SWDIO_WRITE = 0,
SWDIO_READ
};
/* Write at least 50 bits high, two bits low and read DP_IDR and put
* idle cyccles at the end*/
static int line_reset(bmp_info_t *info)
{
uint8_t cmd[44];
cmd[0] = CMD_HW_JTAG3;
cmd[1] = 0;
/* write 19 Bytes.*/
cmd[2] = 19 * 8;
cmd[3] = 0;
uint8_t *direction = cmd + 4;
direction[0] = 0;
direction[1] = 0;
direction[2] = 0;
direction[3] = 0;
direction[4] = 0;
direction[5] = 0xff;
direction[6] = 0xff;
direction[7] = 0xff;
direction[8] = 0xff;
direction[9] = 0xff;
direction[10] = 0xff;
direction[11] = 0xff;
direction[12] = 0xff;
direction[13] = 0xff;
direction[14] = 0x0;
direction[15] = 0x0;
direction[16] = 0x0;
direction[17] = 0x0;
direction[18] = 0xe0;
uint8_t *data = direction + 19;
data[5] = 0xff;
data[6] = 0xff;
data[7] = 0xff;
data[8] = 0xff;
data[9] = 0xff;
data[10] = 0xff;
data[11] = 0xff;
data[12] = 0;
data[13] = 0xa5;
data[18] = 0;
uint8_t res[19];
send_recv(info->usb_link, cmd, 42, res, 19);
send_recv(info->usb_link, NULL, 0, res, 1);
if (res[0] != 0) {
DEBUG_WARN( "Line reset failed\n");
return -1;
}
return 0;
}
static int jlink_swdptap_init(bmp_info_t *info)
{
uint8_t cmd[2] = {CMD_GET_SELECT_IF, JLINK_IF_GET_AVAILABLE};
uint8_t res[4];
send_recv(info->usb_link, cmd, 2, res, sizeof(res));
if (!(res[0] & JLINK_IF_SWD))
return -1;
cmd[1] = SELECT_IF_SWD;
send_recv(info->usb_link, cmd, 2, res, sizeof(res));
platform_delay(10);
/* SWD speed is fixed. Do not set it here*/
return 0;
}
int jlink_swdp_scan(bmp_info_t *info)
{
jlink_swdptap_init(info);
target_list_free();
uint8_t cmd[44];
cmd[0] = CMD_HW_JTAG3;
cmd[1] = 0;
/* write 18 Bytes.*/
cmd[2] = 17 * 8;
cmd[3] = 0;
uint8_t *direction = cmd + 4;
direction[0] = 0xff;
direction[1] = 0xff;
direction[2] = 0xff;
direction[3] = 0xff;
direction[4] = 0xff;
direction[5] = 0xff;
direction[6] = 0xff;
direction[7] = 0xff;
direction[8] = 0xff;
direction[9] = 0xff;
direction[10] = 0xff;
direction[11] = 0xff;
direction[12] = 0xff;
direction[13] = 0xff;
direction[14] = 0xff;
direction[15] = 0xff;
direction[16] = 0xff;
uint8_t *data = direction + 17;
data[0] = 0xff;
data[1] = 0xff;
data[2] = 0xff;
data[3] = 0xff;
data[4] = 0xff;
data[5] = 0xff;
data[6] = 0xff;
data[7] = 0x9e;
data[8] = 0xe7;
data[9] = 0xff;
data[10] = 0xff;
data[11] = 0xff;
data[12] = 0xff;
data[13] = 0xff;
data[14] = 0xff;
data[15] = 0;
data[16] = 0;
uint8_t res[18];
send_recv(info->usb_link, cmd, 38, res, 17);
send_recv(info->usb_link, NULL, 0, res, 1);
if (res[0] != 0) {
DEBUG_WARN( "Line reset failed\n");
return 0;
}
ADIv5_DP_t *dp = (void*)calloc(1, sizeof(*dp));
if (!dp) /* calloc failed: heap exhaustion */
return 0;
volatile struct exception e;
TRY_CATCH (e, EXCEPTION_ALL) {
dp->idcode = jlink_adiv5_swdp_low_access(dp, 1, ADIV5_DP_IDCODE, 0);
}
if (e.type) {
DEBUG_WARN("DP not responding for IDCODE! Reset stuck low?\n");
free(dp);
return 0;
}
dp->dp_read = jlink_adiv5_swdp_read;
dp->error = jlink_adiv5_swdp_error;
dp->low_access = jlink_adiv5_swdp_low_access;
dp->abort = jlink_adiv5_swdp_abort;
jlink_adiv5_swdp_error(dp);
adiv5_dp_init(dp);
return target_list?1:0;
}
static uint32_t jlink_adiv5_swdp_read(ADIv5_DP_t *dp, uint16_t addr)
{
if (addr & ADIV5_APnDP) {
adiv5_dp_low_access(dp, ADIV5_LOW_READ, addr, 0);
return adiv5_dp_low_access(dp, ADIV5_LOW_READ,
ADIV5_DP_RDBUFF, 0);
} else {
return jlink_adiv5_swdp_low_access(dp, ADIV5_LOW_READ, addr, 0);
}
}
static uint32_t jlink_adiv5_swdp_error(ADIv5_DP_t *dp)
{
uint32_t err, clr = 0;
err = jlink_adiv5_swdp_read(dp, ADIV5_DP_CTRLSTAT) &
(ADIV5_DP_CTRLSTAT_STICKYORUN | ADIV5_DP_CTRLSTAT_STICKYCMP |
ADIV5_DP_CTRLSTAT_STICKYERR | ADIV5_DP_CTRLSTAT_WDATAERR);
if(err & ADIV5_DP_CTRLSTAT_STICKYORUN)
clr |= ADIV5_DP_ABORT_ORUNERRCLR;
if(err & ADIV5_DP_CTRLSTAT_STICKYCMP)
clr |= ADIV5_DP_ABORT_STKCMPCLR;
if(err & ADIV5_DP_CTRLSTAT_STICKYERR)
clr |= ADIV5_DP_ABORT_STKERRCLR;
if(err & ADIV5_DP_CTRLSTAT_WDATAERR)
clr |= ADIV5_DP_ABORT_WDERRCLR;
if (clr)
adiv5_dp_write(dp, ADIV5_DP_ABORT, clr);
if (dp->fault)
err |= 0x8000;
dp->fault = 0;
return err;
}
static uint32_t jlink_adiv5_swdp_low_access(ADIv5_DP_t *dp, uint8_t RnW,
uint16_t addr, uint32_t value)
{
bool APnDP = addr & ADIV5_APnDP;
uint8_t addr8 = addr & 0xff;
uint8_t request = 0x81;
uint32_t response = 0;
uint8_t ack;
platform_timeout timeout;
if(APnDP && dp->fault) return 0;
if(APnDP) request ^= 0x22;
if(RnW) request ^= 0x24;
addr8 &= 0xC;
request |= (addr8 << 1) & 0x18;
if((addr8 == 4) || (addr8 == 8))
request ^= 0x20;
uint8_t cmd[16];
uint8_t res[8];
cmd[0] = CMD_HW_JTAG3;
cmd[1] = 0;
/* It seems, JLINK samples read data at end of previous clock.
* So target data read must start at the 12'th clock, while
* write starts as expected at the 14'th clock (8 cmd, 3 response,
* 2 turn around.
*/
cmd[2] = (RnW) ? 11 : 13;
cmd[3] = 0;
cmd[4] = 0xff; /* 8 bits command OUT */
cmd[5] = 0xf0; /* one IN bit to turn around to read, read 2
(read) or 3 (write) IN bits for response and
and one OUT bit to turn around to write on write*/
cmd[6] = request;
cmd[7] = 0x00;
platform_timeout_set(&timeout, 2000);
do {
send_recv(info.usb_link, cmd, 8, res, 2);
send_recv(info.usb_link, NULL, 0, res + 2 , 1);
if (res[2] != 0)
raise_exception(EXCEPTION_ERROR, "Low access setup failed");
ack = res[1] & 7;
} while (ack == SWDP_ACK_WAIT && !platform_timeout_is_expired(&timeout));
if (ack == SWDP_ACK_WAIT)
raise_exception(EXCEPTION_TIMEOUT, "SWDP ACK timeout");
if(ack == SWDP_ACK_FAULT) {
if (cl_debuglevel & BMP_DEBUG_TARGET)
DEBUG_WARN( "Fault\n");
dp->fault = 1;
return 0;
}
if(ack != SWDP_ACK_OK) {
if (cl_debuglevel & BMP_DEBUG_TARGET)
DEBUG_WARN( "Protocol %d\n", ack);
line_reset(&info);
return 0;
}
/* Always append 8 idle cycle (SWDIO = 0)!*/
if(RnW) {
memset(cmd + 4, 0, 10);
cmd[2] = 33 + 2; /* 2 idle cycles */
cmd[8] = 0xfe;
send_recv(info.usb_link, cmd, 14, res, 5);
send_recv(info.usb_link, NULL, 0, res + 5, 1);
if (res[5] != 0)
raise_exception(EXCEPTION_ERROR, "Low access read failed");
response = res[0] | res[1] << 8 | res[2] << 16 | res[3] << 24;
int parity = res[4] & 1;
int bit_count = __builtin_popcount (response) + parity;
if (bit_count & 1) /* Give up on parity error */
raise_exception(EXCEPTION_ERROR, "SWDP Parity error");
} else {
cmd[2] = 33 + 8; /* 8 idle cycle to move data through SW-DP */
memset(cmd + 4, 0xff, 6);
cmd[10] = ((value >> 0) & 0xff);
cmd[11] = ((value >> 8) & 0xff);
cmd[12] = ((value >> 16) & 0xff);
cmd[13] = ((value >> 24) & 0xff);
int bit_count = __builtin_popcount(value);
cmd[14] = bit_count & 1;
cmd[15] = 0;
send_recv(info.usb_link, cmd, 16, res, 6);
send_recv(info.usb_link, NULL, 0, res, 1);
if (res[0] != 0)
raise_exception(EXCEPTION_ERROR, "Low access write failed");
}
return response;
}
static void jlink_adiv5_swdp_abort(ADIv5_DP_t *dp, uint32_t abort)
{
adiv5_dp_write(dp, ADIV5_DP_ABORT, abort);
}

Some files were not shown because too many files have changed in this diff Show More