Skip to content

Commit

Permalink
Implement FullDuplex for SPI and add check_errors method
Browse files Browse the repository at this point in the history
check_errors only checks for Overrun, CRC error and ModeFault flags.
  • Loading branch information
dkm committed Nov 15, 2020
1 parent 2bb8bb9 commit d9a3f0b
Showing 1 changed file with 80 additions and 22 deletions.
102 changes: 80 additions & 22 deletions src/spi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,17 +365,27 @@ where
fn check_read(&mut self) -> nb::Result<(), Error> {
let sr = self.spi.sr.read();

Err(if sr.ovr().bit_is_set() {
nb::Error::Other(Error::Overrun)
self.check_errors()?;

if !sr.rxne().bit_is_set() {
Err(nb::Error::WouldBlock)
} else {
Ok(())
}
}

fn check_errors(&mut self) -> Result<(), Error> {
let sr = self.spi.sr.read();

if sr.ovr().bit_is_set() {
Err(Error::Overrun)
} else if sr.modf().bit_is_set() {
nb::Error::Other(Error::ModeFault)
Err(Error::ModeFault)
} else if sr.crcerr().bit_is_set() {
nb::Error::Other(Error::Crc)
} else if sr.rxne().bit_is_set() {
return Ok(());
Err(Error::Crc)
} else {
nb::Error::WouldBlock
})
Ok(())
}
}

fn send_buffer_size(&mut self) -> u8 {
Expand All @@ -394,17 +404,15 @@ where
fn check_send(&mut self) -> nb::Result<(), Error> {
let sr = self.spi.sr.read();

Err(if sr.ovr().bit_is_set() {
nb::Error::Other(Error::Overrun)
} else if sr.modf().bit_is_set() {
nb::Error::Other(Error::ModeFault)
} else if sr.crcerr().bit_is_set() {
nb::Error::Other(Error::Crc)
} else if sr.txe().bit_is_set() {
return Ok(());
if let Err(e) = self.check_errors() {
return Err(nb::Error::Other(e));
}

if !sr.txe().bit_is_set() {
Err(nb::Error::WouldBlock)
} else {
nb::Error::WouldBlock
})
Ok(())
}
}

fn read_u8(&mut self) -> u8 {
Expand Down Expand Up @@ -454,6 +462,32 @@ where
}
}

impl<SPI, SCKPIN, MISOPIN, MOSIPIN> ::embedded_hal::spi::FullDuplex<u8>
for Spi<SPI, SCKPIN, MISOPIN, MOSIPIN, EightBit>
where
SPI: Deref<Target = SpiRegisterBlock>,
{
type Error = Error;

fn read(&mut self) -> nb::Result<u8, Error> {
self.check_read()?;
Ok(self.read_u8())
}

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

self.check_send()?;
self.send_u8(byte);

match self.check_errors() {
Ok(_) => Ok(()),
Err(e) => Err(nb::Error::Other(e)),
}
}
}

impl<SPI, SCKPIN, MISOPIN, MOSIPIN> ::embedded_hal::blocking::spi::Write<u8>
for Spi<SPI, SCKPIN, MISOPIN, MOSIPIN, EightBit>
where
Expand Down Expand Up @@ -482,8 +516,33 @@ where
}

// Do one last status register check before continuing
self.check_send().ok();
Ok(())
self.check_errors()
}
}

impl<SPI, SCKPIN, MISOPIN, MOSIPIN> ::embedded_hal::spi::FullDuplex<u16>
for Spi<SPI, SCKPIN, MISOPIN, MOSIPIN, SixteenBit>
where
SPI: Deref<Target = SpiRegisterBlock>,
{
type Error = Error;

fn read(&mut self) -> nb::Result<u16, Error> {
self.check_read()?;
Ok(self.read_u16())
}

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

self.check_send()?;
self.send_u16(byte);

match self.check_errors() {
Ok(_) => Ok(()),
Err(e) => Err(nb::Error::Other(e)),
}
}
}

Expand Down Expand Up @@ -526,7 +585,6 @@ where
}

// Do one last status register check before continuing
self.check_send().ok();
Ok(())
self.check_errors()
}
}

0 comments on commit d9a3f0b

Please sign in to comment.