Skip to content

Commit

Permalink
serial
Browse files Browse the repository at this point in the history
  • Loading branch information
burrbull committed Jun 12, 2024
1 parent aed0bde commit 8bde191
Show file tree
Hide file tree
Showing 10 changed files with 140 additions and 50 deletions.
File renamed without changes.
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ version = "1.0"
[dependencies.embedded-hal-nb]
version = "1.0"

[dependencies.embedded-io]
version = "0.6.1"

[dependencies.stm32-usbd]
version = "0.6.0"
optional = true
Expand All @@ -56,7 +59,6 @@ heapless = "0.7.16"
mfrc522 = "0.3.0"
usb-device = "0.2.8"
usbd-serial = "0.1.1"
unwrap-infallible = "0.1.5"

[features]
device-selected = []
Expand Down
2 changes: 1 addition & 1 deletion examples/serial-interrupt-idle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ static mut WIDX: usize = 0;
unsafe fn write(buf: &[u8]) {
if let Some(tx) = TX.as_mut() {
buf.iter()
.for_each(|w| if let Err(_err) = nb::block!(tx.write(*w)) {})
.for_each(|w| if let Err(_err) = nb::block!(tx.write_u8(*w)) {})
}
}
#[interrupt]
Expand Down
5 changes: 2 additions & 3 deletions examples/serial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ use stm32f1xx_hal::{
prelude::*,
serial::{Config, Serial},
};
use unwrap_infallible::UnwrapInfallible;

