1use crate::pac;
2use core::task::Poll;
3use embassy_embedded_hal::SetConfig;
4use paste::paste;
5
6pub trait UartPeripheral: crate::Peripheral {
7 #[doc(hidden)]
8 fn address(&self) -> *mut pac::mss_uart_instance_t;
9 #[doc(hidden)]
10 fn number(&self) -> u8;
11}
12
13pub trait UartRxPeripheral: crate::Peripheral + UartPeripheral {}
14
15pub trait UartTxPeripheral: crate::Peripheral + UartPeripheral {}
16
17macro_rules! impl_uart {
21 ($n:expr) => {
22 paste! {
23 impl_uart!([<Uart $n>], [<UartRx $n>], [<UartTx $n>], [<UART_RX_TAKEN $n>], [<UART_TX_TAKEN $n>], $n, [<g_mss_uart $n _lo>]);
24 }
25 };
26
27 ($UART:ident, $UART_RX:ident, $UART_TX:ident, $UART_RX_TAKEN:ident, $UART_TX_TAKEN:ident, $num:expr, $instance:ident) => {
29 pub struct $UART {
30 _private: (),
31 }
32
33 pub struct $UART_RX {
34 _private: (),
35 }
36
37 pub struct $UART_TX {
38 _private: (),
39 }
40
41 static mut $UART_RX_TAKEN: bool = false;
42 static mut $UART_TX_TAKEN: bool = false;
43
44 impl crate::Peripheral for $UART {
45 fn take() -> Option<Self> {
46 critical_section::with(|_| unsafe {
47 if $UART_RX_TAKEN || $UART_TX_TAKEN {
48 None
49 } else {
50 $UART_RX_TAKEN = true;
51 $UART_TX_TAKEN = true;
52 Some(Self { _private: () })
53 }
54 })
55 }
56
57 unsafe fn steal() -> Self {
58 Self { _private: () }
59 }
60 }
61
62 impl crate::Peripheral for $UART_RX {
63 fn take() -> Option<Self> {
64 critical_section::with(|_| unsafe {
65 if $UART_RX_TAKEN {
66 None
67 } else {
68 $UART_RX_TAKEN = true;
69 Some(Self { _private: () })
70 }
71 })
72 }
73
74 unsafe fn steal() -> Self {
75 Self { _private: () }
76 }
77 }
78
79 impl crate::Peripheral for $UART_TX {
80 fn take() -> Option<Self> {
81 critical_section::with(|_| unsafe {
82 if $UART_TX_TAKEN {
83 None
84 } else {
85 $UART_TX_TAKEN = true;
86 Some(Self { _private: () })
87 }
88 })
89 }
90
91 unsafe fn steal() -> Self {
92 Self { _private: () }
93 }
94 }
95
96 impl UartPeripheral for $UART {
97 fn address(&self) -> *mut pac::mss_uart_instance_t {
98 &raw mut pac::$instance
99 }
100
101 fn number(&self) -> u8 {
102 $num
103 }
104 }
105
106 impl UartPeripheral for $UART_RX {
107 fn address(&self) -> *mut pac::mss_uart_instance_t {
108 &raw mut pac::$instance
109 }
110
111 fn number(&self) -> u8 {
112 $num
113 }
114 }
115
116 impl UartRxPeripheral for $UART_RX {}
117
118 impl UartPeripheral for $UART_TX {
119 fn address(&self) -> *mut pac::mss_uart_instance_t {
120 &raw mut pac::$instance
121 }
122
123 fn number(&self) -> u8 {
124 $num
125 }
126 }
127
128 impl UartTxPeripheral for $UART_TX {}
129 };
130}
131
132macro_rules! impl_uarts {
133 ($($n:expr),*) => {
134 $(impl_uart!($n);)*
135 };
136}
137
138impl_uarts!(0, 1, 2, 3, 4);
140
141#[derive(Debug, Clone, Copy, PartialEq)]
145pub struct UartConfig {
146 pub baud_rate: BaudRate,
147 pub data_bits: DataBits,
148 pub stop_bits: StopBits,
149 pub parity: Parity,
150}
151
152impl Default for UartConfig {
153 fn default() -> Self {
154 Self {
155 baud_rate: BaudRate::Baud115200,
156 data_bits: DataBits::Data8,
157 stop_bits: StopBits::One,
158 parity: Parity::NoParity,
159 }
160 }
161}
162
163#[derive(Debug, Clone, Copy, PartialEq)]
164pub enum BaudRate {
165 Baud110,
166 Baud300,
167 Baud600,
168 Baud1200,
169 Baud2400,
170 Baud4800,
171 Baud9600,
172 Baud19200,
173 Baud38400,
174 Baud57600,
175 Baud115200,
176 Baud230400,
177 Baud460800,
178 Baud921600,
179 Custom(u32),
180}
181
182impl BaudRate {
183 pub fn value(&self) -> u32 {
184 match self {
185 BaudRate::Baud110 => pac::MSS_UART_110_BAUD,
186 BaudRate::Baud300 => pac::MSS_UART_300_BAUD,
187 BaudRate::Baud600 => pac::MSS_UART_600_BAUD,
188 BaudRate::Baud1200 => pac::MSS_UART_1200_BAUD,
189 BaudRate::Baud2400 => pac::MSS_UART_2400_BAUD,
190 BaudRate::Baud4800 => pac::MSS_UART_4800_BAUD,
191 BaudRate::Baud9600 => pac::MSS_UART_9600_BAUD,
192 BaudRate::Baud19200 => pac::MSS_UART_19200_BAUD,
193 BaudRate::Baud38400 => pac::MSS_UART_38400_BAUD,
194 BaudRate::Baud57600 => pac::MSS_UART_57600_BAUD,
195 BaudRate::Baud115200 => pac::MSS_UART_115200_BAUD,
196 BaudRate::Baud230400 => pac::MSS_UART_230400_BAUD,
197 BaudRate::Baud460800 => pac::MSS_UART_460800_BAUD,
198 BaudRate::Baud921600 => pac::MSS_UART_921600_BAUD,
199 BaudRate::Custom(value) => *value,
200 }
201 }
202}
203
204#[derive(Debug, Clone, Copy, PartialEq)]
205pub enum DataBits {
206 Data5,
207 Data6,
208 Data7,
209 Data8,
210}
211
212impl DataBits {
213 pub fn value(&self) -> u8 {
214 match self {
215 DataBits::Data5 => pac::MSS_UART_DATA_5_BITS,
216 DataBits::Data6 => pac::MSS_UART_DATA_6_BITS,
217 DataBits::Data7 => pac::MSS_UART_DATA_7_BITS,
218 DataBits::Data8 => pac::MSS_UART_DATA_8_BITS,
219 }
220 }
221}
222
223#[derive(Debug, Clone, Copy, PartialEq)]
224pub enum StopBits {
225 One,
226 OneHalf,
227 Two,
228}
229
230impl StopBits {
231 pub fn value(&self) -> u8 {
232 match self {
233 StopBits::One => pac::MSS_UART_ONE_STOP_BIT,
234 StopBits::OneHalf => pac::MSS_UART_ONEHALF_STOP_BIT,
235 StopBits::Two => pac::MSS_UART_TWO_STOP_BITS,
236 }
237 }
238}
239
240#[derive(Debug, Clone, Copy, PartialEq)]
241pub enum Parity {
242 NoParity,
243 OddParity,
244 EvenParity,
245 StickParity0,
246 StickParity1,
247}
248
249impl Parity {
250 pub fn value(&self) -> u8 {
251 match self {
252 Parity::NoParity => pac::MSS_UART_NO_PARITY,
253 Parity::OddParity => pac::MSS_UART_ODD_PARITY,
254 Parity::EvenParity => pac::MSS_UART_EVEN_PARITY,
255 Parity::StickParity0 => pac::MSS_UART_STICK_PARITY_0,
256 Parity::StickParity1 => pac::MSS_UART_STICK_PARITY_1,
257 }
258 }
259}
260
261pub(crate) fn init_uart() {
264 unsafe {
265 for i in 0..NUM_UARTS {
267 pac::mss_config_clk_rst(
268 i as u32,
269 pac::MPFS_HAL_FIRST_HART as u8,
270 pac::PERIPH_RESET_STATE__PERIPHERAL_ON,
271 );
272 }
273 }
274}
275
276unsafe fn init_uart_interrupt(num: usize) {
277 unsafe {
278 pac::PLIC_SetPriority(pac::PLIC_IRQn_Type_PLIC_MMUART0_INT_OFFSET + num as u32, 2);
280
281 let uart = match num {
282 0 => &raw mut pac::g_mss_uart0_lo,
283 1 => &raw mut pac::g_mss_uart1_lo,
284 2 => &raw mut pac::g_mss_uart2_lo,
285 3 => &raw mut pac::g_mss_uart3_lo,
286 4 => &raw mut pac::g_mss_uart4_lo,
287 _ => panic!("Invalid UART number"),
288 };
289 pac::MSS_UART_set_rx_handler(
290 uart,
291 Some(uart_rx_handler),
292 pac::mss_uart_rx_trig_level_t_MSS_UART_FIFO_SINGLE_BYTE,
293 );
294 pac::MSS_UART_enable_irq(uart, (pac::MSS_UART_RBF_IRQ | pac::MSS_UART_TBE_IRQ) as u16);
295 }
296}
297
298pub struct Uart<T: UartPeripheral> {
300 rx: UartRx<T>,
301 tx: UartTx<T>,
302}
303
304impl<T: UartPeripheral> Uart<T> {
305 pub fn new(peripheral: T, config: UartConfig) -> Self {
306 unsafe {
307 let mut uart = Uart {
308 rx: UartRx { peripheral },
309 tx: UartTx {
310 peripheral: T::steal(),
311 },
312 };
313 uart.set_config(&config).unwrap();
314 init_uart_interrupt(uart.rx.peripheral.number() as usize);
315 uart
316 }
317 }
318
319 pub fn split(self) -> (UartRx<T>, UartTx<T>) {
320 (self.rx, self.tx)
321 }
322}
323
324impl<T: UartPeripheral> SetConfig for Uart<T> {
325 type Config = UartConfig;
326 type ConfigError = ();
327 fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> {
328 unsafe {
329 pac::MSS_UART_init(
330 self.tx.peripheral.address(),
331 config.baud_rate.value(),
332 config.data_bits.value() | config.parity.value() | config.stop_bits.value(),
333 );
334 }
335 Ok(())
336 }
337}
338
339#[derive(Debug)]
340pub enum Error {
341 EmptyBuffer,
342}
343
344impl embedded_io::Error for Error {
345 fn kind(&self) -> embedded_io::ErrorKind {
346 embedded_io::ErrorKind::Other
347 }
348}
349
350impl<T: UartPeripheral> embedded_io::ErrorType for Uart<T> {
351 type Error = Error;
352}
353
354impl<T: UartPeripheral> embedded_io::Write for Uart<T> {
355 fn write(&mut self, buf: &[u8]) -> Result<usize, Error> {
356 self.tx.write(buf)
357 }
358
359 fn flush(&mut self) -> Result<(), Error> {
360 Ok(())
361 }
362}
363
364impl<T: UartPeripheral> embedded_io::Read for Uart<T> {
365 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
366 self.rx.read(buf)
367 }
368}
369
370impl<T: UartPeripheral> embedded_io_async::Read for Uart<T> {
371 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
372 self.rx.read(buf).await
373 }
374}
375
376pub struct UartTx<T: UartPeripheral> {
380 peripheral: T,
381}
382
383impl<TX: UartTxPeripheral> UartTx<TX> {
384 pub fn new(peripheral: TX, config: UartConfig) -> Self {
385 let mut uart = Self { peripheral };
386 uart.set_config(&config).unwrap();
387 uart
388 }
389}
390
391impl<T: UartPeripheral> embedded_io::ErrorType for UartTx<T> {
392 type Error = Error;
393}
394
395impl<T: UartPeripheral> embedded_io::Write for UartTx<T> {
396 fn write(&mut self, buf: &[u8]) -> Result<usize, Error> {
397 unsafe {
399 pac::MSS_UART_polled_tx(self.peripheral.address(), buf.as_ptr(), buf.len() as u32);
400 }
401 Ok(buf.len())
402 }
403
404 fn flush(&mut self) -> Result<(), Error> {
405 Ok(())
406 }
407}
408
409impl<T: UartPeripheral> SetConfig for UartTx<T> {
410 type Config = UartConfig;
411 type ConfigError = ();
412 fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> {
413 unsafe {
414 pac::MSS_UART_init(
415 self.peripheral.address(),
416 config.baud_rate.value(),
417 config.data_bits.value() | config.parity.value() | config.stop_bits.value(),
418 );
419 }
420 Ok(())
421 }
422}
423
424const NUM_UARTS: usize = 5;
427const RX_BUF_SIZE: usize = 128;
428
429static mut RX_BUF: [[u8; RX_BUF_SIZE]; NUM_UARTS] = [[0; RX_BUF_SIZE]; NUM_UARTS];
430static mut RX_BUFFER_USED: [(usize, usize); NUM_UARTS] = [(0, 0); NUM_UARTS];
432static mut RX_WAKERS: [Option<core::task::Waker>; NUM_UARTS] = [const { None }; NUM_UARTS];
433
434pub struct UartRx<T: UartPeripheral> {
435 peripheral: T,
436}
437
438impl<RX: UartRxPeripheral> UartRx<RX> {
439 pub fn new(peripheral: RX, config: UartConfig) -> Self {
440 let mut uart = Self { peripheral };
441 uart.set_config(&config).unwrap();
442 unsafe { init_uart_interrupt(uart.peripheral.number() as usize) };
443 uart
444 }
445}
446
447impl<T: UartPeripheral> SetConfig for UartRx<T> {
448 type Config = UartConfig;
449 type ConfigError = ();
450 fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> {
451 unsafe {
452 pac::MSS_UART_init(
453 self.peripheral.address(),
454 config.baud_rate.value(),
455 config.data_bits.value() | config.parity.value() | config.stop_bits.value(),
456 );
457 }
458 Ok(())
459 }
460}
461
462impl<T: UartPeripheral> UartRx<T> {
463 fn _read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
464 let uart_idx = self.peripheral.number() as usize;
465 let mut read = 0;
466
467 while read < buf.len() {
468 let (write_idx, read_idx) = critical_section::with(|_| unsafe {
469 let indices = RX_BUFFER_USED[uart_idx];
470 if indices.1 != indices.0 {
471 RX_BUFFER_USED[uart_idx].1 = (indices.1 + 1) % RX_BUF_SIZE;
473 buf[read] = RX_BUF[uart_idx][indices.1];
475 }
476 indices
477 });
478
479 if read_idx == write_idx {
480 break;
481 }
482 read += 1;
483 }
484
485 Ok(read)
486 }
487}
488
489impl<T: UartPeripheral> embedded_io::ErrorType for UartRx<T> {
490 type Error = Error;
491}
492
493impl<T: UartPeripheral> embedded_io::Read for UartRx<T> {
494 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
495 if buf.len() == 0 {
496 return Err(Error::EmptyBuffer);
497 }
498 unsafe {
499 loop {
500 let (write_idx, read_idx) = RX_BUFFER_USED[self.peripheral.number() as usize];
501 if write_idx != read_idx {
502 break;
503 }
504 }
505 }
506 self._read(buf)
507 }
508}
509
510impl<T: UartPeripheral> embedded_io_async::Read for UartRx<T> {
511 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
512 if buf.len() == 0 {
513 return Err(Error::EmptyBuffer);
514 }
515 let uart_idx = self.peripheral.number() as usize;
516 trace!("UART{}: read", uart_idx);
517
518 core::future::poll_fn(|cx| {
520 critical_section::with(|_| unsafe {
521 let (write_idx, read_idx) = RX_BUFFER_USED[uart_idx];
522 if write_idx != read_idx {
523 Poll::Ready(())
524 } else {
525 RX_WAKERS[uart_idx] = Some(cx.waker().clone());
526 Poll::Pending
527 }
528 })
529 })
530 .await;
531
532 self._read(buf)
533 }
534}
535
536fn uart_idx(uart: *mut pac::mss_uart_instance_t) -> usize {
537 if uart == &raw mut pac::g_mss_uart0_lo {
538 0
539 } else if uart == &raw mut pac::g_mss_uart1_lo {
540 1
541 } else if uart == &raw mut pac::g_mss_uart2_lo {
542 2
543 } else if uart == &raw mut pac::g_mss_uart3_lo {
544 3
545 } else if uart == &raw mut pac::g_mss_uart4_lo {
546 4
547 } else {
548 panic!("Invalid UART instance")
549 }
550}
551
552extern "C" fn uart_rx_handler(uart: *mut pac::mss_uart_instance_t) {
553 let uart_idx = uart_idx(uart);
554 trace!("UART{}: rx handler", uart_idx);
555 unsafe {
556 let (mut write_idx, mut read_idx) = RX_BUFFER_USED[uart_idx];
557
558 let size = pac::MSS_UART_get_rx(uart, &mut RX_BUF[uart_idx][write_idx] as *mut u8, 1);
560
561 if size > 0 {
562 write_idx = (write_idx + 1) % RX_BUF_SIZE;
564
565 if write_idx == read_idx {
567 read_idx = (read_idx + 1) % RX_BUF_SIZE;
568 RX_BUFFER_USED[uart_idx].1 = read_idx;
569 }
570
571 RX_BUFFER_USED[uart_idx].0 = write_idx;
572
573 if let Some(waker) = RX_WAKERS[uart_idx].take() {
575 waker.wake();
576 }
577 }
578
579 trace!("UART{}: got {} bytes", uart_idx, size);
580 }
581}