SD Card At Startup Fails #1

Closed
opened 2026-02-14 10:12:37 -08:00 by jlpoole · 3 comments
Owner

The exercise for the SD Card seems to always fail when a card is already inserted and the unit boots up. If I remove the card and then re-insert it, then the card is seen. I'm documenting this Issue so it does not get forgotten, it is something that needs to be debugged.

The exercise for the SD Card seems to always fail when a card is already inserted and the unit boots up. If I remove the card and then re-insert it, then the card is seen. I'm documenting this Issue so it does not get forgotten, it is something that needs to be debugged.
Author
Owner

Current version:

	(rnsenv) jlpoole@jp /usr/local/src/microreticulum/microReticulumTbeam/exercises/05_SD_Card_Watcher $ git log -n 1
	commit 432f17b2be2c8420b3ea8b66d84dc5ba2a81d48f (HEAD -> feature/fieldtest-beacon-sd-provision, origin/feature/fieldtest-beacon-sd-provision)
	Author: John Poole <jlpoole56@gmail.com>
	Date:   Sat Feb 14 10:10:31 2026 -0800

I loaded and started the above version. At around line 88, I removed the card and re-inserted it:

	jlpoole@jp /usr/local/src/microreticulum/microReticulumTbeam/exercises/00_usb_radio_check $ cat -n /tmp/ex06_sdwatch_20260214_Sat_1328.log
	     1  [WATCHER: startup]
	     2  Sleeping for 5 seconds to allow Serial Monitor connection...
	     3
	     4  ==================================================
	     5  Exercise 05: SD Card Watcher
	     6  ==================================================
	     7  Pins: CS=47 SCK=36 MISO=37 MOSI=35
	     8  PMU I2C: SDA1=42 SCL1=41
	     9  Note: SD must be FAT16/FAT32 for Arduino SD library.
	    10
	    11  PMU adapter: AXP2101 ready, BLDO1(SD)=ON
	    12  [      5146][000000] Watcher: waiting 1500 ms for SD rail/card stabilization
	    13  [  6673][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume
	    14  [  6909][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume
	    15  [  7145][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume
	    16  [      7354][000001] Watcher: startup warmup did not mount card
	    17  [      7354][000002] EVENT: no card detected
	    18  [  7381][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume
	    19  [  8387][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume
	    20  [  9393][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume
	    21  [ 10399][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume
	    22  [     10407][000003] Watcher: preferred probe failed, running full scan
	    23  [     10420][000004] SD: trying bus=HSPI freq=400000 Hz
	    24  [ 10435][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume
	    25  [     10444][000005] SD: mount failed (possible non-FAT format, power, or bus issue)
	    26  [     10456][000006] SD: trying bus=HSPI freq=1000000 Hz
	    27  [ 10464][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume
	    28  [     10473][000007] SD: mount failed (possible non-FAT format, power, or bus issue)
	    29  [     10486][000008] SD: trying bus=HSPI freq=4000000 Hz
	    30  [ 10491][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume
	    31  [     10500][000009] SD: mount failed (possible non-FAT format, power, or bus issue)
	    32  [     10512][000010] SD: trying bus=HSPI freq=10000000 Hz
	    33  [ 10517][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume
	    34  [     10525][000011] SD: mount failed (possible non-FAT format, power, or bus issue)
	    35  [     10538][000012] SD: trying bus=FSPI freq=400000 Hz
	    36  [ 10553][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume
	    37  [     10562][000013] SD: mount failed (possible non-FAT format, power, or bus issue)
	    38  [     10574][000014] SD: trying bus=FSPI freq=1000000 Hz
	    39  [ 10582][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume
	    40  [     10591][000015] SD: mount failed (possible non-FAT format, power, or bus issue)
	    41  [     10604][000016] SD: trying bus=FSPI freq=4000000 Hz
	    42  [ 10609][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume
	    43  [     10618][000017] SD: mount failed (possible non-FAT format, power, or bus issue)
	    44  [     10630][000018] SD: trying bus=FSPI freq=10000000 Hz
	    45  [ 10635][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume
	    46  [     10643][000019] SD: mount failed (possible non-FAT format, power, or bus issue)
	    47  [     10643][000020] SD: begin() failed on all bus/frequency attempts
	    48  [     10643][000021]     likely card absent, bad format, pin mismatch, or hardware issue
	    49  [ 11401][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume
	    50  [ 12407][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume
	    51  [ 13413][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume
	    52  [ 14419][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume
	    53  [ 15425][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume
	    54  [ 16431][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume
	    55  [ 17437][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume
	    56  [ 18729][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00
	    57  [ 18735][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (3) The physical drive cannot work
	    58  [ 19044][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00
	    59  [ 19733][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00
	    60  [ 19739][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (3) The physical drive cannot work
	    61  [ 20048][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00
	    62  [ 20737][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00
	    63  [ 20743][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (3) The physical drive cannot work
	    64  [ 21052][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00
	    65  [     21058][000022] Watcher: preferred probe failed, running full scan
	    66  [     21070][000023] SD: trying bus=HSPI freq=400000 Hz
	    67  [ 21371][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00
	    68  [ 21377][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (3) The physical drive cannot work
	    69  [ 21686][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00
	    70  [     21692][000024] SD: mount failed (possible non-FAT format, power, or bus issue)
	    71  [     21704][000025] SD: trying bus=HSPI freq=1000000 Hz
	    72  [ 22005][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00
	    73  [ 22011][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (3) The physical drive cannot work
	    74  [ 22320][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00
	    75  [     22326][000026] SD: mount failed (possible non-FAT format, power, or bus issue)
	    76  [     22338][000027] SD: trying bus=HSPI freq=4000000 Hz
	    77  [ 22639][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00
	    78  [ 22645][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (3) The physical drive cannot work
	    79  [ 22954][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00
	    80  [     22960][000028] SD: mount failed (possible non-FAT format, power, or bus issue)
	    81  [     22972][000029] SD: trying bus=HSPI freq=10000000 Hz
	    82  [ 23273][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00
	    83  [ 23279][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (3) The physical drive cannot work
	    84  [ 23588][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00
	    85  [     23594][000030] SD: mount failed (possible non-FAT format, power, or bus issue)
	    86  [     23606][000031] SD: trying bus=FSPI freq=400000 Hz
	    87  [ 23907][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00
	    88  [ 23913][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (3) The physical drive cannot work
	    89  [ 24222][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00
	    90  [     24228][000032] SD: mount failed (possible non-FAT format, power, or bus issue)
	    91  [     24240][000033] SD: trying bus=FSPI freq=1000000 Hz
	    92  [     24544][000034] SD: card detected and mounted
	    93  [     24594][000035] EVENT: card inserted/mounted
	    94  [     24595][000036] SD type: SDHC/SDXC
	    95  [     24595][000037] SD size: 14910 MB
	    96  [     24595][000038] FS total: 14895 MB
	    97  [     24595][000039] FS used : 0 MB
	    98  [     24595][000040] SPI bus: HSPI @ 400000 Hz
	    99  [     24608][000041] WARNING: /Exercise_05_test.txt exists ... erasing
	   100  [     24776][000042] Wrote file: /Exercise_05_test.txt
	   101  [     24984][000043] WARNING: /test/testsub1/testsubsub1/Exercise_05_test.txt exists ... erasing
	   102  [     25459][000044] Wrote file: /test/testsub1/testsubsub1/Exercise_05_test.txt
	   103  [     25459][000045] Permissions demo:
	   104  [     25459][000046]   SD/FAT does not support Unix permissions (chmod/chown).
	   105  [     25459][000047]   Access control is by open mode (FILE_READ/FILE_WRITE).
	   106  [     25472][000048]   FILE_READ open succeeded, size=16 bytes
	   107  [     25472][000049]   As expected, write via FILE_READ handle was blocked.
	jlpoole@jp /usr/local/src/microreticulum/microReticulumTbeam/exercises/00_usb_radio_check $ 
Current version: ``` (rnsenv) jlpoole@jp /usr/local/src/microreticulum/microReticulumTbeam/exercises/05_SD_Card_Watcher $ git log -n 1 commit 432f17b2be2c8420b3ea8b66d84dc5ba2a81d48f (HEAD -> feature/fieldtest-beacon-sd-provision, origin/feature/fieldtest-beacon-sd-provision) Author: John Poole <jlpoole56@gmail.com> Date: Sat Feb 14 10:10:31 2026 -0800 ``` I loaded and started the above version. At around line 88, I removed the card and re-inserted it: ``` jlpoole@jp /usr/local/src/microreticulum/microReticulumTbeam/exercises/00_usb_radio_check $ cat -n /tmp/ex06_sdwatch_20260214_Sat_1328.log 1 [WATCHER: startup] 2 Sleeping for 5 seconds to allow Serial Monitor connection... 3 4 ================================================== 5 Exercise 05: SD Card Watcher 6 ================================================== 7 Pins: CS=47 SCK=36 MISO=37 MOSI=35 8 PMU I2C: SDA1=42 SCL1=41 9 Note: SD must be FAT16/FAT32 for Arduino SD library. 10 11 PMU adapter: AXP2101 ready, BLDO1(SD)=ON 12 [ 5146][000000] Watcher: waiting 1500 ms for SD rail/card stabilization 13 [ 6673][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume 14 [ 6909][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume 15 [ 7145][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume 16 [ 7354][000001] Watcher: startup warmup did not mount card 17 [ 7354][000002] EVENT: no card detected 18 [ 7381][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume 19 [ 8387][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume 20 [ 9393][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume 21 [ 10399][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume 22 [ 10407][000003] Watcher: preferred probe failed, running full scan 23 [ 10420][000004] SD: trying bus=HSPI freq=400000 Hz 24 [ 10435][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume 25 [ 10444][000005] SD: mount failed (possible non-FAT format, power, or bus issue) 26 [ 10456][000006] SD: trying bus=HSPI freq=1000000 Hz 27 [ 10464][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume 28 [ 10473][000007] SD: mount failed (possible non-FAT format, power, or bus issue) 29 [ 10486][000008] SD: trying bus=HSPI freq=4000000 Hz 30 [ 10491][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume 31 [ 10500][000009] SD: mount failed (possible non-FAT format, power, or bus issue) 32 [ 10512][000010] SD: trying bus=HSPI freq=10000000 Hz 33 [ 10517][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume 34 [ 10525][000011] SD: mount failed (possible non-FAT format, power, or bus issue) 35 [ 10538][000012] SD: trying bus=FSPI freq=400000 Hz 36 [ 10553][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume 37 [ 10562][000013] SD: mount failed (possible non-FAT format, power, or bus issue) 38 [ 10574][000014] SD: trying bus=FSPI freq=1000000 Hz 39 [ 10582][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume 40 [ 10591][000015] SD: mount failed (possible non-FAT format, power, or bus issue) 41 [ 10604][000016] SD: trying bus=FSPI freq=4000000 Hz 42 [ 10609][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume 43 [ 10618][000017] SD: mount failed (possible non-FAT format, power, or bus issue) 44 [ 10630][000018] SD: trying bus=FSPI freq=10000000 Hz 45 [ 10635][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume 46 [ 10643][000019] SD: mount failed (possible non-FAT format, power, or bus issue) 47 [ 10643][000020] SD: begin() failed on all bus/frequency attempts 48 [ 10643][000021] likely card absent, bad format, pin mismatch, or hardware issue 49 [ 11401][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume 50 [ 12407][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume 51 [ 13413][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume 52 [ 14419][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume 53 [ 15425][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume 54 [ 16431][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume 55 [ 17437][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (13) There is no valid FAT volume 56 [ 18729][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00 57 [ 18735][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (3) The physical drive cannot work 58 [ 19044][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00 59 [ 19733][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00 60 [ 19739][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (3) The physical drive cannot work 61 [ 20048][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00 62 [ 20737][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00 63 [ 20743][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (3) The physical drive cannot work 64 [ 21052][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00 65 [ 21058][000022] Watcher: preferred probe failed, running full scan 66 [ 21070][000023] SD: trying bus=HSPI freq=400000 Hz 67 [ 21371][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00 68 [ 21377][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (3) The physical drive cannot work 69 [ 21686][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00 70 [ 21692][000024] SD: mount failed (possible non-FAT format, power, or bus issue) 71 [ 21704][000025] SD: trying bus=HSPI freq=1000000 Hz 72 [ 22005][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00 73 [ 22011][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (3) The physical drive cannot work 74 [ 22320][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00 75 [ 22326][000026] SD: mount failed (possible non-FAT format, power, or bus issue) 76 [ 22338][000027] SD: trying bus=HSPI freq=4000000 Hz 77 [ 22639][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00 78 [ 22645][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (3) The physical drive cannot work 79 [ 22954][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00 80 [ 22960][000028] SD: mount failed (possible non-FAT format, power, or bus issue) 81 [ 22972][000029] SD: trying bus=HSPI freq=10000000 Hz 82 [ 23273][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00 83 [ 23279][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (3) The physical drive cannot work 84 [ 23588][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00 85 [ 23594][000030] SD: mount failed (possible non-FAT format, power, or bus issue) 86 [ 23606][000031] SD: trying bus=FSPI freq=400000 Hz 87 [ 23907][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00 88 [ 23913][E][sd_diskio.cpp:806] sdcard_mount(): f_mount failed: (3) The physical drive cannot work 89 [ 24222][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x00 90 [ 24228][000032] SD: mount failed (possible non-FAT format, power, or bus issue) 91 [ 24240][000033] SD: trying bus=FSPI freq=1000000 Hz 92 [ 24544][000034] SD: card detected and mounted 93 [ 24594][000035] EVENT: card inserted/mounted 94 [ 24595][000036] SD type: SDHC/SDXC 95 [ 24595][000037] SD size: 14910 MB 96 [ 24595][000038] FS total: 14895 MB 97 [ 24595][000039] FS used : 0 MB 98 [ 24595][000040] SPI bus: HSPI @ 400000 Hz 99 [ 24608][000041] WARNING: /Exercise_05_test.txt exists ... erasing 100 [ 24776][000042] Wrote file: /Exercise_05_test.txt 101 [ 24984][000043] WARNING: /test/testsub1/testsubsub1/Exercise_05_test.txt exists ... erasing 102 [ 25459][000044] Wrote file: /test/testsub1/testsubsub1/Exercise_05_test.txt 103 [ 25459][000045] Permissions demo: 104 [ 25459][000046] SD/FAT does not support Unix permissions (chmod/chown). 105 [ 25459][000047] Access control is by open mode (FILE_READ/FILE_WRITE). 106 [ 25472][000048] FILE_READ open succeeded, size=16 bytes 107 [ 25472][000049] As expected, write via FILE_READ handle was blocked. jlpoole@jp /usr/local/src/microreticulum/microReticulumTbeam/exercises/00_usb_radio_check $ ```
Author
Owner

Here's a dialog that explains the problem:

Prompt 1

It looks like you fixed the problem. I ran this twice and the output to the console seems like reading is accomplished. Here's the log from the 2nd run. Can you explain why the older versions failed? I'll place that explanation in the Issue ticket and close the ticket as fixed.

Response 1

Yes — the “why” breaks into two distinct failure modes that happened at different points in your iteration:

  1. Original failure: card inserted at boot would not mount until you physically re-seat it
  2. Regression I accidentally introduced: after you re-seat, it still wouldn’t mount anymore

Your latest 1407 log (and your observation “ran twice and reading is accomplished”) is consistent with fixing both.


1) Why the original versions failed with a card already inserted at boot

In the early versions (before we added the BLDO1 power-cycle + SPI idle clocks), the SD card’s behavior strongly matched:

The card never received a true reset / clean initialization sequence when already powered at boot.

On the T-Beam SUPREME, the SD card is powered from the PMU (AXP2101 BLDO1). If BLDO1 is already ON (or comes up very early), the SD card can be:

  • already powered before your firmware configures SPI
  • already in an “odd” internal state
  • not guaranteed to be in SPI mode / idle state

When you physically remove/reinsert, you force:

  • power collapse on the card
  • a true cold reset
  • a clean entry into the SD init sequence

That explains why the “remove/insert” action acted like magic.

What fixed it

The fix in the working code does two key things:

A. Power-cycle BLDO1 at boot (software equivalent of the physical re-seat)

pmu->disablePowerOutput(XPOWERS_BLDO1);
delay(...);
pmu->enablePowerOutput(XPOWERS_BLDO1);
delay(...);

B. Send “idle clocks” with CS high before the mount attempt

digitalWrite(CS, HIGH);
for (...) bus.transfer(0xFF);

That sequence makes the SD card far more likely to enter the proper SPI idle state before SD.begin() runs.


2) Why the regression happened in one of the newer versions

This was the big gotcha.

To add “pin state” logging, we initially wrote dumpSdPins() like this (conceptually):

pinMode(SCK,  INPUT_PULLUP);
pinMode(MISO, INPUT_PULLUP);
pinMode(MOSI, INPUT_PULLUP);
...
digitalRead(...)

That seems harmless, but it’s not.

Because you were calling dumpSdPins() inside the mount path, it ended up doing this at the worst possible time:

  • SPI bus is configured with bus.begin(...)
  • you issue idle clocks
  • then dumpSdPins() runs and reconfigures SPI pins back to INPUT_PULLUP
  • then you call SD.begin() … with the SPI pins no longer driven properly

So you effectively “cut the legs out from under” SPI right before the mount attempt.

Why that prevented hotplug recovery

Once that regression was in place, even after you removed/reinserted the card, the mount path kept sabotaging itself by reconfiguring the SPI pins.

What fixed the regression

We changed pin-state logging to be non-intrusive, using gpio_get_level() (reads pin state without altering pin modes), and we stopped touching pinMode during active SPI operation.

That’s why the new version both:

  • mounts at boot (due to BLDO1 cycle + idle clocks), and
  • still mounts after a hot re-seat (because diagnostics no longer break SPI).

A good “Issue ticket” summary you can paste

Root cause was twofold:

  1. With SD already inserted at boot, the card often didn’t receive a clean reset / SPI idle entry sequence. The board powers SD from AXP2101 BLDO1, and the card can be in an undefined state when firmware first tries to mount. Physical remove/insert forced a cold reset and made mount succeed.

Fix: explicitly power-cycle BLDO1 at boot and provide the standard SD SPI initialization preamble (CS high + idle clocks) before calling SD.begin().

  1. A later diagnostic change regressed hotplug mounting: the pin-state logger temporarily reconfigured SCK/MISO/MOSI to INPUT_PULLUP, which inadvertently broke SPI right before SD.begin(). This prevented mounting even after re-seat.

Fix: make pin-state logging non-intrusive by using gpio_get_level() and never changing SPI pin modes during SD initialization.

If you want, I can also compress that to a 5–8 line “close reason” suitable for Forgejo issues.

Prompt 2

So part of the consideration is that the SD card has a power component unrelated to the read/write of the memory. If the SD card is not powered up correctly, attempt to call reads on it will fail because the small computer on the SD card has not properly initialized and cannot shake hands over the SPI interface?

Response 2

Yes. That is exactly correct.

An SD card is not passive storage.

It is:

  • NAND flash memory
  • a microcontroller
  • RAM
  • a flash translation layer (FTL)
  • wear-leveling firmware
  • a protocol state machine
  • voltage detection logic
  • SPI / SDIO interface logic

In other words, it is a small embedded computer.


What Actually Lives Inside an SD Card

An SD card contains:

  1. Raw NAND flash chips

  2. A controller ASIC with:

    • CPU core
    • RAM
    • Boot ROM
    • Voltage supervisor
    • SPI / SDIO protocol engine
    • Error correction hardware (ECC)
    • Wear-leveling firmware
    • Bad block management

When you power it up, the controller must:

  • Detect stable Vcc (3.3V)
  • Complete its own internal reset
  • Load internal firmware
  • Initialize flash mapping tables
  • Enter idle state
  • Wait for command sequence

Only then can it respond correctly to SPI commands like CMD0.


What Happens If Power-Up Is Not Clean

If the SD card:

  • never loses power
  • or sees brown-out
  • or sees CS low during power-up
  • or sees clocks during unstable Vcc
  • or does not receive proper idle clocks

Then the internal controller may:

  • Not enter SPI mode
  • Remain in SDIO mode
  • Ignore SPI commands
  • Drive MISO incorrectly
  • Fail CMD0
  • Fail f_mount()
  • Report “physical drive cannot work”

That is exactly what your logs were showing.


Why Physical Re-Seat Fixed It

When you removed the card:

  • Vcc collapsed to 0
  • The controller reset fully
  • Boot ROM ran cleanly
  • State machine reset
  • It re-entered default idle state

That is a hard reset of the SD controller.

Your firmware was previously giving it only a logical reset attempt — not a power reset.


Why Power-Cycling BLDO1 Works

When you do:

pmu->disablePowerOutput(XPOWERS_BLDO1);
delay(...);
pmu->enablePowerOutput(XPOWERS_BLDO1);

You are:

  • Forcing the SD controller to reboot
  • Resetting its protocol engine
  • Clearing any corrupted internal state
  • Making it behave as though it was physically removed

That is why the mount now works deterministically.


Why Idle Clocks Matter

Per SD specification:

To enter SPI mode:

  • CS must be HIGH
  • MOSI must be HIGH
  • At least 74 clock cycles must be provided

If those conditions are not satisfied during power-up, the card may remain in SDIO mode.

So your:

digitalWrite(CS, HIGH);
for (...) SPI.transfer(0xFF);

ensures:

  • Clean SPI entry
  • Card’s state machine transitions properly

So Your Understanding Is Precisely Right

If the SD card is not powered up correctly, attempts to read will fail because the small computer on the SD card has not initialized and cannot handshake over SPI.

That is exactly the mechanism.

You are not “reading memory.”
You are talking to a microcontroller that then reads memory.

If that microcontroller is not in the correct state, nothing above it works.


Why This Is Common on ESP32 Systems

ESP32 boards often:

  • Power SD from a PMU rail
  • Boot MCU before SD rail stabilizes
  • Leave CS floating at boot
  • Share SPI with other peripherals

All of those create subtle power/initialization races.

You eliminated them by:

  • Forcing CS HIGH early
  • Power-cycling BLDO1
  • Sending idle clocks
  • Avoiding SPI pin reconfiguration mid-init

That is a very professional fix.


If you'd like, I can also provide a short “engineering-level explanation” suitable for documentation in your repository README explaining SD controller behavior in embedded systems.

Here's a dialog that explains the problem: ### Prompt 1 It looks like you fixed the problem. I ran this twice and the output to the console seems like reading is accomplished. Here's the log from the 2nd run. Can you explain why the older versions failed? I'll place that explanation in the Issue ticket and close the ticket as fixed. ### Response 1 Yes — the “why” breaks into **two distinct failure modes** that happened at different points in your iteration: 1. **Original failure**: *card inserted at boot would not mount until you physically re-seat it* 2. **Regression I accidentally introduced**: *after you re-seat, it still wouldn’t mount anymore* Your latest `1407` log (and your observation “ran twice and reading is accomplished”) is consistent with fixing **both**. --- # 1) Why the original versions failed with a card already inserted at boot In the early versions (before we added the BLDO1 power-cycle + SPI idle clocks), the SD card’s behavior strongly matched: **The card never received a true reset / clean initialization sequence when already powered at boot.** On the T-Beam SUPREME, the SD card is powered from the PMU (**AXP2101 BLDO1**). If BLDO1 is already ON (or comes up very early), the SD card can be: * already powered before your firmware configures SPI * already in an “odd” internal state * not guaranteed to be in SPI mode / idle state When you *physically remove/reinsert*, you force: * power collapse on the card * a true cold reset * a clean entry into the SD init sequence That explains why the “remove/insert” action acted like magic. ### What fixed it The fix in the working code does two key things: **A. Power-cycle BLDO1 at boot** (software equivalent of the physical re-seat) ```cpp pmu->disablePowerOutput(XPOWERS_BLDO1); delay(...); pmu->enablePowerOutput(XPOWERS_BLDO1); delay(...); ``` **B. Send “idle clocks” with CS high** before the mount attempt ```cpp digitalWrite(CS, HIGH); for (...) bus.transfer(0xFF); ``` That sequence makes the SD card far more likely to enter the proper SPI idle state before `SD.begin()` runs. --- # 2) Why the regression happened in one of the newer versions This was the big gotcha. To add “pin state” logging, we initially wrote `dumpSdPins()` like this (conceptually): ```cpp pinMode(SCK, INPUT_PULLUP); pinMode(MISO, INPUT_PULLUP); pinMode(MOSI, INPUT_PULLUP); ... digitalRead(...) ``` That seems harmless, but it’s not. Because you were calling `dumpSdPins()` **inside the mount path**, it ended up doing this at the worst possible time: * SPI bus is configured with `bus.begin(...)` * you issue idle clocks * then `dumpSdPins()` runs and **reconfigures SPI pins back to INPUT_PULLUP** * then you call `SD.begin()` … with the SPI pins no longer driven properly So you effectively “cut the legs out from under” SPI right before the mount attempt. ### Why that prevented hotplug recovery Once that regression was in place, even after you removed/reinserted the card, the mount path kept sabotaging itself by reconfiguring the SPI pins. ### What fixed the regression We changed pin-state logging to be **non-intrusive**, using `gpio_get_level()` (reads pin state without altering pin modes), and we stopped touching pinMode during active SPI operation. That’s why the new version both: * mounts at boot (due to BLDO1 cycle + idle clocks), and * still mounts after a hot re-seat (because diagnostics no longer break SPI). --- # A good “Issue ticket” summary you can paste > Root cause was twofold: > > 1. With SD already inserted at boot, the card often didn’t receive a clean reset / SPI idle entry sequence. The board powers SD from AXP2101 BLDO1, and the card can be in an undefined state when firmware first tries to mount. Physical remove/insert forced a cold reset and made mount succeed. > > Fix: explicitly power-cycle BLDO1 at boot and provide the standard SD SPI initialization preamble (CS high + idle clocks) before calling SD.begin(). > > 2. A later diagnostic change regressed hotplug mounting: the pin-state logger temporarily reconfigured SCK/MISO/MOSI to INPUT_PULLUP, which inadvertently broke SPI right before SD.begin(). This prevented mounting even after re-seat. > > Fix: make pin-state logging non-intrusive by using gpio_get_level() and never changing SPI pin modes during SD initialization. If you want, I can also compress that to a 5–8 line “close reason” suitable for Forgejo issues. ### Prompt 2 So part of the consideration is that the SD card has a power component unrelated to the read/write of the memory. If the SD card is not powered up correctly, attempt to call reads on it will fail because the small computer on the SD card has not properly initialized and cannot shake hands over the SPI interface? ### Response 2 Yes. That is exactly correct. An SD card is **not passive storage**. It is: * NAND flash memory * a microcontroller * RAM * a flash translation layer (FTL) * wear-leveling firmware * a protocol state machine * voltage detection logic * SPI / SDIO interface logic In other words, it is a small embedded computer. --- # What Actually Lives Inside an SD Card An SD card contains: 1. Raw NAND flash chips 2. A controller ASIC with: * CPU core * RAM * Boot ROM * Voltage supervisor * SPI / SDIO protocol engine * Error correction hardware (ECC) * Wear-leveling firmware * Bad block management When you power it up, the controller must: * Detect stable Vcc (3.3V) * Complete its own internal reset * Load internal firmware * Initialize flash mapping tables * Enter idle state * Wait for command sequence Only then can it respond correctly to SPI commands like CMD0. --- # What Happens If Power-Up Is Not Clean If the SD card: * never loses power * or sees brown-out * or sees CS low during power-up * or sees clocks during unstable Vcc * or does not receive proper idle clocks Then the internal controller may: * Not enter SPI mode * Remain in SDIO mode * Ignore SPI commands * Drive MISO incorrectly * Fail CMD0 * Fail f_mount() * Report “physical drive cannot work” That is exactly what your logs were showing. --- # Why Physical Re-Seat Fixed It When you removed the card: * Vcc collapsed to 0 * The controller reset fully * Boot ROM ran cleanly * State machine reset * It re-entered default idle state That is a **hard reset** of the SD controller. Your firmware was previously giving it only a *logical* reset attempt — not a power reset. --- # Why Power-Cycling BLDO1 Works When you do: ```cpp pmu->disablePowerOutput(XPOWERS_BLDO1); delay(...); pmu->enablePowerOutput(XPOWERS_BLDO1); ``` You are: * Forcing the SD controller to reboot * Resetting its protocol engine * Clearing any corrupted internal state * Making it behave as though it was physically removed That is why the mount now works deterministically. --- # Why Idle Clocks Matter Per SD specification: To enter SPI mode: * CS must be HIGH * MOSI must be HIGH * At least 74 clock cycles must be provided If those conditions are not satisfied during power-up, the card may remain in SDIO mode. So your: ```cpp digitalWrite(CS, HIGH); for (...) SPI.transfer(0xFF); ``` ensures: * Clean SPI entry * Card’s state machine transitions properly --- # So Your Understanding Is Precisely Right > If the SD card is not powered up correctly, attempts to read will fail because the small computer on the SD card has not initialized and cannot handshake over SPI. That is exactly the mechanism. You are not “reading memory.” You are talking to a microcontroller that then reads memory. If that microcontroller is not in the correct state, nothing above it works. --- # Why This Is Common on ESP32 Systems ESP32 boards often: * Power SD from a PMU rail * Boot MCU before SD rail stabilizes * Leave CS floating at boot * Share SPI with other peripherals All of those create subtle power/initialization races. You eliminated them by: * Forcing CS HIGH early * Power-cycling BLDO1 * Sending idle clocks * Avoiding SPI pin reconfiguration mid-init That is a very professional fix. --- If you'd like, I can also provide a short “engineering-level explanation” suitable for documentation in your repository README explaining SD controller behavior in embedded systems.
Author
Owner
Fixed by commit 0217ece https://salemdata.net/repo/jlpoole/microReticulumTbeam/commit/0217ece
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
jlpoole/microReticulumTbeam#1
No description provided.