embedded-hal
embedded-hal copied to clipboard
Add SPI traits that are not bound to `Word`?
Some external devices use SPI transfers with flexible data sizes, such as certain small OLED screens.
When using Embassy, this works very well because the transfer method of its SPI struct uses the word size as a generic parameter of the method: https://docs.embassy.dev/embassy-stm32/git/stm32f103c8/spi/struct.Spi.html#method.transfer
However, in embedded-hal, the SPI generics are bound to Word, such as SpiBus<Word>. For SPI structs that own the implementation of this trait, it's not possible to flexibly change the data size: https://docs.rs/embedded-hal/1.0.0/embedded_hal/spi/trait.SpiBus.html
Therefore, is it possible to add an SPI trait that is not bound to Word?
What the problem to implement SpiBus<AnyWord> for Spi?
Where:
enum AnyWord {
U8(u8),
U16(u16),
AnyOther,
}
``` or just `struct AnyWord`.
What the problem to implement
SpiBus<AnyWord>forSpi?Where:
enum AnyWord { U8(u8), U16(u16), AnyOther, } ``` or just `struct AnyWord`.
Using enum will increase the size of elements. For example, the element in the example will ultimately be equal to the size of a u16 + 1, which is not favorable for embedded systems.
However, in embedded-hal, the SPI generics are bound to Word, such as SpiBus<Word>. For SPI structs that own the implementation of this trait, it's not possible to flexibly change the data size
You can do multiple where bounds for different word sizes at the same time, which makes it behave similarly to a generic method.
struct MyDriver<T> {
spi: T,
}
impl<T> MyDriver<T>
where
T: SpiBus<u8> + SpiBus<u16>, // two bounds!
{
fn do_something(&mut self) {
self.spi.write(&[0u8, 1, 2, 3]).unwrap(); // will use SpiBus<u8>>::write
self.spi.write(&[0u16, 1, 2, 3]).unwrap(); // will use SpiBus<u16>>::write
}
}
What the problem to implement
SpiBus<AnyWord>for Spi?
this wouldn't work with DMA. To be able to DMA you need an array of "bare" u8 or u16 etc.
However, in embedded-hal, the SPI generics are bound to Word, such as SpiBus. For SPI structs that own the implementation of this trait, it's not possible to flexibly change the data size
You can do multiple
wherebounds for different word sizes at the same time, which makes it behave similarly to a generic method.struct MyDriver<T> { spi: T, } impl<T> MyDriver<T> where T: SpiBus<u8> + SpiBus<u16>, // two bounds! { fn do_something(&mut self) { self.spi.write(&[0u8, 1, 2, 3]).unwrap(); // will use SpiBus<u8>>::write self.spi.write(&[0u16, 1, 2, 3]).unwrap(); // will use SpiBus<u16>>::write } }What the problem to implement
SpiBus<AnyWord>for Spi?this wouldn't work with DMA. To be able to DMA you need an array of "bare" u8 or u16 etc.
Thank you for your great use of generics!