Skip to content

SPI initialization failure (UnsupportedChip) on RP2350 #46

@lbarraga

Description

@lbarraga

Description

When using the bme280 crate via SPI on Raspberry Pi Pico 2 (RP2350) hardware, initialization fails with an UnsupportedChip error, even when the hardware is wired correctly.

#[embassy_executor::main]
async fn main(_spawner: Spawner) {
    let p = embassy_rp::init(Default::default());
    let spi = Spi::new_blocking(p.SPI0, p.PIN_18, p.PIN_19, p.PIN_16, Config::default());
    let cs = Output::new(p.PIN_17, Level::High);
    let mut spi_device = ExclusiveDevice::new_no_delay(spi, cs).unwrap();
    
    // TEST 1: Manual transfer (Success)
    let mut buf = [0xD0 | 0x80, 0x00]; 
    spi_device.transfer_in_place(&mut buf).unwrap();
    info!("Manual Read ID: {=u8:#X}", buf[1]); // Prints 0x60

    // TEST 2: Crate Init (Failure)
    let mut bme280 = BME280::new(spi_device).unwrap();
    if let Err(e) = bme280.init(&mut Delay) {
        // Returns Error::UnsupportedChip 
        error!("Crate Init Failed: {:?}", defmt::Debug2Format(&e));
    }
}

I am no hardware expert but changing read_any_register in spi.rs to the following seems to solve the issue for me:

async fn read_any_register(
    &mut self,
    register: u8,
    data: &mut [u8],
) -> Result<(), Error<SPIError<SPI::Error>>> {
    // Max read is 26 bytes (calib) + 1 byte address. 32 is safe for the stack.
    let mut buf = [0u8; 32];
    let len = data.len() + 1;
    
    buf[0] = register;

    // Single continuous transfer prevents clock gaps on RP-series hardware
    self.spi
        .transfer_in_place(&mut buf[..len])
        .await
        .map_err(|e| Error::Bus(SPIError::SPI(e)))?;

    data.copy_from_slice(&buf[1..len]);
    Ok(())
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions