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

Dependencies:   mbed

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

Committer:
oks486
Date:
Sun Aug 21 07:51:01 2016 +0000
Revision:
2:daf6c4719496
Parent:
1:11f73f269fdc
Modified I2c2mem for "FILES" command

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