mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-25 16:23:10 +00:00
Merge pull request #3121 from embassy-rs/nrftests
nRF uart fixes, better tests.
This commit is contained in:
commit
a2acb3e3dc
@ -27,7 +27,7 @@ use crate::ppi::{
|
|||||||
};
|
};
|
||||||
use crate::timer::{Instance as TimerInstance, Timer};
|
use crate::timer::{Instance as TimerInstance, Timer};
|
||||||
use crate::uarte::{configure, drop_tx_rx, Config, Instance as UarteInstance};
|
use crate::uarte::{configure, drop_tx_rx, Config, Instance as UarteInstance};
|
||||||
use crate::{interrupt, pac, Peripheral};
|
use crate::{interrupt, pac, Peripheral, EASY_DMA_SIZE};
|
||||||
|
|
||||||
pub(crate) struct State {
|
pub(crate) struct State {
|
||||||
tx_buf: RingBuffer,
|
tx_buf: RingBuffer,
|
||||||
@ -186,6 +186,7 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt
|
|||||||
// If not TXing, start.
|
// If not TXing, start.
|
||||||
if s.tx_count.load(Ordering::Relaxed) == 0 {
|
if s.tx_count.load(Ordering::Relaxed) == 0 {
|
||||||
let (ptr, len) = tx.pop_buf();
|
let (ptr, len) = tx.pop_buf();
|
||||||
|
let len = len.min(EASY_DMA_SIZE);
|
||||||
if len != 0 {
|
if len != 0 {
|
||||||
//trace!(" irq_tx: starting {:?}", len);
|
//trace!(" irq_tx: starting {:?}", len);
|
||||||
s.tx_count.store(len, Ordering::Relaxed);
|
s.tx_count.store(len, Ordering::Relaxed);
|
||||||
@ -304,6 +305,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
|
|||||||
let tx = BufferedUarteTx::new_innerer(unsafe { peri.clone_unchecked() }, txd, cts, tx_buffer);
|
let tx = BufferedUarteTx::new_innerer(unsafe { peri.clone_unchecked() }, txd, cts, tx_buffer);
|
||||||
let rx = BufferedUarteRx::new_innerer(peri, timer, ppi_ch1, ppi_ch2, ppi_group, rxd, rts, rx_buffer);
|
let rx = BufferedUarteRx::new_innerer(peri, timer, ppi_ch1, ppi_ch2, ppi_group, rxd, rts, rx_buffer);
|
||||||
|
|
||||||
|
U::regs().enable.write(|w| w.enable().enabled());
|
||||||
U::Interrupt::pend();
|
U::Interrupt::pend();
|
||||||
unsafe { U::Interrupt::enable() };
|
unsafe { U::Interrupt::enable() };
|
||||||
|
|
||||||
@ -405,6 +407,7 @@ impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> {
|
|||||||
|
|
||||||
let this = Self::new_innerer(peri, txd, cts, tx_buffer);
|
let this = Self::new_innerer(peri, txd, cts, tx_buffer);
|
||||||
|
|
||||||
|
U::regs().enable.write(|w| w.enable().enabled());
|
||||||
U::Interrupt::pend();
|
U::Interrupt::pend();
|
||||||
unsafe { U::Interrupt::enable() };
|
unsafe { U::Interrupt::enable() };
|
||||||
|
|
||||||
@ -602,6 +605,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> {
|
|||||||
|
|
||||||
let this = Self::new_innerer(peri, timer, ppi_ch1, ppi_ch2, ppi_group, rxd, rts, rx_buffer);
|
let this = Self::new_innerer(peri, timer, ppi_ch1, ppi_ch2, ppi_group, rxd, rts, rx_buffer);
|
||||||
|
|
||||||
|
U::regs().enable.write(|w| w.enable().enabled());
|
||||||
U::Interrupt::pend();
|
U::Interrupt::pend();
|
||||||
unsafe { U::Interrupt::enable() };
|
unsafe { U::Interrupt::enable() };
|
||||||
|
|
||||||
@ -638,8 +642,8 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> {
|
|||||||
s.rx_started_count.store(0, Ordering::Relaxed);
|
s.rx_started_count.store(0, Ordering::Relaxed);
|
||||||
s.rx_ended_count.store(0, Ordering::Relaxed);
|
s.rx_ended_count.store(0, Ordering::Relaxed);
|
||||||
s.rx_started.store(false, Ordering::Relaxed);
|
s.rx_started.store(false, Ordering::Relaxed);
|
||||||
let len = rx_buffer.len();
|
let rx_len = rx_buffer.len().min(EASY_DMA_SIZE * 2);
|
||||||
unsafe { s.rx_buf.init(rx_buffer.as_mut_ptr(), len) };
|
unsafe { s.rx_buf.init(rx_buffer.as_mut_ptr(), rx_len) };
|
||||||
|
|
||||||
// clear errors
|
// clear errors
|
||||||
let errors = r.errorsrc.read().bits();
|
let errors = r.errorsrc.read().bits();
|
||||||
@ -660,7 +664,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> {
|
|||||||
|
|
||||||
// Configure byte counter.
|
// Configure byte counter.
|
||||||
let timer = Timer::new_counter(timer);
|
let timer = Timer::new_counter(timer);
|
||||||
timer.cc(1).write(rx_buffer.len() as u32 * 2);
|
timer.cc(1).write(rx_len as u32 * 2);
|
||||||
timer.cc(1).short_compare_clear();
|
timer.cc(1).short_compare_clear();
|
||||||
timer.clear();
|
timer.clear();
|
||||||
timer.start();
|
timer.start();
|
||||||
|
@ -221,6 +221,7 @@ impl<'d, T: Instance> Uarte<'d, T> {
|
|||||||
|
|
||||||
T::Interrupt::unpend();
|
T::Interrupt::unpend();
|
||||||
unsafe { T::Interrupt::enable() };
|
unsafe { T::Interrupt::enable() };
|
||||||
|
r.enable.write(|w| w.enable().enabled());
|
||||||
|
|
||||||
let s = T::state();
|
let s = T::state();
|
||||||
s.tx_rx_refcount.store(2, Ordering::Relaxed);
|
s.tx_rx_refcount.store(2, Ordering::Relaxed);
|
||||||
@ -319,9 +320,7 @@ pub(crate) fn configure(r: &RegisterBlock, config: Config, hardware_flow_control
|
|||||||
r.psel.cts.write(|w| w.connect().disconnected());
|
r.psel.cts.write(|w| w.connect().disconnected());
|
||||||
r.psel.rts.write(|w| w.connect().disconnected());
|
r.psel.rts.write(|w| w.connect().disconnected());
|
||||||
|
|
||||||
// Enable
|
|
||||||
apply_workaround_for_enable_anomaly(r);
|
apply_workaround_for_enable_anomaly(r);
|
||||||
r.enable.write(|w| w.enable().enabled());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> UarteTx<'d, T> {
|
impl<'d, T: Instance> UarteTx<'d, T> {
|
||||||
@ -369,6 +368,7 @@ impl<'d, T: Instance> UarteTx<'d, T> {
|
|||||||
|
|
||||||
T::Interrupt::unpend();
|
T::Interrupt::unpend();
|
||||||
unsafe { T::Interrupt::enable() };
|
unsafe { T::Interrupt::enable() };
|
||||||
|
r.enable.write(|w| w.enable().enabled());
|
||||||
|
|
||||||
let s = T::state();
|
let s = T::state();
|
||||||
s.tx_rx_refcount.store(1, Ordering::Relaxed);
|
s.tx_rx_refcount.store(1, Ordering::Relaxed);
|
||||||
@ -567,6 +567,7 @@ impl<'d, T: Instance> UarteRx<'d, T> {
|
|||||||
|
|
||||||
T::Interrupt::unpend();
|
T::Interrupt::unpend();
|
||||||
unsafe { T::Interrupt::enable() };
|
unsafe { T::Interrupt::enable() };
|
||||||
|
r.enable.write(|w| w.enable().enabled());
|
||||||
|
|
||||||
let s = T::state();
|
let s = T::state();
|
||||||
s.tx_rx_refcount.store(1, Ordering::Relaxed);
|
s.tx_rx_refcount.store(1, Ordering::Relaxed);
|
||||||
|
@ -32,12 +32,13 @@ portable-atomic = { version = "1.6.0" }
|
|||||||
[features]
|
[features]
|
||||||
nrf51422 = ["embassy-nrf/nrf51", "portable-atomic/unsafe-assume-single-core"]
|
nrf51422 = ["embassy-nrf/nrf51", "portable-atomic/unsafe-assume-single-core"]
|
||||||
nrf52832 = ["embassy-nrf/nrf52832", "easydma"]
|
nrf52832 = ["embassy-nrf/nrf52832", "easydma"]
|
||||||
nrf52833 = ["embassy-nrf/nrf52833", "easydma"]
|
nrf52833 = ["embassy-nrf/nrf52833", "easydma", "two-uarts"]
|
||||||
nrf52840 = ["embassy-nrf/nrf52840", "easydma"]
|
nrf52840 = ["embassy-nrf/nrf52840", "easydma", "two-uarts"]
|
||||||
nrf5340 = ["embassy-nrf/nrf5340-app-s", "easydma"]
|
nrf5340 = ["embassy-nrf/nrf5340-app-s", "easydma", "two-uarts"]
|
||||||
nrf9160 = ["embassy-nrf/nrf9160-s", "easydma"]
|
nrf9160 = ["embassy-nrf/nrf9160-s", "easydma", "two-uarts"]
|
||||||
|
|
||||||
easydma = []
|
easydma = []
|
||||||
|
two-uarts = []
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
@ -53,22 +54,22 @@ overflow-checks = false
|
|||||||
[[bin]]
|
[[bin]]
|
||||||
name = "buffered_uart"
|
name = "buffered_uart"
|
||||||
path = "src/bin/buffered_uart.rs"
|
path = "src/bin/buffered_uart.rs"
|
||||||
required-features = [ "nrf52840",]
|
required-features = [ "easydma",]
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "buffered_uart_full"
|
name = "buffered_uart_full"
|
||||||
path = "src/bin/buffered_uart_full.rs"
|
path = "src/bin/buffered_uart_full.rs"
|
||||||
required-features = [ "nrf52840",]
|
required-features = [ "easydma",]
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "buffered_uart_halves"
|
name = "buffered_uart_halves"
|
||||||
path = "src/bin/buffered_uart_halves.rs"
|
path = "src/bin/buffered_uart_halves.rs"
|
||||||
required-features = [ "nrf52840",]
|
required-features = [ "two-uarts",]
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "buffered_uart_spam"
|
name = "buffered_uart_spam"
|
||||||
path = "src/bin/buffered_uart_spam.rs"
|
path = "src/bin/buffered_uart_spam.rs"
|
||||||
required-features = [ "nrf52840",]
|
required-features = [ "two-uarts",]
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "ethernet_enc28j60_perf"
|
name = "ethernet_enc28j60_perf"
|
||||||
@ -90,6 +91,16 @@ name = "timer"
|
|||||||
path = "src/bin/timer.rs"
|
path = "src/bin/timer.rs"
|
||||||
required-features = []
|
required-features = []
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "uart_halves"
|
||||||
|
path = "src/bin/uart_halves.rs"
|
||||||
|
required-features = [ "two-uarts",]
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "uart_split"
|
||||||
|
path = "src/bin/uart_split.rs"
|
||||||
|
required-features = [ "easydma",]
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "wifi_esp_hosted_perf"
|
name = "wifi_esp_hosted_perf"
|
||||||
path = "src/bin/wifi_esp_hosted_perf.rs"
|
path = "src/bin/wifi_esp_hosted_perf.rs"
|
||||||
|
@ -1,19 +1,17 @@
|
|||||||
// required-features: nrf52840
|
// required-features: easydma
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
teleprobe_meta::target!(b"nrf52840-dk");
|
|
||||||
|
|
||||||
use defmt::{assert_eq, *};
|
#[path = "../common.rs"]
|
||||||
|
mod common;
|
||||||
|
|
||||||
|
use defmt::{panic, *};
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_futures::join::join;
|
use embassy_futures::join::join;
|
||||||
use embassy_nrf::buffered_uarte::{self, BufferedUarte};
|
use embassy_nrf::buffered_uarte::{self, BufferedUarte};
|
||||||
use embassy_nrf::{bind_interrupts, peripherals, uarte};
|
use embassy_nrf::{peripherals, uarte};
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
bind_interrupts!(struct Irqs {
|
|
||||||
UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;
|
|
||||||
});
|
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(_spawner: Spawner) {
|
async fn main(_spawner: Spawner) {
|
||||||
let mut p = embassy_nrf::init(Default::default());
|
let mut p = embassy_nrf::init(Default::default());
|
||||||
@ -27,14 +25,14 @@ async fn main(_spawner: Spawner) {
|
|||||||
// test teardown + recreate of the buffereduarte works fine.
|
// test teardown + recreate of the buffereduarte works fine.
|
||||||
for _ in 0..2 {
|
for _ in 0..2 {
|
||||||
let u = BufferedUarte::new(
|
let u = BufferedUarte::new(
|
||||||
&mut p.UARTE0,
|
&mut peri!(p, UART0),
|
||||||
&mut p.TIMER0,
|
&mut p.TIMER0,
|
||||||
&mut p.PPI_CH0,
|
&mut p.PPI_CH0,
|
||||||
&mut p.PPI_CH1,
|
&mut p.PPI_CH1,
|
||||||
&mut p.PPI_GROUP0,
|
&mut p.PPI_GROUP0,
|
||||||
Irqs,
|
irqs!(UART0_BUFFERED),
|
||||||
&mut p.P1_03,
|
&mut peri!(p, PIN_A),
|
||||||
&mut p.P1_02,
|
&mut peri!(p, PIN_B),
|
||||||
config.clone(),
|
config.clone(),
|
||||||
&mut rx_buffer,
|
&mut rx_buffer,
|
||||||
&mut tx_buffer,
|
&mut tx_buffer,
|
||||||
@ -65,7 +63,9 @@ async fn main(_spawner: Spawner) {
|
|||||||
let buf = unwrap!(rx.fill_buf().await);
|
let buf = unwrap!(rx.fill_buf().await);
|
||||||
|
|
||||||
for &b in buf {
|
for &b in buf {
|
||||||
assert_eq!(b, i as u8);
|
if b != i as u8 {
|
||||||
|
panic!("mismatch {} vs {}, index {}", b, i as u8, i);
|
||||||
|
}
|
||||||
i = i + 1;
|
i = i + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,19 +1,17 @@
|
|||||||
// required-features: nrf52840
|
// required-features: easydma
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
teleprobe_meta::target!(b"nrf52840-dk");
|
|
||||||
|
#[path = "../common.rs"]
|
||||||
|
mod common;
|
||||||
|
|
||||||
use defmt::{assert_eq, *};
|
use defmt::{assert_eq, *};
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_nrf::buffered_uarte::{self, BufferedUarte};
|
use embassy_nrf::buffered_uarte::{self, BufferedUarte};
|
||||||
use embassy_nrf::{bind_interrupts, peripherals, uarte};
|
use embassy_nrf::{peripherals, uarte};
|
||||||
use embedded_io_async::{Read, Write};
|
use embedded_io_async::{Read, Write};
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
bind_interrupts!(struct Irqs {
|
|
||||||
UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;
|
|
||||||
});
|
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(_spawner: Spawner) {
|
async fn main(_spawner: Spawner) {
|
||||||
let p = embassy_nrf::init(Default::default());
|
let p = embassy_nrf::init(Default::default());
|
||||||
@ -21,18 +19,18 @@ async fn main(_spawner: Spawner) {
|
|||||||
config.parity = uarte::Parity::EXCLUDED;
|
config.parity = uarte::Parity::EXCLUDED;
|
||||||
config.baudrate = uarte::Baudrate::BAUD1M;
|
config.baudrate = uarte::Baudrate::BAUD1M;
|
||||||
|
|
||||||
let mut tx_buffer = [0u8; 1024];
|
let mut tx_buffer = [0u8; 500];
|
||||||
let mut rx_buffer = [0u8; 1024];
|
let mut rx_buffer = [0u8; 500];
|
||||||
|
|
||||||
let u = BufferedUarte::new(
|
let u = BufferedUarte::new(
|
||||||
p.UARTE0,
|
peri!(p, UART0),
|
||||||
p.TIMER0,
|
p.TIMER0,
|
||||||
p.PPI_CH0,
|
p.PPI_CH0,
|
||||||
p.PPI_CH1,
|
p.PPI_CH1,
|
||||||
p.PPI_GROUP0,
|
p.PPI_GROUP0,
|
||||||
Irqs,
|
irqs!(UART0_BUFFERED),
|
||||||
p.P1_03,
|
peri!(p, PIN_A),
|
||||||
p.P1_02,
|
peri!(p, PIN_B),
|
||||||
config.clone(),
|
config.clone(),
|
||||||
&mut rx_buffer,
|
&mut rx_buffer,
|
||||||
&mut tx_buffer,
|
&mut tx_buffer,
|
||||||
@ -42,22 +40,22 @@ async fn main(_spawner: Spawner) {
|
|||||||
|
|
||||||
let (mut rx, mut tx) = u.split();
|
let (mut rx, mut tx) = u.split();
|
||||||
|
|
||||||
let mut buf = [0; 1024];
|
let mut buf = [0; 500];
|
||||||
for (j, b) in buf.iter_mut().enumerate() {
|
for (j, b) in buf.iter_mut().enumerate() {
|
||||||
*b = j as u8;
|
*b = j as u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write 1024b. This causes the rx buffer to get exactly full.
|
// Write 500b. This causes the rx buffer to get exactly full.
|
||||||
unwrap!(tx.write_all(&buf).await);
|
unwrap!(tx.write_all(&buf).await);
|
||||||
unwrap!(tx.flush().await);
|
unwrap!(tx.flush().await);
|
||||||
|
|
||||||
// Read those 1024b.
|
// Read those 500b.
|
||||||
unwrap!(rx.read_exact(&mut buf).await);
|
unwrap!(rx.read_exact(&mut buf).await);
|
||||||
for (j, b) in buf.iter().enumerate() {
|
for (j, b) in buf.iter().enumerate() {
|
||||||
assert_eq!(*b, j as u8);
|
assert_eq!(*b, j as u8);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The buffer should now be unclogged. Write 1024b again.
|
// The buffer should now be unclogged. Write 500b again.
|
||||||
unwrap!(tx.write_all(&buf).await);
|
unwrap!(tx.write_all(&buf).await);
|
||||||
unwrap!(tx.flush().await);
|
unwrap!(tx.flush().await);
|
||||||
|
|
||||||
|
@ -1,20 +1,17 @@
|
|||||||
// required-features: nrf52840
|
// required-features: two-uarts
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
teleprobe_meta::target!(b"nrf52840-dk");
|
|
||||||
|
#[path = "../common.rs"]
|
||||||
|
mod common;
|
||||||
|
|
||||||
use defmt::{assert_eq, *};
|
use defmt::{assert_eq, *};
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_futures::join::join;
|
use embassy_futures::join::join;
|
||||||
use embassy_nrf::buffered_uarte::{self, BufferedUarteRx, BufferedUarteTx};
|
use embassy_nrf::buffered_uarte::{self, BufferedUarteRx, BufferedUarteTx};
|
||||||
use embassy_nrf::{bind_interrupts, peripherals, uarte};
|
use embassy_nrf::{peripherals, uarte};
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
bind_interrupts!(struct Irqs {
|
|
||||||
UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;
|
|
||||||
UARTE1 => buffered_uarte::InterruptHandler<peripherals::UARTE1>;
|
|
||||||
});
|
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(_spawner: Spawner) {
|
async fn main(_spawner: Spawner) {
|
||||||
let mut p = embassy_nrf::init(Default::default());
|
let mut p = embassy_nrf::init(Default::default());
|
||||||
@ -29,16 +26,22 @@ async fn main(_spawner: Spawner) {
|
|||||||
for _ in 0..2 {
|
for _ in 0..2 {
|
||||||
const COUNT: usize = 40_000;
|
const COUNT: usize = 40_000;
|
||||||
|
|
||||||
let mut tx = BufferedUarteTx::new(&mut p.UARTE1, Irqs, &mut p.P1_02, config.clone(), &mut tx_buffer);
|
let mut tx = BufferedUarteTx::new(
|
||||||
|
&mut peri!(p, UART1),
|
||||||
|
irqs!(UART1_BUFFERED),
|
||||||
|
&mut peri!(p, PIN_A),
|
||||||
|
config.clone(),
|
||||||
|
&mut tx_buffer,
|
||||||
|
);
|
||||||
|
|
||||||
let mut rx = BufferedUarteRx::new(
|
let mut rx = BufferedUarteRx::new(
|
||||||
&mut p.UARTE0,
|
&mut peri!(p, UART0),
|
||||||
&mut p.TIMER0,
|
&mut p.TIMER0,
|
||||||
&mut p.PPI_CH0,
|
&mut p.PPI_CH0,
|
||||||
&mut p.PPI_CH1,
|
&mut p.PPI_CH1,
|
||||||
&mut p.PPI_GROUP0,
|
&mut p.PPI_GROUP0,
|
||||||
Irqs,
|
irqs!(UART0_BUFFERED),
|
||||||
&mut p.P1_03,
|
&mut peri!(p, PIN_B),
|
||||||
config.clone(),
|
config.clone(),
|
||||||
&mut rx_buffer,
|
&mut rx_buffer,
|
||||||
);
|
);
|
||||||
|
@ -1,26 +1,23 @@
|
|||||||
// required-features: nrf52840
|
// required-features: two-uarts
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
teleprobe_meta::target!(b"nrf52840-dk");
|
|
||||||
|
#[path = "../common.rs"]
|
||||||
|
mod common;
|
||||||
|
|
||||||
use core::mem;
|
use core::mem;
|
||||||
use core::ptr::NonNull;
|
use core::ptr::NonNull;
|
||||||
|
|
||||||
use defmt::{assert_eq, *};
|
use defmt::{assert_eq, *};
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_nrf::buffered_uarte::{self, BufferedUarte};
|
use embassy_nrf::buffered_uarte::{self, BufferedUarteRx};
|
||||||
use embassy_nrf::gpio::{Level, Output, OutputDrive};
|
use embassy_nrf::gpio::{Level, Output, OutputDrive};
|
||||||
use embassy_nrf::ppi::{Event, Ppi, Task};
|
use embassy_nrf::ppi::{Event, Ppi, Task};
|
||||||
use embassy_nrf::uarte::Uarte;
|
use embassy_nrf::uarte::UarteTx;
|
||||||
use embassy_nrf::{bind_interrupts, pac, peripherals, uarte};
|
use embassy_nrf::{pac, peripherals, uarte};
|
||||||
use embassy_time::Timer;
|
use embassy_time::Timer;
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
bind_interrupts!(struct Irqs {
|
|
||||||
UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;
|
|
||||||
UARTE1 => uarte::InterruptHandler<peripherals::UARTE1>;
|
|
||||||
});
|
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(_spawner: Spawner) {
|
async fn main(_spawner: Spawner) {
|
||||||
let mut p = embassy_nrf::init(Default::default());
|
let mut p = embassy_nrf::init(Default::default());
|
||||||
@ -28,23 +25,20 @@ async fn main(_spawner: Spawner) {
|
|||||||
config.parity = uarte::Parity::EXCLUDED;
|
config.parity = uarte::Parity::EXCLUDED;
|
||||||
config.baudrate = uarte::Baudrate::BAUD1M;
|
config.baudrate = uarte::Baudrate::BAUD1M;
|
||||||
|
|
||||||
let mut tx_buffer = [0u8; 1024];
|
|
||||||
let mut rx_buffer = [0u8; 1024];
|
let mut rx_buffer = [0u8; 1024];
|
||||||
|
|
||||||
mem::forget(Output::new(&mut p.P1_02, Level::High, OutputDrive::Standard));
|
mem::forget(Output::new(&mut peri!(p, PIN_A), Level::High, OutputDrive::Standard));
|
||||||
|
|
||||||
let mut u = BufferedUarte::new(
|
let mut u = BufferedUarteRx::new(
|
||||||
p.UARTE0,
|
peri!(p, UART0),
|
||||||
p.TIMER0,
|
p.TIMER0,
|
||||||
p.PPI_CH0,
|
p.PPI_CH0,
|
||||||
p.PPI_CH1,
|
p.PPI_CH1,
|
||||||
p.PPI_GROUP0,
|
p.PPI_GROUP0,
|
||||||
Irqs,
|
irqs!(UART0_BUFFERED),
|
||||||
p.P1_03,
|
peri!(p, PIN_B),
|
||||||
p.P1_04,
|
|
||||||
config.clone(),
|
config.clone(),
|
||||||
&mut rx_buffer,
|
&mut rx_buffer,
|
||||||
&mut tx_buffer,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
info!("uarte initialized!");
|
info!("uarte initialized!");
|
||||||
@ -55,7 +49,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
// Tx spam in a loop.
|
// Tx spam in a loop.
|
||||||
const NSPAM: usize = 17;
|
const NSPAM: usize = 17;
|
||||||
static mut TX_BUF: [u8; NSPAM] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
|
static mut TX_BUF: [u8; NSPAM] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
|
||||||
let _spam = Uarte::new(p.UARTE1, Irqs, p.P1_01, p.P1_02, config.clone());
|
let _spam = UarteTx::new(peri!(p, UART1), irqs!(UART1), peri!(p, PIN_A), config.clone());
|
||||||
let spam_peri: pac::UARTE1 = unsafe { mem::transmute(()) };
|
let spam_peri: pac::UARTE1 = unsafe { mem::transmute(()) };
|
||||||
let event = unsafe { Event::new_unchecked(NonNull::new_unchecked(&spam_peri.events_endtx as *const _ as _)) };
|
let event = unsafe { Event::new_unchecked(NonNull::new_unchecked(&spam_peri.events_endtx as *const _ as _)) };
|
||||||
let task = unsafe { Task::new_unchecked(NonNull::new_unchecked(&spam_peri.tasks_starttx as *const _ as _)) };
|
let task = unsafe { Task::new_unchecked(NonNull::new_unchecked(&spam_peri.tasks_starttx as *const _ as _)) };
|
||||||
|
41
tests/nrf/src/bin/uart_halves.rs
Normal file
41
tests/nrf/src/bin/uart_halves.rs
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// required-features: two-uarts
|
||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
#[path = "../common.rs"]
|
||||||
|
mod common;
|
||||||
|
|
||||||
|
use defmt::{assert_eq, *};
|
||||||
|
use embassy_executor::Spawner;
|
||||||
|
use embassy_futures::join::join;
|
||||||
|
use embassy_nrf::uarte::{UarteRx, UarteTx};
|
||||||
|
use embassy_nrf::{peripherals, uarte};
|
||||||
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
|
#[embassy_executor::main]
|
||||||
|
async fn main(_spawner: Spawner) {
|
||||||
|
let mut p = embassy_nrf::init(Default::default());
|
||||||
|
let mut config = uarte::Config::default();
|
||||||
|
config.parity = uarte::Parity::EXCLUDED;
|
||||||
|
config.baudrate = uarte::Baudrate::BAUD1M;
|
||||||
|
|
||||||
|
let mut tx = UarteTx::new(&mut peri!(p, UART0), irqs!(UART0), &mut peri!(p, PIN_A), config.clone());
|
||||||
|
let mut rx = UarteRx::new(&mut peri!(p, UART1), irqs!(UART1), &mut peri!(p, PIN_B), config.clone());
|
||||||
|
|
||||||
|
let data = [
|
||||||
|
0x42, 0x43, 0x44, 0x45, 0x66, 0x12, 0x23, 0x34, 0x45, 0x19, 0x91, 0xaa, 0xff, 0xa5, 0x5a, 0x77,
|
||||||
|
];
|
||||||
|
|
||||||
|
let tx_fut = async {
|
||||||
|
tx.write(&data).await.unwrap();
|
||||||
|
};
|
||||||
|
let rx_fut = async {
|
||||||
|
let mut buf = [0u8; 16];
|
||||||
|
rx.read(&mut buf).await.unwrap();
|
||||||
|
assert_eq!(data, buf);
|
||||||
|
};
|
||||||
|
join(rx_fut, tx_fut).await;
|
||||||
|
|
||||||
|
info!("Test OK");
|
||||||
|
cortex_m::asm::bkpt();
|
||||||
|
}
|
49
tests/nrf/src/bin/uart_split.rs
Normal file
49
tests/nrf/src/bin/uart_split.rs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// required-features: easydma
|
||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
#[path = "../common.rs"]
|
||||||
|
mod common;
|
||||||
|
|
||||||
|
use defmt::{assert_eq, *};
|
||||||
|
use embassy_executor::Spawner;
|
||||||
|
use embassy_futures::join::join;
|
||||||
|
use embassy_nrf::uarte::Uarte;
|
||||||
|
use embassy_nrf::{peripherals, uarte};
|
||||||
|
use embassy_time::Timer;
|
||||||
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
|
#[embassy_executor::main]
|
||||||
|
async fn main(_spawner: Spawner) {
|
||||||
|
let mut p = embassy_nrf::init(Default::default());
|
||||||
|
let mut config = uarte::Config::default();
|
||||||
|
config.parity = uarte::Parity::EXCLUDED;
|
||||||
|
config.baudrate = uarte::Baudrate::BAUD9600;
|
||||||
|
|
||||||
|
let uarte = Uarte::new(
|
||||||
|
&mut peri!(p, UART0),
|
||||||
|
irqs!(UART0),
|
||||||
|
&mut peri!(p, PIN_A),
|
||||||
|
&mut peri!(p, PIN_B),
|
||||||
|
config.clone(),
|
||||||
|
);
|
||||||
|
let (mut tx, mut rx) = uarte.split();
|
||||||
|
|
||||||
|
let data = [
|
||||||
|
0x42, 0x43, 0x44, 0x45, 0x66, 0x12, 0x23, 0x34, 0x45, 0x19, 0x91, 0xaa, 0xff, 0xa5, 0x5a, 0x77,
|
||||||
|
];
|
||||||
|
|
||||||
|
let tx_fut = async {
|
||||||
|
Timer::after_millis(10).await;
|
||||||
|
tx.write(&data).await.unwrap();
|
||||||
|
};
|
||||||
|
let rx_fut = async {
|
||||||
|
let mut buf = [0u8; 16];
|
||||||
|
rx.read(&mut buf).await.unwrap();
|
||||||
|
assert_eq!(data, buf);
|
||||||
|
};
|
||||||
|
join(rx_fut, tx_fut).await;
|
||||||
|
|
||||||
|
info!("Test OK");
|
||||||
|
cortex_m::asm::bkpt();
|
||||||
|
}
|
@ -50,16 +50,53 @@ macro_rules! define_peris {
|
|||||||
define_peris!(PIN_A = P0_13, PIN_B = P0_14,);
|
define_peris!(PIN_A = P0_13, PIN_B = P0_14,);
|
||||||
|
|
||||||
#[cfg(feature = "nrf52832")]
|
#[cfg(feature = "nrf52832")]
|
||||||
define_peris!(PIN_A = P0_11, PIN_B = P0_12,);
|
define_peris!(
|
||||||
|
PIN_A = P0_11, PIN_B = P0_12,
|
||||||
|
UART0 = UARTE0,
|
||||||
|
@irq UART0 = {UARTE0_UART0 => uarte::InterruptHandler<peripherals::UARTE0>;},
|
||||||
|
@irq UART0_BUFFERED = {UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;},
|
||||||
|
);
|
||||||
|
|
||||||
#[cfg(feature = "nrf52833")]
|
#[cfg(feature = "nrf52833")]
|
||||||
define_peris!(PIN_A = P1_01, PIN_B = P1_02,);
|
define_peris!(
|
||||||
|
PIN_A = P1_01, PIN_B = P1_02,
|
||||||
|
UART0 = UARTE0,
|
||||||
|
UART1 = UARTE1,
|
||||||
|
@irq UART0 = {UARTE0_UART0 => uarte::InterruptHandler<peripherals::UARTE0>;},
|
||||||
|
@irq UART1 = {UARTE1 => uarte::InterruptHandler<peripherals::UARTE1>;},
|
||||||
|
@irq UART0_BUFFERED = {UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;},
|
||||||
|
@irq UART1_BUFFERED = {UARTE1 => buffered_uarte::InterruptHandler<peripherals::UARTE1>;},
|
||||||
|
);
|
||||||
|
|
||||||
#[cfg(feature = "nrf52840")]
|
#[cfg(feature = "nrf52840")]
|
||||||
define_peris!(PIN_A = P1_02, PIN_B = P1_03,);
|
define_peris!(
|
||||||
|
PIN_A = P1_02, PIN_B = P1_03,
|
||||||
|
UART0 = UARTE0,
|
||||||
|
UART1 = UARTE1,
|
||||||
|
@irq UART0 = {UARTE0_UART0 => uarte::InterruptHandler<peripherals::UARTE0>;},
|
||||||
|
@irq UART1 = {UARTE1 => uarte::InterruptHandler<peripherals::UARTE1>;},
|
||||||
|
@irq UART0_BUFFERED = {UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;},
|
||||||
|
@irq UART1_BUFFERED = {UARTE1 => buffered_uarte::InterruptHandler<peripherals::UARTE1>;},
|
||||||
|
);
|
||||||
|
|
||||||
#[cfg(feature = "nrf5340")]
|
#[cfg(feature = "nrf5340")]
|
||||||
define_peris!(PIN_A = P1_00, PIN_B = P1_01,);
|
define_peris!(
|
||||||
|
PIN_A = P1_08, PIN_B = P1_09,
|
||||||
|
UART0 = SERIAL0,
|
||||||
|
UART1 = SERIAL1,
|
||||||
|
@irq UART0 = {SERIAL0 => uarte::InterruptHandler<peripherals::SERIAL0>;},
|
||||||
|
@irq UART1 = {SERIAL1 => uarte::InterruptHandler<peripherals::SERIAL1>;},
|
||||||
|
@irq UART0_BUFFERED = {SERIAL0 => buffered_uarte::InterruptHandler<peripherals::SERIAL0>;},
|
||||||
|
@irq UART1_BUFFERED = {SERIAL1 => buffered_uarte::InterruptHandler<peripherals::SERIAL1>;},
|
||||||
|
);
|
||||||
|
|
||||||
#[cfg(feature = "nrf9160")]
|
#[cfg(feature = "nrf9160")]
|
||||||
define_peris!(PIN_A = P0_00, PIN_B = P0_01,);
|
define_peris!(
|
||||||
|
PIN_A = P0_00, PIN_B = P0_01,
|
||||||
|
UART0 = SERIAL0,
|
||||||
|
UART1 = SERIAL1,
|
||||||
|
@irq UART0 = {UARTE0_SPIM0_SPIS0_TWIM0_TWIS0 => uarte::InterruptHandler<peripherals::SERIAL0>;},
|
||||||
|
@irq UART1 = {UARTE1_SPIM1_SPIS1_TWIM1_TWIS1 => uarte::InterruptHandler<peripherals::SERIAL1>;},
|
||||||
|
@irq UART0_BUFFERED = {UARTE0_SPIM0_SPIS0_TWIM0_TWIS0 => buffered_uarte::InterruptHandler<peripherals::SERIAL0>;},
|
||||||
|
@irq UART1_BUFFERED = {UARTE1_SPIM1_SPIS1_TWIM1_TWIS1 => buffered_uarte::InterruptHandler<peripherals::SERIAL1>;},
|
||||||
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user