IJFW - IchigoJamのBASICプログラムをメモリカード(MMCまたは互換カード)に保存したり読み出したりできるプログラム。メモリカードにファームウェアのファイルを置くだけで、電源ON時に自動的に書き換える機能も搭載(一応こちらがメイン)。LPC1114FN28専用。
参考URL http://www.cyberchabudai.org/index.php/entry?tag=IJFW
UartIsp/UartIspBase.cpp
- Committer:
- oks486
- Date:
- 2016-08-21
- Revision:
- 2:daf6c4719496
- Parent:
- 0:43cce7b453d0
File content as of revision 2:daf6c4719496:
#include "UartIspBase.h" #include <stdio.h> #include <string.h> const int SYNC_RETRY_NUM = 3; const int UUENCODE_LINE_BYTES = 45; // must be multiples of 3 const int RETURN_NORMAL = 1; const int RETURN_FAULT = 0; UartIspBase::UartIspBase() { // echoback setting echoBack = 1; // Generate UUEncode Table uuCharTable[0] = 0x60; for (int i = 1; i < 64; i++) { uuCharTable[i] = i + 32; } } UartIspBase::~UartIspBase() { } char UartIspBase::getUuString(int i) { return uuCharTable[i % 64]; } void UartIspBase::disableEchoBack() { writeString("A 0\n"); echoBack = 0; } void UartIspBase::writeString(const char val) { writeSerial(val); if (echoBack) { readSerial(); } } void UartIspBase::writeString(const char* str) { int length = strlen(str); for (int i = 0; i < length; i++) { writeSerial(*(str+i)); if (echoBack) { while(!readable()); readSerial(); } } } int UartIspBase::isRecieveStringMatch(const char* checkString) { int length = strlen(checkString); for(int i = 0; i < length; i++) { char b = readSerial(); if (b != *(checkString+i)) { return 0; // Not matched } } return 1; // Matched } int UartIspBase::openIsp(int mcufreq) { // Sequence of synchronization for MCU uart for (int i = 0; i < SYNC_RETRY_NUM; i++) { if (i > 0) { sleep(3000); } // step 1 writeSerial('?'); if (!isRecieveStringMatch("Synchronized\r\n")) { writeString("\n"); continue; } // step 2 writeString("Synchronized\n"); if (!isRecieveStringMatch("OK\r\n")) { writeString("\n"); continue; } // step 3 char str[32]; sprintf(str, "%d\n", mcufreq); writeString(str); if (!isRecieveStringMatch("OK\r\n")) { writeString("\n"); continue; } return RETURN_NORMAL; } // when MCU does not sync return RETURN_FAULT; } int UartIspBase::unlockFlash() { // Unlock Flash Write and Erase writeString("U 23130\n"); if (!isRecieveStringMatch("0\r\n")) { return RETURN_FAULT; } return RETURN_NORMAL; } int UartIspBase::eraseFlash(int startSector, int endSector) { // Prepare command char str[32]; sprintf(str, "P %d %d\n", startSector, endSector); writeString(str); if (!isRecieveStringMatch("0\r\n")) { return RETURN_FAULT; } // Erase command (All sectors) sprintf(str, "E %d %d\n", startSector, endSector); writeString(str); if (!isRecieveStringMatch("0\r\n")) { return RETURN_FAULT; } return RETURN_NORMAL; } int UartIspBase::writeToRam(char buffer[], unsigned int ramAddress, int length) { int normalizeLength = ((length + 2) / 3) * 3; // normalize multiples of 3 unsigned int checksum = 0; unsigned int data3bytes = 0; int bufPos = 0; int lineNum = 0; int lineBytes; char str[32]; // Send W command sprintf(str, "W %d %d\n", ramAddress, length); writeString(str); if (!isRecieveStringMatch("0\r\n")) { writeSerial(0x1B); // send ESC return RETURN_FAULT; } while (bufPos < length) { // the number of sending bytes of a line if (bufPos <= length - UUENCODE_LINE_BYTES) { lineBytes = UUENCODE_LINE_BYTES; writeString(getUuString(lineBytes)); } else { lineBytes = normalizeLength - bufPos; writeString(getUuString(length - bufPos)); } // send data of a line for (int i = 0; i < lineBytes; i++) { unsigned char data; if (bufPos + i < length) { data = buffer[bufPos + i]; } else { data = 0; } checksum += data; // Encode uuencode data and store array if ((i % 3) == 0) { data3bytes = data; } else { data3bytes = (data3bytes << 8) + data; } if ((i % 3) == 2) { writeString(getUuString( (data3bytes >> 18) & 0x3F ) ); writeString(getUuString( (data3bytes >> 12) & 0x3F ) ); writeString(getUuString( (data3bytes >> 6) & 0x3F ) ); writeString(getUuString( (data3bytes) & 0x3F ) ); } } writeString("\n"); lineNum++; bufPos += UUENCODE_LINE_BYTES; if (bufPos >= length || (lineNum % 20) == 0) { sprintf(str, "%d\n", checksum); writeString(str); if (echoBack) { // workaround for response (UART ISP bug?) if (!isRecieveStringMatch("OK\r\n")) { writeSerial(0x1B); // send ESC return RETURN_FAULT; } } else { if (!isRecieveStringMatch("0\r\n")) { writeSerial(0x1B); // send ESC return RETURN_FAULT; } } checksum = 0; } } return RETURN_NORMAL; } int UartIspBase::prepareFlash(int startSector, int endSector) { // Send P command char str[32]; sprintf(str, "P %d %d\n", startSector, endSector); writeString(str); if (!isRecieveStringMatch("0\r\n")) { writeSerial(0x1B); // send ESC return RETURN_FAULT; } return RETURN_NORMAL; } int UartIspBase::copyToFlash(unsigned int flashAddress, unsigned int ramAddress, int length) { // Copy program data from RAM to Flash char str[32]; sprintf(str, "C %d %d %d\n", flashAddress, ramAddress, length); writeString(str); if (!isRecieveStringMatch("0\r\n")) { writeSerial(0x1B); // send ESC return RETURN_FAULT; } // Verify RAM and Flash data if (flashAddress < 64) { sprintf(str, "M 64 %d %d\n", ramAddress + 64, length - 64); } else { sprintf(str, "M %d %d %d\n", flashAddress, ramAddress, length); } writeString(str); if (!isRecieveStringMatch("0\r\n")) { writeSerial(0x1B); // send ESC return RETURN_FAULT; } return RETURN_NORMAL; }