1use crate::peripherals::{Uart0, Uart1, Uart2};
8use core::marker::PhantomData;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum DataBits {
12 Five,
13 Six,
14 Seven,
15 Eight,
16}
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
19pub enum Parity {
20 None,
21 Even,
22 Odd,
23}
24
25#[derive(Debug, Clone, Copy, PartialEq, Eq)]
26pub enum StopBits {
27 One,
28 Two,
29}
30
31#[derive(Debug, Clone, Copy)]
32pub struct Config {
33 pub baudrate: u32,
34 pub data_bits: DataBits,
35 pub parity: Parity,
36 pub stop_bits: StopBits,
37}
38
39impl Default for Config {
40 fn default() -> Self {
41 Self { baudrate: 115200, data_bits: DataBits::Eight, parity: Parity::None, stop_bits: StopBits::One }
42 }
43}
44
45pub struct Uart<'d, T> {
46 _peripheral: PhantomData<&'d T>,
47}
48
49#[allow(dead_code)]
50fn regs() -> &'static ws63_pac::uart0::RegisterBlock {
51 unsafe { &*Uart0::ptr() }
53}
54
55fn uart_ptr(idx: u8) -> *const ws63_pac::uart0::RegisterBlock {
56 match idx {
57 0 => Uart0::ptr(),
58 1 => Uart1::ptr(),
59 2 => Uart2::ptr(),
60 _ => unreachable!(),
61 }
62}
63
64fn uart_regs(idx: u8) -> &'static ws63_pac::uart0::RegisterBlock {
65 unsafe { &*uart_ptr(idx) }
67}
68
69impl<'d> Uart<'d, Uart0<'d>> {
70 pub fn new_uart0(_uart: Uart0<'d>, config: Config) -> Self {
71 configure_uart(0, &config);
72 Self { _peripheral: PhantomData }
73 }
74}
75
76impl<'d> Uart<'d, Uart1<'d>> {
77 pub fn new_uart1(_uart: Uart1<'d>, config: Config) -> Self {
78 configure_uart(1, &config);
79 Self { _peripheral: PhantomData }
80 }
81}
82
83impl<'d> Uart<'d, Uart2<'d>> {
84 pub fn new_uart2(_uart: Uart2<'d>, config: Config) -> Self {
85 configure_uart(2, &config);
86 Self { _peripheral: PhantomData }
87 }
88}
89
90fn configure_uart(idx: u8, config: &Config) {
91 let r = uart_regs(idx);
92
93 r.uart_ctl().modify(|_, w| unsafe { w.bits(0) });
95 r.uart_ctl().write(|w| w.div_en().set_bit());
96
97 let pclk = crate::soc::ws63::UART_CLOCK_HZ;
101 let min_baud = (pclk / (16 * 65535)) + 1;
102 let baudrate = if config.baudrate < min_baud { min_baud } else { config.baudrate };
103 let div = pclk / (16 * baudrate);
104 let div_l = (div & 0xFF) as u16;
105 let div_h = ((div >> 8) & 0xFF) as u16;
106 r.div_l().write(|w| unsafe { w.bits(div_l) });
107 r.div_h().write(|w| unsafe { w.bits(div_h) });
108 r.div_fra().write(|w| unsafe { w.bits(0) });
109
110 let mut ctl = 0u16;
112 ctl |= match config.data_bits {
113 DataBits::Five => 0,
114 DataBits::Six => 1 << 2,
115 DataBits::Seven => 2 << 2,
116 DataBits::Eight => 3 << 2,
117 };
118 match config.parity {
119 Parity::Even => {
120 ctl |= 1 << 5;
121 ctl |= 1 << 4;
122 }
123 Parity::Odd => {
124 ctl |= 1 << 5;
125 }
126 Parity::None => {}
127 }
128 if matches!(config.stop_bits, StopBits::Two) {
129 ctl |= 1 << 7;
130 }
131 r.uart_ctl().write(|w| unsafe { w.bits(ctl | (1 << 0)) }); r.fifo_ctl().write(|w| unsafe { w.bits(0x01) });
135
136 r.fifo_ctl().write(|w| unsafe { w.bits(0x07) });
138}
139
140impl<T> Uart<'_, T> {
141 pub fn write_byte(&self, idx: u8, byte: u8) {
142 let r = uart_regs(idx);
143 while r.fifo_status().read().tx_fifo_full().bit_is_set() {}
144 r.data().write(|w| unsafe { w.bits(byte as u16) });
145 }
146
147 pub fn read_byte(&self, idx: u8) -> Option<u8> {
148 let r = uart_regs(idx);
149 if r.fifo_status().read().rx_fifo_empty().bit_is_set() { None } else { Some(r.data().read().bits() as u8) }
150 }
151
152 pub fn flush_tx(&self, idx: u8) {
153 let r = uart_regs(idx);
154 while !r.fifo_status().read().tx_fifo_empty().bit_is_set() {}
155 }
156
157 pub fn tx_flushed(&self, idx: u8) -> bool {
159 uart_regs(idx).fifo_status().read().tx_fifo_empty().bit_is_set()
160 }
161
162 pub fn write(&self, idx: u8, data: &[u8]) {
163 for &b in data {
164 self.write_byte(idx, b);
165 }
166 }
167
168 pub fn uart_regs(&self, idx: u8) -> &'static ws63_pac::uart0::RegisterBlock {
169 uart_regs(idx)
170 }
171}
172
173impl embedded_io::ErrorType for Uart<'_, Uart0<'_>> {
174 type Error = core::convert::Infallible;
175}
176impl embedded_io::Write for Uart<'_, Uart0<'_>> {
177 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
178 for &b in buf {
179 self.write_byte(0, b);
180 }
181 Ok(buf.len())
182 }
183 fn flush(&mut self) -> Result<(), Self::Error> {
184 self.flush_tx(0);
185 Ok(())
186 }
187}
188impl embedded_io::Read for Uart<'_, Uart0<'_>> {
189 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
190 let mut n = 0;
191 for b in buf.iter_mut() {
192 if let Some(byte) = self.read_byte(0) {
193 *b = byte;
194 n += 1;
195 } else {
196 break;
197 }
198 }
199 Ok(n)
200 }
201}
202
203impl embedded_io::ErrorType for Uart<'_, Uart1<'_>> {
205 type Error = core::convert::Infallible;
206}
207impl embedded_io::Write for Uart<'_, Uart1<'_>> {
208 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
209 for &b in buf {
210 self.write_byte(1, b);
211 }
212 Ok(buf.len())
213 }
214 fn flush(&mut self) -> Result<(), Self::Error> {
215 self.flush_tx(1);
216 Ok(())
217 }
218}
219impl embedded_io::Read for Uart<'_, Uart1<'_>> {
220 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
221 let mut n = 0;
222 for b in buf.iter_mut() {
223 if let Some(byte) = self.read_byte(1) {
224 *b = byte;
225 n += 1;
226 } else {
227 break;
228 }
229 }
230 Ok(n)
231 }
232}
233
234impl embedded_io::ErrorType for Uart<'_, Uart2<'_>> {
236 type Error = core::convert::Infallible;
237}
238impl embedded_io::Write for Uart<'_, Uart2<'_>> {
239 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
240 for &b in buf {
241 self.write_byte(2, b);
242 }
243 Ok(buf.len())
244 }
245 fn flush(&mut self) -> Result<(), Self::Error> {
246 self.flush_tx(2);
247 Ok(())
248 }
249}
250impl embedded_io::Read for Uart<'_, Uart2<'_>> {
251 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
252 let mut n = 0;
253 for b in buf.iter_mut() {
254 if let Some(byte) = self.read_byte(2) {
255 *b = byte;
256 n += 1;
257 } else {
258 break;
259 }
260 }
261 Ok(n)
262 }
263}
264
265macro_rules! impl_nb_serial {
268 ($uart:ty, $idx:expr) => {
269 impl embedded_hal_nb::serial::ErrorType for Uart<'_, $uart> {
270 type Error = core::convert::Infallible;
271 }
272 impl embedded_hal_nb::serial::Read for Uart<'_, $uart> {
273 fn read(&mut self) -> nb::Result<u8, Self::Error> {
274 match self.read_byte($idx) {
275 Some(b) => Ok(b),
276 None => Err(nb::Error::WouldBlock),
277 }
278 }
279 }
280 impl embedded_hal_nb::serial::Write for Uart<'_, $uart> {
281 fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
282 self.write_byte($idx, byte);
283 Ok(())
284 }
285 fn flush(&mut self) -> nb::Result<(), Self::Error> {
286 if self.tx_flushed($idx) { Ok(()) } else { Err(nb::Error::WouldBlock) }
287 }
288 }
289 };
290}
291
292impl_nb_serial!(Uart0<'_>, 0);
293impl_nb_serial!(Uart1<'_>, 1);
294impl_nb_serial!(Uart2<'_>, 2);
295
296#[cfg(feature = "async")]
298mod asynch_impl {
299 use super::{Uart, uart_regs};
300 use crate::asynch::IrqSignal;
301 use crate::peripherals::{Uart0, Uart1, Uart2};
302 use core::cell::Cell;
303 use core::future::Future;
304 use core::pin::Pin;
305 use core::task::{Context, Poll};
306 use critical_section::Mutex;
307 use embedded_io_async::{Read, Write};
308
309 static UART_RX: [IrqSignal; 3] = [IrqSignal::new(), IrqSignal::new(), IrqSignal::new()];
310 static UART_BYTE: [Mutex<Cell<u8>>; 3] = [const { Mutex::new(Cell::new(0)) }; 3];
311
312 fn uart_base(idx: u8) -> usize {
313 match idx {
314 0 => 0x4401_0000,
315 1 => 0x4401_1000,
316 _ => 0x4401_2000,
317 }
318 }
319
320 pub fn on_interrupt(idx: u8) {
324 let r = uart_regs(idx);
325 if !r.fifo_status().read().rx_fifo_empty().bit_is_set() {
326 let b = r.data().read().bits() as u8;
327 critical_section::with(|cs| UART_BYTE[idx as usize].borrow(cs).set(b));
328 UART_RX[idx as usize].signal();
329 }
330 }
331
332 struct RxFuture {
333 idx: u8,
334 }
335 impl Future for RxFuture {
336 type Output = ();
337 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
338 if UART_RX[self.idx as usize].take_fired() {
339 Poll::Ready(())
340 } else {
341 UART_RX[self.idx as usize].register(cx.waker());
342 Poll::Pending
343 }
344 }
345 }
346
347 async fn read_one(uart: &Uart<'_, impl Sized>, idx: u8) -> u8 {
348 let r = uart_regs(idx);
349 if !r.fifo_status().read().rx_fifo_empty().bit_is_set() {
350 return r.data().read().bits() as u8; }
352 UART_RX[idx as usize].reset();
353 unsafe { core::ptr::write_volatile((uart_base(idx) + 0x18) as *mut u32, 1) };
355 let _ = uart; RxFuture { idx }.await;
357 critical_section::with(|cs| UART_BYTE[idx as usize].borrow(cs).get())
358 }
359
360 macro_rules! async_uart {
361 ($uart:ty, $idx:expr) => {
362 impl Write for Uart<'_, $uart> {
365 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
366 for &b in buf {
369 self.write_byte($idx, b);
370 }
371 Ok(buf.len())
372 }
373 async fn flush(&mut self) -> Result<(), Self::Error> {
374 self.flush_tx($idx);
375 Ok(())
376 }
377 }
378 impl Read for Uart<'_, $uart> {
379 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
380 if buf.is_empty() {
381 return Ok(0);
382 }
383 buf[0] = read_one(self, $idx).await;
384 Ok(1)
385 }
386 }
387 };
388 }
389 async_uart!(Uart0<'_>, 0);
390 async_uart!(Uart1<'_>, 1);
391 async_uart!(Uart2<'_>, 2);
392}
393
394#[cfg(feature = "async")]
395pub use asynch_impl::on_interrupt;