1use crate::pac::LP_UART;
38
39const UART_FIFO_SIZE: u16 = property!("lp_uart.ram_size");
40
41#[doc(hidden)]
42pub unsafe fn conjure() -> LpUart {
43 unsafe {
44 LpUart {
45 uart: LP_UART::steal(),
46 }
47 }
48}
49
50#[derive(Debug)]
52pub enum Error {}
53
54#[cfg(feature = "embedded-io")]
55impl core::error::Error for Error {}
56
57#[cfg(feature = "embedded-io")]
58impl core::fmt::Display for Error {
59 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
60 write!(f, "UART error")
61 }
62}
63
64#[cfg(feature = "embedded-hal")]
65impl embedded_hal_nb::serial::Error for Error {
66 fn kind(&self) -> embedded_hal_nb::serial::ErrorKind {
67 embedded_hal_nb::serial::ErrorKind::Other
68 }
69}
70
71#[cfg(feature = "embedded-io")]
72impl embedded_io_06::Error for Error {
73 fn kind(&self) -> embedded_io_06::ErrorKind {
74 embedded_io_06::ErrorKind::Other
75 }
76}
77
78#[cfg(feature = "embedded-io")]
79impl embedded_io_07::Error for Error {
80 fn kind(&self) -> embedded_io_07::ErrorKind {
81 embedded_io_07::ErrorKind::Other
82 }
83}
84
85pub mod config {
87 #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
89 pub enum DataBits {
90 DataBits5 = 0,
92 DataBits6 = 1,
94 DataBits7 = 2,
96 #[default]
98 DataBits8 = 3,
99 }
100
101 #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
103 pub enum Parity {
104 #[default]
106 ParityNone = 0,
107 ParityEven = 1,
109 ParityOdd = 2,
111 }
112
113 #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
115 pub enum StopBits {
116 #[default]
118 Stop1 = 1,
119 Stop1p5 = 2,
121 Stop2 = 3,
123 }
124
125 #[derive(Debug, Clone, Copy)]
127 pub struct Config {
128 baudrate: u32,
129 data_bits: DataBits,
130 parity: Parity,
131 stop_bits: StopBits,
132 }
133
134 impl Config {
135 pub fn baudrate(mut self, baudrate: u32) -> Self {
137 self.baudrate = baudrate;
138 self
139 }
140
141 pub fn parity_none(mut self) -> Self {
143 self.parity = Parity::ParityNone;
144 self
145 }
146
147 pub fn parity_even(mut self) -> Self {
149 self.parity = Parity::ParityEven;
150 self
151 }
152
153 pub fn parity_odd(mut self) -> Self {
155 self.parity = Parity::ParityOdd;
156 self
157 }
158
159 pub fn data_bits(mut self, data_bits: DataBits) -> Self {
161 self.data_bits = data_bits;
162 self
163 }
164
165 pub fn stop_bits(mut self, stop_bits: StopBits) -> Self {
167 self.stop_bits = stop_bits;
168 self
169 }
170 }
171
172 impl Default for Config {
173 fn default() -> Config {
174 Config {
175 baudrate: 115_200,
176 data_bits: Default::default(),
177 parity: Default::default(),
178 stop_bits: Default::default(),
179 }
180 }
181 }
182}
183
184pub struct LpUart {
186 uart: LP_UART,
187}
188
189impl LpUart {
190 pub fn read_byte(&mut self) -> nb::Result<u8, Error> {
192 if self.rx_fifo_count() > 0 {
193 let byte = self.uart.fifo().read().rxfifo_rd_byte().bits();
194 Ok(byte)
195 } else {
196 Err(nb::Error::WouldBlock)
197 }
198 }
199
200 pub fn write_byte(&mut self, byte: u8) -> nb::Result<(), Error> {
202 if self.tx_fifo_count() < UART_FIFO_SIZE {
203 self.uart
204 .fifo()
205 .write(|w| unsafe { w.rxfifo_rd_byte().bits(byte) });
206 Ok(())
207 } else {
208 Err(nb::Error::WouldBlock)
209 }
210 }
211
212 pub fn write_bytes(&mut self, data: &[u8]) -> Result<usize, Error> {
215 let count = data.len();
216
217 data.iter()
218 .try_for_each(|c| nb::block!(self.write_byte(*c)))?;
219
220 Ok(count)
221 }
222
223 pub fn flush_tx(&mut self) -> nb::Result<(), Error> {
225 if self.is_tx_idle() {
226 Ok(())
227 } else {
228 Err(nb::Error::WouldBlock)
229 }
230 }
231
232 fn rx_fifo_count(&mut self) -> u16 {
233 self.uart.status().read().rxfifo_cnt().bits().into()
234 }
235
236 fn tx_fifo_count(&mut self) -> u16 {
237 self.uart.status().read().txfifo_cnt().bits().into()
238 }
239
240 fn is_tx_idle(&self) -> bool {
241 self.uart.fsm_status().read().st_utx_out().bits() == 0
242 }
243}
244
245impl core::fmt::Write for LpUart {
246 fn write_str(&mut self, s: &str) -> core::fmt::Result {
247 self.write_bytes(s.as_bytes())
248 .map_err(|_| core::fmt::Error)?;
249 Ok(())
250 }
251}
252
253#[cfg(feature = "embedded-hal")]
254impl embedded_hal_nb::serial::ErrorType for LpUart {
255 type Error = Error;
256}
257
258#[cfg(feature = "embedded-hal")]
259impl embedded_hal_nb::serial::Read for LpUart {
260 fn read(&mut self) -> nb::Result<u8, Self::Error> {
261 self.read_byte()
262 }
263}
264
265#[cfg(feature = "embedded-hal")]
266impl embedded_hal_nb::serial::Write for LpUart {
267 fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
268 self.write_byte(word)
269 }
270
271 fn flush(&mut self) -> nb::Result<(), Self::Error> {
272 self.flush_tx()
273 }
274}
275
276#[cfg(feature = "embedded-io")]
277impl embedded_io_06::ErrorType for LpUart {
278 type Error = Error;
279}
280
281#[cfg(feature = "embedded-io")]
282impl embedded_io_06::Read for LpUart {
283 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
284 if buf.is_empty() {
285 return Ok(0);
286 }
287
288 while self.rx_fifo_count() == 0 {
289 }
291
292 let mut count = 0;
293 while self.rx_fifo_count() > 0 && count < buf.len() {
294 buf[count] = self.uart.fifo().read().rxfifo_rd_byte().bits();
295 count += 1;
296 }
297
298 Ok(count)
299 }
300}
301
302#[cfg(feature = "embedded-io")]
303impl embedded_io_06::ReadReady for LpUart {
304 fn read_ready(&mut self) -> Result<bool, Self::Error> {
305 Ok(self.rx_fifo_count() > 0)
306 }
307}
308
309#[cfg(feature = "embedded-io")]
310impl embedded_io_06::Write for LpUart {
311 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
312 self.write_bytes(buf)
313 }
314
315 fn flush(&mut self) -> Result<(), Self::Error> {
316 loop {
317 match self.flush_tx() {
318 Ok(_) => break,
319 Err(nb::Error::WouldBlock) => { }
320 #[allow(unreachable_patterns)]
321 Err(nb::Error::Other(e)) => return Err(e),
322 }
323 }
324
325 Ok(())
326 }
327}
328
329#[cfg(feature = "embedded-io")]
330impl embedded_io_07::ErrorType for LpUart {
331 type Error = Error;
332}
333
334#[cfg(feature = "embedded-io")]
335impl embedded_io_07::Read for LpUart {
336 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
337 if buf.is_empty() {
338 return Ok(0);
339 }
340
341 while self.rx_fifo_count() == 0 {
342 }
344
345 let mut count = 0;
346 while self.rx_fifo_count() > 0 && count < buf.len() {
347 buf[count] = self.uart.fifo().read().rxfifo_rd_byte().bits();
348 count += 1;
349 }
350
351 Ok(count)
352 }
353}
354
355#[cfg(feature = "embedded-io")]
356impl embedded_io_07::ReadReady for LpUart {
357 fn read_ready(&mut self) -> Result<bool, Self::Error> {
358 Ok(self.rx_fifo_count() > 0)
359 }
360}
361
362#[cfg(feature = "embedded-io")]
363impl embedded_io_07::Write for LpUart {
364 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
365 self.write_bytes(buf)
366 }
367
368 fn flush(&mut self) -> Result<(), Self::Error> {
369 loop {
370 match self.flush_tx() {
371 Ok(_) => break,
372 Err(nb::Error::WouldBlock) => { }
373 #[allow(unreachable_patterns)]
374 Err(nb::Error::Other(e)) => return Err(e),
375 }
376 }
377
378 Ok(())
379 }
380}