Skip to content

Commit db4b2ce

Browse files
committed
Implement FullDuplex for SPI and add check_errors method
check_errors only checks for Overrun, CRC error and ModeFault flags. Signed-off-by: Marc Poulhiès <[email protected]>
1 parent 0d1a7f4 commit db4b2ce

File tree

1 file changed

+75
-22
lines changed

1 file changed

+75
-22
lines changed

src/spi.rs

Lines changed: 75 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -364,17 +364,27 @@ where
364364
fn check_read(&mut self) -> nb::Result<(), Error> {
365365
let sr = self.spi.sr.read();
366366

367-
Err(if sr.ovr().bit_is_set() {
368-
nb::Error::Other(Error::Overrun)
367+
self.check_errors()?;
368+
369+
if !sr.rxne().bit_is_set() {
370+
Err(nb::Error::WouldBlock)
371+
} else {
372+
Ok(())
373+
}
374+
}
375+
376+
fn check_errors(&mut self) -> Result<(), Error> {
377+
let sr = self.spi.sr.read();
378+
379+
if sr.ovr().bit_is_set() {
380+
Err(Error::Overrun)
369381
} else if sr.modf().bit_is_set() {
370-
nb::Error::Other(Error::ModeFault)
382+
Err(Error::ModeFault)
371383
} else if sr.crcerr().bit_is_set() {
372-
nb::Error::Other(Error::Crc)
373-
} else if sr.rxne().bit_is_set() {
374-
return Ok(());
384+
Err(Error::Crc)
375385
} else {
376-
nb::Error::WouldBlock
377-
})
386+
Ok(())
387+
}
378388
}
379389

380390
fn send_buffer_size(&mut self) -> u8 {
@@ -393,17 +403,13 @@ where
393403
fn check_send(&mut self) -> nb::Result<(), Error> {
394404
let sr = self.spi.sr.read();
395405

396-
Err(if sr.ovr().bit_is_set() {
397-
nb::Error::Other(Error::Overrun)
398-
} else if sr.modf().bit_is_set() {
399-
nb::Error::Other(Error::ModeFault)
400-
} else if sr.crcerr().bit_is_set() {
401-
nb::Error::Other(Error::Crc)
402-
} else if sr.txe().bit_is_set() && sr.bsy().bit_is_clear() {
403-
return Ok(());
406+
self.check_errors()?;
407+
408+
if !(sr.txe().bit_is_set() && sr.bsy().bit_is_clear()) {
409+
Err(nb::Error::WouldBlock)
404410
} else {
405-
nb::Error::WouldBlock
406-
})
411+
Ok(())
412+
}
407413
}
408414

409415
fn read_u8(&mut self) -> u8 {
@@ -453,6 +459,29 @@ where
453459
}
454460
}
455461

462+
impl<SPI, SCKPIN, MISOPIN, MOSIPIN> ::embedded_hal::spi::FullDuplex<u8>
463+
for Spi<SPI, SCKPIN, MISOPIN, MOSIPIN, EightBit>
464+
where
465+
SPI: Deref<Target = SpiRegisterBlock>,
466+
{
467+
type Error = Error;
468+
469+
fn read(&mut self) -> nb::Result<u8, Error> {
470+
self.check_read()?;
471+
Ok(self.read_u8())
472+
}
473+
474+
fn send(&mut self, byte: u8) -> nb::Result<(), Error> {
475+
// We want to transfer bidirectionally, make sure we're in the correct mode
476+
self.set_bidi();
477+
478+
self.check_send()?;
479+
self.send_u8(byte);
480+
481+
self.check_errors().map_err(|e| nb::Error::Other(e))
482+
}
483+
}
484+
456485
impl<SPI, SCKPIN, MISOPIN, MOSIPIN> ::embedded_hal::blocking::spi::Write<u8>
457486
for Spi<SPI, SCKPIN, MISOPIN, MOSIPIN, EightBit>
458487
where
@@ -481,8 +510,33 @@ where
481510
}
482511

483512
// Do one last status register check before continuing
484-
nb::block!(self.check_send()).ok();
485-
Ok(())
513+
self.check_errors()
514+
}
515+
}
516+
517+
impl<SPI, SCKPIN, MISOPIN, MOSIPIN> ::embedded_hal::spi::FullDuplex<u16>
518+
for Spi<SPI, SCKPIN, MISOPIN, MOSIPIN, SixteenBit>
519+
where
520+
SPI: Deref<Target = SpiRegisterBlock>,
521+
{
522+
type Error = Error;
523+
524+
fn read(&mut self) -> nb::Result<u16, Error> {
525+
self.check_read()?;
526+
Ok(self.read_u16())
527+
}
528+
529+
fn send(&mut self, byte: u16) -> nb::Result<(), Error> {
530+
// We want to transfer bidirectionally, make sure we're in the correct mode
531+
self.set_bidi();
532+
533+
self.check_send()?;
534+
self.send_u16(byte);
535+
536+
match self.check_errors() {
537+
Ok(_) => Ok(()),
538+
Err(e) => Err(nb::Error::Other(e)),
539+
}
486540
}
487541
}
488542

@@ -525,7 +579,6 @@ where
525579
}
526580

527581
// Do one last status register check before continuing
528-
nb::block!(self.check_send()).ok();
529-
Ok(())
582+
self.check_errors()
530583
}
531584
}

0 commit comments

Comments
 (0)