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:
On the SPI transport, what causes the CMD53 data phase to time out (DATA_TIMEOUT) after CMD63 startup succeeds?
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?
Must SPI_INT assert for the chip-ID read’s data-ready handshake, and does it require configuration before the first read?
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.
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?
Running the MM-IoT-SDK Porting Assistant on a custom board pairing an MM8108-MF15457 with a Seeed XIAO ESP32-C5 over SPI. morsemicro/halow 2.11.2-esp32-2, ESP-IDF v5.5.4, SPI mode 0 at 40 MHz, chip variant mm8108, BCF bcf_mf15457.mbin, country GB.
I have three hand-assembled boards from one build. Board 1 passes the Porting Assistant 11/11 (chip ID 0x0809 / MM8108B2, ~9570 kbit/s raw throughput, AP starts fine on opclass 6 ch3). The exact same binary (SHA256-verified) fails on Board 2 at “SDIO/SPI Startup.”
I instrumented mmhal_wlan_sdio_cmd() to print the R1 status and data bytes for every command. On Board 2, every command in the startup sequence returns:
i.e. the response poll loop exhausts its full attempt count with MISO reading 0xFF the entire time — across all three startup retries. The module never drives MISO low for any command, including the very first CMD63.
Host side is verified good:
Identical binary passes 11/11 on Board 1.
Boot log confirms correct pin config: CS (GPIO12) output-enabled, INT (GPIO11) input, SPI clock negotiated at 40000 kHz.
Training sequence is sent; RESET_N is toggled (Hard reset device executes).
Pin mapping SCK=8, MISO=9, MOSI=10, CS=12, IRQ=11, RESET_N=7, WAKE=25, BUSY=0. 47k pull-up on MISO per datasheet note [1], nothing on SCK.
Static measurements on Board 2 (powered, booted):
Module VDD pins: 3.3V
RESET_N: 3.3V (released) after boot
MISO: 3.3V at rest — but I understand this is the 47k pull-up holding it, indistinguishable at DC from the module actively driving high.
Continuity on all four SPI lines to the module pads: good. No shorts between adjacent pins (12/13/16/17).
My read is that the module receives commands (MOSI/SCK/CS reach it) but never drives MISO back — pointing at either a marginal joint on the MISO pad, the module not fully coming up despite VDD/RESET_N reading correct, or the part itself, none of which a DC meter can distinguish.
Questions:
Is “0xFF for all commands including CMD63, poll exhausted” consistent in your experience with a MISO-side connection fault specifically, versus a non-functional module?
Is there anything host-side that could produce total non-response on the first CMD63 that I might still be missing, given an identical binary works on a sibling board?
Any recommended check to distinguish a marginal LGA reflow from a dead part without X-ray
BUSY is a GPIO driven by the MM8108. busy_gpio_num is the mm8108 gpio number. It is module pin 29 as per the datasheet.
Have you put an oscilloscope on this pin to see if it is being driven or in an indeterminate state?
0xFF could be caused by a MISO connection fault.
I think this is highly unlikely given the same software works on another board. Ensure you aren’t mixing pullups/pulldowns such that the driven state isn’t marginal.
Consider the porting assistant as being that check.
But also, please capture a logic analyzer trace or oscilloscope capture of the busy line just in case your board design is pulling the line into a marginal state.
I’ve done extensive testing on a XIAO ESP32-C5 + MM8108-MF15457 setup (SDK morsemicro/halow ^2.11.2-esp32-2, ESP-IDF v5.5.4) and I’ve isolated a problem I can’t explain from software alone. I’d appreciate a sanity check on whether I’m missing an SDK step, or whether this is now definitively a hardware issue.
What’s confirmed working:
Both boards pass the porting assistant 11/11 (chip ID 0x0809, bulk R/W, throughput ~9576 kbit/s, firmware + BCF validate).
Country GB, powersave disabled (CONFIG_HALOW_PS_MODE off — with it on I hit a yaps_worker stack-canary crash after association, disabling it stops that).
AP side — confirmed genuinely enabled and on the correct channel. I bypassed the mmhalow_wifi_start() wrapper and called mmwlan_ap_enable() directly with status checking:
So the AP reports it is enabled and operating on GB channel 1 / op_class 6 / 1 MHz, with a valid BSSID.
STA side — receiver confirmed functional, hears nothing. I wrote a diagnostic that continuously calls mmwlan_scan_request() with 300 ms per-channel dwell, registers a raw RX callback via mmwlan_register_rx_cb(), and dumps UMAC stats each pass. Over many passes (~40 s of listening) with the AP beaconing ~10 cm away:
Every call succeeds, scans complete successfully — but the raw RX callback never fires and zero scan results are ever returned. The receiver appears fully functional but hears zero frames, not even fragments.
Hardware checks done:
Antenna is an 868 MHz quarter-wave whip (RF Solutions FLEXI-SMA-868), 50 Ω.
DC continuity confirmed: SMA centre → module ANT pad (pin 2) is connected (~0 Ω); SMA centre → GND is open (not shorted). Confirmed on both boards.
Board is 4-layer, 1.6 mm FR-4, ANT on top layer, full GND on layer 2, ~0.5 mm 50 Ω microstrip to the SMA, direct trace (no 0R, matching is integrated in the module per the datasheet).
My questions:
Given mmwlan_ap_enable() returns SUCCESS and mmwlan_get_vif_channel_info() reports a valid operating channel — is the AP definitely transmitting beacons at that point, or is there a further call/step required to actually key the transmitter / start beaconing?
On the STA side, is there anything beyond mmwlan_scan_request() needed to actually enable the receiver front-end? The scans complete successfully but hear nothing.
Is there a diagnostic or test command (e.g. via mmwlan_ate_execute_command / the rf-test app) you’d recommend to confirm the module is actually radiating, that I can run without a spectrum analyzer?
Is there any known requirement around ground-plane / counterpoise size for the ANT pin on the MF15457 that would explain near-zero radiated power on a small board?
Both radios are healthy and correctly configured in software as far as I can tell — I just can’t get any RF to cross between them at 10 cm. Any pointers on whether this is a missing SDK step or confirmed hardware would be hugely appreciated.
If you’re calling mmwlan_ functions directly, rather than using the wrapper API esp-halow provides, then as long as you are following the sequence as laid out in mm-iot-sdk/examples/scan/src/scan.c at main · MorseMicro/mm-iot-sdk · GitHub you should be okay.
Make sure you set the region to be the same country code, as the mm-iot-sdk driver/mac layer filters SSIDs beaconing with different region information, despite operating on a compatible channel.
With esp-halow this should just be mmhalow_init which handles the region setting and booting of the transceiver for you.