Skip to content

Commit

Permalink
implement eh1 traits for gpios and spi
Browse files Browse the repository at this point in the history
  • Loading branch information
dimpolo committed Apr 16, 2024
1 parent b2e2e9d commit 076139a
Show file tree
Hide file tree
Showing 4 changed files with 197 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- PWM complementary output capability for TIM1 with new example to demonstrate
- Implement interface for reading and writing to the internal flash memory and an example for demonstration.
- PWM output on complementary channels only for single channel timers (TIM16 + TIM17)
- impl embedded_hal_1::spi::SpiBus for SPI
- impl embedded_hal_1::digital traits for Pins

### Fixed

Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ bare-metal = { version = "1.0.0" }
cast = "0.3"
cortex-m = "0.7"
embedded-hal = { version = "0.2", features = ["unproven"] }
embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
stm32f0 = "0.14"
nb = "1"
void = { version = "1.0", default-features = false }
Expand Down
89 changes: 89 additions & 0 deletions src/gpio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,55 @@ impl<MODE> InputPin for Pin<Input<MODE>> {
}
}

impl<MODE> embedded_hal_1::digital::ErrorType for Pin<MODE> {
type Error = Infallible;
}

impl<MODE> embedded_hal_1::digital::InputPin for Pin<MODE>
where
Pin<MODE>: InputPin<Error = Infallible>,
{
#[inline(always)]
fn is_high(&mut self) -> Result<bool, Self::Error> {
InputPin::is_high(self)
}

#[inline(always)]
fn is_low(&mut self) -> Result<bool, Self::Error> {
InputPin::is_low(self)
}
}

impl<MODE> embedded_hal_1::digital::OutputPin for Pin<MODE>
where
Pin<MODE>: OutputPin<Error = Infallible>,
{
#[inline(always)]
fn set_high(&mut self) -> Result<(), Self::Error> {
OutputPin::set_high(self)
}

#[inline(always)]
fn set_low(&mut self) -> Result<(), Self::Error> {
OutputPin::set_low(self)
}
}

impl<MODE> embedded_hal_1::digital::StatefulOutputPin for Pin<MODE>
where
Pin<MODE>: StatefulOutputPin<Error = Infallible>,
{
#[inline(always)]
fn is_set_high(&mut self) -> Result<bool, Self::Error> {
StatefulOutputPin::is_set_high(self)
}

#[inline(always)]
fn is_set_low(&mut self) -> Result<bool, Self::Error> {
StatefulOutputPin::is_set_low(self)
}
}

macro_rules! gpio_trait {
($gpiox:ident) => {
impl GpioRegExt for crate::pac::$gpiox::RegisterBlock {
Expand Down Expand Up @@ -564,6 +613,46 @@ macro_rules! gpio {
Ok(unsafe { (*$GPIOX::ptr()).is_low($i) })
}
}

impl<MODE> embedded_hal_1::digital::ErrorType for $PXi<MODE>{
type Error = Infallible;
}

impl<MODE> embedded_hal_1::digital::InputPin for $PXi<MODE> where $PXi<MODE>: InputPin<Error=Infallible> {
#[inline(always)]
fn is_high(&mut self) -> Result<bool, Self::Error> {
InputPin::is_high(self)
}

#[inline(always)]
fn is_low(&mut self) -> Result<bool, Self::Error> {
InputPin::is_low(self)
}
}

impl<MODE> embedded_hal_1::digital::OutputPin for $PXi<MODE> where $PXi<MODE>: OutputPin<Error=Infallible> {
#[inline(always)]
fn set_high(&mut self) -> Result<(), Self::Error> {
OutputPin::set_high(self)
}

#[inline(always)]
fn set_low(&mut self) -> Result<(), Self::Error> {
OutputPin::set_low(self)
}
}

impl<MODE> embedded_hal_1::digital::StatefulOutputPin for $PXi<MODE> where $PXi<MODE>: StatefulOutputPin<Error=Infallible> {
#[inline(always)]
fn is_set_high(&mut self) -> Result<bool, Self::Error> {
StatefulOutputPin::is_set_high(self)
}

#[inline(always)]
fn is_set_low(&mut self) -> Result<bool, Self::Error> {
StatefulOutputPin::is_set_low(self)
}
}
)+
}
)+
Expand Down
105 changes: 105 additions & 0 deletions src/spi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -529,3 +529,108 @@ where
Ok(())
}
}

