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

Dependencies:   mbed

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

Committer:
oks486
Date:
Thu Apr 28 11:23:24 2016 +0000
Revision:
0:43cce7b453d0
Child:
1:11f73f269fdc
first commit

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 0:43cce7b453d0 4 #include "FatfsIJFW.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 0:43cce7b453d0 16 I2c2mem::I2c2mem(I2CSlave2* _i2cs, FatfsIJFW* _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 0:43cce7b453d0 51 return RETURN_ERROR;
oks486 0:43cce7b453d0 52 }
oks486 0:43cce7b453d0 53
oks486 0:43cce7b453d0 54 if (length == 34) {
oks486 0:43cce7b453d0 55 for (int i = 0; i < 32; i++) {
oks486 0:43cce7b453d0 56 buffer[count + i] = bufi2c[i + 2];
oks486 0:43cce7b453d0 57 }
oks486 0:43cce7b453d0 58 count += 32;
oks486 0:43cce7b453d0 59
oks486 0:43cce7b453d0 60 if (count >= PROGRAM_BYTES_MAX) {
oks486 0:43cce7b453d0 61 count = 0;
oks486 0:43cce7b453d0 62 fs->mount();
oks486 0:43cce7b453d0 63 int res = fs->open(filename, MODE_OVERWRITE);
oks486 0:43cce7b453d0 64 if (res != FR_OK) {
oks486 0:43cce7b453d0 65 return RETURN_ERROR;
oks486 0:43cce7b453d0 66 }
oks486 0:43cce7b453d0 67
oks486 0:43cce7b453d0 68 fs->write(buffer, PROGRAM_BYTES_MAX);
oks486 0:43cce7b453d0 69 fs->close();
oks486 0:43cce7b453d0 70 }
oks486 0:43cce7b453d0 71 }
oks486 0:43cce7b453d0 72
oks486 0:43cce7b453d0 73 ledcard->write(0);
oks486 0:43cce7b453d0 74 return RETURN_NORMAL;
oks486 0:43cce7b453d0 75 }
oks486 0:43cce7b453d0 76
oks486 0:43cce7b453d0 77
oks486 0:43cce7b453d0 78 // Read a BASIC program from memory card
oks486 0:43cce7b453d0 79 int I2c2mem::readProgram() {
oks486 0:43cce7b453d0 80 ledcard->write(1);
oks486 0:43cce7b453d0 81
oks486 0:43cce7b453d0 82 if (count == 0) {
oks486 0:43cce7b453d0 83 fs->mount();
oks486 0:43cce7b453d0 84 int res = fs->open(filename, MODE_RO);
oks486 0:43cce7b453d0 85 if (res != FR_OK) {
oks486 0:43cce7b453d0 86 i2cs->stop();
oks486 0:43cce7b453d0 87 return RETURN_ERROR;
oks486 0:43cce7b453d0 88 }
oks486 0:43cce7b453d0 89 if (fs->read(buffer, PROGRAM_BYTES_MAX) != PROGRAM_BYTES_MAX) {
oks486 0:43cce7b453d0 90 fs->close();
oks486 0:43cce7b453d0 91 i2cs->stop();
oks486 0:43cce7b453d0 92 return RETURN_ERROR;
oks486 0:43cce7b453d0 93 }
oks486 0:43cce7b453d0 94 fs->close();
oks486 0:43cce7b453d0 95 }
oks486 0:43cce7b453d0 96
oks486 0:43cce7b453d0 97 char bufi2c[32];
oks486 0:43cce7b453d0 98 for (int i = 0; i < 32; i++) {
oks486 0:43cce7b453d0 99 bufi2c[i] = buffer[count + i];
oks486 0:43cce7b453d0 100 }
oks486 0:43cce7b453d0 101
oks486 0:43cce7b453d0 102 if (i2cs->write(bufi2c, 32) != 32) {
oks486 0:43cce7b453d0 103 i2cs->stop();
oks486 0:43cce7b453d0 104 count = 0;
oks486 0:43cce7b453d0 105 return RETURN_ERROR;
oks486 0:43cce7b453d0 106 }
oks486 0:43cce7b453d0 107 count += 32;
oks486 0:43cce7b453d0 108
oks486 0:43cce7b453d0 109 if (count >= PROGRAM_BYTES_MAX) {
oks486 0:43cce7b453d0 110 i2cs->stop();
oks486 0:43cce7b453d0 111 count = 0;
oks486 0:43cce7b453d0 112 }
oks486 0:43cce7b453d0 113
oks486 0:43cce7b453d0 114 ledcard->write(0);
oks486 0:43cce7b453d0 115 return RETURN_NORMAL;
oks486 0:43cce7b453d0 116 }
oks486 0:43cce7b453d0 117
oks486 0:43cce7b453d0 118
oks486 0:43cce7b453d0 119 // Write a I2C data to memory card
oks486 0:43cce7b453d0 120 int I2c2mem::writeData()
oks486 0:43cce7b453d0 121 {
oks486 0:43cce7b453d0 122 ledcard->write(1);
oks486 0:43cce7b453d0 123
oks486 0:43cce7b453d0 124 // Data from master
oks486 0:43cce7b453d0 125 char bufi2c[DATA_BYTES_MAX+2];
oks486 0:43cce7b453d0 126 int length = i2cs->read(bufi2c, DATA_BYTES_MAX+2) - 1;
oks486 0:43cce7b453d0 127 // The reason of "DATA_BYTES_MAX+2" is the one is "command byte"
oks486 0:43cce7b453d0 128 // from IchigoJam and the other is caused by behavior of i2c_api
oks486 0:43cce7b453d0 129
oks486 0:43cce7b453d0 130 if (length == 1) { // when "i2cr" instruction
oks486 0:43cce7b453d0 131 count = 1;
oks486 0:43cce7b453d0 132 return RETURN_NORMAL;
oks486 0:43cce7b453d0 133 } else {
oks486 0:43cce7b453d0 134 count = 0;
oks486 0:43cce7b453d0 135 }
oks486 0:43cce7b453d0 136
oks486 0:43cce7b453d0 137 length--; // decresement the number of command bytes
oks486 0:43cce7b453d0 138 if (length > DATA_BYTES_MAX) {
oks486 0:43cce7b453d0 139 length = DATA_BYTES_MAX;
oks486 0:43cce7b453d0 140 }
oks486 0:43cce7b453d0 141
oks486 0:43cce7b453d0 142 // Write data to memory card
oks486 0:43cce7b453d0 143 fs->mount();
oks486 0:43cce7b453d0 144 int res = fs->open(DATA_FILENAME, MODE_OVERWRITE);
oks486 0:43cce7b453d0 145 if (res != FR_OK) {
oks486 0:43cce7b453d0 146 return RETURN_ERROR;
oks486 0:43cce7b453d0 147 }
oks486 0:43cce7b453d0 148 fs->write(&bufi2c[1], length);
oks486 0:43cce7b453d0 149 fs->close();
oks486 0:43cce7b453d0 150
oks486 0:43cce7b453d0 151 ledcard->write(0);
oks486 0:43cce7b453d0 152 return RETURN_NORMAL;
oks486 0:43cce7b453d0 153 }
oks486 0:43cce7b453d0 154
oks486 0:43cce7b453d0 155
oks486 0:43cce7b453d0 156 // Read a I2C data to memory card
oks486 0:43cce7b453d0 157 int I2c2mem::readData()
oks486 0:43cce7b453d0 158 {
oks486 0:43cce7b453d0 159 ledcard->write(1);
oks486 0:43cce7b453d0 160
oks486 0:43cce7b453d0 161 if (count != 1) {
oks486 0:43cce7b453d0 162 i2cs->stop();
oks486 0:43cce7b453d0 163 count = 0;
oks486 0:43cce7b453d0 164 return RETURN_ERROR;
oks486 0:43cce7b453d0 165 }
oks486 0:43cce7b453d0 166
oks486 0:43cce7b453d0 167 // Read data from memory card
oks486 0:43cce7b453d0 168 fs->mount();
oks486 0:43cce7b453d0 169 int res = fs->open(DATA_FILENAME, MODE_RO);
oks486 0:43cce7b453d0 170 if (res != FR_OK) {
oks486 0:43cce7b453d0 171 return RETURN_ERROR;
oks486 0:43cce7b453d0 172 }
oks486 0:43cce7b453d0 173
oks486 0:43cce7b453d0 174 int length = fs->filesize();
oks486 0:43cce7b453d0 175 if (length > DATA_BYTES_MAX) {
oks486 0:43cce7b453d0 176 length = DATA_BYTES_MAX;
oks486 0:43cce7b453d0 177 }
oks486 0:43cce7b453d0 178
oks486 0:43cce7b453d0 179 char bufi2c[DATA_BYTES_MAX];
oks486 0:43cce7b453d0 180 if (fs->read(bufi2c, length) != length) {
oks486 0:43cce7b453d0 181 fs->close();
oks486 0:43cce7b453d0 182 return RETURN_ERROR;
oks486 0:43cce7b453d0 183 }
oks486 0:43cce7b453d0 184 fs->close();
oks486 0:43cce7b453d0 185
oks486 0:43cce7b453d0 186 // Send to master
oks486 0:43cce7b453d0 187 i2cs->write(bufi2c, length);
oks486 0:43cce7b453d0 188
oks486 0:43cce7b453d0 189 count = 0;
oks486 0:43cce7b453d0 190 ledcard->write(0);
oks486 0:43cce7b453d0 191 return RETURN_NORMAL;
oks486 0:43cce7b453d0 192 }
oks486 0:43cce7b453d0 193
oks486 0:43cce7b453d0 194
oks486 0:43cce7b453d0 195 // Write a I2C data to memory card card (Continuous writting mode)
oks486 0:43cce7b453d0 196 int I2c2mem::writeDataContinuous()
oks486 0:43cce7b453d0 197 {
oks486 0:43cce7b453d0 198 // Data from master
oks486 0:43cce7b453d0 199 char bufi2c[DATA_BYTES_MAX+2];
oks486 0:43cce7b453d0 200 int length = i2cs->read(bufi2c, DATA_BYTES_MAX+2) - 1;
oks486 0:43cce7b453d0 201
oks486 0:43cce7b453d0 202 length--; // decresement the number of command bytes
oks486 0:43cce7b453d0 203 if (length > DATA_BYTES_MAX) {
oks486 0:43cce7b453d0 204 length = DATA_BYTES_MAX;
oks486 0:43cce7b453d0 205 }
oks486 0:43cce7b453d0 206
oks486 0:43cce7b453d0 207 for (int i = 0; i < length; i++) {
oks486 0:43cce7b453d0 208 buffer[dataBytesCount + i] = bufi2c[i + 1];
oks486 0:43cce7b453d0 209 }
oks486 0:43cce7b453d0 210
oks486 0:43cce7b453d0 211 dataBytesCount += length;
oks486 0:43cce7b453d0 212 if (dataBytesCount < DATA_BYTES_MAX) {
oks486 0:43cce7b453d0 213 return RETURN_NORMAL;
oks486 0:43cce7b453d0 214 }
oks486 0:43cce7b453d0 215
oks486 0:43cce7b453d0 216 // Write data to memory card
oks486 0:43cce7b453d0 217 ledcard->write(1);
oks486 0:43cce7b453d0 218 fs->mount();
oks486 0:43cce7b453d0 219 fs->mkdir("data");
oks486 0:43cce7b453d0 220
oks486 0:43cce7b453d0 221 sprintf(filename, "/data/%04d.dat", dataFileNum);
oks486 0:43cce7b453d0 222 int res = fs->open(filename, MODE_APPEND);
oks486 0:43cce7b453d0 223 if (res != FR_OK) {
oks486 0:43cce7b453d0 224 return RETURN_ERROR;
oks486 0:43cce7b453d0 225 }
oks486 0:43cce7b453d0 226
oks486 0:43cce7b453d0 227 int datafilesize = fs->filesize();
oks486 0:43cce7b453d0 228 if (datafilesize > 1024*1024) {
oks486 0:43cce7b453d0 229 fs->close();
oks486 0:43cce7b453d0 230 dataFileNum++;
oks486 0:43cce7b453d0 231 if (dataFileNum > DATA_FILENUM_MAX) {
oks486 0:43cce7b453d0 232 dataFileNum = 0;
oks486 0:43cce7b453d0 233 }
oks486 0:43cce7b453d0 234 sprintf(filename, "/data/%04d.dat", dataFileNum);
oks486 0:43cce7b453d0 235 res = fs->open(filename, MODE_OVERWRITE);
oks486 0:43cce7b453d0 236 if (res != FR_OK) {
oks486 0:43cce7b453d0 237 return RETURN_ERROR;
oks486 0:43cce7b453d0 238 }
oks486 0:43cce7b453d0 239 }
oks486 0:43cce7b453d0 240
oks486 0:43cce7b453d0 241 fs->write(buffer, dataBytesCount);
oks486 0:43cce7b453d0 242 fs->close();
oks486 0:43cce7b453d0 243 dataBytesCount = 0;
oks486 0:43cce7b453d0 244 ledcard->write(0);
oks486 0:43cce7b453d0 245
oks486 0:43cce7b453d0 246 return RETURN_NORMAL;
oks486 0:43cce7b453d0 247 }
oks486 0:43cce7b453d0 248
oks486 0:43cce7b453d0 249
oks486 0:43cce7b453d0 250 int I2c2mem::reset()
oks486 0:43cce7b453d0 251 {
oks486 0:43cce7b453d0 252 i2cs->stop();
oks486 0:43cce7b453d0 253
oks486 0:43cce7b453d0 254 // If there is data remaining in the buffer, it is written to memory card.
oks486 0:43cce7b453d0 255 if (dataBytesCount != 0) {
oks486 0:43cce7b453d0 256 ledcard->write(1);
oks486 0:43cce7b453d0 257 fs->mount();
oks486 0:43cce7b453d0 258
oks486 0:43cce7b453d0 259 sprintf(filename, "/data/%04d.dat", dataFileNum);
oks486 0:43cce7b453d0 260 int res = fs->open(filename, MODE_APPEND);
oks486 0:43cce7b453d0 261 if (res != FR_OK) {
oks486 0:43cce7b453d0 262 return RETURN_ERROR;
oks486 0:43cce7b453d0 263 }
oks486 0:43cce7b453d0 264
oks486 0:43cce7b453d0 265 int datafilesize = fs->filesize();
oks486 0:43cce7b453d0 266 if (datafilesize > 1024*1024) {
oks486 0:43cce7b453d0 267 fs->close();
oks486 0:43cce7b453d0 268 dataFileNum++;
oks486 0:43cce7b453d0 269 if (dataFileNum > DATA_FILENUM_MAX) {
oks486 0:43cce7b453d0 270 dataFileNum = 0;
oks486 0:43cce7b453d0 271 }
oks486 0:43cce7b453d0 272 sprintf(filename, "/data/%04d.dat", dataFileNum);
oks486 0:43cce7b453d0 273 res = fs->open(filename, MODE_OVERWRITE);
oks486 0:43cce7b453d0 274 if (res != FR_OK) {
oks486 0:43cce7b453d0 275 return RETURN_ERROR;
oks486 0:43cce7b453d0 276 }
oks486 0:43cce7b453d0 277 }
oks486 0:43cce7b453d0 278
oks486 0:43cce7b453d0 279 fs->write(buffer, dataBytesCount);
oks486 0:43cce7b453d0 280 fs->close();
oks486 0:43cce7b453d0 281 ledcard->write(0);
oks486 0:43cce7b453d0 282 }
oks486 0:43cce7b453d0 283
oks486 0:43cce7b453d0 284 address = 0;
oks486 0:43cce7b453d0 285 count = 0;
oks486 0:43cce7b453d0 286 dataBytesCount = 0;
oks486 0:43cce7b453d0 287 dataFileNum = 0;
oks486 0:43cce7b453d0 288
oks486 0:43cce7b453d0 289 return RETURN_NORMAL;
oks486 0:43cce7b453d0 290 }
oks486 0:43cce7b453d0 291