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

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers I2c2mem.cpp Source File

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