Skip to content

Commit 969c917

Browse files
committed
implement eh1 traits for gpios and spi
1 parent b2e2e9d commit 969c917

File tree

4 files changed

+188
-0
lines changed

4 files changed

+188
-0
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1818
- PWM complementary output capability for TIM1 with new example to demonstrate
1919
- Implement interface for reading and writing to the internal flash memory and an example for demonstration.
2020
- PWM output on complementary channels only for single channel timers (TIM16 + TIM17)
21+
- impl embedded_hal_1::spi::SpiBus for SPI
22+
- impl embedded_hal_1::digital traits for Pins
2123

2224
### Fixed
2325

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ bare-metal = { version = "1.0.0" }
3434
cast = "0.3"
3535
cortex-m = "0.7"
3636
embedded-hal = { version = "0.2", features = ["unproven"] }
37+
embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
3738
stm32f0 = "0.14"
3839
nb = "1"
3940
void = { version = "1.0", default-features = false }

src/gpio.rs

+80
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,46 @@ impl<MODE> InputPin for Pin<Input<MODE>> {
144144
}
145145
}
146146

147+
impl<MODE> embedded_hal_1::digital::ErrorType for Pin<MODE>{
148+
type Error = Infallible;
149+
}
150+
151+
impl<MODE> embedded_hal_1::digital::InputPin for Pin<MODE> where Pin<MODE>: InputPin<Error=Infallible> {
152+
#[inline(always)]
153+
fn is_high(&mut self) -> Result<bool, Self::Error> {
154+
InputPin::is_high(self)
155+
}
156+
157+
#[inline(always)]
158+
fn is_low(&mut self) -> Result<bool, Self::Error> {
159+
InputPin::is_low(self)
160+
}
161+
}
162+
163+
impl<MODE> embedded_hal_1::digital::OutputPin for Pin<MODE> where Pin<MODE>: OutputPin<Error=Infallible> {
164+
#[inline(always)]
165+
fn set_high(&mut self) -> Result<(), Self::Error> {
166+
OutputPin::set_high(self)
167+
}
168+
169+
#[inline(always)]
170+
fn set_low(&mut self) -> Result<(), Self::Error> {
171+
OutputPin::set_low(self)
172+
}
173+
}
174+
175+
impl<MODE> embedded_hal_1::digital::StatefulOutputPin for Pin<MODE> where Pin<MODE>: StatefulOutputPin<Error=Infallible> {
176+
#[inline(always)]
177+
fn is_set_high(&mut self) -> Result<bool, Self::Error> {
178+
StatefulOutputPin::is_set_high(self)
179+
}
180+
181+
#[inline(always)]
182+
fn is_set_low(&mut self) -> Result<bool, Self::Error> {
183+
StatefulOutputPin::is_set_low(self)
184+
}
185+
}
186+
147187
macro_rules! gpio_trait {
148188
($gpiox:ident) => {
149189
impl GpioRegExt for crate::pac::$gpiox::RegisterBlock {
@@ -564,6 +604,46 @@ macro_rules! gpio {
564604
Ok(unsafe { (*$GPIOX::ptr()).is_low($i) })
565605
}
566606
}
607+
608+
impl<MODE> embedded_hal_1::digital::ErrorType for $PXi<MODE>{
609+
type Error = Infallible;
610+
}
611+
612+
impl<MODE> embedded_hal_1::digital::InputPin for $PXi<MODE> where $PXi<MODE>: InputPin<Error=Infallible> {
613+
#[inline(always)]
614+
fn is_high(&mut self) -> Result<bool, Self::Error> {
615+
InputPin::is_high(self)
616+
}
617+
618+
#[inline(always)]
619+
fn is_low(&mut self) -> Result<bool, Self::Error> {
620+
InputPin::is_low(self)
621+
}
622+
}
623+
624+
impl<MODE> embedded_hal_1::digital::OutputPin for $PXi<MODE> where $PXi<MODE>: OutputPin<Error=Infallible> {
625+
#[inline(always)]
626+
fn set_high(&mut self) -> Result<(), Self::Error> {
627+
OutputPin::set_high(self)
628+
}
629+
630+
#[inline(always)]
631+
fn set_low(&mut self) -> Result<(), Self::Error> {
632+
OutputPin::set_low(self)
633+
}
634+
}
635+
636+
impl<MODE> embedded_hal_1::digital::StatefulOutputPin for $PXi<MODE> where $PXi<MODE>: StatefulOutputPin<Error=Infallible> {
637+
#[inline(always)]
638+
fn is_set_high(&mut self) -> Result<bool, Self::Error> {
639+
StatefulOutputPin::is_set_high(self)
640+
}
641+
642+
#[inline(always)]
643+
fn is_set_low(&mut self) -> Result<bool, Self::Error> {
644+
StatefulOutputPin::is_set_low(self)
645+
}
646+
}
567647
)+
568648
}
569649
)+

