1616#include "supervisor/shared/tick.h"
1717
1818#include "py/mperrno.h"
19+ #include "py/mphal.h"
1920
2021#if 0
2122#define DEBUG_PRINT (...) ((void)mp_printf(&mp_plat_print,##__VA_ARGS__))
2223#else
2324#define DEBUG_PRINT (...) ((void)0)
2425#endif
2526
27+ // https://nodeloop.org/guides/sd-card-spi-init-guide/ is an excellent source of info for SPI card use.
28+
2629// https://www.taterli.com/wp-content/uploads/2017/05/Physical-Layer-Simplified-SpecificationV6.0.pdf
2730// specifies timeouts for read (100 ms), write (250 ms), erase (depends on size), and other operations.
2831// But the document also suggests allowing 500 ms even if a shorter timeout is specified.
29- // So let's allow a nice long time, but don't wait in a tight loop: allow background tasks to run.
30- #define CMD_TIMEOUT_MS (500)
31- #define TIMEOUT_MS (500)
32- #define SPI_TIMEOUT_MS (10000)
32+ #define CMD_TIMEOUT_MS (250)
33+ #define SPI_TIMEOUT_MS (250)
34+ // Init ready timeout.
35+ #define READY_TIMEOUT_MS (300)
36+
3337
3438#define R1_IDLE_STATE (1 << 0)
3539#define R1_ILLEGAL_COMMAND (1 << 2)
@@ -84,11 +88,10 @@ static void lock_bus_or_throw(sdcardio_sdcard_obj_t *self) {
8488}
8589
8690static void clock_card (sdcardio_sdcard_obj_t * self , int bytes ) {
87- uint8_t buf [] = {0xff };
91+ uint8_t buf [bytes ];
92+ memset (buf , 0xff , bytes );
8893 common_hal_digitalio_digitalinout_set_value (& self -> cs , true);
89- for (int i = 0 ; i < bytes ; i ++ ) {
90- common_hal_busio_spi_write (self -> bus , buf , 1 );
91- }
94+ common_hal_busio_spi_write (self -> bus , buf , bytes );
9295}
9396
9497static void extraclock_and_unlock_bus (sdcardio_sdcard_obj_t * self ) {
@@ -124,19 +127,16 @@ static int32_t wait_for_masked_response(sdcardio_sdcard_obj_t *self, uint8_t mas
124127 if (((b & mask ) == response ) ^ not_match ) {
125128 return b ;
126129 }
127- RUN_BACKGROUND_TASKS ;
128130 }
129131 return -1 ;
130132}
131133
132134// Wait for the given response byte.
133135static bool wait_for_response (sdcardio_sdcard_obj_t * self , uint8_t response ) {
134- return wait_for_masked_response (self , 0xff , response , false, TIMEOUT_MS ) != -1 ;
136+ return wait_for_masked_response (self , 0xff , response , false, CMD_TIMEOUT_MS ) != -1 ;
135137}
136138
137- #define READY_TIMEOUT_MS (300)
138-
139- // Wait for 0xff, with a shorter timeout.
139+ // Wait for 0xff, with a specific timeout.
140140static bool wait_for_ready (sdcardio_sdcard_obj_t * self ) {
141141 return wait_for_masked_response (self , 0xff , 0xff , false, READY_TIMEOUT_MS ) != -1 ;
142142}
@@ -232,7 +232,6 @@ static mp_rom_error_text_t init_card_v1(sdcardio_sdcard_obj_t *self) {
232232 if (cmd (self , 41 , 0 , NULL , 0 , true, true) == 0 ) {
233233 return NULL ;
234234 }
235- RUN_BACKGROUND_TASKS ;
236235 }
237236 return MP_ERROR_TEXT ("timeout waiting for v1 card" );
238237}
@@ -251,12 +250,13 @@ static mp_rom_error_text_t init_card_v2(sdcardio_sdcard_obj_t *self) {
251250 }
252251 return NULL ;
253252 }
254- RUN_BACKGROUND_TASKS ;
255253 }
256254 return MP_ERROR_TEXT ("timeout waiting for v2 card" );
257255}
258256
259257static mp_rom_error_text_t init_card (sdcardio_sdcard_obj_t * self ) {
258+ // https://nodeloop.org/guides/sd-card-spi-init-guide/ recommends at least 74 bit clocks
259+ // and says 80 bit clocks(10*8) is common. Value below is bytes, not bits.
260260 clock_card (self , 10 );
261261
262262 common_hal_digitalio_digitalinout_set_value (& self -> cs , false);
@@ -476,21 +476,19 @@ static int _write(sdcardio_sdcard_obj_t *self, uint8_t token, void *buf, size_t
476476 uint64_t deadline = supervisor_ticks_ms64 () + CMD_TIMEOUT_MS ;
477477 while (supervisor_ticks_ms64 () < deadline ) {
478478 common_hal_busio_spi_read (self -> bus , cmd , 1 , 0xff );
479- DEBUG_PRINT ("i=%02d cmd[0] = 0x%02x\n" , i , cmd [0 ]);
480479 if ((cmd [0 ] & 0b00010001 ) == 0b00000001 ) {
481480 if ((cmd [0 ] & 0x1f ) != 0x5 ) {
482481 return - MP_EIO ;
483482 } else {
484483 break ;
485484 }
486485 }
487- RUN_BACKGROUND_TASKS ;
488486 }
489487
490488 // Wait for the write to finish
491489
492490 // Wait for a non-zero value.
493- if (wait_for_masked_response (self , 0xff /*mask*/ , 0 , true /*not_match*/ , TIMEOUT_MS ) == -1 ) {
491+ if (wait_for_masked_response (self , 0xff /*mask*/ , 0 , true /*not_match*/ , CMD_TIMEOUT_MS ) == -1 ) {
494492 return - MP_EIO ;
495493 }
496494
0 commit comments