Skip to content

Commit 34d2ee3

Browse files
committed
Implement FullDuplex for SPI and add check_errors method
check_errors only checks for Overrun, CRC error and ModeFault flags.
1 parent 2bb8bb9 commit 34d2ee3

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
@@ -365,17 +365,27 @@ where
365365
fn check_read(&mut self) -> nb::Result<(), Error> {
366366
let sr = self.spi.sr.read();
367367

368-
Err(if sr.ovr().bit_is_set() {
369-
nb::Error::Other(Error::Overrun)
368+
self.check_errors()?;
369+
370+
if !sr.rxne().bit_is_set() {
371+
Err(nb::Error::WouldBlock)
372+
} else {
373+
Ok(())
374+
}
375+
}
376+
377+
fn check_errors(&mut self) -> Result<(), Error> {
378+
let sr = self.spi.sr.read();
379+
380+
if sr.ovr().bit_is_set() {
381+
Err(Error::Overrun)
370382
} else if sr.modf().bit_is_set() {
371-
nb::Error::Other(Error::ModeFault)
383+
Err(Error::ModeFault)
372384
} else if sr.crcerr().bit_is_set() {
373-
nb::Error::Other(Error::Crc)
374-
} else if sr.rxne().bit_is_set() {
375-
return Ok(());
385+
Err(Error::Crc)
376386
} else {
377-
nb::Error::WouldBlock
378-
})
387+
Ok(())
388+
}
379389
}
380390

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

397-
Err(if sr.ovr().bit_is_set() {
398-
nb::Error::Other(Error::Overrun)
399-
} else if sr.modf().bit_is_set() {
400-
nb::Error::Other(Error::ModeFault)
401-
} else if sr.crcerr().bit_is_set() {
402-
nb::Error::Other(Error::Crc)
403-
} else if sr.txe().bit_is_set() {
404-
return Ok(());
407+
self.check_errors()?;
408+
409+
if !sr.txe().bit_is_set() {
410+
Err(nb::Error::WouldBlock)
405411
} else {
406-
nb::Error::WouldBlock
407-
})
412+
Ok(())
413+
}
408414
}
409415

410416
fn read_u8(&mut self) -> u8 {
@@ -454,6 +460,29 @@ where
454460
}
455461
}
456462

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

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

@@ -526,7 +580,6 @@ where
526580
}
527581

528582
// Do one last status register check before continuing
529-
self.check_send().ok();
530-
Ok(())
583+
self.check_errors()
531584
}
532585
}

0 commit comments

Comments
 (0)