1use core::cell::Cell;
6use kernel::deferred_call::{DeferredCall, DeferredCallClient};
7use kernel::hil;
8use kernel::platform::chip::ClockInterface;
9use kernel::utilities::cells::{OptionalCell, TakeCell};
10use kernel::utilities::leasable_buffer::SubSliceMut;
11use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
12use kernel::utilities::registers::{register_bitfields, ReadWrite};
13use kernel::utilities::StaticRef;
14use kernel::ErrorCode;
15
16use crate::clocks::{phclk, Stm32f4Clocks};
17use crate::dma;
18
19#[repr(C)]
21pub struct UsartRegisters {
22 sr: ReadWrite<u32, SR::Register>,
24 dr: ReadWrite<u32>,
26 brr: ReadWrite<u32, BRR::Register>,
28 cr1: ReadWrite<u32, CR1::Register>,
30 cr2: ReadWrite<u32, CR2::Register>,
32 cr3: ReadWrite<u32, CR3::Register>,
34 gtpr: ReadWrite<u32, GTPR::Register>,
36}
37
38register_bitfields![u32,
39 SR [
40 CTS OFFSET(9) NUMBITS(1) [],
42 LBD OFFSET(8) NUMBITS(1) [],
44 TXE OFFSET(7) NUMBITS(1) [],
46 TC OFFSET(6) NUMBITS(1) [],
48 RXNE OFFSET(5) NUMBITS(1) [],
50 IDLE OFFSET(4) NUMBITS(1) [],
52 ORE OFFSET(3) NUMBITS(1) [],
54 NF OFFSET(2) NUMBITS(1) [],
56 FE OFFSET(1) NUMBITS(1) [],
58 PE OFFSET(0) NUMBITS(1) []
60 ],
61 BRR [
62 DIV_Mantissa OFFSET(4) NUMBITS(12) [],
64 DIV_Fraction OFFSET(0) NUMBITS(4) []
66 ],
67 CR1 [
68 OVER8 OFFSET(15) NUMBITS(1) [],
70 UE OFFSET(13) NUMBITS(1) [],
72 M OFFSET(12) NUMBITS(1) [],
74 WAKE OFFSET(11) NUMBITS(1) [],
76 PCE OFFSET(10) NUMBITS(1) [],
78 PS OFFSET(9) NUMBITS(1) [],
80 PEIE OFFSET(8) NUMBITS(1) [],
82 TXEIE OFFSET(7) NUMBITS(1) [],
84 TCIE OFFSET(6) NUMBITS(1) [],
86 RXNEIE OFFSET(5) NUMBITS(1) [],
88 IDLEIE OFFSET(4) NUMBITS(1) [],
90 TE OFFSET(3) NUMBITS(1) [],
92 RE OFFSET(2) NUMBITS(1) [],
94 RWU OFFSET(1) NUMBITS(1) [],
96 SBK OFFSET(0) NUMBITS(1) []
98 ],
99 CR2 [
100 LINEN OFFSET(14) NUMBITS(1) [],
102 STOP OFFSET(12) NUMBITS(2) [],
104 CLKEN OFFSET(11) NUMBITS(1) [],
106 CPOL OFFSET(10) NUMBITS(1) [],
108 CPHA OFFSET(9) NUMBITS(1) [],
110 LBCL OFFSET(8) NUMBITS(1) [],
112 LBDIE OFFSET(6) NUMBITS(1) [],
114 LBDL OFFSET(5) NUMBITS(1) [],
116 ADD OFFSET(0) NUMBITS(4) []
118 ],
119 CR3 [
120 ONEBIT OFFSET(11) NUMBITS(1) [],
122 CTSIE OFFSET(10) NUMBITS(1) [],
124 CTSE OFFSET(9) NUMBITS(1) [],
126 RTSE OFFSET(8) NUMBITS(1) [],
128 DMAT OFFSET(7) NUMBITS(1) [],
130 DMAR OFFSET(6) NUMBITS(1) [],
132 SCEN OFFSET(5) NUMBITS(1) [],
134 NACK OFFSET(4) NUMBITS(1) [],
136 HDSEL OFFSET(3) NUMBITS(1) [],
138 IRLP OFFSET(2) NUMBITS(1) [],
140 IREN OFFSET(1) NUMBITS(1) [],
142 EIE OFFSET(0) NUMBITS(1) []
144 ],
145 GTPR [
146 GT OFFSET(8) NUMBITS(8) [],
148 PSC OFFSET(0) NUMBITS(8) []
150 ]
151];
152
153pub const USART1_BASE: StaticRef<UsartRegisters> =
156 unsafe { StaticRef::new(0x40011000 as *const UsartRegisters) };
157pub const USART2_BASE: StaticRef<UsartRegisters> =
158 unsafe { StaticRef::new(0x40004400 as *const UsartRegisters) };
159pub const USART3_BASE: StaticRef<UsartRegisters> =
160 unsafe { StaticRef::new(0x40004800 as *const UsartRegisters) };
161
162pub(crate) fn get_address_dr(regs: StaticRef<UsartRegisters>) -> u32 {
164 core::ptr::addr_of!(regs.dr) as u32
165}
166
167#[allow(non_camel_case_types)]
168#[derive(Copy, Clone, PartialEq)]
169enum USARTStateRX {
170 Idle,
171 DMA_Receiving,
172 Aborted(Result<(), ErrorCode>, hil::uart::Error),
173}
174
175#[allow(non_camel_case_types)]
176#[derive(Copy, Clone, PartialEq)]
177enum USARTStateTX {
178 Idle,
179 DMA_Transmitting,
180 Aborted(Result<(), ErrorCode>),
181 Transfer_Completing, }
183
184pub struct Usart<'a, DMA: dma::StreamServer<'a>> {
185 registers: StaticRef<UsartRegisters>,
186 clock: UsartClock<'a>,
187
188 tx_client: OptionalCell<&'a dyn hil::uart::TransmitClient>,
189 rx_client: OptionalCell<&'a dyn hil::uart::ReceiveClient>,
190
191 tx_dma: OptionalCell<&'a dma::Stream<'a, DMA>>,
192 tx_dma_pid: DMA::Peripheral,
193 rx_dma: OptionalCell<&'a dma::Stream<'a, DMA>>,
194 rx_dma_pid: DMA::Peripheral,
195
196 tx_len: Cell<usize>,
197 rx_len: Cell<usize>,
198
199 usart_tx_state: Cell<USARTStateTX>,
200 usart_rx_state: Cell<USARTStateRX>,
201
202 partial_tx_buffer: TakeCell<'static, [u8]>,
203 partial_tx_len: Cell<usize>,
204
205 partial_rx_buffer: TakeCell<'static, [u8]>,
206 partial_rx_len: Cell<usize>,
207
208 deferred_call: DeferredCall,
209}
210
211pub struct TxDMA<'a, DMA: dma::StreamServer<'a>>(pub &'a dma::Stream<'a, DMA>);
213pub struct RxDMA<'a, DMA: dma::StreamServer<'a>>(pub &'a dma::Stream<'a, DMA>);
214
215impl<'a> Usart<'a, dma::Dma1<'a>> {
216 pub fn new_usart2(clocks: &'a dyn Stm32f4Clocks) -> Self {
217 Self::new(
218 USART2_BASE,
219 UsartClock(phclk::PeripheralClock::new(
220 phclk::PeripheralClockType::APB1(phclk::PCLK1::USART2),
221 clocks,
222 )),
223 dma::Dma1Peripheral::USART2_TX,
224 dma::Dma1Peripheral::USART2_RX,
225 )
226 }
227
228 pub fn new_usart3(clocks: &'a dyn Stm32f4Clocks) -> Self {
229 Self::new(
230 USART3_BASE,
231 UsartClock(phclk::PeripheralClock::new(
232 phclk::PeripheralClockType::APB1(phclk::PCLK1::USART3),
233 clocks,
234 )),
235 dma::Dma1Peripheral::USART3_TX,
236 dma::Dma1Peripheral::USART3_RX,
237 )
238 }
239}
240
241impl<'a> Usart<'a, dma::Dma2<'a>> {
242 pub fn new_usart1(clocks: &'a dyn Stm32f4Clocks) -> Self {
243 Self::new(
244 USART1_BASE,
245 UsartClock(phclk::PeripheralClock::new(
246 phclk::PeripheralClockType::APB2(phclk::PCLK2::USART1),
247 clocks,
248 )),
249 dma::Dma2Peripheral::USART1_TX,
250 dma::Dma2Peripheral::USART1_RX,
251 )
252 }
253}
254
255impl<'a, DMA: dma::StreamServer<'a>> Usart<'a, DMA> {
256 fn new(
257 base_addr: StaticRef<UsartRegisters>,
258 clock: UsartClock<'a>,
259 tx_dma_pid: DMA::Peripheral,
260 rx_dma_pid: DMA::Peripheral,
261 ) -> Usart<'a, DMA> {
262 Usart {
263 registers: base_addr,
264 clock,
265
266 tx_client: OptionalCell::empty(),
267 rx_client: OptionalCell::empty(),
268
269 tx_dma: OptionalCell::empty(),
270 tx_dma_pid,
271 rx_dma: OptionalCell::empty(),
272 rx_dma_pid,
273
274 tx_len: Cell::new(0),
275 rx_len: Cell::new(0),
276
277 usart_tx_state: Cell::new(USARTStateTX::Idle),
278 usart_rx_state: Cell::new(USARTStateRX::Idle),
279
280 partial_tx_buffer: TakeCell::empty(),
281 partial_tx_len: Cell::new(0),
282
283 partial_rx_buffer: TakeCell::empty(),
284 partial_rx_len: Cell::new(0),
285
286 deferred_call: DeferredCall::new(),
287 }
288 }
289
290 pub fn is_enabled_clock(&self) -> bool {
291 self.clock.is_enabled()
292 }
293
294 pub fn enable_clock(&self) {
295 self.clock.enable();
296 }
297
298 pub fn disable_clock(&self) {
299 self.clock.disable();
300 }
301
302 pub fn set_dma(&self, tx_dma: TxDMA<'a, DMA>, rx_dma: RxDMA<'a, DMA>) {
303 self.tx_dma.set(tx_dma.0);
304 self.rx_dma.set(rx_dma.0);
305 }
306
307 pub fn handle_interrupt(&self) {
310 if self.registers.sr.is_set(SR::TC) {
311 self.clear_transmit_complete();
312 self.disable_transmit_complete_interrupt();
313
314 if self.usart_tx_state.get() == USARTStateTX::Transfer_Completing {
317 self.disable_tx();
318 self.usart_tx_state.set(USARTStateTX::Idle);
319
320 let buffer = self.tx_dma.map_or(None, |tx_dma| tx_dma.return_buffer());
322 let len = self.tx_len.get();
323 self.tx_len.set(0);
324
325 self.tx_client.map(|client| {
327 buffer.map(|buf| {
328 let buf = buf.take();
329 client.transmitted_buffer(buf, len, Ok(()));
330 });
331 });
332 }
333 }
334
335 if self.is_enabled_error_interrupt() && self.registers.sr.is_set(SR::ORE) {
336 let _ = self.registers.dr.get(); if self.usart_rx_state.get() == USARTStateRX::DMA_Receiving {
338 self.usart_rx_state.set(USARTStateRX::Idle);
339
340 self.disable_rx();
341 self.disable_error_interrupt();
342
343 let (buffer, len) = self.rx_dma.map_or((None, 0), |rx_dma| {
345 rx_dma.abort_transfer()
347 });
348
349 let count = self.rx_len.get() - len as usize;
352 self.rx_len.set(0);
353
354 self.rx_client.map(|client| {
356 buffer.map(|buf| {
357 let buf = buf.take();
358 client.received_buffer(
359 buf,
360 count,
361 Err(ErrorCode::CANCEL),
362 hil::uart::Error::OverrunError,
363 );
364 })
365 });
366 }
367 }
368 }
369
370 pub fn send_byte(&self, byte: u8) {
372 while !self.registers.sr.is_set(SR::TXE) {}
374
375 self.registers.dr.set(byte.into());
376 }
377
378 fn enable_tx(&self) {
380 self.registers.cr3.modify(CR3::DMAT::SET);
381 }
382
383 fn disable_tx(&self) {
385 self.registers.cr3.modify(CR3::DMAT::CLEAR);
386 }
387
388 fn enable_rx(&self) {
390 self.registers.cr3.modify(CR3::DMAR::SET);
391 }
392
393 fn disable_rx(&self) {
395 self.registers.cr3.modify(CR3::DMAR::CLEAR);
396 }
397
398 fn enable_error_interrupt(&self) {
400 self.registers.cr3.modify(CR3::EIE::SET);
401 }
402
403 fn disable_error_interrupt(&self) {
405 self.registers.cr3.modify(CR3::EIE::CLEAR);
406 }
407
408 fn is_enabled_error_interrupt(&self) -> bool {
410 self.registers.cr3.is_set(CR3::EIE)
411 }
412
413 fn abort_tx(&self, rcode: Result<(), ErrorCode>) {
414 if matches!(self.usart_tx_state.get(), USARTStateTX::Aborted(_)) {
415 return;
416 }
417
418 self.disable_tx();
419
420 let (mut buffer, len) = self.tx_dma.map_or((None, 0), |tx_dma| {
422 tx_dma.abort_transfer()
424 });
425
426 let count = self.tx_len.get() - len as usize;
429 self.tx_len.set(0);
430
431 if let Some(buf) = buffer.take() {
432 let buf = buf.take();
433 self.partial_tx_buffer.replace(buf);
434 self.partial_tx_len.set(count);
435
436 self.usart_tx_state.set(USARTStateTX::Aborted(rcode));
437
438 self.deferred_call.set();
439 } else {
440 self.usart_tx_state.set(USARTStateTX::Idle);
441 }
442 }
443
444 fn abort_rx(&self, rcode: Result<(), ErrorCode>, error: hil::uart::Error) {
445 if matches!(self.usart_rx_state.get(), USARTStateRX::Aborted(_, _)) {
446 return;
447 }
448
449 self.disable_rx();
450 self.disable_error_interrupt();
451
452 let (mut buffer, len) = self.rx_dma.map_or((None, 0), |rx_dma| {
454 rx_dma.abort_transfer()
456 });
457
458 let count = self.rx_len.get() - len as usize;
461 self.rx_len.set(0);
462
463 if let Some(buf) = buffer.take() {
464 let buf = buf.take();
465 self.partial_rx_buffer.replace(buf);
466 self.partial_rx_len.set(count);
467
468 self.usart_rx_state.set(USARTStateRX::Aborted(rcode, error));
469
470 self.deferred_call.set();
471 } else {
472 self.usart_rx_state.set(USARTStateRX::Idle);
473 }
474 }
475
476 fn enable_transmit_complete_interrupt(&self) {
477 self.registers.cr1.modify(CR1::TCIE::SET);
478 }
479
480 fn disable_transmit_complete_interrupt(&self) {
481 self.registers.cr1.modify(CR1::TCIE::CLEAR);
482 }
483
484 fn clear_transmit_complete(&self) {
485 self.registers.sr.modify(SR::TC::CLEAR);
486 }
487
488 fn transfer_done(&self, pid: DMA::Peripheral) {
489 if pid == self.tx_dma_pid {
490 self.usart_tx_state.set(USARTStateTX::Transfer_Completing);
491 self.enable_transmit_complete_interrupt();
492 } else if pid == self.rx_dma_pid {
493 if self.usart_rx_state.get() == USARTStateRX::DMA_Receiving {
496 self.disable_rx();
497 self.disable_error_interrupt();
498 self.usart_rx_state.set(USARTStateRX::Idle);
499
500 let buffer = self.rx_dma.map_or(None, |rx_dma| rx_dma.return_buffer());
502
503 let length = self.rx_len.get();
504 self.rx_len.set(0);
505
506 self.rx_client.map(|client| {
508 buffer.map(|buf| {
509 let buf = buf.take();
510 client.received_buffer(buf, length, Ok(()), hil::uart::Error::None);
511 });
512 });
513 }
514 }
515 }
516
517 fn set_baud_rate(&self, baud_rate: u32) -> Result<(), ErrorCode> {
518 let pclk_freq = self.clock.0.get_frequency();
543
544 let (mantissa, fraction) = if (pclk_freq / 16) >= baud_rate {
545 let div = (pclk_freq + (baud_rate / 2)) / baud_rate;
550
551 self.registers.cr1.modify(CR1::OVER8::CLEAR);
552
553 (div >> 4, div & 0x0F)
554 } else if (pclk_freq / 8) >= baud_rate {
555 let div = ((pclk_freq * 2) + (baud_rate / 2)) / baud_rate;
560
561 self.registers.cr1.modify(CR1::OVER8::SET);
562
563 (div >> 4, (div & 0x0F) >> 1)
565 } else {
566 return Err(ErrorCode::INVAL);
567 };
568
569 self.registers.brr.modify(BRR::DIV_Mantissa.val(mantissa));
570 self.registers.brr.modify(BRR::DIV_Fraction.val(fraction));
571 Ok(())
572 }
573
574 pub fn disable(&self) -> Result<(), ErrorCode> {
576 if self.usart_tx_state.get() == USARTStateTX::DMA_Transmitting
577 || self.usart_tx_state.get() == USARTStateTX::Transfer_Completing
578 || self.usart_rx_state.get() == USARTStateRX::DMA_Receiving
579 {
580 Err(ErrorCode::BUSY)
581 } else {
582 self.registers.cr1.modify(CR1::UE::CLEAR);
583 Ok(())
584 }
585 }
586}
587
588impl<'a, DMA: dma::StreamServer<'a>> DeferredCallClient for Usart<'a, DMA> {
589 fn register(&'static self) {
590 self.deferred_call.register(self);
591 }
592
593 fn handle_deferred_call(&self) {
594 if let USARTStateTX::Aborted(rcode) = self.usart_tx_state.get() {
595 self.tx_client.map(|client| {
597 self.partial_tx_buffer.take().map(|buf| {
598 client.transmitted_buffer(buf, self.partial_tx_len.get(), rcode);
599 });
600 });
601 self.usart_tx_state.set(USARTStateTX::Idle);
602 }
603
604 if let USARTStateRX::Aborted(rcode, error) = self.usart_rx_state.get() {
605 self.rx_client.map(|client| {
607 self.partial_rx_buffer.take().map(|buf| {
608 client.received_buffer(buf, self.partial_rx_len.get(), rcode, error);
609 });
610 });
611 self.usart_rx_state.set(USARTStateRX::Idle);
612 }
613 }
614}
615
616impl<'a, DMA: dma::StreamServer<'a>> hil::uart::Transmit<'a> for Usart<'a, DMA> {
617 fn set_transmit_client(&self, client: &'a dyn hil::uart::TransmitClient) {
618 self.tx_client.set(client);
619 }
620
621 fn transmit_buffer(
622 &self,
623 tx_data: &'static mut [u8],
624 tx_len: usize,
625 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
626 if self.usart_tx_state.get() != USARTStateTX::Idle {
631 return Err((ErrorCode::BUSY, tx_data));
633 }
634
635 self.tx_dma.map(move |dma| {
637 self.tx_len.set(tx_len);
638 let mut tx_data: SubSliceMut<u8> = tx_data.into();
639 tx_data.slice(..tx_len);
640 dma.do_transfer(tx_data);
641 });
642
643 self.usart_tx_state.set(USARTStateTX::DMA_Transmitting);
644
645 self.enable_tx();
647 Ok(())
648 }
649
650 fn transmit_word(&self, _word: u32) -> Result<(), ErrorCode> {
651 Err(ErrorCode::FAIL)
652 }
653
654 fn transmit_abort(&self) -> Result<(), ErrorCode> {
655 if self.usart_tx_state.get() != USARTStateTX::Idle {
656 self.abort_tx(Err(ErrorCode::CANCEL));
657 Err(ErrorCode::BUSY)
658 } else {
659 Ok(())
660 }
661 }
662}
663
664impl<'a, DMA: dma::StreamServer<'a>> hil::uart::Configure for Usart<'a, DMA> {
665 fn configure(&self, params: hil::uart::Parameters) -> Result<(), ErrorCode> {
666 if params.stop_bits != hil::uart::StopBits::One
667 || params.parity != hil::uart::Parity::None
668 || params.hw_flow_control
669 || params.width != hil::uart::Width::Eight
670 {
671 panic!("Currently we only support uart setting of 8N1, no hardware flow control");
672 }
673
674 self.registers.cr1.modify(CR1::M::CLEAR);
676
677 self.registers.cr2.modify(CR2::STOP.val(0b00_u32));
679
680 self.registers.cr1.modify(CR1::PCE::CLEAR);
682
683 self.set_baud_rate(params.baud_rate)?;
684
685 self.registers.cr1.modify(CR1::TE::SET);
687
688 self.registers.cr1.modify(CR1::RE::SET);
690
691 self.registers.cr1.modify(CR1::UE::SET);
693
694 Ok(())
695 }
696}
697
698impl<'a, DMA: dma::StreamServer<'a>> hil::uart::Receive<'a> for Usart<'a, DMA> {
699 fn set_receive_client(&self, client: &'a dyn hil::uart::ReceiveClient) {
700 self.rx_client.set(client);
701 }
702
703 fn receive_buffer(
704 &self,
705 rx_buffer: &'static mut [u8],
706 rx_len: usize,
707 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
708 if self.usart_rx_state.get() != USARTStateRX::Idle {
709 return Err((ErrorCode::BUSY, rx_buffer));
710 }
711
712 if rx_len > rx_buffer.len() {
713 return Err((ErrorCode::SIZE, rx_buffer));
714 }
715
716 self.rx_dma.map(move |dma| {
718 self.rx_len.set(rx_len);
719 let mut rx_buffer: SubSliceMut<u8> = rx_buffer.into();
720 rx_buffer.slice(..rx_len);
721 dma.do_transfer(rx_buffer);
722 });
723
724 self.usart_rx_state.set(USARTStateRX::DMA_Receiving);
725
726 self.enable_error_interrupt();
727
728 self.enable_rx();
730 Ok(())
731 }
732
733 fn receive_word(&self) -> Result<(), ErrorCode> {
734 Err(ErrorCode::FAIL)
735 }
736
737 fn receive_abort(&self) -> Result<(), ErrorCode> {
738 if self.usart_rx_state.get() != USARTStateRX::Idle {
739 self.abort_rx(Err(ErrorCode::CANCEL), hil::uart::Error::Aborted);
740 Err(ErrorCode::BUSY)
741 } else {
742 Ok(())
743 }
744 }
745}
746
747impl<'a> dma::StreamClient<'a, dma::Dma1<'a>> for Usart<'a, dma::Dma1<'a>> {
748 fn transfer_done(&self, pid: dma::Dma1Peripheral) {
749 self.transfer_done(pid);
750 }
751}
752
753impl<'a> dma::StreamClient<'a, dma::Dma2<'a>> for Usart<'a, dma::Dma2<'a>> {
754 fn transfer_done(&self, pid: dma::Dma2Peripheral) {
755 self.transfer_done(pid);
756 }
757}
758
759struct UsartClock<'a>(phclk::PeripheralClock<'a>);
760
761impl ClockInterface for UsartClock<'_> {
762 fn is_enabled(&self) -> bool {
763 self.0.is_enabled()
764 }
765
766 fn enable(&self) {
767 self.0.enable();
768 }
769
770 fn disable(&self) {
771 self.0.disable();
772 }
773}