1use core::{convert::Infallible, fmt};
7use embedded_hal_0_2::serial as eh0;
8use fugit::HertzU32;
9use nb::Error::{Other, WouldBlock};
10
11use crate::{
12 pac::{self, uart0::uartlcr_h::W as UART_LCR_H_Writer, Peripherals, UART0, UART1},
13 typelevel::OptionT,
14 uart::*,
15};
16
17use embedded_hal_nb::serial::{ErrorType, Read, Write};
18
19pub struct UartPeripheral<S: State, D: UartDevice, P: ValidUartPinout<D>> {
21 device: D,
22 _state: S,
23 pins: P,
24 read_error: Option<ReadErrorType>,
25}
26
27impl<S: State, D: UartDevice, P: ValidUartPinout<D>> UartPeripheral<S, D, P> {
28 fn transition<To: State>(self, state: To) -> UartPeripheral<To, D, P> {
29 UartPeripheral {
30 device: self.device,
31 pins: self.pins,
32 _state: state,
33 read_error: None,
34 }
35 }
36
37 pub fn free(self) -> (D, P) {
39 (self.device, self.pins)
40 }
41}
42
43impl<D: UartDevice, P: ValidUartPinout<D>> UartPeripheral<Disabled, D, P> {
44 pub fn new(device: D, pins: P, resets: &mut pac::RESETS) -> UartPeripheral<Disabled, D, P> {
46 device.reset_bring_down(resets);
47 device.reset_bring_up(resets);
48
49 UartPeripheral {
50 device,
51 _state: Disabled,
52 pins,
53 read_error: None,
54 }
55 }
56
57 pub fn enable(
59 self,
60 config: UartConfig,
61 frequency: HertzU32,
62 ) -> Result<UartPeripheral<Enabled, D, P>, Error> {
63 let (mut device, pins) = self.free();
64 configure_baudrate(&mut device, config.baudrate, frequency)?;
65
66 device.uartlcr_h().write(|w| {
67 w.fen().set_bit(); set_format(w, &config.data_bits, &config.stop_bits, &config.parity);
70 w
71 });
72
73 device.uartcr().write(|w| {
75 w.uarten().set_bit();
76 w.txe().bit(P::Tx::IS_SOME);
77 w.rxe().bit(P::Rx::IS_SOME);
78 w.ctsen().bit(P::Cts::IS_SOME);
79 w.rtsen().bit(P::Rts::IS_SOME);
80
81 w
82 });
83
84 device.uartdmacr().write(|w| {
85 w.txdmae().set_bit();
86 w.rxdmae().set_bit();
87 w
88 });
89
90 Ok(UartPeripheral {
91 device,
92 pins,
93 _state: Enabled,
94 read_error: None,
95 })
96 }
97}
98
99impl<D: UartDevice, P: ValidUartPinout<D>> UartPeripheral<Enabled, D, P> {
100 pub fn disable(self) -> UartPeripheral<Disabled, D, P> {
102 self.device.uartcr().write(|w| {
104 w.uarten().clear_bit();
105 w.txe().clear_bit();
106 w.rxe().clear_bit();
107 w.ctsen().clear_bit();
108 w.rtsen().clear_bit();
109 w
110 });
111
112 self.transition(Disabled)
113 }
114
115 pub fn set_fifos(&mut self, enable: bool) {
121 super::reader::set_fifos(&self.device, enable)
122 }
123
124 pub fn set_rx_watermark(&mut self, watermark: FifoWatermark) {
128 super::reader::set_rx_watermark(&self.device, watermark)
129 }
130
131 pub fn set_tx_watermark(&mut self, watermark: FifoWatermark) {
135 super::writer::set_tx_watermark(&self.device, watermark)
136 }
137
138 pub fn enable_rx_interrupt(&mut self) {
142 super::reader::enable_rx_interrupt(&self.device)
143 }
144
145 pub fn enable_tx_interrupt(&mut self) {
149 super::writer::enable_tx_interrupt(&self.device)
150 }
151
152 pub fn disable_rx_interrupt(&mut self) {
154 super::reader::disable_rx_interrupt(&self.device)
155 }
156
157 pub fn disable_tx_interrupt(&mut self) {
159 super::writer::disable_tx_interrupt(&self.device)
160 }
161
162 pub fn uart_is_writable(&self) -> bool {
164 super::writer::uart_is_writable(&self.device)
165 }
166
167 pub fn uart_is_busy(&self) -> bool {
169 super::writer::uart_is_busy(&self.device)
170 }
171
172 pub fn uart_is_readable(&self) -> bool {
174 super::reader::is_readable(&self.device)
175 }
176
177 pub fn write_raw<'d>(&self, data: &'d [u8]) -> nb::Result<&'d [u8], Infallible> {
184 super::writer::write_raw(&self.device, data)
185 }
186
187 pub fn read_raw<'b>(&self, buffer: &'b mut [u8]) -> nb::Result<usize, ReadError<'b>> {
194 super::reader::read_raw(&self.device, buffer)
195 }
196
197 pub fn write_full_blocking(&self, data: &[u8]) {
201 super::writer::write_full_blocking(&self.device, data);
202 }
203
204 pub fn read_full_blocking(&self, buffer: &mut [u8]) -> Result<(), ReadErrorType> {
208 super::reader::read_full_blocking(&self.device, buffer)
209 }
210
211 pub fn lowlevel_break_start(&mut self) {
236 self.device.uartlcr_h().modify(|_, w| w.brk().set_bit());
237 }
238
239 pub fn lowlevel_break_stop(&mut self) {
243 self.device.uartlcr_h().modify(|_, w| w.brk().clear_bit());
244 }
245
246 pub fn join(reader: Reader<D, P>, writer: Writer<D, P>) -> Self {
252 let _ = writer;
253 Self {
254 device: reader.device,
255 _state: Enabled,
256 pins: reader.pins,
257 read_error: reader.read_error,
258 }
259 }
260}
261
262impl<P: ValidUartPinout<UART0>> UartPeripheral<Enabled, UART0, P> {
263 pub fn split(self) -> (Reader<UART0, P>, Writer<UART0, P>) {
265 let reader = Reader {
266 device: self.device,
267 pins: self.pins,
268 read_error: self.read_error,
269 };
270 let device_copy = unsafe { Peripherals::steal().UART0 };
272 let writer = Writer {
273 device: device_copy,
274 device_marker: core::marker::PhantomData,
275 pins: core::marker::PhantomData,
276 };
277 (reader, writer)
278 }
279}
280
281impl<P: ValidUartPinout<UART1>> UartPeripheral<Enabled, UART1, P> {
282 pub fn split(self) -> (Reader<UART1, P>, Writer<UART1, P>) {
284 let reader = Reader {
285 device: self.device,
286 pins: self.pins,
287 read_error: self.read_error,
288 };
289 let device_copy = unsafe { Peripherals::steal().UART1 };
291 let writer = Writer {
292 device: device_copy,
293 device_marker: core::marker::PhantomData,
294 pins: core::marker::PhantomData,
295 };
296 (reader, writer)
297 }
298}
299
300fn calculate_baudrate_dividers(
304 wanted_baudrate: HertzU32,
305 frequency: HertzU32,
306) -> Result<(u16, u16), Error> {
307 let baudrate_div = frequency
310 .to_Hz()
311 .checked_mul(8)
312 .and_then(|r| r.checked_div(wanted_baudrate.to_Hz()))
313 .ok_or(Error::BadArgument)?;
314
315 Ok(
316 match (baudrate_div >> 7, (baudrate_div & 0x7F).div_ceil(2)) {
317 (0, _) => (1, 0),
318
319 (int_part, _) if int_part >= 65535 => (65535, 0),
320
321 (int_part, frac_part) => (int_part as u16, frac_part as u16),
322 },
323 )
324}
325
326#[allow(unknown_lints)]
328#[allow(clippy::needless_pass_by_ref_mut)]
329fn configure_baudrate<U: UartDevice>(
330 device: &mut U,
331 wanted_baudrate: HertzU32,
332 frequency: HertzU32,
333) -> Result<HertzU32, Error> {
334 let (baud_div_int, baud_div_frac) = calculate_baudrate_dividers(wanted_baudrate, frequency)?;
335
336 device.uartibrd().write(|w| unsafe {
338 w.baud_divint().bits(baud_div_int);
339 w
340 });
341
342 device.uartfbrd().write(|w| unsafe {
344 w.baud_divfrac().bits(baud_div_frac as u8);
345 w
346 });
347
348 device.uartlcr_h().modify(|_, w| w);
351
352 Ok(HertzU32::from_raw(
353 (4 * frequency.to_Hz()) / (64 * baud_div_int as u32 + baud_div_frac as u32),
354 ))
355}
356
357fn set_format<'w>(
359 w: &'w mut UART_LCR_H_Writer,
360 data_bits: &DataBits,
361 stop_bits: &StopBits,
362 parity: &Option<Parity>,
363) -> &'w mut UART_LCR_H_Writer {
364 match parity {
365 Some(p) => {
366 w.pen().set_bit();
367 match p {
368 Parity::Odd => w.eps().clear_bit(),
369 Parity::Even => w.eps().set_bit(),
370 };
371 }
372 None => {
373 w.pen().bit(false);
374 }
375 };
376
377 unsafe {
378 w.wlen().bits(match data_bits {
379 DataBits::Five => 0b00,
380 DataBits::Six => 0b01,
381 DataBits::Seven => 0b10,
382 DataBits::Eight => 0b11,
383 })
384 };
385
386 match stop_bits {
387 StopBits::One => w.stp2().clear_bit(),
388 StopBits::Two => w.stp2().set_bit(),
389 };
390
391 w
392}
393
394impl<D: UartDevice, P: ValidUartPinout<D>> eh0::Read<u8> for UartPeripheral<Enabled, D, P> {
395 type Error = ReadErrorType;
396
397 fn read(&mut self) -> nb::Result<u8, Self::Error> {
398 let byte: &mut [u8] = &mut [0; 1];
399
400 match self.read_raw(byte) {
401 Ok(_) => Ok(byte[0]),
402 Err(e) => match e {
403 Other(inner) => Err(Other(inner.err_type)),
404 WouldBlock => Err(WouldBlock),
405 },
406 }
407 }
408}
409
410impl<D: UartDevice, P: ValidUartPinout<D>> ErrorType for UartPeripheral<Enabled, D, P> {
411 type Error = ReadErrorType;
412}
413
414impl<D: UartDevice, P: ValidUartPinout<D>> Read<u8> for UartPeripheral<Enabled, D, P> {
415 fn read(&mut self) -> nb::Result<u8, Self::Error> {
416 let byte: &mut [u8] = &mut [0; 1];
417
418 match self.read_raw(byte) {
419 Ok(_) => Ok(byte[0]),
420 Err(e) => match e {
421 Other(inner) => Err(Other(inner.err_type)),
422 WouldBlock => Err(WouldBlock),
423 },
424 }
425 }
426}
427
428impl<D: UartDevice, P: ValidUartPinout<D>> eh0::Write<u8> for UartPeripheral<Enabled, D, P> {
429 type Error = Infallible;
430
431 fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
432 if self.write_raw(&[word]).is_err() {
433 Err(WouldBlock)
434 } else {
435 Ok(())
436 }
437 }
438
439 fn flush(&mut self) -> nb::Result<(), Self::Error> {
440 super::writer::transmit_flushed(&self.device)
441 }
442}
443
444impl<D: UartDevice, P: ValidUartPinout<D>> Write<u8> for UartPeripheral<Enabled, D, P> {
445 fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
446 if self.write_raw(&[word]).is_err() {
447 Err(WouldBlock)
448 } else {
449 Ok(())
450 }
451 }
452
453 fn flush(&mut self) -> nb::Result<(), Self::Error> {
454 super::writer::transmit_flushed(&self.device).map_err(|e| match e {
455 WouldBlock => WouldBlock,
456 Other(v) => match v {},
457 })
458 }
459}
460
461impl<D: UartDevice, P: ValidUartPinout<D>> fmt::Write for UartPeripheral<Enabled, D, P> {
462 fn write_str(&mut self, s: &str) -> fmt::Result {
463 s.bytes()
464 .try_for_each(|c| nb::block!(self.write(c)))
465 .map_err(|_| fmt::Error)
466 }
467}
468
469impl core::fmt::Display for ReadErrorType {
470 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
471 write!(f, "{:?}", self)
472 }
473}
474
475impl core::error::Error for ReadErrorType {}
476
477impl embedded_io::Error for ReadErrorType {
478 fn kind(&self) -> embedded_io::ErrorKind {
479 embedded_io::ErrorKind::Other
480 }
481}
482
483impl<D: UartDevice, P: ValidUartPinout<D>> embedded_io::ErrorType
484 for UartPeripheral<Enabled, D, P>
485{
486 type Error = ReadErrorType;
487}
488impl<D: UartDevice, P: ValidUartPinout<D>> embedded_io::Read for UartPeripheral<Enabled, D, P> {
489 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
490 if let Some(err) = self.read_error.take() {
492 return Err(err);
493 }
494 match nb::block!(self.read_raw(buf)) {
495 Ok(bytes_read) => Ok(bytes_read),
496 Err(err) if !err.discarded.is_empty() => {
497 self.read_error = Some(err.err_type);
501 Ok(err.discarded.len())
502 }
503 Err(err) => Err(err.err_type),
504 }
505 }
506}
507
508impl<D: UartDevice, P: ValidUartPinout<D>> embedded_io::ReadReady
509 for UartPeripheral<Enabled, D, P>
510{
511 fn read_ready(&mut self) -> Result<bool, Self::Error> {
512 Ok(self.uart_is_readable() || self.read_error.is_some())
513 }
514}
515
516impl<D: UartDevice, P: ValidUartPinout<D>> embedded_io::Write for UartPeripheral<Enabled, D, P> {
517 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
518 let remaining = nb::block!(super::writer::write_raw(&self.device, buf)).unwrap(); Ok(buf.len() - remaining.len())
521 }
522 fn flush(&mut self) -> Result<(), Self::Error> {
523 nb::block!(super::writer::transmit_flushed(&self.device)).unwrap(); Ok(())
525 }
526}
527
528impl<D: UartDevice, P: ValidUartPinout<D>> embedded_io::WriteReady
529 for UartPeripheral<Enabled, D, P>
530{
531 fn write_ready(&mut self) -> Result<bool, Self::Error> {
532 Ok(self.uart_is_writable())
533 }
534}