DAP(Debug Access Port) interface
Dependents: USBMSD_LPC_HelloWorld lpcterm2 Simple-CMSIS-DAP 11u35_usbLocalFilesystem
Revision 0:76588be01e71, committed 2013-09-14
- Comitter:
- va009039
- Date:
- Sat Sep 14 11:21:12 2013 +0000
- Commit message:
- first commit
Changed in this revision
diff -r 000000000000 -r 76588be01e71 BaseDAP.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BaseDAP.cpp Sat Sep 14 11:21:12 2013 +0000 @@ -0,0 +1,233 @@ +// BaseDAP.cpp 2013/9/14 +#include "BaseDAP.h" + +BaseDAP::BaseDAP(SWD* swd) : _swd(swd) +{ +} + +BaseDAP::~BaseDAP() +{ +} + +int BaseDAP::Command(uint8_t* request, uint8_t* response) +{ + switch(*request) { + case 0x00: return Info(request, response); + case 0x01: return LED(request, response); + case 0x02: return Connect(request, response); + case 0x03: return Disconnect(request, response); + case 0x04: return TransferConfigure(request, response); + case 0x05: return Transfer(request, response); + case 0x06: return TransferBlock(request, response); + + case 0x08: return WriteABORT(request, response); + + case 0x10: return SWJ_Pins(request, response); + case 0x11: return SWJ_Clock(request, response); + case 0x12: return SWJ_Sequence(request, response); + case 0x13: return SWD_Configure(request, response); + + case 0x80 ... 0x9f: return Vendor(request, response); + }; + return Invalid(request, response); +} + +/* virtual */ const char* BaseDAP::getInfo(int id) +{ + const char* info_str[] = { + NULL, // 1 VENDOR + NULL, // 2 PRODUCT + NULL, // 3 SER_NUM + "1.0", // 4 FW_VER + NULL, // 5 DEVICE_VENDOR + NULL, // 6 DEVICE_NAME + }; + if (id >= 1 && id <= 6) { + return info_str[id-1]; + } + return NULL; +} + +/* virtual */ int BaseDAP::Info(uint8_t* request, uint8_t* response) // 0x00 +{ + const char* s; + int slen; + response[0] = 0x00; // Info + int length = 2; + int id = request[1]; + switch(id) { + case 1 ... 6: // VENDOR PRODUCT SER_NUM FW_VER DEVICE_VENDOR DEVICE_NAME + slen = 0; + s = getInfo(id); + if (s) { + slen = strlen(s) + 1; + memcpy(response+2, s, slen); + } + response[1] = slen; + length += slen; + break; + case 0xf0: // CAPABILITIES + response[1] = sizeof(uint8_t); + response[2] = 0x01; // SWD + length += sizeof(uint8_t); + break; + case 0xfe: // PACKET_COUNT + response[1] = sizeof(uint8_t); + response[2] = 1; + length += sizeof(uint8_t); + break; + case 0xff: // PACKET_SIZE + response[1] = sizeof(uint16_t); + ST<uint16_t>(response+2, 64); + length += sizeof(uint16_t); + break; + default: + response[1] = DAP_ERROR; + break; + } + return length; +} + +/* virtual */ void BaseDAP::infoLED(int select, int value) +{ +} + +int BaseDAP::LED(uint8_t* request, uint8_t* response) // 0x01 +{ + infoLED(request[1], request[2]&1); + response[0] = 0x01; // LED + response[1] = DAP_OK; + return 2; +} + +int BaseDAP::Connect(uint8_t* request, uint8_t* response) // 0x02 +{ + response[0] = 0x02; // Connect + response[1] = DAP_PORT_DISABLED; + if (_swd) { + if (request[1] == DAP_PORT_AUTODETECT || request[1] == DAP_PORT_SWD) { + response[1] = DAP_PORT_SWD; + _swd->Setup(); + } + } + return 2; +} + +int BaseDAP::Disconnect(uint8_t* request, uint8_t* response) // 0x03 +{ + response[0] = 0x03; // disconnect + response[1] = DAP_OK; + return 2; +} + +int BaseDAP::TransferConfigure(uint8_t* request, uint8_t* response) // 0x04 +{ + uint8_t idle_cycles = request[1]; + uint16_t retry_count = LD<uint16_t>(request+2); + transfer.match_retry = LD<uint16_t>(request+4); + _swd->TransferConfigure(idle_cycles, retry_count); + response[0] = 0x04; //tansfer configure + response[1] = DAP_OK; + return 2; +} + +int BaseDAP::Transfer(uint8_t* request, uint8_t* response) // 0x05 +{ + return transfer.Transfer(_swd, request, response); +} + +int BaseDAP::TransferBlock(uint8_t* request, uint8_t* response) // 0x06 +{ + return transfer.TransferBlock(_swd, request, response); +} + +int BaseDAP::WriteABORT(uint8_t* request, uint8_t* response) // 0x08 +{ + uint32_t data = LD<uint32_t>(request+2); + uint8_t ack = _swd->Transfer(DP_ABORT, &data); + response[0] = 0x08; // write abort + response[1] = ack == SWD_OK ? DAP_OK : DAP_ERROR; + return 2; +} + +int BaseDAP::Delay(uint8_t* request, uint8_t* response) // 0x09 +{ + int waittime_ms = LD<uint16_t>(request+1); + wait_ms(waittime_ms); + response[0] = 0x09; + response[1] = DAP_OK; + return 2; +} + +int BaseDAP::ResetTarget(uint8_t* request, uint8_t* response) // 0x0A +{ + response[0] = 0x0a; + response[1] = 0; + response[2] = DAP_OK; + return 3; +} + +int BaseDAP::SWJ_Pins(uint8_t* request, uint8_t* response) // 0x10 +{ + uint32_t value = request[1]; + uint32_t select = request[2]; + uint32_t waittime_us = LD<uint32_t>(request+3); + response[0] = 0x10; // swj pins + response[1] = _swd->SWJPins(value, select, waittime_us); + return 2; +} + +int BaseDAP::SWJ_Clock(uint8_t* request, uint8_t* response) // 0x11 +{ + uint32_t clock = LD<uint32_t>(request+1); + _swd->SWJClock(clock); + response[0] = 0x11; // swj clock + response[1] = DAP_OK; + return 2; +} + +int BaseDAP::SWJ_Sequence(uint8_t* request, uint8_t* response) // 0x12 +{ + int count = request[1]; + if (count == 0) { + count = 256; + } + _swd->SWJSequence(count, request+2); + response[0] = 0x12; // swj sequence + response[1] = DAP_OK; + return 2; +} + +int BaseDAP::SWD_Configure(uint8_t* request, uint8_t* response) // 0x13 +{ + uint8_t cfg = request[1]; + _swd->Configure((cfg&0x03)+1, cfg&0x04 ? 1: 0); + response[0] = 0x13; // swd configure + response[1] = DAP_OK; + return 2; +} + +/* virtual */ int BaseDAP::Vendor(uint8_t* request, uint8_t* response) // 0x80 ... 0x9f +{ + switch(request[0]) { + case 0x80: return Vendor0(request, response); + } + response[0] = 0xff; // invalid + return 1; +} + +int BaseDAP::Vendor0(uint8_t* request, uint8_t* response) // 0x80 +{ + const char* board_id = "1040123456789"; // lpc11u24 + int len = strlen(board_id); + response[0] = 0x80; + response[1] = len; + memcpy(response+2, board_id, len); + return len + 1; +} + +/* virtual */ int BaseDAP::Invalid(uint8_t* request, uint8_t* response) +{ + response[0] = 0xff; // invalid + return 1; +}
diff -r 000000000000 -r 76588be01e71 BaseDAP.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BaseDAP.h Sat Sep 14 11:21:12 2013 +0000 @@ -0,0 +1,98 @@ +// BaseDAP.h 2013/9/14 +#pragma once +#include "SWD.h" +#include "TransferCore.h" + +// DAP Status Code +#define DAP_OK 0 +#define DAP_ERROR 0xFF + +// DAP Port +#define DAP_PORT_AUTODETECT 0 // Autodetect Port +#define DAP_PORT_DISABLED 0 // Port Disabled (I/O pins in High-Z) +#define DAP_PORT_SWD 1 // SWD Port (SWCLK, SWDIO) + nRESET + +/** DAP(Debug Access Port) interface + * + * Example: + * @code + * #include "BaseDAP.h" + * #include "USBDAP.h" + * + * USBDAP hid(64, 64, 0x0d28, 0x0204); + * + * SWD swd(p21,p22,p17); // SWDIO(dp12),SWCLK(dp3),nReset(dp23) + * DigitalOut connected(LED1); + * DigitalOut running(LED2); + * class myDAP : public BaseDAP { + * public: + * myDAP(SWD* swd):BaseDAP(swd){}; + * virtual void infoLED(int select, int value) { + * switch(select) { + * case 0: connected = value; break; + * case 1: running = value; break; + * } + * } + * }; + * + * int main() + * { + * HID_REPORT recv_report; + * HID_REPORT send_report; + * + * myDAP* dap = new myDAP(&swd); + * while(1) { + * if(hid.readNB(&recv_report)) { + * dap->Command(recv_report.data, send_report.data); + * send_report.length = 64; + * hid.send(&send_report); + * } + * } + * } + * @endcode + */ +class BaseDAP { +public: + /** Create a DAP(Debug Access Port) interface + * @param swd assign SWD interface + */ + BaseDAP(SWD* swd); + virtual ~BaseDAP(); + /** Process command + * @param request request data(64 bytes) + * @param response response data(64 bytes) + * @returns response length + */ + int Command(uint8_t* request, uint8_t* response); +protected: + virtual const char* getInfo(int id); + /** LED indicator + * @param selct 0...connected LED, 1...running LED + * @param value 0...OFF, 1...ON + */ + virtual void infoLED(int select, int value); + + virtual int Info(uint8_t* request, uint8_t* response); // 0x00 + int LED(uint8_t* request, uint8_t* response); // 0x01 + int Connect(uint8_t* request, uint8_t* response); // 0x02 + int Disconnect(uint8_t* request, uint8_t* response); // 0x03 + int TransferConfigure(uint8_t* request, uint8_t* response);// 0x04 + int Transfer(uint8_t* request, uint8_t* response); // 0x05 + int TransferBlock(uint8_t* request, uint8_t* response); // 0x06 + + int WriteABORT(uint8_t* request, uint8_t* response); // 0x08 + int Delay(uint8_t* request, uint8_t* response); // 0x09 + int ResetTarget(uint8_t* request, uint8_t* response); // 0x0A + int SWJ_Pins(uint8_t* request, uint8_t* response); // 0x10 + int SWJ_Clock(uint8_t* request, uint8_t* response); // 0x11 + int SWJ_Sequence(uint8_t* request, uint8_t* response); // 0x12 + int SWD_Configure(uint8_t* request, uint8_t* response); // 0x13 + int Vendor0(uint8_t* request, uint8_t* response); // 0x80 + /** vendor command + */ + virtual int Vendor(uint8_t* request, uint8_t* response);// 0x80-0x9f + virtual int Invalid(uint8_t* request, uint8_t* response); + + TransferCore transfer; + SWD* _swd; +};
diff -r 000000000000 -r 76588be01e71 TransferCore.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TransferCore.cpp Sat Sep 14 11:21:12 2013 +0000 @@ -0,0 +1,184 @@ +// TransferCore.cpp 2013/9/14 +#include "TransferCore.h" + +void transData::init(uint8_t* base, int pos) +{ + _base = base; + _pos = pos; +} + +void transData::append(uint32_t data) +{ + ST<uint32_t>(_base+_pos, data); + _pos += sizeof(uint32_t); +} + +uint8_t* transData::data() +{ + return _base; +} + +int transData::length() +{ + return _pos; +} + +int TransferCore::Transfer(SWD* swd, uint8_t* request, uint8_t* response) // 0x05 +{ + _swd = swd; + reqData.init(request, 2); + resData.init(response, 3); + post_read = check_write = false; + response_count = 0; + uint8_t ack = 0; + for(int count = reqData.get<uint8_t>(); count > 0; count--) { + uint8_t cmd = reqData.get<uint8_t>(); + if (cmd & SWD_RnW) { // read register + ack = read(cmd); + check_write = false; + } else { // write register + ack = write(cmd); + } + if (ack != SWD_OK) { + break; + } + response_count++; + } + if (ack == SWD_OK) { + if (post_read) { // read previous data + uint32_t data; + ack = _swd->Transfer(DP_RDBUFF, &data); + resData.append(data); + } else if (check_write) { // check last write + ack = _swd->Transfer(DP_RDBUFF, NULL); + } + } + resData.data()[0] = 0x05; // transfer + resData.data()[1] = response_count; + resData.data()[2] = ack; + return resData.length(); +} + +uint8_t TransferCore::read(uint8_t cmd) +{ + uint8_t ack = 0; + uint32_t data; + if (post_read) { + if ((cmd & SWD_APnDP) && !(cmd & DAP_TRANSFER_MATCH_VALUE)) { + ack = _swd->Transfer(cmd, &data); // next post_read + } else { + ack = _swd->Transfer(DP_RDBUFF, &data); + post_read = false; + } + if (ack != SWD_OK) { + return ack; + } + resData.append(data); + } + if (cmd & DAP_TRANSFER_MATCH_VALUE) { + uint32_t match_value = reqData.get<uint32_t>(); + if (cmd & SWD_APnDP) { + ack = _swd->Transfer(cmd, NULL); + if (ack != SWD_OK) { + return ack; + } + } + for(int retry = match_retry; retry >= 0; retry--) { + ack = _swd->Transfer(cmd, &data); + if (ack == SWD_OK && (data&match_mask) == match_value) { + return ack; + } + } + return ack | DAP_TRANSFER_MISMATCH; + } else { + if (cmd & SWD_APnDP) { + if (post_read == false) { + ack = _swd->Transfer(cmd, NULL); + post_read = true; + } + } else { + ack = _swd->Transfer(cmd, &data); + resData.append(data); + } + } + return ack; +} + +uint8_t TransferCore::write(uint8_t cmd) +{ + if (post_read) { // read previous data + uint32_t data; + uint8_t ack = _swd->Transfer(DP_RDBUFF, &data); + if (ack != SWD_OK) { + return ack; + } + resData.append(data); + post_read = false; + } + if (cmd & DAP_TRANSFER_MATCH_MASK) { + match_mask = reqData.get<uint32_t>(); + return SWD_OK; + } + check_write = true; + uint32_t data = reqData.get<uint32_t>(); + return _swd->Transfer(cmd, &data); +} + +int TransferCore::TransferBlock(SWD* swd, uint8_t* request, uint8_t* response) +{ + _swd = swd; + reqData.init(request, 2); + resData.init(response, 4); + uint8_t ack = 0; + response_count = 0; + int count = reqData.get<uint16_t>(); + if (count > 0) { + uint8_t cmd = reqData.get<uint8_t>(); + if (cmd & SWD_RnW) { // read register block + ack = read_block(cmd, count); + } else { // write register block + ack = write_block(cmd, count); + } + } + resData.data()[0] = 0x06; // transfer block + ST<uint16_t>(resData.data()+1, response_count); + resData.data()[3] = ack; + return resData.length(); +} + +uint8_t TransferCore::read_block(uint8_t cmd, int count) +{ + if (cmd & SWD_APnDP) { // post AP read + uint8_t ack = _swd->Transfer(cmd, NULL); + if (ack != SWD_OK) { + return ack; + } + } + uint8_t ack = 0; + while(count-- > 0) { // read DP/AP register + if (count == 0 && (cmd & SWD_APnDP)) { // last AP read + cmd = DP_RDBUFF; + } + uint32_t data; + ack = _swd->Transfer(cmd, &data); + if (ack != SWD_OK) { + break; + } + resData.append(data); + response_count++; + } + return ack; +} + +uint8_t TransferCore::write_block(uint8_t cmd, int count) +{ + while(count-- > 0) { + uint32_t data = reqData.get<uint32_t>(); + uint8_t ack = _swd->Transfer(cmd, &data); + if (ack != SWD_OK) { + return ack; + } + response_count++; + } + return _swd->Transfer(DP_RDBUFF, NULL); +}
diff -r 000000000000 -r 76588be01e71 TransferCore.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TransferCore.h Sat Sep 14 11:21:12 2013 +0000 @@ -0,0 +1,66 @@ +// TransferCore.h 2013/9/14 +#pragma once +#include "SWD.h" + +// DAP Transfer Request +#define DAP_TRANSFER_MATCH_VALUE (1<<4) +#define DAP_TRANSFER_MATCH_MASK (1<<5) + +// DAP Transfer Response +#define DAP_TRANSFER_MISMATCH (1<<4) + +template<typename T> +T LD(uint8_t* buf) { + T data = 0; + for(int i = sizeof(T)-1; i >= 0; i--) { + data <<= 8; + data |= buf[i]; + } + return data; +} + +template<typename T> +void ST(uint8_t* buf, T data) { + for(int i = 0; i < sizeof(T); i++) { + buf[i] = data>>(8*i); + } +} + +class transData { +public: + void init(uint8_t* base, int pos); + void append(uint32_t data); + uint8_t* data(); + int length(); + + template<typename T> + T get() { + T data = LD<T>(_base+_pos); + _pos += sizeof(T); + return data; + } +protected: + uint8_t* _base; + int _pos; +}; + +class TransferCore { +public: + int Transfer(SWD* swd, uint8_t* request, uint8_t* response); + int TransferBlock(SWD* swd, uint8_t* request, uint8_t* response); + uint16_t match_retry; // Number of retries if read value does not match + uint32_t match_mask; // Match Mask +private: + uint8_t read(uint8_t cmd); + uint8_t write(uint8_t cmd); + uint8_t read_block(uint8_t cmd, int count); + uint8_t write_block(uint8_t cmd, int count); + + bool post_read; + bool check_write; + transData reqData; + transData resData; + int response_count; +protected: + SWD* _swd; +};