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}