I am trying to read a value from a sensor, BMP280 over SPI on a Raspberry Pi Pico. But I am getting an unexpected value.
I created a new repo based on the rp2040-project-template and modified it to add SPI functionality.
I added these imports:
use embedded_hal::prelude::_embedded_hal_spi_FullDuplex;
use rp_pico::hal::spi;
use rp_pico::hal::gpio;
use fugit::RateExtU32;
Then I setup SPI in the bottom of main function:
let _spi_sclk = pins.gpio2.into_mode::<gpio::FunctionSpi>();
let _spi_mosi = pins.gpio3.into_mode::<gpio::FunctionSpi>();
let _spi_miso = pins.gpio4.into_mode::<gpio::FunctionSpi>();
let mut spi_cs = pins.gpio5.into_push_pull_output_in_state(PinState::Low); // initial pull down, for SPI
let spi = spi::Spi::<_, _, 8>::new(pac.SPI0);
let mut spi = spi.init(
&mut pac.RESETS,
clocks.peripheral_clock.freq(),
10.MHz(), // bmp280 has 10MHz as maximum
&embedded_hal::spi::MODE_0,
);
spi_cs.set_high().unwrap(); // pull up, set as inactive after init
delay.delay_ms(200); // some delay for testing
Then I try to read the ID registry
spi_cs.set_low().unwrap();
let res_w = spi.send(0xd0 as u8); // 0xd0 is address for ID, with msb 1
let res_r = spi.read();
spi_cs.set_high().unwrap();
// check results
match res_w {
Ok(_) => info!("write worked"),
Err(_) => info!("failed to write")
}
match res_r {
Ok(v) => info!("read value from SPI: {}", v),
Err(_) => info!("failed to read SPI")
}
With this code, the SPI read fails. Why is that?
Perhaps it is necessary to set a mode on the sensor, before reading the ID. I can add this code above the read, to set forced mode.
spi_cs.set_low().unwrap();
spi.send(0xf4-128 as u8).expect("failed to send first byte"); // registry 0xf4 with msb 0
spi.send(0x1 as u8).expect("failed to send second byte");
spi_cs.set_high().unwrap();
Now the read of ID registry works, but I get value 255
and not the expected 0x58
.
What am I doing wrong?
I have also tried with transfer
using this code:
let mut data: [u8; 2] = [0xd0, 0x0];
let transfer_success = spi.transfer(&mut data);
match transfer_success {
Ok(v) => info!("read data {}", v),
Err(_) => info!("failed to read")
}
But I read the values as [255, 255]
with this code, not the expected 0x58
.