impl embedded_hal_1::spi::Error for Error {
fn kind(&self) -> embedded_hal_1::spi::ErrorKind {
match self {
Error::Overrun => embedded_hal_1::spi::ErrorKind::Overrun,
Error::ModeFault => embedded_hal_1::spi::ErrorKind::ModeFault,
Error::Crc => embedded_hal_1::spi::ErrorKind::Other,
}
}
}
impl<SPI, SCKPIN, MISOPIN, MOSIPIN, WIDTH> embedded_hal_1::spi::ErrorType
for Spi<SPI, SCKPIN, MISOPIN, MOSIPIN, WIDTH>
where
SPI: Deref<Target = SpiRegisterBlock>,
{
type Error = Error;
}

impl<SPI, SCKPIN, MISOPIN, MOSIPIN> embedded_hal_1::spi::SpiBus<u8>
for Spi<SPI, SCKPIN, MISOPIN, MOSIPIN, EightBit>
where
SPI: Deref<Target = SpiRegisterBlock>,
{
fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
// We want to transfer bidirectionally, make sure we're in the correct mode
self.set_bidi();

for word in words.iter_mut() {
nb::block!(self.check_send())?;
self.send_u8(0); // FIXME is this necessary?
nb::block!(self.check_read())?;
*word = self.read_u8();
}
Ok(())
}

fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
embedded_hal::blocking::spi::Write::write(self, words)
}

fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> {
// We want to transfer bidirectionally, make sure we're in the correct mode
self.set_bidi();

for (w, r) in write.iter().zip(read.iter_mut()) {
nb::block!(self.check_send())?;
self.send_u8(*w);
nb::block!(self.check_read())?;
*r = self.read_u8();
}
Ok(())
}

fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
embedded_hal::blocking::spi::Transfer::transfer(self, words).map(|_| ())
}

fn flush(&mut self) -> Result<(), Self::Error> {
Ok(())
}
}

impl<SPI, SCKPIN, MISOPIN, MOSIPIN> embedded_hal_1::spi::SpiBus<u16>
for Spi<SPI, SCKPIN, MISOPIN, MOSIPIN, SixteenBit>
where
SPI: Deref<Target = SpiRegisterBlock>,
{
fn read(&mut self, words: &mut [u16]) -> Result<(), Self::Error> {
// We want to transfer bidirectionally, make sure we're in the correct mode
self.set_bidi();

for word in words.iter_mut() {
nb::block!(self.check_send())?;
self.send_u16(0); // FIXME is this necessary?
nb::block!(self.check_read())?;
*word = self.read_u16();
}
Ok(())
}

fn write(&mut self, words: &[u16]) -> Result<(), Self::Error> {
embedded_hal::blocking::spi::Write::write(self, words)
}

fn transfer(&mut self, read: &mut [u16], write: &[u16]) -> Result<(), Self::Error> {
// We want to transfer bidirectionally, make sure we're in the correct mode
self.set_bidi();

for (w, r) in write.iter().zip(read.iter_mut()) {
nb::block!(self.check_send())?;
self.send_u16(*w);
nb::block!(self.check_read())?;
*r = self.read_u16();
}
Ok(())
}

fn transfer_in_place(&mut self, words: &mut [u16]) -> Result<(), Self::Error> {
embedded_hal::blocking::spi::Transfer::transfer(self, words).map(|_| ())
}

fn flush(&mut self) -> Result<(), Self::Error> {
Ok(())
}
}

0 comments on commit 076139a

Please sign in to comment.