Skip to content

RP2350: SPI pins sometimes left in wrong FUNCSEL (not SPI) after busio.SPI construct/configure; fixed by MCU reset #10857

@w4iei

Description

@w4iei

I’m working on a custom RP2350A board and seeing an intermittent SPI bring-up issue when using the C shared-module APIs. Firmware is based on CircuitPython 10.1.2

Summary
About ~50% of cold boots result in my SPI-based ADC driver returning all 0x00 for all reads (both data and register reads). The driver code continues to run and calls to common_hal_busio_spi_write/transfer/read return success, but the device never responds. Running:

import microcontroller; microcontroller.reset()

usually recovers the system (often on the first or second reset).

What I’m doing (C)
Example SPI construction (pins vary per bus; this is one instance):
common_hal_busio_spi_construct(spi, &pin_GPIO18, &pin_GPIO19, &pin_GPIO16, false);

Then I lock/configure and begin transfers.

Symptoms
• All SPI reads return 0x00 (including device status/config readbacks).
• The application loop continues running and “samples_written” counters increment (i.e., the code path is executing).
• A microcontroller.reset() usually resolves it (without power-cycling the external ADCs).

Pin mux (FUNCSEL) check
I added a debug check using Pico SDK gpio_get_function() on RP2350 to see whether the pins are muxed to SPI. On failing boots I capture the pin function for each bus:
• spi0 funcsel: sck=0x01 mosi=0x01 miso=0x01 (expected GPIO_FUNC_SPI)
• spi1 funcsel: sck=0x01 mosi=0x01 miso=0x01 (expected GPIO_FUNC_SPI)

So the pins appear to be in SPI function, yet the bus behaves like the peripheral is not effectively communicating until an MCU reset.

Debug code used

static inline void debug_capture_spi_mux_state(uint8_t bus) {

`bool mismatch = false;
uint8_t expected_spi_funcsel = (uint8_t)GPIO_FUNC_SPI;
const mcu_pin_obj_t *sck = spi_pin_config[bus][0];
const mcu_pin_obj_t *mosi = spi_pin_config[bus][1];
const mcu_pin_obj_t *miso = spi_pin_config[bus][2];
debug_state.expected_spi_funcsel = expected_spi_funcsel;

debug_state.sck_funcsel[bus] = sck == NULL ? 0xFF : (uint8_t)gpio_get_function(sck->number);
debug_state.mosi_funcsel[bus] = mosi == NULL ? 0xFF : (uint8_t)gpio_get_function(mosi->number);
debug_state.miso_funcsel[bus] = miso == NULL ? 0xFF : (uint8_t)gpio_get_function(miso->number);

if (sck != NULL && debug_state.sck_funcsel[bus] != expected_spi_funcsel) mismatch = true;
if (mosi != NULL && debug_state.mosi_funcsel[bus] != expected_spi_funcsel) mismatch = true;
if (miso != NULL && debug_state.miso_funcsel[bus] != expected_spi_funcsel) mismatch = true;

if (mismatch) {
debug_state.spi_funcsel_assert_fail[bus]++;
}`

Metadata

Metadata

Assignees

No one assigned

    Labels

    rp235xsupportissues that involve helping a user accomplish a task

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions