50 SDArduinoSPIIO(
int cs = -1, SPIClass &spi = SPI) { setSPI(cs, spi); }
53 void setSPI(SPIClass &spi = SPI) {
58 void setSPI(
int cs = -1, SPIClass &spi = SPI) {
66 DSTATUS disk_initialize(BYTE drv
68 BYTE n, cmd, ty, ocr[4];
70 if (drv != 0)
return STA_NOINIT;
73 if (stat & STA_NODISK)
return stat;
76 for (n = 10; n; n--) xchg_spi(0xFF);
79 if (send_cmd(CMD0, 0) == 1) {
81 if (send_cmd(CMD8, 0x1AA) == 1) {
82 for (n = 0; n < 4; n++)
83 ocr[n] = xchg_spi(0xFF);
86 while (spi_timer_status() &&
87 send_cmd(ACMD41, 1UL << 30));
89 if (spi_timer_status() &&
90 send_cmd(CMD58, 0) == 0) {
91 for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF);
93 (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;
97 if (send_cmd(ACMD41, 0) <= 1) {
104 while (spi_timer_status() &&
106 if (!spi_timer_status() ||
107 send_cmd(CMD16, 512) != 0)
128 DSTATUS disk_status(BYTE drv
130 if (drv)
return STA_NOINIT;
144 if (drv || !count)
return RES_PARERR;
145 if (stat & STA_NOINIT)
return RES_NOTRDY;
147 if (!(CardType & CT_BLOCK))
151 if ((send_cmd(CMD17, sector) == 0)
152 && rcvr_datablock(buff, 512)) {
156 if (send_cmd(CMD18, sector) == 0) {
158 if (!rcvr_datablock(buff, 512))
break;
166 return count ? RES_ERROR : RES_OK;
174 DRESULT disk_write(BYTE drv,
179 if (drv || !count)
return RES_PARERR;
180 if (stat & STA_NOINIT)
return RES_NOTRDY;
181 if (stat & STA_PROTECT)
return RES_WRPRT;
183 if (!(CardType & CT_BLOCK))
187 if ((send_cmd(CMD24, sector) == 0)
188 && xmit_datablock(buff, 0xFE)) {
192 if (CardType & CT_SDC)
193 send_cmd(ACMD23, count);
194 if (send_cmd(CMD25, sector) == 0) {
196 if (!xmit_datablock(buff, 0xFC))
break;
199 if (!xmit_datablock(0, 0xFD)) count = 1;
204 return count ? RES_ERROR : RES_OK;
213 DRESULT disk_ioctl(BYTE drv,
219 DWORD *dp, st, ed, csize;
221 if (drv)
return RES_PARERR;
222 if (stat & STA_NOINIT)
return RES_NOTRDY;
228 if (spiselect()) res = RES_OK;
231 case GET_SECTOR_COUNT:
232 if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {
233 if ((csd[0] >> 6) == 1) {
235 csd[9] + ((WORD)csd[8] << 8) + ((DWORD)(csd[7] & 63) << 16) + 1;
236 *(DWORD *)buff = csize << 10;
238 n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) +
240 csize = (csd[8] >> 6) + ((WORD)csd[7] << 2) +
241 ((WORD)(csd[6] & 3) << 10) + 1;
242 *(DWORD *)buff = csize << (n - 9);
249 if (CardType & CT_SD2) {
250 if (send_cmd(ACMD13, 0) == 0) {
252 if (rcvr_datablock(csd, 16)) {
253 for (n = 64 - 16; n; n--)
255 *(DWORD *)buff = 16UL << (csd[10] >> 4);
260 if ((send_cmd(CMD9, 0) == 0) &&
261 rcvr_datablock(csd, 16)) {
262 if (CardType & CT_SD1) {
264 (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7) + 1)
265 << ((csd[13] >> 6) - 1);
268 ((WORD)((csd[10] & 124) >> 2) + 1) *
269 (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1);
278 if (!(CardType & CT_SDC))
break;
279 if (disk_ioctl(drv, MMC_GET_CSD, csd))
break;
280 if (!(csd[0] >> 6) && !(csd[10] & 0x40))
285 if (!(CardType & CT_BLOCK)) {
289 if (send_cmd(CMD32, st) == 0 && send_cmd(CMD33, ed) == 0 &&
290 send_cmd(CMD38, 0) == 0 &&
308 volatile DSTATUS stat = STA_NOINIT;
310 SPIClass *p_spi = &SPI;
311 SPISettings spi_slow{280000, MSBFIRST, SPI_MODE0};
312 SPISettings spi_fast{4500000, MSBFIRST, SPI_MODE0};
313 SPISettings spi_settings;
314 uint32_t spi_timeout;
317 void spi_timer_on(uint32_t waitTicks) { spi_timeout = millis() + waitTicks; }
319 bool spi_timer_status() {
return (millis() < spi_timeout); }
322 void set_spi_fast(
bool fast) { spi_settings = fast ? spi_fast : spi_slow; }
326 if (cs != -1) digitalWrite(cs, high);
330 inline BYTE xchg_spi(BYTE dat) {
return p_spi->transfer(dat); }
333 void xchg_spi_multi(BYTE *buff, UINT btr) { p_spi->transfer(buff, btr); }
342 uint32_t timeout = millis() + wt;
348 }
while (d != 0xFF && ((millis() < timeout)));
350 return (d == 0xFF) ? 1 : 0;
355 void despiselect(
void) {
356 p_spi->endTransaction();
365 p_spi->beginTransaction(spi_settings);
368 if (wait_ready(500))
return 1;
382 uint64_t end = millis() + 200;
384 token = xchg_spi(0xFF);
387 }
while ((token == 0xFF) && millis() < end);
391 xchg_spi_multi(buff, btr);
407 if (!wait_ready(500))
return 0;
411 xchg_spi_multi(buff, 512);
415 resp = xchg_spi(0xFF);
416 if ((resp & 0x1F) != 0x05)
432 res = send_cmd(CMD55, 0);
433 if (res > 1)
return res;
439 if (!spiselect())
return 0xFF;
443 xchg_spi(0x40 | cmd);
444 xchg_spi((BYTE)(arg >> 24));
445 xchg_spi((BYTE)(arg >> 16));
446 xchg_spi((BYTE)(arg >> 8));
449 if (cmd == CMD0) n = 0x95;
450 if (cmd == CMD8) n = 0x87;
458 res = xchg_spi(0xFF);
459 }
while ((res & 0x80) && --n);
Empty IO implementation that we can use to test the compilation.
Definition: BaseIO.h:10
Accessing a SD card via the Arduino SPI API.
Definition: SDArduinoSPIIO.h:48
void set_spi_fast(bool fast)
set fast/slow SPI speed
Definition: SDArduinoSPIIO.h:322
void set_cs(bool high)
update the CS pin
Definition: SDArduinoSPIIO.h:325