semihost server example program

Dependencies:   SWD mbed USBLocalFileSystem BaseDAP USBDAP

/media/uploads/va009039/kl46z-lpc800-360x480.jpg

LPCXpresso
LPC11U68
LPCXpresso
LPC1549
FRDM-KL46ZEA LPC4088 QSB
app-board
LPC1768
app-board
LPC810LPC1114FN28
serverserverserverserverserverclientclient
SWDIOD12D12D12p25p21p4(P0_2)p12
SWCLKD10D10D10p26p22p3(P0_3)p3
nRESET
*option
D6D6D6p34p30p1(P0_5)p23
GNDGNDGNDGNDp1p1p7p22
3.3VP3V3P3V3P3V3p44p40p6p21
flash writeSW2(P0_1)SW3(P1_9)SW1p14
joystick
center
p14
joystick
center

client example:

Import programlpc810-semihost_helloworld

semihost client example program

Committer:
va009039
Date:
Sun Jun 22 12:04:16 2014 +0000
Revision:
18:5ed1759e863b
Parent:
14:e6acf863207e
add LPC11U68 interface.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 8:d7f5d80531e4 1 // Flash.cpp 2014/2/18
va009039 0:27d35fa263b5 2 #include "Flash.h"
va009039 0:27d35fa263b5 3 #include "Target2.h"
va009039 0:27d35fa263b5 4 #include "mydebug.h"
va009039 0:27d35fa263b5 5
va009039 8:d7f5d80531e4 6 // LPC1347,LPC1114,LPC812,LPC810
va009039 8:d7f5d80531e4 7 #define LPC_SYSCON_SYSMEMREMAP 0x40048000
va009039 8:d7f5d80531e4 8 #define LPC_SYSCON_MAINCLKSEL 0x40048070
va009039 8:d7f5d80531e4 9 #define LPC_SYSCON_MAINCLKUEN 0x40048074
va009039 8:d7f5d80531e4 10 #define LPC_SYSCON_SYSAHBCLKDIV 0x40048078
va009039 8:d7f5d80531e4 11
va009039 8:d7f5d80531e4 12 // LPC1768,LPC1769
va009039 8:d7f5d80531e4 13 #define LPC_SC_MEMMAP 0x400fc040
va009039 8:d7f5d80531e4 14 #define LPC_SC_PLL0CON 0x400fc080
va009039 8:d7f5d80531e4 15 #define LPC_SC_PLL0CFG 0x400fc084
va009039 8:d7f5d80531e4 16 #define LPC_SC_PLL0STAT 0x400fc088
va009039 8:d7f5d80531e4 17 #define LPC_SC_PLL0FEED 0x400fc08c
va009039 3:d7a7cde0bfb8 18
va009039 0:27d35fa263b5 19 Flash::Flash(Target2* target, Serial* usbpc) :_target(target),_pc(usbpc)
va009039 0:27d35fa263b5 20 {
va009039 0:27d35fa263b5 21 _setup();
va009039 0:27d35fa263b5 22 }
va009039 0:27d35fa263b5 23
va009039 0:27d35fa263b5 24 void Flash::_setup()
va009039 0:27d35fa263b5 25 {
va009039 0:27d35fa263b5 26 _target->halt();
va009039 0:27d35fa263b5 27 _target->wait_status(TARGET_HALTED);
va009039 4:5e4107edcbdb 28 _target->prog_status();
va009039 0:27d35fa263b5 29 }
va009039 0:27d35fa263b5 30
va009039 3:d7a7cde0bfb8 31 bool Flash::init()
va009039 3:d7a7cde0bfb8 32 {
va009039 8:d7f5d80531e4 33 _pc->printf("Initializing");
va009039 14:e6acf863207e 34 ram_addr = 0x10000000;
va009039 14:e6acf863207e 35 ram_size = 0x400;
va009039 8:d7f5d80531e4 36 if (remoteIAP(READ_PART_ID) != CMD_SUCCESS) {
va009039 8:d7f5d80531e4 37 _pc->printf("\nfaild. READ_PART_ID\n");
va009039 3:d7a7cde0bfb8 38 return false;
va009039 8:d7f5d80531e4 39 }
va009039 8:d7f5d80531e4 40 bool result = false;
va009039 8:d7f5d80531e4 41 _pc->printf("(%08x).", part_id);
va009039 8:d7f5d80531e4 42 switch(part_id) {
va009039 8:d7f5d80531e4 43 case 0x08020543: // LPC1347
va009039 8:d7f5d80531e4 44 result = flash_init_lpc1347();
va009039 8:d7f5d80531e4 45 break;
va009039 8:d7f5d80531e4 46 case 0x26113f37: // LPC1768,LPC1769
va009039 8:d7f5d80531e4 47 result = flash_init_lpc1769();
va009039 8:d7f5d80531e4 48 break;
va009039 8:d7f5d80531e4 49 default:
va009039 8:d7f5d80531e4 50 if (part_id >= 0x00008100 && part_id <= 0x000081ff) { // LOC810
va009039 8:d7f5d80531e4 51 result = init_lpc1114fn28_lpc810(1024);
va009039 8:d7f5d80531e4 52 } else { // part_id = 0x0a40902b or 0x1a40902b LPC1114FN28
va009039 8:d7f5d80531e4 53 result = init_lpc1114fn28_lpc810(4096);
va009039 8:d7f5d80531e4 54 }
va009039 8:d7f5d80531e4 55 break;
va009039 8:d7f5d80531e4 56 }
va009039 8:d7f5d80531e4 57 if (result) {
va009039 8:d7f5d80531e4 58 _pc->printf("passed.\n");
va009039 8:d7f5d80531e4 59 }
va009039 8:d7f5d80531e4 60 return result;
va009039 8:d7f5d80531e4 61 }
va009039 8:d7f5d80531e4 62
va009039 8:d7f5d80531e4 63 bool Flash::remoteREG(uint32_t addr, uint32_t value)
va009039 8:d7f5d80531e4 64 {
va009039 8:d7f5d80531e4 65 _target->writeMemory(addr, value);
va009039 3:d7a7cde0bfb8 66 return true;
va009039 3:d7a7cde0bfb8 67 }
va009039 3:d7a7cde0bfb8 68
va009039 8:d7f5d80531e4 69 bool Flash::init_lpc1114fn28_lpc810(int sector_size)
va009039 8:d7f5d80531e4 70 {
va009039 8:d7f5d80531e4 71 cfg.iap_cclk = 12000;
va009039 8:d7f5d80531e4 72 cfg.sector_size = sector_size;
va009039 8:d7f5d80531e4 73 remoteREG(LPC_SYSCON_MAINCLKSEL, 0); // Select Internal RC Oscillator
va009039 8:d7f5d80531e4 74 remoteREG(LPC_SYSCON_MAINCLKUEN, 1); // Update Main Clock Source
va009039 8:d7f5d80531e4 75 remoteREG(LPC_SYSCON_MAINCLKUEN, 0); // Toggle Update Register
va009039 8:d7f5d80531e4 76 remoteREG(LPC_SYSCON_MAINCLKUEN, 1);
va009039 8:d7f5d80531e4 77 uint32_t data = _target->readMemory(LPC_SYSCON_MAINCLKUEN); // Wait until updated
va009039 8:d7f5d80531e4 78 if (!(data & 1)) {
va009039 8:d7f5d80531e4 79 _pc->printf("\nerror MAINCLKUEN=%08x\n", data);
va009039 8:d7f5d80531e4 80 return false;
va009039 8:d7f5d80531e4 81 }
va009039 8:d7f5d80531e4 82 remoteREG(LPC_SYSCON_SYSAHBCLKDIV, 1);// Set Main Clock divider to 1
va009039 8:d7f5d80531e4 83 remoteREG(LPC_SYSCON_SYSMEMREMAP, 2); // User Flash Mode
va009039 8:d7f5d80531e4 84 return true;
va009039 8:d7f5d80531e4 85 }
va009039 8:d7f5d80531e4 86
va009039 8:d7f5d80531e4 87 bool Flash::flash_init_lpc1347() {
va009039 8:d7f5d80531e4 88 cfg.iap_cclk = 12000;
va009039 8:d7f5d80531e4 89 cfg.sector_size = 4096;
va009039 8:d7f5d80531e4 90 remoteREG(LPC_SYSCON_MAINCLKSEL, 0); // Select Internal RC Oscillator
va009039 8:d7f5d80531e4 91 remoteREG(LPC_SYSCON_SYSAHBCLKDIV, 1);// Set Main Clock divider to 1
va009039 8:d7f5d80531e4 92 if (!remoteREG(LPC_SYSCON_SYSMEMREMAP, 2)) { // User Flash Mode
va009039 8:d7f5d80531e4 93 return false;
va009039 8:d7f5d80531e4 94 }
va009039 8:d7f5d80531e4 95 return true;
va009039 8:d7f5d80531e4 96 }
va009039 8:d7f5d80531e4 97
va009039 8:d7f5d80531e4 98 bool Flash::flash_init_lpc1769() {
va009039 8:d7f5d80531e4 99 cfg.iap_cclk = 4000;
va009039 8:d7f5d80531e4 100 cfg.sector_size = 4096;
va009039 8:d7f5d80531e4 101 remoteREG(LPC_SC_PLL0CON, 0x00); // Select Internal RC Oscillator
va009039 8:d7f5d80531e4 102 remoteREG(LPC_SC_PLL0FEED, 0xaa);
va009039 8:d7f5d80531e4 103 remoteREG(LPC_SC_PLL0FEED, 0x55);
va009039 8:d7f5d80531e4 104 if (!remoteREG(LPC_SC_MEMMAP, 0x01)) { // User Flash Mode
va009039 8:d7f5d80531e4 105 return false;
va009039 8:d7f5d80531e4 106 }
va009039 8:d7f5d80531e4 107 return true;
va009039 8:d7f5d80531e4 108 }
va009039 8:d7f5d80531e4 109
va009039 0:27d35fa263b5 110 bool Flash::write(const char* filename)
va009039 0:27d35fa263b5 111 {
va009039 14:e6acf863207e 112 const int chunk_size = 512;
va009039 0:27d35fa263b5 113 FILE* fp = fopen(filename, "rb");
va009039 0:27d35fa263b5 114 if (fp == NULL) {
va009039 0:27d35fa263b5 115 _pc->printf("file open error [%s]\n", filename);
va009039 0:27d35fa263b5 116 return false;
va009039 0:27d35fa263b5 117 }
va009039 0:27d35fa263b5 118 _pc->printf("Writing.");
va009039 8:d7f5d80531e4 119 uint8_t buf[chunk_size];
va009039 0:27d35fa263b5 120 bool passed = false;
va009039 14:e6acf863207e 121 for(int addr = 0; addr < 0x80000; addr += sizeof(buf)) {
va009039 3:d7a7cde0bfb8 122 int ret = fread(buf, 1, sizeof(buf), fp);
va009039 0:27d35fa263b5 123 if (!_patch(buf, sizeof(buf), addr)) {
va009039 0:27d35fa263b5 124 break;
va009039 0:27d35fa263b5 125 }
va009039 6:5da6ad51a18f 126 if (!write(addr, buf, sizeof(buf))) {
va009039 4:5e4107edcbdb 127 break;
va009039 0:27d35fa263b5 128 }
va009039 0:27d35fa263b5 129 _pc->printf(".");
va009039 3:d7a7cde0bfb8 130 if (ret < sizeof(buf)) {
va009039 3:d7a7cde0bfb8 131 passed = true;
va009039 3:d7a7cde0bfb8 132 break;
va009039 3:d7a7cde0bfb8 133 }
va009039 0:27d35fa263b5 134 }
va009039 0:27d35fa263b5 135 fclose(fp);
va009039 0:27d35fa263b5 136 if (passed) {
va009039 0:27d35fa263b5 137 _pc->printf("passed.\n");
va009039 0:27d35fa263b5 138 }
va009039 0:27d35fa263b5 139 return passed;
va009039 0:27d35fa263b5 140 }
va009039 0:27d35fa263b5 141
va009039 8:d7f5d80531e4 142 int Flash::addr_to_sector(int addr) {
va009039 8:d7f5d80531e4 143 if (addr < 0x10000) {
va009039 8:d7f5d80531e4 144 return addr / cfg.sector_size;
va009039 8:d7f5d80531e4 145 }
va009039 8:d7f5d80531e4 146 return addr / 0x8000 + 0x10000/cfg.sector_size - 2;
va009039 8:d7f5d80531e4 147 }
va009039 8:d7f5d80531e4 148
va009039 8:d7f5d80531e4 149 bool Flash::sector_head(int addr) {
va009039 8:d7f5d80531e4 150 if (addr < 0x10000) {
va009039 8:d7f5d80531e4 151 return (addr%cfg.sector_size) == 0;
va009039 8:d7f5d80531e4 152 }
va009039 8:d7f5d80531e4 153 return (addr%0x8000) == 0;
va009039 8:d7f5d80531e4 154 }
va009039 8:d7f5d80531e4 155
va009039 6:5da6ad51a18f 156 bool Flash::write(int addr, const uint8_t* data, int size)
va009039 6:5da6ad51a18f 157 {
va009039 14:e6acf863207e 158 int temp_addr = ram_addr + 44;
va009039 14:e6acf863207e 159 int temp_size = 512;
va009039 14:e6acf863207e 160 for(int i = 0; i < size; i += temp_size) {
va009039 9:7e71c20c96e4 161 update();
va009039 14:e6acf863207e 162 if (!_write_to_ram(temp_addr, temp_size, data+i)) {
va009039 14:e6acf863207e 163 _pc->printf("faild. write to ram %08x\n", temp_addr);
va009039 6:5da6ad51a18f 164 return false;
va009039 6:5da6ad51a18f 165 }
va009039 8:d7f5d80531e4 166 int sector = addr_to_sector(addr + i);
va009039 8:d7f5d80531e4 167 if (sector_head(addr + i)) {
va009039 8:d7f5d80531e4 168 if (remoteIAP(PREPARE_SECTOR, sector, sector) != CMD_SUCCESS) {
va009039 8:d7f5d80531e4 169 _pc->printf("faild. PREPARE_SECTOR %d %d\n", sector, sector);
va009039 8:d7f5d80531e4 170 return false;
va009039 8:d7f5d80531e4 171 }
va009039 8:d7f5d80531e4 172 if (remoteIAP(ERASE_SECTOR, sector, sector, cfg.iap_cclk) != CMD_SUCCESS) {
va009039 8:d7f5d80531e4 173 _pc->printf("faild. ERASE_SECTOR %d %d %d\n", sector, sector, cfg.iap_cclk);
va009039 8:d7f5d80531e4 174 return false;
va009039 8:d7f5d80531e4 175 }
va009039 8:d7f5d80531e4 176 if (remoteIAP(BLANK_CHECK, sector, sector, cfg.iap_cclk) != CMD_SUCCESS) {
va009039 8:d7f5d80531e4 177 _pc->printf("faild. BLANK_CHECK %d %d %d\n", sector, sector, cfg.iap_cclk);
va009039 8:d7f5d80531e4 178 return false;
va009039 8:d7f5d80531e4 179 }
va009039 8:d7f5d80531e4 180 }
va009039 8:d7f5d80531e4 181 if (remoteIAP(PREPARE_SECTOR, sector, sector) != CMD_SUCCESS) {
va009039 8:d7f5d80531e4 182 _pc->printf("faild. PREPARE_SECTOR %d %d\n", sector, sector);
va009039 6:5da6ad51a18f 183 return false;
va009039 6:5da6ad51a18f 184 }
va009039 14:e6acf863207e 185 if (remoteIAP(COPY_RAM_TO_FLASH, addr+i, temp_addr, temp_size, cfg.iap_cclk) != CMD_SUCCESS) {
va009039 14:e6acf863207e 186 _pc->printf("faild. COPY_RAM_TO_FLASH %d %d %d %dn", addr+i, temp_addr, temp_size, cfg.iap_cclk);
va009039 6:5da6ad51a18f 187 return false;
va009039 6:5da6ad51a18f 188 }
va009039 14:e6acf863207e 189 if (remoteIAP(COMPARE, addr+i, temp_addr, temp_size) != CMD_SUCCESS) {
va009039 14:e6acf863207e 190 _pc->printf("faild. COMPARE %d %d %d", addr+i, temp_addr, temp_size);
va009039 6:5da6ad51a18f 191 return false;
va009039 6:5da6ad51a18f 192 }
va009039 6:5da6ad51a18f 193 }
va009039 6:5da6ad51a18f 194 return true;
va009039 6:5da6ad51a18f 195 }
va009039 6:5da6ad51a18f 196
va009039 6:5da6ad51a18f 197 bool Flash::_write_to_ram(int addr, int size, const uint8_t* buf)
va009039 0:27d35fa263b5 198 {
va009039 0:27d35fa263b5 199 _target->writeMemory(addr, (uint32_t*)buf, size / sizeof(uint32_t));
va009039 0:27d35fa263b5 200 return true;
va009039 0:27d35fa263b5 201 }
va009039 0:27d35fa263b5 202
va009039 5:2774358f5e4f 203 static uint32_t LD32(uint8_t* buf)
va009039 5:2774358f5e4f 204 {
va009039 8:d7f5d80531e4 205 return (buf[0]) | (buf[1]<<8) | (buf[2]<<16) | (buf[3]<<24);
va009039 5:2774358f5e4f 206 }
va009039 5:2774358f5e4f 207
va009039 0:27d35fa263b5 208 bool Flash::_patch(uint8_t* buf, int size, int addr)
va009039 0:27d35fa263b5 209 {
va009039 0:27d35fa263b5 210 const int crp_start = 0x2fc; // Code Read Protection location
va009039 0:27d35fa263b5 211 if (crp_start >= addr && crp_start < addr+size) {
va009039 5:2774358f5e4f 212 uint32_t pat = LD32(crp_start-addr+buf);
va009039 0:27d35fa263b5 213 if (pat != 0xffffffff) { // NO_CRP ?
va009039 0:27d35fa263b5 214 _pc->printf("\nCAUTION: CRP Pattern is not NO_CRP; %08x\n", pat);
va009039 0:27d35fa263b5 215 return false;
va009039 0:27d35fa263b5 216 }
va009039 0:27d35fa263b5 217 }
va009039 0:27d35fa263b5 218 return true;
va009039 0:27d35fa263b5 219 }
va009039 0:27d35fa263b5 220
va009039 2:32e9437348ad 221 Flash::IAP_STATUS Flash::remoteIAP(Flash::IAP_CMD cmd, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3)
va009039 0:27d35fa263b5 222 {
va009039 0:27d35fa263b5 223 struct {
va009039 0:27d35fa263b5 224 uint32_t bkpt; // +0
va009039 0:27d35fa263b5 225 struct { // IAP Structure
va009039 0:27d35fa263b5 226 uint32_t cmd; // +4 Command
va009039 0:27d35fa263b5 227 uint32_t par[4]; // +8 Parameters
va009039 0:27d35fa263b5 228 uint32_t stat; // +24 Status
va009039 0:27d35fa263b5 229 uint32_t res[4]; // +28 Result
va009039 0:27d35fa263b5 230 } IAP; // +44
va009039 0:27d35fa263b5 231 } ram;
va009039 0:27d35fa263b5 232
va009039 2:32e9437348ad 233 ram.bkpt = 0xe00abe00; // bpkt #00
va009039 0:27d35fa263b5 234 ram.IAP.cmd = cmd;
va009039 0:27d35fa263b5 235 ram.IAP.par[0] = p0;
va009039 0:27d35fa263b5 236 ram.IAP.par[1] = p1;
va009039 0:27d35fa263b5 237 ram.IAP.par[2] = p2;
va009039 0:27d35fa263b5 238 ram.IAP.par[3] = p3;
va009039 0:27d35fa263b5 239 _target->halt();
va009039 0:27d35fa263b5 240 _target->wait_status(TARGET_HALTED);
va009039 14:e6acf863207e 241
va009039 0:27d35fa263b5 242 _target->writeMemory(ram_addr, (uint32_t*)&ram, sizeof(ram)/sizeof(uint32_t));
va009039 2:32e9437348ad 243 _target->r0 = ram_addr + 4; // command addr
va009039 2:32e9437348ad 244 _target->r1 = ram_addr + 24; // status addr
va009039 2:32e9437348ad 245 _target->sp = 0x10000400-32; // IAP use ram top 32bytes
va009039 0:27d35fa263b5 246 _target->lr = ram_addr + 1; // return to bkpt
va009039 0:27d35fa263b5 247 _target->pc = 0x1fff1ff1; // IAP_Call
va009039 0:27d35fa263b5 248 _target->resume();
va009039 0:27d35fa263b5 249 _target->wait_status(TARGET_HALTED);
va009039 8:d7f5d80531e4 250 if (cmd == READ_PART_ID) {
va009039 8:d7f5d80531e4 251 part_id = _target->readMemory(ram_addr + 28);
va009039 8:d7f5d80531e4 252 }
va009039 2:32e9437348ad 253 return (IAP_STATUS)_target->readMemory(ram_addr + 24);
va009039 0:27d35fa263b5 254 }
va009039 0:27d35fa263b5 255
va009039 0:27d35fa263b5 256 bool Flash::verify(const char* filename)
va009039 0:27d35fa263b5 257 {
va009039 0:27d35fa263b5 258 FILE* fp = fopen(filename, "rb");
va009039 0:27d35fa263b5 259 if (fp == NULL) {
va009039 0:27d35fa263b5 260 _pc->printf("file open error [%s]\n", filename);
va009039 0:27d35fa263b5 261 return false;
va009039 0:27d35fa263b5 262 }
va009039 0:27d35fa263b5 263 _pc->printf("Verifying.");
va009039 0:27d35fa263b5 264 uint8_t buf[256];
va009039 0:27d35fa263b5 265 bool passed = false;
va009039 14:e6acf863207e 266 for(int addr = 0; addr < 0x80000; addr++) {
va009039 0:27d35fa263b5 267 int c = fgetc(fp);
va009039 0:27d35fa263b5 268 if (c == EOF) {
va009039 0:27d35fa263b5 269 passed = true;
va009039 0:27d35fa263b5 270 break;
va009039 0:27d35fa263b5 271 }
va009039 0:27d35fa263b5 272 if ((addr % sizeof(buf)) == 0) {
va009039 0:27d35fa263b5 273 _target->readMemory(addr, (uint32_t*)buf, sizeof(buf)/sizeof(uint32_t));
va009039 0:27d35fa263b5 274 _pc->printf(".");
va009039 0:27d35fa263b5 275 }
va009039 0:27d35fa263b5 276 if (c != buf[addr % sizeof(buf)]) {
va009039 0:27d35fa263b5 277 _pc->printf("\nError at %08x(%02x:%02x)\n", addr, c, buf[addr % sizeof(buf)]);
va009039 4:5e4107edcbdb 278 break;
va009039 0:27d35fa263b5 279 }
va009039 0:27d35fa263b5 280 }
va009039 0:27d35fa263b5 281 fclose(fp);
va009039 0:27d35fa263b5 282 if (passed) {
va009039 0:27d35fa263b5 283 _pc->printf("passed.\n");
va009039 0:27d35fa263b5 284 }
va009039 0:27d35fa263b5 285 return passed;
va009039 0:27d35fa263b5 286 }