IJFW - IchigoJamのBASICプログラムをメモリカード(MMCまたは互換カード)に保存したり読み出したりできるプログラム。メモリカードにファームウェアのファイルを置くだけで、電源ON時に自動的に書き換える機能も搭載(一応こちらがメイン)。LPC1114FN28専用。
I2c2mem.cpp
00001 #include "I2c2mem.h" 00002 #include "mbed.h" 00003 #include "I2CSlave2.h" 00004 #include "FatfsIjfwConfigurable.h" 00005 00006 const int PROGRAM_BYTES_MAX = 1024; 00007 const int PROGRAM_NUM_MAX = 128; 00008 const int DATA_BYTES_MAX = 512; 00009 const char* DATA_FILENAME = "ijdata.dat"; 00010 const int DATA_FILENUM_MAX = 1023; 00011 00012 const int RETURN_NORMAL = 1; 00013 const int RETURN_ERROR = 0; 00014 00015 00016 I2c2mem::I2c2mem(I2CSlave2* _i2cs, FatfsIjfwConfigurable* _fs, DigitalOut* _ledcard) 00017 : i2cs(_i2cs), fs(_fs), ledcard(_ledcard) { 00018 buffer = new char[PROGRAM_BYTES_MAX]; 00019 address = 0; 00020 address_old = 0; 00021 count = 0; 00022 dataBytesCount = 0; 00023 dataFileNum = 0; 00024 } 00025 00026 00027 I2c2mem::~I2c2mem(){ 00028 delete [] buffer; 00029 } 00030 00031 00032 // Write a BASIC program to memory card 00033 int I2c2mem::writeProgram(int flag){ 00034 ledcard->write(1); 00035 00036 // Receive I2C data ( 00037 char bufi2c[36]; 00038 int length = i2cs->read(bufi2c, 36) - 1; 00039 00040 if (length == 2 || length == 34) { 00041 // Calculate memory address in EEPROM 00042 address = 0x10000 * flag; // This flag expresses 64-127 block 00043 address |= (bufi2c[0] << 8) | bufi2c[1]; 00044 00045 // if command is "FILES" 00046 if (address != address_old + 32) { 00047 count = 0; 00048 } 00049 address_old = address; 00050 00051 // BAS file name 00052 if (count == 0) { 00053 int filenum = ((address / PROGRAM_BYTES_MAX) % PROGRAM_NUM_MAX) + 100; 00054 sprintf(filename, "ij%03d.bas", filenum); 00055 } 00056 } else { // Not match 2 nor 34 00057 i2cs->stop(); 00058 count = 0; 00059 ledcard->write(0); 00060 return RETURN_ERROR; 00061 } 00062 00063 if (length == 34) { 00064 for (int i = 0; i < 32; i++) { 00065 buffer[count + i] = bufi2c[i + 2]; 00066 } 00067 count += 32; 00068 00069 if (count >= PROGRAM_BYTES_MAX) { 00070 count = 0; 00071 fs->mount(); 00072 int res = fs->openBas(filename, MODE_OVERWRITE); 00073 if (res != FR_OK) { 00074 ledcard->write(0); 00075 return RETURN_ERROR; 00076 } 00077 00078 fs->write(buffer, PROGRAM_BYTES_MAX); 00079 fs->close(); 00080 } 00081 } 00082 00083 ledcard->write(0); 00084 return RETURN_NORMAL; 00085 } 00086 00087 00088 // Read a BASIC program from memory card 00089 int I2c2mem::readProgram() { 00090 ledcard->write(1); 00091 00092 if (count == 0) { 00093 fs->mount(); 00094 int res = fs->openBas(filename, MODE_RO); 00095 if (res != FR_OK) { 00096 i2cs->stop(); 00097 ledcard->write(0); 00098 return RETURN_ERROR; 00099 } 00100 if (fs->read(buffer, PROGRAM_BYTES_MAX) != PROGRAM_BYTES_MAX) { 00101 fs->close(); 00102 i2cs->stop(); 00103 ledcard->write(0); 00104 return RETURN_ERROR; 00105 } 00106 fs->close(); 00107 } 00108 00109 char bufi2c[32]; 00110 for (int i = 0; i < 32; i++) { 00111 bufi2c[i] = buffer[count + i]; 00112 } 00113 00114 if (i2cs->write(bufi2c, 32) != 32) { 00115 i2cs->stop(); 00116 count = 0; 00117 ledcard->write(0); 00118 return RETURN_ERROR; 00119 } 00120 count += 32; 00121 00122 if (count >= PROGRAM_BYTES_MAX) { 00123 i2cs->stop(); 00124 count = 0; 00125 } 00126 00127 ledcard->write(0); 00128 return RETURN_NORMAL; 00129 } 00130 00131 00132 // Write a I2C data to memory card 00133 int I2c2mem::writeData() 00134 { 00135 ledcard->write(1); 00136 00137 // Data from master 00138 char bufi2c[DATA_BYTES_MAX+2]; 00139 int length = i2cs->read(bufi2c, DATA_BYTES_MAX+2) - 1; 00140 // The reason of "DATA_BYTES_MAX+2" is the one is "command byte" 00141 // from IchigoJam and the other is caused by behavior of i2c_api 00142 00143 if (length == 1) { // when "i2cr" instruction 00144 count = 1; 00145 return RETURN_NORMAL; 00146 } else { 00147 count = 0; 00148 } 00149 00150 length--; // decresement the number of command bytes 00151 if (length > DATA_BYTES_MAX) { 00152 length = DATA_BYTES_MAX; 00153 } 00154 00155 // Write data to memory card 00156 fs->mount(); 00157 int res = fs->open(DATA_FILENAME, MODE_OVERWRITE); 00158 if (res != FR_OK) { 00159 ledcard->write(0); 00160 return RETURN_ERROR; 00161 } 00162 fs->write(&bufi2c[1], length); 00163 fs->close(); 00164 00165 ledcard->write(0); 00166 return RETURN_NORMAL; 00167 } 00168 00169 00170 // Read a I2C data to memory card 00171 int I2c2mem::readData() 00172 { 00173 ledcard->write(1); 00174 00175 if (count != 1) { 00176 i2cs->stop(); 00177 count = 0; 00178 ledcard->write(0); 00179 return RETURN_ERROR; 00180 } 00181 00182 // Read data from memory card 00183 fs->mount(); 00184 int res = fs->open(DATA_FILENAME, MODE_RO); 00185 if (res != FR_OK) { 00186 ledcard->write(0); 00187 return RETURN_ERROR; 00188 } 00189 00190 int length = fs->filesize(); 00191 if (length > DATA_BYTES_MAX) { 00192 length = DATA_BYTES_MAX; 00193 } 00194 00195 char bufi2c[DATA_BYTES_MAX]; 00196 if (fs->read(bufi2c, length) != length) { 00197 fs->close(); 00198 ledcard->write(0); 00199 return RETURN_ERROR; 00200 } 00201 fs->close(); 00202 00203 // Send to master 00204 i2cs->write(bufi2c, length); 00205 00206 count = 0; 00207 ledcard->write(0); 00208 return RETURN_NORMAL; 00209 } 00210 00211 00212 // Write a I2C data to memory card card (Continuous writting mode) 00213 int I2c2mem::writeDataContinuous() 00214 { 00215 // Data from master 00216 char bufi2c[DATA_BYTES_MAX+2]; 00217 int length = i2cs->read(bufi2c, DATA_BYTES_MAX+2) - 1; 00218 00219 length--; // decresement the number of command bytes 00220 if (length > DATA_BYTES_MAX) { 00221 length = DATA_BYTES_MAX; 00222 } 00223 00224 for (int i = 0; i < length; i++) { 00225 buffer[dataBytesCount + i] = bufi2c[i + 1]; 00226 } 00227 00228 dataBytesCount += length; 00229 if (dataBytesCount < DATA_BYTES_MAX) { 00230 return RETURN_NORMAL; 00231 } 00232 00233 // Write data to memory card 00234 ledcard->write(1); 00235 fs->mount(); 00236 fs->mkdir("data"); 00237 00238 sprintf(filename, "/data/%04d.dat", dataFileNum); 00239 int res = fs->open(filename, MODE_APPEND); 00240 if (res != FR_OK) { 00241 ledcard->write(0); 00242 return RETURN_ERROR; 00243 } 00244 00245 int datafilesize = fs->filesize(); 00246 if (datafilesize > 1024*1024) { 00247 fs->close(); 00248 dataFileNum++; 00249 if (dataFileNum > DATA_FILENUM_MAX) { 00250 dataFileNum = 0; 00251 } 00252 sprintf(filename, "/data/%04d.dat", dataFileNum); 00253 res = fs->open(filename, MODE_OVERWRITE); 00254 if (res != FR_OK) { 00255 ledcard->write(0); 00256 return RETURN_ERROR; 00257 } 00258 } 00259 00260 fs->write(buffer, dataBytesCount); 00261 fs->close(); 00262 dataBytesCount = 0; 00263 ledcard->write(0); 00264 00265 return RETURN_NORMAL; 00266 } 00267 00268 00269 int I2c2mem::reset() 00270 { 00271 i2cs->stop(); 00272 00273 // If there is data remaining in the buffer, it is written to memory card. 00274 if (dataBytesCount != 0) { 00275 ledcard->write(1); 00276 fs->mount(); 00277 00278 sprintf(filename, "/data/%04d.dat", dataFileNum); 00279 int res = fs->open(filename, MODE_APPEND); 00280 if (res != FR_OK) { 00281 ledcard->write(0); 00282 return RETURN_ERROR; 00283 } 00284 00285 int datafilesize = fs->filesize(); 00286 if (datafilesize > 1024*1024) { 00287 fs->close(); 00288 dataFileNum++; 00289 if (dataFileNum > DATA_FILENUM_MAX) { 00290 dataFileNum = 0; 00291 } 00292 sprintf(filename, "/data/%04d.dat", dataFileNum); 00293 res = fs->open(filename, MODE_OVERWRITE); 00294 if (res != FR_OK) { 00295 ledcard->write(0); 00296 return RETURN_ERROR; 00297 } 00298 } 00299 00300 fs->write(buffer, dataBytesCount); 00301 fs->close(); 00302 ledcard->write(0); 00303 } 00304 00305 address = 0; 00306 address_old = 0; 00307 count = 0; 00308 dataBytesCount = 0; 00309 dataFileNum = 0; 00310 00311 return RETURN_NORMAL; 00312 } 00313
Generated on Sat Jul 16 2022 19:47:26 by 1.7.2