Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

07-uart code refactor #583

Merged
16 changes: 9 additions & 7 deletions microbit/src/07-uart/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,24 @@ authors = ["Henrik Böving <[email protected]>"]
edition = "2018"

[dependencies.microbit-v2]
version = "0.12.0"
version = "0.15.1"
optional = true

[dependencies.microbit]
version = "0.12.0"
version = "0.15.1"
optional = true

[dependencies]
cortex-m = "0.7.3"
cortex-m = { version = "0.7.7", features = ["critical-section-single-core"] }
cortex-m-rt = "0.7.0"
rtt-target = { version = "0.3.1", features = ["cortex-m"] }
rtt-target = "0.5.0"
panic-rtt-target = { version = "0.1.2", features = ["cortex-m"] }
nb = "1.0.0"
heapless = "0.7.10"
embedded-hal = "0.2.6"
heapless = "0.8.0"
embedded-hal = "1.0.0"
embedded-hal-nb = "1.0.0"
embedded-io = "0.6.1"

[features]
v2 = ["microbit-v2"]
v1 = ["microbit"]
v1 = ["microbit"]
2 changes: 1 addition & 1 deletion microbit/src/07-uart/Embed.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[default.general]
# chip = "nrf52833_xxAA" # uncomment this line for micro:bit V2
chip = "nrf52833_xxAA" # uncomment this line for micro:bit V2
# chip = "nrf51822_xxAA" # uncomment this line for micro:bit V1

[default.reset]
Expand Down
26 changes: 21 additions & 5 deletions microbit/src/07-uart/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
#![no_std]

use cortex_m_rt::entry;
use rtt_target::rtt_init_print;
use panic_rtt_target as _;
use rtt_target::rtt_init_print;

#[cfg(feature = "v1")]
use microbit::{
Expand All @@ -19,6 +19,12 @@ use microbit::{
hal::uarte::{Baudrate, Parity},
};

#[cfg(feature = "v1")]
use embedded_io::Write;

#[cfg(feature = "v2")]
use embedded_hal_nb::serial::Write;

#[cfg(feature = "v2")]
mod serial_setup;
#[cfg(feature = "v2")]
Expand All @@ -31,16 +37,19 @@ fn main() -> ! {

#[cfg(feature = "v1")]
let mut serial = {
uart::Uart::new(
// Set up UART for microbit v1
let serial = uart::Uart::new(
board.UART0,
board.uart.into(),
Parity::EXCLUDED,
Baudrate::BAUD115200,
)
);
serial
};

#[cfg(feature = "v2")]
let mut serial = {
// Set up UARTE for microbit v2 using UartePort wrapper
let serial = uarte::Uarte::new(
board.UARTE0,
board.uart.into(),
Expand All @@ -50,8 +59,15 @@ fn main() -> ! {
UartePort::new(serial)
};

nb::block!(serial.write(b'X')).unwrap();
nb::block!(serial.flush()).unwrap();
// Write a byte and flush
#[cfg(feature = "v1")]
serial.write(&[b'X']).unwrap(); // Adjusted for UART on v1, no need for nb::block!

#[cfg(feature = "v2")]
{
nb::block!(serial.write(b'X')).unwrap();
nb::block!(serial.flush()).unwrap();
}

loop {}
}
58 changes: 41 additions & 17 deletions microbit/src/07-uart/src/serial_setup.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use core::fmt;
use embedded_hal::blocking::serial as bserial;
use embedded_hal::serial;
use microbit::hal::uarte::{Error, Instance, Uarte, UarteRx, UarteTx};
use core::ptr::addr_of_mut;
use embedded_hal_nb::nb;
use embedded_hal_nb::serial::{Error as SerialError, ErrorType, Read, Write};
use embedded_io::{Read as EmbeddedIoRead, Write as EmbeddedIoWrite};
use microbit::hal::uarte::{Instance, Uarte, UarteRx, UarteTx};

static mut TX_BUF: [u8; 1] = [0; 1];
static mut RX_BUF: [u8; 1] = [0; 1];
Expand All @@ -11,36 +13,58 @@ pub struct UartePort<T: Instance>(UarteTx<T>, UarteRx<T>);
impl<T: Instance> UartePort<T> {
pub fn new(serial: Uarte<T>) -> UartePort<T> {
let (tx, rx) = serial
.split(unsafe { &mut TX_BUF }, unsafe { &mut RX_BUF })
.split(unsafe { &mut *addr_of_mut!(TX_BUF) }, unsafe {
&mut *addr_of_mut!(RX_BUF)
})
.unwrap();
UartePort(tx, rx)
}
}

impl<T: Instance> fmt::Write for UartePort<T> {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.0.write_str(s)
#[derive(Debug)]
pub enum Error {
Other,
}

impl SerialError for Error {
fn kind(&self) -> embedded_hal_nb::serial::ErrorKind {
embedded_hal_nb::serial::ErrorKind::Other
}
}

impl<T: Instance> serial::Write<u8> for UartePort<T> {
impl<T: Instance> ErrorType for UartePort<T> {
type Error = Error;
}

fn write(&mut self, b: u8) -> nb::Result<(), Self::Error> {
self.0.write(b)
impl<T: Instance> fmt::Write for UartePort<T> {
fn write_str(&mut self, s: &str) -> fmt::Result {
for byte in s.bytes() {
nb::block!(self.write(byte)).map_err(|_| fmt::Error)?;
}
Ok(())
}
}

impl<T: Instance> Write<u8> for UartePort<T> {
fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
self.0
.write(&[word])
.map_err(|_| nb::Error::Other(Error::Other))?;
Ok(())
}

fn flush(&mut self) -> nb::Result<(), Self::Error> {
self.0.flush()
self.0.flush().map_err(|_| nb::Error::Other(Error::Other))
}
}

impl<T: Instance> bserial::write::Default<u8> for UartePort<T> {}

impl<T: Instance> serial::Read<u8> for UartePort<T> {
type Error = Error;

impl<T: Instance> Read<u8> for UartePort<T> {
fn read(&mut self) -> nb::Result<u8, Self::Error> {
self.1.read()
let mut buffer = [0u8; 1];
match self.1.read(&mut buffer) {
Ok(1) => Ok(buffer[0]),
Ok(_) => Err(nb::Error::WouldBlock),
Err(_) => Err(nb::Error::Other(Error::Other)),
}
}
}
Loading