ISP example program.

Dependencies:   SLCD mbed USBLocalFileSystem

/media/uploads/va009039/lpc81isp-360x240.jpg

FRDM-KL46ZLPC810
UART RXDPTE23p2(P0_4)
UART TXDPTE22p8(P0_0)
nRESETD6p1(P0_5)
nISPD8p5(P0_1)
GNDGNDp7
3.3VP3V3p6

Copy binary image to the disk called LPC81ISP.
Push sw1 or sw3, start write to LPC810 flash.

Committer:
va009039
Date:
Sun May 04 00:36:04 2014 +0000
Revision:
2:eafc1c6787c7
Parent:
src/BaseLpcIsp.cpp@0:ad2b1fc04955
update USBLocalFileSystem library.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 0:ad2b1fc04955 1 #include "BaseLpcIsp.h"
va009039 0:ad2b1fc04955 2 #include <algorithm>
va009039 0:ad2b1fc04955 3
va009039 0:ad2b1fc04955 4 #if (DEBUG2 > 3)
va009039 0:ad2b1fc04955 5 #define ISP_DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\r\n");} while(0);
va009039 0:ad2b1fc04955 6 #else
va009039 0:ad2b1fc04955 7 #define ISP_DBG(...) while(0);
va009039 0:ad2b1fc04955 8 #endif
va009039 0:ad2b1fc04955 9
va009039 0:ad2b1fc04955 10 #define ISP_ERR() isp_error(__LINE__)
va009039 0:ad2b1fc04955 11
va009039 0:ad2b1fc04955 12 #define RAM 0x10000300
va009039 0:ad2b1fc04955 13 #define ROM_SIZE 0x10000
va009039 0:ad2b1fc04955 14
va009039 0:ad2b1fc04955 15 void BaseLpcIsp::Reset(bool isp)
va009039 0:ad2b1fc04955 16 {
va009039 0:ad2b1fc04955 17 _nisp = isp ? 0 : 1;
va009039 0:ad2b1fc04955 18 _nreset = 0;
va009039 0:ad2b1fc04955 19 wait_ms(50);
va009039 0:ad2b1fc04955 20 _nreset = 1;
va009039 0:ad2b1fc04955 21 wait_ms(100);
va009039 0:ad2b1fc04955 22 }
va009039 0:ad2b1fc04955 23
va009039 0:ad2b1fc04955 24 bool BaseLpcIsp::Sync()
va009039 0:ad2b1fc04955 25 {
va009039 0:ad2b1fc04955 26 putc('?');
va009039 0:ad2b1fc04955 27 if (waitln("Synchronized")) { // Synchronized
va009039 0:ad2b1fc04955 28 sendln("Synchronized");
va009039 0:ad2b1fc04955 29 if (waitln("OK")) {
va009039 0:ad2b1fc04955 30 sendln("14748");
va009039 0:ad2b1fc04955 31 if (waitln("OK")) {
va009039 0:ad2b1fc04955 32 if (_cmd("A 0")) { // echo off
va009039 0:ad2b1fc04955 33 return true;
va009039 0:ad2b1fc04955 34 }
va009039 0:ad2b1fc04955 35 }
va009039 0:ad2b1fc04955 36 }
va009039 0:ad2b1fc04955 37 }
va009039 0:ad2b1fc04955 38 ISP_ERR();
va009039 0:ad2b1fc04955 39 return false;
va009039 0:ad2b1fc04955 40 }
va009039 0:ad2b1fc04955 41
va009039 0:ad2b1fc04955 42 bool BaseLpcIsp::_cmd(const char* format, ...)
va009039 0:ad2b1fc04955 43 {
va009039 0:ad2b1fc04955 44 char buf[128];
va009039 0:ad2b1fc04955 45 va_list args;
va009039 0:ad2b1fc04955 46 va_start(args, format);
va009039 0:ad2b1fc04955 47 vsprintf(buf, format, args);
va009039 0:ad2b1fc04955 48 va_end(args);
va009039 0:ad2b1fc04955 49 sendln(buf);
va009039 0:ad2b1fc04955 50
va009039 0:ad2b1fc04955 51 if (waitln("0")) { // CMD_SUCCESS ?
va009039 0:ad2b1fc04955 52 return true;
va009039 0:ad2b1fc04955 53 }
va009039 0:ad2b1fc04955 54 ISP_ERR();
va009039 0:ad2b1fc04955 55 return false;
va009039 0:ad2b1fc04955 56 }
va009039 0:ad2b1fc04955 57
va009039 0:ad2b1fc04955 58 void BaseLpcIsp::sendln(const char* s)
va009039 0:ad2b1fc04955 59 {
va009039 0:ad2b1fc04955 60 infoLED(LED_TX, tx_sw++ & 1);
va009039 0:ad2b1fc04955 61 ISP_DBG("send:[%s]", s);
va009039 0:ad2b1fc04955 62 puts(s);
va009039 0:ad2b1fc04955 63 puts(CRLF);
va009039 0:ad2b1fc04955 64 }
va009039 0:ad2b1fc04955 65
va009039 0:ad2b1fc04955 66 bool BaseLpcIsp::waitln(const char* s)
va009039 0:ad2b1fc04955 67 {
va009039 0:ad2b1fc04955 68 char buf[64];
va009039 0:ad2b1fc04955 69 while(recvln(buf, sizeof(buf))) {
va009039 0:ad2b1fc04955 70 if (strcmp(buf, s) == 0) {
va009039 0:ad2b1fc04955 71 ISP_DBG("recv:[%s]", buf);
va009039 0:ad2b1fc04955 72 return true;
va009039 0:ad2b1fc04955 73 }
va009039 0:ad2b1fc04955 74 ISP_DBG("skip:[%s]", buf);
va009039 0:ad2b1fc04955 75 }
va009039 0:ad2b1fc04955 76 ISP_ERR();
va009039 0:ad2b1fc04955 77 return false;
va009039 0:ad2b1fc04955 78 }
va009039 0:ad2b1fc04955 79
va009039 0:ad2b1fc04955 80 bool BaseLpcIsp::recvln(mystring& s)
va009039 0:ad2b1fc04955 81 {
va009039 0:ad2b1fc04955 82 Timer t;
va009039 0:ad2b1fc04955 83 t.reset();
va009039 0:ad2b1fc04955 84 t.start();
va009039 0:ad2b1fc04955 85 while(t.read_ms() < 900) {
va009039 0:ad2b1fc04955 86 if (readable()) {
va009039 0:ad2b1fc04955 87 int c = getc();
va009039 0:ad2b1fc04955 88 if (c == LF) {
va009039 0:ad2b1fc04955 89 return true;
va009039 0:ad2b1fc04955 90 } else if (c >= ' ') {
va009039 0:ad2b1fc04955 91 s.append(c);
va009039 0:ad2b1fc04955 92 }
va009039 0:ad2b1fc04955 93 }
va009039 0:ad2b1fc04955 94 }
va009039 0:ad2b1fc04955 95 ISP_ERR();
va009039 0:ad2b1fc04955 96 return false;
va009039 0:ad2b1fc04955 97 }
va009039 0:ad2b1fc04955 98
va009039 0:ad2b1fc04955 99 bool BaseLpcIsp::recvln(char* buf, int size)
va009039 0:ad2b1fc04955 100 {
va009039 0:ad2b1fc04955 101 Timer t;
va009039 0:ad2b1fc04955 102 t.reset();
va009039 0:ad2b1fc04955 103 t.start();
va009039 0:ad2b1fc04955 104 int pos = 0;
va009039 0:ad2b1fc04955 105 while(t.read_ms() < 900) {
va009039 0:ad2b1fc04955 106 if (readable()) {
va009039 0:ad2b1fc04955 107 int c = getc();
va009039 0:ad2b1fc04955 108 if (c == LF) {
va009039 0:ad2b1fc04955 109 buf[pos] = '\0';
va009039 0:ad2b1fc04955 110 return true;
va009039 0:ad2b1fc04955 111 } else if (c >= ' ') {
va009039 0:ad2b1fc04955 112 if (pos < size-1) {
va009039 0:ad2b1fc04955 113 buf[pos++] = c;
va009039 0:ad2b1fc04955 114 }
va009039 0:ad2b1fc04955 115 }
va009039 0:ad2b1fc04955 116 }
va009039 0:ad2b1fc04955 117 }
va009039 0:ad2b1fc04955 118 return false;
va009039 0:ad2b1fc04955 119 }
va009039 0:ad2b1fc04955 120
va009039 0:ad2b1fc04955 121 bool BaseLpcIsp::FlashWrite(const char* filename)
va009039 0:ad2b1fc04955 122 {
va009039 0:ad2b1fc04955 123 infoLED(LED_TX, 0);
va009039 0:ad2b1fc04955 124 if (!_cmd("J")) {
va009039 0:ad2b1fc04955 125 return false;
va009039 0:ad2b1fc04955 126 }
va009039 0:ad2b1fc04955 127 char lineBuf[16];
va009039 0:ad2b1fc04955 128 if (!recvln(lineBuf, sizeof(lineBuf))) {
va009039 0:ad2b1fc04955 129 ISP_ERR();
va009039 0:ad2b1fc04955 130 return false;
va009039 0:ad2b1fc04955 131 }
va009039 0:ad2b1fc04955 132 ISP_DBG("recv:[%s]", lineBuf);
va009039 0:ad2b1fc04955 133
va009039 0:ad2b1fc04955 134 part_code = strtoul(lineBuf, NULL, 10);
va009039 0:ad2b1fc04955 135 if (part_code >= 0x8100 && part_code <= 0x81ff) { // LPC8XX
va009039 0:ad2b1fc04955 136 chunk_size = 64;
va009039 0:ad2b1fc04955 137 sector_size = 1024;
va009039 0:ad2b1fc04955 138 plan_binary = true;
va009039 0:ad2b1fc04955 139 infoSLCD("810 ");
va009039 0:ad2b1fc04955 140 } else {
va009039 0:ad2b1fc04955 141 chunk_size = 256;
va009039 0:ad2b1fc04955 142 sector_size = 4096;
va009039 0:ad2b1fc04955 143 plan_binary = false;
va009039 0:ad2b1fc04955 144 infoSLCD("1114");
va009039 0:ad2b1fc04955 145 }
va009039 0:ad2b1fc04955 146
va009039 0:ad2b1fc04955 147 if (!_cmd("U 23130")) { // Unlock
va009039 0:ad2b1fc04955 148 ISP_ERR();
va009039 0:ad2b1fc04955 149 return false;
va009039 0:ad2b1fc04955 150 }
va009039 0:ad2b1fc04955 151
va009039 0:ad2b1fc04955 152 FILE* fp = fopen(filename, "rb");
va009039 0:ad2b1fc04955 153 if (fp == NULL) {
va009039 0:ad2b1fc04955 154 ISP_ERR();
va009039 0:ad2b1fc04955 155 return false;
va009039 0:ad2b1fc04955 156 }
va009039 0:ad2b1fc04955 157
va009039 0:ad2b1fc04955 158 int bin_size = 0;
va009039 0:ad2b1fc04955 159 Timer t;
va009039 0:ad2b1fc04955 160 t.reset();
va009039 0:ad2b1fc04955 161 t.start();
va009039 0:ad2b1fc04955 162 uint8_t buf[chunk_size];
va009039 0:ad2b1fc04955 163 int sector = 0;
va009039 0:ad2b1fc04955 164 bool result = false;
va009039 0:ad2b1fc04955 165 for(int addr = 0; addr < ROM_SIZE; addr += sizeof(buf)) {
va009039 0:ad2b1fc04955 166 if (feof(fp)) {
va009039 0:ad2b1fc04955 167 result = true;
va009039 0:ad2b1fc04955 168 break;
va009039 0:ad2b1fc04955 169 }
va009039 0:ad2b1fc04955 170 fread(buf, sizeof(buf), 1, fp);
va009039 0:ad2b1fc04955 171 if (!_patch(addr, buf, sizeof(buf))) {
va009039 0:ad2b1fc04955 172 break;
va009039 0:ad2b1fc04955 173 }
va009039 0:ad2b1fc04955 174 bin_size += sizeof(buf);
va009039 0:ad2b1fc04955 175 if (!_write_to_ram(RAM, buf, sizeof(buf))) {
va009039 0:ad2b1fc04955 176 break;
va009039 0:ad2b1fc04955 177 }
va009039 0:ad2b1fc04955 178 if ((addr % sector_size) == 0) {
va009039 0:ad2b1fc04955 179 sector = addr / sector_size;
va009039 0:ad2b1fc04955 180 if (!_cmd("P %u %u", sector, sector)) {
va009039 0:ad2b1fc04955 181 break;
va009039 0:ad2b1fc04955 182 }
va009039 0:ad2b1fc04955 183 if (!_cmd("E %u %u", sector, sector)) { // Erase
va009039 0:ad2b1fc04955 184 break;
va009039 0:ad2b1fc04955 185 }
va009039 0:ad2b1fc04955 186 if (!_cmd("I %u %u", sector, sector)) { // Blank check
va009039 0:ad2b1fc04955 187 break;
va009039 0:ad2b1fc04955 188 }
va009039 0:ad2b1fc04955 189 }
va009039 0:ad2b1fc04955 190 if (!_cmd("P %u %u", sector, sector)) {
va009039 0:ad2b1fc04955 191 break;
va009039 0:ad2b1fc04955 192 }
va009039 0:ad2b1fc04955 193 if (!_cmd("C %u %u %u", addr, RAM, sizeof(buf))) { // copy
va009039 0:ad2b1fc04955 194 break;
va009039 0:ad2b1fc04955 195 }
va009039 0:ad2b1fc04955 196 if (!_cmd("M %u %u %u", addr, RAM, sizeof(buf))) { // compare
va009039 0:ad2b1fc04955 197 break;
va009039 0:ad2b1fc04955 198 }
va009039 0:ad2b1fc04955 199 }
va009039 0:ad2b1fc04955 200 fclose(fp);
va009039 0:ad2b1fc04955 201 infoLED(LED_TX, 0);
va009039 0:ad2b1fc04955 202 if (result) {
va009039 0:ad2b1fc04955 203 t.stop();
va009039 0:ad2b1fc04955 204 ISP_DBG("bin size: %d bytes, %d ms, %d bytes/sec",
va009039 0:ad2b1fc04955 205 bin_size, t.read_ms(), bin_size*1000/t.read_ms());
va009039 0:ad2b1fc04955 206 infoSLCD("OK ");
va009039 0:ad2b1fc04955 207 }
va009039 0:ad2b1fc04955 208 return result;
va009039 0:ad2b1fc04955 209 }
va009039 0:ad2b1fc04955 210
va009039 0:ad2b1fc04955 211 extern void uuencode(const void* src, int srcsize, char* dst); //utils.cpp
va009039 0:ad2b1fc04955 212
va009039 0:ad2b1fc04955 213 bool BaseLpcIsp::_write_to_ram(int addr, uint8_t* buf, int size)
va009039 0:ad2b1fc04955 214 {
va009039 0:ad2b1fc04955 215 if (!_cmd("W %u %u", addr, size)) {
va009039 0:ad2b1fc04955 216 return false;
va009039 0:ad2b1fc04955 217 }
va009039 0:ad2b1fc04955 218 if (plan_binary) {
va009039 0:ad2b1fc04955 219 for(int i = 0; i < size; i++) {
va009039 0:ad2b1fc04955 220 _target.putc(buf[i]);
va009039 0:ad2b1fc04955 221 }
va009039 0:ad2b1fc04955 222 return true;
va009039 0:ad2b1fc04955 223 }
va009039 0:ad2b1fc04955 224 int sum = 0;
va009039 0:ad2b1fc04955 225 int line = 0;
va009039 0:ad2b1fc04955 226 for(int n = 0; n < size; n += 45) {
va009039 0:ad2b1fc04955 227 char tmp[61+1];
va009039 0:ad2b1fc04955 228 int size2 = std::min(45, size - n);
va009039 0:ad2b1fc04955 229 uuencode(buf+n, size2, tmp);
va009039 0:ad2b1fc04955 230 sendln(tmp);
va009039 0:ad2b1fc04955 231 for(int i = 0; i < size2; i++) {
va009039 0:ad2b1fc04955 232 sum += buf[n+i];
va009039 0:ad2b1fc04955 233 }
va009039 0:ad2b1fc04955 234 if (++line >= 20 || (n + size2) >= size) {
va009039 0:ad2b1fc04955 235 snprintf(tmp, sizeof(tmp), "%u", sum);
va009039 0:ad2b1fc04955 236 sendln(tmp);
va009039 0:ad2b1fc04955 237 if (!waitln("OK")) {
va009039 0:ad2b1fc04955 238 return false;
va009039 0:ad2b1fc04955 239 }
va009039 0:ad2b1fc04955 240 line = 0;
va009039 0:ad2b1fc04955 241 sum = 0;
va009039 0:ad2b1fc04955 242 }
va009039 0:ad2b1fc04955 243 }
va009039 0:ad2b1fc04955 244 return true;
va009039 0:ad2b1fc04955 245 }
va009039 0:ad2b1fc04955 246
va009039 0:ad2b1fc04955 247 bool BaseLpcIsp::_patch(int addr, uint8_t* buf, int size)
va009039 0:ad2b1fc04955 248 {
va009039 0:ad2b1fc04955 249 const int crp_start = 0x2fc; // Code Read Protection location
va009039 0:ad2b1fc04955 250 if (crp_start >= addr && crp_start < addr+size) {
va009039 0:ad2b1fc04955 251 uint32_t pat = *reinterpret_cast<uint32_t*>(crp_start-addr+buf);
va009039 0:ad2b1fc04955 252 if (pat != 0xffffffff) { // NO_CRP ?
va009039 0:ad2b1fc04955 253 ISP_ERR();
va009039 0:ad2b1fc04955 254 return false;
va009039 0:ad2b1fc04955 255 }
va009039 0:ad2b1fc04955 256 }
va009039 0:ad2b1fc04955 257 return true;
va009039 0:ad2b1fc04955 258 }