stm32-rs / stm32g4xx-hal

Peripheral access API for STM32G4 series microcontrollers
Apache License 2.0
66 stars 48 forks source link

Spi improvements #91

Open amcelroy opened 11 months ago

amcelroy commented 11 months ago

Howdy,

I'd like to submit some changes to the SPI module. Long story short, I need to write 16-bit data to a TLV5614 and don't care about return data, as there is none. The default FullDuplex implementations had two issues: they only use 8-bits and they throw an error if the OVR bit is set which happens when writing but not reading from the data register.

The 8-bit-only problem was solved by creating a new SpiDataSize enum that is passed in when instantiating the SPI object.

For the second problem, the first attempt was to add trait implementations for FullDuplex<u16>, but the logic would have differed from FullDuplex<u8> and that didn't seem right.

The second attempt was to add unchecked_send_u8 and unchecked_send_u16 functions to the default impl SPI. These are functions used write to the data register blindly, it is up to the user to check the status register. However, the data was not properly outputting on the SPI bus, which required the is_busy function to check if the SPI bus is busy. This is used in the other two functions as a blocking check before writing to the data register.

Attached is a picture from a Seleae logic analyzer showing data (12 words, 0x0001 through 0x000C) written to the SPI bus using a 20MHz SPI clock using the unchecked_send_u16 function.

Screenshot 2023-11-28 at 9 42 18 AM

no111u3 commented 11 months ago

Looks good for begin. Also would be better to use https://github.com/stm32-rs/stm32f4xx-hal/tree/master/src/spi base methodology: Bidi + Uni direction exchange implementation for future use in some crates like displays, smart LEDs, etc..