ISP example program.
Dependencies: SLCD mbed USBLocalFileSystem
BaseLpcIsp.cpp
00001 #include "BaseLpcIsp.h" 00002 #include <algorithm> 00003 00004 #if (DEBUG2 > 3) 00005 #define ISP_DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\r\n");} while(0); 00006 #else 00007 #define ISP_DBG(...) while(0); 00008 #endif 00009 00010 #define ISP_ERR() isp_error(__LINE__) 00011 00012 #define RAM 0x10000300 00013 #define ROM_SIZE 0x10000 00014 00015 void BaseLpcIsp::Reset(bool isp) 00016 { 00017 _nisp = isp ? 0 : 1; 00018 _nreset = 0; 00019 wait_ms(50); 00020 _nreset = 1; 00021 wait_ms(100); 00022 } 00023 00024 bool BaseLpcIsp::Sync() 00025 { 00026 putc('?'); 00027 if (waitln("Synchronized")) { // Synchronized 00028 sendln("Synchronized"); 00029 if (waitln("OK")) { 00030 sendln("14748"); 00031 if (waitln("OK")) { 00032 if (_cmd("A 0")) { // echo off 00033 return true; 00034 } 00035 } 00036 } 00037 } 00038 ISP_ERR(); 00039 return false; 00040 } 00041 00042 bool BaseLpcIsp::_cmd(const char* format, ...) 00043 { 00044 char buf[128]; 00045 va_list args; 00046 va_start(args, format); 00047 vsprintf(buf, format, args); 00048 va_end(args); 00049 sendln(buf); 00050 00051 if (waitln("0")) { // CMD_SUCCESS ? 00052 return true; 00053 } 00054 ISP_ERR(); 00055 return false; 00056 } 00057 00058 void BaseLpcIsp::sendln(const char* s) 00059 { 00060 infoLED(LED_TX, tx_sw++ & 1); 00061 ISP_DBG("send:[%s]", s); 00062 puts(s); 00063 puts(CRLF); 00064 } 00065 00066 bool BaseLpcIsp::waitln(const char* s) 00067 { 00068 char buf[64]; 00069 while(recvln(buf, sizeof(buf))) { 00070 if (strcmp(buf, s) == 0) { 00071 ISP_DBG("recv:[%s]", buf); 00072 return true; 00073 } 00074 ISP_DBG("skip:[%s]", buf); 00075 } 00076 ISP_ERR(); 00077 return false; 00078 } 00079 00080 bool BaseLpcIsp::recvln(mystring& s) 00081 { 00082 Timer t; 00083 t.reset(); 00084 t.start(); 00085 while(t.read_ms() < 900) { 00086 if (readable()) { 00087 int c = getc(); 00088 if (c == LF) { 00089 return true; 00090 } else if (c >= ' ') { 00091 s.append(c); 00092 } 00093 } 00094 } 00095 ISP_ERR(); 00096 return false; 00097 } 00098 00099 bool BaseLpcIsp::recvln(char* buf, int size) 00100 { 00101 Timer t; 00102 t.reset(); 00103 t.start(); 00104 int pos = 0; 00105 while(t.read_ms() < 900) { 00106 if (readable()) { 00107 int c = getc(); 00108 if (c == LF) { 00109 buf[pos] = '\0'; 00110 return true; 00111 } else if (c >= ' ') { 00112 if (pos < size-1) { 00113 buf[pos++] = c; 00114 } 00115 } 00116 } 00117 } 00118 return false; 00119 } 00120 00121 bool BaseLpcIsp::FlashWrite(const char* filename) 00122 { 00123 infoLED(LED_TX, 0); 00124 if (!_cmd("J")) { 00125 return false; 00126 } 00127 char lineBuf[16]; 00128 if (!recvln(lineBuf, sizeof(lineBuf))) { 00129 ISP_ERR(); 00130 return false; 00131 } 00132 ISP_DBG("recv:[%s]", lineBuf); 00133 00134 part_code = strtoul(lineBuf, NULL, 10); 00135 if (part_code >= 0x8100 && part_code <= 0x81ff) { // LPC8XX 00136 chunk_size = 64; 00137 sector_size = 1024; 00138 plan_binary = true; 00139 infoSLCD("810 "); 00140 } else { 00141 chunk_size = 256; 00142 sector_size = 4096; 00143 plan_binary = false; 00144 infoSLCD("1114"); 00145 } 00146 00147 if (!_cmd("U 23130")) { // Unlock 00148 ISP_ERR(); 00149 return false; 00150 } 00151 00152 FILE* fp = fopen(filename, "rb"); 00153 if (fp == NULL) { 00154 ISP_ERR(); 00155 return false; 00156 } 00157 00158 int bin_size = 0; 00159 Timer t; 00160 t.reset(); 00161 t.start(); 00162 uint8_t buf[chunk_size]; 00163 int sector = 0; 00164 bool result = false; 00165 for(int addr = 0; addr < ROM_SIZE; addr += sizeof(buf)) { 00166 if (feof(fp)) { 00167 result = true; 00168 break; 00169 } 00170 fread(buf, sizeof(buf), 1, fp); 00171 if (!_patch(addr, buf, sizeof(buf))) { 00172 break; 00173 } 00174 bin_size += sizeof(buf); 00175 if (!_write_to_ram(RAM, buf, sizeof(buf))) { 00176 break; 00177 } 00178 if ((addr % sector_size) == 0) { 00179 sector = addr / sector_size; 00180 if (!_cmd("P %u %u", sector, sector)) { 00181 break; 00182 } 00183 if (!_cmd("E %u %u", sector, sector)) { // Erase 00184 break; 00185 } 00186 if (!_cmd("I %u %u", sector, sector)) { // Blank check 00187 break; 00188 } 00189 } 00190 if (!_cmd("P %u %u", sector, sector)) { 00191 break; 00192 } 00193 if (!_cmd("C %u %u %u", addr, RAM, sizeof(buf))) { // copy 00194 break; 00195 } 00196 if (!_cmd("M %u %u %u", addr, RAM, sizeof(buf))) { // compare 00197 break; 00198 } 00199 } 00200 fclose(fp); 00201 infoLED(LED_TX, 0); 00202 if (result) { 00203 t.stop(); 00204 ISP_DBG("bin size: %d bytes, %d ms, %d bytes/sec", 00205 bin_size, t.read_ms(), bin_size*1000/t.read_ms()); 00206 infoSLCD("OK "); 00207 } 00208 return result; 00209 } 00210 00211 extern void uuencode(const void* src, int srcsize, char* dst); //utils.cpp 00212 00213 bool BaseLpcIsp::_write_to_ram(int addr, uint8_t* buf, int size) 00214 { 00215 if (!_cmd("W %u %u", addr, size)) { 00216 return false; 00217 } 00218 if (plan_binary) { 00219 for(int i = 0; i < size; i++) { 00220 _target.putc(buf[i]); 00221 } 00222 return true; 00223 } 00224 int sum = 0; 00225 int line = 0; 00226 for(int n = 0; n < size; n += 45) { 00227 char tmp[61+1]; 00228 int size2 = std::min(45, size - n); 00229 uuencode(buf+n, size2, tmp); 00230 sendln(tmp); 00231 for(int i = 0; i < size2; i++) { 00232 sum += buf[n+i]; 00233 } 00234 if (++line >= 20 || (n + size2) >= size) { 00235 snprintf(tmp, sizeof(tmp), "%u", sum); 00236 sendln(tmp); 00237 if (!waitln("OK")) { 00238 return false; 00239 } 00240 line = 0; 00241 sum = 0; 00242 } 00243 } 00244 return true; 00245 } 00246 00247 bool BaseLpcIsp::_patch(int addr, uint8_t* buf, int size) 00248 { 00249 const int crp_start = 0x2fc; // Code Read Protection location 00250 if (crp_start >= addr && crp_start < addr+size) { 00251 uint32_t pat = *reinterpret_cast<uint32_t*>(crp_start-addr+buf); 00252 if (pat != 0xffffffff) { // NO_CRP ? 00253 ISP_ERR(); 00254 return false; 00255 } 00256 } 00257 return true; 00258 }
Generated on Sun Jul 24 2022 14:33:07 by 1.7.2