#[entry]
fn main() -> ! {
Expand Down Expand Up @@ -71,7 +70,7 @@ fn main() -> ! {

// Loopback test. Write `X` and wait until the write is successful.
let sent = b'X';
block!(serial.tx.write(sent)).unwrap_infallible();
block!(serial.tx.write_u8(sent)).unwrap();

// Read the byte that was just sent. Blocks until the read is complete
let received = block!(serial.rx.read()).unwrap();
Expand All @@ -85,7 +84,7 @@ fn main() -> ! {
// You can also split the serial struct into a receiving and a transmitting part
let (mut tx, mut rx) = serial.split();
let sent = b'Y';
block!(tx.write(sent)).unwrap_infallible();
block!(tx.write_u8(sent)).unwrap();
let received = block!(rx.read()).unwrap();
assert_eq!(received, sent);
asm::bkpt();
Expand Down
14 changes: 6 additions & 8 deletions examples/serial_9bits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,14 @@
#![no_main]
#![no_std]

use core::convert::Infallible;
use cortex_m_rt::entry;
use nb::block;
use panic_halt as _;
use stm32f1xx_hal::{
pac,
prelude::*,
serial::{self, Config, Serial},
serial::{self, Config, Error, Serial},
};
use unwrap_infallible::UnwrapInfallible;

// The address of the slave device.
const SLAVE_ADDR: u8 = 123;
Expand Down Expand Up @@ -79,19 +77,19 @@ where
// Send message.
fn send_msg<TX>(serial_tx: &mut TX, msg: &[u8])
where
TX: embedded_hal_02::serial::Write<u8, Error = Infallible>
+ embedded_hal_02::serial::Write<u16, Error = Infallible>,
TX: embedded_hal_02::serial::Write<u8, Error = Error>
+ embedded_hal_02::serial::Write<u16, Error = Error>,
{
// Send address.
block!(serial_tx.write(SLAVE_ADDR as u16 | 0x100)).unwrap_infallible();
block!(serial_tx.write(SLAVE_ADDR as u16 | 0x100)).unwrap();

// Send message len.
assert!(msg.len() <= MSG_MAX_LEN);
block!(serial_tx.write(msg.len() as u8)).unwrap_infallible();
block!(serial_tx.write(msg.len() as u8)).unwrap();

// Send message.
for &b in msg {
block!(serial_tx.write(b)).unwrap_infallible();
block!(serial_tx.write(b)).unwrap();
}
}

Expand Down
5 changes: 2 additions & 3 deletions examples/serial_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ use stm32f1xx_hal::{
prelude::*,
serial::{self, Serial},
};
use unwrap_infallible::UnwrapInfallible;

#[entry]
fn main() -> ! {
Expand Down Expand Up @@ -75,8 +74,8 @@ fn main() -> ! {
let (mut tx, _rx) = serial.split();

let sent = b'U';
block!(tx.write(sent)).unwrap_infallible();
block!(tx.write(sent)).unwrap_infallible();
block!(tx.write_u8(sent)).unwrap();
block!(tx.write_u8(sent)).unwrap();

loop {}
}
5 changes: 2 additions & 3 deletions examples/serial_reconfigure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ use stm32f1xx_hal::{
prelude::*,
serial::{self, Config, Serial},
};
use unwrap_infallible::UnwrapInfallible;

#[entry]
fn main() -> ! {
Expand Down Expand Up @@ -71,7 +70,7 @@ fn main() -> ! {

// Loopback test. Write `X` and wait until the write is successful.
let sent = b'X';
block!(serial.tx.write(sent)).unwrap_infallible();
block!(serial.tx.write_u8(sent)).unwrap();

// Read the byte that was just sent. Blocks until the read is complete
let received = block!(serial.rx.read()).unwrap();
Expand All @@ -88,7 +87,7 @@ fn main() -> ! {

// Let's see if it works.'
let sent = b'Y';
block!(serial.tx.write(sent)).unwrap_infallible();
block!(serial.tx.write_u8(sent)).unwrap();
let received = block!(serial.rx.read()).unwrap();
assert_eq!(received, sent);
asm::bkpt();
Expand Down
47 changes: 32 additions & 15 deletions src/serial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@
//!
//! // Write data (9 bits) to the USART.
//! // Depending on the configuration, only the lower 7, 8, or 9 bits are used.
//! block!(tx.write_u16(0x1FF)).unwrap_infallible();
//! block!(tx.write_u16(0x1FF)).unwrap();
//!
//! // Write 'R' (8 bits) to the USART
//! block!(tx.write(b'R')).unwrap_infallible();
//! block!(tx.write_u8(b'R')).unwrap();
//!
//! // Receive a data (9 bits) from the USART and store it in "received"
//! let received = block!(rx.read_u16()).unwrap();
Expand All @@ -61,7 +61,6 @@
//! let received = block!(rx.read()).unwrap();
//! ```

use core::convert::Infallible;
use core::marker::PhantomData;
use core::ops::Deref;
use core::sync::atomic::{self, Ordering};
Expand Down Expand Up @@ -134,8 +133,26 @@ inst! {
USART3
}

/// Serial error
pub use embedded_hal_nb::serial::ErrorKind as Error;
/// Serial error kind
///
/// This represents a common set of serial operation errors. HAL implementations are
/// free to define more specific or additional error types. However, by providing
/// a mapping to these common serial errors, generic code can still react to them.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[non_exhaustive]
pub enum Error {
/// The peripheral receive buffer was overrun.
Overrun,
/// Received data does not conform to the peripheral configuration.
/// Can be caused by a misconfigured device on either end of the serial line.
FrameFormat,
/// Parity check failed.
Parity,
/// Serial line is too noisy to read valid data.
Noise,
/// A different error occurred. The original error may contain more information.
Other,
}

pub enum WordLength {
/// When parity is enabled, a word has 7 data bits + 1 parity bit,
Expand Down Expand Up @@ -321,7 +338,7 @@ impl<USART: Instance, PINS> Serial<USART, PINS> {
&mut self,
config: impl Into<Config>,
clocks: &Clocks,
) -> nb::Result<(), Infallible> {
) -> nb::Result<(), Error> {
reconfigure(&mut self.tx, &mut self.rx, config, clocks)
}

Expand Down Expand Up @@ -403,7 +420,7 @@ pub fn reconfigure<USART: Instance>(
#[allow(unused_variables)] rx: &mut Rx<USART>,
config: impl Into<Config>,
clocks: &Clocks,
) -> nb::Result<(), Infallible> {
) -> nb::Result<(), Error> {
// if we're currently busy transmitting, we have to wait until that is
// over -- regarding reception, we assume that the caller -- with
// exclusive access to the Serial instance due to &mut self -- knows
Expand All @@ -419,7 +436,7 @@ impl<USART: Instance> Tx<USART> {
/// If the UART/USART was configured with `WordLength::Bits9`, the 9 least significant bits will
/// be transmitted and the other 7 bits will be ignored. Otherwise, the 8 least significant bits
/// will be transmitted and the other 8 bits will be ignored.
pub fn write_u16(&mut self, word: u16) -> nb::Result<(), Infallible> {
pub fn write_u16(&mut self, word: u16) -> nb::Result<(), Error> {
let usart = unsafe { &*USART::ptr() };

if usart.sr.read().txe().bit_is_set() {
Expand All @@ -430,25 +447,25 @@ impl<USART: Instance> Tx<USART> {
}
}

pub fn write(&mut self, word: u8) -> nb::Result<(), Infallible> {
pub fn write_u8(&mut self, word: u8) -> nb::Result<(), Error> {
self.write_u16(word as u16)
}

pub fn bwrite_all_u16(&mut self, buffer: &[u16]) -> Result<(), Infallible> {
pub fn bwrite_all_u16(&mut self, buffer: &[u16]) -> Result<(), Error> {
for &w in buffer {
nb::block!(self.write_u16(w))?;
}
Ok(())
}

pub fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Infallible> {
pub fn bwrite_all_u8(&mut self, buffer: &[u8]) -> Result<(), Error> {
for &w in buffer {
nb::block!(self.write(w))?;
nb::block!(self.write_u8(w))?;
}
Ok(())
}

pub fn flush(&mut self) -> nb::Result<(), Infallible> {
pub fn flush(&mut self) -> nb::Result<(), Error> {
let usart = unsafe { &*USART::ptr() };

if usart.sr.read().tc().bit_is_set() {
Expand All @@ -458,7 +475,7 @@ impl<USART: Instance> Tx<USART> {
}
}

pub fn bflush(&mut self) -> Result<(), Infallible> {
pub fn bflush(&mut self) -> Result<(), Error> {
nb::block!(self.flush())
}

Expand All @@ -485,7 +502,7 @@ impl<USART: Instance> Tx<USART> {
impl<USART: Instance> core::fmt::Write for Tx<USART> {
fn write_str(&mut self, s: &str) -> core::fmt::Result {
s.bytes()
.try_for_each(|c| nb::block!(self.write(c)))
.try_for_each(|c| nb::block!(self.write_u8(c)))
.map_err(|_| core::fmt::Error)
}
}
Expand Down
24 changes: 12 additions & 12 deletions src/serial/hal_02.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ use super::*;
use embedded_hal_02::{blocking::serial as blocking, serial};

impl<USART: Instance> serial::Write<u8> for Tx<USART> {
type Error = Infallible;
type Error = Error;

fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
self.write(word)
self.write_u8(word)
}

fn flush(&mut self) -> nb::Result<(), Self::Error> {
Expand All @@ -14,7 +14,7 @@ impl<USART: Instance> serial::Write<u8> for Tx<USART> {
}

impl<USART: Instance> serial::Write<u16> for Tx<USART> {
type Error = Infallible;
type Error = Error;

fn write(&mut self, word: u16) -> nb::Result<(), Self::Error> {
self.write_u16(word)
Expand Down Expand Up @@ -42,10 +42,10 @@ impl<USART: Instance> serial::Read<u16> for Rx<USART> {
}

impl<USART: Instance, PINS> serial::Write<u8> for Serial<USART, PINS> {
type Error = Infallible;
type Error = Error;

fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
self.tx.write(word)
self.tx.write_u8(word)
}

fn flush(&mut self) -> nb::Result<(), Self::Error> {
Expand All @@ -54,7 +54,7 @@ impl<USART: Instance, PINS> serial::Write<u8> for Serial<USART, PINS> {
}

impl<USART: Instance, PINS> serial::Write<u16> for Serial<USART, PINS> {
type Error = Infallible;
type Error = Error;

fn write(&mut self, word: u16) -> nb::Result<(), Self::Error> {
self.tx.write_u16(word)
Expand Down Expand Up @@ -84,10 +84,10 @@ impl<USART: Instance, PINS> serial::Read<u16> for Serial<USART, PINS> {
// Blocking

impl<USART: Instance> blocking::Write<u8> for Tx<USART> {
type Error = Infallible;
type Error = Error;

fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
self.bwrite_all(buffer)
self.bwrite_all_u8(buffer)
}

fn bflush(&mut self) -> Result<(), Self::Error> {
Expand All @@ -96,7 +96,7 @@ impl<USART: Instance> blocking::Write<u8> for Tx<USART> {
}

impl<USART: Instance> blocking::Write<u16> for Tx<USART> {
type Error = Infallible;
type Error = Error;

fn bwrite_all(&mut self, buffer: &[u16]) -> Result<(), Self::Error> {
self.bwrite_all_u16(buffer)
Expand All @@ -108,10 +108,10 @@ impl<USART: Instance> blocking::Write<u16> for Tx<USART> {
}

impl<USART: Instance, PINS> blocking::Write<u8> for Serial<USART, PINS> {
type Error = Infallible;
type Error = Error;

fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
self.tx.bwrite_all(buffer)
self.tx.bwrite_all_u8(buffer)
}

fn bflush(&mut self) -> Result<(), Self::Error> {
Expand All @@ -120,7 +120,7 @@ impl<USART: Instance, PINS> blocking::Write<u8> for Serial<USART, PINS> {
}

impl<USART: Instance, PINS> blocking::Write<u16> for Serial<USART, PINS> {
type Error = Infallible;
type Error = Error;

fn bwrite_all(&mut self, buffer: &[u16]) -> Result<(), Self::Error> {
self.tx.bwrite_all_u16(buffer)
Expand Down
Loading

0 comments on commit 8bde191

Please sign in to comment.