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
Flash.cpp
- Committer:
- va009039
- Date:
- 2013-09-14
- Revision:
- 5:2774358f5e4f
- Parent:
- 4:5e4107edcbdb
- Child:
- 6:5da6ad51a18f
File content as of revision 5:2774358f5e4f:
// Flash.cpp 2013/9/11 #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(); } void Flash::_setup() { _target->halt(); _target->wait_status(TARGET_HALTED); _target->prog_status(); } 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"); if (fp == NULL) { _pc->printf("file open error [%s]\n", filename); return false; } _pc->printf("Writing."); uint8_t buf[256]; bool passed = false; for(int addr = 0; addr < 0x8000; addr += sizeof(buf)) { int ret = fread(buf, 1, sizeof(buf), fp); if (!_patch(buf, sizeof(buf), addr)) { break; } const int ram = 0x10000200; if (!_write_to_ram(ram, sizeof(buf), buf)) { break; } if (remoteIAP(PREPARE_SECTOR, _sector(addr), _sector(addr)) != CMD_SUCCESS) { _pc->printf("faild. PREPARE_SECTOR %d %d\n", _sector(addr), _sector(addr)); break; } if (remoteIAP(COPY_RAM_TO_FLASH, addr, ram, sizeof(buf), IAP_CCLK) != CMD_SUCCESS) { _pc->printf("faild. COPY_RAM_TO_FLASH %d %d %d %dn", addr, ram, sizeof(buf)); break; } if (remoteIAP(COMPARE, addr, ram, sizeof(buf)) != CMD_SUCCESS) { _pc->printf("faild. COMPARE %d %d %d", addr, ram, sizeof(buf)); break; } _pc->printf("."); if (ret < sizeof(buf)) { passed = true; break; } } fclose(fp); if (passed) { _pc->printf("passed.\n"); } return passed; } bool Flash::eraseAll() { _pc->printf("Erasing."); for(int sector = 0; sector <= 7; sector++) { IAP_STATUS status = remoteIAP(PREPARE_SECTOR, sector, sector); if (status != CMD_SUCCESS) { _pc->printf("faild. PREPARE_SECTOR %d %d status=%d\n", sector, sector, status); return false; } if (remoteIAP(ERASE_SECTOR, sector, sector, IAP_CCLK) != CMD_SUCCESS) { _pc->printf("faild. ERASE_SECTOR %d %d %d\n", sector, sector, IAP_CCLK); return false; } if (remoteIAP(BLANK_CHECK, sector, sector, IAP_CCLK) != CMD_SUCCESS) { _pc->printf("faild. BLANK_CHECK %d %d %d\n", sector, sector, IAP_CCLK); return false; } _pc->printf("."); } _pc->printf("passed.\n"); return true; } bool Flash::_write_to_ram(int addr, int size, uint8_t* buf) { _target->writeMemory(addr, (uint32_t*)buf, size / sizeof(uint32_t)); return true; } int Flash::_sector(int addr) { return addr / 4096; } static uint32_t LD32(uint8_t* buf) { return buf[0] | buf[1]<<8 | buf[2]<<16 | buf[3]<<24; } bool Flash::_patch(uint8_t* buf, int size, int addr) { const int crp_start = 0x2fc; // Code Read Protection location if (crp_start >= addr && crp_start < addr+size) { uint32_t pat = LD32(crp_start-addr+buf); if (pat != 0xffffffff) { // NO_CRP ? _pc->printf("\nCAUTION: CRP Pattern is not NO_CRP; %08x\n", pat); return false; } } return true; } Flash::IAP_STATUS Flash::remoteIAP(Flash::IAP_CMD cmd, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3) { struct { uint32_t bkpt; // +0 struct { // IAP Structure uint32_t cmd; // +4 Command uint32_t par[4]; // +8 Parameters uint32_t stat; // +24 Status uint32_t res[4]; // +28 Result } IAP; // +44 } ram; ram.bkpt = 0xe00abe00; // bpkt #00 ram.IAP.cmd = cmd; ram.IAP.par[0] = p0; ram.IAP.par[1] = p1; ram.IAP.par[2] = p2; ram.IAP.par[3] = p3; _target->halt(); _target->wait_status(TARGET_HALTED); const uint32_t ram_addr = 0x10000100; _target->writeMemory(ram_addr, (uint32_t*)&ram, sizeof(ram)/sizeof(uint32_t)); _target->r0 = ram_addr + 4; // command addr _target->r1 = ram_addr + 24; // status addr _target->sp = 0x10000400-32; // IAP use ram top 32bytes _target->lr = ram_addr + 1; // return to bkpt _target->pc = 0x1fff1ff1; // IAP_Call _target->resume(); _target->wait_status(TARGET_HALTED); return (IAP_STATUS)_target->readMemory(ram_addr + 24); } bool Flash::verify(const char* filename) { FILE* fp = fopen(filename, "rb"); if (fp == NULL) { _pc->printf("file open error [%s]\n", filename); return false; } _pc->printf("Verifying."); uint8_t buf[256]; bool passed = false; for(int addr = 0; addr < 0x8000; addr++) { int c = fgetc(fp); if (c == EOF) { passed = true; break; } if ((addr % sizeof(buf)) == 0) { _target->readMemory(addr, (uint32_t*)buf, sizeof(buf)/sizeof(uint32_t)); _pc->printf("."); } if (c != buf[addr % sizeof(buf)]) { _pc->printf("\nError at %08x(%02x:%02x)\n", addr, c, buf[addr % sizeof(buf)]); break; } } fclose(fp); if (passed) { _pc->printf("passed.\n"); } return passed; }