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

Dependencies:   SWD USBDevice mbed BaseDAP

Committer:
va009039
Date:
Sat Sep 28 03:21:14 2013 +0000
Revision:
1:ea8e179320d7
Parent:
0:2385683c867a
add USBMSD_Drop class. add CDC(Virtual COM) and HID(for example CMSIS-DAP), but KL25Z not work.

Who changed what in which revision?

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