-
Notifications
You must be signed in to change notification settings - Fork 17
Description
The macros for the various peripherals create a new type for each instance of the same hardware. These types share the general embedded_hal
traits, but I need something that provides the hardware-specific methods. I'd like to write some code that is general and doesn't care, say, what SPI device (for example) is passed in.
I have code like this, for example:
use hifive1::hal::spi::{Spi, Mode, Polarity, Phase};
...
// SPI backend trait for display interface
pub trait SPI {
fn send(&mut self, data: u8);
fn complete(&mut self);
fn mode_data(&mut self);
fn mode_cmd(&mut self);
}
pub struct Hifive1SPI<X, Y, DC> where
DC: OutputPin {
hwspi: Spi<X, Y>,
dc: DC,
}
impl <Y, DC> Hifive1SPI<QSPI1, Y, DC> where
Y: hifive1::hal::spi::Pins<QSPI1>,
DC: OutputPin {
pub fn new(hwspi: Spi<QSPI1, Y>, dc: DC) -> Hifive1SPI<QSPI1, Y, DC> {
Hifive1SPI {
hwspi,
dc,
}
}
}
impl <Y, DC> SPI for Hifive1SPI<QSPI1, Y, DC> where
Y: hifive1::hal::spi::Pins<QSPI1>,
DC: OutputPin {
fn complete(&mut self)
{
// Wait for send FIFO to drain
while !self.hwspi.tx_wm_is_pending() {
// IDLE
}
}
fn send(&mut self, data: u8)
{
while let Err(_) = self.hwspi.send(data) {
// IDLE
}
}
fn mode_data(&mut self)
{
self.complete();
self.dc.set_high();
}
fn mode_cmd(&mut self)
{
self.complete();
self.dc.set_low();
}
}
Currently this specializes on QSPI1
because I don't see a way to generalize it over all SPI devices, as tx_wm_is_pending
is not on a trait.
(I had a similar situation with GPIO pins in the board setup, where I wanted to make it possible to pass in arbitrary pins to configure, but there is no trait that provides into_output
into_inverted_output
. There's OutputPin
of course, but that's only useful when the pin is already set up)
I'm fairly new to Rust, entirely new to using Rust for embedded programming, so I may be missing something.