transport-dap.c (18629B)
1 // Copyright 2023, Brian Swetland <swetland@frotz.net> 2 // Licensed under the Apache License, Version 2.0. 3 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <unistd.h> 7 #include <string.h> 8 9 #include "usb.h" 10 #include "arm-debug.h" 11 #include "cmsis-dap-protocol.h" 12 #include "transport.h" 13 #include "transport-private.h" 14 15 uint32_t dc_flags(dctx_t* dc, uint32_t clr, uint32_t set) { 16 dc->flags = (dc->flags & (~clr)) | set; 17 return dc->flags; 18 } 19 20 void dc_interrupt(DC *dc) { 21 dc->attn++; 22 } 23 24 uint32_t dc_get_attn_value(DC *dc) { 25 return dc->attn; 26 } 27 28 void dc_set_status(DC* dc, uint32_t status) { 29 dc->status = status; 30 if (dc->status_callback) { 31 dc->status_callback(dc->status_cookie, status); 32 } 33 } 34 35 static void usb_failure(DC* dc, int status) { 36 ERROR("usb_failure status %d usb %p\n", status, dc->usb); 37 if (dc->usb != NULL) { 38 usb_close(dc->usb); 39 dc->usb = NULL; 40 } 41 dc_set_status(dc, DC_OFFLINE); 42 } 43 44 static int dap_get_info(DC* dc, unsigned di, void *out, unsigned minlen, unsigned maxlen) { 45 uint8_t buf[256 + 2]; 46 buf[0] = DAP_Info; 47 buf[1] = di; 48 int r; 49 if ((r = usb_write(dc->usb, buf, 2)) != 2) { 50 if (r < 0) { 51 usb_failure(dc, r); 52 } 53 return DC_ERR_IO; 54 } 55 int sz = usb_read(dc->usb, buf, 256 + 2); 56 if ((sz < 2) || (buf[0] != DAP_Info)) { 57 if (sz < 0) { 58 usb_failure(dc, sz); 59 } 60 return DC_ERR_PROTOCOL; 61 } 62 if ((buf[1] < minlen) || (buf[1] > maxlen)) { 63 return DC_ERR_PROTOCOL; 64 } 65 memcpy(out, buf + 2, buf[1]); 66 return buf[1]; 67 } 68 69 static int dap_cmd(DC* dc, const void* tx, unsigned txlen, void* rx, unsigned rxlen) { 70 uint8_t cmd = ((const uint8_t*) tx)[0]; 71 dump("TX>", tx, txlen); 72 int r; 73 if ((r = usb_write(dc->usb, tx, txlen)) != txlen) { 74 ERROR("dap_cmd(0x%02x): usb write error\n", cmd); 75 if (r < 0) { 76 usb_failure(dc, r); 77 } 78 return DC_ERR_IO; 79 } 80 int sz = usb_read(dc->usb, rx, rxlen); 81 if (sz < 1) { 82 ERROR("dap_cmd(0x%02x): usb read error\n", cmd); 83 if (sz < 0) { 84 usb_failure(dc, sz); 85 } 86 return DC_ERR_IO; 87 } 88 dump("RX>", rx, rxlen); 89 if (((uint8_t*) rx)[0] != cmd) { 90 ERROR("dap_cmd(0x%02x): unsupported (0x%02x)\n", 91 cmd, ((uint8_t*) rx)[0]); 92 return DC_ERR_UNSUPPORTED; 93 } 94 return sz; 95 } 96 97 static int dap_cmd_std(DC* dc, const char* name, uint8_t* io, 98 unsigned txlen, unsigned rxlen) { 99 int r = dap_cmd(dc, io, txlen, io, rxlen); 100 if (r < 0) { 101 return r; 102 } 103 if (io[1] != 0) { 104 ERROR("%s status 0x%02x\n", name, io[1]); 105 return DC_ERR_REMOTE; 106 } 107 return 0; 108 } 109 110 static int dap_connect(DC* dc) { 111 uint8_t io[2] = { DAP_Connect, PORT_SWD }; 112 int r = dap_cmd(dc, io, 2, io, 2); 113 if (r < 0) { 114 return r; 115 } 116 if (io[1] != PORT_SWD) { 117 return DC_ERR_REMOTE; 118 } 119 return 0; 120 } 121 122 static int dap_swd_configure(DC* dc, unsigned cfg) { 123 uint8_t io[2] = { DAP_SWD_Configure, cfg }; 124 return dap_cmd_std(dc, "dap_swd_configure()", io, 2, 2); 125 } 126 127 int dc_set_clock(DC* dc, uint32_t hz) { 128 uint8_t io[5] = { DAP_SWJ_Clock, 129 hz, hz >> 8, hz >> 16, hz >> 24 }; 130 return dap_cmd_std(dc, "dap_swj_clock()", io, 5, 2); 131 } 132 133 static int dap_xfer_config(DC* dc, unsigned idle, unsigned wait, unsigned match) { 134 // clamp to allowed max values 135 if (idle > 255) idle = 255; 136 if (wait > 65535) wait = 65535; 137 if (match > 65535) match = 65535; 138 139 // do nothing if unchanged from last set values 140 if ((dc->cfg_idle == idle) && 141 (dc->cfg_wait == wait) && 142 (dc->cfg_match == match)) { 143 return 0; 144 } 145 146 // cache new values 147 dc->cfg_idle = idle; 148 dc->cfg_wait = wait; 149 dc->cfg_match = match; 150 151 // inform the probe 152 uint8_t io[6] = { DAP_TransferConfigure, idle, wait, wait >> 8, match, match >> 8}; 153 return dap_cmd_std(dc, "dap_transfer_configure()", io, 6, 2); 154 } 155 156 static void dc_q_clear(DC* dc) { 157 dc->txnext = dc->txbuf + 3; 158 dc->rxnext = dc->rxptr; 159 dc->txavail = dc->max_packet_size - 3; 160 dc->rxavail = dc->max_packet_size - 3; 161 dc->qerror = 0; 162 dc->txbuf[0] = DAP_Transfer; 163 dc->txbuf[1] = 0; // Index 0 for SWD 164 dc->txbuf[2] = 0; // Count 0 initially 165 166 // TODO: less conservative mode: don't always invalidate 167 dc->dp_select_cache = INVALID; 168 dc->cfg_mask = INVALID; 169 dc->map_csw_cache = INVALID; 170 dc->map_tar_cache = INVALID; 171 } 172 173 static inline void _dc_q_init(DC* dc) { 174 // no side-effects version for use from dc_attach(), etc 175 dc_q_clear(dc); 176 } 177 178 void dc_q_init(DC* dc) { 179 // TODO: handle error cleanup, re-attach, etc 180 dc_q_clear(dc); 181 182 if ((dc->status == DC_DETACHED) && (dc->flags & DCF_AUTO_ATTACH)) { 183 INFO("attach: auto\n"); 184 dc->qerror = dc_attach(dc, 0, 0, 0); 185 } 186 } 187 188 // unpack the status bits into a useful status code 189 static int dc_decode_status(unsigned n) { 190 unsigned ack = n & RSP_ACK_MASK; 191 if (n & RSP_ProtocolError) { 192 ERROR("DAP SWD Parity Error\n"); 193 return DC_ERR_SWD_PARITY; 194 } 195 switch (ack) { 196 case RSP_ACK_OK: 197 break; 198 case RSP_ACK_WAIT: 199 ERROR("DAP SWD WAIT (Timeout)\n"); 200 return DC_ERR_TIMEOUT; 201 case RSP_ACK_FAULT: 202 ERROR("DAP SWD FAULT\n"); 203 return DC_ERR_SWD_FAULT; 204 case RSP_ACK_MASK: // all bits set 205 ERROR("DAP SWD SILENT\n"); 206 return DC_ERR_SWD_SILENT; 207 default: 208 ERROR("DAP SWD BOGUS\n"); 209 return DC_ERR_SWD_BOGUS; 210 } 211 if (n & RSP_ValueMismatch) { 212 ERROR("DAP Value Mismatch\n"); 213 return DC_ERR_MATCH; 214 } 215 return DC_OK; 216 } 217 218 // this internal version is called from the "public" dc_q_exec 219 // as well as when we need to flush outstanding txns before 220 // continuing to queue up more 221 static int _dc_q_exec(DC* dc) { 222 // if we're already in error, don't generate more usb traffic 223 if (dc->qerror) { 224 int r = dc->qerror; 225 dc_q_clear(dc); 226 return r; 227 } 228 // if we have no work to do, succeed 229 if (dc->txbuf[2] == 0) { 230 return 0; 231 } 232 int sz = dc->txnext - dc->txbuf; 233 dump("TX>", dc->txbuf, sz); 234 int n = usb_write(dc->usb, dc->txbuf, sz); 235 if (n != sz) { 236 ERROR("dc_q_exec() usb write error\n"); 237 if (n < 0) { 238 usb_failure(dc, n); 239 } 240 return DC_ERR_IO; 241 } 242 sz = 3 + (dc->rxnext - dc->rxptr) * 4; 243 uint8_t rxbuf[1024]; 244 memset(rxbuf, 0xEE, 1024); // DEBUG 245 n = usb_read(dc->usb, rxbuf, sz); 246 if (n < 0) { 247 ERROR("dc_q_exec() usb read error\n"); 248 usb_failure(dc, n); 249 return DC_ERR_IO; 250 } 251 dump("RX>", rxbuf, sz); 252 if ((n < 3) || (rxbuf[0] != DAP_Transfer)) { 253 ERROR("dc_q_exec() bad response\n"); 254 return DC_ERR_PROTOCOL; 255 } 256 int r = dc_decode_status(rxbuf[2]); 257 if (r == DC_OK) { 258 // how many response words available? 259 n = (n - 3) / 4; 260 uint8_t* rxptr = rxbuf + 3; 261 for (unsigned i = 0; i < n; i++) { 262 memcpy(dc->rxptr[i], rxptr, 4); 263 rxptr += 4; 264 } 265 } 266 267 dc_q_clear(dc); 268 return r; 269 } 270 271 // the public dc_q_exec() is called from higher layers 272 int dc_q_exec(DC* dc) { 273 int r = _dc_q_exec(dc); 274 if (r == DC_ERR_SWD_FAULT) { 275 // clear all sticky errors 276 if (dc_dp_wr(dc, DP_ABORT, DP_ABORT_ALLCLR) < 0) { 277 dc_set_status(dc, DC_DETACHED); 278 } 279 } 280 return r; 281 } 282 283 // internal use only -- queue raw dp reads and writes 284 // these do not check req for correctness 285 static void dc_q_raw_rd(DC* dc, unsigned req, uint32_t* val) { 286 if ((dc->txavail < 1) || (dc->rxavail < 4)) { 287 // exec q to make space for more work, 288 // but if there's an error, latch it 289 // so we don't send any further txns 290 if ((dc->qerror = _dc_q_exec(dc)) != DC_OK) { 291 return; 292 } 293 } 294 dc->txnext[0] = req; 295 dc->rxnext[0] = val; 296 dc->txnext += 1; 297 dc->rxnext += 1; 298 dc->txbuf[2] += 1; 299 dc->txavail -= 1; 300 dc->rxavail -= 4; 301 } 302 303 static void dc_q_raw_wr(DC* dc, unsigned req, uint32_t val) { 304 if (dc->txavail < 5) { 305 // exec q to make space for more work, 306 // but if there's an error, latch it 307 // so we don't send any further txns 308 if ((dc->qerror = _dc_q_exec(dc)) != DC_OK) { 309 return; 310 } 311 } 312 dc->txnext[0] = req; 313 memcpy(dc->txnext + 1, &val, 4); 314 dc->txnext += 5; 315 dc->txavail -= 5; 316 dc->txbuf[2] += 1; 317 } 318 319 // adjust DP.SELECT for desired DP access, if necessary 320 void dc_q_dp_sel(DC* dc, uint32_t dpaddr) { 321 // DP address is BANK:4 REG:4 322 if (dpaddr & 0xFFFFFF03U) { 323 ERROR("invalid DP addr 0x%08x\n", dpaddr); 324 dc->qerror = DC_ERR_FAILED; 325 return; 326 } 327 // only register 4 cares about the value of DP.SELECT.DPBANK 328 // so do nothing unless we're setting a register 4 variant 329 if ((dpaddr & 0xF) != 0x4) { 330 return; 331 } 332 uint32_t mask = DP_SELECT_DPBANK(0xFU); 333 uint32_t addr = DP_SELECT_DPBANK((dpaddr >> 4)); 334 uint32_t select = (dc->dp_select & mask) | addr; 335 if (select != dc->dp_select_cache) { 336 dc->dp_select_cache = select; 337 dc_q_raw_wr(dc, XFER_DP | XFER_WR | DP_SELECT, select); 338 } 339 } 340 341 // adjust DP.SELECT for desired AP access, if necessary 342 void dc_q_ap_sel(DC* dc, uint32_t apaddr) { 343 // AP address is AP:8 BANK:4 REG:4 344 if (apaddr & 0xFFFF0003U) { 345 ERROR("invalid DP addr 0x%08x\n", apaddr); 346 dc->qerror = DC_ERR_FAILED; 347 return; 348 } 349 // we always return DPBANK to 0 when adjusting AP & APBANK 350 // since it preceeds an AP write which will need DPBANK at 0 351 uint32_t select = 352 DP_SELECT_AP((apaddr & 0xFF00U) << 16) | 353 DP_SELECT_APBANK(apaddr >> 4); 354 if (select != dc->dp_select_cache) { 355 dc->dp_select_cache = select; 356 dc_q_raw_wr(dc, XFER_DP | XFER_WR | DP_SELECT, select); 357 } 358 } 359 360 // DP and AP reads and writes 361 // DP.SELECT will be adjusted as necessary to ensure proper addressing 362 void dc_q_dp_rd(DC* dc, unsigned dpaddr, uint32_t* val) { 363 if (dc->qerror) return; 364 dc_q_dp_sel(dc, dpaddr); 365 dc_q_raw_rd(dc, XFER_DP | XFER_RD | (dpaddr & 0x0C), val); 366 } 367 368 void dc_q_dp_wr(DC* dc, unsigned dpaddr, uint32_t val) { 369 if (dc->qerror) return; 370 dc_q_dp_sel(dc, dpaddr); 371 dc_q_raw_wr(dc, XFER_DP | XFER_WR | (dpaddr & 0x0C), val); 372 } 373 374 void dc_q_ap_rd(DC* dc, unsigned apaddr, uint32_t* val) { 375 if (dc->qerror) return; 376 dc_q_ap_sel(dc, apaddr); 377 dc_q_raw_rd(dc, XFER_AP | XFER_RD | (apaddr & 0x0C), val); 378 } 379 380 void dc_q_ap_wr(DC* dc, unsigned apaddr, uint32_t val) { 381 if (dc->qerror) return; 382 dc_q_ap_sel(dc, apaddr); 383 dc_q_raw_wr(dc, XFER_AP | XFER_WR | (apaddr & 0x0C), val); 384 } 385 386 void dc_q_set_mask(DC* dc, uint32_t mask) { 387 if (dc->qerror) return; 388 if (dc->cfg_mask == mask) return; 389 dc->cfg_mask = mask; 390 dc_q_raw_wr(dc, XFER_WR | XFER_MatchMask, mask); 391 } 392 393 void dc_set_match_retry(dctx_t* dc, unsigned num) { 394 if (dc->qerror) return; 395 dap_xfer_config(dc, dc->cfg_idle, dc->cfg_wait, num); 396 } 397 398 void dc_q_ap_match(DC* dc, unsigned apaddr, uint32_t val) { 399 if (dc->qerror) return; 400 dc_q_ap_sel(dc, apaddr); 401 dc_q_raw_wr(dc, XFER_AP | XFER_RD | XFER_ValueMatch | (apaddr & 0x0C), val); 402 } 403 404 void dc_q_dp_match(DC* dc, unsigned apaddr, uint32_t val) { 405 if (dc->qerror) return; 406 dc_q_ap_sel(dc, apaddr); 407 dc_q_raw_wr(dc, XFER_DP | XFER_RD | XFER_ValueMatch | (apaddr & 0x0C), val); 408 } 409 410 // convenience wrappers for single reads and writes 411 int dc_dp_rd(DC* dc, unsigned dpaddr, uint32_t* val) { 412 dc_q_init(dc); 413 dc_q_dp_rd(dc, dpaddr, val); 414 return dc_q_exec(dc); 415 } 416 int dc_dp_wr(DC* dc, unsigned dpaddr, uint32_t val) { 417 dc_q_init(dc); 418 dc_q_dp_wr(dc, dpaddr, val); 419 return dc_q_exec(dc); 420 } 421 int dc_ap_rd(DC* dc, unsigned apaddr, uint32_t* val) { 422 dc_q_init(dc); 423 dc_q_ap_rd(dc, apaddr, val); 424 return dc_q_exec(dc); 425 } 426 int dc_ap_wr(DC* dc, unsigned apaddr, uint32_t val) { 427 dc_q_init(dc); 428 dc_q_ap_wr(dc, apaddr, val); 429 return dc_q_exec(dc); 430 } 431 432 // SWD Attach Sequence: 433 // 1. Send >50 1s and then the JTAG to SWD escape code 434 // (in case this is a JTAG-SWD DAP in JTAG mode) 435 // 2. Send >8 1s and then the Selection Alert Sequence 436 // and then the SWD Activation Code 437 // (in case this is a SWD v2 DAP in Dormant State) 438 // 3. Send >50 1s and then 4 0s -- the Line Reset Sequence 439 // 4. If multidrop, issue a write to DP.TARGETSEL, but 440 // ignore the ACK response 441 // 5. Issue a read from DP.IDR 442 443 static uint8_t attach_cmd[54] = { 444 DAP_SWD_Sequence, 5, 445 446 // [--- 64 1s ----------------------------------] 447 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 448 // [JTAG2SWD] [- 16 1s ] [--------------------- 449 0x00, 0x9E, 0xE7, 0xFF, 0xFF, 0x92, 0xF3, 0x09, 0x62, 450 // ----- Selection Alert Sequence --------------- 451 0x00, 0x95, 0x2D, 0x85, 0x86, 0xE9, 0xAF, 0xDD, 0xE3, 452 // ---------------------] [Act Code] [--------- 453 0x00, 0xA2, 0x0E, 0xBC, 0x19, 0xA0, 0xF1, 0xFF, 0xFF, 454 // ----- Line Reset Sequence -------] 455 0x30, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 456 457 // WR DP TARGETSEL 458 0x08, 0x99, 459 // 5 bits idle 460 0x85, 461 // WR VALUE:32, PARTY:1, ZEROs:7 462 0x28, 0x00, 0x00, 0x00, 0x00, 0x00 463 }; 464 465 static int _dc_attach(DC* dc, unsigned flags, uint32_t tgt, uint32_t* idcode) { 466 uint8_t rsp[3]; 467 468 if (flags & DC_MULTIDROP) { 469 // Copy and patch the attach sequence to include 470 // the DP.TARGETSEL write and insert the target 471 // id and parity 472 uint8_t cmd[54]; 473 memcpy(cmd, attach_cmd, 54); 474 cmd[1] = 8; 475 memcpy(cmd + 49, &tgt, sizeof(tgt)); 476 cmd[53] = __builtin_parity(tgt); 477 dap_cmd(dc, cmd, 54, rsp, 3); 478 } else { 479 // use the common part of the attach sequence, as-is 480 dap_cmd(dc, attach_cmd, 45, rsp, 2); 481 } 482 483 // Issue a bare DP.IDR read, as required after a line reset 484 // or line reset + target select 485 _dc_q_init(dc); 486 dc_q_raw_rd(dc, XFER_DP | XFER_RD | XFER_00, idcode); 487 int r = _dc_q_exec(dc); 488 return r; 489 } 490 491 int dc_attach(DC* dc, unsigned flags, unsigned tgt, uint32_t* idcode) { 492 uint32_t n; 493 494 _dc_attach(dc, 0, 0, &n); 495 INFO("attach: IDCODE %08x\n", n); 496 if (idcode != NULL) { 497 *idcode = n; 498 } 499 500 // If this is a RP2040, we need to connect in multidrop 501 // mode before doing anything else. 502 if ((n == 0x0bc12477) && (tgt == 0)) { 503 dc_dp_rd(dc, DP_TARGETID, &n); 504 if (n == 0x01002927) { // RP2040 505 _dc_attach(dc, DC_MULTIDROP, 0x01002927, &n); 506 } 507 } 508 509 _dc_q_init(dc); 510 dc_q_dp_rd(dc, DP_CS, &n); 511 dc_q_exec(dc); 512 DEBUG("attach: CTRL/STAT %08x\n", n); 513 514 // clear all sticky errors 515 _dc_q_init(dc); 516 dc_q_dp_wr(dc, DP_ABORT, DP_ABORT_ALLCLR); 517 dc_q_exec(dc); 518 519 // power up and wait for ack 520 _dc_q_init(dc); 521 dc_q_set_mask(dc, DP_CS_CDBGPWRUPACK | DP_CS_CSYSPWRUPACK); 522 dc_q_dp_wr(dc, DP_CS, DP_CS_CDBGPWRUPREQ | DP_CS_CSYSPWRUPREQ); 523 dc_q_dp_match(dc, DP_CS, DP_CS_CDBGPWRUPACK | DP_CS_CSYSPWRUPACK); 524 dc_q_dp_rd(dc, DP_CS, &n); 525 dc_q_ap_rd(dc, MAP_CSW, &dc->map_csw_keep); 526 dc_q_exec(dc); 527 DEBUG("attach: CTRL/STAT %08x\n", n); 528 DEBUG("attach: MAP.CSW %08x\n", dc->map_csw_keep); 529 530 //preserving existing settings is insufficient 531 //dc->map_csw_keep &= MAP_CSW_KEEP; 532 533 dc->map_csw_keep = AHB_CSW_PROT_PRIV | AHB_CSW_MASTER_DEBUG; 534 535 dc_set_status(dc, DC_ATTACHED); 536 537 if (dc->flags & DCF_AUTO_CONFIG) { 538 // ... 539 } 540 541 return 0; 542 } 543 544 545 static unsigned dc_vid = 0; 546 static unsigned dc_pid = 0; 547 static const char* dc_serialno = NULL; 548 549 void dc_require_vid_pid(unsigned vid, unsigned pid) { 550 dc_vid = vid; 551 dc_pid = pid; 552 } 553 554 void dc_require_serialno(const char* sn) { 555 dc_serialno = sn; 556 } 557 558 static usb_handle* usb_connect(void) { 559 return usb_open(dc_vid, dc_pid, dc_serialno); 560 } 561 562 static const char* di_name(unsigned n) { 563 switch (n) { 564 case DI_Vendor_Name: return "Vendor Name"; 565 case DI_Product_Name: return "Product Name"; 566 case DI_Serial_Number: return "Serial Number"; 567 case DI_Protocol_Version: return "Protocol Version"; 568 case DI_Target_Device_Vendor: return "Target Device Vendor"; 569 case DI_Target_Device_Name: return "Target Device Name"; 570 case DI_Target_Board_Vendor: return "Target Board Vendor"; 571 case DI_Target_Board_Name: return "Target Board Name"; 572 case DI_Product_Firmware_Version: return "Product Firmware Version"; 573 default: return "???"; 574 } 575 } 576 577 // setup a newly connected DAP device 578 static int dap_configure(DC* dc) { 579 uint8_t buf[256 + 2]; 580 uint32_t n32; 581 uint16_t n16; 582 uint8_t n8; 583 584 // invalidate cached state 585 dc->cfg_idle = INVALID; 586 dc->cfg_wait = INVALID; 587 dc->cfg_match = INVALID; 588 dc->cfg_mask = INVALID; 589 590 dc->map_csw_keep = 0; 591 dc->map_csw_cache = INVALID; 592 dc->map_tar_cache = INVALID; 593 594 // setup default packet limits 595 dc->max_packet_count = 1; 596 dc->max_packet_size = 64; 597 598 // flush queue 599 dc_q_clear(dc); 600 601 buf[0] = DAP_Info; 602 for (unsigned n = 0; n < 10; n++) { 603 int sz = dap_get_info(dc, n, buf, 0, 255); 604 if (sz > 0) { 605 buf[sz] = 0; 606 INFO("connect: %s: '%s'\n", di_name(n), (char*) buf); 607 } 608 } 609 610 buf[0] = 0; buf[1] = 0; 611 if (dap_get_info(dc, DI_Capabilities, buf, 1, 2) > 0) { 612 INFO("connect: Capabilities:"); 613 if (buf[0] & I0_SWD) INFO(" SWD"); 614 if (buf[0] & I0_JTAG) INFO(" JTAG"); 615 if (buf[0] & I0_SWO_UART) INFO(" SWO(UART)"); 616 if (buf[0] & I0_SWO_Manchester) INFO(" SWO(Manchester)"); 617 if (buf[0] & I0_Atomic_Commands) INFO(" ATOMIC"); 618 if (buf[0] & I0_Test_Domain_Timer) INFO(" TIMER"); 619 if (buf[0] & I0_SWO_Streaming_Trace) INFO(" SWO(Streaming)"); 620 if (buf[0] & I0_UART_Comm_Port) INFO(" UART"); 621 if (buf[1] & I1_USB_COM_Port) INFO(" USBCOM"); 622 INFO("\n"); 623 } 624 if (dap_get_info(dc, DI_UART_RX_Buffer_Size, &n32, 4, 4) == 4) { 625 INFO("connect: UART RX Buffer Size: %u\n", n32); 626 } 627 if (dap_get_info(dc, DI_UART_TX_Buffer_Size, &n32, 4, 4) == 4) { 628 INFO("connect: UART TX Buffer Size: %u\n", n32); 629 } 630 if (dap_get_info(dc, DI_SWO_Trace_Buffer_Size, &n32, 4, 4) == 4) { 631 INFO("connect: SWO Trace Buffer Size: %u\n", n32); 632 } 633 if (dap_get_info(dc, DI_Max_Packet_Count, &n8, 1, 1) == 1) { 634 dc->max_packet_count = n8; 635 } 636 if (dap_get_info(dc, DI_Max_Packet_Size, &n16, 2, 2) == 2) { 637 dc->max_packet_size = n16; 638 } 639 INFO("connect: Max Packet Count: %u, Size: %u\n", 640 dc->max_packet_count, dc->max_packet_size); 641 if ((dc->max_packet_count < 1) || (dc->max_packet_size < 64)) { 642 ERROR("dc_init() impossible packet configuration\n"); 643 return DC_ERR_PROTOCOL; 644 } 645 646 // invalidate register cache 647 dc->dp_select_cache = INVALID; 648 649 // clip to our buffer size 650 if (dc->max_packet_size > 1024) { 651 dc->max_packet_size = 1024; 652 } 653 654 dap_connect(dc); 655 dap_swd_configure(dc, CFG_Turnaround_1); 656 dap_xfer_config(dc, 8, 64, 64); 657 return DC_OK; 658 } 659 660 static int dc_connect(DC* dc) { 661 if ((dc->usb = usb_connect()) != NULL) { 662 if (dap_configure(dc) == 0) { 663 dc_set_status(dc, DC_DETACHED); 664 } else { 665 dc_set_status(dc, DC_UNCONFIG); 666 } 667 return 0; 668 } 669 return DC_ERR_FAILED; 670 } 671 672 int dc_create(DC** out, void (*cb)(void *cookie, uint32_t status), void *cookie) { 673 DC* dc; 674 675 if ((dc = calloc(1, sizeof(DC))) == NULL) { 676 return DC_ERR_FAILED; 677 } 678 dc->status_callback = cb; 679 dc->status_cookie = cookie; 680 dc->flags = DCF_POLL | DCF_AUTO_ATTACH; 681 *out = dc; 682 dc_set_status(dc, DC_OFFLINE); 683 dc_connect(dc); 684 return 0; 685 } 686 687 int dc_periodic(DC* dc) { 688 switch (dc->status) { 689 case DC_OFFLINE: 690 if (dc_connect(dc) < 0) { 691 return 500; 692 } else { 693 return 100; 694 } 695 case DC_ATTACHED: 696 if (dc->flags & DCF_POLL) { 697 uint32_t n; 698 int r = dc_dp_rd(dc, DP_CS, &n); 699 if (r == DC_ERR_IO) { 700 dc_set_status(dc, DC_OFFLINE); 701 ERROR("offline\n"); 702 } else if (r < 0) { 703 dc_set_status(dc, DC_DETACHED); 704 ERROR("detached\n"); 705 } 706 } 707 return 100; 708 case DC_FAILURE: 709 case DC_UNCONFIG: 710 case DC_DETACHED: { 711 // ping the probe to see if USB is still connected 712 uint8_t buf[256 + 2]; 713 dap_get_info(dc, DI_Protocol_Version, buf, 0, 255); 714 return 500; 715 } 716 default: 717 return 1000; 718 } 719 } 720