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

Dependencies:   mbed

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

Committer:
oks486
Date:
Sun Aug 21 07:51:01 2016 +0000
Revision:
2:daf6c4719496
Parent:
0:43cce7b453d0
Modified I2c2mem for "FILES" command

Who changed what in which revision?

UserRevisionLine numberNew contents of line
oks486 0:43cce7b453d0 1 #include "UartIspBase.h"
oks486 0:43cce7b453d0 2 #include <stdio.h>
oks486 0:43cce7b453d0 3 #include <string.h>
oks486 0:43cce7b453d0 4
oks486 0:43cce7b453d0 5 const int SYNC_RETRY_NUM = 3;
oks486 0:43cce7b453d0 6 const int UUENCODE_LINE_BYTES = 45; // must be multiples of 3
oks486 0:43cce7b453d0 7 const int RETURN_NORMAL = 1;
oks486 0:43cce7b453d0 8 const int RETURN_FAULT = 0;
oks486 0:43cce7b453d0 9
oks486 0:43cce7b453d0 10
oks486 0:43cce7b453d0 11 UartIspBase::UartIspBase() {
oks486 0:43cce7b453d0 12 // echoback setting
oks486 0:43cce7b453d0 13 echoBack = 1;
oks486 0:43cce7b453d0 14
oks486 0:43cce7b453d0 15 // Generate UUEncode Table
oks486 0:43cce7b453d0 16 uuCharTable[0] = 0x60;
oks486 0:43cce7b453d0 17 for (int i = 1; i < 64; i++) {
oks486 0:43cce7b453d0 18 uuCharTable[i] = i + 32;
oks486 0:43cce7b453d0 19 }
oks486 0:43cce7b453d0 20 }
oks486 0:43cce7b453d0 21
oks486 0:43cce7b453d0 22
oks486 0:43cce7b453d0 23 UartIspBase::~UartIspBase() {
oks486 0:43cce7b453d0 24
oks486 0:43cce7b453d0 25 }
oks486 0:43cce7b453d0 26
oks486 0:43cce7b453d0 27
oks486 0:43cce7b453d0 28 char UartIspBase::getUuString(int i) {
oks486 0:43cce7b453d0 29 return uuCharTable[i % 64];
oks486 0:43cce7b453d0 30 }
oks486 0:43cce7b453d0 31
oks486 0:43cce7b453d0 32
oks486 0:43cce7b453d0 33 void UartIspBase::disableEchoBack() {
oks486 0:43cce7b453d0 34 writeString("A 0\n");
oks486 0:43cce7b453d0 35 echoBack = 0;
oks486 0:43cce7b453d0 36 }
oks486 0:43cce7b453d0 37
oks486 0:43cce7b453d0 38
oks486 0:43cce7b453d0 39 void UartIspBase::writeString(const char val) {
oks486 0:43cce7b453d0 40 writeSerial(val);
oks486 0:43cce7b453d0 41 if (echoBack) {
oks486 0:43cce7b453d0 42 readSerial();
oks486 0:43cce7b453d0 43 }
oks486 0:43cce7b453d0 44 }
oks486 0:43cce7b453d0 45
oks486 0:43cce7b453d0 46
oks486 0:43cce7b453d0 47 void UartIspBase::writeString(const char* str) {
oks486 0:43cce7b453d0 48 int length = strlen(str);
oks486 0:43cce7b453d0 49 for (int i = 0; i < length; i++) {
oks486 0:43cce7b453d0 50 writeSerial(*(str+i));
oks486 0:43cce7b453d0 51
oks486 0:43cce7b453d0 52 if (echoBack) {
oks486 0:43cce7b453d0 53 while(!readable());
oks486 0:43cce7b453d0 54 readSerial();
oks486 0:43cce7b453d0 55 }
oks486 0:43cce7b453d0 56 }
oks486 0:43cce7b453d0 57 }
oks486 0:43cce7b453d0 58
oks486 0:43cce7b453d0 59
oks486 0:43cce7b453d0 60 int UartIspBase::isRecieveStringMatch(const char* checkString) {
oks486 0:43cce7b453d0 61 int length = strlen(checkString);
oks486 0:43cce7b453d0 62
oks486 0:43cce7b453d0 63 for(int i = 0; i < length; i++) {
oks486 0:43cce7b453d0 64 char b = readSerial();
oks486 0:43cce7b453d0 65 if (b != *(checkString+i)) {
oks486 0:43cce7b453d0 66 return 0; // Not matched
oks486 0:43cce7b453d0 67 }
oks486 0:43cce7b453d0 68 }
oks486 0:43cce7b453d0 69
oks486 0:43cce7b453d0 70 return 1; // Matched
oks486 0:43cce7b453d0 71 }
oks486 0:43cce7b453d0 72
oks486 0:43cce7b453d0 73
oks486 0:43cce7b453d0 74 int UartIspBase::openIsp(int mcufreq) {
oks486 0:43cce7b453d0 75 // Sequence of synchronization for MCU uart
oks486 0:43cce7b453d0 76 for (int i = 0; i < SYNC_RETRY_NUM; i++) {
oks486 0:43cce7b453d0 77 if (i > 0) {
oks486 0:43cce7b453d0 78 sleep(3000);
oks486 0:43cce7b453d0 79 }
oks486 0:43cce7b453d0 80 // step 1
oks486 0:43cce7b453d0 81 writeSerial('?');
oks486 0:43cce7b453d0 82 if (!isRecieveStringMatch("Synchronized\r\n")) {
oks486 0:43cce7b453d0 83 writeString("\n");
oks486 0:43cce7b453d0 84 continue;
oks486 0:43cce7b453d0 85 }
oks486 0:43cce7b453d0 86 // step 2
oks486 0:43cce7b453d0 87 writeString("Synchronized\n");
oks486 0:43cce7b453d0 88 if (!isRecieveStringMatch("OK\r\n")) {
oks486 0:43cce7b453d0 89 writeString("\n");
oks486 0:43cce7b453d0 90 continue;
oks486 0:43cce7b453d0 91 }
oks486 0:43cce7b453d0 92 // step 3
oks486 0:43cce7b453d0 93 char str[32];
oks486 0:43cce7b453d0 94 sprintf(str, "%d\n", mcufreq);
oks486 0:43cce7b453d0 95 writeString(str);
oks486 0:43cce7b453d0 96 if (!isRecieveStringMatch("OK\r\n")) {
oks486 0:43cce7b453d0 97 writeString("\n");
oks486 0:43cce7b453d0 98 continue;
oks486 0:43cce7b453d0 99 }
oks486 0:43cce7b453d0 100 return RETURN_NORMAL;
oks486 0:43cce7b453d0 101 }
oks486 0:43cce7b453d0 102 // when MCU does not sync
oks486 0:43cce7b453d0 103 return RETURN_FAULT;
oks486 0:43cce7b453d0 104 }
oks486 0:43cce7b453d0 105
oks486 0:43cce7b453d0 106
oks486 0:43cce7b453d0 107 int UartIspBase::unlockFlash() {
oks486 0:43cce7b453d0 108 // Unlock Flash Write and Erase
oks486 0:43cce7b453d0 109 writeString("U 23130\n");
oks486 0:43cce7b453d0 110 if (!isRecieveStringMatch("0\r\n")) {
oks486 0:43cce7b453d0 111 return RETURN_FAULT;
oks486 0:43cce7b453d0 112 }
oks486 0:43cce7b453d0 113 return RETURN_NORMAL;
oks486 0:43cce7b453d0 114 }
oks486 0:43cce7b453d0 115
oks486 0:43cce7b453d0 116
oks486 0:43cce7b453d0 117 int UartIspBase::eraseFlash(int startSector, int endSector) {
oks486 0:43cce7b453d0 118 // Prepare command
oks486 0:43cce7b453d0 119 char str[32];
oks486 0:43cce7b453d0 120 sprintf(str, "P %d %d\n", startSector, endSector);
oks486 0:43cce7b453d0 121 writeString(str);
oks486 0:43cce7b453d0 122 if (!isRecieveStringMatch("0\r\n")) {
oks486 0:43cce7b453d0 123 return RETURN_FAULT;
oks486 0:43cce7b453d0 124 }
oks486 0:43cce7b453d0 125
oks486 0:43cce7b453d0 126 // Erase command (All sectors)
oks486 0:43cce7b453d0 127 sprintf(str, "E %d %d\n", startSector, endSector);
oks486 0:43cce7b453d0 128 writeString(str);
oks486 0:43cce7b453d0 129 if (!isRecieveStringMatch("0\r\n")) {
oks486 0:43cce7b453d0 130 return RETURN_FAULT;
oks486 0:43cce7b453d0 131 }
oks486 0:43cce7b453d0 132
oks486 0:43cce7b453d0 133 return RETURN_NORMAL;
oks486 0:43cce7b453d0 134 }
oks486 0:43cce7b453d0 135
oks486 0:43cce7b453d0 136
oks486 0:43cce7b453d0 137 int UartIspBase::writeToRam(char buffer[], unsigned int ramAddress, int length) {
oks486 0:43cce7b453d0 138 int normalizeLength = ((length + 2) / 3) * 3; // normalize multiples of 3
oks486 0:43cce7b453d0 139 unsigned int checksum = 0;
oks486 0:43cce7b453d0 140 unsigned int data3bytes = 0;
oks486 0:43cce7b453d0 141 int bufPos = 0;
oks486 0:43cce7b453d0 142 int lineNum = 0;
oks486 0:43cce7b453d0 143 int lineBytes;
oks486 0:43cce7b453d0 144 char str[32];
oks486 0:43cce7b453d0 145
oks486 0:43cce7b453d0 146 // Send W command
oks486 0:43cce7b453d0 147 sprintf(str, "W %d %d\n", ramAddress, length);
oks486 0:43cce7b453d0 148 writeString(str);
oks486 0:43cce7b453d0 149 if (!isRecieveStringMatch("0\r\n")) {
oks486 0:43cce7b453d0 150 writeSerial(0x1B); // send ESC
oks486 0:43cce7b453d0 151 return RETURN_FAULT;
oks486 0:43cce7b453d0 152 }
oks486 0:43cce7b453d0 153
oks486 0:43cce7b453d0 154 while (bufPos < length) {
oks486 0:43cce7b453d0 155 // the number of sending bytes of a line
oks486 0:43cce7b453d0 156 if (bufPos <= length - UUENCODE_LINE_BYTES) {
oks486 0:43cce7b453d0 157 lineBytes = UUENCODE_LINE_BYTES;
oks486 0:43cce7b453d0 158 writeString(getUuString(lineBytes));
oks486 0:43cce7b453d0 159 } else {
oks486 0:43cce7b453d0 160 lineBytes = normalizeLength - bufPos;
oks486 0:43cce7b453d0 161 writeString(getUuString(length - bufPos));
oks486 0:43cce7b453d0 162 }
oks486 0:43cce7b453d0 163
oks486 0:43cce7b453d0 164 // send data of a line
oks486 0:43cce7b453d0 165 for (int i = 0; i < lineBytes; i++) {
oks486 0:43cce7b453d0 166 unsigned char data;
oks486 0:43cce7b453d0 167 if (bufPos + i < length) {
oks486 0:43cce7b453d0 168 data = buffer[bufPos + i];
oks486 0:43cce7b453d0 169 } else {
oks486 0:43cce7b453d0 170 data = 0;
oks486 0:43cce7b453d0 171 }
oks486 0:43cce7b453d0 172 checksum += data;
oks486 0:43cce7b453d0 173
oks486 0:43cce7b453d0 174 // Encode uuencode data and store array
oks486 0:43cce7b453d0 175 if ((i % 3) == 0) {
oks486 0:43cce7b453d0 176 data3bytes = data;
oks486 0:43cce7b453d0 177 } else {
oks486 0:43cce7b453d0 178 data3bytes = (data3bytes << 8) + data;
oks486 0:43cce7b453d0 179 }
oks486 0:43cce7b453d0 180
oks486 0:43cce7b453d0 181 if ((i % 3) == 2) {
oks486 0:43cce7b453d0 182 writeString(getUuString( (data3bytes >> 18) & 0x3F ) );
oks486 0:43cce7b453d0 183 writeString(getUuString( (data3bytes >> 12) & 0x3F ) );
oks486 0:43cce7b453d0 184 writeString(getUuString( (data3bytes >> 6) & 0x3F ) );
oks486 0:43cce7b453d0 185 writeString(getUuString( (data3bytes) & 0x3F ) );
oks486 0:43cce7b453d0 186 }
oks486 0:43cce7b453d0 187 }
oks486 0:43cce7b453d0 188 writeString("\n");
oks486 0:43cce7b453d0 189 lineNum++;
oks486 0:43cce7b453d0 190 bufPos += UUENCODE_LINE_BYTES;
oks486 0:43cce7b453d0 191
oks486 0:43cce7b453d0 192 if (bufPos >= length || (lineNum % 20) == 0) {
oks486 0:43cce7b453d0 193 sprintf(str, "%d\n", checksum);
oks486 0:43cce7b453d0 194 writeString(str);
oks486 0:43cce7b453d0 195 if (echoBack) { // workaround for response (UART ISP bug?)
oks486 0:43cce7b453d0 196 if (!isRecieveStringMatch("OK\r\n")) {
oks486 0:43cce7b453d0 197 writeSerial(0x1B); // send ESC
oks486 0:43cce7b453d0 198 return RETURN_FAULT;
oks486 0:43cce7b453d0 199 }
oks486 0:43cce7b453d0 200 } else {
oks486 0:43cce7b453d0 201 if (!isRecieveStringMatch("0\r\n")) {
oks486 0:43cce7b453d0 202 writeSerial(0x1B); // send ESC
oks486 0:43cce7b453d0 203 return RETURN_FAULT;
oks486 0:43cce7b453d0 204 }
oks486 0:43cce7b453d0 205 }
oks486 0:43cce7b453d0 206 checksum = 0;
oks486 0:43cce7b453d0 207 }
oks486 0:43cce7b453d0 208 }
oks486 0:43cce7b453d0 209
oks486 0:43cce7b453d0 210 return RETURN_NORMAL;
oks486 0:43cce7b453d0 211 }
oks486 0:43cce7b453d0 212
oks486 0:43cce7b453d0 213
oks486 0:43cce7b453d0 214 int UartIspBase::prepareFlash(int startSector, int endSector) {
oks486 0:43cce7b453d0 215 // Send P command
oks486 0:43cce7b453d0 216 char str[32];
oks486 0:43cce7b453d0 217 sprintf(str, "P %d %d\n", startSector, endSector);
oks486 0:43cce7b453d0 218 writeString(str);
oks486 0:43cce7b453d0 219
oks486 0:43cce7b453d0 220 if (!isRecieveStringMatch("0\r\n")) {
oks486 0:43cce7b453d0 221 writeSerial(0x1B); // send ESC
oks486 0:43cce7b453d0 222 return RETURN_FAULT;
oks486 0:43cce7b453d0 223 }
oks486 0:43cce7b453d0 224 return RETURN_NORMAL;
oks486 0:43cce7b453d0 225 }
oks486 0:43cce7b453d0 226
oks486 0:43cce7b453d0 227
oks486 0:43cce7b453d0 228 int UartIspBase::copyToFlash(unsigned int flashAddress, unsigned int ramAddress, int length) {
oks486 0:43cce7b453d0 229 // Copy program data from RAM to Flash
oks486 0:43cce7b453d0 230 char str[32];
oks486 0:43cce7b453d0 231 sprintf(str, "C %d %d %d\n", flashAddress, ramAddress, length);
oks486 0:43cce7b453d0 232 writeString(str);
oks486 0:43cce7b453d0 233
oks486 0:43cce7b453d0 234 if (!isRecieveStringMatch("0\r\n")) {
oks486 0:43cce7b453d0 235 writeSerial(0x1B); // send ESC
oks486 0:43cce7b453d0 236 return RETURN_FAULT;
oks486 0:43cce7b453d0 237 }
oks486 0:43cce7b453d0 238
oks486 0:43cce7b453d0 239 // Verify RAM and Flash data
oks486 0:43cce7b453d0 240 if (flashAddress < 64) {
oks486 0:43cce7b453d0 241 sprintf(str, "M 64 %d %d\n", ramAddress + 64, length - 64);
oks486 0:43cce7b453d0 242 } else {
oks486 0:43cce7b453d0 243 sprintf(str, "M %d %d %d\n", flashAddress, ramAddress, length);
oks486 0:43cce7b453d0 244 }
oks486 0:43cce7b453d0 245 writeString(str);
oks486 0:43cce7b453d0 246
oks486 0:43cce7b453d0 247 if (!isRecieveStringMatch("0\r\n")) {
oks486 0:43cce7b453d0 248 writeSerial(0x1B); // send ESC
oks486 0:43cce7b453d0 249 return RETURN_FAULT;
oks486 0:43cce7b453d0 250 }
oks486 0:43cce7b453d0 251
oks486 0:43cce7b453d0 252 return RETURN_NORMAL;
oks486 0:43cce7b453d0 253 }