Skip to content

P4: machine.SDCard() untested on the Waveshare P4 panel — the slot has been empty; GPIO45 is SD D4, not power control #4

Description

@bdbarnett

Summary

On the Waveshare ESP32-P4-WIFI6-Touch-LCD-4B, machine.SDCard() — the form board_peripherals.sdcard() uses — never brings up the card. The peripheral initialises, the card never answers: info() raises ESP_ERR_TIMEOUT, ioctl(4/5/6) return -1, and readblocks() returns False.

The card itself is fine. When it did come up, it read as a 32 GB card (62,685,184 x 512 blocks) with a valid MBR (55aa).

Three things the board config does not do

From the Waveshare GPIO allocation table: D0-D3 = GPIO39-42, CLK = GPIO43, CMD = GPIO44, power control = GPIO45.

  1. GPIO45 is a power-control pin and nothing drives it. Observed working with it driven low. board_peripherals.sdcard() drives nothing — the same shape as the S3's CH422G/EXIO5 trap, where an unset enable pin made a whole peripheral look absent.
  2. 4-bit width is required. width=1 never answered at any frequency.
  3. 25 MHz and above fail. 4-20 MHz worked; the default is 20 MHz.

The explicit-pin arguments are not available here — SDCard(clk=..., cmd=..., data=...) raises TypeError: extra keyword arguments given, so SOC_SDMMC_USE_GPIO_MATRIX is off for this target and 39-44 are the fixed pins.

What is still unexplained, and why this is not just a config fix

Getting the parameters right is not sufficient. With Pin(45, OUT, value=0), slot=0, width=4, freq=20000000, a fresh boot still times out.

The two runs where the card came up were both preceded by many failed attempts in the same session, and — critically — the following run also worked. An ESP32 reset does not reset the card, so those successes are a card left initialised by an earlier accident, not a sequence that can be reproduced on demand. Everything since is ESP_ERR_TIMEOUT.

Sequences tried, all failing from a clean boot: retry loops (5x with settles), a deliberate power cycle (GPIO45 high 400 ms, then low), a slow identification pass at 400 kHz then a fast open, and an ascending frequency walk with deinit() between attempts.

Also note the first SDCard() after boot constructs; subsequent ones raise ESP_ERR_TIMEOUT at construction, so the peripheral is left held and a naive retry loop cannot work without a deinit() on every path.

Impact

  • board_peripherals.sdcard() on this board cannot work as written, whatever else is fixed.
  • Blocks the host-side SD format test across the USB MSC link — the last open item on the "SD card as a device drive" row in the roadmap, which needs a working card behind sd_drive.py.

Method note

An earlier report in this session claimed the card was unformatted with "sector 0 signature 0000". That was wrong: readblocks() had returned False and never written the buffer, and the zeros were the buffer's own. Anything checking this should pre-fill the buffer with a poison value (0xA5) and assert it was overwritten — reading zeros from an untouched buffer is indistinguishable from reading an empty sector.

Separately: sd_drive.py takes ioctl at face value

examples/sd_drive.py reads card.ioctl(4, 0) straight into its block count. A card returning -1 produces no output and no error — the example simply does nothing, which is how this was first mistaken for the example being broken. It should refuse a non-positive block count with a real message.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-boardNeeds a board on the bench (P4 panel, S3-Touch-4.3, T-Embed)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions