stm32f4xx/
usart.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5use 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/// Universal synchronous asynchronous receiver transmitter
20#[repr(C)]
21pub struct UsartRegisters {
22    /// Status register
23    sr: ReadWrite<u32, SR::Register>,
24    /// Data register
25    dr: ReadWrite<u32>,
26    /// Baud rate register
27    brr: ReadWrite<u32, BRR::Register>,
28    /// Control register 1
29    cr1: ReadWrite<u32, CR1::Register>,
30    /// Control register 2
31    cr2: ReadWrite<u32, CR2::Register>,
32    /// Control register 3
33    cr3: ReadWrite<u32, CR3::Register>,
34    /// Guard time and prescaler register
35    gtpr: ReadWrite<u32, GTPR::Register>,
36}
37
38register_bitfields![u32,
39    SR [
40        /// CTS flag
41        CTS OFFSET(9) NUMBITS(1) [],
42        /// LIN break detection flag
43        LBD OFFSET(8) NUMBITS(1) [],
44        /// Transmit data register empty
45        TXE OFFSET(7) NUMBITS(1) [],
46        /// Transmission complete
47        TC OFFSET(6) NUMBITS(1) [],
48        /// Read data register not empty
49        RXNE OFFSET(5) NUMBITS(1) [],
50        /// IDLE line detected
51        IDLE OFFSET(4) NUMBITS(1) [],
52        /// Overrun error
53        ORE OFFSET(3) NUMBITS(1) [],
54        /// Noise detected flag
55        NF OFFSET(2) NUMBITS(1) [],
56        /// Framing error
57        FE OFFSET(1) NUMBITS(1) [],
58        /// Parity error
59        PE OFFSET(0) NUMBITS(1) []
60    ],
61    BRR [
62        /// mantissa of USARTDIV
63        DIV_Mantissa OFFSET(4) NUMBITS(12) [],
64        /// fraction of USARTDIV
65        DIV_Fraction OFFSET(0) NUMBITS(4) []
66    ],
67    CR1 [
68        /// Oversampling mode
69        OVER8 OFFSET(15) NUMBITS(1) [],
70        /// USART enable
71        UE OFFSET(13) NUMBITS(1) [],
72        /// Word length
73        M OFFSET(12) NUMBITS(1) [],
74        /// Wakeup method
75        WAKE OFFSET(11) NUMBITS(1) [],
76        /// Parity control enable
77        PCE OFFSET(10) NUMBITS(1) [],
78        /// Parity selection
79        PS OFFSET(9) NUMBITS(1) [],
80        /// PE interrupt enable
81        PEIE OFFSET(8) NUMBITS(1) [],
82        /// TXE interrupt enable
83        TXEIE OFFSET(7) NUMBITS(1) [],
84        /// Transmission complete interrupt enable
85        TCIE OFFSET(6) NUMBITS(1) [],
86        /// RXNE interrupt enable
87        RXNEIE OFFSET(5) NUMBITS(1) [],
88        /// IDLE interrupt enable
89        IDLEIE OFFSET(4) NUMBITS(1) [],
90        /// Transmitter enable
91        TE OFFSET(3) NUMBITS(1) [],
92        /// Receiver enable
93        RE OFFSET(2) NUMBITS(1) [],
94        /// Receiver wakeup
95        RWU OFFSET(1) NUMBITS(1) [],
96        /// Send break
97        SBK OFFSET(0) NUMBITS(1) []
98    ],
99    CR2 [
100        /// LIN mode enable
101        LINEN OFFSET(14) NUMBITS(1) [],
102        /// STOP bits
103        STOP OFFSET(12) NUMBITS(2) [],
104        /// Clock enable
105        CLKEN OFFSET(11) NUMBITS(1) [],
106        /// Clock polarity
107        CPOL OFFSET(10) NUMBITS(1) [],
108        /// Clock phase
109        CPHA OFFSET(9) NUMBITS(1) [],
110        /// Last bit clock pulse
111        LBCL OFFSET(8) NUMBITS(1) [],
112        /// LIN break detection interrupt enable
113        LBDIE OFFSET(6) NUMBITS(1) [],
114        /// lin break detection length
115        LBDL OFFSET(5) NUMBITS(1) [],
116        /// Address of the USART node
117        ADD OFFSET(0) NUMBITS(4) []
118    ],
119    CR3 [
120        /// One sample bit method enable
121        ONEBIT OFFSET(11) NUMBITS(1) [],
122        /// CTS interrupt enable
123        CTSIE OFFSET(10) NUMBITS(1) [],
124        /// CTS enable
125        CTSE OFFSET(9) NUMBITS(1) [],
126        /// RTS enable
127        RTSE OFFSET(8) NUMBITS(1) [],
128        /// DMA enable transmitter
129        DMAT OFFSET(7) NUMBITS(1) [],
130        /// DMA enable receiver
131        DMAR OFFSET(6) NUMBITS(1) [],
132        /// Smartcard mode enable
133        SCEN OFFSET(5) NUMBITS(1) [],
134        /// Smartcard NACK enable
135        NACK OFFSET(4) NUMBITS(1) [],
136        /// Half-duplex selection
137        HDSEL OFFSET(3) NUMBITS(1) [],
138        /// IrDA low-power
139        IRLP OFFSET(2) NUMBITS(1) [],
140        /// IrDA mode enable
141        IREN OFFSET(1) NUMBITS(1) [],
142        /// Error interrupt enable
143        EIE OFFSET(0) NUMBITS(1) []
144    ],
145    GTPR [
146        /// Guard time value
147        GT OFFSET(8) NUMBITS(8) [],
148        /// Prescaler value
149        PSC OFFSET(0) NUMBITS(8) []
150    ]
151];
152
153// See Table 13. STM32F427xx and STM32F429xx register boundary addresses
154// of the STM32F429zi datasheet
155pub 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
162// for use by dma1
163pub(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, // DMA finished, but not all bytes sent
182}
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
211// for use by `set_dma`
212pub 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    // According to section 25.4.13, we need to make sure that USART TC flag is
308    // set before disabling the DMA TX on the peripheral side.
309    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            // Ignore if USARTStateTX is in some other state other than
315            // Transfer_Completing.
316            if self.usart_tx_state.get() == USARTStateTX::Transfer_Completing {
317                self.disable_tx();
318                self.usart_tx_state.set(USARTStateTX::Idle);
319
320                // get buffer
321                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                // alert client
326                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(); // clear overrun error
337            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                // get buffer
344                let (buffer, len) = self.rx_dma.map_or((None, 0), |rx_dma| {
345                    // `abort_transfer` also disables the stream
346                    rx_dma.abort_transfer()
347                });
348
349                // The number actually received is the difference between
350                // the requested number and the number remaining in DMA transfer.
351                let count = self.rx_len.get() - len as usize;
352                self.rx_len.set(0);
353
354                // alert client
355                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    // for use by panic in io.rs
371    pub fn send_byte(&self, byte: u8) {
372        // loop till TXE (Transmit data register empty) becomes 1
373        while !self.registers.sr.is_set(SR::TXE) {}
374
375        self.registers.dr.set(byte.into());
376    }
377
378    // enable DMA TX from the peripheral side
379    fn enable_tx(&self) {
380        self.registers.cr3.modify(CR3::DMAT::SET);
381    }
382
383    // disable DMA TX from the peripheral side
384    fn disable_tx(&self) {
385        self.registers.cr3.modify(CR3::DMAT::CLEAR);
386    }
387
388    // enable DMA RX from the peripheral side
389    fn enable_rx(&self) {
390        self.registers.cr3.modify(CR3::DMAR::SET);
391    }
392
393    // disable DMA RX from the peripheral side
394    fn disable_rx(&self) {
395        self.registers.cr3.modify(CR3::DMAR::CLEAR);
396    }
397
398    // enable interrupts for framing, overrun and noise errors
399    fn enable_error_interrupt(&self) {
400        self.registers.cr3.modify(CR3::EIE::SET);
401    }
402
403    // disable interrupts for framing, overrun and noise errors
404    fn disable_error_interrupt(&self) {
405        self.registers.cr3.modify(CR3::EIE::CLEAR);
406    }
407
408    // check if interrupts for framing, overrun and noise errors are enbaled
409    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        // get buffer
421        let (mut buffer, len) = self.tx_dma.map_or((None, 0), |tx_dma| {
422            // `abort_transfer` also disables the stream
423            tx_dma.abort_transfer()
424        });
425
426        // The number actually transmitted is the difference between
427        // the requested number and the number remaining in DMA transfer.
428        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        // get buffer
453        let (mut buffer, len) = self.rx_dma.map_or((None, 0), |rx_dma| {
454            // `abort_transfer` also disables the stream
455            rx_dma.abort_transfer()
456        });
457
458        // The number actually received is the difference between
459        // the requested number and the number remaining in DMA transfer.
460        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            // In case of RX, we can call the client directly without having
494            // to trigger an interrupt.
495            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                // get buffer
501                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                // alert client
507                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        // USARTDIV calculation based on stm32-rs stm32f4xx-hal:
519        // https://github.com/stm32-rs/stm32f4xx-hal/blob/v0.20.0/src/serial/uart_impls.rs#L145
520        //
521        // The equation to calculate USARTDIV is this:
522        //
523        // (Taken from STM32F411xC/E Reference Manual, Section 19.3.4, Equation 1)
524        //
525        // 16 bit oversample: OVER8 = 0
526        // 8 bit oversample:  OVER8 = 1
527        //
528        // USARTDIV =          (pclk)
529        //            ------------------------
530        //            8 x (2 - OVER8) x (baud)
531        //
532        // BUT, the USARTDIV has 4 "fractional" bits, which effectively means that we need to
533        // "correct" the equation as follows:
534        //
535        // USARTDIV =      (pclk) * 16
536        //            ------------------------
537        //            8 x (2 - OVER8) x (baud)
538        //
539        // When OVER8 is enabled, we can only use the lowest three fractional bits, so we'll need
540        // to shift those last four bits right one bit
541
542        let pclk_freq = self.clock.0.get_frequency();
543
544        let (mantissa, fraction) = if (pclk_freq / 16) >= baud_rate {
545            // We have the ability to oversample to 16 bits, take advantage of it.
546            //
547            // We also add `baud / 2` to the `pclk_freq` to ensure rounding of values to the
548            // closest scale, rather than the floored behavior of normal integer division.
549            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            // We are close enough to pclk where we can only
556            // oversample 8.
557
558            // See note above regarding `baud` and rounding.
559            let div = ((pclk_freq * 2) + (baud_rate / 2)) / baud_rate;
560
561            self.registers.cr1.modify(CR1::OVER8::SET);
562
563            // Ensure the the fractional bits (only 3) are right-aligned.
564            (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    // try to disable the USART and return BUSY if a transfer is taking place
575    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            // alert client
596            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            // alert client
606            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        // In virtual_uart.rs, transmit is only called when inflight is None. So
627        // if the state machine is working correctly, transmit should never
628        // abort.
629
630        if self.usart_tx_state.get() != USARTStateTX::Idle {
631            // there is an ongoing transmission, quit it
632            return Err((ErrorCode::BUSY, tx_data));
633        }
634
635        // setup and enable dma stream
636        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        // enable dma tx on peripheral side
646        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        // Configure the word length - 0: 1 Start bit, 8 Data bits, n Stop bits
675        self.registers.cr1.modify(CR1::M::CLEAR);
676
677        // Set the stop bit length - 00: 1 Stop bits
678        self.registers.cr2.modify(CR2::STOP.val(0b00_u32));
679
680        // Set no parity
681        self.registers.cr1.modify(CR1::PCE::CLEAR);
682
683        self.set_baud_rate(params.baud_rate)?;
684
685        // Enable transmit block
686        self.registers.cr1.modify(CR1::TE::SET);
687
688        // Enable receive block
689        self.registers.cr1.modify(CR1::RE::SET);
690
691        // Enable USART
692        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        // setup and enable dma stream
717        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        // enable dma rx on the peripheral side
729        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}