32#if defined(PICO_BUILD)
35#include "pico/stdlib.h"
36#include "hardware/clocks.h"
37#include "hardware/spi.h"
38#include "hardware/gpio.h"
43#include "hardware/spi.h"
46#define SPI_ACTIVE spi1
47#define PIN_SPI0_SCK 10
48#define PIN_SPI0_MOSI 11
49#define PIN_SPI0_MISO 12
67#define ACMD41 (0x80+41)
72#define ACMD13 (0x80+13)
77#define ACMD23 (0x80+23)
90#define CT_SDC (CT_SD1|CT_SD2)
93#define CLK_SLOW (100 * KHZ)
94#define CLK_FAST (50 * MHZ)
104 return to_ms_since_boot(get_absolute_time());
111static inline void cs_select(uint cs_pin) {
112 asm volatile(
"nop \n nop \n nop");
114 asm volatile(
"nop \n nop \n nop");
117static inline void cs_deselect(uint cs_pin) {
118 asm volatile(
"nop \n nop \n nop");
120 asm volatile(
"nop \n nop \n nop");
123static void FCLK_SLOW(
void)
125 spi_set_baudrate(SPI_ACTIVE, CLK_SLOW);
128static void FCLK_FAST(
void)
130 spi_set_baudrate(SPI_ACTIVE, CLK_FAST);
133static void CS_HIGH(
void)
135 cs_deselect(PIN_SPI0_CS);
138static void CS_LOW(
void)
140 cs_select(PIN_SPI0_CS);
150 gpio_init(PIN_SPI0_SCK);
151 gpio_pull_up(PIN_SPI0_SCK);
152 gpio_set_drive_strength(PIN_SPI0_SCK, PADS_BANK0_GPIO0_DRIVE_VALUE_4MA);
153 gpio_set_slew_rate(PIN_SPI0_SCK, 0);
154 gpio_set_function(PIN_SPI0_SCK, GPIO_FUNC_SPI);
156 gpio_init(PIN_SPI0_MISO);
157 gpio_pull_up(PIN_SPI0_MISO);
158 gpio_set_input_hysteresis_enabled(PIN_SPI0_MISO, 1);
159 gpio_set_function(PIN_SPI0_MISO, GPIO_FUNC_SPI);
161 gpio_init(PIN_SPI0_MOSI);
162 gpio_pull_up(PIN_SPI0_MOSI);
163 gpio_set_drive_strength(PIN_SPI0_MOSI, PADS_BANK0_GPIO0_DRIVE_VALUE_4MA);
164 gpio_set_slew_rate(PIN_SPI0_MOSI, 0);
165 gpio_set_function(PIN_SPI0_MOSI, GPIO_FUNC_SPI);
167 gpio_init(PIN_SPI0_CS);
168 gpio_pull_up(PIN_SPI0_CS);
169 gpio_set_drive_strength(PIN_SPI0_CS, PADS_BANK0_GPIO0_DRIVE_VALUE_4MA);
170 gpio_set_slew_rate(PIN_SPI0_CS, 0);
171 gpio_set_dir(PIN_SPI0_CS, GPIO_OUT);
176 spi_init(SPI_ACTIVE, CLK_SLOW);
179 spi_set_format(SPI_ACTIVE,
194 spi_write_read_blocking(SPI_ACTIVE, buff, buff, 1);
207 spi_read_blocking(SPI_ACTIVE, 0xff,
b, btr);
226 }
while (
d != 0xFF && _millis() < t + wt);
228 return (
d == 0xFF) ? 1 : 0;
255 if (wait_ready(500))
return 1;
278 token = xchg_spi(0xFF);
280 }
while (token == 0xFF && _millis() < t + timeout);
281 if(token != 0xFE)
return 0;
283 rcvr_spi_multi(buff, btr);
284 xchg_spi(0xFF); xchg_spi(0xFF);
305 res = send_cmd(CMD55, 0);
306 if (res > 1)
return res;
312 if (!_select())
return 0xFF;
316 xchg_spi(0x40 |
cmd);
317 xchg_spi((
BYTE)(arg >> 24));
318 xchg_spi((
BYTE)(arg >> 16));
319 xchg_spi((
BYTE)(arg >> 8));
322 if (
cmd == CMD0) n = 0x95;
323 if (
cmd == CMD8) n = 0x87;
327 if (
cmd == CMD12) xchg_spi(0xFF);
330 res = xchg_spi(0xFF);
331 }
while ((res & 0x80) && --n);
364 for (n = 10; n; n--) xchg_spi(0xFF);
367 if (send_cmd(CMD0, 0) == 1) {
369 if (send_cmd(CMD8, 0x1AA) == 1) {
370 for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF);
371 if (ocr[2] == 0x01 && ocr[3] == 0xAA) {
372 while (_millis() < t + timeout && send_cmd(ACMD41, 1UL << 30)) ;
373 if (_millis() < t + timeout && send_cmd(CMD58, 0) == 0) {
374 for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF);
375 ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;
379 if (send_cmd(ACMD41, 0) <= 1) {
380 ty = CT_SD1;
cmd = ACMD41;
382 ty = CT_MMC;
cmd = CMD1;
384 while (_millis() < t + timeout && send_cmd(
cmd, 0)) ;
385 if (_millis() >= t + timeout || send_cmd(CMD16, 512) != 0)
433 if (!(CardType & CT_BLOCK)) sector *= 512;
436 if ((send_cmd(CMD17, sector) == 0)
437 && rcvr_datablock(buff, 512)) {
442 if (send_cmd(CMD18, sector) == 0) {
444 if (!rcvr_datablock(buff, 512))
break;
457#if !FF_FS_READONLY && !FF_FS_NORTC
459DWORD get_fattime (
void)
465#if FF_FS_READONLY == 0
474 spi_write_blocking(SPI_ACTIVE,
b, btx);
488 if (!wait_ready(500))
return 0;
491 xmit_spi_multi(buff, 512);
494 resp = xchg_spi(0xFF);
495 if ((resp & 0x1F) != 0x05)
516 if (!(CardType & CT_BLOCK)) sector *= 512;
521 if ((send_cmd(CMD24, sector) == 0)
522 && xmit_datablock(buff, 0xFE)) {
527 if (CardType & CT_SDC) send_cmd(ACMD23, count);
528 if (send_cmd(CMD25, sector) == 0) {
530 if (!xmit_datablock(buff, 0xFC))
break;
533 if (!xmit_datablock(0, 0xFD)) count = 1;
555 DWORD *dp, st, ed, csize;
565 if (_select()) res =
RES_OK;
569 if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {
570 if ((csd[0] >> 6) == 1) {
571 csize = csd[9] + ((
WORD)csd[8] << 8) + ((
DWORD)(csd[7] & 63) << 16) + 1;
572 *(
DWORD*)buff = csize << 10;
574 n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
575 csize = (csd[8] >> 6) + ((
WORD)csd[7] << 2) + ((
WORD)(csd[6] & 3) << 10) + 1;
576 *(
DWORD*)buff = csize << (n - 9);
583 if (CardType & CT_SD2) {
584 if (send_cmd(ACMD13, 0) == 0) {
586 if (rcvr_datablock(csd, 16)) {
587 for (n = 64 - 16; n; n--) xchg_spi(0xFF);
588 *(
DWORD*)buff = 16UL << (csd[10] >> 4);
593 if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {
594 if (CardType & CT_SD1) {
595 *(
DWORD*)buff = (((csd[10] & 63) << 1) + ((
WORD)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1);
597 *(
DWORD*)buff = ((
WORD)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1);
605 if (!(CardType & CT_SDC))
break;
607 if (!(csd[0] >> 6) && !(csd[10] & 0x40))
break;
608 dp = buff; st = dp[0]; ed = dp[1];
609 if (!(CardType & CT_BLOCK)) {
610 st *= 512; ed *= 512;
612 if (send_cmd(CMD32, st) == 0 && send_cmd(CMD33, ed) == 0 && send_cmd(CMD38, 0) == 0 && wait_ready(30000)) {
static ft_void_t ft_uint32_t * cmd
DRESULT disk_read(BYTE pdrv, BYTE *buff, LBA_t sector, UINT count)
DSTATUS disk_initialize(BYTE pdrv)
DSTATUS disk_status(BYTE pdrv)
DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff)
DRESULT disk_write(BYTE pdrv, const BYTE *buff, LBA_t sector, UINT count)