IJFW - IchigoJamのBASICプログラムをメモリカード(MMCまたは互換カード)に保存したり読み出したりできるプログラム。メモリカードにファームウェアのファイルを置くだけで、電源ON時に自動的に書き換える機能も搭載(一応こちらがメイン)。LPC1114FN28専用。
UartIspBase.cpp
00001 #include "UartIspBase.h" 00002 #include <stdio.h> 00003 #include <string.h> 00004 00005 const int SYNC_RETRY_NUM = 3; 00006 const int UUENCODE_LINE_BYTES = 45; // must be multiples of 3 00007 const int RETURN_NORMAL = 1; 00008 const int RETURN_FAULT = 0; 00009 00010 00011 UartIspBase::UartIspBase() { 00012 // echoback setting 00013 echoBack = 1; 00014 00015 // Generate UUEncode Table 00016 uuCharTable[0] = 0x60; 00017 for (int i = 1; i < 64; i++) { 00018 uuCharTable[i] = i + 32; 00019 } 00020 } 00021 00022 00023 UartIspBase::~UartIspBase() { 00024 00025 } 00026 00027 00028 char UartIspBase::getUuString(int i) { 00029 return uuCharTable[i % 64]; 00030 } 00031 00032 00033 void UartIspBase::disableEchoBack() { 00034 writeString("A 0\n"); 00035 echoBack = 0; 00036 } 00037 00038 00039 void UartIspBase::writeString(const char val) { 00040 writeSerial(val); 00041 if (echoBack) { 00042 readSerial(); 00043 } 00044 } 00045 00046 00047 void UartIspBase::writeString(const char* str) { 00048 int length = strlen(str); 00049 for (int i = 0; i < length; i++) { 00050 writeSerial(*(str+i)); 00051 00052 if (echoBack) { 00053 while(!readable()); 00054 readSerial(); 00055 } 00056 } 00057 } 00058 00059 00060 int UartIspBase::isRecieveStringMatch(const char* checkString) { 00061 int length = strlen(checkString); 00062 00063 for(int i = 0; i < length; i++) { 00064 char b = readSerial(); 00065 if (b != *(checkString+i)) { 00066 return 0; // Not matched 00067 } 00068 } 00069 00070 return 1; // Matched 00071 } 00072 00073 00074 int UartIspBase::openIsp(int mcufreq) { 00075 // Sequence of synchronization for MCU uart 00076 for (int i = 0; i < SYNC_RETRY_NUM; i++) { 00077 if (i > 0) { 00078 sleep(3000); 00079 } 00080 // step 1 00081 writeSerial('?'); 00082 if (!isRecieveStringMatch("Synchronized\r\n")) { 00083 writeString("\n"); 00084 continue; 00085 } 00086 // step 2 00087 writeString("Synchronized\n"); 00088 if (!isRecieveStringMatch("OK\r\n")) { 00089 writeString("\n"); 00090 continue; 00091 } 00092 // step 3 00093 char str[32]; 00094 sprintf(str, "%d\n", mcufreq); 00095 writeString(str); 00096 if (!isRecieveStringMatch("OK\r\n")) { 00097 writeString("\n"); 00098 continue; 00099 } 00100 return RETURN_NORMAL; 00101 } 00102 // when MCU does not sync 00103 return RETURN_FAULT; 00104 } 00105 00106 00107 int UartIspBase::unlockFlash() { 00108 // Unlock Flash Write and Erase 00109 writeString("U 23130\n"); 00110 if (!isRecieveStringMatch("0\r\n")) { 00111 return RETURN_FAULT; 00112 } 00113 return RETURN_NORMAL; 00114 } 00115 00116 00117 int UartIspBase::eraseFlash(int startSector, int endSector) { 00118 // Prepare command 00119 char str[32]; 00120 sprintf(str, "P %d %d\n", startSector, endSector); 00121 writeString(str); 00122 if (!isRecieveStringMatch("0\r\n")) { 00123 return RETURN_FAULT; 00124 } 00125 00126 // Erase command (All sectors) 00127 sprintf(str, "E %d %d\n", startSector, endSector); 00128 writeString(str); 00129 if (!isRecieveStringMatch("0\r\n")) { 00130 return RETURN_FAULT; 00131 } 00132 00133 return RETURN_NORMAL; 00134 } 00135 00136 00137 int UartIspBase::writeToRam(char buffer[], unsigned int ramAddress, int length) { 00138 int normalizeLength = ((length + 2) / 3) * 3; // normalize multiples of 3 00139 unsigned int checksum = 0; 00140 unsigned int data3bytes = 0; 00141 int bufPos = 0; 00142 int lineNum = 0; 00143 int lineBytes; 00144 char str[32]; 00145 00146 // Send W command 00147 sprintf(str, "W %d %d\n", ramAddress, length); 00148 writeString(str); 00149 if (!isRecieveStringMatch("0\r\n")) { 00150 writeSerial(0x1B); // send ESC 00151 return RETURN_FAULT; 00152 } 00153 00154 while (bufPos < length) { 00155 // the number of sending bytes of a line 00156 if (bufPos <= length - UUENCODE_LINE_BYTES) { 00157 lineBytes = UUENCODE_LINE_BYTES; 00158 writeString(getUuString(lineBytes)); 00159 } else { 00160 lineBytes = normalizeLength - bufPos; 00161 writeString(getUuString(length - bufPos)); 00162 } 00163 00164 // send data of a line 00165 for (int i = 0; i < lineBytes; i++) { 00166 unsigned char data; 00167 if (bufPos + i < length) { 00168 data = buffer[bufPos + i]; 00169 } else { 00170 data = 0; 00171 } 00172 checksum += data; 00173 00174 // Encode uuencode data and store array 00175 if ((i % 3) == 0) { 00176 data3bytes = data; 00177 } else { 00178 data3bytes = (data3bytes << 8) + data; 00179 } 00180 00181 if ((i % 3) == 2) { 00182 writeString(getUuString( (data3bytes >> 18) & 0x3F ) ); 00183 writeString(getUuString( (data3bytes >> 12) & 0x3F ) ); 00184 writeString(getUuString( (data3bytes >> 6) & 0x3F ) ); 00185 writeString(getUuString( (data3bytes) & 0x3F ) ); 00186 } 00187 } 00188 writeString("\n"); 00189 lineNum++; 00190 bufPos += UUENCODE_LINE_BYTES; 00191 00192 if (bufPos >= length || (lineNum % 20) == 0) { 00193 sprintf(str, "%d\n", checksum); 00194 writeString(str); 00195 if (echoBack) { // workaround for response (UART ISP bug?) 00196 if (!isRecieveStringMatch("OK\r\n")) { 00197 writeSerial(0x1B); // send ESC 00198 return RETURN_FAULT; 00199 } 00200 } else { 00201 if (!isRecieveStringMatch("0\r\n")) { 00202 writeSerial(0x1B); // send ESC 00203 return RETURN_FAULT; 00204 } 00205 } 00206 checksum = 0; 00207 } 00208 } 00209 00210 return RETURN_NORMAL; 00211 } 00212 00213 00214 int UartIspBase::prepareFlash(int startSector, int endSector) { 00215 // Send P command 00216 char str[32]; 00217 sprintf(str, "P %d %d\n", startSector, endSector); 00218 writeString(str); 00219 00220 if (!isRecieveStringMatch("0\r\n")) { 00221 writeSerial(0x1B); // send ESC 00222 return RETURN_FAULT; 00223 } 00224 return RETURN_NORMAL; 00225 } 00226 00227 00228 int UartIspBase::copyToFlash(unsigned int flashAddress, unsigned int ramAddress, int length) { 00229 // Copy program data from RAM to Flash 00230 char str[32]; 00231 sprintf(str, "C %d %d %d\n", flashAddress, ramAddress, length); 00232 writeString(str); 00233 00234 if (!isRecieveStringMatch("0\r\n")) { 00235 writeSerial(0x1B); // send ESC 00236 return RETURN_FAULT; 00237 } 00238 00239 // Verify RAM and Flash data 00240 if (flashAddress < 64) { 00241 sprintf(str, "M 64 %d %d\n", ramAddress + 64, length - 64); 00242 } else { 00243 sprintf(str, "M %d %d %d\n", flashAddress, ramAddress, length); 00244 } 00245 writeString(str); 00246 00247 if (!isRecieveStringMatch("0\r\n")) { 00248 writeSerial(0x1B); // send ESC 00249 return RETURN_FAULT; 00250 } 00251 00252 return RETURN_NORMAL; 00253 }
Generated on Sat Jul 16 2022 19:47:26 by 1.7.2