1use core::cell::Cell;
6use kernel::utilities::cells::{OptionalCell, TakeCell};
7use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
8use kernel::utilities::registers::{register_bitfields, ReadOnly, ReadWrite};
9
10use kernel::hil;
11use kernel::platform::chip::ClockInterface;
12use kernel::utilities::StaticRef;
13use kernel::ErrorCode;
14
15use crate::{ccm, dma};
16
17#[repr(C)]
19struct LpuartRegisters {
20 verid: ReadOnly<u32, VERID::Register>,
22 param: ReadOnly<u32, PARAM::Register>,
24 global: ReadWrite<u32, GLOBAL::Register>,
26 pincfg: ReadWrite<u32, PINCFG::Register>,
28 baud: ReadWrite<u32, BAUD::Register>,
30 stat: ReadWrite<u32, STAT::Register>,
32 ctrl: ReadWrite<u32, CTRL::Register>,
34 data: ReadWrite<u32, DATA::Register>,
36 r#match: ReadWrite<u32, MATCH::Register>,
38 modir: ReadWrite<u32, MODIR::Register>,
40 fifo: ReadWrite<u32, FIFO::Register>,
42 water: ReadWrite<u32, WATER::Register>,
44}
45
46register_bitfields![u32,
47 VERID [
48 MAJOR OFFSET(24) NUMBITS(8) [],
50 MINOR OFFSET(16) NUMBITS(8) [],
52 FEATURE OFFSET(0) NUMBITS(16) []
54 ],
55
56 PARAM [
57 RXFIFO OFFSET(8) NUMBITS(8) [],
59 TXFIFO OFFSET(0) NUMBITS(8) []
61 ],
62
63 GLOBAL [
64 RST OFFSET(1) NUMBITS(1) []
66 ],
67
68 PINCFG [
69 TRGSEL OFFSET(0) NUMBITS(2) []
71 ],
72
73 BAUD [
74 MAEN1 OFFSET(31) NUMBITS(1) [],
76 MAEN2 OFFSET(30) NUMBITS(1) [],
78 M10 OFFSET(29) NUMBITS(1) [],
80 OSR OFFSET(24) NUMBITS(5) [],
82 TDMAE OFFSET(23) NUMBITS(1) [],
84 RDMAE OFFSET(21) NUMBITS(1) [],
86 RIDMAE OFFSET(20) NUMBITS(1) [],
88 MATCFG OFFSET(18) NUMBITS(2) [],
90 BOTHEDGE OFFSET(17) NUMBITS(1) [],
92 RESYNCDIS OFFSET(16) NUMBITS(1) [],
94 LBKDIE OFFSET(15) NUMBITS(1) [],
96 RXEDGIE OFFSET(14) NUMBITS(1) [],
98 SBNS OFFSET(13) NUMBITS(1) [],
100 SBR OFFSET(0) NUMBITS(13) []
102 ],
103
104 STAT [
105 LBKDIF OFFSET(31) NUMBITS(1) [],
107 RXEDGIF OFFSET(30) NUMBITS(1) [],
109 MSBF OFFSET(29) NUMBITS(1) [],
111 RXINV OFFSET(28) NUMBITS(1) [],
113 RWUID OFFSET(27) NUMBITS(1) [],
115 BRK13 OFFSET(26) NUMBITS(1) [],
117 LBKDE OFFSET(25) NUMBITS(1) [],
119 RAF OFFSET(24) NUMBITS(1) [],
121 TDRE OFFSET(23) NUMBITS(1) [],
123 TC OFFSET(22) NUMBITS(1) [],
125 RDRF OFFSET(21) NUMBITS(1) [],
127 IDLE OFFSET(20) NUMBITS(1) [],
129 OR OFFSET(19) NUMBITS(1) [],
131 NF OFFSET(18) NUMBITS(1) [],
133 FE OFFSET(17) NUMBITS(1) [],
135 PF OFFSET(16) NUMBITS(1) [],
137 MA1F OFFSET(15) NUMBITS(1) [],
139 MA2F OFFSET(14) NUMBITS(1) []
141 ],
142
143 CTRL [
144 R8T9 OFFSET(31) NUMBITS(1) [],
146 R9T8 OFFSET(30) NUMBITS(1) [],
148 TXDIR OFFSET(29) NUMBITS(1) [],
150 TXINV OFFSET(28) NUMBITS(1) [],
152 ORIE OFFSET(27) NUMBITS(1) [],
154 NEIE OFFSET(26) NUMBITS(1) [],
156 FEIE OFFSET(25) NUMBITS(1) [],
158 PEIE OFFSET(24) NUMBITS(1) [],
160 TIE OFFSET(23) NUMBITS(1) [],
162 TCIE OFFSET(22) NUMBITS(1) [],
164 RIE OFFSET(21) NUMBITS(1) [],
166 ILIE OFFSET(20) NUMBITS(1) [],
168 TE OFFSET(19) NUMBITS(1) [],
170 RE OFFSET(18) NUMBITS(1) [],
172 RWU OFFSET(17) NUMBITS(1) [],
174 SBK OFFSET(16) NUMBITS(1) [],
176 MA1IE OFFSET(15) NUMBITS(1) [],
178 MA2IE OFFSET(14) NUMBITS(1) [],
180 M7 OFFSET(11) NUMBITS(1) [],
182 IDLECFG OFFSET(8) NUMBITS(3) [],
184 LOOPS OFFSET(7) NUMBITS(1) [],
186 DOZEEN OFFSET(6) NUMBITS(1) [],
188 RSRC OFFSET(5) NUMBITS(1) [],
190 M OFFSET(4) NUMBITS(1) [],
192 WAKE OFFSET(3) NUMBITS(1) [],
194 ILT OFFSET(2) NUMBITS(1) [],
196 PE OFFSET(1) NUMBITS(1) [],
198 PT OFFSET(0) NUMBITS(1) []
200 ],
201
202 DATA [
203 NOISY OFFSET(15) NUMBITS(8) [],
205 PARITYE OFFSET(14) NUMBITS(8) [],
207 FRETSC OFFSET(13) NUMBITS(8) [],
209 RXEMPT OFFSET(12) NUMBITS(8) [],
211 IDLINE OFFSET(11) NUMBITS(8) [],
213 R9T9 OFFSET(9) NUMBITS(8) [],
215 R8T8 OFFSET(8) NUMBITS(8) [],
217 R7T7 OFFSET(7) NUMBITS(8) [],
219 R6T6 OFFSET(6) NUMBITS(8) [],
221 R5T5 OFFSET(5) NUMBITS(8) [],
223 R4T4 OFFSET(4) NUMBITS(8) [],
225 R3T3 OFFSET(3) NUMBITS(8) [],
227 R2T2 OFFSET(2) NUMBITS(8) [],
229 R1T1 OFFSET(1) NUMBITS(8) [],
231 R0T0 OFFSET(0) NUMBITS(8) []
233 ],
234
235 MATCH [
236 MA2 OFFSET(16) NUMBITS(10) [],
238 MA1 OFFSET(0) NUMBITS(10) []
240 ],
241
242 MODIR [
243 IREN OFFSET(18) NUMBITS(1) [],
245 TNP OFFSET(16) NUMBITS(2) [],
247 RTSWATER OFFSET(8) NUMBITS(2) [],
249 TXCTSSRC OFFSET(5) NUMBITS(1) [],
251 TXCTSC OFFSET(4) NUMBITS(1) [],
253 RXRTSE OFFSET(3) NUMBITS(1) [],
255 TXRTSPOL OFFSET(2) NUMBITS(1) [],
257 TXRTSE OFFSET(1) NUMBITS(1) [],
259 TXCTSE OFFSET(0) NUMBITS(1) []
261 ],
262
263 FIFO [
264 TXEMPT OFFSET(23) NUMBITS(1) [],
266 RXEMPT OFFSET(22) NUMBITS(1) [],
268 TXOF OFFSET(17) NUMBITS(1) [],
270 RXUF OFFSET(16) NUMBITS(1) [],
272 TXFLUSH OFFSET(15) NUMBITS(1) [],
274 RXFLUSH OFFSET(14) NUMBITS(1) [],
276 RXIDEN OFFSET(10) NUMBITS(2) [],
278 TXOFE OFFSET(9) NUMBITS(1) [],
280 RXUFE OFFSET(8) NUMBITS(1) [],
282 TXFE OFFSET(7) NUMBITS(1) [],
284 TXFIFOSIZE OFFSET(4) NUMBITS(3) [],
286 RXFE OFFSET(3) NUMBITS(1) [],
288 RXFIFOSIZE OFFSET(0) NUMBITS(3) []
290 ],
291
292 WATER [
293 RXCOUNT OFFSET(24) NUMBITS(3) [],
295 RXWATER OFFSET(16) NUMBITS(2) [],
297 TXCOUNT OFFSET(8) NUMBITS(3) [],
299 TXWATER OFFSET(0) NUMBITS(2) []
301 ]
302];
303
304const LPUART1_BASE: StaticRef<LpuartRegisters> =
305 unsafe { StaticRef::new(0x40184000 as *const LpuartRegisters) };
306const LPUART2_BASE: StaticRef<LpuartRegisters> =
307 unsafe { StaticRef::new(0x4018_8000 as *const LpuartRegisters) };
308
309#[derive(Copy, Clone, PartialEq)]
310enum LPUARTStateTX {
311 Idle,
312 Transmitting,
313 AbortRequested,
314}
315
316#[derive(Copy, Clone, PartialEq)]
317enum USARTStateRX {
318 Idle,
319 Receiving,
320 AbortRequested,
321}
322
323pub struct Lpuart<'a> {
324 registers: StaticRef<LpuartRegisters>,
325 clock: LpuartClock<'a>,
326
327 tx_client: OptionalCell<&'a dyn hil::uart::TransmitClient>,
328 rx_client: OptionalCell<&'a dyn hil::uart::ReceiveClient>,
329
330 tx_buffer: TakeCell<'static, [u8]>,
331 tx_position: Cell<usize>,
332 tx_len: Cell<usize>,
333 tx_status: Cell<LPUARTStateTX>,
334 tx_dma_channel: OptionalCell<&'a dma::DmaChannel>,
335 tx_dma_source: dma::DmaHardwareSource,
336
337 rx_buffer: TakeCell<'static, [u8]>,
338 rx_position: Cell<usize>,
339 rx_len: Cell<usize>,
340 rx_status: Cell<USARTStateRX>,
341 rx_dma_channel: OptionalCell<&'a dma::DmaChannel>,
342 rx_dma_source: dma::DmaHardwareSource,
343}
344
345impl<'a> Lpuart<'a> {
346 pub fn new_lpuart1(ccm: &'a ccm::Ccm) -> Self {
347 Lpuart::new(
348 LPUART1_BASE,
349 LpuartClock(ccm::PeripheralClock::ccgr5(ccm, ccm::HCLK5::LPUART1)),
350 dma::DmaHardwareSource::Lpuart1Transfer,
351 dma::DmaHardwareSource::Lpuart1Receive,
352 )
353 }
354
355 pub fn new_lpuart2(ccm: &'a ccm::Ccm) -> Self {
356 Lpuart::new(
357 LPUART2_BASE,
358 LpuartClock(ccm::PeripheralClock::ccgr0(ccm, ccm::HCLK0::LPUART2)),
359 dma::DmaHardwareSource::Lpuart2Transfer,
360 dma::DmaHardwareSource::Lpuart2Receive,
361 )
362 }
363
364 fn new(
365 base_addr: StaticRef<LpuartRegisters>,
366 clock: LpuartClock<'a>,
367 tx_dma_source: dma::DmaHardwareSource,
368 rx_dma_source: dma::DmaHardwareSource,
369 ) -> Lpuart<'a> {
370 Lpuart {
371 registers: base_addr,
372 clock,
373
374 tx_client: OptionalCell::empty(),
375 rx_client: OptionalCell::empty(),
376
377 tx_buffer: TakeCell::empty(),
378 tx_position: Cell::new(0),
379 tx_len: Cell::new(0),
380 tx_status: Cell::new(LPUARTStateTX::Idle),
381 tx_dma_channel: OptionalCell::empty(),
382 tx_dma_source,
383
384 rx_buffer: TakeCell::empty(),
385 rx_position: Cell::new(0),
386 rx_len: Cell::new(0),
387 rx_status: Cell::new(USARTStateRX::Idle),
388 rx_dma_channel: OptionalCell::empty(),
389 rx_dma_source,
390 }
391 }
392
393 pub fn set_tx_dma_channel(&'static self, dma_channel: &'static dma::DmaChannel) {
395 dma_channel.set_client(self, self.tx_dma_source);
396 unsafe {
397 dma_channel.set_destination(core::ptr::addr_of!(self.registers.data) as *const u8);
399 }
400 dma_channel.set_interrupt_on_completion(true);
401 dma_channel.set_disable_on_completion(true);
402 self.tx_dma_channel.set(dma_channel);
403 }
404
405 pub fn set_rx_dma_channel(&'static self, dma_channel: &'static dma::DmaChannel) {
407 dma_channel.set_client(self, self.rx_dma_source);
408 unsafe {
409 dma_channel.set_source(core::ptr::addr_of!(self.registers.data) as *const u8);
411 }
412 dma_channel.set_interrupt_on_completion(true);
413 dma_channel.set_disable_on_completion(true);
414 self.rx_dma_channel.set(dma_channel);
415 }
416
417 pub fn is_enabled_clock(&self) -> bool {
418 self.clock.is_enabled()
419 }
420
421 pub fn enable_clock(&self) {
422 self.clock.enable();
423 }
424
425 pub fn disable_clock(&self) {
426 self.clock.disable();
427 }
428
429 pub fn set_baud(&self) {
430 self.registers.baud.modify(BAUD::SBR.val(139_u32));
432 }
433
434 pub fn send_byte(&self, byte: u8) {
436 while !self.registers.stat.is_set(STAT::TDRE) {}
438
439 self.registers.data.set(byte.into());
440
441 while !self.registers.stat.is_set(STAT::TC) {}
442 }
443
444 pub fn is_transmit_enabled(&self) -> bool {
446 self.registers.ctrl.is_set(CTRL::TE)
447 }
448
449 pub fn is_receive_enabled(&self) -> bool {
451 self.registers.ctrl.is_set(CTRL::RE)
452 }
453
454 fn enable_transmit_complete_interrupt(&self) {
455 self.registers.ctrl.modify(CTRL::TIE::SET);
456 }
457
458 fn disable_transmit_complete_interrupt(&self) {
459 self.registers.ctrl.modify(CTRL::TIE::CLEAR);
460 }
461
462 fn clear_transmit_complete(&self) {
463 self.registers.stat.modify(STAT::TDRE::CLEAR);
464 }
465
466 fn enable_receive_interrupt(&self) {
467 self.registers.ctrl.modify(CTRL::RIE::SET);
468 }
469
470 fn disable_receive_interrupt(&self) {
471 self.registers.ctrl.modify(CTRL::RIE::CLEAR);
472 }
473
474 fn clear_overrun(&self) {
475 self.registers.ctrl.modify(CTRL::ORIE::CLEAR);
476 }
477
478 pub fn handle_interrupt(&self) {
479 if self.registers.stat.is_set(STAT::TDRE) {
480 self.clear_transmit_complete();
481 self.disable_transmit_complete_interrupt();
482
483 if self.tx_status.get() == LPUARTStateTX::Transmitting {
485 let position = self.tx_position.get();
486 if position < self.tx_len.get() {
487 self.tx_buffer.map(|buf| {
488 self.registers.data.set(buf[position].into());
489 self.tx_position.replace(self.tx_position.get() + 1);
490 self.enable_transmit_complete_interrupt();
491 });
492 } else {
493 self.tx_status.replace(LPUARTStateTX::Idle);
495 }
496 if self.tx_status.get() == LPUARTStateTX::Idle {
498 self.tx_client.map(|client| {
499 if let Some(buf) = self.tx_buffer.take() {
500 client.transmitted_buffer(buf, self.tx_len.get(), Ok(()));
501 }
502 });
503 }
504 } else if self.tx_status.get() == LPUARTStateTX::AbortRequested {
505 self.tx_status.replace(LPUARTStateTX::Idle);
506 self.tx_client.map(|client| {
507 if let Some(buf) = self.tx_buffer.take() {
508 client.transmitted_buffer(
509 buf,
510 self.tx_position.get(),
511 Err(ErrorCode::CANCEL),
512 );
513 }
514 });
515 }
516 }
517
518 if self.registers.stat.is_set(STAT::RDRF) {
519 let byte = self.registers.data.get() as u8;
520
521 self.disable_receive_interrupt();
522
523 if self.rx_status.get() == USARTStateRX::Receiving {
525 if self.rx_position.get() < self.rx_len.get() {
526 self.rx_buffer.map(|buf| {
527 buf[self.rx_position.get()] = byte;
528 self.rx_position.replace(self.rx_position.get() + 1);
529 });
530 }
531 if self.rx_position.get() == self.rx_len.get() {
532 self.rx_status.replace(USARTStateRX::Idle);
534 } else {
535 self.enable_receive_interrupt();
536 }
537 if self.rx_status.get() == USARTStateRX::Idle {
539 self.rx_client.map(|client| {
540 if let Some(buf) = self.rx_buffer.take() {
541 client.received_buffer(
542 buf,
543 self.rx_len.get(),
544 Ok(()),
545 hil::uart::Error::None,
546 );
547 }
548 });
549 }
550 } else if self.rx_status.get() == USARTStateRX::AbortRequested {
551 self.rx_status.replace(USARTStateRX::Idle);
552 self.rx_client.map(|client| {
553 if let Some(buf) = self.rx_buffer.take() {
554 client.received_buffer(
555 buf,
556 self.rx_position.get(),
557 Err(ErrorCode::CANCEL),
558 hil::uart::Error::Aborted,
559 );
560 }
561 });
562 }
563 }
564
565 if self.registers.stat.is_set(STAT::OR) {
566 self.clear_overrun();
567 self.rx_status.replace(USARTStateRX::Idle);
568 self.rx_client.map(|client| {
569 if let Some(buf) = self.rx_buffer.take() {
570 client.received_buffer(
571 buf,
572 self.rx_position.get(),
573 Err(ErrorCode::CANCEL),
574 hil::uart::Error::OverrunError,
575 );
576 }
577 });
578 }
579 }
580
581 fn check_status(&self) -> kernel::hil::uart::Error {
582 use kernel::hil::uart::Error;
583 let stat = self.registers.stat.extract();
584 if stat.is_set(STAT::PF) {
585 Error::ParityError
586 } else if stat.is_set(STAT::FE) {
587 Error::FramingError
588 } else if stat.is_set(STAT::OR) {
589 Error::OverrunError
590 } else {
591 Error::None
592 }
593 }
594
595 fn clear_status(&self) {
597 self.registers.stat.modify(
598 STAT::IDLE::SET
599 + STAT::OR::SET
600 + STAT::NF::SET
601 + STAT::FE::SET
602 + STAT::PF::SET
603 + STAT::RXEDGIF::SET
604 + STAT::MA1F::SET
605 + STAT::MA2F::SET,
606 )
607 }
608
609 fn transmit_buffer_interrupt(
611 &self,
612 tx_data: &'static mut [u8],
613 tx_len: usize,
614 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
615 if self.tx_status.get() == LPUARTStateTX::Idle {
616 if tx_len <= tx_data.len() {
617 self.tx_buffer.put(Some(tx_data));
618 self.tx_position.set(0);
619 self.tx_len.set(tx_len);
620 self.tx_status.set(LPUARTStateTX::Transmitting);
621 self.enable_transmit_complete_interrupt();
622 Ok(())
623 } else {
624 Err((ErrorCode::SIZE, tx_data))
625 }
626 } else {
627 Err((ErrorCode::BUSY, tx_data))
628 }
629 }
630
631 fn transmit_buffer_dma(
637 &self,
638 tx_buffer: &'static mut [u8],
639 tx_len: usize,
640 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
641 if self.tx_buffer.is_some() {
642 return Err((ErrorCode::BUSY, tx_buffer));
643 } else if !self.is_transmit_enabled() {
644 return Err((ErrorCode::OFF, tx_buffer));
645 } else if tx_len > tx_buffer.len() {
646 return Err((ErrorCode::SIZE, tx_buffer));
647 } else if self.tx_dma_channel.is_none() {
648 return Err((ErrorCode::FAIL, tx_buffer));
649 }
650
651 self.tx_dma_channel
652 .map(move |dma_channel| unsafe {
653 dma_channel.set_source_buffer(&tx_buffer[..tx_len]);
654
655 self.tx_buffer.put(Some(tx_buffer));
656 self.tx_len.set(tx_len);
657 dma_channel.enable();
658 self.registers.baud.modify(BAUD::TDMAE::SET);
659 Ok(())
660 })
661 .unwrap() }
663
664 fn transmit_abort_interrupt(&self) -> Result<(), ErrorCode> {
666 if self.tx_status.get() != LPUARTStateTX::Idle {
667 self.tx_status.set(LPUARTStateTX::AbortRequested);
668 Err(ErrorCode::BUSY)
669 } else {
670 Ok(())
671 }
672 }
673
674 fn transmit_abort_dma(&self) -> Result<(), ErrorCode> {
676 self.registers.baud.modify(BAUD::TDMAE::CLEAR);
677 while self.registers.baud.is_set(BAUD::TDMAE) {
678 cortexm7::support::nop();
679 }
680 self.tx_dma_channel.map(|dma_channel| {
681 while dma_channel.is_hardware_signaling() {
682 cortexm7::support::nop();
683 }
684 dma_channel.disable();
685 });
686 Ok(())
687 }
688
689 fn receive_buffer_interrupt(
691 &self,
692 rx_buffer: &'static mut [u8],
693 rx_len: usize,
694 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
695 if self.rx_status.get() == USARTStateRX::Idle {
696 if rx_len <= rx_buffer.len() {
697 self.rx_buffer.put(Some(rx_buffer));
698 self.rx_position.set(0);
699 self.rx_len.set(rx_len);
700 self.rx_status.set(USARTStateRX::Receiving);
701 self.enable_receive_interrupt();
702 Ok(())
703 } else {
704 Err((ErrorCode::SIZE, rx_buffer))
705 }
706 } else {
707 Err((ErrorCode::BUSY, rx_buffer))
708 }
709 }
710
711 fn receive_buffer_dma(
717 &self,
718 rx_buffer: &'static mut [u8],
719 rx_size: usize,
720 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
721 if self.rx_buffer.is_some() {
722 return Err((ErrorCode::BUSY, rx_buffer));
723 } else if !self.is_receive_enabled() {
724 return Err((ErrorCode::OFF, rx_buffer));
725 } else if rx_size > rx_buffer.len() {
726 return Err((ErrorCode::SIZE, rx_buffer));
727 } else if self.rx_dma_channel.is_none() {
728 return Err((ErrorCode::FAIL, rx_buffer));
729 }
730
731 self.rx_dma_channel
732 .map(move |dma_channel| unsafe {
733 dma_channel.set_destination_buffer(&mut rx_buffer[..rx_size]);
734
735 self.clear_status();
736 self.rx_buffer.put(Some(rx_buffer));
737 self.rx_len.set(rx_size);
738
739 dma_channel.enable();
740 self.registers.baud.modify(BAUD::RDMAE::SET);
741 Ok(())
742 })
743 .unwrap() }
745
746 fn receive_abort_interrupt(&self) -> Result<(), ErrorCode> {
748 if self.rx_status.get() != USARTStateRX::Idle {
749 self.rx_status.set(USARTStateRX::AbortRequested);
750 Err(ErrorCode::BUSY)
751 } else {
752 Ok(())
753 }
754 }
755
756 fn receive_abort_dma(&self) -> Result<(), ErrorCode> {
758 self.registers.baud.modify(BAUD::RDMAE::CLEAR);
759 while self.registers.baud.is_set(BAUD::RDMAE) {
760 cortexm7::support::nop();
761 }
762
763 self.rx_dma_channel.map(|dma_channel| {
764 while dma_channel.is_hardware_signaling() {
765 cortexm7::support::nop();
766 }
767 dma_channel.disable()
768 });
769 Ok(())
770 }
771}
772
773impl<'a> hil::uart::Transmit<'a> for Lpuart<'a> {
774 fn set_transmit_client(&self, client: &'a dyn hil::uart::TransmitClient) {
775 self.tx_client.set(client);
776 }
777
778 fn transmit_buffer(
779 &self,
780 tx_data: &'static mut [u8],
781 tx_len: usize,
782 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
783 if self.tx_dma_channel.is_some() {
784 self.transmit_buffer_dma(tx_data, tx_len)
785 } else {
786 self.transmit_buffer_interrupt(tx_data, tx_len)
787 }
788 }
789
790 fn transmit_word(&self, _word: u32) -> Result<(), ErrorCode> {
791 Err(ErrorCode::FAIL)
793 }
794
795 fn transmit_abort(&self) -> Result<(), ErrorCode> {
796 if self.tx_dma_channel.is_some() {
797 self.transmit_abort_dma()
798 } else {
799 self.transmit_abort_interrupt()
800 }
801 }
802}
803
804impl hil::uart::Configure for Lpuart<'_> {
805 fn configure(&self, params: hil::uart::Parameters) -> Result<(), ErrorCode> {
806 if params.baud_rate != 115200
807 || params.stop_bits != hil::uart::StopBits::One
808 || params.parity != hil::uart::Parity::None
809 || params.hw_flow_control
810 || params.width != hil::uart::Width::Eight
811 {
812 panic!(
813 "Currently we only support uart setting of 115200bps 8N1, no hardware flow control"
814 );
815 }
816
817 self.enable_clock();
818 self.registers.global.modify(GLOBAL::RST::SET);
820 self.registers.global.modify(GLOBAL::RST::CLEAR);
821
822 self.registers.baud.modify(BAUD::BOTHEDGE::SET);
824
825 self.registers.baud.modify(BAUD::OSR.val(0b100_u32));
827
828 self.registers.baud.modify(BAUD::SBR.val(139_u32));
830
831 self.registers.baud.modify(BAUD::M10::CLEAR);
833
834 self.registers.ctrl.modify(CTRL::PE::CLEAR);
835 self.registers.ctrl.modify(CTRL::PT::CLEAR);
836 self.registers.ctrl.modify(CTRL::M::CLEAR);
837 self.registers.ctrl.modify(CTRL::ILT::CLEAR);
838 self.registers.ctrl.modify(CTRL::IDLECFG::CLEAR);
839
840 self.registers.baud.modify(BAUD::SBNS::CLEAR);
842
843 self.registers.water.modify(WATER::RXWATER::CLEAR);
845 self.registers.water.modify(WATER::TXWATER::CLEAR);
846
847 self.registers.fifo.modify(FIFO::TXFE::CLEAR);
849 self.registers.fifo.modify(FIFO::RXFE::CLEAR);
850
851 self.registers.fifo.modify(FIFO::TXFLUSH::SET);
853 self.registers.fifo.modify(FIFO::RXFLUSH::SET);
854
855 self.clear_status();
856
857 self.registers.modir.modify(MODIR::TXCTSC::CLEAR);
859 self.registers.modir.modify(MODIR::TXCTSSRC::CLEAR);
860
861 self.registers.stat.modify(STAT::MSBF::CLEAR);
863
864 self.registers.ctrl.modify(CTRL::TE::SET);
866 self.registers.ctrl.modify(CTRL::RE::SET);
867
868 Ok(())
869 }
870}
871
872impl<'a> hil::uart::Receive<'a> for Lpuart<'a> {
873 fn set_receive_client(&self, client: &'a dyn hil::uart::ReceiveClient) {
874 self.rx_client.set(client);
875 }
876
877 fn receive_buffer(
878 &self,
879 rx_buffer: &'static mut [u8],
880 rx_len: usize,
881 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
882 if self.rx_dma_channel.is_some() {
883 self.receive_buffer_dma(rx_buffer, rx_len)
884 } else {
885 self.receive_buffer_interrupt(rx_buffer, rx_len)
886 }
887 }
888
889 fn receive_word(&self) -> Result<(), ErrorCode> {
890 Err(ErrorCode::FAIL)
892 }
893
894 fn receive_abort(&self) -> Result<(), ErrorCode> {
895 if self.rx_dma_channel.is_some() {
896 self.receive_abort_dma()
897 } else {
898 self.receive_abort_interrupt()
899 }
900 }
901}
902
903struct LpuartClock<'a>(ccm::PeripheralClock<'a>);
904
905impl ClockInterface for LpuartClock<'_> {
906 fn is_enabled(&self) -> bool {
907 self.0.is_enabled()
908 }
909
910 fn enable(&self) {
911 self.0.enable();
912 }
913
914 fn disable(&self) {
915 self.0.disable();
916 }
917}
918
919impl dma::DmaClient for Lpuart<'_> {
920 fn transfer_complete(&self, result: dma::Result) {
921 match result {
922 Ok(source) if source == self.tx_dma_source => {
924 self.registers.baud.modify(BAUD::TDMAE::CLEAR);
925 let result = if self.registers.fifo.is_set(FIFO::TXOF) {
926 Err(ErrorCode::FAIL)
927 } else {
928 Ok(())
929 };
930 self.tx_client.map(|client| {
931 client.transmitted_buffer(
932 self.tx_buffer.take().unwrap(),
933 self.tx_len.take(),
934 result,
935 );
936 });
937 }
938 Err(source) if source == self.tx_dma_source => {
940 self.registers.baud.modify(BAUD::TDMAE::CLEAR);
941 self.tx_client.map(|client| {
942 client.transmitted_buffer(
943 self.tx_buffer.take().unwrap(),
944 self.tx_len.take(),
945 Err(ErrorCode::FAIL),
946 );
947 });
948 }
949 Ok(source) if source == self.rx_dma_source => {
951 self.registers.baud.modify(BAUD::RDMAE::CLEAR);
952 let err = self.check_status();
953 let code = if kernel::hil::uart::Error::None == err {
954 Ok(())
955 } else {
956 Err(ErrorCode::FAIL)
957 };
958 self.rx_client.map(|client| {
959 client.received_buffer(
960 self.rx_buffer.take().unwrap(),
961 self.rx_len.take(),
962 code,
963 err,
964 );
965 });
966 }
967 Err(source) if source == self.rx_dma_source => {
969 self.registers.baud.modify(BAUD::RDMAE::CLEAR);
970 self.rx_client.map(|client| {
971 client.received_buffer(
972 self.rx_buffer.take().unwrap(),
973 self.rx_len.take(),
974 Err(ErrorCode::FAIL),
975 kernel::hil::uart::Error::Aborted,
976 );
977 });
978 }
979 _ => panic!("DMA channel has reference to the wrong DMA client"),
980 }
981 }
982}