USB composite device example program, drag-and-drop flash writer.

Dependencies:   SWD USBDevice mbed BaseDAP

Committer:
va009039
Date:
Tue Sep 17 04:33:44 2013 +0000
Revision:
0:2385683c867a
Child:
1:ea8e179320d7
first commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 0:2385683c867a 1 // Target2.cpp 2013/9/17
va009039 0:2385683c867a 2 #include "Target2.h"
va009039 0:2385683c867a 3 #include "mydebug.h"
va009039 0:2385683c867a 4
va009039 0:2385683c867a 5 #define SYSMEMREMAP 0x40048000
va009039 0:2385683c867a 6
va009039 0:2385683c867a 7 #define CoreDebug_BASE (0xE000EDF0UL)
va009039 0:2385683c867a 8 #define DHCSR (CoreDebug_BASE+0)
va009039 0:2385683c867a 9 #define DCRSR (CoreDebug_BASE+4)
va009039 0:2385683c867a 10 #define DCRDR (CoreDebug_BASE+8)
va009039 0:2385683c867a 11 #define DEMCR (CoreDebug_BASE+12)
va009039 0:2385683c867a 12
va009039 0:2385683c867a 13 #define NVIC_AIRCR 0xE000ED0C
va009039 0:2385683c867a 14
va009039 0:2385683c867a 15 // FPB (breakpoint)
va009039 0:2385683c867a 16 #define FP_CTRL (0xE0002000)
va009039 0:2385683c867a 17 #define FP_CTRL_KEY (1 << 1)
va009039 0:2385683c867a 18 #define FP_COMP0 (0xE0002008)
va009039 0:2385683c867a 19
va009039 0:2385683c867a 20 Target2::Target2(PinName swdio, PinName swclk, PinName reset)
va009039 0:2385683c867a 21 : _swd(swdio, swclk, reset)
va009039 0:2385683c867a 22 {
va009039 0:2385683c867a 23 r0.setup(this, 0);
va009039 0:2385683c867a 24 r1.setup(this, 1);
va009039 0:2385683c867a 25 r2.setup(this, 2);
va009039 0:2385683c867a 26 r3.setup(this, 3);
va009039 0:2385683c867a 27 r4.setup(this, 4);
va009039 0:2385683c867a 28 r5.setup(this, 5);
va009039 0:2385683c867a 29 r6.setup(this, 6);
va009039 0:2385683c867a 30 r7.setup(this, 7);
va009039 0:2385683c867a 31 r8.setup(this, 8);
va009039 0:2385683c867a 32 r9.setup(this, 9);
va009039 0:2385683c867a 33 r10.setup(this, 10);
va009039 0:2385683c867a 34 r11.setup(this, 11);
va009039 0:2385683c867a 35 r12.setup(this, 12);
va009039 0:2385683c867a 36 sp.setup(this, 13);
va009039 0:2385683c867a 37 lr.setup(this, 14);
va009039 0:2385683c867a 38 pc.setup(this, 15);
va009039 0:2385683c867a 39 xpsr.setup(this, 16);
va009039 0:2385683c867a 40 }
va009039 0:2385683c867a 41
va009039 0:2385683c867a 42 bool Target2::setup()
va009039 0:2385683c867a 43 {
va009039 0:2385683c867a 44 _swd.Setup();
va009039 0:2385683c867a 45 JTAG2SWD();
va009039 0:2385683c867a 46
va009039 0:2385683c867a 47 uint32_t data;
va009039 0:2385683c867a 48 uint8_t ack = _swd.Transfer(DP_IDCODE, &data);
va009039 0:2385683c867a 49 TEST_ASSERT(ack == SWD_OK);
va009039 0:2385683c867a 50 if (ack != SWD_OK) {
va009039 0:2385683c867a 51 return false;
va009039 0:2385683c867a 52 }
va009039 0:2385683c867a 53 idcode = data;
va009039 0:2385683c867a 54 //TEST_ASSERT(data == 0x0bb11477);
va009039 0:2385683c867a 55
va009039 0:2385683c867a 56 Abort();
va009039 0:2385683c867a 57
va009039 0:2385683c867a 58 data = 0x0;
va009039 0:2385683c867a 59 ack = _swd.Transfer(DP_SELECT, &data);
va009039 0:2385683c867a 60 TEST_ASSERT(ack == SWD_OK);
va009039 0:2385683c867a 61 if (ack != SWD_OK) {
va009039 0:2385683c867a 62 return false;
va009039 0:2385683c867a 63 }
va009039 0:2385683c867a 64
va009039 0:2385683c867a 65 ack = _swd.Transfer(DP_RDBUFF, &data);
va009039 0:2385683c867a 66 TEST_ASSERT(ack == SWD_OK);
va009039 0:2385683c867a 67 if (ack != SWD_OK) {
va009039 0:2385683c867a 68 return false;
va009039 0:2385683c867a 69 }
va009039 0:2385683c867a 70
va009039 0:2385683c867a 71 data = CSYSPWRUPREQ | CDBGPWRUPREQ;
va009039 0:2385683c867a 72 ack = _swd.Transfer(DP_CTRL_STAT, &data);
va009039 0:2385683c867a 73 TEST_ASSERT(ack == SWD_OK);
va009039 0:2385683c867a 74 if (ack != SWD_OK) {
va009039 0:2385683c867a 75 return false;
va009039 0:2385683c867a 76 }
va009039 0:2385683c867a 77
va009039 0:2385683c867a 78 ack = _swd.Transfer(DP_RDBUFF, &data);
va009039 0:2385683c867a 79 TEST_ASSERT(ack == SWD_OK);
va009039 0:2385683c867a 80 if (ack != SWD_OK) {
va009039 0:2385683c867a 81 return false;
va009039 0:2385683c867a 82 }
va009039 0:2385683c867a 83
va009039 0:2385683c867a 84 ack = _swd.Transfer(DP_CTRL_STAT_R, &data);
va009039 0:2385683c867a 85 TEST_ASSERT(ack == SWD_OK);
va009039 0:2385683c867a 86 if (ack != SWD_OK) {
va009039 0:2385683c867a 87 return false;
va009039 0:2385683c867a 88 }
va009039 0:2385683c867a 89 TEST_ASSERT(data == 0xf0000040);
va009039 0:2385683c867a 90
va009039 0:2385683c867a 91 data = CSYSPWRUPREQ | CDBGPWRUPREQ | 0x04000000;
va009039 0:2385683c867a 92 ack = _swd.Transfer(DP_CTRL_STAT, &data);
va009039 0:2385683c867a 93 TEST_ASSERT(ack == SWD_OK);
va009039 0:2385683c867a 94 if (ack != SWD_OK) {
va009039 0:2385683c867a 95 return false;
va009039 0:2385683c867a 96 }
va009039 0:2385683c867a 97
va009039 0:2385683c867a 98 ack = _swd.Transfer(DP_RDBUFF, &data);
va009039 0:2385683c867a 99 TEST_ASSERT(ack == SWD_OK);
va009039 0:2385683c867a 100 if (ack != SWD_OK) {
va009039 0:2385683c867a 101 return false;
va009039 0:2385683c867a 102 }
va009039 0:2385683c867a 103
va009039 0:2385683c867a 104 data = CSYSPWRUPREQ | CDBGPWRUPREQ | MASKLANE;
va009039 0:2385683c867a 105 ack = _swd.Transfer(DP_CTRL_STAT, &data);
va009039 0:2385683c867a 106 TEST_ASSERT(ack == SWD_OK);
va009039 0:2385683c867a 107 if (ack != SWD_OK) {
va009039 0:2385683c867a 108 return false;
va009039 0:2385683c867a 109 }
va009039 0:2385683c867a 110
va009039 0:2385683c867a 111 ack = _swd.Transfer(DP_RDBUFF, &data);
va009039 0:2385683c867a 112 TEST_ASSERT(ack == SWD_OK);
va009039 0:2385683c867a 113 if (ack != SWD_OK) {
va009039 0:2385683c867a 114 return false;
va009039 0:2385683c867a 115 }
va009039 0:2385683c867a 116 return true;
va009039 0:2385683c867a 117 }
va009039 0:2385683c867a 118
va009039 0:2385683c867a 119 void Target2::SWJClock(uint32_t clock_hz)
va009039 0:2385683c867a 120 {
va009039 0:2385683c867a 121 _swd.SWJClock(clock_hz);
va009039 0:2385683c867a 122 }
va009039 0:2385683c867a 123
va009039 0:2385683c867a 124 void Target2::JTAG2SWD()
va009039 0:2385683c867a 125 {
va009039 0:2385683c867a 126 const uint8_t data1[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff};
va009039 0:2385683c867a 127 const uint8_t data2[] = {0x9e,0xe7};
va009039 0:2385683c867a 128 const uint8_t data3[] = {0x00};
va009039 0:2385683c867a 129 _swd.SWJSequence(sizeof(data1)*8, data1);
va009039 0:2385683c867a 130 _swd.SWJSequence(sizeof(data2)*8, data2);
va009039 0:2385683c867a 131 _swd.SWJSequence(sizeof(data1)*8, data1);
va009039 0:2385683c867a 132 _swd.SWJSequence(sizeof(data3)*8, data3);
va009039 0:2385683c867a 133 }
va009039 0:2385683c867a 134
va009039 0:2385683c867a 135 void Target2::HardwareReset()
va009039 0:2385683c867a 136 {
va009039 0:2385683c867a 137 _swd.SWJPins(0x00, 0x80); // nReset off
va009039 0:2385683c867a 138 _swd.SWJPins(0x80, 0x80); // nReset on
va009039 0:2385683c867a 139 }
va009039 0:2385683c867a 140
va009039 0:2385683c867a 141 void Target2::SoftwareReset()
va009039 0:2385683c867a 142 {
va009039 0:2385683c867a 143 writeMemory(NVIC_AIRCR, 0x05fa0004);
va009039 0:2385683c867a 144 }
va009039 0:2385683c867a 145
va009039 0:2385683c867a 146 uint32_t Target2::readMemory(uint32_t addr)
va009039 0:2385683c867a 147 {
va009039 0:2385683c867a 148 _setaddr(addr);
va009039 0:2385683c867a 149
va009039 0:2385683c867a 150 uint32_t data;
va009039 0:2385683c867a 151 uint8_t ack = _swd.Transfer(AP_DRW_R, &data); // dummy read
va009039 0:2385683c867a 152 TEST_ASSERT(ack == SWD_OK);
va009039 0:2385683c867a 153
va009039 0:2385683c867a 154 ack = _swd.Transfer(DP_RDBUFF, &data);
va009039 0:2385683c867a 155 TEST_ASSERT(ack == SWD_OK);
va009039 0:2385683c867a 156 return data;
va009039 0:2385683c867a 157 }
va009039 0:2385683c867a 158
va009039 0:2385683c867a 159 void Target2::readMemory(uint32_t addr, uint32_t* data, int count)
va009039 0:2385683c867a 160 {
va009039 0:2385683c867a 161 if (count == 0) {
va009039 0:2385683c867a 162 return;
va009039 0:2385683c867a 163 }
va009039 0:2385683c867a 164
va009039 0:2385683c867a 165 _setaddr(addr);
va009039 0:2385683c867a 166
va009039 0:2385683c867a 167 uint8_t ack = _swd.Transfer(AP_DRW_R, NULL); // dummy read
va009039 0:2385683c867a 168 TEST_ASSERT(ack == SWD_OK);
va009039 0:2385683c867a 169
va009039 0:2385683c867a 170 for(int i = 0; i < count-1; i++) {
va009039 0:2385683c867a 171 ack = _swd.Transfer(AP_DRW_R, data++);
va009039 0:2385683c867a 172 TEST_ASSERT(ack == SWD_OK);
va009039 0:2385683c867a 173 }
va009039 0:2385683c867a 174 ack = _swd.Transfer(DP_RDBUFF, data);
va009039 0:2385683c867a 175 TEST_ASSERT(ack == SWD_OK);
va009039 0:2385683c867a 176 }
va009039 0:2385683c867a 177
va009039 0:2385683c867a 178 void Target2::writeMemory(uint32_t addr, uint32_t data)
va009039 0:2385683c867a 179 {
va009039 0:2385683c867a 180 writeMemory(addr, &data, 1);
va009039 0:2385683c867a 181 }
va009039 0:2385683c867a 182
va009039 0:2385683c867a 183 void Target2::writeMemory(uint32_t addr, uint32_t* data, int count)
va009039 0:2385683c867a 184 {
va009039 0:2385683c867a 185 _setaddr(addr);
va009039 0:2385683c867a 186
va009039 0:2385683c867a 187 while(count-- > 0) {
va009039 0:2385683c867a 188 uint8_t ack = _swd.Transfer(AP_DRW_W, data);
va009039 0:2385683c867a 189 TEST_ASSERT(ack == SWD_OK);
va009039 0:2385683c867a 190 data++;
va009039 0:2385683c867a 191 }
va009039 0:2385683c867a 192 }
va009039 0:2385683c867a 193
va009039 0:2385683c867a 194 uint8_t Target2::readMemory8(uint32_t addr)
va009039 0:2385683c867a 195 {
va009039 0:2385683c867a 196 _setaddr8(addr);
va009039 0:2385683c867a 197
va009039 0:2385683c867a 198 uint32_t data32;
va009039 0:2385683c867a 199 uint8_t ack = _swd.Transfer(AP_DRW_R, &data32); // dummy read
va009039 0:2385683c867a 200 TEST_ASSERT(ack == SWD_OK);
va009039 0:2385683c867a 201
va009039 0:2385683c867a 202 ack = _swd.Transfer(DP_RDBUFF, &data32);
va009039 0:2385683c867a 203 TEST_ASSERT(ack == SWD_OK);
va009039 0:2385683c867a 204 return (data32 >> ((addr & 0x03) << 3)) & 0xff;
va009039 0:2385683c867a 205 }
va009039 0:2385683c867a 206
va009039 0:2385683c867a 207 void Target2::writeMemory8(uint32_t addr, uint8_t data)
va009039 0:2385683c867a 208 {
va009039 0:2385683c867a 209 _setaddr8(addr);
va009039 0:2385683c867a 210
va009039 0:2385683c867a 211 uint32_t data32 = data;
va009039 0:2385683c867a 212 data32 <<= ((addr & 0x03) << 3);
va009039 0:2385683c867a 213 uint8_t ack = _swd.Transfer(AP_DRW_W, &data32);
va009039 0:2385683c867a 214 TEST_ASSERT(ack == SWD_OK);
va009039 0:2385683c867a 215 }
va009039 0:2385683c867a 216
va009039 0:2385683c867a 217 void Target2::_setaddr(uint32_t addr)
va009039 0:2385683c867a 218 {
va009039 0:2385683c867a 219 uint32_t ctl = CSW_VALUE|CSW_SIZE32;
va009039 0:2385683c867a 220 uint8_t ack = _swd.Transfer(AP_CSW, &ctl);
va009039 0:2385683c867a 221 TEST_ASSERT(ack == SWD_OK);
va009039 0:2385683c867a 222
va009039 0:2385683c867a 223 ack = _swd.Transfer(DP_RDBUFF, NULL);
va009039 0:2385683c867a 224 TEST_ASSERT(ack == SWD_OK);
va009039 0:2385683c867a 225
va009039 0:2385683c867a 226 ack = _swd.Transfer(AP_TAR, &addr);
va009039 0:2385683c867a 227 TEST_ASSERT(ack == SWD_OK);
va009039 0:2385683c867a 228
va009039 0:2385683c867a 229 ack = _swd.Transfer(DP_RDBUFF, NULL);
va009039 0:2385683c867a 230 TEST_ASSERT(ack == SWD_OK);
va009039 0:2385683c867a 231 }
va009039 0:2385683c867a 232
va009039 0:2385683c867a 233 void Target2::_setaddr8(uint32_t addr)
va009039 0:2385683c867a 234 {
va009039 0:2385683c867a 235 uint32_t ctl = CSW_VALUE|CSW_SIZE8;
va009039 0:2385683c867a 236 uint8_t ack = _swd.Transfer(AP_CSW, &ctl);
va009039 0:2385683c867a 237 TEST_ASSERT(ack == SWD_OK);
va009039 0:2385683c867a 238
va009039 0:2385683c867a 239 ack = _swd.Transfer(DP_RDBUFF, NULL);
va009039 0:2385683c867a 240 TEST_ASSERT(ack == SWD_OK);
va009039 0:2385683c867a 241
va009039 0:2385683c867a 242 ack = _swd.Transfer(AP_TAR, &addr);
va009039 0:2385683c867a 243 TEST_ASSERT(ack == SWD_OK);
va009039 0:2385683c867a 244
va009039 0:2385683c867a 245 ack = _swd.Transfer(DP_RDBUFF, NULL);
va009039 0:2385683c867a 246 TEST_ASSERT(ack == SWD_OK);
va009039 0:2385683c867a 247 }
va009039 0:2385683c867a 248
va009039 0:2385683c867a 249 void Target2::Abort()
va009039 0:2385683c867a 250 {
va009039 0:2385683c867a 251 uint32_t data = 0x1e;
va009039 0:2385683c867a 252 uint8_t ack = _swd.Transfer(DP_ABORT, &data);
va009039 0:2385683c867a 253 TEST_ASSERT(ack == SWD_OK);
va009039 0:2385683c867a 254 }
va009039 0:2385683c867a 255
va009039 0:2385683c867a 256 int Target2::getStatus()
va009039 0:2385683c867a 257 {
va009039 0:2385683c867a 258 return readMemory(DHCSR) & 6 ? TARGET_HALTED : TARGET_RUNNING;
va009039 0:2385683c867a 259 }
va009039 0:2385683c867a 260
va009039 0:2385683c867a 261 bool Target2::wait_status(int status, int timeout_ms)
va009039 0:2385683c867a 262 {
va009039 0:2385683c867a 263 Timer t;
va009039 0:2385683c867a 264 t.reset();
va009039 0:2385683c867a 265 t.start();
va009039 0:2385683c867a 266 while(t.read_ms() < timeout_ms) {
va009039 0:2385683c867a 267 if (getStatus() == status) {
va009039 0:2385683c867a 268 return true;
va009039 0:2385683c867a 269 }
va009039 0:2385683c867a 270 }
va009039 0:2385683c867a 271 return false;
va009039 0:2385683c867a 272 }
va009039 0:2385683c867a 273
va009039 0:2385683c867a 274 bool Target2::prog_status()
va009039 0:2385683c867a 275 {
va009039 0:2385683c867a 276 writeMemory(DEMCR, 1);
va009039 0:2385683c867a 277 int status = getStatus();
va009039 0:2385683c867a 278 TEST_ASSERT(status == TARGET_HALTED);
va009039 0:2385683c867a 279 if (status == TARGET_RUNNING) {
va009039 0:2385683c867a 280 halt();
va009039 0:2385683c867a 281 }
va009039 0:2385683c867a 282 bool st = wait_status(TARGET_HALTED);
va009039 0:2385683c867a 283 TEST_ASSERT(st == true);
va009039 0:2385683c867a 284 writeMemory(DEMCR, 0);
va009039 0:2385683c867a 285 writeMemory(SYSMEMREMAP, 2); // user flash page
va009039 0:2385683c867a 286 uint32_t reset_handler = readMemory(4);
va009039 0:2385683c867a 287 if (setBreakpoint0(reset_handler)) {
va009039 0:2385683c867a 288 writeMemory(NVIC_AIRCR, 0x05fa0004); // SYSRESETREQ software reset
va009039 0:2385683c867a 289 st = wait_status(TARGET_HALTED);
va009039 0:2385683c867a 290 TEST_ASSERT(st == true);
va009039 0:2385683c867a 291 TEST_ASSERT((reset_handler&0xfffffffe) == pc);
va009039 0:2385683c867a 292 removeBreakpoint0(0);
va009039 0:2385683c867a 293 }
va009039 0:2385683c867a 294 return true;
va009039 0:2385683c867a 295 }
va009039 0:2385683c867a 296
va009039 0:2385683c867a 297 bool Target2::setBreakpoint0(uint32_t addr)
va009039 0:2385683c867a 298 {
va009039 0:2385683c867a 299 if ((addr&1) == 0 || addr >= 0x20000000) {
va009039 0:2385683c867a 300 return false;
va009039 0:2385683c867a 301 }
va009039 0:2385683c867a 302 uint32_t data = (addr&0x1ffffffc) | 0xc0000001;
va009039 0:2385683c867a 303 if (addr&0x00000002) {
va009039 0:2385683c867a 304 data |= 0x80000000;
va009039 0:2385683c867a 305 } else {
va009039 0:2385683c867a 306 data |= 0x40000000;
va009039 0:2385683c867a 307 }
va009039 0:2385683c867a 308 writeMemory(FP_COMP0, data); // set breakpoint
va009039 0:2385683c867a 309 writeMemory(FP_CTRL, 3); // enable FPB
va009039 0:2385683c867a 310 return true;
va009039 0:2385683c867a 311 }
va009039 0:2385683c867a 312
va009039 0:2385683c867a 313 void Target2::removeBreakpoint0(uint32_t addr)
va009039 0:2385683c867a 314 {
va009039 0:2385683c867a 315 writeMemory(FP_COMP0, 0); // breakpoint clear
va009039 0:2385683c867a 316 writeMemory(FP_CTRL, 2); // desable FPB
va009039 0:2385683c867a 317 }
va009039 0:2385683c867a 318
va009039 0:2385683c867a 319 void Target2::halt()
va009039 0:2385683c867a 320 {
va009039 0:2385683c867a 321 writeMemory(DHCSR, 0xa05f0003);
va009039 0:2385683c867a 322 }
va009039 0:2385683c867a 323
va009039 0:2385683c867a 324 void Target2::resume()
va009039 0:2385683c867a 325 {
va009039 0:2385683c867a 326 writeMemory(DHCSR, 0xa05f0001);
va009039 0:2385683c867a 327 }
va009039 0:2385683c867a 328
va009039 0:2385683c867a 329 void Target2::step()
va009039 0:2385683c867a 330 {
va009039 0:2385683c867a 331 writeMemory(DHCSR, 0xa05f0005);
va009039 0:2385683c867a 332 }
va009039 0:2385683c867a 333
va009039 0:2385683c867a 334 uint32_t CoreReg::read()
va009039 0:2385683c867a 335 {
va009039 0:2385683c867a 336 _target->writeMemory(DCRSR, _reg);
va009039 0:2385683c867a 337 return _target->readMemory(DCRDR);
va009039 0:2385683c867a 338 }
va009039 0:2385683c867a 339
va009039 0:2385683c867a 340 void CoreReg::write(uint32_t value)
va009039 0:2385683c867a 341 {
va009039 0:2385683c867a 342 _target->writeMemory(DCRDR, value);
va009039 0:2385683c867a 343 _target->writeMemory(DCRSR, _reg|0x10000);
va009039 0:2385683c867a 344 }
va009039 0:2385683c867a 345
va009039 0:2385683c867a 346 void CoreReg::setup(Target2* target, uint8_t reg)
va009039 0:2385683c867a 347 {
va009039 0:2385683c867a 348 _target = target;
va009039 0:2385683c867a 349 _reg = reg;
va009039 0:2385683c867a 350 }