1use crate::peripherals::{Uart0, Uart1, Uart2};
7use core::marker::PhantomData;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum DataBits {
11 Five,
12 Six,
13 Seven,
14 Eight,
15}
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18pub enum Parity {
19 None,
20 Even,
21 Odd,
22}
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq)]
25pub enum StopBits {
26 One,
27 Two,
28}
29
30#[derive(Debug, Clone, Copy)]
31pub struct Config {
32 pub baudrate: u32,
33 pub data_bits: DataBits,
34 pub parity: Parity,
35 pub stop_bits: StopBits,
36}
37
38impl Default for Config {
39 fn default() -> Self {
40 Self { baudrate: 115200, data_bits: DataBits::Eight, parity: Parity::None, stop_bits: StopBits::One }
41 }
42}
43
44pub struct Uart<'d, T> {
45 _peripheral: PhantomData<&'d T>,
46}
47
48#[allow(dead_code)]
49fn regs() -> &'static ws63_pac::uart0::RegisterBlock {
50 unsafe { &*Uart0::ptr() }
52}
53
54fn uart_ptr(idx: u8) -> *const ws63_pac::uart0::RegisterBlock {
55 match idx {
56 0 => Uart0::ptr(),
57 1 => Uart1::ptr(),
58 2 => Uart2::ptr(),
59 _ => unreachable!(),
60 }
61}
62
63fn uart_regs(idx: u8) -> &'static ws63_pac::uart0::RegisterBlock {
64 unsafe { &*uart_ptr(idx) }
66}
67
68impl<'d> Uart<'d, Uart0<'d>> {
69 pub fn new_uart0(_uart: Uart0<'d>, config: Config) -> Self {
70 configure_uart(0, &config);
71 Self { _peripheral: PhantomData }
72 }
73}
74
75impl<'d> Uart<'d, Uart1<'d>> {
76 pub fn new_uart1(_uart: Uart1<'d>, config: Config) -> Self {
77 configure_uart(1, &config);
78 Self { _peripheral: PhantomData }
79 }
80}
81
82impl<'d> Uart<'d, Uart2<'d>> {
83 pub fn new_uart2(_uart: Uart2<'d>, config: Config) -> Self {
84 configure_uart(2, &config);
85 Self { _peripheral: PhantomData }
86 }
87}
88
89fn configure_uart(idx: u8, config: &Config) {
90 let r = uart_regs(idx);
91
92 r.uart_ctl().modify(|_, w| unsafe { w.bits(0) });
94 r.uart_ctl().write(|w| w.div_en().set_bit());
95
96 let pclk = crate::soc::ws63::SYSTEM_CLOCK_HZ;
100 let min_baud = (pclk / (16 * 65535)) + 1;
101 let baudrate = if config.baudrate < min_baud { min_baud } else { config.baudrate };
102 let div = pclk / (16 * baudrate);
103 let div_l = (div & 0xFF) as u16;
104 let div_h = ((div >> 8) & 0xFF) as u16;
105 r.div_l().write(|w| unsafe { w.bits(div_l) });
106 r.div_h().write(|w| unsafe { w.bits(div_h) });
107 r.div_fra().write(|w| unsafe { w.bits(0) });
108
109 let mut ctl = 0u16;
111 ctl |= match config.data_bits {
112 DataBits::Five => 0,
113 DataBits::Six => 1 << 2,
114 DataBits::Seven => 2 << 2,
115 DataBits::Eight => 3 << 2,
116 };
117 match config.parity {
118 Parity::Even => {
119 ctl |= 1 << 5;
120 ctl |= 1 << 4;
121 }
122 Parity::Odd => {
123 ctl |= 1 << 5;
124 }
125 Parity::None => {}
126 }
127 if matches!(config.stop_bits, StopBits::Two) {
128 ctl |= 1 << 7;
129 }
130 r.uart_ctl().write(|w| unsafe { w.bits(ctl | (1 << 0)) }); r.fifo_ctl().write(|w| unsafe { w.bits(0x01) });
134
135 r.fifo_ctl().write(|w| unsafe { w.bits(0x07) });
137}
138
139impl<T> Uart<'_, T> {
140 pub fn write_byte(&self, idx: u8, byte: u8) {
141 let r = uart_regs(idx);
142 while r.fifo_status().read().tx_fifo_full().bit_is_set() {}
143 r.data().write(|w| unsafe { w.bits(byte as u16) });
144 }
145
146 pub fn read_byte(&self, idx: u8) -> Option<u8> {
147 let r = uart_regs(idx);
148 if r.fifo_status().read().rx_fifo_empty().bit_is_set() { None } else { Some(r.data().read().bits() as u8) }
149 }
150
151 pub fn flush_tx(&self, idx: u8) {
152 let r = uart_regs(idx);
153 while !r.fifo_status().read().tx_fifo_empty().bit_is_set() {}
154 }
155
156 pub fn tx_flushed(&self, idx: u8) -> bool {
158 uart_regs(idx).fifo_status().read().tx_fifo_empty().bit_is_set()
159 }
160
161 pub fn write(&self, idx: u8, data: &[u8]) {
162 for &b in data {
163 self.write_byte(idx, b);
164 }
165 }
166
167 pub fn uart_regs(&self, idx: u8) -> &'static ws63_pac::uart0::RegisterBlock {
168 uart_regs(idx)
169 }
170}
171
172impl embedded_io::ErrorType for Uart<'_, Uart0<'_>> {
173 type Error = core::convert::Infallible;
174}
175impl embedded_io::Write for Uart<'_, Uart0<'_>> {
176 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
177 for &b in buf {
178 self.write_byte(0, b);
179 }
180 Ok(buf.len())
181 }
182 fn flush(&mut self) -> Result<(), Self::Error> {
183 self.flush_tx(0);
184 Ok(())
185 }
186}
187impl embedded_io::Read for Uart<'_, Uart0<'_>> {
188 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
189 let mut n = 0;
190 for b in buf.iter_mut() {
191 if let Some(byte) = self.read_byte(0) {
192 *b = byte;
193 n += 1;
194 } else {
195 break;
196 }
197 }
198 Ok(n)
199 }
200}
201
202impl embedded_io::ErrorType for Uart<'_, Uart1<'_>> {
204 type Error = core::convert::Infallible;
205}
206impl embedded_io::Write for Uart<'_, Uart1<'_>> {
207 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
208 for &b in buf {
209 self.write_byte(1, b);
210 }
211 Ok(buf.len())
212 }
213 fn flush(&mut self) -> Result<(), Self::Error> {
214 self.flush_tx(1);
215 Ok(())
216 }
217}
218impl embedded_io::Read for Uart<'_, Uart1<'_>> {
219 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
220 let mut n = 0;
221 for b in buf.iter_mut() {
222 if let Some(byte) = self.read_byte(1) {
223 *b = byte;
224 n += 1;
225 } else {
226 break;
227 }
228 }
229 Ok(n)
230 }
231}
232
233impl embedded_io::ErrorType for Uart<'_, Uart2<'_>> {
235 type Error = core::convert::Infallible;
236}
237impl embedded_io::Write for Uart<'_, Uart2<'_>> {
238 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
239 for &b in buf {
240 self.write_byte(2, b);
241 }
242 Ok(buf.len())
243 }
244 fn flush(&mut self) -> Result<(), Self::Error> {
245 self.flush_tx(2);
246 Ok(())
247 }
248}
249impl embedded_io::Read for Uart<'_, Uart2<'_>> {
250 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
251 let mut n = 0;
252 for b in buf.iter_mut() {
253 if let Some(byte) = self.read_byte(2) {
254 *b = byte;
255 n += 1;
256 } else {
257 break;
258 }
259 }
260 Ok(n)
261 }
262}
263
264macro_rules! impl_nb_serial {
267 ($uart:ty, $idx:expr) => {
268 impl embedded_hal_nb::serial::ErrorType for Uart<'_, $uart> {
269 type Error = core::convert::Infallible;
270 }
271 impl embedded_hal_nb::serial::Read for Uart<'_, $uart> {
272 fn read(&mut self) -> nb::Result<u8, Self::Error> {
273 match self.read_byte($idx) {
274 Some(b) => Ok(b),
275 None => Err(nb::Error::WouldBlock),
276 }
277 }
278 }
279 impl embedded_hal_nb::serial::Write for Uart<'_, $uart> {
280 fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
281 self.write_byte($idx, byte);
282 Ok(())
283 }
284 fn flush(&mut self) -> nb::Result<(), Self::Error> {
285 if self.tx_flushed($idx) { Ok(()) } else { Err(nb::Error::WouldBlock) }
286 }
287 }
288 };
289}
290
291impl_nb_serial!(Uart0<'_>, 0);
292impl_nb_serial!(Uart1<'_>, 1);
293impl_nb_serial!(Uart2<'_>, 2);