src/spi.rs

+105
Original file line numberDiff line numberDiff line change
@@ -529,3 +529,108 @@ where
529529
Ok(())
530530
}
531531
}
532+
533+
impl embedded_hal_1::spi::Error for Error {
534+
fn kind(&self) -> embedded_hal_1::spi::ErrorKind {
535+
match self {
536+
Error::Overrun => embedded_hal_1::spi::ErrorKind::Overrun,
537+
Error::ModeFault => embedded_hal_1::spi::ErrorKind::ModeFault,
538+
Error::Crc => embedded_hal_1::spi::ErrorKind::Other,
539+
}
540+
}
541+
}
542+
impl<SPI, SCKPIN, MISOPIN, MOSIPIN, WIDTH> embedded_hal_1::spi::ErrorType
543+
for Spi<SPI, SCKPIN, MISOPIN, MOSIPIN, WIDTH>
544+
where
545+
SPI: Deref<Target = SpiRegisterBlock>,
546+
{
547+
type Error = Error;
548+
}
549+
550+
impl<SPI, SCKPIN, MISOPIN, MOSIPIN> embedded_hal_1::spi::SpiBus<u8>
551+
for Spi<SPI, SCKPIN, MISOPIN, MOSIPIN, EightBit>
552+
where
553+
SPI: Deref<Target = SpiRegisterBlock>,
554+
{
555+
fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
556+
// We want to transfer bidirectionally, make sure we're in the correct mode
557+
self.set_bidi();
558+
559+
for word in words.iter_mut() {
560+
nb::block!(self.check_send())?;
561+
self.send_u8(0); // FIXME is this necessary?
562+
nb::block!(self.check_read())?;
563+
*word = self.read_u8();
564+
}
565+
Ok(())
566+
}
567+
568+
fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
569+
embedded_hal::blocking::spi::Write::write(self, words)
570+
}
571+
572+
fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> {
573+
// We want to transfer bidirectionally, make sure we're in the correct mode
574+
self.set_bidi();
575+
576+
for (w, r) in write.iter().zip(read.iter_mut()) {
577+
nb::block!(self.check_send())?;
578+
self.send_u8(*w);
579+
nb::block!(self.check_read())?;
580+
*r = self.read_u8();
581+
}
582+
Ok(())
583+
}
584+
585+
fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
586+
embedded_hal::blocking::spi::Transfer::transfer(self, words).map(|_| ())
587+
}
588+
589+
fn flush(&mut self) -> Result<(), Self::Error> {
590+
Ok(())
591+
}
592+
}
593+
594+
impl<SPI, SCKPIN, MISOPIN, MOSIPIN> embedded_hal_1::spi::SpiBus<u16>
595+
for Spi<SPI, SCKPIN, MISOPIN, MOSIPIN, SixteenBit>
596+
where
597+
SPI: Deref<Target = SpiRegisterBlock>,
598+
{
599+
fn read(&mut self, words: &mut [u16]) -> Result<(), Self::Error> {
600+
// We want to transfer bidirectionally, make sure we're in the correct mode
601+
self.set_bidi();
602+
603+
for word in words.iter_mut() {
604+
nb::block!(self.check_send())?;
605+
self.send_u16(0); // FIXME is this necessary?
606+
nb::block!(self.check_read())?;
607+
*word = self.read_u16();
608+
}
609+
Ok(())
610+
}
611+
612+
fn write(&mut self, words: &[u16]) -> Result<(), Self::Error> {
613+
embedded_hal::blocking::spi::Write::write(self, words)
614+
}
615+
616+
fn transfer(&mut self, read: &mut [u16], write: &[u16]) -> Result<(), Self::Error> {
617+
// We want to transfer bidirectionally, make sure we're in the correct mode
618+
self.set_bidi();
619+
620+
for (w, r) in write.iter().zip(read.iter_mut()) {
621+
nb::block!(self.check_send())?;
622+
self.send_u16(*w);
623+
nb::block!(self.check_read())?;
624+
*r = self.read_u16();
625+
}
626+
Ok(())
627+
}
628+
629+
fn transfer_in_place(&mut self, words: &mut [u16]) -> Result<(), Self::Error> {
630+
embedded_hal::blocking::spi::Transfer::transfer(self, words).map(|_| ())
631+
}
632+
633+
fn flush(&mut self) -> Result<(), Self::Error> {
634+
Ok(())
635+
}
636+
}

0 commit comments

Comments
 (0)