diff --git a/CHANGELOG.md b/CHANGELOG.md index 29344ac..680e5cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Add Board struct following the pattern used in other nrf board support crates. - Add magnetometer example. - LEDs on the micro:bit V1 are now turned off per default +- UART(E) is now exposed in the same way as I2C ## [0.10.1] - 2021-05-25 diff --git a/examples/serial-hal-blocking-echo/Cargo.toml b/examples/serial-hal-blocking-echo/Cargo.toml index 0ba0f49..c44d6d2 100644 --- a/examples/serial-hal-blocking-echo/Cargo.toml +++ b/examples/serial-hal-blocking-echo/Cargo.toml @@ -8,6 +8,16 @@ cortex-m-rt = "0.6.12" panic-halt = "0.2.0" defmt-rtt = "0.2.0" nb = "0.1.2" +embedded-hal = "0.2.6" [dependencies.microbit] path = "../../microbit" +optional = true + +[dependencies.microbit-v2] +path = "../../microbit-v2" +optional = true + +[features] +v1 = ["microbit"] +v2 = ["microbit-v2"] diff --git a/examples/serial-hal-blocking-echo/src/main.rs b/examples/serial-hal-blocking-echo/src/main.rs index e67a580..ef07833 100644 --- a/examples/serial-hal-blocking-echo/src/main.rs +++ b/examples/serial-hal-blocking-echo/src/main.rs @@ -4,33 +4,56 @@ use panic_halt as _; use core::fmt::Write; -use microbit::hal; -use microbit::hal::prelude::*; -use microbit::hal::uart::Baudrate; + +#[cfg(feature = "v1")] +use microbit::{ + hal::prelude::*, + hal::uart, + hal::uart::{Baudrate, Parity}, +}; + +#[cfg(feature = "v2")] +use microbit::{ + hal::prelude::*, + hal::uarte, + hal::uarte::{Baudrate, Parity}, +}; use cortex_m_rt::entry; +#[cfg(feature = "v2")] +mod serial_setup; +#[cfg(feature = "v2")] +use serial_setup::UartePort; + #[entry] fn main() -> ! { - if let Some(p) = microbit::Peripherals::take() { - let gpio = hal::gpio::p0::Parts::new(p.GPIO); - - /* Initialise serial port on the micro:bit */ - let mut serial = microbit::serial_port!(gpio, p.UART0, Baudrate::BAUD115200); - - /* Print a nice hello message */ - write!(serial, "Please type characters to echo:\r\n"); - - /* Endless loop */ - loop { - /* Read and echo back */ - if let Ok(c) = nb::block!(serial.read()) { - let _ = nb::block!(serial.write(c)); - } - } - } + let board = microbit::Board::take().unwrap(); + + #[cfg(feature = "v1")] + let mut serial = { + uart::Uart::new( + board.UART0, + board.uart.into(), + Parity::EXCLUDED, + Baudrate::BAUD115200, + ) + }; + + #[cfg(feature = "v2")] + let mut serial = { + let serial = uarte::Uarte::new( + board.UARTE0, + board.uart.into(), + Parity::EXCLUDED, + Baudrate::BAUD115200, + ); + UartePort::new(serial) + }; loop { - continue; + write!(serial, "Hello World:\r\n").unwrap(); + let input = nb::block!(serial.read()).unwrap(); + write!(serial, "You said: {}\r\n", input as char).unwrap(); } } diff --git a/examples/serial-hal-blocking-echo/src/serial_setup.rs b/examples/serial-hal-blocking-echo/src/serial_setup.rs new file mode 100644 index 0000000..eb3997a --- /dev/null +++ b/examples/serial-hal-blocking-echo/src/serial_setup.rs @@ -0,0 +1,46 @@ +use core::fmt; +use embedded_hal::blocking::serial as bserial; +use embedded_hal::serial; +use microbit::hal::uarte::{Error, Instance, Uarte, UarteRx, UarteTx}; + +static mut TX_BUF: [u8; 1] = [0; 1]; +static mut RX_BUF: [u8; 1] = [0; 1]; + +pub struct UartePort(UarteTx, UarteRx); + +impl UartePort { + pub fn new(serial: Uarte) -> UartePort { + let (tx, rx) = serial + .split(unsafe { &mut TX_BUF }, unsafe { &mut RX_BUF }) + .unwrap(); + UartePort(tx, rx) + } +} + +impl fmt::Write for UartePort { + fn write_str(&mut self, s: &str) -> fmt::Result { + self.0.write_str(s) + } +} + +impl serial::Write for UartePort { + type Error = Error; + + fn write(&mut self, b: u8) -> nb::Result<(), Self::Error> { + self.0.write(b) + } + + fn flush(&mut self) -> nb::Result<(), Self::Error> { + self.0.flush() + } +} + +impl bserial::write::Default for UartePort {} + +impl serial::Read for UartePort { + type Error = Error; + + fn read(&mut self) -> nb::Result { + self.1.read() + } +} diff --git a/examples/v2-speaker/src/main.rs b/examples/v2-speaker/src/main.rs index 2df2d63..260d591 100644 --- a/examples/v2-speaker/src/main.rs +++ b/examples/v2-speaker/src/main.rs @@ -48,7 +48,7 @@ fn main() -> ! { let speaker = pwm::Pwm::new(board.PWM0); speaker // output the waveform on the speaker pin - .set_output_pin(pwm::Channel::C0, &speaker_pin.degrade()) + .set_output_pin(pwm::Channel::C0, speaker_pin.degrade()) // Use prescale by 16 to achive darker sounds .set_prescaler(pwm::Prescaler::Div16) // Initial frequency diff --git a/microbit-common/Cargo.toml b/microbit-common/Cargo.toml index 315274b..94c436e 100644 --- a/microbit-common/Cargo.toml +++ b/microbit-common/Cargo.toml @@ -30,11 +30,12 @@ embedded-hal = "0.2.4" [dependencies.nrf51-hal] optional = true -version = "0.12.1" +version = "0.13.0" [dependencies.nrf52833-hal] optional = true -version = "0.12.1" +version = "0.13.0" +git = "https://github.com/nrf-rs/nrf-hal" [features] doc = [] diff --git a/microbit-common/src/display/blocking.rs b/microbit-common/src/display/blocking.rs index 4de4def..ba155d3 100644 --- a/microbit-common/src/display/blocking.rs +++ b/microbit-common/src/display/blocking.rs @@ -72,12 +72,11 @@ impl Display { /// to create [`DisplayPins`]. pub fn new(pins: DisplayPins) -> Self { let (cols, rows) = pins.degrade(); - let mut retval = Display { + Display { delay_ms: DEFAULT_DELAY_MS, rows, cols, - }; - retval + } } /// Clear the display diff --git a/microbit-common/src/v1/board.rs b/microbit-common/src/v1/board.rs index edf19c0..22cb11b 100644 --- a/microbit-common/src/v1/board.rs +++ b/microbit-common/src/v1/board.rs @@ -1,8 +1,8 @@ -use super::gpio::{DisplayPins, BTN_A, BTN_B, SCL, SDA}; +use super::gpio::{DisplayPins, BTN_A, BTN_B, SCL, SDA, UART_RX, UART_TX}; use crate::{ hal::{ gpio::{p0, Disconnected, Level}, - twi, + twi, uart, }, pac, }; @@ -22,6 +22,9 @@ pub struct Board { /// I2C shared internal and external bus pins pub i2c: I2CPins, + /// UART to debugger pins + pub uart: UartPins, + /// Core peripheral: Cache and branch predictor maintenance operations pub CBP: pac::CBP, @@ -84,6 +87,9 @@ pub struct Board { /// nRF51 peripheral: TWI0 pub TWI0: pac::TWI0, + + /// nrf51 peripheral: UART0 + pub UART0: pac::UART0, } impl Board { @@ -112,8 +118,6 @@ impl Board { p0_21: p0parts.p0_21, p0_22: p0parts.p0_22, p0_23: p0parts.p0_23, - p0_24: p0parts.p0_24, - p0_25: p0parts.p0_25, p0_27: p0parts.p0_27, p0_28: p0parts.p0_28, p0_29: p0parts.p0_29, @@ -140,6 +144,10 @@ impl Board { scl: p0parts.p0_00.into_floating_input(), sda: p0parts.p0_30.into_floating_input(), }, + uart: UartPins { + tx: p0parts.p0_24.into_push_pull_output(Level::Low), + rx: p0parts.p0_25.into_floating_input(), + }, // Core peripherals CBP: cp.CBP, @@ -165,6 +173,7 @@ impl Board { TIMER1: p.TIMER1, TIMER2: p.TIMER2, TWI0: p.TWI0, + UART0: p.UART0, } } } @@ -196,8 +205,8 @@ pub struct Pins { pub p0_21: p0::P0_21, pub p0_22: p0::P0_22, pub p0_23: p0::P0_23, - pub p0_24: p0::P0_24, - pub p0_25: p0::P0_25, + // pub p0_24: p0::P0_24, // UART TX + // pub p0_25: p0::P0_25, // UART RX // pub p0_26: p0::P0_26, // BTN_B pub p0_27: p0::P0_27, pub p0_28: p0::P0_28, @@ -227,3 +236,20 @@ impl Into for I2CPins { } } } + +/// UART to debugger pins +pub struct UartPins { + tx: UART_TX, + rx: UART_RX, +} + +impl Into for UartPins { + fn into(self) -> uart::Pins { + uart::Pins { + txd: self.tx.degrade(), + rxd: self.rx.degrade(), + cts: None, + rts: None, + } + } +} diff --git a/microbit-common/src/v2/board.rs b/microbit-common/src/v2/board.rs index 2fd80dc..cb2faa6 100644 --- a/microbit-common/src/v2/board.rs +++ b/microbit-common/src/v2/board.rs @@ -1,8 +1,8 @@ -use super::gpio::{DisplayPins, BTN_A, BTN_B, INT_SCL, INT_SDA, SCL, SDA}; +use super::gpio::{DisplayPins, BTN_A, BTN_B, INT_SCL, INT_SDA, SCL, SDA, UART_RX, UART_TX}; use crate::{ hal::{ gpio::{p0, p1, Disconnected, Level}, - twim, twis, + twim, twis, uarte, }, pac, }; @@ -28,6 +28,9 @@ pub struct Board { /// I2C external bus pins pub i2c_external: I2CExternalPins, + /// UART to debugger pins + pub uart: UartPins, + /// Core peripheral: Cache and branch predictor maintenance operations pub CBP: pac::CBP, @@ -114,6 +117,12 @@ pub struct Board { /// nRF52 peripheral: TWIS0 pub TWIS0: pac::TWIS0, + + /// nRF52 peripheral: UARTE0 + pub UARTE0: pac::UARTE0, + + /// nRF52 peripheral: UARTE1 + pub UARTE1: pac::UARTE1, } impl Board { @@ -138,7 +147,6 @@ impl Board { p0_03: p0parts.p0_03, p0_04: p0parts.p0_04, p0_05: p0parts.p0_05, - p0_06: p0parts.p0_06, p0_07: p0parts.p0_07, p0_09: p0parts.p0_09, p0_10: p0parts.p0_10, @@ -156,7 +164,6 @@ impl Board { p1_04: p1parts.p1_04, p1_06: p1parts.p1_06, p1_07: p1parts.p1_07, - p1_08: p1parts.p1_08, p1_09: p1parts.p1_09, }, display_pins: DisplayPins { @@ -184,6 +191,10 @@ impl Board { scl: p0parts.p0_26.into_floating_input(), sda: p1parts.p1_00.into_floating_input(), }, + uart: UartPins { + tx: p0parts.p0_06.into_push_pull_output(Level::High), + rx: p1parts.p1_08.into_floating_input(), + }, // Core peripherals CBP: cp.CBP, @@ -217,6 +228,8 @@ impl Board { TIMER4: p.TIMER4, TWIM0: p.TWIM0, TWIS0: p.TWIS0, + UARTE0: p.UARTE0, + UARTE1: p.UARTE1, } } } @@ -230,7 +243,7 @@ pub struct Pins { pub p0_03: p0::P0_03, pub p0_04: p0::P0_04, pub p0_05: p0::P0_05, - pub p0_06: p0::P0_06, + // pub p0_06: p0::P0_06, // UART RX pub p0_07: p0::P0_07, // pub p0_08: p0::P0_08, // INT_SCL pub p0_09: p0::P0_09, @@ -264,7 +277,7 @@ pub struct Pins { // pub p1_05: p1::P1_05, // LEDs pub p1_06: p1::P1_06, pub p1_07: p1::P1_07, - pub p1_08: p1::P1_08, + // pub p1_08: p1::P1_08, // UART TX pub p1_09: p1::P1_09, } @@ -323,3 +336,20 @@ impl Into for I2CExternalPins { } } } + +/// UART to debugger pins +pub struct UartPins { + tx: UART_TX, + rx: UART_RX, +} + +impl Into for UartPins { + fn into(self) -> uarte::Pins { + uarte::Pins { + txd: self.tx.degrade(), + rxd: self.rx.degrade(), + cts: None, + rts: None, + } + } +} diff --git a/microbit-common/src/v2/gpio.rs b/microbit-common/src/v2/gpio.rs index 19920a6..20ae2b2 100644 --- a/microbit-common/src/v2/gpio.rs +++ b/microbit-common/src/v2/gpio.rs @@ -114,8 +114,8 @@ pub type SCL = p0::P0_26>; pub type SDA = p1::P1_00>; /* uart */ -pub type UART_TX = p1::P1_08>; -pub type UART_RX = p0::P0_06>; +pub type UART_TX = p0::P0_06>; +pub type UART_RX = p1::P1_08>; /* speaker */ pub type SPEAKER = p0::P0_00>; diff --git a/microbit/src/lib.rs b/microbit/src/lib.rs index d003173..1732923 100644 --- a/microbit/src/lib.rs +++ b/microbit/src/lib.rs @@ -14,22 +14,3 @@ #![allow(non_camel_case_types)] pub use microbit_common::*; - -/// Create a [Uart](hal::uart::Uart) client with the default pins -#[macro_export] -macro_rules! serial_port { - ( $gpio:expr, $uart:expr, $speed:expr ) => {{ - use microbit::hal::{gpio::Level, uart}; - - /* Configure RX and TX pins accordingly */ - let pins = uart::Pins { - rxd: $gpio.p0_25.into_floating_input().degrade(), - txd: $gpio.p0_24.into_push_pull_output(Level::Low).degrade(), - cts: None, - rts: None, - }; - - /* Set up serial port using the prepared pins */ - uart::Uart::new($uart, pins, uart::Parity::EXCLUDED, $speed) - }}; -}