MM8108-MF15457 + XIAO ESP32-C5, SPI transport, two custom PCBs — chip-ID read fails with DATA_TIMEOUT after startup passes

MM8108-MF15457 + XIAO ESP32-C5, SPI transport, two custom PCBs — chip-ID read fails with DATA_TIMEOUT after startup passes

ESP-IDF 5.5.4, morsemicro/halow + morsemicro/firmware 2.10.4-esp32-2 (moved to local components/). FW mm8108b2-rl.mbin + BCF bcf_mf15457.mbin confirmed embedded in build.
Pins:

  • SCK=GPIO9
  • MOSI=GPIO10,
  • MISO=GPIO8
  • CS=GPIO12 (bit-banged, .spics_io_num=-1)
  • SPI_INT=GPIO11 (47k pull-up to 3V3 present)
  • RESET_N=GPIO7
  • WAKE=GPIO25
  • BUSY=GPIO0

SPI mode 0 @ 5 MHz.

Porting assistant:

memory/time/task PASS;
SDIO/SPI Startup (CMD63) PASS;
Read chip id FAILSsdio_spi_read_le32 returns -5 (MMHAL_SDIO_DATA_TIMEOUT)

MISO all 0x00 through the data phase. SPI_INT (GPIO11) reads high at every CS assertion — never asserts data-ready. BUSY (GPIO0) idles low. Reproduced identically on two independent boards.

Questions:

  1. On the SPI transport, what causes the CMD53 data phase to time out (DATA_TIMEOUT) after CMD63 startup succeeds?
  2. Are the three CMD52 address-window writes (morse_address_base_set) expected to complete over SPI, and is there a way to verify they landed?
  3. Must SPI_INT assert for the chip-ID read’s data-ready handshake, and does it require configuration before the first read?
  4. Any known XIAO ESP32-C5 SPI bring-up gotcha?

Hi @chamith1,

I’ve reformatted your post for readability

First thing that sticks out to me is your pin assignments don’t match seeed’s xiao c5 pin mappings,

Specifically seeed has:
SCK = GPIO8
MISO = GPIO9

Hi @michael.mccandless

Thank you for that and it was indeed the hardware barrier initially. But i have been stuck in this loop for hours now. Transport now communicating; response framing question.
Root cause of the earlier dead bus was a SCK/MISO pin-config mismatch on my board (now SCK=GPIO8→pin17, MISO=GPIO9→pin12). With that corrected the module responds reliably.
Remaining issue: every CMD52 response reads as FF FF … FF FE 00. mmhal_wlan_sdio_cmd breaks on the first non-0xFF byte and treats the 0xFE as an invalid ack → MMHAL_SDIO_OTHER_ERROR. Same on SPI mode 0 and mode 3, 5 MHz, two independent boards.
What is the expected response byte framing for CMD52/CMD53 on the MM8108 SPI transport? Should a 0xFE precede the R1 status, and if so how should the stock parser handle it?

Further finding. With SPI mode 2 (mode 0 caused a one-bit sampling misalignment producing a phantom 0xFE before every R1 — worth noting for the ESP32 port), CMD52 to FUNCTION_1 works correctly: morse_address_base_set returns 0 and the window registers echo back the written values. However CMD52 to FUNCTION_0 (CCCR) receives no response at all — e.g. a write to CCCR 0x07 or 0x04 returns only 0xFF for the full response window, MMHAL_SDIO_OTHER_ERROR. Consequently SPI_INT (pin 14, continuity verified) never asserts, and morse_cmd53_get_data reads only 0xFF — the module never sends the 0xFE data-start token.
Q: Why would the MM8108 respond to FUNCTION_1 CMD52 but not FUNCTION_0/CCCR on the SPI transport? Is CCCR access expected to work, and is an interrupt-enable via CCCR 0x04 required before the first CMD53 read?

MM8108-MF15457 + ESP32-C5, SPI mode 2 @ 5 MHz. Chip ID reads 0x0809 (MM8108B2). CMD52 read and write work on FN1 and FN2 — including writing/reading back a test pattern at 0x80100000. CMD53 reads work. CMD53 writes always return data-response token 0xEB, and large writes leave the module unresponsive until hard reset.
Eliminated: CRC over data / token+data, init 0 / 0xFFFF, both CRC byte orders, burst vs byte-wise vs full-duplex transmission, FN1 and FN2 FBR block size, all four SPI modes, 1–5 MHz, MOSI idle state.
Note: mode 0 (per your SPI Troubleshooting FAQ) gives a consistent one-bit sampling misalignment on this hardware; only mode 2 produces valid responses.
What causes the MM8108 to reject the CMD53 write data phase while accepting CMD52 writes to the same address?

@chamith1 I’ve collapsed your new thread back into this one as the discussion appears to be a continuation of your development.

The first point I will make is - Don’t use SPI Mode 2. There is a timing diagram below, with details, but we are designed to be compatible with SPI mode 0.

The esp32-c5 is known to work, we have tested it with the 2.11.2 version of esp-halow on the espressif component registry.

The most common “gotcha” with SPI is that our chip exposes an SDIO interface, and our SPI mode is SDIO operating in SPI mode as per the SDIO specification. Hence, we follow the timing as shown below, from Part 1 Physical Layer Specification v9.10, 6.6.7

This timing is mostly compatible with SPI mode 0. However data from the chip is shifted out within 14ns of the last rising edge. While this works fine for most applications, there have been many devices we have seen, particularly with long traces, which result in shifted bits. Pay close attention to the timing.

We have seen failures like this on a board before where undocumented PU/PD resistors were placed on the clock line and “confused” the chip.

To help us help you debug this further, please provide a logic analyzer trace.

In order to put the chip into SPI mode, the host must toggle SPI_CLK ~74 times with CS held high. Following this the host driver will send CMD63 followed by the CMD52 writes.

Yes they must succeed. Just get a logic analyzer capture, it is much easier to debug.

Hi @ajudge

Thank you for the information you provided. with that i have passed further in, However Verify Busy pin seems to FAIL. In c5 the Gpio 0 is connected to 8108 pin 29. MM-IoT-SDK Porting Assistant

Memory allocation [ PASS ]
Memory reallocation [ PASS ]
Passage of time [ PASS ]
Task creation and preemption [ PASS ]
WLAN HAL initialisation
Hard reset device
SDIO/SPI Startup [ PASS ]
Read chip id from the MM chip [ PASS ]
Verify BUSY pin [OE gpio=2 ret=0 rb_ret=0 rb=0x00000004][GPIOSET gpio=2 val=0x4 ret=0 | rb_ret=0 rb=0x00000004][ FAIL ]

On stock 2.11.2 with an ESP32-C5, SDIO/SPI startup and chip-ID pass. The “Verify BUSY pin” test drives internal GPIO 2 via sdio_spi_write_le32; the OE (0x1360) and value (0x1368) registers both write and read back correctly, confirmed by read-back. I swept internal GPIOs 0–11 — all set correctly in the registers, none causes module pin 29 (BUSY) to assert on the host. Is BUSY on the MF15457 driven by a general-purpose GPIO, and if so which index? Or is busy_gpio_num = 2 in chip_cfg.c specific to the bare MM8108 rather than the module?