ISP example program.
Dependencies: SLCD mbed USBLocalFileSystem
FRDM-KL46Z | LPC810 | |
---|---|---|
UART RXD | PTE23 | p2(P0_4) |
UART TXD | PTE22 | p8(P0_0) |
nRESET | D6 | p1(P0_5) |
nISP | D8 | p5(P0_1) |
GND | GND | p7 |
3.3V | P3V3 | p6 |
Copy binary image to the disk called LPC81ISP.
Push sw1 or sw3, start write to LPC810 flash.
BaseLpcIsp.cpp
- Committer:
- va009039
- Date:
- 2014-05-04
- Revision:
- 2:eafc1c6787c7
- Parent:
- src/BaseLpcIsp.cpp@ 0:ad2b1fc04955
File content as of revision 2:eafc1c6787c7:
#include "BaseLpcIsp.h" #include <algorithm> #if (DEBUG2 > 3) #define ISP_DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\r\n");} while(0); #else #define ISP_DBG(...) while(0); #endif #define ISP_ERR() isp_error(__LINE__) #define RAM 0x10000300 #define ROM_SIZE 0x10000 void BaseLpcIsp::Reset(bool isp) { _nisp = isp ? 0 : 1; _nreset = 0; wait_ms(50); _nreset = 1; wait_ms(100); } bool BaseLpcIsp::Sync() { putc('?'); if (waitln("Synchronized")) { // Synchronized sendln("Synchronized"); if (waitln("OK")) { sendln("14748"); if (waitln("OK")) { if (_cmd("A 0")) { // echo off return true; } } } } ISP_ERR(); return false; } bool BaseLpcIsp::_cmd(const char* format, ...) { char buf[128]; va_list args; va_start(args, format); vsprintf(buf, format, args); va_end(args); sendln(buf); if (waitln("0")) { // CMD_SUCCESS ? return true; } ISP_ERR(); return false; } void BaseLpcIsp::sendln(const char* s) { infoLED(LED_TX, tx_sw++ & 1); ISP_DBG("send:[%s]", s); puts(s); puts(CRLF); } bool BaseLpcIsp::waitln(const char* s) { char buf[64]; while(recvln(buf, sizeof(buf))) { if (strcmp(buf, s) == 0) { ISP_DBG("recv:[%s]", buf); return true; } ISP_DBG("skip:[%s]", buf); } ISP_ERR(); return false; } bool BaseLpcIsp::recvln(mystring& s) { Timer t; t.reset(); t.start(); while(t.read_ms() < 900) { if (readable()) { int c = getc(); if (c == LF) { return true; } else if (c >= ' ') { s.append(c); } } } ISP_ERR(); return false; } bool BaseLpcIsp::recvln(char* buf, int size) { Timer t; t.reset(); t.start(); int pos = 0; while(t.read_ms() < 900) { if (readable()) { int c = getc(); if (c == LF) { buf[pos] = '\0'; return true; } else if (c >= ' ') { if (pos < size-1) { buf[pos++] = c; } } } } return false; } bool BaseLpcIsp::FlashWrite(const char* filename) { infoLED(LED_TX, 0); if (!_cmd("J")) { return false; } char lineBuf[16]; if (!recvln(lineBuf, sizeof(lineBuf))) { ISP_ERR(); return false; } ISP_DBG("recv:[%s]", lineBuf); part_code = strtoul(lineBuf, NULL, 10); if (part_code >= 0x8100 && part_code <= 0x81ff) { // LPC8XX chunk_size = 64; sector_size = 1024; plan_binary = true; infoSLCD("810 "); } else { chunk_size = 256; sector_size = 4096; plan_binary = false; infoSLCD("1114"); } if (!_cmd("U 23130")) { // Unlock ISP_ERR(); return false; } FILE* fp = fopen(filename, "rb"); if (fp == NULL) { ISP_ERR(); return false; } int bin_size = 0; Timer t; t.reset(); t.start(); uint8_t buf[chunk_size]; int sector = 0; bool result = false; for(int addr = 0; addr < ROM_SIZE; addr += sizeof(buf)) { if (feof(fp)) { result = true; break; } fread(buf, sizeof(buf), 1, fp); if (!_patch(addr, buf, sizeof(buf))) { break; } bin_size += sizeof(buf); if (!_write_to_ram(RAM, buf, sizeof(buf))) { break; } if ((addr % sector_size) == 0) { sector = addr / sector_size; if (!_cmd("P %u %u", sector, sector)) { break; } if (!_cmd("E %u %u", sector, sector)) { // Erase break; } if (!_cmd("I %u %u", sector, sector)) { // Blank check break; } } if (!_cmd("P %u %u", sector, sector)) { break; } if (!_cmd("C %u %u %u", addr, RAM, sizeof(buf))) { // copy break; } if (!_cmd("M %u %u %u", addr, RAM, sizeof(buf))) { // compare break; } } fclose(fp); infoLED(LED_TX, 0); if (result) { t.stop(); ISP_DBG("bin size: %d bytes, %d ms, %d bytes/sec", bin_size, t.read_ms(), bin_size*1000/t.read_ms()); infoSLCD("OK "); } return result; } extern void uuencode(const void* src, int srcsize, char* dst); //utils.cpp bool BaseLpcIsp::_write_to_ram(int addr, uint8_t* buf, int size) { if (!_cmd("W %u %u", addr, size)) { return false; } if (plan_binary) { for(int i = 0; i < size; i++) { _target.putc(buf[i]); } return true; } int sum = 0; int line = 0; for(int n = 0; n < size; n += 45) { char tmp[61+1]; int size2 = std::min(45, size - n); uuencode(buf+n, size2, tmp); sendln(tmp); for(int i = 0; i < size2; i++) { sum += buf[n+i]; } if (++line >= 20 || (n + size2) >= size) { snprintf(tmp, sizeof(tmp), "%u", sum); sendln(tmp); if (!waitln("OK")) { return false; } line = 0; sum = 0; } } return true; } bool BaseLpcIsp::_patch(int addr, uint8_t* buf, int size) { const int crp_start = 0x2fc; // Code Read Protection location if (crp_start >= addr && crp_start < addr+size) { uint32_t pat = *reinterpret_cast<uint32_t*>(crp_start-addr+buf); if (pat != 0xffffffff) { // NO_CRP ? ISP_ERR(); return false; } } return true; }