DAP(Debug Access Port) interface
Dependents: USBMSD_LPC_HelloWorld lpcterm2 Simple-CMSIS-DAP 11u35_usbLocalFilesystem
BaseDAP.cpp@0:76588be01e71, 2013-09-14 (annotated)
- Committer:
- va009039
- Date:
- Sat Sep 14 11:21:12 2013 +0000
- Revision:
- 0:76588be01e71
first commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
va009039 | 0:76588be01e71 | 1 | // BaseDAP.cpp 2013/9/14 |
va009039 | 0:76588be01e71 | 2 | #include "BaseDAP.h" |
va009039 | 0:76588be01e71 | 3 | |
va009039 | 0:76588be01e71 | 4 | BaseDAP::BaseDAP(SWD* swd) : _swd(swd) |
va009039 | 0:76588be01e71 | 5 | { |
va009039 | 0:76588be01e71 | 6 | } |
va009039 | 0:76588be01e71 | 7 | |
va009039 | 0:76588be01e71 | 8 | BaseDAP::~BaseDAP() |
va009039 | 0:76588be01e71 | 9 | { |
va009039 | 0:76588be01e71 | 10 | } |
va009039 | 0:76588be01e71 | 11 | |
va009039 | 0:76588be01e71 | 12 | int BaseDAP::Command(uint8_t* request, uint8_t* response) |
va009039 | 0:76588be01e71 | 13 | { |
va009039 | 0:76588be01e71 | 14 | switch(*request) { |
va009039 | 0:76588be01e71 | 15 | case 0x00: return Info(request, response); |
va009039 | 0:76588be01e71 | 16 | case 0x01: return LED(request, response); |
va009039 | 0:76588be01e71 | 17 | case 0x02: return Connect(request, response); |
va009039 | 0:76588be01e71 | 18 | case 0x03: return Disconnect(request, response); |
va009039 | 0:76588be01e71 | 19 | case 0x04: return TransferConfigure(request, response); |
va009039 | 0:76588be01e71 | 20 | case 0x05: return Transfer(request, response); |
va009039 | 0:76588be01e71 | 21 | case 0x06: return TransferBlock(request, response); |
va009039 | 0:76588be01e71 | 22 | |
va009039 | 0:76588be01e71 | 23 | case 0x08: return WriteABORT(request, response); |
va009039 | 0:76588be01e71 | 24 | |
va009039 | 0:76588be01e71 | 25 | case 0x10: return SWJ_Pins(request, response); |
va009039 | 0:76588be01e71 | 26 | case 0x11: return SWJ_Clock(request, response); |
va009039 | 0:76588be01e71 | 27 | case 0x12: return SWJ_Sequence(request, response); |
va009039 | 0:76588be01e71 | 28 | case 0x13: return SWD_Configure(request, response); |
va009039 | 0:76588be01e71 | 29 | |
va009039 | 0:76588be01e71 | 30 | case 0x80 ... 0x9f: return Vendor(request, response); |
va009039 | 0:76588be01e71 | 31 | }; |
va009039 | 0:76588be01e71 | 32 | return Invalid(request, response); |
va009039 | 0:76588be01e71 | 33 | } |
va009039 | 0:76588be01e71 | 34 | |
va009039 | 0:76588be01e71 | 35 | /* virtual */ const char* BaseDAP::getInfo(int id) |
va009039 | 0:76588be01e71 | 36 | { |
va009039 | 0:76588be01e71 | 37 | const char* info_str[] = { |
va009039 | 0:76588be01e71 | 38 | NULL, // 1 VENDOR |
va009039 | 0:76588be01e71 | 39 | NULL, // 2 PRODUCT |
va009039 | 0:76588be01e71 | 40 | NULL, // 3 SER_NUM |
va009039 | 0:76588be01e71 | 41 | "1.0", // 4 FW_VER |
va009039 | 0:76588be01e71 | 42 | NULL, // 5 DEVICE_VENDOR |
va009039 | 0:76588be01e71 | 43 | NULL, // 6 DEVICE_NAME |
va009039 | 0:76588be01e71 | 44 | }; |
va009039 | 0:76588be01e71 | 45 | if (id >= 1 && id <= 6) { |
va009039 | 0:76588be01e71 | 46 | return info_str[id-1]; |
va009039 | 0:76588be01e71 | 47 | } |
va009039 | 0:76588be01e71 | 48 | return NULL; |
va009039 | 0:76588be01e71 | 49 | } |
va009039 | 0:76588be01e71 | 50 | |
va009039 | 0:76588be01e71 | 51 | /* virtual */ int BaseDAP::Info(uint8_t* request, uint8_t* response) // 0x00 |
va009039 | 0:76588be01e71 | 52 | { |
va009039 | 0:76588be01e71 | 53 | const char* s; |
va009039 | 0:76588be01e71 | 54 | int slen; |
va009039 | 0:76588be01e71 | 55 | response[0] = 0x00; // Info |
va009039 | 0:76588be01e71 | 56 | int length = 2; |
va009039 | 0:76588be01e71 | 57 | int id = request[1]; |
va009039 | 0:76588be01e71 | 58 | switch(id) { |
va009039 | 0:76588be01e71 | 59 | case 1 ... 6: // VENDOR PRODUCT SER_NUM FW_VER DEVICE_VENDOR DEVICE_NAME |
va009039 | 0:76588be01e71 | 60 | slen = 0; |
va009039 | 0:76588be01e71 | 61 | s = getInfo(id); |
va009039 | 0:76588be01e71 | 62 | if (s) { |
va009039 | 0:76588be01e71 | 63 | slen = strlen(s) + 1; |
va009039 | 0:76588be01e71 | 64 | memcpy(response+2, s, slen); |
va009039 | 0:76588be01e71 | 65 | } |
va009039 | 0:76588be01e71 | 66 | response[1] = slen; |
va009039 | 0:76588be01e71 | 67 | length += slen; |
va009039 | 0:76588be01e71 | 68 | break; |
va009039 | 0:76588be01e71 | 69 | case 0xf0: // CAPABILITIES |
va009039 | 0:76588be01e71 | 70 | response[1] = sizeof(uint8_t); |
va009039 | 0:76588be01e71 | 71 | response[2] = 0x01; // SWD |
va009039 | 0:76588be01e71 | 72 | length += sizeof(uint8_t); |
va009039 | 0:76588be01e71 | 73 | break; |
va009039 | 0:76588be01e71 | 74 | case 0xfe: // PACKET_COUNT |
va009039 | 0:76588be01e71 | 75 | response[1] = sizeof(uint8_t); |
va009039 | 0:76588be01e71 | 76 | response[2] = 1; |
va009039 | 0:76588be01e71 | 77 | length += sizeof(uint8_t); |
va009039 | 0:76588be01e71 | 78 | break; |
va009039 | 0:76588be01e71 | 79 | case 0xff: // PACKET_SIZE |
va009039 | 0:76588be01e71 | 80 | response[1] = sizeof(uint16_t); |
va009039 | 0:76588be01e71 | 81 | ST<uint16_t>(response+2, 64); |
va009039 | 0:76588be01e71 | 82 | length += sizeof(uint16_t); |
va009039 | 0:76588be01e71 | 83 | break; |
va009039 | 0:76588be01e71 | 84 | default: |
va009039 | 0:76588be01e71 | 85 | response[1] = DAP_ERROR; |
va009039 | 0:76588be01e71 | 86 | break; |
va009039 | 0:76588be01e71 | 87 | } |
va009039 | 0:76588be01e71 | 88 | return length; |
va009039 | 0:76588be01e71 | 89 | } |
va009039 | 0:76588be01e71 | 90 | |
va009039 | 0:76588be01e71 | 91 | /* virtual */ void BaseDAP::infoLED(int select, int value) |
va009039 | 0:76588be01e71 | 92 | { |
va009039 | 0:76588be01e71 | 93 | } |
va009039 | 0:76588be01e71 | 94 | |
va009039 | 0:76588be01e71 | 95 | int BaseDAP::LED(uint8_t* request, uint8_t* response) // 0x01 |
va009039 | 0:76588be01e71 | 96 | { |
va009039 | 0:76588be01e71 | 97 | infoLED(request[1], request[2]&1); |
va009039 | 0:76588be01e71 | 98 | response[0] = 0x01; // LED |
va009039 | 0:76588be01e71 | 99 | response[1] = DAP_OK; |
va009039 | 0:76588be01e71 | 100 | return 2; |
va009039 | 0:76588be01e71 | 101 | } |
va009039 | 0:76588be01e71 | 102 | |
va009039 | 0:76588be01e71 | 103 | int BaseDAP::Connect(uint8_t* request, uint8_t* response) // 0x02 |
va009039 | 0:76588be01e71 | 104 | { |
va009039 | 0:76588be01e71 | 105 | response[0] = 0x02; // Connect |
va009039 | 0:76588be01e71 | 106 | response[1] = DAP_PORT_DISABLED; |
va009039 | 0:76588be01e71 | 107 | if (_swd) { |
va009039 | 0:76588be01e71 | 108 | if (request[1] == DAP_PORT_AUTODETECT || request[1] == DAP_PORT_SWD) { |
va009039 | 0:76588be01e71 | 109 | response[1] = DAP_PORT_SWD; |
va009039 | 0:76588be01e71 | 110 | _swd->Setup(); |
va009039 | 0:76588be01e71 | 111 | } |
va009039 | 0:76588be01e71 | 112 | } |
va009039 | 0:76588be01e71 | 113 | return 2; |
va009039 | 0:76588be01e71 | 114 | } |
va009039 | 0:76588be01e71 | 115 | |
va009039 | 0:76588be01e71 | 116 | int BaseDAP::Disconnect(uint8_t* request, uint8_t* response) // 0x03 |
va009039 | 0:76588be01e71 | 117 | { |
va009039 | 0:76588be01e71 | 118 | response[0] = 0x03; // disconnect |
va009039 | 0:76588be01e71 | 119 | response[1] = DAP_OK; |
va009039 | 0:76588be01e71 | 120 | return 2; |
va009039 | 0:76588be01e71 | 121 | } |
va009039 | 0:76588be01e71 | 122 | |
va009039 | 0:76588be01e71 | 123 | int BaseDAP::TransferConfigure(uint8_t* request, uint8_t* response) // 0x04 |
va009039 | 0:76588be01e71 | 124 | { |
va009039 | 0:76588be01e71 | 125 | uint8_t idle_cycles = request[1]; |
va009039 | 0:76588be01e71 | 126 | uint16_t retry_count = LD<uint16_t>(request+2); |
va009039 | 0:76588be01e71 | 127 | transfer.match_retry = LD<uint16_t>(request+4); |
va009039 | 0:76588be01e71 | 128 | _swd->TransferConfigure(idle_cycles, retry_count); |
va009039 | 0:76588be01e71 | 129 | response[0] = 0x04; //tansfer configure |
va009039 | 0:76588be01e71 | 130 | response[1] = DAP_OK; |
va009039 | 0:76588be01e71 | 131 | return 2; |
va009039 | 0:76588be01e71 | 132 | } |
va009039 | 0:76588be01e71 | 133 | |
va009039 | 0:76588be01e71 | 134 | int BaseDAP::Transfer(uint8_t* request, uint8_t* response) // 0x05 |
va009039 | 0:76588be01e71 | 135 | { |
va009039 | 0:76588be01e71 | 136 | return transfer.Transfer(_swd, request, response); |
va009039 | 0:76588be01e71 | 137 | } |
va009039 | 0:76588be01e71 | 138 | |
va009039 | 0:76588be01e71 | 139 | int BaseDAP::TransferBlock(uint8_t* request, uint8_t* response) // 0x06 |
va009039 | 0:76588be01e71 | 140 | { |
va009039 | 0:76588be01e71 | 141 | return transfer.TransferBlock(_swd, request, response); |
va009039 | 0:76588be01e71 | 142 | } |
va009039 | 0:76588be01e71 | 143 | |
va009039 | 0:76588be01e71 | 144 | int BaseDAP::WriteABORT(uint8_t* request, uint8_t* response) // 0x08 |
va009039 | 0:76588be01e71 | 145 | { |
va009039 | 0:76588be01e71 | 146 | uint32_t data = LD<uint32_t>(request+2); |
va009039 | 0:76588be01e71 | 147 | uint8_t ack = _swd->Transfer(DP_ABORT, &data); |
va009039 | 0:76588be01e71 | 148 | response[0] = 0x08; // write abort |
va009039 | 0:76588be01e71 | 149 | response[1] = ack == SWD_OK ? DAP_OK : DAP_ERROR; |
va009039 | 0:76588be01e71 | 150 | return 2; |
va009039 | 0:76588be01e71 | 151 | } |
va009039 | 0:76588be01e71 | 152 | |
va009039 | 0:76588be01e71 | 153 | int BaseDAP::Delay(uint8_t* request, uint8_t* response) // 0x09 |
va009039 | 0:76588be01e71 | 154 | { |
va009039 | 0:76588be01e71 | 155 | int waittime_ms = LD<uint16_t>(request+1); |
va009039 | 0:76588be01e71 | 156 | wait_ms(waittime_ms); |
va009039 | 0:76588be01e71 | 157 | response[0] = 0x09; |
va009039 | 0:76588be01e71 | 158 | response[1] = DAP_OK; |
va009039 | 0:76588be01e71 | 159 | return 2; |
va009039 | 0:76588be01e71 | 160 | } |
va009039 | 0:76588be01e71 | 161 | |
va009039 | 0:76588be01e71 | 162 | int BaseDAP::ResetTarget(uint8_t* request, uint8_t* response) // 0x0A |
va009039 | 0:76588be01e71 | 163 | { |
va009039 | 0:76588be01e71 | 164 | response[0] = 0x0a; |
va009039 | 0:76588be01e71 | 165 | response[1] = 0; |
va009039 | 0:76588be01e71 | 166 | response[2] = DAP_OK; |
va009039 | 0:76588be01e71 | 167 | return 3; |
va009039 | 0:76588be01e71 | 168 | } |
va009039 | 0:76588be01e71 | 169 | |
va009039 | 0:76588be01e71 | 170 | int BaseDAP::SWJ_Pins(uint8_t* request, uint8_t* response) // 0x10 |
va009039 | 0:76588be01e71 | 171 | { |
va009039 | 0:76588be01e71 | 172 | uint32_t value = request[1]; |
va009039 | 0:76588be01e71 | 173 | uint32_t select = request[2]; |
va009039 | 0:76588be01e71 | 174 | uint32_t waittime_us = LD<uint32_t>(request+3); |
va009039 | 0:76588be01e71 | 175 | response[0] = 0x10; // swj pins |
va009039 | 0:76588be01e71 | 176 | response[1] = _swd->SWJPins(value, select, waittime_us); |
va009039 | 0:76588be01e71 | 177 | return 2; |
va009039 | 0:76588be01e71 | 178 | } |
va009039 | 0:76588be01e71 | 179 | |
va009039 | 0:76588be01e71 | 180 | int BaseDAP::SWJ_Clock(uint8_t* request, uint8_t* response) // 0x11 |
va009039 | 0:76588be01e71 | 181 | { |
va009039 | 0:76588be01e71 | 182 | uint32_t clock = LD<uint32_t>(request+1); |
va009039 | 0:76588be01e71 | 183 | _swd->SWJClock(clock); |
va009039 | 0:76588be01e71 | 184 | response[0] = 0x11; // swj clock |
va009039 | 0:76588be01e71 | 185 | response[1] = DAP_OK; |
va009039 | 0:76588be01e71 | 186 | return 2; |
va009039 | 0:76588be01e71 | 187 | } |
va009039 | 0:76588be01e71 | 188 | |
va009039 | 0:76588be01e71 | 189 | int BaseDAP::SWJ_Sequence(uint8_t* request, uint8_t* response) // 0x12 |
va009039 | 0:76588be01e71 | 190 | { |
va009039 | 0:76588be01e71 | 191 | int count = request[1]; |
va009039 | 0:76588be01e71 | 192 | if (count == 0) { |
va009039 | 0:76588be01e71 | 193 | count = 256; |
va009039 | 0:76588be01e71 | 194 | } |
va009039 | 0:76588be01e71 | 195 | _swd->SWJSequence(count, request+2); |
va009039 | 0:76588be01e71 | 196 | response[0] = 0x12; // swj sequence |
va009039 | 0:76588be01e71 | 197 | response[1] = DAP_OK; |
va009039 | 0:76588be01e71 | 198 | return 2; |
va009039 | 0:76588be01e71 | 199 | } |
va009039 | 0:76588be01e71 | 200 | |
va009039 | 0:76588be01e71 | 201 | int BaseDAP::SWD_Configure(uint8_t* request, uint8_t* response) // 0x13 |
va009039 | 0:76588be01e71 | 202 | { |
va009039 | 0:76588be01e71 | 203 | uint8_t cfg = request[1]; |
va009039 | 0:76588be01e71 | 204 | _swd->Configure((cfg&0x03)+1, cfg&0x04 ? 1: 0); |
va009039 | 0:76588be01e71 | 205 | response[0] = 0x13; // swd configure |
va009039 | 0:76588be01e71 | 206 | response[1] = DAP_OK; |
va009039 | 0:76588be01e71 | 207 | return 2; |
va009039 | 0:76588be01e71 | 208 | } |
va009039 | 0:76588be01e71 | 209 | |
va009039 | 0:76588be01e71 | 210 | /* virtual */ int BaseDAP::Vendor(uint8_t* request, uint8_t* response) // 0x80 ... 0x9f |
va009039 | 0:76588be01e71 | 211 | { |
va009039 | 0:76588be01e71 | 212 | switch(request[0]) { |
va009039 | 0:76588be01e71 | 213 | case 0x80: return Vendor0(request, response); |
va009039 | 0:76588be01e71 | 214 | } |
va009039 | 0:76588be01e71 | 215 | response[0] = 0xff; // invalid |
va009039 | 0:76588be01e71 | 216 | return 1; |
va009039 | 0:76588be01e71 | 217 | } |
va009039 | 0:76588be01e71 | 218 | |
va009039 | 0:76588be01e71 | 219 | int BaseDAP::Vendor0(uint8_t* request, uint8_t* response) // 0x80 |
va009039 | 0:76588be01e71 | 220 | { |
va009039 | 0:76588be01e71 | 221 | const char* board_id = "1040123456789"; // lpc11u24 |
va009039 | 0:76588be01e71 | 222 | int len = strlen(board_id); |
va009039 | 0:76588be01e71 | 223 | response[0] = 0x80; |
va009039 | 0:76588be01e71 | 224 | response[1] = len; |
va009039 | 0:76588be01e71 | 225 | memcpy(response+2, board_id, len); |
va009039 | 0:76588be01e71 | 226 | return len + 1; |
va009039 | 0:76588be01e71 | 227 | } |
va009039 | 0:76588be01e71 | 228 | |
va009039 | 0:76588be01e71 | 229 | /* virtual */ int BaseDAP::Invalid(uint8_t* request, uint8_t* response) |
va009039 | 0:76588be01e71 | 230 | { |
va009039 | 0:76588be01e71 | 231 | response[0] = 0xff; // invalid |
va009039 | 0:76588be01e71 | 232 | return 1; |
va009039 | 0:76588be01e71 | 233 | } |