David-OConnor / stm32-hal

This library provides access to STM32 peripherals in Rust.
MIT License
148 stars 44 forks source link

Question: SPI always reading 255 #76

Closed Simonrazer closed 4 months ago

Simonrazer commented 1 year ago

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!!

David-OConnor commented 1 year ago

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

Simonrazer commented 1 year ago

No change, 255 all the way

David-OConnor commented 1 year ago

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.

Simonrazer commented 1 year ago

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

David-OConnor commented 1 year ago

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?

Simonrazer commented 1 year ago

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

David-OConnor commented 1 year ago

From that it sounds like the clocks are fine.

Simonrazer commented 1 year ago

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

Simonrazer commented 1 year ago

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

David-OConnor commented 4 months ago

Any updates on this?

Simonrazer commented 4 months ago

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