Skip to content

Commit 076139a

Browse files
committed
implement eh1 traits for gpios and spi
1 parent b2e2e9d commit 076139a

File tree

4 files changed

+197
-0
lines changed

4 files changed

+197
-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

+89
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,55 @@ 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>
152+
where
153+
Pin<MODE>: InputPin<Error = Infallible>,
154+
{
155+
#[inline(always)]
156+
fn is_high(&mut self) -> Result<bool, Self::Error> {
157+
InputPin::is_high(self)
158+
}
159+
160+
#[inline(always)]
161+
fn is_low(&mut self) -> Result<bool, Self::Error> {
162+
InputPin::is_low(self)
163+
}
164+
}
165+
166+
impl<MODE> embedded_hal_1::digital::OutputPin for Pin<MODE>
167+
where
168+
Pin<MODE>: OutputPin<Error = Infallible>,
169+
{
170+
#[inline(always)]
171+
fn set_high(&mut self) -> Result<(), Self::Error> {
172+
OutputPin::set_high(self)
173+
}
174+
175+
#[inline(always)]
176+
fn set_low(&mut self) -> Result<(), Self::Error> {
177+
OutputPin::set_low(self)
178+
}
179+
}
180+
181+
impl<MODE> embedded_hal_1::digital::StatefulOutputPin for Pin<MODE>
182+
where
183+
Pin<MODE>: StatefulOutputPin<Error = Infallible>,
184+
{
185+
#[inline(always)]
186+
fn is_set_high(&mut self) -> Result<bool, Self::Error> {
187+
StatefulOutputPin::is_set_high(self)
188+
}
189+
190+
#[inline(always)]
191+
fn is_set_low(&mut self) -> Result<bool, Self::Error> {
192+
StatefulOutputPin::is_set_low(self)
193+
}
194+
}
195+
147196
macro_rules! gpio_trait {
148197
($gpiox:ident) => {
149198
impl GpioRegExt for crate::pac::$gpiox::RegisterBlock {
@@ -564,6 +613,46 @@ macro_rules! gpio {
564613
Ok(unsafe { (*$GPIOX::ptr()).is_low($i) })
565614
}
566615
}
616+
617+
impl<MODE> embedded_hal_1::digital::ErrorType for $PXi<MODE>{
618+
type Error = Infallible;
619+
}
620+
621+
impl<MODE> embedded_hal_1::digital::InputPin for $PXi<MODE> where $PXi<MODE>: InputPin<Error=Infallible> {
622+
#[inline(always)]
623+
fn is_high(&mut self) -> Result<bool, Self::Error> {
624+
InputPin::is_high(self)
625+
}
626+
627+
#[inline(always)]
628+
fn is_low(&mut self) -> Result<bool, Self::Error> {
629+
InputPin::is_low(self)
630+
}
631+
}
632+
633+
impl<MODE> embedded_hal_1::digital::OutputPin for $PXi<MODE> where $PXi<MODE>: OutputPin<Error=Infallible> {
634+
#[inline(always)]
635+
fn set_high(&mut self) -> Result<(), Self::Error> {
636+
OutputPin::set_high(self)
637+
}
638+
639+
#[inline(always)]
640+
fn set_low(&mut self) -> Result<(), Self::Error> {
641+
OutputPin::set_low(self)
642+
}
643+
}
644+
645+
impl<MODE> embedded_hal_1::digital::StatefulOutputPin for $PXi<MODE> where $PXi<MODE>: StatefulOutputPin<Error=Infallible> {
646+
#[inline(always)]
647+
fn is_set_high(&mut self) -> Result<bool, Self::Error> {
648+
StatefulOutputPin::is_set_high(self)
649+
}
650+
651+
#[inline(always)]
652+
fn is_set_low(&mut self) -> Result<bool, Self::Error> {
653+
StatefulOutputPin::is_set_low(self)
654+
}
655+
}
567656
)+
568657
}
569658
)+

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)