IJFW - IchigoJamのBASICプログラムをメモリカード(MMCまたは互換カード)に保存したり読み出したりできるプログラム。メモリカードにファームウェアのファイルを置くだけで、電源ON時に自動的に書き換える機能も搭載(一応こちらがメイン)。LPC1114FN28専用。
参考URL http://www.cyberchabudai.org/index.php/entry?tag=IJFW
I2c2mem/I2c2mem.cpp
- Committer:
- oks486
- Date:
- 2016-08-21
- Revision:
- 2:daf6c4719496
- Parent:
- 1:11f73f269fdc
File content as of revision 2:daf6c4719496:
#include "I2c2mem.h" #include "mbed.h" #include "I2CSlave2.h" #include "FatfsIjfwConfigurable.h" const int PROGRAM_BYTES_MAX = 1024; const int PROGRAM_NUM_MAX = 128; const int DATA_BYTES_MAX = 512; const char* DATA_FILENAME = "ijdata.dat"; const int DATA_FILENUM_MAX = 1023; const int RETURN_NORMAL = 1; const int RETURN_ERROR = 0; I2c2mem::I2c2mem(I2CSlave2* _i2cs, FatfsIjfwConfigurable* _fs, DigitalOut* _ledcard) : i2cs(_i2cs), fs(_fs), ledcard(_ledcard) { buffer = new char[PROGRAM_BYTES_MAX]; address = 0; address_old = 0; count = 0; dataBytesCount = 0; dataFileNum = 0; } I2c2mem::~I2c2mem(){ delete [] buffer; } // Write a BASIC program to memory card int I2c2mem::writeProgram(int flag){ ledcard->write(1); // Receive I2C data ( char bufi2c[36]; int length = i2cs->read(bufi2c, 36) - 1; if (length == 2 || length == 34) { // Calculate memory address in EEPROM address = 0x10000 * flag; // This flag expresses 64-127 block address |= (bufi2c[0] << 8) | bufi2c[1]; // if command is "FILES" if (address != address_old + 32) { count = 0; } address_old = address; // BAS file name if (count == 0) { int filenum = ((address / PROGRAM_BYTES_MAX) % PROGRAM_NUM_MAX) + 100; sprintf(filename, "ij%03d.bas", filenum); } } else { // Not match 2 nor 34 i2cs->stop(); count = 0; ledcard->write(0); return RETURN_ERROR; } if (length == 34) { for (int i = 0; i < 32; i++) { buffer[count + i] = bufi2c[i + 2]; } count += 32; if (count >= PROGRAM_BYTES_MAX) { count = 0; fs->mount(); int res = fs->openBas(filename, MODE_OVERWRITE); if (res != FR_OK) { ledcard->write(0); return RETURN_ERROR; } fs->write(buffer, PROGRAM_BYTES_MAX); fs->close(); } } ledcard->write(0); return RETURN_NORMAL; } // Read a BASIC program from memory card int I2c2mem::readProgram() { ledcard->write(1); if (count == 0) { fs->mount(); int res = fs->openBas(filename, MODE_RO); if (res != FR_OK) { i2cs->stop(); ledcard->write(0); return RETURN_ERROR; } if (fs->read(buffer, PROGRAM_BYTES_MAX) != PROGRAM_BYTES_MAX) { fs->close(); i2cs->stop(); ledcard->write(0); return RETURN_ERROR; } fs->close(); } char bufi2c[32]; for (int i = 0; i < 32; i++) { bufi2c[i] = buffer[count + i]; } if (i2cs->write(bufi2c, 32) != 32) { i2cs->stop(); count = 0; ledcard->write(0); return RETURN_ERROR; } count += 32; if (count >= PROGRAM_BYTES_MAX) { i2cs->stop(); count = 0; } ledcard->write(0); return RETURN_NORMAL; } // Write a I2C data to memory card int I2c2mem::writeData() { ledcard->write(1); // Data from master char bufi2c[DATA_BYTES_MAX+2]; int length = i2cs->read(bufi2c, DATA_BYTES_MAX+2) - 1; // The reason of "DATA_BYTES_MAX+2" is the one is "command byte" // from IchigoJam and the other is caused by behavior of i2c_api if (length == 1) { // when "i2cr" instruction count = 1; return RETURN_NORMAL; } else { count = 0; } length--; // decresement the number of command bytes if (length > DATA_BYTES_MAX) { length = DATA_BYTES_MAX; } // Write data to memory card fs->mount(); int res = fs->open(DATA_FILENAME, MODE_OVERWRITE); if (res != FR_OK) { ledcard->write(0); return RETURN_ERROR; } fs->write(&bufi2c[1], length); fs->close(); ledcard->write(0); return RETURN_NORMAL; } // Read a I2C data to memory card int I2c2mem::readData() { ledcard->write(1); if (count != 1) { i2cs->stop(); count = 0; ledcard->write(0); return RETURN_ERROR; } // Read data from memory card fs->mount(); int res = fs->open(DATA_FILENAME, MODE_RO); if (res != FR_OK) { ledcard->write(0); return RETURN_ERROR; } int length = fs->filesize(); if (length > DATA_BYTES_MAX) { length = DATA_BYTES_MAX; } char bufi2c[DATA_BYTES_MAX]; if (fs->read(bufi2c, length) != length) { fs->close(); ledcard->write(0); return RETURN_ERROR; } fs->close(); // Send to master i2cs->write(bufi2c, length); count = 0; ledcard->write(0); return RETURN_NORMAL; } // Write a I2C data to memory card card (Continuous writting mode) int I2c2mem::writeDataContinuous() { // Data from master char bufi2c[DATA_BYTES_MAX+2]; int length = i2cs->read(bufi2c, DATA_BYTES_MAX+2) - 1; length--; // decresement the number of command bytes if (length > DATA_BYTES_MAX) { length = DATA_BYTES_MAX; } for (int i = 0; i < length; i++) { buffer[dataBytesCount + i] = bufi2c[i + 1]; } dataBytesCount += length; if (dataBytesCount < DATA_BYTES_MAX) { return RETURN_NORMAL; } // Write data to memory card ledcard->write(1); fs->mount(); fs->mkdir("data"); sprintf(filename, "/data/%04d.dat", dataFileNum); int res = fs->open(filename, MODE_APPEND); if (res != FR_OK) { ledcard->write(0); return RETURN_ERROR; } int datafilesize = fs->filesize(); if (datafilesize > 1024*1024) { fs->close(); dataFileNum++; if (dataFileNum > DATA_FILENUM_MAX) { dataFileNum = 0; } sprintf(filename, "/data/%04d.dat", dataFileNum); res = fs->open(filename, MODE_OVERWRITE); if (res != FR_OK) { ledcard->write(0); return RETURN_ERROR; } } fs->write(buffer, dataBytesCount); fs->close(); dataBytesCount = 0; ledcard->write(0); return RETURN_NORMAL; } int I2c2mem::reset() { i2cs->stop(); // If there is data remaining in the buffer, it is written to memory card. if (dataBytesCount != 0) { ledcard->write(1); fs->mount(); sprintf(filename, "/data/%04d.dat", dataFileNum); int res = fs->open(filename, MODE_APPEND); if (res != FR_OK) { ledcard->write(0); return RETURN_ERROR; } int datafilesize = fs->filesize(); if (datafilesize > 1024*1024) { fs->close(); dataFileNum++; if (dataFileNum > DATA_FILENUM_MAX) { dataFileNum = 0; } sprintf(filename, "/data/%04d.dat", dataFileNum); res = fs->open(filename, MODE_OVERWRITE); if (res != FR_OK) { ledcard->write(0); return RETURN_ERROR; } } fs->write(buffer, dataBytesCount); fs->close(); ledcard->write(0); } address = 0; address_old = 0; count = 0; dataBytesCount = 0; dataFileNum = 0; return RETURN_NORMAL; }