IJFW - IchigoJamのBASICプログラムをメモリカード(MMCまたは互換カード)に保存したり読み出したりできるプログラム。メモリカードにファームウェアのファイルを置くだけで、電源ON時に自動的に書き換える機能も搭載(一応こちらがメイン)。LPC1114FN28専用。
参考URL http://www.cyberchabudai.org/index.php/entry?tag=IJFW
FatfsIJFW/FatfsIJFW.cpp@2:daf6c4719496, 2016-08-21 (annotated)
- 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?
User | Revision | Line number | New 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 |