aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2023-05-01 15:35:39 +0000
committerGitHub <[email protected]>2023-05-01 15:35:39 +0000
commit05c36e05f9f6b1a0a36982239b2e7c697f0d3734 (patch)
tree68852621ce845a7e5a6e15ee07bbcb54b49ef9a8 /tests
parentac0ea406f91a5b630811accd0c97a622a020c700 (diff)
parentb58b9ff390fb885f0cca2ad15fc89d537f3a9818 (diff)
Merge #1414
1414: rp: report errors from buffered and dma uart receives r=Dirbaio a=pennae neither of these reported errors so far, which is not ideal. add error reporting to both of them that matches the blocking error reporting as closely as is feasible, even allowing partial receives from buffered uarts before errors are reported where they would have been by the blocking code. dma transfers don't do this, if an errors applies to any byte in a transfer the entire transfer is nuked (though we probably could report how many bytes have been transferred). Co-authored-by: pennae <[email protected]>
Diffstat (limited to 'tests')
-rw-r--r--tests/rp/src/bin/uart.rs159
-rw-r--r--tests/rp/src/bin/uart_buffered.rs249
-rw-r--r--tests/rp/src/bin/uart_dma.rs238
3 files changed, 605 insertions, 41 deletions
diff --git a/tests/rp/src/bin/uart.rs b/tests/rp/src/bin/uart.rs
index 92f61464e..80c18c02e 100644
--- a/tests/rp/src/bin/uart.rs
+++ b/tests/rp/src/bin/uart.rs
@@ -4,28 +4,165 @@
4 4
5use defmt::{assert_eq, *}; 5use defmt::{assert_eq, *};
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_rp::uart::{Config, Uart}; 7use embassy_rp::gpio::{Level, Output};
8use embassy_rp::uart::{Blocking, Config, Error, Instance, Parity, Uart, UartRx};
9use embassy_time::{Duration, Timer};
8use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
9 11
12fn read<const N: usize>(uart: &mut Uart<'_, impl Instance, Blocking>) -> Result<[u8; N], Error> {
13 let mut buf = [255; N];
14 uart.blocking_read(&mut buf)?;
15 Ok(buf)
16}
17
18fn read1<const N: usize>(uart: &mut UartRx<'_, impl Instance, Blocking>) -> Result<[u8; N], Error> {
19 let mut buf = [255; N];
20 uart.blocking_read(&mut buf)?;
21 Ok(buf)
22}
23
24async fn send(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, parity: Option<bool>) {
25 pin.set_low();
26 Timer::after(Duration::from_millis(1)).await;
27 for i in 0..8 {
28 if v & (1 << i) == 0 {
29 pin.set_low();
30 } else {
31 pin.set_high();
32 }
33 Timer::after(Duration::from_millis(1)).await;
34 }
35 if let Some(b) = parity {
36 if b {
37 pin.set_high();
38 } else {
39 pin.set_low();
40 }
41 Timer::after(Duration::from_millis(1)).await;
42 }
43 pin.set_high();
44 Timer::after(Duration::from_millis(1)).await;
45}
46
10#[embassy_executor::main] 47#[embassy_executor::main]
11async fn main(_spawner: Spawner) { 48async fn main(_spawner: Spawner) {
12 let p = embassy_rp::init(Default::default()); 49 let p = embassy_rp::init(Default::default());
13 info!("Hello World!"); 50 info!("Hello World!");
14 51
15 let (tx, rx, uart) = (p.PIN_0, p.PIN_1, p.UART0); 52 let (mut tx, mut rx, mut uart) = (p.PIN_0, p.PIN_1, p.UART0);
53
54 {
55 let config = Config::default();
56 let mut uart = Uart::new_blocking(&mut uart, &mut tx, &mut rx, config);
57
58 // We can't send too many bytes, they have to fit in the FIFO.
59 // This is because we aren't sending+receiving at the same time.
60
61 let data = [0xC0, 0xDE];
62 uart.blocking_write(&data).unwrap();
63 assert_eq!(read(&mut uart).unwrap(), data);
64 }
65
66 info!("test overflow detection");
67 {
68 let config = Config::default();
69 let mut uart = Uart::new_blocking(&mut uart, &mut tx, &mut rx, config);
70
71 let data = [
72 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
73 30, 31, 32,
74 ];
75 let overflow = [
76 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
77 ];
78 uart.blocking_write(&data).unwrap();
79 uart.blocking_write(&overflow).unwrap();
80 while uart.busy() {}
81
82 // prefix in fifo is valid
83 assert_eq!(read(&mut uart).unwrap(), data);
84 // next received character causes overrun error and is discarded
85 uart.blocking_write(&[1, 2, 3]).unwrap();
86 assert_eq!(read::<1>(&mut uart).unwrap_err(), Error::Overrun);
87 assert_eq!(read(&mut uart).unwrap(), [2, 3]);
88 }
89
90 info!("test break detection");
91 {
92 let config = Config::default();
93 let mut uart = Uart::new_blocking(&mut uart, &mut tx, &mut rx, config);
94
95 // break on empty fifo
96 uart.send_break(20).await;
97 uart.blocking_write(&[64]).unwrap();
98 assert_eq!(read::<1>(&mut uart).unwrap_err(), Error::Break);
99 assert_eq!(read(&mut uart).unwrap(), [64]);
100
101 // break on partially filled fifo
102 uart.blocking_write(&[65; 2]).unwrap();
103 uart.send_break(20).await;
104 uart.blocking_write(&[66]).unwrap();
105 assert_eq!(read(&mut uart).unwrap(), [65; 2]);
106 assert_eq!(read::<1>(&mut uart).unwrap_err(), Error::Break);
107 assert_eq!(read(&mut uart).unwrap(), [66]);
108 }
109
110 // parity detection. here we bitbang to not require two uarts.
111 info!("test parity error detection");
112 {
113 let mut pin = Output::new(&mut tx, Level::High);
114 let mut config = Config::default();
115 config.baudrate = 1000;
116 config.parity = Parity::ParityEven;
117 let mut uart = UartRx::new_blocking(&mut uart, &mut rx, config);
118
119 async fn chr(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, parity: u8) {
120 send(pin, v, Some(parity != 0)).await;
121 }
122
123 // first check that we can send correctly
124 chr(&mut pin, 64, 1).await;
125 assert_eq!(read1(&mut uart).unwrap(), [64]);
126
127 // all good, check real errors
128 chr(&mut pin, 2, 1).await;
129 chr(&mut pin, 3, 0).await;
130 chr(&mut pin, 4, 0).await;
131 chr(&mut pin, 5, 0).await;
132 assert_eq!(read1(&mut uart).unwrap(), [2, 3]);
133 assert_eq!(read1::<1>(&mut uart).unwrap_err(), Error::Parity);
134 assert_eq!(read1(&mut uart).unwrap(), [5]);
135 }
16 136
17 let config = Config::default(); 137 // framing error detection. here we bitbang because there's no other way.
18 let mut uart = Uart::new_blocking(uart, tx, rx, config); 138 info!("test framing error detection");
139 {
140 let mut pin = Output::new(&mut tx, Level::High);
141 let mut config = Config::default();
142 config.baudrate = 1000;
143 let mut uart = UartRx::new_blocking(&mut uart, &mut rx, config);
19 144
20 // We can't send too many bytes, they have to fit in the FIFO. 145 async fn chr(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, good: bool) {
21 // This is because we aren't sending+receiving at the same time. 146 if good {
147 send(pin, v, None).await;
148 } else {
149 send(pin, v, Some(false)).await;
150 }
151 }
22 152
23 let data = [0xC0, 0xDE]; 153 // first check that we can send correctly
24 uart.blocking_write(&data).unwrap(); 154 chr(&mut pin, 64, true).await;
155 assert_eq!(read1(&mut uart).unwrap(), [64]);
25 156
26 let mut buf = [0; 2]; 157 // all good, check real errors
27 uart.blocking_read(&mut buf).unwrap(); 158 chr(&mut pin, 2, true).await;
28 assert_eq!(buf, data); 159 chr(&mut pin, 3, true).await;
160 chr(&mut pin, 4, false).await;
161 chr(&mut pin, 5, true).await;
162 assert_eq!(read1(&mut uart).unwrap(), [2, 3]);
163 assert_eq!(read1::<1>(&mut uart).unwrap_err(), Error::Framing);
164 assert_eq!(read1(&mut uart).unwrap(), [5]);
165 }
29 166
30 info!("Test OK"); 167 info!("Test OK");
31 cortex_m::asm::bkpt(); 168 cortex_m::asm::bkpt();
diff --git a/tests/rp/src/bin/uart_buffered.rs b/tests/rp/src/bin/uart_buffered.rs
index bea9283e7..1deb22ce6 100644
--- a/tests/rp/src/bin/uart_buffered.rs
+++ b/tests/rp/src/bin/uart_buffered.rs
@@ -2,39 +2,248 @@
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait)] 3#![feature(type_alias_impl_trait)]
4 4
5use defmt::{assert_eq, *}; 5use defmt::{assert_eq, panic, *};
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_rp::gpio::{Level, Output};
7use embassy_rp::interrupt; 8use embassy_rp::interrupt;
8use embassy_rp::uart::{BufferedUart, Config}; 9use embassy_rp::uart::{BufferedUart, BufferedUartRx, Config, Error, Instance, Parity};
9use embedded_io::asynch::{Read, Write}; 10use embassy_time::{Duration, Timer};
11use embedded_io::asynch::{Read, ReadExactError, Write};
10use {defmt_rtt as _, panic_probe as _}; 12use {defmt_rtt as _, panic_probe as _};
11 13
14async fn read<const N: usize>(uart: &mut BufferedUart<'_, impl Instance>) -> Result<[u8; N], Error> {
15 let mut buf = [255; N];
16 match uart.read_exact(&mut buf).await {
17 Ok(()) => Ok(buf),
18 // we should not ever produce an Eof condition
19 Err(ReadExactError::UnexpectedEof) => panic!(),
20 Err(ReadExactError::Other(e)) => Err(e),
21 }
22}
23
24async fn read1<const N: usize>(uart: &mut BufferedUartRx<'_, impl Instance>) -> Result<[u8; N], Error> {
25 let mut buf = [255; N];
26 match uart.read_exact(&mut buf).await {
27 Ok(()) => Ok(buf),
28 // we should not ever produce an Eof condition
29 Err(ReadExactError::UnexpectedEof) => panic!(),
30 Err(ReadExactError::Other(e)) => Err(e),
31 }
32}
33
34async fn send(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, parity: Option<bool>) {
35 pin.set_low();
36 Timer::after(Duration::from_millis(1)).await;
37 for i in 0..8 {
38 if v & (1 << i) == 0 {
39 pin.set_low();
40 } else {
41 pin.set_high();
42 }
43 Timer::after(Duration::from_millis(1)).await;
44 }
45 if let Some(b) = parity {
46 if b {
47 pin.set_high();
48 } else {
49 pin.set_low();
50 }
51 Timer::after(Duration::from_millis(1)).await;
52 }
53 pin.set_high();
54 Timer::after(Duration::from_millis(1)).await;
55}
56
12#[embassy_executor::main] 57#[embassy_executor::main]
13async fn main(_spawner: Spawner) { 58async fn main(_spawner: Spawner) {
14 let p = embassy_rp::init(Default::default()); 59 let p = embassy_rp::init(Default::default());
15 info!("Hello World!"); 60 info!("Hello World!");
16 61
17 let (tx, rx, uart) = (p.PIN_0, p.PIN_1, p.UART0); 62 let (mut tx, mut rx, mut uart) = (p.PIN_0, p.PIN_1, p.UART0);
63 let mut irq = interrupt::take!(UART0_IRQ);
64
65 {
66 let config = Config::default();
67 let tx_buf = &mut [0u8; 16];
68 let rx_buf = &mut [0u8; 16];
69 let mut uart = BufferedUart::new(&mut uart, &mut irq, &mut tx, &mut rx, tx_buf, rx_buf, config);
70
71 // Make sure we send more bytes than fits in the FIFO, to test the actual
72 // bufferedUart.
73
74 let data = [
75 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
76 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
77 ];
78 uart.write_all(&data).await.unwrap();
79 info!("Done writing");
80
81 assert_eq!(read(&mut uart).await.unwrap(), data);
82 }
83
84 info!("test overflow detection");
85 {
86 let config = Config::default();
87 let tx_buf = &mut [0u8; 16];
88 let rx_buf = &mut [0u8; 16];
89 let mut uart = BufferedUart::new(&mut uart, &mut irq, &mut tx, &mut rx, tx_buf, rx_buf, config);
90
91 // Make sure we send more bytes than fits in the FIFO, to test the actual
92 // bufferedUart.
93
94 let data = [
95 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
96 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
97 ];
98 let overflow = [
99 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
100 ];
101 // give each block time to settle into the fifo. we want the overrun to occur at a well-defined point.
102 uart.write_all(&data).await.unwrap();
103 uart.blocking_flush().unwrap();
104 while uart.busy() {}
105 uart.write_all(&overflow).await.unwrap();
106 uart.blocking_flush().unwrap();
107 while uart.busy() {}
108
109 // already buffered/fifod prefix is valid
110 assert_eq!(read(&mut uart).await.unwrap(), data);
111 // next received character causes overrun error and is discarded
112 uart.write_all(&[1, 2, 3]).await.unwrap();
113 uart.blocking_flush().unwrap();
114 assert_eq!(read::<1>(&mut uart).await.unwrap_err(), Error::Overrun);
115 assert_eq!(read(&mut uart).await.unwrap(), [2, 3]);
116 }
117
118 info!("test break detection");
119 {
120 let mut config = Config::default();
121 config.baudrate = 1000;
122 let tx_buf = &mut [0u8; 16];
123 let rx_buf = &mut [0u8; 16];
124 let mut uart = BufferedUart::new(&mut uart, &mut irq, &mut tx, &mut rx, tx_buf, rx_buf, config);
125
126 // break on empty buffer
127 uart.send_break(20).await;
128 assert_eq!(read::<1>(&mut uart).await.unwrap_err(), Error::Break);
129 uart.write_all(&[64]).await.unwrap();
130 assert_eq!(read(&mut uart).await.unwrap(), [64]);
131
132 // break on partially filled buffer
133 uart.write_all(&[65; 2]).await.unwrap();
134 uart.send_break(20).await;
135 uart.write_all(&[66]).await.unwrap();
136 assert_eq!(read(&mut uart).await.unwrap(), [65; 2]);
137 assert_eq!(read::<1>(&mut uart).await.unwrap_err(), Error::Break);
138 assert_eq!(read(&mut uart).await.unwrap(), [66]);
139
140 // break on full buffer
141 uart.write_all(&[64; 16]).await.unwrap();
142 uart.send_break(20).await;
143 uart.write_all(&[65]).await.unwrap();
144 assert_eq!(read(&mut uart).await.unwrap(), [64; 16]);
145 assert_eq!(read::<1>(&mut uart).await.unwrap_err(), Error::Break);
146 assert_eq!(read(&mut uart).await.unwrap(), [65]);
147 }
148
149 // parity detection. here we bitbang to not require two uarts.
150 info!("test parity error detection");
151 {
152 let mut pin = Output::new(&mut tx, Level::High);
153 // choose a very slow baud rate to make tests reliable even with O0
154 let mut config = Config::default();
155 config.baudrate = 1000;
156 config.parity = Parity::ParityEven;
157 let rx_buf = &mut [0u8; 16];
158 let mut uart = BufferedUartRx::new(&mut uart, &mut irq, &mut rx, rx_buf, config);
159
160 async fn chr(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, parity: u32) {
161 send(pin, v, Some(parity != 0)).await;
162 }
163
164 // first check that we can send correctly
165 chr(&mut pin, 64, 1).await;
166 assert_eq!(read1(&mut uart).await.unwrap(), [64]);
167
168 // parity on empty buffer
169 chr(&mut pin, 64, 0).await;
170 chr(&mut pin, 4, 1).await;
171 assert_eq!(read1::<1>(&mut uart).await.unwrap_err(), Error::Parity);
172 assert_eq!(read1(&mut uart).await.unwrap(), [4]);
173
174 // parity on partially filled buffer
175 chr(&mut pin, 64, 1).await;
176 chr(&mut pin, 32, 1).await;
177 chr(&mut pin, 64, 0).await;
178 chr(&mut pin, 65, 0).await;
179 assert_eq!(read1(&mut uart).await.unwrap(), [64, 32]);
180 assert_eq!(read1::<1>(&mut uart).await.unwrap_err(), Error::Parity);
181 assert_eq!(read1(&mut uart).await.unwrap(), [65]);
182
183 // parity on full buffer
184 for i in 0..16 {
185 chr(&mut pin, i, i.count_ones() % 2).await;
186 }
187 chr(&mut pin, 64, 0).await;
188 chr(&mut pin, 65, 0).await;
189 assert_eq!(
190 read1(&mut uart).await.unwrap(),
191 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
192 );
193 assert_eq!(read1::<1>(&mut uart).await.unwrap_err(), Error::Parity);
194 assert_eq!(read1(&mut uart).await.unwrap(), [65]);
195 }
196
197 // framing error detection. here we bitbang because there's no other way.
198 info!("test framing error detection");
199 {
200 let mut pin = Output::new(&mut tx, Level::High);
201 // choose a very slow baud rate to make tests reliable even with O0
202 let mut config = Config::default();
203 config.baudrate = 1000;
204 let rx_buf = &mut [0u8; 16];
205 let mut uart = BufferedUartRx::new(&mut uart, &mut irq, &mut rx, rx_buf, config);
206
207 async fn chr(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, good: bool) {
208 if good {
209 send(pin, v, None).await;
210 } else {
211 send(pin, v, Some(false)).await;
212 }
213 }
18 214
19 let config = Config::default(); 215 // first check that we can send correctly
20 let irq = interrupt::take!(UART0_IRQ); 216 chr(&mut pin, 64, true).await;
21 let tx_buf = &mut [0u8; 16]; 217 assert_eq!(read1(&mut uart).await.unwrap(), [64]);
22 let rx_buf = &mut [0u8; 16];
23 let mut uart = BufferedUart::new(uart, irq, tx, rx, tx_buf, rx_buf, config);
24 218
25 // Make sure we send more bytes than fits in the FIFO, to test the actual 219 // framing on empty buffer
26 // bufferedUart. 220 chr(&mut pin, 64, false).await;
221 assert_eq!(read1::<1>(&mut uart).await.unwrap_err(), Error::Framing);
222 chr(&mut pin, 65, true).await;
223 assert_eq!(read1(&mut uart).await.unwrap(), [65]);
27 224
28 let data = [ 225 // framing on partially filled buffer
29 1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 226 chr(&mut pin, 64, true).await;
30 30, 31, 227 chr(&mut pin, 32, true).await;
31 ]; 228 chr(&mut pin, 64, false).await;
32 uart.write_all(&data).await.unwrap(); 229 chr(&mut pin, 65, true).await;
33 info!("Done writing"); 230 assert_eq!(read1(&mut uart).await.unwrap(), [64, 32]);
231 assert_eq!(read1::<1>(&mut uart).await.unwrap_err(), Error::Framing);
232 assert_eq!(read1(&mut uart).await.unwrap(), [65]);
34 233
35 let mut buf = [0; 31]; 234 // framing on full buffer
36 uart.read_exact(&mut buf).await.unwrap(); 235 for i in 0..16 {
37 assert_eq!(buf, data); 236 chr(&mut pin, i, true).await;
237 }
238 chr(&mut pin, 64, false).await;
239 chr(&mut pin, 65, true).await;
240 assert_eq!(
241 read1(&mut uart).await.unwrap(),
242 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
243 );
244 assert_eq!(read1::<1>(&mut uart).await.unwrap_err(), Error::Framing);
245 assert_eq!(read1(&mut uart).await.unwrap(), [65]);
246 }
38 247
39 info!("Test OK"); 248 info!("Test OK");
40 cortex_m::asm::bkpt(); 249 cortex_m::asm::bkpt();
diff --git a/tests/rp/src/bin/uart_dma.rs b/tests/rp/src/bin/uart_dma.rs
index 963c22707..92aa205c9 100644
--- a/tests/rp/src/bin/uart_dma.rs
+++ b/tests/rp/src/bin/uart_dma.rs
@@ -4,28 +4,246 @@
4 4
5use defmt::{assert_eq, *}; 5use defmt::{assert_eq, *};
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_rp::uart::{Config, Uart}; 7use embassy_rp::gpio::{Level, Output};
8use embassy_rp::interrupt;
9use embassy_rp::uart::{Async, Config, Error, Instance, Parity, Uart, UartRx};
10use embassy_time::{Duration, Timer};
8use {defmt_rtt as _, panic_probe as _}; 11use {defmt_rtt as _, panic_probe as _};
9 12
13async fn read<const N: usize>(uart: &mut Uart<'_, impl Instance, Async>) -> Result<[u8; N], Error> {
14 let mut buf = [255; N];
15 uart.read(&mut buf).await?;
16 Ok(buf)
17}
18
19async fn read1<const N: usize>(uart: &mut UartRx<'_, impl Instance, Async>) -> Result<[u8; N], Error> {
20 let mut buf = [255; N];
21 uart.read(&mut buf).await?;
22 Ok(buf)
23}
24
25async fn send(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, parity: Option<bool>) {
26 pin.set_low();
27 Timer::after(Duration::from_millis(1)).await;
28 for i in 0..8 {
29 if v & (1 << i) == 0 {
30 pin.set_low();
31 } else {
32 pin.set_high();
33 }
34 Timer::after(Duration::from_millis(1)).await;
35 }
36 if let Some(b) = parity {
37 if b {
38 pin.set_high();
39 } else {
40 pin.set_low();
41 }
42 Timer::after(Duration::from_millis(1)).await;
43 }
44 pin.set_high();
45 Timer::after(Duration::from_millis(1)).await;
46}
47
10#[embassy_executor::main] 48#[embassy_executor::main]
11async fn main(_spawner: Spawner) { 49async fn main(_spawner: Spawner) {
12 let p = embassy_rp::init(Default::default()); 50 let mut p = embassy_rp::init(Default::default());
13 info!("Hello World!"); 51 info!("Hello World!");
14 52
15 let (tx, rx, uart) = (p.PIN_0, p.PIN_1, p.UART0); 53 let (mut tx, mut rx, mut uart) = (p.PIN_0, p.PIN_1, p.UART0);
54 let mut irq = interrupt::take!(UART0_IRQ);
16 55
17 let config = Config::default(); 56 // TODO
18 let mut uart = Uart::new(uart, tx, rx, p.DMA_CH0, p.DMA_CH1, config); 57 // nuclear error reporting. just abort the entire transfer and invalidate the
58 // dma buffer, buffered buffer, fifo etc.
19 59
20 // We can't send too many bytes, they have to fit in the FIFO. 60 // We can't send too many bytes, they have to fit in the FIFO.
21 // This is because we aren't sending+receiving at the same time. 61 // This is because we aren't sending+receiving at the same time.
62 {
63 let config = Config::default();
64 let mut uart = Uart::new(
65 &mut uart,
66 &mut tx,
67 &mut rx,
68 &mut irq,
69 &mut p.DMA_CH0,
70 &mut p.DMA_CH1,
71 config,
72 );
73
74 let data = [0xC0, 0xDE];
75 uart.write(&data).await.unwrap();
76
77 let mut buf = [0; 2];
78 uart.read(&mut buf).await.unwrap();
79 assert_eq!(buf, data);
80 }
81
82 info!("test overflow detection");
83 {
84 let config = Config::default();
85 let mut uart = Uart::new(
86 &mut uart,
87 &mut tx,
88 &mut rx,
89 &mut irq,
90 &mut p.DMA_CH0,
91 &mut p.DMA_CH1,
92 config,
93 );
94
95 uart.blocking_write(&[42; 32]).unwrap();
96 uart.blocking_write(&[1, 2, 3]).unwrap();
97 uart.blocking_flush().unwrap();
98
99 // can receive regular fifo contents
100 assert_eq!(read(&mut uart).await, Ok([42; 16]));
101 assert_eq!(read(&mut uart).await, Ok([42; 16]));
102 // receiving the rest fails with overrun
103 assert_eq!(read::<16>(&mut uart).await, Err(Error::Overrun));
104 // new data is accepted, latest overrunning byte first
105 assert_eq!(read(&mut uart).await, Ok([3]));
106 uart.blocking_write(&[8, 9]).unwrap();
107 Timer::after(Duration::from_millis(1)).await;
108 assert_eq!(read(&mut uart).await, Ok([8, 9]));
109 }
110
111 info!("test break detection");
112 {
113 let config = Config::default();
114 let (mut tx, mut rx) = Uart::new(
115 &mut uart,
116 &mut tx,
117 &mut rx,
118 &mut irq,
119 &mut p.DMA_CH0,
120 &mut p.DMA_CH1,
121 config,
122 )
123 .split();
124
125 // break before read
126 tx.send_break(20).await;
127 tx.write(&[64]).await.unwrap();
128 assert_eq!(read1::<1>(&mut rx).await.unwrap_err(), Error::Break);
129 assert_eq!(read1(&mut rx).await.unwrap(), [64]);
130
131 // break during read
132 {
133 let r = read1::<2>(&mut rx);
134 tx.write(&[2]).await.unwrap();
135 tx.send_break(20).await;
136 tx.write(&[3]).await.unwrap();
137 assert_eq!(r.await.unwrap_err(), Error::Break);
138 assert_eq!(read1(&mut rx).await.unwrap(), [3]);
139 }
140
141 // break after read
142 {
143 let r = read1(&mut rx);
144 tx.write(&[2]).await.unwrap();
145 tx.send_break(20).await;
146 tx.write(&[3]).await.unwrap();
147 assert_eq!(r.await.unwrap(), [2]);
148 assert_eq!(read1::<1>(&mut rx).await.unwrap_err(), Error::Break);
149 assert_eq!(read1(&mut rx).await.unwrap(), [3]);
150 }
151 }
152
153 // parity detection. here we bitbang to not require two uarts.
154 info!("test parity error detection");
155 {
156 let mut pin = Output::new(&mut tx, Level::High);
157 // choose a very slow baud rate to make tests reliable even with O0
158 let mut config = Config::default();
159 config.baudrate = 1000;
160 config.parity = Parity::ParityEven;
161 let mut uart = UartRx::new(&mut uart, &mut rx, &mut irq, &mut p.DMA_CH0, config);
162
163 async fn chr(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, parity: u32) {
164 send(pin, v, Some(parity != 0)).await;
165 }
166
167 // first check that we can send correctly
168 chr(&mut pin, 32, 1).await;
169 assert_eq!(read1(&mut uart).await.unwrap(), [32]);
170
171 // parity error before read
172 chr(&mut pin, 32, 0).await;
173 chr(&mut pin, 31, 1).await;
174 assert_eq!(read1::<1>(&mut uart).await.unwrap_err(), Error::Parity);
175 assert_eq!(read1(&mut uart).await.unwrap(), [31]);
176
177 // parity error during read
178 {
179 let r = read1::<2>(&mut uart);
180 chr(&mut pin, 2, 1).await;
181 chr(&mut pin, 32, 0).await;
182 chr(&mut pin, 3, 0).await;
183 assert_eq!(r.await.unwrap_err(), Error::Parity);
184 assert_eq!(read1(&mut uart).await.unwrap(), [3]);
185 }
186
187 // parity error after read
188 {
189 let r = read1(&mut uart);
190 chr(&mut pin, 2, 1).await;
191 chr(&mut pin, 32, 0).await;
192 chr(&mut pin, 3, 0).await;
193 assert_eq!(r.await.unwrap(), [2]);
194 assert_eq!(read1::<1>(&mut uart).await.unwrap_err(), Error::Parity);
195 assert_eq!(read1(&mut uart).await.unwrap(), [3]);
196 }
197 }
198
199 // framing error detection. here we bitbang because there's no other way.
200 info!("test framing error detection");
201 {
202 let mut pin = Output::new(&mut tx, Level::High);
203 // choose a very slow baud rate to make tests reliable even with O0
204 let mut config = Config::default();
205 config.baudrate = 1000;
206 let mut uart = UartRx::new(&mut uart, &mut rx, &mut irq, &mut p.DMA_CH0, config);
207
208 async fn chr(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, good: bool) {
209 if good {
210 send(pin, v, None).await;
211 } else {
212 send(pin, v, Some(false)).await;
213 }
214 }
215
216 // first check that we can send correctly
217 chr(&mut pin, 32, true).await;
218 assert_eq!(read1(&mut uart).await.unwrap(), [32]);
219
220 // parity error before read
221 chr(&mut pin, 32, false).await;
222 chr(&mut pin, 31, true).await;
223 assert_eq!(read1::<1>(&mut uart).await.unwrap_err(), Error::Framing);
224 assert_eq!(read1(&mut uart).await.unwrap(), [31]);
22 225
23 let data = [0xC0, 0xDE]; 226 // parity error during read
24 uart.write(&data).await.unwrap(); 227 {
228 let r = read1::<2>(&mut uart);
229 chr(&mut pin, 2, true).await;
230 chr(&mut pin, 32, false).await;
231 chr(&mut pin, 3, true).await;
232 assert_eq!(r.await.unwrap_err(), Error::Framing);
233 assert_eq!(read1(&mut uart).await.unwrap(), [3]);
234 }
25 235
26 let mut buf = [0; 2]; 236 // parity error after read
27 uart.read(&mut buf).await.unwrap(); 237 {
28 assert_eq!(buf, data); 238 let r = read1(&mut uart);
239 chr(&mut pin, 2, true).await;
240 chr(&mut pin, 32, false).await;
241 chr(&mut pin, 3, true).await;
242 assert_eq!(r.await.unwrap(), [2]);
243 assert_eq!(read1::<1>(&mut uart).await.unwrap_err(), Error::Framing);
244 assert_eq!(read1(&mut uart).await.unwrap(), [3]);
245 }
246 }
29 247
30 info!("Test OK"); 248 info!("Test OK");
31 cortex_m::asm::bkpt(); 249 cortex_m::asm::bkpt();