USB composite device example program, drag-and-drop flash writer.
Dependencies: SWD USBDevice mbed BaseDAP
Flash.cpp
00001 // Flash.cpp 2013/9/16 00002 #include "Flash.h" 00003 #include "Target2.h" 00004 #include "mydebug.h" 00005 00006 #define SYSMEMREMAP 0x40048000 00007 #define MAINCLKSEL 0x40048070 00008 #define MAINCLKUEN 0x40048074 00009 #define SYSAHBCLKDIV 0x40048078 00010 00011 Flash::Flash(Target2* target, Serial* usbpc) :_target(target),_pc(usbpc) 00012 { 00013 _setup(); 00014 } 00015 00016 void Flash::_setup() 00017 { 00018 _target->halt(); 00019 _target->wait_status(TARGET_HALTED); 00020 _target->prog_status(); 00021 } 00022 00023 bool Flash::init() 00024 { 00025 _pc->printf("Initializing."); 00026 if (_target->idcode == 0x0bb11477) { // LPC1114FN28 00027 _target->writeMemory(MAINCLKSEL, 0); // Select Internal RC Oscillator 00028 _target->writeMemory(MAINCLKUEN, 1); // Update Main Clock Source 00029 _target->writeMemory(MAINCLKUEN, 0); // Toggle Update Register 00030 _target->writeMemory(MAINCLKUEN, 1); 00031 uint32_t data = _target->readMemory(MAINCLKUEN); // Wait until updated 00032 if (!(data & 1)) { 00033 _pc->printf("\nerror MAINCLKUEN=%08x\n", data); 00034 return false; 00035 } 00036 _target->writeMemory(SYSAHBCLKDIV, 1);// Set Main Clock divider to 1 00037 _target->writeMemory(SYSMEMREMAP, 2); // User Flash Mode 00038 } else { 00039 _pc->printf("\nerror idcode=%08x\n", _target->idcode); 00040 return false; 00041 } 00042 _pc->printf("passed.\n"); 00043 return true; 00044 } 00045 00046 bool Flash::write(const char* filename) 00047 { 00048 FILE* fp = fopen(filename, "rb"); 00049 if (fp == NULL) { 00050 _pc->printf("file open error [%s]\n", filename); 00051 return false; 00052 } 00053 _pc->printf("Writing."); 00054 uint8_t buf[512]; 00055 bool passed = false; 00056 for(int addr = 0; addr < 0x8000; addr += sizeof(buf)) { 00057 int ret = fread(buf, 1, sizeof(buf), fp); 00058 if (!_patch(buf, sizeof(buf), addr)) { 00059 break; 00060 } 00061 if (!write(addr, buf, sizeof(buf))) { 00062 break; 00063 } 00064 _pc->printf("."); 00065 if (ret < sizeof(buf)) { 00066 passed = true; 00067 break; 00068 } 00069 } 00070 fclose(fp); 00071 if (passed) { 00072 _pc->printf("passed.\n"); 00073 } 00074 return passed; 00075 } 00076 00077 bool Flash::write(int addr, const uint8_t* data, int size) 00078 { 00079 const int ram = 0x10000200; 00080 const int ram_size = 256; 00081 for(int i = 0; i < size; i += ram_size) { 00082 if (!_write_to_ram(ram, ram_size, data+i)) { 00083 _pc->printf("faild. write to ram %08x\n", ram); 00084 return false; 00085 } 00086 if (remoteIAP(PREPARE_SECTOR, _sector(addr+i), _sector(addr+i)) != CMD_SUCCESS) { 00087 _pc->printf("faild. PREPARE_SECTOR %d %d\n", _sector(addr+i), _sector(addr+i)); 00088 return false; 00089 } 00090 if (remoteIAP(COPY_RAM_TO_FLASH, addr+i, ram, ram_size, IAP_CCLK) != CMD_SUCCESS) { 00091 _pc->printf("faild. COPY_RAM_TO_FLASH %d %d %d %dn", addr+i, ram, ram_size); 00092 return false; 00093 } 00094 if (remoteIAP(COMPARE, addr+i, ram, ram_size) != CMD_SUCCESS) { 00095 _pc->printf("faild. COMPARE %d %d %d", addr+i, ram, ram_size); 00096 return false; 00097 } 00098 } 00099 return true; 00100 } 00101 00102 bool Flash::eraseAll() 00103 { 00104 _pc->printf("Erasing."); 00105 for(int sector = 0; sector <= 7; sector++) { 00106 IAP_STATUS status = remoteIAP(PREPARE_SECTOR, sector, sector); 00107 if (status != CMD_SUCCESS) { 00108 _pc->printf("faild. PREPARE_SECTOR %d %d status=%d\n", sector, sector, status); 00109 return false; 00110 } 00111 if (remoteIAP(ERASE_SECTOR, sector, sector, IAP_CCLK) != CMD_SUCCESS) { 00112 _pc->printf("faild. ERASE_SECTOR %d %d %d\n", sector, sector, IAP_CCLK); 00113 return false; 00114 } 00115 if (remoteIAP(BLANK_CHECK, sector, sector, IAP_CCLK) != CMD_SUCCESS) { 00116 _pc->printf("faild. BLANK_CHECK %d %d %d\n", sector, sector, IAP_CCLK); 00117 return false; 00118 } 00119 _pc->printf("."); 00120 } 00121 _pc->printf("passed.\n"); 00122 return true; 00123 } 00124 00125 bool Flash::_write_to_ram(int addr, int size, const uint8_t* buf) 00126 { 00127 _target->writeMemory(addr, (uint32_t*)buf, size / sizeof(uint32_t)); 00128 return true; 00129 } 00130 00131 int Flash::_sector(int addr) 00132 { 00133 return addr / 4096; 00134 } 00135 00136 static uint32_t LD32(uint8_t* buf) 00137 { 00138 return buf[0] | buf[1]<<8 | buf[2]<<16 | buf[3]<<24; 00139 } 00140 00141 bool Flash::_patch(uint8_t* buf, int size, int addr) 00142 { 00143 const int crp_start = 0x2fc; // Code Read Protection location 00144 if (crp_start >= addr && crp_start < addr+size) { 00145 uint32_t pat = LD32(crp_start-addr+buf); 00146 if (pat != 0xffffffff) { // NO_CRP ? 00147 _pc->printf("\nCAUTION: CRP Pattern is not NO_CRP; %08x\n", pat); 00148 return false; 00149 } 00150 } 00151 return true; 00152 } 00153 00154 Flash::IAP_STATUS Flash::remoteIAP(Flash::IAP_CMD cmd, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3) 00155 { 00156 struct { 00157 uint32_t bkpt; // +0 00158 struct { // IAP Structure 00159 uint32_t cmd; // +4 Command 00160 uint32_t par[4]; // +8 Parameters 00161 uint32_t stat; // +24 Status 00162 uint32_t res[4]; // +28 Result 00163 } IAP; // +44 00164 } ram; 00165 00166 ram.bkpt = 0xe00abe00; // bpkt #00 00167 ram.IAP.cmd = cmd; 00168 ram.IAP.par[0] = p0; 00169 ram.IAP.par[1] = p1; 00170 ram.IAP.par[2] = p2; 00171 ram.IAP.par[3] = p3; 00172 _target->halt(); 00173 _target->wait_status(TARGET_HALTED); 00174 const uint32_t ram_addr = 0x10000100; 00175 _target->writeMemory(ram_addr, (uint32_t*)&ram, sizeof(ram)/sizeof(uint32_t)); 00176 _target->r0 = ram_addr + 4; // command addr 00177 _target->r1 = ram_addr + 24; // status addr 00178 _target->sp = 0x10000400-32; // IAP use ram top 32bytes 00179 _target->lr = ram_addr + 1; // return to bkpt 00180 _target->pc = 0x1fff1ff1; // IAP_Call 00181 _target->resume(); 00182 _target->wait_status(TARGET_HALTED); 00183 return (IAP_STATUS)_target->readMemory(ram_addr + 24); 00184 } 00185 00186 bool Flash::verify(const char* filename) 00187 { 00188 FILE* fp = fopen(filename, "rb"); 00189 if (fp == NULL) { 00190 _pc->printf("file open error [%s]\n", filename); 00191 return false; 00192 } 00193 _pc->printf("Verifying."); 00194 uint8_t buf[256]; 00195 bool passed = false; 00196 for(int addr = 0; addr < 0x8000; addr++) { 00197 int c = fgetc(fp); 00198 if (c == EOF) { 00199 passed = true; 00200 break; 00201 } 00202 if ((addr % sizeof(buf)) == 0) { 00203 _target->readMemory(addr, (uint32_t*)buf, sizeof(buf)/sizeof(uint32_t)); 00204 _pc->printf("."); 00205 } 00206 if (c != buf[addr % sizeof(buf)]) { 00207 _pc->printf("\nError at %08x(%02x:%02x)\n", addr, c, buf[addr % sizeof(buf)]); 00208 break; 00209 } 00210 } 00211 fclose(fp); 00212 if (passed) { 00213 _pc->printf("passed.\n"); 00214 } 00215 return passed; 00216 }
Generated on Wed Jul 13 2022 08:08:24 by 1.7.2