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

Dependencies:   mbed

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

Committer:
oks486
Date:
Wed Aug 17 07:19:20 2016 +0000
Revision:
1:11f73f269fdc
Parent:
0:43cce7b453d0
Child:
2:daf6c4719496
Implementation of some configurable settings

Who changed what in which revision?

UserRevisionLine numberNew contents of line
oks486 0:43cce7b453d0 1 #include "I2c2mem.h"
oks486 0:43cce7b453d0 2 #include "mbed.h"
oks486 0:43cce7b453d0 3 #include "I2CSlave2.h"
oks486 1:11f73f269fdc 4 #include "FatfsIjfwConfigurable.h"
oks486 0:43cce7b453d0 5
oks486 0:43cce7b453d0 6 const int PROGRAM_BYTES_MAX = 1024;
oks486 0:43cce7b453d0 7 const int PROGRAM_NUM_MAX = 128;
oks486 0:43cce7b453d0 8 const int DATA_BYTES_MAX = 512;
oks486 0:43cce7b453d0 9 const char* DATA_FILENAME = "ijdata.dat";
oks486 0:43cce7b453d0 10 const int DATA_FILENUM_MAX = 1023;
oks486 0:43cce7b453d0 11
oks486 0:43cce7b453d0 12 const int RETURN_NORMAL = 1;
oks486 0:43cce7b453d0 13 const int RETURN_ERROR = 0;
oks486 0:43cce7b453d0 14
oks486 0:43cce7b453d0 15
oks486 1:11f73f269fdc 16 I2c2mem::I2c2mem(I2CSlave2* _i2cs, FatfsIjfwConfigurable* _fs, DigitalOut* _ledcard)
oks486 0:43cce7b453d0 17 : i2cs(_i2cs), fs(_fs), ledcard(_ledcard) {
oks486 0:43cce7b453d0 18 buffer = new char[PROGRAM_BYTES_MAX];
oks486 0:43cce7b453d0 19 address = 0;
oks486 0:43cce7b453d0 20 count = 0;
oks486 0:43cce7b453d0 21 dataBytesCount = 0;
oks486 0:43cce7b453d0 22 dataFileNum = 0;
oks486 0:43cce7b453d0 23 }
oks486 0:43cce7b453d0 24
oks486 0:43cce7b453d0 25
oks486 0:43cce7b453d0 26 I2c2mem::~I2c2mem(){
oks486 0:43cce7b453d0 27 delete [] buffer;
oks486 0:43cce7b453d0 28 }
oks486 0:43cce7b453d0 29
oks486 0:43cce7b453d0 30
oks486 0:43cce7b453d0 31 // Write a BASIC program to memory card
oks486 0:43cce7b453d0 32 int I2c2mem::writeProgram(int flag){
oks486 0:43cce7b453d0 33 ledcard->write(1);
oks486 0:43cce7b453d0 34
oks486 0:43cce7b453d0 35 // Receive I2C data (
oks486 0:43cce7b453d0 36 char bufi2c[36];
oks486 0:43cce7b453d0 37 int length = i2cs->read(bufi2c, 36) - 1;
oks486 0:43cce7b453d0 38
oks486 0:43cce7b453d0 39 if (length == 2 || length == 34) {
oks486 0:43cce7b453d0 40 if (count == 0) {
oks486 0:43cce7b453d0 41 // Calculate memory address in EEPROM
oks486 0:43cce7b453d0 42 address = 0x10000 * flag; // This flag expresses 64-127 block
oks486 0:43cce7b453d0 43 address |= (bufi2c[0] << 8) | bufi2c[1];
oks486 0:43cce7b453d0 44 // BAS file
oks486 0:43cce7b453d0 45 int filenum = ((address / PROGRAM_BYTES_MAX) % PROGRAM_NUM_MAX) + 100;
oks486 0:43cce7b453d0 46 sprintf(filename, "ij%03d.bas", filenum);
oks486 0:43cce7b453d0 47 }
oks486 0:43cce7b453d0 48 } else { // Not match 2 nor 34
oks486 0:43cce7b453d0 49 i2cs->stop();
oks486 0:43cce7b453d0 50 count = 0;
oks486 1:11f73f269fdc 51 ledcard->write(0);
oks486 0:43cce7b453d0 52 return RETURN_ERROR;
oks486 0:43cce7b453d0 53 }
oks486 0:43cce7b453d0 54
oks486 0:43cce7b453d0 55 if (length == 34) {
oks486 0:43cce7b453d0 56 for (int i = 0; i < 32; i++) {
oks486 0:43cce7b453d0 57 buffer[count + i] = bufi2c[i + 2];
oks486 0:43cce7b453d0 58 }
oks486 0:43cce7b453d0 59 count += 32;
oks486 0:43cce7b453d0 60
oks486 0:43cce7b453d0 61 if (count >= PROGRAM_BYTES_MAX) {
oks486 0:43cce7b453d0 62 count = 0;
oks486 0:43cce7b453d0 63 fs->mount();
oks486 1:11f73f269fdc 64 int res = fs->openBas(filename, MODE_OVERWRITE);
oks486 0:43cce7b453d0 65 if (res != FR_OK) {
oks486 1:11f73f269fdc 66 ledcard->write(0);
oks486 0:43cce7b453d0 67 return RETURN_ERROR;
oks486 0:43cce7b453d0 68 }
oks486 0:43cce7b453d0 69
oks486 0:43cce7b453d0 70 fs->write(buffer, PROGRAM_BYTES_MAX);
oks486 0:43cce7b453d0 71 fs->close();
oks486 0:43cce7b453d0 72 }
oks486 0:43cce7b453d0 73 }
oks486 0:43cce7b453d0 74
oks486 0:43cce7b453d0 75 ledcard->write(0);
oks486 0:43cce7b453d0 76 return RETURN_NORMAL;
oks486 0:43cce7b453d0 77 }
oks486 0:43cce7b453d0 78
oks486 0:43cce7b453d0 79
oks486 0:43cce7b453d0 80 // Read a BASIC program from memory card
oks486 0:43cce7b453d0 81 int I2c2mem::readProgram() {
oks486 0:43cce7b453d0 82 ledcard->write(1);
oks486 0:43cce7b453d0 83
oks486 0:43cce7b453d0 84 if (count == 0) {
oks486 0:43cce7b453d0 85 fs->mount();
oks486 1:11f73f269fdc 86 int res = fs->openBas(filename, MODE_RO);
oks486 0:43cce7b453d0 87 if (res != FR_OK) {
oks486 0:43cce7b453d0 88 i2cs->stop();
oks486 1:11f73f269fdc 89 ledcard->write(0);
oks486 0:43cce7b453d0 90 return RETURN_ERROR;
oks486 0:43cce7b453d0 91 }
oks486 0:43cce7b453d0 92 if (fs->read(buffer, PROGRAM_BYTES_MAX) != PROGRAM_BYTES_MAX) {
oks486 0:43cce7b453d0 93 fs->close();
oks486 0:43cce7b453d0 94 i2cs->stop();
oks486 1:11f73f269fdc 95 ledcard->write(0);
oks486 0:43cce7b453d0 96 return RETURN_ERROR;
oks486 0:43cce7b453d0 97 }
oks486 0:43cce7b453d0 98 fs->close();
oks486 0:43cce7b453d0 99 }
oks486 0:43cce7b453d0 100
oks486 0:43cce7b453d0 101 char bufi2c[32];
oks486 0:43cce7b453d0 102 for (int i = 0; i < 32; i++) {
oks486 0:43cce7b453d0 103 bufi2c[i] = buffer[count + i];
oks486 0:43cce7b453d0 104 }
oks486 0:43cce7b453d0 105
oks486 0:43cce7b453d0 106 if (i2cs->write(bufi2c, 32) != 32) {
oks486 0:43cce7b453d0 107 i2cs->stop();
oks486 0:43cce7b453d0 108 count = 0;
oks486 1:11f73f269fdc 109 ledcard->write(0);
oks486 0:43cce7b453d0 110 return RETURN_ERROR;
oks486 0:43cce7b453d0 111 }
oks486 0:43cce7b453d0 112 count += 32;
oks486 0:43cce7b453d0 113
oks486 0:43cce7b453d0 114 if (count >= PROGRAM_BYTES_MAX) {
oks486 0:43cce7b453d0 115 i2cs->stop();
oks486 0:43cce7b453d0 116 count = 0;
oks486 0:43cce7b453d0 117 }
oks486 0:43cce7b453d0 118
oks486 0:43cce7b453d0 119 ledcard->write(0);
oks486 0:43cce7b453d0 120 return RETURN_NORMAL;
oks486 0:43cce7b453d0 121 }
oks486 0:43cce7b453d0 122
oks486 0:43cce7b453d0 123
oks486 0:43cce7b453d0 124 // Write a I2C data to memory card
oks486 0:43cce7b453d0 125 int I2c2mem::writeData()
oks486 0:43cce7b453d0 126 {
oks486 0:43cce7b453d0 127 ledcard->write(1);
oks486 0:43cce7b453d0 128
oks486 0:43cce7b453d0 129 // Data from master
oks486 0:43cce7b453d0 130 char bufi2c[DATA_BYTES_MAX+2];
oks486 0:43cce7b453d0 131 int length = i2cs->read(bufi2c, DATA_BYTES_MAX+2) - 1;
oks486 0:43cce7b453d0 132 // The reason of "DATA_BYTES_MAX+2" is the one is "command byte"
oks486 0:43cce7b453d0 133 // from IchigoJam and the other is caused by behavior of i2c_api
oks486 0:43cce7b453d0 134
oks486 0:43cce7b453d0 135 if (length == 1) { // when "i2cr" instruction
oks486 0:43cce7b453d0 136 count = 1;
oks486 0:43cce7b453d0 137 return RETURN_NORMAL;
oks486 0:43cce7b453d0 138 } else {
oks486 0:43cce7b453d0 139 count = 0;
oks486 0:43cce7b453d0 140 }
oks486 0:43cce7b453d0 141
oks486 0:43cce7b453d0 142 length--; // decresement the number of command bytes
oks486 0:43cce7b453d0 143 if (length > DATA_BYTES_MAX) {
oks486 0:43cce7b453d0 144 length = DATA_BYTES_MAX;
oks486 0:43cce7b453d0 145 }
oks486 0:43cce7b453d0 146
oks486 0:43cce7b453d0 147 // Write data to memory card
oks486 0:43cce7b453d0 148 fs->mount();
oks486 0:43cce7b453d0 149 int res = fs->open(DATA_FILENAME, MODE_OVERWRITE);
oks486 0:43cce7b453d0 150 if (res != FR_OK) {
oks486 1:11f73f269fdc 151 ledcard->write(0);
oks486 0:43cce7b453d0 152 return RETURN_ERROR;
oks486 0:43cce7b453d0 153 }
oks486 0:43cce7b453d0 154 fs->write(&bufi2c[1], length);
oks486 0:43cce7b453d0 155 fs->close();
oks486 0:43cce7b453d0 156
oks486 0:43cce7b453d0 157 ledcard->write(0);
oks486 0:43cce7b453d0 158 return RETURN_NORMAL;
oks486 0:43cce7b453d0 159 }
oks486 0:43cce7b453d0 160
oks486 0:43cce7b453d0 161
oks486 0:43cce7b453d0 162 // Read a I2C data to memory card
oks486 0:43cce7b453d0 163 int I2c2mem::readData()
oks486 0:43cce7b453d0 164 {
oks486 0:43cce7b453d0 165 ledcard->write(1);
oks486 0:43cce7b453d0 166
oks486 0:43cce7b453d0 167 if (count != 1) {
oks486 0:43cce7b453d0 168 i2cs->stop();
oks486 0:43cce7b453d0 169 count = 0;
oks486 1:11f73f269fdc 170 ledcard->write(0);
oks486 0:43cce7b453d0 171 return RETURN_ERROR;
oks486 0:43cce7b453d0 172 }
oks486 0:43cce7b453d0 173
oks486 0:43cce7b453d0 174 // Read data from memory card
oks486 0:43cce7b453d0 175 fs->mount();
oks486 0:43cce7b453d0 176 int res = fs->open(DATA_FILENAME, MODE_RO);
oks486 0:43cce7b453d0 177 if (res != FR_OK) {
oks486 1:11f73f269fdc 178 ledcard->write(0);
oks486 0:43cce7b453d0 179 return RETURN_ERROR;
oks486 0:43cce7b453d0 180 }
oks486 0:43cce7b453d0 181
oks486 0:43cce7b453d0 182 int length = fs->filesize();
oks486 0:43cce7b453d0 183 if (length > DATA_BYTES_MAX) {
oks486 0:43cce7b453d0 184 length = DATA_BYTES_MAX;
oks486 0:43cce7b453d0 185 }
oks486 0:43cce7b453d0 186
oks486 0:43cce7b453d0 187 char bufi2c[DATA_BYTES_MAX];
oks486 0:43cce7b453d0 188 if (fs->read(bufi2c, length) != length) {
oks486 0:43cce7b453d0 189 fs->close();
oks486 1:11f73f269fdc 190 ledcard->write(0);
oks486 0:43cce7b453d0 191 return RETURN_ERROR;
oks486 0:43cce7b453d0 192 }
oks486 0:43cce7b453d0 193 fs->close();
oks486 0:43cce7b453d0 194
oks486 0:43cce7b453d0 195 // Send to master
oks486 0:43cce7b453d0 196 i2cs->write(bufi2c, length);
oks486 0:43cce7b453d0 197
oks486 0:43cce7b453d0 198 count = 0;
oks486 0:43cce7b453d0 199 ledcard->write(0);
oks486 0:43cce7b453d0 200 return RETURN_NORMAL;
oks486 0:43cce7b453d0 201 }
oks486 0:43cce7b453d0 202
oks486 0:43cce7b453d0 203
oks486 0:43cce7b453d0 204 // Write a I2C data to memory card card (Continuous writting mode)
oks486 0:43cce7b453d0 205 int I2c2mem::writeDataContinuous()
oks486 0:43cce7b453d0 206 {
oks486 0:43cce7b453d0 207 // Data from master
oks486 0:43cce7b453d0 208 char bufi2c[DATA_BYTES_MAX+2];
oks486 0:43cce7b453d0 209 int length = i2cs->read(bufi2c, DATA_BYTES_MAX+2) - 1;
oks486 0:43cce7b453d0 210
oks486 0:43cce7b453d0 211 length--; // decresement the number of command bytes
oks486 0:43cce7b453d0 212 if (length > DATA_BYTES_MAX) {
oks486 0:43cce7b453d0 213 length = DATA_BYTES_MAX;
oks486 0:43cce7b453d0 214 }
oks486 0:43cce7b453d0 215
oks486 0:43cce7b453d0 216 for (int i = 0; i < length; i++) {
oks486 0:43cce7b453d0 217 buffer[dataBytesCount + i] = bufi2c[i + 1];
oks486 0:43cce7b453d0 218 }
oks486 0:43cce7b453d0 219
oks486 0:43cce7b453d0 220 dataBytesCount += length;
oks486 0:43cce7b453d0 221 if (dataBytesCount < DATA_BYTES_MAX) {
oks486 0:43cce7b453d0 222 return RETURN_NORMAL;
oks486 0:43cce7b453d0 223 }
oks486 0:43cce7b453d0 224
oks486 0:43cce7b453d0 225 // Write data to memory card
oks486 0:43cce7b453d0 226 ledcard->write(1);
oks486 0:43cce7b453d0 227 fs->mount();
oks486 0:43cce7b453d0 228 fs->mkdir("data");
oks486 0:43cce7b453d0 229
oks486 0:43cce7b453d0 230 sprintf(filename, "/data/%04d.dat", dataFileNum);
oks486 0:43cce7b453d0 231 int res = fs->open(filename, MODE_APPEND);
oks486 0:43cce7b453d0 232 if (res != FR_OK) {
oks486 1:11f73f269fdc 233 ledcard->write(0);
oks486 0:43cce7b453d0 234 return RETURN_ERROR;
oks486 0:43cce7b453d0 235 }
oks486 0:43cce7b453d0 236
oks486 0:43cce7b453d0 237 int datafilesize = fs->filesize();
oks486 0:43cce7b453d0 238 if (datafilesize > 1024*1024) {
oks486 0:43cce7b453d0 239 fs->close();
oks486 0:43cce7b453d0 240 dataFileNum++;
oks486 0:43cce7b453d0 241 if (dataFileNum > DATA_FILENUM_MAX) {
oks486 0:43cce7b453d0 242 dataFileNum = 0;
oks486 0:43cce7b453d0 243 }
oks486 0:43cce7b453d0 244 sprintf(filename, "/data/%04d.dat", dataFileNum);
oks486 0:43cce7b453d0 245 res = fs->open(filename, MODE_OVERWRITE);
oks486 0:43cce7b453d0 246 if (res != FR_OK) {
oks486 1:11f73f269fdc 247 ledcard->write(0);
oks486 0:43cce7b453d0 248 return RETURN_ERROR;
oks486 0:43cce7b453d0 249 }
oks486 0:43cce7b453d0 250 }
oks486 0:43cce7b453d0 251
oks486 0:43cce7b453d0 252 fs->write(buffer, dataBytesCount);
oks486 0:43cce7b453d0 253 fs->close();
oks486 0:43cce7b453d0 254 dataBytesCount = 0;
oks486 0:43cce7b453d0 255 ledcard->write(0);
oks486 0:43cce7b453d0 256
oks486 0:43cce7b453d0 257 return RETURN_NORMAL;
oks486 0:43cce7b453d0 258 }
oks486 0:43cce7b453d0 259
oks486 0:43cce7b453d0 260
oks486 0:43cce7b453d0 261 int I2c2mem::reset()
oks486 0:43cce7b453d0 262 {
oks486 0:43cce7b453d0 263 i2cs->stop();
oks486 0:43cce7b453d0 264
oks486 0:43cce7b453d0 265 // If there is data remaining in the buffer, it is written to memory card.
oks486 0:43cce7b453d0 266 if (dataBytesCount != 0) {
oks486 0:43cce7b453d0 267 ledcard->write(1);
oks486 0:43cce7b453d0 268 fs->mount();
oks486 0:43cce7b453d0 269
oks486 0:43cce7b453d0 270 sprintf(filename, "/data/%04d.dat", dataFileNum);
oks486 0:43cce7b453d0 271 int res = fs->open(filename, MODE_APPEND);
oks486 0:43cce7b453d0 272 if (res != FR_OK) {
oks486 1:11f73f269fdc 273 ledcard->write(0);
oks486 0:43cce7b453d0 274 return RETURN_ERROR;
oks486 0:43cce7b453d0 275 }
oks486 0:43cce7b453d0 276
oks486 0:43cce7b453d0 277 int datafilesize = fs->filesize();
oks486 0:43cce7b453d0 278 if (datafilesize > 1024*1024) {
oks486 0:43cce7b453d0 279 fs->close();
oks486 0:43cce7b453d0 280 dataFileNum++;
oks486 0:43cce7b453d0 281 if (dataFileNum > DATA_FILENUM_MAX) {
oks486 0:43cce7b453d0 282 dataFileNum = 0;
oks486 0:43cce7b453d0 283 }
oks486 0:43cce7b453d0 284 sprintf(filename, "/data/%04d.dat", dataFileNum);
oks486 0:43cce7b453d0 285 res = fs->open(filename, MODE_OVERWRITE);
oks486 0:43cce7b453d0 286 if (res != FR_OK) {
oks486 1:11f73f269fdc 287 ledcard->write(0);
oks486 0:43cce7b453d0 288 return RETURN_ERROR;
oks486 0:43cce7b453d0 289 }
oks486 0:43cce7b453d0 290 }
oks486 0:43cce7b453d0 291
oks486 0:43cce7b453d0 292 fs->write(buffer, dataBytesCount);
oks486 0:43cce7b453d0 293 fs->close();
oks486 0:43cce7b453d0 294 ledcard->write(0);
oks486 0:43cce7b453d0 295 }
oks486 0:43cce7b453d0 296
oks486 0:43cce7b453d0 297 address = 0;
oks486 0:43cce7b453d0 298 count = 0;
oks486 0:43cce7b453d0 299 dataBytesCount = 0;
oks486 0:43cce7b453d0 300 dataFileNum = 0;
oks486 0:43cce7b453d0 301
oks486 0:43cce7b453d0 302 return RETURN_NORMAL;
oks486 0:43cce7b453d0 303 }
oks486 0:43cce7b453d0 304