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@18:5ed1759e863b, 2014-06-22 (annotated)
- 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?
User | Revision | Line number | New 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 | } |