diff options
| -rw-r--r-- | embassy-nrf/src/buffered_uarte.rs | 12 | ||||
| -rw-r--r-- | embassy-nrf/src/uarte.rs | 5 | ||||
| -rw-r--r-- | tests/nrf/Cargo.toml | 29 | ||||
| -rw-r--r-- | tests/nrf/src/bin/buffered_uart.rs | 26 | ||||
| -rw-r--r-- | tests/nrf/src/bin/buffered_uart_full.rs | 32 | ||||
| -rw-r--r-- | tests/nrf/src/bin/buffered_uart_halves.rs | 27 | ||||
| -rw-r--r-- | tests/nrf/src/bin/buffered_uart_spam.rs | 32 | ||||
| -rw-r--r-- | tests/nrf/src/bin/uart_halves.rs | 41 | ||||
| -rw-r--r-- | tests/nrf/src/bin/uart_split.rs | 49 | ||||
| -rw-r--r-- | tests/nrf/src/common.rs | 47 |
10 files changed, 219 insertions, 81 deletions
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index 385d4015e..8e4064aaa 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs | |||
| @@ -27,7 +27,7 @@ use crate::ppi::{ | |||
| 27 | }; | 27 | }; |
| 28 | use crate::timer::{Instance as TimerInstance, Timer}; | 28 | use crate::timer::{Instance as TimerInstance, Timer}; |
| 29 | use crate::uarte::{configure, drop_tx_rx, Config, Instance as UarteInstance}; | 29 | use crate::uarte::{configure, drop_tx_rx, Config, Instance as UarteInstance}; |
| 30 | use crate::{interrupt, pac, Peripheral}; | 30 | use crate::{interrupt, pac, Peripheral, EASY_DMA_SIZE}; |
| 31 | 31 | ||
| 32 | pub(crate) struct State { | 32 | pub(crate) struct State { |
| 33 | tx_buf: RingBuffer, | 33 | tx_buf: RingBuffer, |
| @@ -186,6 +186,7 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt | |||
| 186 | // If not TXing, start. | 186 | // If not TXing, start. |
| 187 | if s.tx_count.load(Ordering::Relaxed) == 0 { | 187 | if s.tx_count.load(Ordering::Relaxed) == 0 { |
| 188 | let (ptr, len) = tx.pop_buf(); | 188 | let (ptr, len) = tx.pop_buf(); |
| 189 | let len = len.min(EASY_DMA_SIZE); | ||
| 189 | if len != 0 { | 190 | if len != 0 { |
| 190 | //trace!(" irq_tx: starting {:?}", len); | 191 | //trace!(" irq_tx: starting {:?}", len); |
| 191 | s.tx_count.store(len, Ordering::Relaxed); | 192 | s.tx_count.store(len, Ordering::Relaxed); |
| @@ -304,6 +305,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { | |||
| 304 | let tx = BufferedUarteTx::new_innerer(unsafe { peri.clone_unchecked() }, txd, cts, tx_buffer); | 305 | let tx = BufferedUarteTx::new_innerer(unsafe { peri.clone_unchecked() }, txd, cts, tx_buffer); |
| 305 | let rx = BufferedUarteRx::new_innerer(peri, timer, ppi_ch1, ppi_ch2, ppi_group, rxd, rts, rx_buffer); | 306 | let rx = BufferedUarteRx::new_innerer(peri, timer, ppi_ch1, ppi_ch2, ppi_group, rxd, rts, rx_buffer); |
| 306 | 307 | ||
| 308 | U::regs().enable.write(|w| w.enable().enabled()); | ||
| 307 | U::Interrupt::pend(); | 309 | U::Interrupt::pend(); |
| 308 | unsafe { U::Interrupt::enable() }; | 310 | unsafe { U::Interrupt::enable() }; |
| 309 | 311 | ||
| @@ -405,6 +407,7 @@ impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> { | |||
| 405 | 407 | ||
| 406 | let this = Self::new_innerer(peri, txd, cts, tx_buffer); | 408 | let this = Self::new_innerer(peri, txd, cts, tx_buffer); |
| 407 | 409 | ||
| 410 | U::regs().enable.write(|w| w.enable().enabled()); | ||
| 408 | U::Interrupt::pend(); | 411 | U::Interrupt::pend(); |
| 409 | unsafe { U::Interrupt::enable() }; | 412 | unsafe { U::Interrupt::enable() }; |
| 410 | 413 | ||
| @@ -602,6 +605,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> { | |||
| 602 | 605 | ||
| 603 | let this = Self::new_innerer(peri, timer, ppi_ch1, ppi_ch2, ppi_group, rxd, rts, rx_buffer); | 606 | let this = Self::new_innerer(peri, timer, ppi_ch1, ppi_ch2, ppi_group, rxd, rts, rx_buffer); |
| 604 | 607 | ||
| 608 | U::regs().enable.write(|w| w.enable().enabled()); | ||
| 605 | U::Interrupt::pend(); | 609 | U::Interrupt::pend(); |
| 606 | unsafe { U::Interrupt::enable() }; | 610 | unsafe { U::Interrupt::enable() }; |
| 607 | 611 | ||
| @@ -638,8 +642,8 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> { | |||
| 638 | s.rx_started_count.store(0, Ordering::Relaxed); | 642 | s.rx_started_count.store(0, Ordering::Relaxed); |
| 639 | s.rx_ended_count.store(0, Ordering::Relaxed); | 643 | s.rx_ended_count.store(0, Ordering::Relaxed); |
| 640 | s.rx_started.store(false, Ordering::Relaxed); | 644 | s.rx_started.store(false, Ordering::Relaxed); |
| 641 | let len = rx_buffer.len(); | 645 | let rx_len = rx_buffer.len().min(EASY_DMA_SIZE * 2); |
| 642 | unsafe { s.rx_buf.init(rx_buffer.as_mut_ptr(), len) }; | 646 | unsafe { s.rx_buf.init(rx_buffer.as_mut_ptr(), rx_len) }; |
| 643 | 647 | ||
| 644 | // clear errors | 648 | // clear errors |
| 645 | let errors = r.errorsrc.read().bits(); | 649 | let errors = r.errorsrc.read().bits(); |
| @@ -660,7 +664,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> { | |||
| 660 | 664 | ||
| 661 | // Configure byte counter. | 665 | // Configure byte counter. |
| 662 | let timer = Timer::new_counter(timer); | 666 | let timer = Timer::new_counter(timer); |
| 663 | timer.cc(1).write(rx_buffer.len() as u32 * 2); | 667 | timer.cc(1).write(rx_len as u32 * 2); |
| 664 | timer.cc(1).short_compare_clear(); | 668 | timer.cc(1).short_compare_clear(); |
| 665 | timer.clear(); | 669 | timer.clear(); |
| 666 | timer.start(); | 670 | timer.start(); |
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index fa0a773a8..4cf193617 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs | |||
| @@ -221,6 +221,7 @@ impl<'d, T: Instance> Uarte<'d, T> { | |||
| 221 | 221 | ||
| 222 | T::Interrupt::unpend(); | 222 | T::Interrupt::unpend(); |
| 223 | unsafe { T::Interrupt::enable() }; | 223 | unsafe { T::Interrupt::enable() }; |
| 224 | r.enable.write(|w| w.enable().enabled()); | ||
| 224 | 225 | ||
| 225 | let s = T::state(); | 226 | let s = T::state(); |
| 226 | s.tx_rx_refcount.store(2, Ordering::Relaxed); | 227 | s.tx_rx_refcount.store(2, Ordering::Relaxed); |
| @@ -319,9 +320,7 @@ pub(crate) fn configure(r: &RegisterBlock, config: Config, hardware_flow_control | |||
| 319 | r.psel.cts.write(|w| w.connect().disconnected()); | 320 | r.psel.cts.write(|w| w.connect().disconnected()); |
| 320 | r.psel.rts.write(|w| w.connect().disconnected()); | 321 | r.psel.rts.write(|w| w.connect().disconnected()); |
| 321 | 322 | ||
| 322 | // Enable | ||
| 323 | apply_workaround_for_enable_anomaly(r); | 323 | apply_workaround_for_enable_anomaly(r); |
| 324 | r.enable.write(|w| w.enable().enabled()); | ||
| 325 | } | 324 | } |
| 326 | 325 | ||
| 327 | impl<'d, T: Instance> UarteTx<'d, T> { | 326 | impl<'d, T: Instance> UarteTx<'d, T> { |
| @@ -369,6 +368,7 @@ impl<'d, T: Instance> UarteTx<'d, T> { | |||
| 369 | 368 | ||
| 370 | T::Interrupt::unpend(); | 369 | T::Interrupt::unpend(); |
| 371 | unsafe { T::Interrupt::enable() }; | 370 | unsafe { T::Interrupt::enable() }; |
| 371 | r.enable.write(|w| w.enable().enabled()); | ||
| 372 | 372 | ||
| 373 | let s = T::state(); | 373 | let s = T::state(); |
| 374 | s.tx_rx_refcount.store(1, Ordering::Relaxed); | 374 | s.tx_rx_refcount.store(1, Ordering::Relaxed); |
| @@ -567,6 +567,7 @@ impl<'d, T: Instance> UarteRx<'d, T> { | |||
| 567 | 567 | ||
| 568 | T::Interrupt::unpend(); | 568 | T::Interrupt::unpend(); |
| 569 | unsafe { T::Interrupt::enable() }; | 569 | unsafe { T::Interrupt::enable() }; |
| 570 | r.enable.write(|w| w.enable().enabled()); | ||
| 570 | 571 | ||
| 571 | let s = T::state(); | 572 | let s = T::state(); |
| 572 | s.tx_rx_refcount.store(1, Ordering::Relaxed); | 573 | s.tx_rx_refcount.store(1, Ordering::Relaxed); |
diff --git a/tests/nrf/Cargo.toml b/tests/nrf/Cargo.toml index 2faee70e3..c714e8f7e 100644 --- a/tests/nrf/Cargo.toml +++ b/tests/nrf/Cargo.toml | |||
| @@ -30,14 +30,15 @@ panic-probe = { version = "0.3", features = ["print-defmt"] } | |||
| 30 | portable-atomic = { version = "1.6.0" } | 30 | portable-atomic = { version = "1.6.0" } |
| 31 | 31 | ||
| 32 | [features] | 32 | [features] |
| 33 | nrf51422 = ["embassy-nrf/nrf51", "portable-atomic/unsafe-assume-single-core"] | 33 | nrf51422 = ["embassy-nrf/nrf51", "portable-atomic/unsafe-assume-single-core"] |
| 34 | nrf52832 = ["embassy-nrf/nrf52832", "easydma"] | 34 | nrf52832 = ["embassy-nrf/nrf52832", "easydma"] |
| 35 | nrf52833 = ["embassy-nrf/nrf52833", "easydma"] | 35 | nrf52833 = ["embassy-nrf/nrf52833", "easydma", "two-uarts"] |
| 36 | nrf52840 = ["embassy-nrf/nrf52840", "easydma"] | 36 | nrf52840 = ["embassy-nrf/nrf52840", "easydma", "two-uarts"] |
| 37 | nrf5340 = ["embassy-nrf/nrf5340-app-s", "easydma"] | 37 | nrf5340 = ["embassy-nrf/nrf5340-app-s", "easydma", "two-uarts"] |
| 38 | nrf9160 = ["embassy-nrf/nrf9160-s", "easydma"] | 38 | nrf9160 = ["embassy-nrf/nrf9160-s", "easydma", "two-uarts"] |
| 39 | 39 | ||
| 40 | easydma = [] | 40 | easydma = [] |
| 41 | two-uarts = [] | ||
| 41 | 42 | ||
| 42 | [profile.release] | 43 | [profile.release] |
| 43 | codegen-units = 1 | 44 | codegen-units = 1 |
| @@ -53,22 +54,22 @@ overflow-checks = false | |||
| 53 | [[bin]] | 54 | [[bin]] |
| 54 | name = "buffered_uart" | 55 | name = "buffered_uart" |
| 55 | path = "src/bin/buffered_uart.rs" | 56 | path = "src/bin/buffered_uart.rs" |
| 56 | required-features = [ "nrf52840",] | 57 | required-features = [ "easydma",] |
| 57 | 58 | ||
| 58 | [[bin]] | 59 | [[bin]] |
| 59 | name = "buffered_uart_full" | 60 | name = "buffered_uart_full" |
| 60 | path = "src/bin/buffered_uart_full.rs" | 61 | path = "src/bin/buffered_uart_full.rs" |
| 61 | required-features = [ "nrf52840",] | 62 | required-features = [ "easydma",] |
| 62 | 63 | ||
| 63 | [[bin]] | 64 | [[bin]] |
| 64 | name = "buffered_uart_halves" | 65 | name = "buffered_uart_halves" |
| 65 | path = "src/bin/buffered_uart_halves.rs" | 66 | path = "src/bin/buffered_uart_halves.rs" |
| 66 | required-features = [ "nrf52840",] | 67 | required-features = [ "two-uarts",] |
| 67 | 68 | ||
| 68 | [[bin]] | 69 | [[bin]] |
| 69 | name = "buffered_uart_spam" | 70 | name = "buffered_uart_spam" |
| 70 | path = "src/bin/buffered_uart_spam.rs" | 71 | path = "src/bin/buffered_uart_spam.rs" |
| 71 | required-features = [ "nrf52840",] | 72 | required-features = [ "two-uarts",] |
| 72 | 73 | ||
| 73 | [[bin]] | 74 | [[bin]] |
| 74 | name = "ethernet_enc28j60_perf" | 75 | name = "ethernet_enc28j60_perf" |
| @@ -91,6 +92,16 @@ path = "src/bin/timer.rs" | |||
| 91 | required-features = [] | 92 | required-features = [] |
| 92 | 93 | ||
| 93 | [[bin]] | 94 | [[bin]] |
| 95 | name = "uart_halves" | ||
| 96 | path = "src/bin/uart_halves.rs" | ||
| 97 | required-features = [ "two-uarts",] | ||
| 98 | |||
| 99 | [[bin]] | ||
| 100 | name = "uart_split" | ||
| 101 | path = "src/bin/uart_split.rs" | ||
| 102 | required-features = [ "easydma",] | ||
| 103 | |||
| 104 | [[bin]] | ||
| 94 | name = "wifi_esp_hosted_perf" | 105 | name = "wifi_esp_hosted_perf" |
| 95 | path = "src/bin/wifi_esp_hosted_perf.rs" | 106 | path = "src/bin/wifi_esp_hosted_perf.rs" |
| 96 | required-features = [ "nrf52840",] | 107 | required-features = [ "nrf52840",] |
diff --git a/tests/nrf/src/bin/buffered_uart.rs b/tests/nrf/src/bin/buffered_uart.rs index 89314bfc9..04f32832f 100644 --- a/tests/nrf/src/bin/buffered_uart.rs +++ b/tests/nrf/src/bin/buffered_uart.rs | |||
| @@ -1,19 +1,17 @@ | |||
| 1 | // required-features: nrf52840 | 1 | // required-features: easydma |
| 2 | #![no_std] | 2 | #![no_std] |
| 3 | #![no_main] | 3 | #![no_main] |
| 4 | teleprobe_meta::target!(b"nrf52840-dk"); | ||
| 5 | 4 | ||
| 6 | use defmt::{assert_eq, *}; | 5 | #[path = "../common.rs"] |
| 6 | mod common; | ||
| 7 | |||
| 8 | use defmt::{panic, *}; | ||
| 7 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| 8 | use embassy_futures::join::join; | 10 | use embassy_futures::join::join; |
| 9 | use embassy_nrf::buffered_uarte::{self, BufferedUarte}; | 11 | use embassy_nrf::buffered_uarte::{self, BufferedUarte}; |
| 10 | use embassy_nrf::{bind_interrupts, peripherals, uarte}; | 12 | use embassy_nrf::{peripherals, uarte}; |
| 11 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 12 | 14 | ||
| 13 | bind_interrupts!(struct Irqs { | ||
| 14 | UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>; | ||
| 15 | }); | ||
| 16 | |||
| 17 | #[embassy_executor::main] | 15 | #[embassy_executor::main] |
| 18 | async fn main(_spawner: Spawner) { | 16 | async fn main(_spawner: Spawner) { |
| 19 | let mut p = embassy_nrf::init(Default::default()); | 17 | let mut p = embassy_nrf::init(Default::default()); |
| @@ -27,14 +25,14 @@ async fn main(_spawner: Spawner) { | |||
| 27 | // test teardown + recreate of the buffereduarte works fine. | 25 | // test teardown + recreate of the buffereduarte works fine. |
| 28 | for _ in 0..2 { | 26 | for _ in 0..2 { |
| 29 | let u = BufferedUarte::new( | 27 | let u = BufferedUarte::new( |
| 30 | &mut p.UARTE0, | 28 | &mut peri!(p, UART0), |
| 31 | &mut p.TIMER0, | 29 | &mut p.TIMER0, |
| 32 | &mut p.PPI_CH0, | 30 | &mut p.PPI_CH0, |
| 33 | &mut p.PPI_CH1, | 31 | &mut p.PPI_CH1, |
| 34 | &mut p.PPI_GROUP0, | 32 | &mut p.PPI_GROUP0, |
| 35 | Irqs, | 33 | irqs!(UART0_BUFFERED), |
| 36 | &mut p.P1_03, | 34 | &mut peri!(p, PIN_A), |
| 37 | &mut p.P1_02, | 35 | &mut peri!(p, PIN_B), |
| 38 | config.clone(), | 36 | config.clone(), |
| 39 | &mut rx_buffer, | 37 | &mut rx_buffer, |
| 40 | &mut tx_buffer, | 38 | &mut tx_buffer, |
| @@ -65,7 +63,9 @@ async fn main(_spawner: Spawner) { | |||
| 65 | let buf = unwrap!(rx.fill_buf().await); | 63 | let buf = unwrap!(rx.fill_buf().await); |
| 66 | 64 | ||
| 67 | for &b in buf { | 65 | for &b in buf { |
| 68 | assert_eq!(b, i as u8); | 66 | if b != i as u8 { |
| 67 | panic!("mismatch {} vs {}, index {}", b, i as u8, i); | ||
| 68 | } | ||
| 69 | i = i + 1; | 69 | i = i + 1; |
| 70 | } | 70 | } |
| 71 | 71 | ||
diff --git a/tests/nrf/src/bin/buffered_uart_full.rs b/tests/nrf/src/bin/buffered_uart_full.rs index a7d9a3717..09353bbe8 100644 --- a/tests/nrf/src/bin/buffered_uart_full.rs +++ b/tests/nrf/src/bin/buffered_uart_full.rs | |||
| @@ -1,19 +1,17 @@ | |||
| 1 | // required-features: nrf52840 | 1 | // required-features: easydma |
| 2 | #![no_std] | 2 | #![no_std] |
| 3 | #![no_main] | 3 | #![no_main] |
| 4 | teleprobe_meta::target!(b"nrf52840-dk"); | 4 | |
| 5 | #[path = "../common.rs"] | ||
| 6 | mod common; | ||
| 5 | 7 | ||
| 6 | use defmt::{assert_eq, *}; | 8 | use defmt::{assert_eq, *}; |
| 7 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| 8 | use embassy_nrf::buffered_uarte::{self, BufferedUarte}; | 10 | use embassy_nrf::buffered_uarte::{self, BufferedUarte}; |
| 9 | use embassy_nrf::{bind_interrupts, peripherals, uarte}; | 11 | use embassy_nrf::{peripherals, uarte}; |
| 10 | use embedded_io_async::{Read, Write}; | 12 | use embedded_io_async::{Read, Write}; |
| 11 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 12 | 14 | ||
| 13 | bind_interrupts!(struct Irqs { | ||
| 14 | UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>; | ||
| 15 | }); | ||
| 16 | |||
| 17 | #[embassy_executor::main] | 15 | #[embassy_executor::main] |
| 18 | async fn main(_spawner: Spawner) { | 16 | async fn main(_spawner: Spawner) { |
| 19 | let p = embassy_nrf::init(Default::default()); | 17 | let p = embassy_nrf::init(Default::default()); |
| @@ -21,18 +19,18 @@ async fn main(_spawner: Spawner) { | |||
| 21 | config.parity = uarte::Parity::EXCLUDED; | 19 | config.parity = uarte::Parity::EXCLUDED; |
| 22 | config.baudrate = uarte::Baudrate::BAUD1M; | 20 | config.baudrate = uarte::Baudrate::BAUD1M; |
| 23 | 21 | ||
| 24 | let mut tx_buffer = [0u8; 1024]; | 22 | let mut tx_buffer = [0u8; 500]; |
| 25 | let mut rx_buffer = [0u8; 1024]; | 23 | let mut rx_buffer = [0u8; 500]; |
| 26 | 24 | ||
| 27 | let u = BufferedUarte::new( | 25 | let u = BufferedUarte::new( |
| 28 | p.UARTE0, | 26 | peri!(p, UART0), |
| 29 | p.TIMER0, | 27 | p.TIMER0, |
| 30 | p.PPI_CH0, | 28 | p.PPI_CH0, |
| 31 | p.PPI_CH1, | 29 | p.PPI_CH1, |
| 32 | p.PPI_GROUP0, | 30 | p.PPI_GROUP0, |
| 33 | Irqs, | 31 | irqs!(UART0_BUFFERED), |
| 34 | p.P1_03, | 32 | peri!(p, PIN_A), |
| 35 | p.P1_02, | 33 | peri!(p, PIN_B), |
| 36 | config.clone(), | 34 | config.clone(), |
| 37 | &mut rx_buffer, | 35 | &mut rx_buffer, |
| 38 | &mut tx_buffer, | 36 | &mut tx_buffer, |
| @@ -42,22 +40,22 @@ async fn main(_spawner: Spawner) { | |||
| 42 | 40 | ||
| 43 | let (mut rx, mut tx) = u.split(); | 41 | let (mut rx, mut tx) = u.split(); |
| 44 | 42 | ||
| 45 | let mut buf = [0; 1024]; | 43 | let mut buf = [0; 500]; |
| 46 | for (j, b) in buf.iter_mut().enumerate() { | 44 | for (j, b) in buf.iter_mut().enumerate() { |
| 47 | *b = j as u8; | 45 | *b = j as u8; |
| 48 | } | 46 | } |
| 49 | 47 | ||
| 50 | // Write 1024b. This causes the rx buffer to get exactly full. | 48 | // Write 500b. This causes the rx buffer to get exactly full. |
| 51 | unwrap!(tx.write_all(&buf).await); | 49 | unwrap!(tx.write_all(&buf).await); |
| 52 | unwrap!(tx.flush().await); | 50 | unwrap!(tx.flush().await); |
| 53 | 51 | ||
| 54 | // Read those 1024b. | 52 | // Read those 500b. |
| 55 | unwrap!(rx.read_exact(&mut buf).await); | 53 | unwrap!(rx.read_exact(&mut buf).await); |
| 56 | for (j, b) in buf.iter().enumerate() { | 54 | for (j, b) in buf.iter().enumerate() { |
| 57 | assert_eq!(*b, j as u8); | 55 | assert_eq!(*b, j as u8); |
| 58 | } | 56 | } |
| 59 | 57 | ||
| 60 | // The buffer should now be unclogged. Write 1024b again. | 58 | // The buffer should now be unclogged. Write 500b again. |
| 61 | unwrap!(tx.write_all(&buf).await); | 59 | unwrap!(tx.write_all(&buf).await); |
| 62 | unwrap!(tx.flush().await); | 60 | unwrap!(tx.flush().await); |
| 63 | 61 | ||
diff --git a/tests/nrf/src/bin/buffered_uart_halves.rs b/tests/nrf/src/bin/buffered_uart_halves.rs index ae1021f04..bdf5ad726 100644 --- a/tests/nrf/src/bin/buffered_uart_halves.rs +++ b/tests/nrf/src/bin/buffered_uart_halves.rs | |||
| @@ -1,20 +1,17 @@ | |||
| 1 | // required-features: nrf52840 | 1 | // required-features: two-uarts |
| 2 | #![no_std] | 2 | #![no_std] |
| 3 | #![no_main] | 3 | #![no_main] |
| 4 | teleprobe_meta::target!(b"nrf52840-dk"); | 4 | |
| 5 | #[path = "../common.rs"] | ||
| 6 | mod common; | ||
| 5 | 7 | ||
| 6 | use defmt::{assert_eq, *}; | 8 | use defmt::{assert_eq, *}; |
| 7 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| 8 | use embassy_futures::join::join; | 10 | use embassy_futures::join::join; |
| 9 | use embassy_nrf::buffered_uarte::{self, BufferedUarteRx, BufferedUarteTx}; | 11 | use embassy_nrf::buffered_uarte::{self, BufferedUarteRx, BufferedUarteTx}; |
| 10 | use embassy_nrf::{bind_interrupts, peripherals, uarte}; | 12 | use embassy_nrf::{peripherals, uarte}; |
| 11 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 12 | 14 | ||
| 13 | bind_interrupts!(struct Irqs { | ||
| 14 | UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>; | ||
| 15 | UARTE1 => buffered_uarte::InterruptHandler<peripherals::UARTE1>; | ||
| 16 | }); | ||
| 17 | |||
| 18 | #[embassy_executor::main] | 15 | #[embassy_executor::main] |
| 19 | async fn main(_spawner: Spawner) { | 16 | async fn main(_spawner: Spawner) { |
| 20 | let mut p = embassy_nrf::init(Default::default()); | 17 | let mut p = embassy_nrf::init(Default::default()); |
| @@ -29,16 +26,22 @@ async fn main(_spawner: Spawner) { | |||
| 29 | for _ in 0..2 { | 26 | for _ in 0..2 { |
| 30 | const COUNT: usize = 40_000; | 27 | const COUNT: usize = 40_000; |
| 31 | 28 | ||
| 32 | let mut tx = BufferedUarteTx::new(&mut p.UARTE1, Irqs, &mut p.P1_02, config.clone(), &mut tx_buffer); | 29 | let mut tx = BufferedUarteTx::new( |
| 30 | &mut peri!(p, UART1), | ||
| 31 | irqs!(UART1_BUFFERED), | ||
| 32 | &mut peri!(p, PIN_A), | ||
| 33 | config.clone(), | ||
| 34 | &mut tx_buffer, | ||
| 35 | ); | ||
| 33 | 36 | ||
| 34 | let mut rx = BufferedUarteRx::new( | 37 | let mut rx = BufferedUarteRx::new( |
| 35 | &mut p.UARTE0, | 38 | &mut peri!(p, UART0), |
| 36 | &mut p.TIMER0, | 39 | &mut p.TIMER0, |
| 37 | &mut p.PPI_CH0, | 40 | &mut p.PPI_CH0, |
| 38 | &mut p.PPI_CH1, | 41 | &mut p.PPI_CH1, |
| 39 | &mut p.PPI_GROUP0, | 42 | &mut p.PPI_GROUP0, |
| 40 | Irqs, | 43 | irqs!(UART0_BUFFERED), |
| 41 | &mut p.P1_03, | 44 | &mut peri!(p, PIN_B), |
| 42 | config.clone(), | 45 | config.clone(), |
| 43 | &mut rx_buffer, | 46 | &mut rx_buffer, |
| 44 | ); | 47 | ); |
diff --git a/tests/nrf/src/bin/buffered_uart_spam.rs b/tests/nrf/src/bin/buffered_uart_spam.rs index 906723229..e8fca452e 100644 --- a/tests/nrf/src/bin/buffered_uart_spam.rs +++ b/tests/nrf/src/bin/buffered_uart_spam.rs | |||
| @@ -1,26 +1,23 @@ | |||
| 1 | // required-features: nrf52840 | 1 | // required-features: two-uarts |
| 2 | #![no_std] | 2 | #![no_std] |
| 3 | #![no_main] | 3 | #![no_main] |
| 4 | teleprobe_meta::target!(b"nrf52840-dk"); | 4 | |
| 5 | #[path = "../common.rs"] | ||
| 6 | mod common; | ||
| 5 | 7 | ||
| 6 | use core::mem; | 8 | use core::mem; |
| 7 | use core::ptr::NonNull; | 9 | use core::ptr::NonNull; |
| 8 | 10 | ||
| 9 | use defmt::{assert_eq, *}; | 11 | use defmt::{assert_eq, *}; |
| 10 | use embassy_executor::Spawner; | 12 | use embassy_executor::Spawner; |
| 11 | use embassy_nrf::buffered_uarte::{self, BufferedUarte}; | 13 | use embassy_nrf::buffered_uarte::{self, BufferedUarteRx}; |
| 12 | use embassy_nrf::gpio::{Level, Output, OutputDrive}; | 14 | use embassy_nrf::gpio::{Level, Output, OutputDrive}; |
| 13 | use embassy_nrf::ppi::{Event, Ppi, Task}; | 15 | use embassy_nrf::ppi::{Event, Ppi, Task}; |
| 14 | use embassy_nrf::uarte::Uarte; | 16 | use embassy_nrf::uarte::UarteTx; |
| 15 | use embassy_nrf::{bind_interrupts, pac, peripherals, uarte}; | 17 | use embassy_nrf::{pac, peripherals, uarte}; |
| 16 | use embassy_time::Timer; | 18 | use embassy_time::Timer; |
| 17 | use {defmt_rtt as _, panic_probe as _}; | 19 | use {defmt_rtt as _, panic_probe as _}; |
| 18 | 20 | ||
| 19 | bind_interrupts!(struct Irqs { | ||
| 20 | UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>; | ||
| 21 | UARTE1 => uarte::InterruptHandler<peripherals::UARTE1>; | ||
| 22 | }); | ||
| 23 | |||
| 24 | #[embassy_executor::main] | 21 | #[embassy_executor::main] |
| 25 | async fn main(_spawner: Spawner) { | 22 | async fn main(_spawner: Spawner) { |
| 26 | let mut p = embassy_nrf::init(Default::default()); | 23 | let mut p = embassy_nrf::init(Default::default()); |
| @@ -28,23 +25,20 @@ async fn main(_spawner: Spawner) { | |||
| 28 | config.parity = uarte::Parity::EXCLUDED; | 25 | config.parity = uarte::Parity::EXCLUDED; |
| 29 | config.baudrate = uarte::Baudrate::BAUD1M; | 26 | config.baudrate = uarte::Baudrate::BAUD1M; |
| 30 | 27 | ||
| 31 | let mut tx_buffer = [0u8; 1024]; | ||
| 32 | let mut rx_buffer = [0u8; 1024]; | 28 | let mut rx_buffer = [0u8; 1024]; |
| 33 | 29 | ||
| 34 | mem::forget(Output::new(&mut p.P1_02, Level::High, OutputDrive::Standard)); | 30 | mem::forget(Output::new(&mut peri!(p, PIN_A), Level::High, OutputDrive::Standard)); |
| 35 | 31 | ||
| 36 | let mut u = BufferedUarte::new( | 32 | let mut u = BufferedUarteRx::new( |
| 37 | p.UARTE0, | 33 | peri!(p, UART0), |
| 38 | p.TIMER0, | 34 | p.TIMER0, |
| 39 | p.PPI_CH0, | 35 | p.PPI_CH0, |
| 40 | p.PPI_CH1, | 36 | p.PPI_CH1, |
| 41 | p.PPI_GROUP0, | 37 | p.PPI_GROUP0, |
| 42 | Irqs, | 38 | irqs!(UART0_BUFFERED), |
| 43 | p.P1_03, | 39 | peri!(p, PIN_B), |
| 44 | p.P1_04, | ||
| 45 | config.clone(), | 40 | config.clone(), |
| 46 | &mut rx_buffer, | 41 | &mut rx_buffer, |
| 47 | &mut tx_buffer, | ||
| 48 | ); | 42 | ); |
| 49 | 43 | ||
| 50 | info!("uarte initialized!"); | 44 | info!("uarte initialized!"); |
| @@ -55,7 +49,7 @@ async fn main(_spawner: Spawner) { | |||
| 55 | // Tx spam in a loop. | 49 | // Tx spam in a loop. |
| 56 | const NSPAM: usize = 17; | 50 | const NSPAM: usize = 17; |
| 57 | static mut TX_BUF: [u8; NSPAM] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; | 51 | static mut TX_BUF: [u8; NSPAM] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; |
| 58 | let _spam = Uarte::new(p.UARTE1, Irqs, p.P1_01, p.P1_02, config.clone()); | 52 | let _spam = UarteTx::new(peri!(p, UART1), irqs!(UART1), peri!(p, PIN_A), config.clone()); |
| 59 | let spam_peri: pac::UARTE1 = unsafe { mem::transmute(()) }; | 53 | let spam_peri: pac::UARTE1 = unsafe { mem::transmute(()) }; |
| 60 | let event = unsafe { Event::new_unchecked(NonNull::new_unchecked(&spam_peri.events_endtx as *const _ as _)) }; | 54 | let event = unsafe { Event::new_unchecked(NonNull::new_unchecked(&spam_peri.events_endtx as *const _ as _)) }; |
| 61 | let task = unsafe { Task::new_unchecked(NonNull::new_unchecked(&spam_peri.tasks_starttx as *const _ as _)) }; | 55 | let task = unsafe { Task::new_unchecked(NonNull::new_unchecked(&spam_peri.tasks_starttx as *const _ as _)) }; |
diff --git a/tests/nrf/src/bin/uart_halves.rs b/tests/nrf/src/bin/uart_halves.rs new file mode 100644 index 000000000..f48ea43a1 --- /dev/null +++ b/tests/nrf/src/bin/uart_halves.rs | |||
| @@ -0,0 +1,41 @@ | |||
| 1 | // required-features: two-uarts | ||
| 2 | #![no_std] | ||
| 3 | #![no_main] | ||
| 4 | |||
| 5 | #[path = "../common.rs"] | ||
| 6 | mod common; | ||
| 7 | |||
| 8 | use defmt::{assert_eq, *}; | ||
| 9 | use embassy_executor::Spawner; | ||
| 10 | use embassy_futures::join::join; | ||
| 11 | use embassy_nrf::uarte::{UarteRx, UarteTx}; | ||
| 12 | use embassy_nrf::{peripherals, uarte}; | ||
| 13 | use {defmt_rtt as _, panic_probe as _}; | ||
| 14 | |||
| 15 | #[embassy_executor::main] | ||
| 16 | async fn main(_spawner: Spawner) { | ||
| 17 | let mut p = embassy_nrf::init(Default::default()); | ||
| 18 | let mut config = uarte::Config::default(); | ||
| 19 | config.parity = uarte::Parity::EXCLUDED; | ||
| 20 | config.baudrate = uarte::Baudrate::BAUD1M; | ||
| 21 | |||
| 22 | let mut tx = UarteTx::new(&mut peri!(p, UART0), irqs!(UART0), &mut peri!(p, PIN_A), config.clone()); | ||
| 23 | let mut rx = UarteRx::new(&mut peri!(p, UART1), irqs!(UART1), &mut peri!(p, PIN_B), config.clone()); | ||
| 24 | |||
| 25 | let data = [ | ||
| 26 | 0x42, 0x43, 0x44, 0x45, 0x66, 0x12, 0x23, 0x34, 0x45, 0x19, 0x91, 0xaa, 0xff, 0xa5, 0x5a, 0x77, | ||
| 27 | ]; | ||
| 28 | |||
| 29 | let tx_fut = async { | ||
| 30 | tx.write(&data).await.unwrap(); | ||
| 31 | }; | ||
| 32 | let rx_fut = async { | ||
| 33 | let mut buf = [0u8; 16]; | ||
| 34 | rx.read(&mut buf).await.unwrap(); | ||
| 35 | assert_eq!(data, buf); | ||
| 36 | }; | ||
| 37 | join(rx_fut, tx_fut).await; | ||
| 38 | |||
| 39 | info!("Test OK"); | ||
| 40 | cortex_m::asm::bkpt(); | ||
| 41 | } | ||
diff --git a/tests/nrf/src/bin/uart_split.rs b/tests/nrf/src/bin/uart_split.rs new file mode 100644 index 000000000..70d8b2e33 --- /dev/null +++ b/tests/nrf/src/bin/uart_split.rs | |||
| @@ -0,0 +1,49 @@ | |||
| 1 | // required-features: easydma | ||
| 2 | #![no_std] | ||
| 3 | #![no_main] | ||
| 4 | |||
| 5 | #[path = "../common.rs"] | ||
| 6 | mod common; | ||
| 7 | |||
| 8 | use defmt::{assert_eq, *}; | ||
| 9 | use embassy_executor::Spawner; | ||
| 10 | use embassy_futures::join::join; | ||
| 11 | use embassy_nrf::uarte::Uarte; | ||
| 12 | use embassy_nrf::{peripherals, uarte}; | ||
| 13 | use embassy_time::Timer; | ||
| 14 | use {defmt_rtt as _, panic_probe as _}; | ||
| 15 | |||
| 16 | #[embassy_executor::main] | ||
| 17 | async fn main(_spawner: Spawner) { | ||
| 18 | let mut p = embassy_nrf::init(Default::default()); | ||
| 19 | let mut config = uarte::Config::default(); | ||
| 20 | config.parity = uarte::Parity::EXCLUDED; | ||
| 21 | config.baudrate = uarte::Baudrate::BAUD9600; | ||
| 22 | |||
| 23 | let uarte = Uarte::new( | ||
| 24 | &mut peri!(p, UART0), | ||
| 25 | irqs!(UART0), | ||
| 26 | &mut peri!(p, PIN_A), | ||
| 27 | &mut peri!(p, PIN_B), | ||
| 28 | config.clone(), | ||
| 29 | ); | ||
| 30 | let (mut tx, mut rx) = uarte.split(); | ||
| 31 | |||
| 32 | let data = [ | ||
| 33 | 0x42, 0x43, 0x44, 0x45, 0x66, 0x12, 0x23, 0x34, 0x45, 0x19, 0x91, 0xaa, 0xff, 0xa5, 0x5a, 0x77, | ||
| 34 | ]; | ||
| 35 | |||
| 36 | let tx_fut = async { | ||
| 37 | Timer::after_millis(10).await; | ||
| 38 | tx.write(&data).await.unwrap(); | ||
| 39 | }; | ||
| 40 | let rx_fut = async { | ||
| 41 | let mut buf = [0u8; 16]; | ||
| 42 | rx.read(&mut buf).await.unwrap(); | ||
| 43 | assert_eq!(data, buf); | ||
| 44 | }; | ||
| 45 | join(rx_fut, tx_fut).await; | ||
| 46 | |||
| 47 | info!("Test OK"); | ||
| 48 | cortex_m::asm::bkpt(); | ||
| 49 | } | ||
diff --git a/tests/nrf/src/common.rs b/tests/nrf/src/common.rs index 79336c5de..ff5299b0f 100644 --- a/tests/nrf/src/common.rs +++ b/tests/nrf/src/common.rs | |||
| @@ -50,16 +50,53 @@ macro_rules! define_peris { | |||
| 50 | define_peris!(PIN_A = P0_13, PIN_B = P0_14,); | 50 | define_peris!(PIN_A = P0_13, PIN_B = P0_14,); |
| 51 | 51 | ||
| 52 | #[cfg(feature = "nrf52832")] | 52 | #[cfg(feature = "nrf52832")] |
| 53 | define_peris!(PIN_A = P0_11, PIN_B = P0_12,); | 53 | define_peris!( |
| 54 | PIN_A = P0_11, PIN_B = P0_12, | ||
| 55 | UART0 = UARTE0, | ||
| 56 | @irq UART0 = {UARTE0_UART0 => uarte::InterruptHandler<peripherals::UARTE0>;}, | ||
| 57 | @irq UART0_BUFFERED = {UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;}, | ||
| 58 | ); | ||
| 54 | 59 | ||
| 55 | #[cfg(feature = "nrf52833")] | 60 | #[cfg(feature = "nrf52833")] |
| 56 | define_peris!(PIN_A = P1_01, PIN_B = P1_02,); | 61 | define_peris!( |
| 62 | PIN_A = P1_01, PIN_B = P1_02, | ||
| 63 | UART0 = UARTE0, | ||
| 64 | UART1 = UARTE1, | ||
| 65 | @irq UART0 = {UARTE0_UART0 => uarte::InterruptHandler<peripherals::UARTE0>;}, | ||
| 66 | @irq UART1 = {UARTE1 => uarte::InterruptHandler<peripherals::UARTE1>;}, | ||
| 67 | @irq UART0_BUFFERED = {UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;}, | ||
| 68 | @irq UART1_BUFFERED = {UARTE1 => buffered_uarte::InterruptHandler<peripherals::UARTE1>;}, | ||
| 69 | ); | ||
| 57 | 70 | ||
| 58 | #[cfg(feature = "nrf52840")] | 71 | #[cfg(feature = "nrf52840")] |
| 59 | define_peris!(PIN_A = P1_02, PIN_B = P1_03,); | 72 | define_peris!( |
| 73 | PIN_A = P1_02, PIN_B = P1_03, | ||
| 74 | UART0 = UARTE0, | ||
| 75 | UART1 = UARTE1, | ||
| 76 | @irq UART0 = {UARTE0_UART0 => uarte::InterruptHandler<peripherals::UARTE0>;}, | ||
| 77 | @irq UART1 = {UARTE1 => uarte::InterruptHandler<peripherals::UARTE1>;}, | ||
| 78 | @irq UART0_BUFFERED = {UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;}, | ||
| 79 | @irq UART1_BUFFERED = {UARTE1 => buffered_uarte::InterruptHandler<peripherals::UARTE1>;}, | ||
| 80 | ); | ||
| 60 | 81 | ||
| 61 | #[cfg(feature = "nrf5340")] | 82 | #[cfg(feature = "nrf5340")] |
| 62 | define_peris!(PIN_A = P1_00, PIN_B = P1_01,); | 83 | define_peris!( |
| 84 | PIN_A = P1_08, PIN_B = P1_09, | ||
| 85 | UART0 = SERIAL0, | ||
| 86 | UART1 = SERIAL1, | ||
| 87 | @irq UART0 = {SERIAL0 => uarte::InterruptHandler<peripherals::SERIAL0>;}, | ||
| 88 | @irq UART1 = {SERIAL1 => uarte::InterruptHandler<peripherals::SERIAL1>;}, | ||
| 89 | @irq UART0_BUFFERED = {SERIAL0 => buffered_uarte::InterruptHandler<peripherals::SERIAL0>;}, | ||
| 90 | @irq UART1_BUFFERED = {SERIAL1 => buffered_uarte::InterruptHandler<peripherals::SERIAL1>;}, | ||
| 91 | ); | ||
| 63 | 92 | ||
| 64 | #[cfg(feature = "nrf9160")] | 93 | #[cfg(feature = "nrf9160")] |
| 65 | define_peris!(PIN_A = P0_00, PIN_B = P0_01,); | 94 | define_peris!( |
| 95 | PIN_A = P0_00, PIN_B = P0_01, | ||
| 96 | UART0 = SERIAL0, | ||
| 97 | UART1 = SERIAL1, | ||
| 98 | @irq UART0 = {UARTE0_SPIM0_SPIS0_TWIM0_TWIS0 => uarte::InterruptHandler<peripherals::SERIAL0>;}, | ||
| 99 | @irq UART1 = {UARTE1_SPIM1_SPIS1_TWIM1_TWIS1 => uarte::InterruptHandler<peripherals::SERIAL1>;}, | ||
| 100 | @irq UART0_BUFFERED = {UARTE0_SPIM0_SPIS0_TWIM0_TWIS0 => buffered_uarte::InterruptHandler<peripherals::SERIAL0>;}, | ||
| 101 | @irq UART1_BUFFERED = {UARTE1_SPIM1_SPIS1_TWIM1_TWIS1 => buffered_uarte::InterruptHandler<peripherals::SERIAL1>;}, | ||
| 102 | ); | ||
