IJFW - IchigoJamのBASICプログラムをメモリカード(MMCまたは互換カード)に保存したり読み出したりできるプログラム。メモリカードにファームウェアのファイルを置くだけで、電源ON時に自動的に書き換える機能も搭載(一応こちらがメイン)。LPC1114FN28専用。

Dependencies:   mbed

参考URL http://www.cyberchabudai.org/index.php/entry?tag=IJFW

Revision:
0:43cce7b453d0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UartIsp/UartIspBase.cpp	Thu Apr 28 11:23:24 2016 +0000
@@ -0,0 +1,253 @@
+#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;
+}