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
SWD.cpp
- Committer:
- va009039
- Date:
- 2013-09-08
- Revision:
- 3:d7a7cde0bfb8
- Parent:
- 0:27d35fa263b5
- Child:
- 4:5e4107edcbdb
File content as of revision 3:d7a7cde0bfb8:
// SWD.cpp 2013/9/7 #include "SWD.h" #include <algorithm> #include "mydebug.h" SWD::SWD(PinName swdio, PinName swclk, PinName reset) : _swdio(swdio), _swclk(swclk), _nreset(reset) { conf.turnaround = 1; conf.data_phase = 0; idle_cycles = 0; retry_count = 100; _cpu_delay_count = 2; TransferAbort = false; } void SWD::Setup() { _swclk = 1; _swdio.output(); _swdio = 1; _nreset.input(); _nreset.mode(PullUp); } void SWD::reset() { SWJPins(0x00, 0x80); SWJPins(0x80, 0x80); } void SWD::JTAG2SWD() { const uint8_t data1[] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff}; const uint8_t data2[] = {0x9e,0xe7}; const uint8_t data3[] = {0x00}; SWJSequence(sizeof(data1)*8, data1); SWJSequence(sizeof(data2)*8, data2); SWJSequence(sizeof(data1)*8, data1); SWJSequence(sizeof(data3)*8, data3); } void SWD::SWJSequence(int count, const uint8_t* data) { for(int n = 0; n < count; n++) { uint8_t val = data[n/8]; write_bit(val>>(n%8)); } } 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) { uint32_t parity = 0; for(int i = 0; i < n; i++) { parity += data>>i; } return parity & 1; } uint8_t SWD::rawTransfer(uint8_t request, uint32_t *data) { write_bit(1); // start bit write_bit(request, 4); // APnDP,RnW,A2,A3 write_bit(calc_parity(request, 4)); // parity bit write_bit(0); // stop bit write_bit(1); // park bit _swdio.input(); clock_cycle(conf.turnaround); uint8_t ack = read_bit(3); if (ack == SWD_OK) { if (request & SWD_RnW) { // read uint32_t val = read_bit(32); uint32_t parity = read_bit(1); if (parity ^ calc_parity(val, 32)) { ack = SWD_ERROR; } if (data) { *data = val; } clock_cycle(conf.turnaround); _swdio.output(); } else { // write clock_cycle(conf.turnaround); _swdio.output(); uint32_t val = *data; write_bit(val, 32); write_bit(calc_parity(val, 32)); } if (idle_cycles) { _swdio = 0; clock_cycle(idle_cycles); } _swdio = 1; return ack; } if (ack == SWD_WAIT || ack == SWD_FAULT) { if (conf.data_phase && (request & SWD_RnW)) { clock_cycle(32+1); } clock_cycle(conf.turnaround); _swdio.output(); if (conf.data_phase && ((request & SWD_RnW) == 0)) { _swdio = 0; clock_cycle(32+1); } _swdio = 1; return ack; } clock_cycle(32 + 1 + conf.turnaround); _swdio.output(); return ack; } void SWD::pin_delay() { __IO int n = _cpu_delay_count; while(n-- > 0) ; } void SWD::clock_cycle(int n) { while(n-- > 0) { _swclk = 0; pin_delay(); _swclk = 1; pin_delay(); } } void SWD::write_bit(uint32_t data, int n) { for(int i = 0; i < n; i++) { _swdio = (data>>i) & 1; clock_cycle(); } } uint32_t SWD::read_bit(int n) { uint32_t data = 0; for(int i = 0; i < n; i++) { _swclk = 0; pin_delay(); uint32_t val = _swdio & 1; data |= val<<i; _swclk = 1; pin_delay(); } return data; }