|
|
|
@ -75,6 +75,7 @@ pub struct SixteenBit;
|
|
|
|
|
|
|
|
|
|
/// SPI error
|
|
|
|
|
#[derive(Debug)] |
|
|
|
|
#[non_exhaustive] |
|
|
|
|
pub enum Error { |
|
|
|
|
/// Overrun occurred
|
|
|
|
|
Overrun, |
|
|
|
@ -82,8 +83,6 @@ pub enum Error {
|
|
|
|
|
ModeFault, |
|
|
|
|
/// CRC error
|
|
|
|
|
Crc, |
|
|
|
|
#[doc(hidden)] |
|
|
|
|
_Extensible, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// SPI abstraction
|
|
|
|
@ -365,27 +364,17 @@ where
|
|
|
|
|
fn check_read(&mut self) -> nb::Result<(), Error> { |
|
|
|
|
let sr = self.spi.sr.read(); |
|
|
|
|
|
|
|
|
|
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) |
|
|
|
|
Err(if sr.ovr().bit_is_set() { |
|
|
|
|
nb::Error::Other(Error::Overrun) |
|
|
|
|
} else if sr.modf().bit_is_set() { |
|
|
|
|
Err(Error::ModeFault) |
|
|
|
|
nb::Error::Other(Error::ModeFault) |
|
|
|
|
} else if sr.crcerr().bit_is_set() { |
|
|
|
|
Err(Error::Crc) |
|
|
|
|
nb::Error::Other(Error::Crc) |
|
|
|
|
} else if sr.rxne().bit_is_set() { |
|
|
|
|
return Ok(()); |
|
|
|
|
} else { |
|
|
|
|
Ok(()) |
|
|
|
|
} |
|
|
|
|
nb::Error::WouldBlock |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn send_buffer_size(&mut self) -> u8 { |
|
|
|
@ -404,13 +393,17 @@ where
|
|
|
|
|
fn check_send(&mut self) -> nb::Result<(), Error> { |
|
|
|
|
let sr = self.spi.sr.read(); |
|
|
|
|
|
|
|
|
|
self.check_errors()?; |
|
|
|
|
|
|
|
|
|
if !sr.txe().bit_is_set() { |
|
|
|
|
Err(nb::Error::WouldBlock) |
|
|
|
|
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(()); |
|
|
|
|
} else { |
|
|
|
|
Ok(()) |
|
|
|
|
} |
|
|
|
|
nb::Error::WouldBlock |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn read_u8(&mut self) -> u8 { |
|
|
|
@ -451,7 +444,7 @@ where
|
|
|
|
|
|
|
|
|
|
for word in words.iter_mut() { |
|
|
|
|
nb::block!(self.check_send())?; |
|
|
|
|
self.send_u8(word.clone()); |
|
|
|
|
self.send_u8(*word); |
|
|
|
|
nb::block!(self.check_read())?; |
|
|
|
|
*word = self.read_u8(); |
|
|
|
|
} |
|
|
|
@ -460,29 +453,6 @@ 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); |
|
|
|
|
|
|
|
|
|
self.check_errors().map_err(|e| nb::Error::Other(e)) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl<SPI, SCKPIN, MISOPIN, MOSIPIN> ::embedded_hal::blocking::spi::Write<u8> |
|
|
|
|
for Spi<SPI, SCKPIN, MISOPIN, MOSIPIN, EightBit> |
|
|
|
|
where |
|
|
|
@ -511,33 +481,8 @@ where
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Do one last status register check before continuing
|
|
|
|
|
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)), |
|
|
|
|
} |
|
|
|
|
self.check_send().ok(); |
|
|
|
|
Ok(()) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -576,10 +521,11 @@ where
|
|
|
|
|
|
|
|
|
|
for word in words { |
|
|
|
|
nb::block!(self.check_send())?; |
|
|
|
|
self.send_u16(word.clone()); |
|
|
|
|
self.send_u16(*word); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Do one last status register check before continuing
|
|
|
|
|
self.check_errors() |
|
|
|
|
self.check_send().ok(); |
|
|
|
|
Ok(()) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|