semihost server example program
Dependencies: SWD mbed USBLocalFileSystem BaseDAP USBDAP
LPCXpresso LPC11U68 | LPCXpresso LPC1549 | FRDM-KL46Z | EA LPC4088 QSB app-board | LPC1768 app-board | LPC810 | LPC1114FN28 | |
---|---|---|---|---|---|---|---|
server | server | server | server | server | client | client | |
SWDIO | D12 | D12 | D12 | p25 | p21 | p4(P0_2) | p12 |
SWCLK | D10 | D10 | D10 | p26 | p22 | p3(P0_3) | p3 |
nRESET *option | D6 | D6 | D6 | p34 | p30 | p1(P0_5) | p23 |
GND | GND | GND | GND | p1 | p1 | p7 | p22 |
3.3V | P3V3 | P3V3 | P3V3 | p44 | p40 | p6 | p21 |
flash write | SW2(P0_1) | SW3(P1_9) | SW1 | p14 joystick center | p14 joystick center |
client example:
Import programlpc810-semihost_helloworld
semihost client example program
Revision 3:d7a7cde0bfb8, committed 2013-09-08
- Comitter:
- va009039
- Date:
- Sun Sep 08 14:13:15 2013 +0000
- Parent:
- 2:32e9437348ad
- Child:
- 4:5e4107edcbdb
- Commit message:
- add softwarereset(),flash.init()
Changed in this revision
--- a/Flash.cpp Thu Sep 05 09:34:12 2013 +0000 +++ b/Flash.cpp Sun Sep 08 14:13:15 2013 +0000 @@ -1,8 +1,13 @@ -// Flash.cpp 2013/9/5 +// Flash.cpp 2013/9/6 #include "Flash.h" #include "Target2.h" #include "mydebug.h" +#define SYSMEMREMAP 0x40048000 +#define MAINCLKSEL 0x40048070 +#define MAINCLKUEN 0x40048074 +#define SYSAHBCLKDIV 0x40048078 + Flash::Flash(Target2* target, Serial* usbpc) :_target(target),_pc(usbpc) { _setup(); @@ -14,6 +19,29 @@ _target->wait_status(TARGET_HALTED); } +bool Flash::init() +{ + _pc->printf("Initializing."); + if (_target->idcode == 0x0bb11477) { // LPC1114FN28 + _target->writeMemory(MAINCLKSEL, 0); // Select Internal RC Oscillator + _target->writeMemory(MAINCLKUEN, 1); // Update Main Clock Source + _target->writeMemory(MAINCLKUEN, 0); // Toggle Update Register + _target->writeMemory(MAINCLKUEN, 1); + uint32_t data = _target->readMemory(MAINCLKUEN); // Wait until updated + if (!(data & 1)) { + _pc->printf("\nerror MAINCLKUEN=%08x\n", data); + return false; + } + _target->writeMemory(SYSAHBCLKDIV, 1);// Set Main Clock divider to 1 + _target->writeMemory(SYSMEMREMAP, 2); // User Flash Mode + } else { + _pc->printf("\nerror idcode=%08x\n", _target->idcode); + return false; + } + _pc->printf("passed.\n"); + return true; +} + bool Flash::write(const char* filename) { FILE* fp = fopen(filename, "rb"); @@ -25,11 +53,7 @@ uint8_t buf[256]; bool passed = false; for(int addr = 0; addr < 0x8000; addr += sizeof(buf)) { - if (feof(fp)) { - passed = true; - break; - } - fread(buf, sizeof(buf), 1, fp); + int ret = fread(buf, 1, sizeof(buf), fp); if (!_patch(buf, sizeof(buf), addr)) { break; } @@ -52,6 +76,10 @@ } } _pc->printf("."); + if (ret < sizeof(buf)) { + passed = true; + break; + } } fclose(fp); if (passed) {
--- a/Flash.h Thu Sep 05 09:34:12 2013 +0000 +++ b/Flash.h Sun Sep 08 14:13:15 2013 +0000 @@ -1,4 +1,4 @@ -// Flash.h 2013/9/5 +// Flash.h 2013/9/6 #pragma once #include "Target2.h" @@ -7,6 +7,7 @@ class Flash { public: Flash(Target2* target, Serial* usbpc); + bool init(); bool write(const char* filename); bool eraseAll(); bool verify(const char* filename);
--- a/SWD.cpp Thu Sep 05 09:34:12 2013 +0000 +++ b/SWD.cpp Sun Sep 08 14:13:15 2013 +0000 @@ -1,5 +1,6 @@ -// SWD.cpp 2013/9/1 +// SWD.cpp 2013/9/7 #include "SWD.h" +#include <algorithm> #include "mydebug.h" SWD::SWD(PinName swdio, PinName swclk, PinName reset) @@ -8,8 +9,10 @@ conf.turnaround = 1; conf.data_phase = 0; idle_cycles = 0; + retry_count = 100; _cpu_delay_count = 2; + TransferAbort = false; } void SWD::Setup() @@ -23,10 +26,8 @@ void SWD::reset() { - _nreset.output(); - _nreset = 0; - wait_ms(50); - _nreset.input(); + SWJPins(0x00, 0x80); + SWJPins(0x80, 0x80); } void SWD::JTAG2SWD() @@ -48,6 +49,76 @@ } } +uint8_t SWD::SWJPins(uint32_t value, uint32_t select ,int waittime_us) +{ + if (select & 0x01) { // swclk + _swclk = (value & 0x01) ? 1 : 0; + } + if (select & 0x02) { // swdio + _swdio = (value & 0x02) ? 1 : 0; + } + if (select & 0x80) { // nReset + if (value & 0x80) { + _nreset.input(); + } else { + _nreset.output(); + _nreset = 0; + } + } + if (waittime_us) { + waittime_us = std::min(waittime_us, 3000000); + Timer t; + t.reset(); + t.start(); + while(t.read_us() < waittime_us) { + if (select & 0x01) { // swclk + if (_swclk ^ ((value & 0x01) ? 1 : 0)) { + continue; + } + } + if (select & 0x02) { // swdio + if (_swdio ^ ((value & 0x02) ? 1 : 0)) { + continue; + } + } + if (select & 0x80) { // nReset + if (_nreset ^ ((value & 0x80) ? 1 : 0)) { + continue; + } + } + break; + } + } + return (_swclk ? 0x01 : 0x00) | (_swdio ? 0x02 : 0x00) | (_nreset ? 0x80 : 0x00); +} + +void SWD::SWJClock(uint32_t clock) +{ +} + +void SWD::TransferConfigure(int _idle_cycles, int _retry_count) +{ + idle_cycles = _idle_cycles; + retry_count = _retry_count; +} + +void SWD::Configure(int turnaround, int data_phase) +{ + conf.turnaround = turnaround; + conf.data_phase = data_phase; +} + +uint8_t SWD::Transfer(uint8_t request, uint32_t *data) +{ + for(int retry = retry_count; retry >= 0; retry--) { + uint8_t ack = rawTransfer(request, data); + if (ack != SWD_WAIT || TransferAbort) { + return ack; + } + } + return SWD_WAIT; +} + #pragma Otime static uint32_t calc_parity(uint32_t data, int n) @@ -59,7 +130,7 @@ return parity & 1; } -uint8_t SWD::Transfer(uint8_t request, uint32_t *data) +uint8_t SWD::rawTransfer(uint8_t request, uint32_t *data) { write_bit(1); // start bit write_bit(request, 4); // APnDP,RnW,A2,A3
--- a/SWD.h Thu Sep 05 09:34:12 2013 +0000 +++ b/SWD.h Sun Sep 08 14:13:15 2013 +0000 @@ -1,4 +1,4 @@ -// SWD.h 2013/9/1 +// SWD.h 2013/9/8 #pragma once #include "mbed.h" @@ -7,6 +7,7 @@ #define SWD_FAULT 0x04 #define SWD_ERROR 0x08 +#define SWD_APnDP 0x01 #define SWD_RnW 0x02 #define DP_ABORT 0<<0|0<<1|0x00 @@ -55,13 +56,16 @@ SWD(PinName swdio, PinName swclk, PinName reset); void Setup(); void SWJSequence(int count, const uint8_t* data); - uint8_t SWJPins(uint32_t value, uint32_t select ,uint32_t wait_us); + uint8_t SWJPins(uint32_t value, uint32_t select ,int waittime_us = 0); void SWJClock(uint32_t clock); + void TransferConfigure(int idle_cycles, int retry_count); void Configure(int turnaround, int data_phase); void JTAG2SWD(); uint8_t Transfer(uint8_t request, uint32_t *data); + __IO bool TransferAbort; void reset(); private: + uint8_t rawTransfer(uint8_t request, uint32_t *data); void pin_delay(); void clock_cycle(int n = 1); void write_bit(uint32_t data, int n = 1); @@ -72,6 +76,7 @@ int data_phase; } conf; int idle_cycles; + int retry_count; int _cpu_delay_count; DigitalInOut _swdio; DigitalOut _swclk;
--- a/Semihost.cpp Thu Sep 05 09:34:12 2013 +0000 +++ b/Semihost.cpp Sun Sep 08 14:13:15 2013 +0000 @@ -1,4 +1,4 @@ -// Semihost.cpp 2013/9/5 +// Semihost.cpp 2013/9/8 #include "Semihost.h" #include "mydebug.h" @@ -234,7 +234,7 @@ int Semihost::usr_reset(uint32_t arg) // 0x102 { - _target->Reset(); + _target->SoftwareReset(); _target->setup(); return 0; }
--- a/Target2.cpp Thu Sep 05 09:34:12 2013 +0000 +++ b/Target2.cpp Sun Sep 08 14:13:15 2013 +0000 @@ -1,7 +1,9 @@ -// Target2.cpp 2013/9/5 +// Target2.cpp 2013/9/8 #include "Target2.h" #include "mydebug.h" +#define SYSMEMREMAP 0x40048000 + #define CoreDebug_BASE (0xE000EDF0UL) #define DHCSR (CoreDebug_BASE+0) #define DCRSR (CoreDebug_BASE+4) @@ -43,7 +45,8 @@ if (ack != SWD_OK) { return false; } - TEST_ASSERT(data == 0x0bb11477); + idcode = data; + //TEST_ASSERT(data == 0x0bb11477); Abort(); @@ -111,9 +114,15 @@ return true; } -void Target2::Reset() +void Target2::HardwareReset() { - _swd.reset(); + _swd.SWJPins(0x00, 0x80); // nReset off + _swd.SWJPins(0x80, 0x80); // nReset on +} + +void Target2::SoftwareReset() +{ + writeMemory(NVIC_AIRCR, 0x05fa0004); } uint32_t Target2::readMemory(uint32_t addr) @@ -190,7 +199,6 @@ void Target2::_setaddr(uint32_t addr) { uint32_t ctl = CSW_VALUE|CSW_SIZE32; - TEST_ASSERT(ctl == 0x23000052); uint8_t ack = _swd.Transfer(AP_CSW, &ctl); TEST_ASSERT(ack == SWD_OK); @@ -207,7 +215,6 @@ void Target2::_setaddr8(uint32_t addr) { uint32_t ctl = CSW_VALUE|CSW_SIZE8; - TEST_ASSERT(ctl == 0x23000050); uint8_t ack = _swd.Transfer(AP_CSW, &ctl); TEST_ASSERT(ack == SWD_OK);
--- a/Target2.h Thu Sep 05 09:34:12 2013 +0000 +++ b/Target2.h Sun Sep 08 14:13:15 2013 +0000 @@ -1,4 +1,4 @@ -// Target2.h 2013/9/4 +// Target2.h 2013/9/8 #pragma once #include "mbed.h" #include "SWD.h" @@ -45,7 +45,7 @@ void resume(); void step(); void Abort(); - void Reset(); + void HardwareReset(); void SoftwareReset(); int getStatus(); bool wait_status(int status, int timeout_ms = 500); @@ -66,6 +66,8 @@ CoreReg lr; CoreReg pc; CoreReg xpsr; + + uint32_t idcode; private: void _setaddr(uint32_t addr); void _setaddr8(uint32_t addr);
--- a/main.cpp Thu Sep 05 09:34:12 2013 +0000 +++ b/main.cpp Sun Sep 08 14:13:15 2013 +0000 @@ -1,4 +1,4 @@ -// main.cpp 2013/9/5 +// main.cpp 2013/9/8 #if 1 #include "Target2.h" #include "Flash.h" @@ -30,9 +30,8 @@ } int main() { - //pc.baud(9600); pc.baud(921600); - pc.printf("\ndumb-terminal with flash writer using swd\n"); + pc.printf("\ndumb-terminal with semihosting\n"); const char* filename = "/local/1114FN28.LPC"; pc.printf("%s\n", filename); @@ -40,12 +39,12 @@ Target2* LPC1114 = new Target2(p21,p22,p17, &pc); // SWDIO(dp12),SWCLK(dp3),nReset(dp23),Stream LPC1114->setup(); Flash flash(LPC1114, &pc); + flash.init(); if (flash.eraseAll()) { flash.write(filename); } - target_uart.baud(9600); - LPC1114->Reset(); + LPC1114->SoftwareReset(); Terminal(LPC1114); } #endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/DAP.cpp Sun Sep 08 14:13:15 2013 +0000 @@ -0,0 +1,340 @@ +// DAP.cpp 2013/9/7 +#include "DAP.h" + +#define DAP_OK 0 +#define DAP_ERROR 0xFF + +#define DAP_TRANSFER_MATCH_VALUE (1<<4) +#define DAP_TRANSFER_MATCH_MASK (1<<5) + +// 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::DAP(SWD* swd) : _swd(swd) +{ +} + +int DAP::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); + + }; + *response = 0xff; // invalid + return 1; +} + +int DAP::Info(uint8_t* request, uint8_t* response) // 0x00 +{ + 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 + }; + 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 = info_str[id-1]; + 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); + *reinterpret_cast<uint16_t*>(response+2) = 64; + length += sizeof(uint16_t); + break; + default: + response[1] = DAP_ERROR; + break; + } + return length; +} + +int DAP::LED(uint8_t* request, uint8_t* response) // 0x01 +{ + response[0] = 0x01; // LED + response[1] = DAP_OK; + return 2; +} + +int DAP::Connect(uint8_t* request, uint8_t* response) // 0x02 +{ + response[0] = 0x02; // Connect + response[1] = DAP_PORT_DISABLED; + if (request[1] == DAP_PORT_AUTODETECT || request[1] == DAP_PORT_SWD) { + response[1] = DAP_PORT_SWD; + _swd->Setup(); + } + return 2; +} + +int DAP::Disconnect(uint8_t* request, uint8_t* response) // 0x03 +{ + response[0] = 0x03; // disconnect + response[1] = DAP_OK; + return 2; +} + +int DAP::TransferConfigure(uint8_t* request, uint8_t* response) // 0x04 +{ + uint8_t idle_cycles = request[1]; + uint16_t retry_count = *reinterpret_cast<uint16_t*>(request+2); + transfer.match_retry = *reinterpret_cast<uint16_t*>(request+4); + _swd->TransferConfigure(idle_cycles, retry_count); + response[0] = 0x04; //tansfer configure + response[1] = DAP_OK; + return 2; +} + +int DAP::Transfer(uint8_t* request, uint8_t* response) // 0x05 +{ + bool post_read = false; + bool check_write = false; + uint8_t swd_request; + uint8_t ack = 0; + int reqpos = 2; + int respos = 3; + int response_count = 0; + for(int request_count = request[reqpos++]; request_count > 0; request_count--, response_count++) { + swd_request = request[reqpos++]; + if (swd_request & SWD_RnW) { // read register + if (post_read) { + if ((swd_request & SWD_APnDP) && !(swd_request & DAP_TRANSFER_MATCH_VALUE)) { + ack = _swd->Transfer(swd_request, reinterpret_cast<uint32_t*>(response+respos)); + } else { + ack = _swd->Transfer(DP_RDBUFF, reinterpret_cast<uint32_t*>(response+respos)); + post_read = false; + } + if (ack != SWD_OK) { + break; + } + respos += sizeof(uint32_t); + } + if (swd_request & DAP_TRANSFER_MATCH_VALUE) { + uint32_t match_value = *reinterpret_cast<uint32_t*>(request+reqpos); + reqpos += sizeof(uint32_t); + if (swd_request & SWD_APnDP) { + ack = _swd->Transfer(swd_request, NULL); + if (ack != SWD_OK) { + break; + } + } + bool match = false; + for(int retry = transfer.match_retry; retry >= 0 && !match; retry--) { + uint32_t data; + ack = _swd->Transfer(swd_request, &data); + if (ack == SWD_OK && (data&transfer.match_mask) == match_value) { + match = true; + } + } + if (!match) { + break; + } + } else { + if (swd_request & SWD_APnDP) { + if (post_read) { + ack = _swd->Transfer(swd_request, NULL); + if (ack != SWD_OK) { + break; + } + post_read = true; + } + } else { + ack = _swd->Transfer(swd_request, reinterpret_cast<uint32_t*>(response+respos)); + if (ack != SWD_OK) { + break; + } + respos += sizeof(uint32_t); + } + } + check_write = false; + } else { // write register + if (post_read) { // read previous data + ack = _swd->Transfer(DP_RDBUFF, reinterpret_cast<uint32_t*>(response+respos)); + if (ack != SWD_OK) { + break; + } + respos += sizeof(uint32_t); + post_read = false; + } + uint32_t data = *reinterpret_cast<uint32_t*>(request+reqpos); + reqpos += sizeof(uint32_t); + if (swd_request & DAP_TRANSFER_MATCH_MASK) { + transfer.match_mask = data; + ack = SWD_OK; + } else { + ack = _swd->Transfer(swd_request, &data); + if (ack != SWD_OK) { + break; + } + check_write = true; + } + } + } + if (ack == SWD_OK) { + if (post_read) { // read previous data + ack = _swd->Transfer(DP_RDBUFF, reinterpret_cast<uint32_t*>(response+respos)); + if (ack == SWD_OK) { + respos += sizeof(uint32_t); + } + } else if (check_write) { // check last write + ack = _swd->Transfer(DP_RDBUFF, NULL); + } + } + response[0] = 0x05; // transfer + response[1] = response_count; + response[2] = ack; + return respos; +} + +int DAP::TransferBlock(uint8_t* request, uint8_t* response) // 0x06 +{ + uint8_t swd_request; + uint8_t ack = 0; + int reqpos = 2; + int respos = 4; + int response_count = 0; + int request_count = *reinterpret_cast<uint16_t*>(request+reqpos); + reqpos += sizeof(uint16_t); + if (request_count == 0) { + goto end; + } + swd_request = request[reqpos++]; + if (swd_request & SWD_RnW) { // read register block + if (swd_request & SWD_APnDP) { // post AP read + ack = _swd->Transfer(swd_request, NULL); + if (ack != SWD_OK) { + goto end; + } + } + while(request_count--) { // read DP/AP register + if (request_count == 0 && (swd_request & SWD_APnDP)) { // last AP read + swd_request = DP_RDBUFF; + } + ack = _swd->Transfer(swd_request, reinterpret_cast<uint32_t*>(response+respos)); + if (ack != SWD_OK) { + goto end; + } + respos += sizeof(uint32_t); + response_count++; + } + } else { // write register block + while(request_count--) { + ack = _swd->Transfer(swd_request, reinterpret_cast<uint32_t*>(request+reqpos)); + if (ack != SWD_OK) { + goto end; + } + response_count++; + } + ack = _swd->Transfer(DP_RDBUFF, NULL); + } +end: + response[0] = 0x06; // transfer block + *reinterpret_cast<uint16_t*>(response+1) = response_count; + response[3] = ack; + return respos; +} + +int DAP::WriteABORT(uint8_t* request, uint8_t* response) // 0x08 +{ + uint32_t data = *reinterpret_cast<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 DAP::Delay(uint8_t* request, uint8_t* response) // 0x09 +{ + int waittime_ms = *reinterpret_cast<uint16_t*>(request+1); + wait_ms(waittime_ms); + response[0] = 0x09; + response[1] = DAP_OK; + return 2; +} + +int DAP::ResetTarget(uint8_t* request, uint8_t* response) // 0x0A +{ + response[0] = 0x0a; + response[1] = 0; + response[2] = DAP_OK; + return 3; +} + +int DAP::SWJ_Pins(uint8_t* request, uint8_t* response) // 0x10 +{ + uint32_t value = request[1]; + uint32_t select = request[2]; + uint32_t waittime_us = *reinterpret_cast<uint32_t*>(request+3); + response[0] = 0x10; // swj pins + response[1] = _swd->SWJPins(value, select, waittime_us); + return 2; +} + +int DAP::SWJ_Clock(uint8_t* request, uint8_t* response) // 0x11 +{ + uint32_t clock = *reinterpret_cast<uint32_t*>(request+1); + _swd->SWJClock(clock); + response[0] = 0x11; // swj clock + response[1] = DAP_OK; + return 2; +} + +int DAP::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 DAP::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; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/DAP.h Sun Sep 08 14:13:15 2013 +0000 @@ -0,0 +1,33 @@ +// DAP.h 2013/9/7 +#pragma once +#include "SWD.h" + +class DAP { +public: + DAP(SWD* swd); + int Command(uint8_t* request, uint8_t* response); + + 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 + +private: + struct { // Transfer Configuration + uint16_t match_retry; // Number of retries if read value does not match + uint32_t match_mask; // Match Mask + } transfer; +protected: + SWD* _swd; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test1_DAP.cpp Sun Sep 08 14:13:15 2013 +0000 @@ -0,0 +1,298 @@ +// test1_DAP.cpp 2013/9/8 +#if 0 +#include "DAP.h" +#include "mytest.h" +#include "mydebug.h" + +Serial pc(USBTX, USBRX); + +SWD* swd; +DAP* dap; +uint8_t recv[64]; + +TEST(DAP1,setup) { + swd = new SWD(p21,p22,p17); // SWDIO(dp12),SWCLK(dp3),nReset(dp23) + dap = new DAP(swd); +} + +TEST(DAP1,Info_PRODUCT) { + const uint8_t req[] = {0x00,0x02}; + const uint8_t res[] = {0x00,0x00}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +TEST(DAP1,Info_SER_NUM) { + const uint8_t req[] = {0x00,0x03}; + const uint8_t res[] = {0x00,0x00}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +TEST(DAP1,Info_FW_VER) { + const uint8_t req[] = {0x00,0x04}; + const uint8_t res[] = {0x00,0x04,0x31,0x2e,0x30,0x00}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +TEST(DAP1,Info_VENDOR) { + const uint8_t req[] = {0x00,0x01}; + const uint8_t res[] = {0x00,0x00}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +TEST(DAP1,Info_PRODUCT_2) { + const uint8_t req[] = {0x00,0x02}; + const uint8_t res[] = {0x00,0x00}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +TEST(DAP1,Info_PACKET_SIZE) { + const uint8_t req[] = {0x00,0xff}; + const uint8_t res[] = {0x00,0x02,0x40,0x00}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +TEST(DAP1,Info_PACKET_COUNT) { + const uint8_t req[] = {0x00,0xfe}; + const uint8_t res[] = {0x00,0x01,0x01}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +TEST(DAP1,Connect_SWD) { + const uint8_t req[] = {0x02,0x01}; + const uint8_t res[] = {0x02,0x01}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +TEST(DAP1,SWJ_Clock_5000_Hz) { + const uint8_t req[] = {0x11,0x88,0x13,0x00,0x00}; + const uint8_t res[] = {0x11,0x00}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +TEST(DAP1,TransferConfigure) { + const uint8_t req[] = {0x04,0x00,0x64,0x00,0x00,0x00}; + const uint8_t res[] = {0x04,0x00}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +TEST(DAP1,SWD_Configure) { + const uint8_t req[] = {0x13,0x00}; + const uint8_t res[] = {0x13,0x00}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +TEST(DAP1,LED_DEBUGGER_CONNECTED_ON) { + const uint8_t req[] = {0x01,0x00,0x01}; + const uint8_t res[] = {0x01,0x00}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +TEST(DAP1,SWJ_Sequence_1_51) { + const uint8_t req[] = {0x12,0x33, 0xff,0xff,0xff,0xff,0xff,0xff,0xff}; + const uint8_t res[] = {0x12,0x00}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +TEST(DAP1,SWJ_Sequence_2_16) { + const uint8_t req[] = {0x12,0x10, 0x9e,0xe7}; + const uint8_t res[] = {0x12,0x00}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +TEST(DAP1,SWJ_Sequence_3_51) { + const uint8_t req[] = {0x12,0x33, 0xff,0xff,0xff,0xff,0xff,0xff,0xff}; + const uint8_t res[] = {0x12,0x00}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +TEST(DAP1,SWJ_Sequence_4_8) { + const uint8_t req[] = {0x12,0x08, 0x00}; + const uint8_t res[] = {0x12,0x00}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +TEST(DAP1,Transfer_DP_IDCODE) { + const uint8_t req[] = {0x05, 0x00, 0x01, 0x02}; + const uint8_t res[] = {0x05, 0x01, 0x01, 0x77,0x14,0xb1,0x0b}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +TEST(DAP1,Transfer_DP_SELECT) { + const uint8_t req[] = {0x05, 0x00, 0x01, 0x08, 0x00,0x00,0x00,0x00}; + //SWD: DP_SELECT 00000000 request=08(DP nW 8) wdata=00000000 rdata=00000000 ack=01 + //SWD: DP_RDBUFF 10008000 request=0e(DP R c) wdata=ffffffff rdata=10008000 ack=01 + const uint8_t res[] = {0x05, 0x01, 0x01}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +TEST(DAP1,Transfer_DP_CTRL_STAT_W) { + const uint8_t req[] = {0x05,0x00, 0x01, 0x04, 0x00,0x00,0x00,0x50}; + //SWD: DP_CTRL_STAT W 50000000 request=04(DP nW 4) wdata=50000000 rdata=50000000 ack=01 + //SWD: DP_RDBUFF 10008000 request=0e(DP R c) wdata=ffffffff rdata=10008000 ack=01 + const uint8_t res[] = {0x05,0x01, 0x01}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +TEST(DAP1,Transfer_DP_CTRL_STAT_R) { + const uint8_t req[] = {0x05,0x00, 0x01, 0x06}; + //SWD: DP_CTRL_STAT R f0000040 request=06(DP R 4) wdata=00000040 rdata=f0000040 ack=01 + const uint8_t res[] = {0x05,0x01, 0x01, 0x40,0x00,0x00,0xf0}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +TEST(DAP1,WriteABORT) { + const uint8_t req[] = {0x08,0x00,0x1e,0x00,0x00,0x00}; + //SWD: DP_ABORT 0000001e request=00(DP nW 0) wdata=0000001e rdata=0000001e ack=01 + const uint8_t res[] = {0x08,0x00}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +TEST(DAP1,Transfer_DP_CTRL_STAT_W_2) { + const uint8_t req[] = {0x05,0x00, 0x01, 0x04, 0x00,0x00,0x00,0x54}; + //SWD: DP_CTRL_STAT W 54000000 request=04(DP nW 4) wdata=54000000 rdata=54000000 ack=01 + //SWD: DP_RDBUFF 10008000 request=0e(DP R c) wdata=ffffffff rdata=10008000 ack=01 + const uint8_t res[] = {0x05,0x01, 0x01}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +TEST(DAP1,Transfer_DP_CTRL_STAT_W_3) { + const uint8_t req[] = {0x05,0x00, 0x01, 0x04, 0x00,0x0f,0x00,0x50}; + //SWD: DP_CTRL_STAT W 50000f00 request=04(DP nW 4) wdata=50000f00 rdata=50000f00 ack=01 + //SWD: DP_RDBUFF 10008000 request=0e(DP R c) wdata=ffffffff rdata=10008000 ack=01 + const uint8_t res[] = {0x05,0x01, 0x01}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +TEST(DAP1,Transfer_AP_CSW) { + const uint8_t req[] = {0x05,0x00, 0x01, 0x01, 0x52,0x00,0x00,0x23}; + //SWD: AP_CSW W 23000052 request=01(AP nW 0) wdata=23000052 rdata=23000052 ack=01 + //SWD: DP_RDBUFF 10008000 request=0e(DP R c) wdata=ffffffff rdata=10008000 ack=01 + const uint8_t res[] = {0x05,0x01, 0x01}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +TEST(DAP1,Transfer_AP_TAR) { + const uint8_t req[] = {0x05,0x00, 0x01, 0x05, 0xf0,0xff,0x0f,0xe0}; + //SWD: AP_TAR W e00ffff0 request=05(AP nW 4) wdata=e00ffff0 rdata=e00ffff0 ack=01 + //SWD: DP_RDBUFF 10008000 request=0e(DP R c) wdata=ffffffff rdata=10008000 ack=01 + const uint8_t res[] = {0x05,0x01, 0x01}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +TEST(DAP1,TransferBlock_AP_DRW_R) { + const uint8_t req[] = {0x06,0x00, 0x04,0x00, 0x0f}; + //SWD: AP_DRW R 10008000 request=0f(AP R c) wdata=ffffffff rdata=10008000 ack=01 + //SWD: AP_DRW R 0000000d request=0f(AP R c) wdata=00000006 rdata=0000000d ack=01 + //SWD: AP_DRW R 00000010 request=0f(AP R c) wdata=0000000d rdata=00000010 ack=01 + //SWD: AP_DRW R 00000005 request=0f(AP R c) wdata=00000010 rdata=00000005 ack=01 + //SWD: DP_RDBUFF 000000b1 request=0e(DP R c) wdata=00000005 rdata=000000b1 ack=01 + const uint8_t res[] = {0x06, 0x04,0x00, 0x01, + 0x0d,0x00,0x00,0x00, 0x10,0x00,0x00,0x00, 0x05,0x00,0x00,0x00, 0xb1,0x00,0x00,0x00}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, 4) == 0); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +TEST(DAP1,SWJ_Pins_nRESET_OFF) { + const uint8_t req[] = {0x10,0x00,0x80,0x00,0x00,0x00,0x00,}; + //DAP: SWJ_Pins wait: 0 us nRESET OFF + const uint8_t res[] = {0x10,0x03}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +TEST(DAP1,SWJ_Pins_nRESET_ON) { + const uint8_t req[] = {0x10,0x80,0x80,0x00,0x00,0x00,0x00,}; + //DAP: SWJ_Pins wait: 0 us nRESET ON + const uint8_t res[] = {0x10,0x83}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +TEST(DAP1,SWJ_Pins) { + const uint8_t req[] = {0x10,0x00,0x00,0x00,0x00,0x00,0x00,}; + //DAP: SWJ_Pins wait: 0 us nRESET ON + const uint8_t res[] = {0x10,0x83}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +TEST(DAP1,Disconnect) { + const uint8_t req[] = {0x03}; + const uint8_t res[] = {0x03,0x00}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +TEST(DAP1,LED_DEBUGGER_CONNECTED_OFF) { + const uint8_t req[] = {0x01,0x00,0x00}; + const uint8_t res[] = {0x01,0x00}; + int len = dap->Command((uint8_t*)req, recv); + ASSERT_TRUE(len == sizeof(res)); + ASSERT_TRUE(memcmp(recv, res, len) == 0); +} + +int main() { + pc.baud(921600); + //pc.baud(9600); + DBG("%s", __FILE__); + + RUN_ALL_TESTS(); + exit(0); +} +#endif
--- a/tests/test_Semihost.cpp Thu Sep 05 09:34:12 2013 +0000 +++ b/tests/test_Semihost.cpp Sun Sep 08 14:13:15 2013 +0000 @@ -1,4 +1,4 @@ -// test_Semihost.cpp 2013/9/5 +// test_Semihost.cpp 2013/9/6 #if 0 #include "Semihost.h" #include "Flash.h" @@ -49,7 +49,9 @@ #if 1 TEST(Flash1,flash1) { Flash flash(&target, &pc); - bool r = flash.eraseAll(); + bool r = flash.init(); + ASSERT_TRUE(r); + r = flash.eraseAll(); ASSERT_TRUE(r); r = flash.write("/local/SEMIHOST.LPC"); ASSERT_TRUE(r); @@ -83,6 +85,3 @@ exit(0); } #endif - - -