David-OConnor / stm32-hal

This library provides access to STM32 peripherals in Rust.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Question: SPI always reading 255

Simonrazer opened this issue · comments

Heyo, I have another question. I have a STM32F407G-DISC1. I want to use the accelerometer on it with SPI.
I read a bunch of threads/the datasheets of the board, but when I try to use it if this HAL all I read over SPI is 255, no matter what register.
Based on this table im pretty sure I am using the right pins.
grafik
grafik

Here is (the interesting part of) my code:

    //Pins
    let mut sck = Pin::new(Port::A, 5, PinMode::Alt(5));
    let mut miso = Pin::new(Port::A, 6, PinMode::Alt(5));
    let mut mosi = Pin::new(Port::A, 7, PinMode::Alt(5));
    let mut cs = Pin::new(Port::E, 3, PinMode::Output); 

    //Set SPI mode 0, rest default
    let spi_cfg = SpiConfig{mode: SpiMode::mode0(), ..Default::default()};
    let mut spi = Spi::new(dp.SPI1, spi_cfg, BaudRate::Div32); //Mode and Baud Rate are correct, working C++ code uses the same

    cs.set_low(); //Chip Select for SPI/the Accelerometer is active low
    let write_buf1 = [0x20, 0b01000111];//The Acc. is of by default, enable it by writing those regss
    spi.write(&write_buf1).ok();
    cs.set_high();

    cs.set_low();
    let mut rb:[u8;1] = [0x20]; //The register is r/w so lets see if that write did anything
    spi.transfer(&mut rb).ok();
    println!("{:b}", rb); //prints: 11111111
    //No matter where I read, i get 255..

I know this isnt really a place to ask this stuff, but I am at a total loss. Any help is greatly appreciated!!

What happens if you set CS high after the transfer, and before printing the buf?

No change, 255 all the way

Are you able to read the device id? (SHould be a register for that).

Also, the transfer buffer needs to include space for the readings. Ie if the reading is 1 byte long, it needs to be [0x20, 0] or w/e, and the 0 will be replaced by the reading.

Ah okay, that makes sense.
Unfortunatly it didnt help. Still having 255 in all places of the reading buffer when printing.
Yes the ID register (WHO_AM_I i guess) is also 255, even tho it shouldn't be. Any adress Im trying to read is 255

What accel/IMU is it?

Of note, AFAIK other than the things I mentioned, your code looks right. (Setting CS high after an operation is required on some SPI devices, but not others). Of note, I'm using an SPI Acc/Gyro on one of my projects, although that's on H7 and G4. It could be a bug in this lib's F4 SPI implementation - I haven't tested that.

It might be worth seeing if you can make it work on STM32F4xx HAL. The fact that it works in Cube (And this is an official dev board, so it's likely not a hardware problem!) helps narrow it down; this would give another data point.

Another thing to check out would be the SPI clock used on F4. Ie, what is the source? Is it configured in an appropriate range in conjunction with your Div32?

It is the onboard one, as I couldn't read the WHO_AM_I i dont know if it is the LIS3DHH or LIS302DL. They are simillar, most importantly (I think) the Adresss of WHO_AM_I is the same.
lis3dhh.pdf
lis302dl.pdf

Ill check out that HAL tomorrow!
I left the default clock setup in place:
let clock_cfg = Clocks::default(); clock_cfg.setup().unwrap();
From what I can find the SPI clock is the APB1 clock, which by default is 42MHz, div by 32 results in 1.31MHz

From that it sounds like the clocks are fine.

Unforunatly I fail to get the other HAL to work enough. I cant get rprintl to work, or actually anything else than blinking LEDs 😅(Really appreciate the much better docs+examples here! ^^)

Another thing, the F407 has 3 SPI devices. When using the second one all communication over USB/dfmt just fails until I erase the flash. The third one only prints 0 so far, but as it doesnt share pins with the Motion sensor I think that may even make sense for once. Going to find cables to connect them today

Update: Even with the Pins connected it prints out 0.

Any updates on this?

Sorry, not really. I switched to I2C and an external IMU, that worked. Code is here: https://github.com/Simonrazer/Embedded-Rust-Demo/blob/main/src/main.rs