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:
0:43cce7b453d0
Modified I2c2mem for "FILES" command

Who changed what in which revision?

UserRevisionLine numberNew contents of line
oks486 0:43cce7b453d0 1 #include "mbed.h"
oks486 0:43cce7b453d0 2 #include "ff.h"
oks486 0:43cce7b453d0 3 #include "FatfsIJFW.h"
oks486 0:43cce7b453d0 4
oks486 0:43cce7b453d0 5
oks486 0:43cce7b453d0 6 // Command of memory card
oks486 0:43cce7b453d0 7 const BYTE CMD0 = 0; // GO_IDLE_STATE
oks486 0:43cce7b453d0 8 const BYTE CMD1 = 1; // SEND_OP_COND
oks486 0:43cce7b453d0 9 const BYTE ACMD41 = 0x80+41; // SEND_OP_COND
oks486 0:43cce7b453d0 10 const BYTE CMD8 = 8; // SEND_IF_COND
oks486 0:43cce7b453d0 11 const BYTE CMD12 = 12; // STOP_TRANSMISSION
oks486 0:43cce7b453d0 12 const BYTE CMD16 = 16; // SET_BLOCKLEN
oks486 0:43cce7b453d0 13 const BYTE CMD17 = 17; // READ_SINGLE_BLOCK
oks486 0:43cce7b453d0 14 const BYTE CMD18 = 18; // READ_MULTIPLE_BLOCK
oks486 0:43cce7b453d0 15 const BYTE ACMD23 = 0x80+23; // SET_WR_BLK_ERASE_COUNT
oks486 0:43cce7b453d0 16 const BYTE CMD24 = 24; // WRITE_BLOCK
oks486 0:43cce7b453d0 17 const BYTE CMD25 = 25; // WRITE_MULTIPLE_BLOCK
oks486 0:43cce7b453d0 18 const BYTE CMD55 = 55; // APP_CMD
oks486 0:43cce7b453d0 19 const BYTE CMD58 = 58; // READ_OCR
oks486 0:43cce7b453d0 20
oks486 0:43cce7b453d0 21 // Card type flag
oks486 0:43cce7b453d0 22 int CardType;
oks486 0:43cce7b453d0 23
oks486 0:43cce7b453d0 24 // Extern to diskio.cpp
oks486 0:43cce7b453d0 25 extern FatfsIJFW* _fatfs;
oks486 0:43cce7b453d0 26
oks486 0:43cce7b453d0 27
oks486 0:43cce7b453d0 28 FatfsIJFW::FatfsIJFW(SPI* _spi, DigitalOut* _cs) : spi(_spi), cs(_cs) {
oks486 0:43cce7b453d0 29 _fatfs = this;
oks486 0:43cce7b453d0 30 Stat = 0;
oks486 0:43cce7b453d0 31 spi->format(8, 0);
oks486 0:43cce7b453d0 32 f_mount(NULL, "", 0);
oks486 0:43cce7b453d0 33 }
oks486 0:43cce7b453d0 34
oks486 0:43cce7b453d0 35
oks486 0:43cce7b453d0 36 int FatfsIJFW::mount() {
oks486 0:43cce7b453d0 37 Stat = 0;
oks486 0:43cce7b453d0 38 FRESULT res = f_mount(&fs, "", 1);
oks486 0:43cce7b453d0 39 return (int)res;
oks486 0:43cce7b453d0 40 }
oks486 0:43cce7b453d0 41
oks486 0:43cce7b453d0 42
oks486 0:43cce7b453d0 43 int FatfsIJFW::open(const char* name, const FileMode mode) {
oks486 0:43cce7b453d0 44 BYTE flags;
oks486 0:43cce7b453d0 45
oks486 0:43cce7b453d0 46 if (mode == MODE_WR) {
oks486 0:43cce7b453d0 47 // Write and Read
oks486 0:43cce7b453d0 48 flags = FA_OPEN_EXISTING | FA_READ | FA_WRITE;
oks486 0:43cce7b453d0 49 } else if (mode == MODE_RO) {
oks486 0:43cce7b453d0 50 // Read Only
oks486 0:43cce7b453d0 51 flags = FA_OPEN_EXISTING | FA_READ;
oks486 0:43cce7b453d0 52 } else if (mode == MODE_APPEND) {
oks486 0:43cce7b453d0 53 // Append write
oks486 0:43cce7b453d0 54 flags = FA_OPEN_ALWAYS | FA_WRITE;
oks486 0:43cce7b453d0 55 } else if (mode == MODE_OVERWRITE) {
oks486 0:43cce7b453d0 56 // Overwrite
oks486 0:43cce7b453d0 57 flags = FA_CREATE_ALWAYS | FA_WRITE;
oks486 0:43cce7b453d0 58 }
oks486 0:43cce7b453d0 59
oks486 0:43cce7b453d0 60 FRESULT res = f_open(&file, name, flags);
oks486 0:43cce7b453d0 61
oks486 0:43cce7b453d0 62 if (mode == MODE_APPEND) {
oks486 0:43cce7b453d0 63 f_lseek(&file, f_size(&file));
oks486 0:43cce7b453d0 64 }
oks486 0:43cce7b453d0 65
oks486 0:43cce7b453d0 66 return (int)res;
oks486 0:43cce7b453d0 67 }
oks486 0:43cce7b453d0 68
oks486 0:43cce7b453d0 69
oks486 0:43cce7b453d0 70 int FatfsIJFW::close() {
oks486 0:43cce7b453d0 71 FRESULT res = f_close(&file);
oks486 0:43cce7b453d0 72 return (int)res;
oks486 0:43cce7b453d0 73 }
oks486 0:43cce7b453d0 74
oks486 0:43cce7b453d0 75
oks486 0:43cce7b453d0 76 int FatfsIJFW::remove(const char* filename) {
oks486 0:43cce7b453d0 77 FRESULT res = f_unlink(filename);
oks486 0:43cce7b453d0 78 return (int)res;
oks486 0:43cce7b453d0 79 }
oks486 0:43cce7b453d0 80
oks486 0:43cce7b453d0 81
oks486 0:43cce7b453d0 82 int FatfsIJFW::mkdir(const char* filename) {
oks486 0:43cce7b453d0 83 FRESULT res = f_mkdir(filename);
oks486 0:43cce7b453d0 84 return (int)res;
oks486 0:43cce7b453d0 85 }
oks486 0:43cce7b453d0 86
oks486 0:43cce7b453d0 87
oks486 0:43cce7b453d0 88 int FatfsIJFW::read(char* buf, const int length) {
oks486 0:43cce7b453d0 89 UINT br;
oks486 0:43cce7b453d0 90 f_read(&file, buf, (UINT)length, &br);
oks486 0:43cce7b453d0 91 return (int)br;
oks486 0:43cce7b453d0 92 }
oks486 0:43cce7b453d0 93
oks486 0:43cce7b453d0 94
oks486 0:43cce7b453d0 95 int FatfsIJFW::write(const char* buf, const int length) {
oks486 0:43cce7b453d0 96 UINT br;
oks486 0:43cce7b453d0 97 f_write(&file, buf, (UINT)length, &br);
oks486 0:43cce7b453d0 98 return (int)br;
oks486 0:43cce7b453d0 99 }
oks486 0:43cce7b453d0 100
oks486 0:43cce7b453d0 101
oks486 0:43cce7b453d0 102 int FatfsIJFW::lseek(int pos) {
oks486 0:43cce7b453d0 103 return (int)f_lseek(&file, (DWORD)pos);
oks486 0:43cce7b453d0 104 }
oks486 0:43cce7b453d0 105
oks486 0:43cce7b453d0 106
oks486 0:43cce7b453d0 107 int FatfsIJFW::filesize() {
oks486 0:43cce7b453d0 108 return (int)f_size(&file);
oks486 0:43cce7b453d0 109 }
oks486 0:43cce7b453d0 110
oks486 0:43cce7b453d0 111
oks486 0:43cce7b453d0 112 void FatfsIJFW::timerproc() {
oks486 0:43cce7b453d0 113 if (timerCount) {
oks486 0:43cce7b453d0 114 timerCount--;
oks486 0:43cce7b453d0 115 }
oks486 0:43cce7b453d0 116 }
oks486 0:43cce7b453d0 117
oks486 0:43cce7b453d0 118
oks486 0:43cce7b453d0 119 void FatfsIJFW::deselect() {
oks486 0:43cce7b453d0 120 cs->write(1);
oks486 0:43cce7b453d0 121 spi->write(0xFF);
oks486 0:43cce7b453d0 122 }
oks486 0:43cce7b453d0 123
oks486 0:43cce7b453d0 124
oks486 0:43cce7b453d0 125 int FatfsIJFW::select() {
oks486 0:43cce7b453d0 126 cs->write(0);
oks486 0:43cce7b453d0 127 spi->write(0xFF);
oks486 0:43cce7b453d0 128
oks486 0:43cce7b453d0 129 // Wait for card is ready
oks486 0:43cce7b453d0 130 if (waitReady(500)) {
oks486 0:43cce7b453d0 131 return 1;
oks486 0:43cce7b453d0 132 }
oks486 0:43cce7b453d0 133
oks486 0:43cce7b453d0 134 // Timerout
oks486 0:43cce7b453d0 135 deselect();
oks486 0:43cce7b453d0 136 return 0;
oks486 0:43cce7b453d0 137 }
oks486 0:43cce7b453d0 138
oks486 0:43cce7b453d0 139
oks486 0:43cce7b453d0 140 int FatfsIJFW::waitReady(int wait) {
oks486 0:43cce7b453d0 141 BYTE res;
oks486 0:43cce7b453d0 142
oks486 0:43cce7b453d0 143 timerCount = wait;
oks486 0:43cce7b453d0 144 do {
oks486 0:43cce7b453d0 145 res = spi->write(0xFF);
oks486 0:43cce7b453d0 146 } while (res != 0xFF && timerCount);
oks486 0:43cce7b453d0 147
oks486 0:43cce7b453d0 148 return (res == 0xFF);
oks486 0:43cce7b453d0 149 }
oks486 0:43cce7b453d0 150
oks486 0:43cce7b453d0 151
oks486 0:43cce7b453d0 152 char FatfsIJFW::sendCommand(BYTE cmd, DWORD arg) {
oks486 0:43cce7b453d0 153 char res;
oks486 0:43cce7b453d0 154
oks486 0:43cce7b453d0 155 // cmd is ACMD<n>
oks486 0:43cce7b453d0 156 if (cmd & 0x80) {
oks486 0:43cce7b453d0 157 cmd &= 0x7F;
oks486 0:43cce7b453d0 158 res = sendCommand(CMD55, 0);
oks486 0:43cce7b453d0 159 if (res > 1) {
oks486 0:43cce7b453d0 160 return res;
oks486 0:43cce7b453d0 161 }
oks486 0:43cce7b453d0 162 }
oks486 0:43cce7b453d0 163
oks486 0:43cce7b453d0 164 // Select the card and wait for ready except to stop multiple block read
oks486 0:43cce7b453d0 165 if (cmd != CMD12) {
oks486 0:43cce7b453d0 166 deselect();
oks486 0:43cce7b453d0 167 if (!select()) {
oks486 0:43cce7b453d0 168 return 0xFF;
oks486 0:43cce7b453d0 169 }
oks486 0:43cce7b453d0 170 }
oks486 0:43cce7b453d0 171
oks486 0:43cce7b453d0 172 // Send command packet
oks486 0:43cce7b453d0 173 spi->write(0x40 | cmd);
oks486 0:43cce7b453d0 174 spi->write((uint8_t)(arg >> 24));
oks486 0:43cce7b453d0 175 spi->write((uint8_t)(arg >> 16));
oks486 0:43cce7b453d0 176 spi->write((uint8_t)(arg >> 8));
oks486 0:43cce7b453d0 177 spi->write((uint8_t)arg);
oks486 0:43cce7b453d0 178
oks486 0:43cce7b453d0 179 // Send CRC packet
oks486 0:43cce7b453d0 180 BYTE crc;
oks486 0:43cce7b453d0 181 if (cmd == CMD0) {
oks486 0:43cce7b453d0 182 crc = 0x95;
oks486 0:43cce7b453d0 183 } else if (cmd == CMD8) {
oks486 0:43cce7b453d0 184 crc = 0x87;
oks486 0:43cce7b453d0 185 } else {
oks486 0:43cce7b453d0 186 crc = 0x01;
oks486 0:43cce7b453d0 187 }
oks486 0:43cce7b453d0 188 spi->write(crc);
oks486 0:43cce7b453d0 189
oks486 0:43cce7b453d0 190 // Diacard following one byte when CMD12
oks486 0:43cce7b453d0 191 if (cmd == CMD12) {
oks486 0:43cce7b453d0 192 spi->write(0xFF);
oks486 0:43cce7b453d0 193 }
oks486 0:43cce7b453d0 194
oks486 0:43cce7b453d0 195 // Wait for response
oks486 0:43cce7b453d0 196 for (int i = 0; i < 10; i++) {
oks486 0:43cce7b453d0 197 res = spi->write(0xFF);
oks486 0:43cce7b453d0 198 if (!(res & 0x80)) {
oks486 0:43cce7b453d0 199 break;
oks486 0:43cce7b453d0 200 }
oks486 0:43cce7b453d0 201 }
oks486 0:43cce7b453d0 202
oks486 0:43cce7b453d0 203 return res;
oks486 0:43cce7b453d0 204 }
oks486 0:43cce7b453d0 205
oks486 0:43cce7b453d0 206
oks486 0:43cce7b453d0 207 int FatfsIJFW::rcvDataBlock(BYTE *buff, UINT btr) {
oks486 0:43cce7b453d0 208 BYTE token;
oks486 0:43cce7b453d0 209 timerCount = 200;
oks486 0:43cce7b453d0 210
oks486 0:43cce7b453d0 211 do {
oks486 0:43cce7b453d0 212 token = spi->write(0xFF);
oks486 0:43cce7b453d0 213 } while ((token == 0xFF) && timerCount);
oks486 0:43cce7b453d0 214
oks486 0:43cce7b453d0 215 if(token != 0xFE) { // if invalid token or timeout
oks486 0:43cce7b453d0 216 return 0;
oks486 0:43cce7b453d0 217 }
oks486 0:43cce7b453d0 218
oks486 0:43cce7b453d0 219 // Receive the data block
oks486 0:43cce7b453d0 220 WORD data;
oks486 0:43cce7b453d0 221 spi->format(16, 0); // 16bit mode
oks486 0:43cce7b453d0 222
oks486 0:43cce7b453d0 223 for (int i = 0; i < btr; i += 2) {
oks486 0:43cce7b453d0 224 data = spi->write(0xFFFF);
oks486 0:43cce7b453d0 225 buff[i] = data >> 8;
oks486 0:43cce7b453d0 226 buff[i + 1] = data;
oks486 0:43cce7b453d0 227 }
oks486 0:43cce7b453d0 228
oks486 0:43cce7b453d0 229 spi->write(0xFFFF); // CRC
oks486 0:43cce7b453d0 230 spi->format(8, 0); // 8bit mkode
oks486 0:43cce7b453d0 231
oks486 0:43cce7b453d0 232 return 1;
oks486 0:43cce7b453d0 233 }
oks486 0:43cce7b453d0 234
oks486 0:43cce7b453d0 235
oks486 0:43cce7b453d0 236 int FatfsIJFW::sendDataBlock(const BYTE *buff, BYTE token) {
oks486 0:43cce7b453d0 237 // Wait for card is ready
oks486 0:43cce7b453d0 238 if (!waitReady(500)) {
oks486 0:43cce7b453d0 239 return 0;
oks486 0:43cce7b453d0 240 }
oks486 0:43cce7b453d0 241
oks486 0:43cce7b453d0 242 spi->write(token);
oks486 0:43cce7b453d0 243 if (token != 0xFD) { // if token is not StopTran
oks486 0:43cce7b453d0 244 // Send the data block
oks486 0:43cce7b453d0 245 spi->format(16, 0); // 16bit mode
oks486 0:43cce7b453d0 246
oks486 0:43cce7b453d0 247 for (int i = 0; i < 512; i += 2) {
oks486 0:43cce7b453d0 248 unsigned short data = (buff[i] << 8) | buff[i + 1];
oks486 0:43cce7b453d0 249 spi->write(data);
oks486 0:43cce7b453d0 250 }
oks486 0:43cce7b453d0 251 spi->write(0xFFFF); // CRC
oks486 0:43cce7b453d0 252 spi->format(8, 0); // 8bit mode
oks486 0:43cce7b453d0 253
oks486 0:43cce7b453d0 254 BYTE res = spi->write(0xFF); // Receive data response
oks486 0:43cce7b453d0 255 if ((res & 0x1F) != 0x05) { // if the data packet was not accepted
oks486 0:43cce7b453d0 256 return 0;
oks486 0:43cce7b453d0 257 }
oks486 0:43cce7b453d0 258 }
oks486 0:43cce7b453d0 259
oks486 0:43cce7b453d0 260 return 1;
oks486 0:43cce7b453d0 261 }
oks486 0:43cce7b453d0 262
oks486 0:43cce7b453d0 263
oks486 0:43cce7b453d0 264 DSTATUS FatfsIJFW::disk_initialize(BYTE drv) {
oks486 0:43cce7b453d0 265 if (drv) { // drive 0 only
oks486 0:43cce7b453d0 266 return STA_NOINIT;
oks486 0:43cce7b453d0 267 }
oks486 0:43cce7b453d0 268
oks486 0:43cce7b453d0 269 // Set spi slow clock
oks486 0:43cce7b453d0 270 spi->frequency(400000);
oks486 0:43cce7b453d0 271 cs->write(1);
oks486 0:43cce7b453d0 272
oks486 0:43cce7b453d0 273 // Send 80 dummy clocks
oks486 0:43cce7b453d0 274 for (int i = 0; i < 10; i++) {
oks486 0:43cce7b453d0 275 spi->write(0xFF);
oks486 0:43cce7b453d0 276 }
oks486 0:43cce7b453d0 277
oks486 0:43cce7b453d0 278 CardType = 0;
oks486 0:43cce7b453d0 279 if (sendCommand(CMD0, 0) == 1) { // reset card
oks486 0:43cce7b453d0 280 timerCount = 1000; // Timeout is 1ms
oks486 0:43cce7b453d0 281
oks486 0:43cce7b453d0 282 if (sendCommand(CMD8, 0x1AA) == 1) {
oks486 0:43cce7b453d0 283 // Get value of R7 response
oks486 0:43cce7b453d0 284 int ocr[4];
oks486 0:43cce7b453d0 285 for (int i = 0; i < 4; i++) {
oks486 0:43cce7b453d0 286 ocr[i] = spi->write(0xFF);
oks486 0:43cce7b453d0 287 }
oks486 0:43cce7b453d0 288
oks486 0:43cce7b453d0 289 if (ocr[2] == 0x01 && ocr[3] == 0xAA) {
oks486 0:43cce7b453d0 290 // Wait for end of initialization
oks486 0:43cce7b453d0 291 while (timerCount > 0 && sendCommand(ACMD41, 1UL << 30));
oks486 0:43cce7b453d0 292
oks486 0:43cce7b453d0 293 if (timerCount && sendCommand(CMD58, 0) == 0) {
oks486 0:43cce7b453d0 294 // Check CCS bit
oks486 0:43cce7b453d0 295 for (int i = 0; i < 4; i++) {
oks486 0:43cce7b453d0 296 ocr[i] = spi->write(0xFF);
oks486 0:43cce7b453d0 297 }
oks486 0:43cce7b453d0 298 if (ocr[0] & 0x40) {
oks486 0:43cce7b453d0 299 CardType = 0x04 | 0x08;
oks486 0:43cce7b453d0 300 } else {
oks486 0:43cce7b453d0 301 CardType = 0x04;
oks486 0:43cce7b453d0 302 }
oks486 0:43cce7b453d0 303 }
oks486 0:43cce7b453d0 304 }
oks486 0:43cce7b453d0 305 } else {
oks486 0:43cce7b453d0 306 if (sendCommand(ACMD41, 0) <= 1) {
oks486 0:43cce7b453d0 307 CardType = 0x02;
oks486 0:43cce7b453d0 308 while (timerCount > 0 && sendCommand(ACMD41, 0)); // initialization
oks486 0:43cce7b453d0 309 } else {
oks486 0:43cce7b453d0 310 CardType = 0x01;
oks486 0:43cce7b453d0 311 while (timerCount > 0 && sendCommand(CMD1, 0)); // initialization
oks486 0:43cce7b453d0 312 }
oks486 0:43cce7b453d0 313
oks486 0:43cce7b453d0 314 if (timerCount == 0 || sendCommand(CMD16, 512) != 0) {
oks486 0:43cce7b453d0 315 CardType = 0;
oks486 0:43cce7b453d0 316 }
oks486 0:43cce7b453d0 317 }
oks486 0:43cce7b453d0 318 }
oks486 0:43cce7b453d0 319
oks486 0:43cce7b453d0 320 deselect();
oks486 0:43cce7b453d0 321
oks486 0:43cce7b453d0 322 if (CardType) {
oks486 0:43cce7b453d0 323 spi->frequency(1000000); // Set spi 1MHz
oks486 0:43cce7b453d0 324 Stat &= ~STA_NOINIT; // Clear STA_NOINIT flag
oks486 0:43cce7b453d0 325 } else {
oks486 0:43cce7b453d0 326 select();
oks486 0:43cce7b453d0 327 deselect();
oks486 0:43cce7b453d0 328 Stat = STA_NOINIT;
oks486 0:43cce7b453d0 329 }
oks486 0:43cce7b453d0 330
oks486 0:43cce7b453d0 331 return Stat;
oks486 0:43cce7b453d0 332 }
oks486 0:43cce7b453d0 333
oks486 0:43cce7b453d0 334
oks486 0:43cce7b453d0 335 DSTATUS FatfsIJFW::disk_status(BYTE drv) {
oks486 0:43cce7b453d0 336 return RES_OK;
oks486 0:43cce7b453d0 337 }
oks486 0:43cce7b453d0 338
oks486 0:43cce7b453d0 339
oks486 0:43cce7b453d0 340 DRESULT FatfsIJFW::disk_read(BYTE drv, BYTE *buff, DWORD sector, UINT count) {
oks486 0:43cce7b453d0 341 // if drive is not ready
oks486 0:43cce7b453d0 342 if (Stat & STA_NOINIT) {
oks486 0:43cce7b453d0 343 return RES_NOTRDY;
oks486 0:43cce7b453d0 344 }
oks486 0:43cce7b453d0 345
oks486 0:43cce7b453d0 346 if (drv || !count) {
oks486 0:43cce7b453d0 347 return RES_PARERR;
oks486 0:43cce7b453d0 348 }
oks486 0:43cce7b453d0 349
oks486 0:43cce7b453d0 350 // if byte address is BA
oks486 0:43cce7b453d0 351 if (!(CardType & 0x08)) {
oks486 0:43cce7b453d0 352 sector *= 512;
oks486 0:43cce7b453d0 353 }
oks486 0:43cce7b453d0 354
oks486 0:43cce7b453d0 355 // Read a single block or multiple blocks
oks486 0:43cce7b453d0 356 BYTE cmd = count > 1 ? CMD18 : CMD17;
oks486 0:43cce7b453d0 357 if (sendCommand(cmd, sector) == 0) {
oks486 0:43cce7b453d0 358 while (count > 0) {
oks486 0:43cce7b453d0 359 if (!rcvDataBlock(buff, 512)) {
oks486 0:43cce7b453d0 360 if (cmd == CMD18) {
oks486 0:43cce7b453d0 361 sendCommand(CMD12, 0);
oks486 0:43cce7b453d0 362 }
oks486 0:43cce7b453d0 363 break;
oks486 0:43cce7b453d0 364 }
oks486 0:43cce7b453d0 365 buff += 512;
oks486 0:43cce7b453d0 366 count--;
oks486 0:43cce7b453d0 367 }
oks486 0:43cce7b453d0 368 }
oks486 0:43cce7b453d0 369 deselect();
oks486 0:43cce7b453d0 370
oks486 0:43cce7b453d0 371 return count ? RES_ERROR : RES_OK;
oks486 0:43cce7b453d0 372 }
oks486 0:43cce7b453d0 373
oks486 0:43cce7b453d0 374
oks486 0:43cce7b453d0 375 DRESULT FatfsIJFW::disk_write(BYTE drv, const BYTE *buff, DWORD sector, UINT count) {
oks486 0:43cce7b453d0 376 // if drive is not ready
oks486 0:43cce7b453d0 377 if (Stat & STA_NOINIT) {
oks486 0:43cce7b453d0 378 return RES_NOTRDY;
oks486 0:43cce7b453d0 379 }
oks486 0:43cce7b453d0 380
oks486 0:43cce7b453d0 381 if (drv || !count) {
oks486 0:43cce7b453d0 382 return RES_PARERR;
oks486 0:43cce7b453d0 383 }
oks486 0:43cce7b453d0 384
oks486 0:43cce7b453d0 385 // if byte address is BA
oks486 0:43cce7b453d0 386 if (!(CardType & 0x08)) {
oks486 0:43cce7b453d0 387 sector *= 512;
oks486 0:43cce7b453d0 388 }
oks486 0:43cce7b453d0 389
oks486 0:43cce7b453d0 390 // Write a single block or multiple blocks
oks486 0:43cce7b453d0 391 DRESULT res = RES_ERROR;
oks486 0:43cce7b453d0 392 if (count > 1) {
oks486 0:43cce7b453d0 393 if (CardType & 0x06) {
oks486 0:43cce7b453d0 394 sendCommand(ACMD23, count); // Send predefine number of sectors
oks486 0:43cce7b453d0 395 }
oks486 0:43cce7b453d0 396 if (sendCommand(CMD25, sector) == 0) {
oks486 0:43cce7b453d0 397 while (count > 0) {
oks486 0:43cce7b453d0 398 if (!sendDataBlock(buff, 0xFC)) {
oks486 0:43cce7b453d0 399 break;
oks486 0:43cce7b453d0 400 }
oks486 0:43cce7b453d0 401 buff += 512;
oks486 0:43cce7b453d0 402 count--;
oks486 0:43cce7b453d0 403 }
oks486 0:43cce7b453d0 404 if (sendDataBlock(0, 0xFD)) {
oks486 0:43cce7b453d0 405 res = RES_OK;
oks486 0:43cce7b453d0 406 }
oks486 0:43cce7b453d0 407 }
oks486 0:43cce7b453d0 408 } else {
oks486 0:43cce7b453d0 409 if (sendCommand(CMD24, sector) == 0) {
oks486 0:43cce7b453d0 410 if (sendDataBlock(buff, 0xFE)) {
oks486 0:43cce7b453d0 411 res = RES_OK;
oks486 0:43cce7b453d0 412 }
oks486 0:43cce7b453d0 413 }
oks486 0:43cce7b453d0 414 }
oks486 0:43cce7b453d0 415 deselect();
oks486 0:43cce7b453d0 416
oks486 0:43cce7b453d0 417 return res;
oks486 0:43cce7b453d0 418 }
oks486 0:43cce7b453d0 419
oks486 0:43cce7b453d0 420
oks486 0:43cce7b453d0 421 DRESULT FatfsIJFW::disk_ioctl(BYTE drv, BYTE cmd, void* buff) {
oks486 0:43cce7b453d0 422 // ioctl is not supported
oks486 0:43cce7b453d0 423 return RES_ERROR;
oks486 0:43cce7b453d0 424 }
oks486 0:43cce7b453d0 425