xdebug

next generation of mdebug (work in progress)
git clone http://frotz.net/git/xdebug.git
Log | Files | Refs | README

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