Skip to main content

hal_mik32/
usart.rs

1//! USART
2
3use core::fmt;
4use core::marker::PhantomData;
5
6use embedded_hal_nb::nb::{Error as NbError, Result as NbResult};
7use embedded_hal_nb::serial::{ErrorKind, ErrorType, Read, Write};
8use mik32_pac::usart_0::RegisterBlock;
9use mik32_pac::{Peripherals, Usart0, Usart1};
10
11use crate::constants::{DIV_AHB, DIV_APB_P};
12use crate::gpio::{Func2Mode, Pin};
13use crate::rcc::system_clock;
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub enum WordLength {
17    DataBits7,
18    DataBits8,
19    DataBits9,
20}
21
22#[derive(Debug, Clone, Copy, PartialEq, Eq)]
23pub enum DuplexMode {
24    Half,
25    Full,
26}
27
28#[derive(Debug, Clone, Copy, PartialEq, Eq)]
29pub enum SyncMode {
30    Async,
31    Sync,
32}
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq)]
35pub enum Parity {
36    None,
37    Even,
38    Odd,
39}
40
41#[derive(Debug, Clone, Copy, PartialEq, Eq)]
42pub enum StopBits {
43    Stop1,
44    Stop2,
45}
46
47#[derive(Debug, Clone, Copy, PartialEq, Eq)]
48pub enum DmaConfig {
49    None,
50    Tx,
51    Rx,
52    TxRx,
53}
54
55#[derive(Debug, Clone, Copy, PartialEq, Eq)]
56pub struct Config {
57    pub baudrate: u32,
58    pub word_length: WordLength,
59    pub parity: Parity,
60    pub stop_bits: StopBits,
61    pub duplex_mode: DuplexMode,
62    pub sync_mode: SyncMode,
63    pub dma: DmaConfig,
64}
65
66impl Config {
67    pub const fn default() -> Self {
68        Self {
69            baudrate: 115_200,
70            word_length: WordLength::DataBits8,
71            parity: Parity::None,
72            stop_bits: StopBits::Stop1,
73            duplex_mode: DuplexMode::Full,
74            sync_mode: SyncMode::Async,
75            dma: DmaConfig::None,
76        }
77    }
78
79    pub const fn baudrate(mut self, baudrate: u32) -> Self {
80        self.baudrate = baudrate;
81        self
82    }
83
84    pub const fn word_length(mut self, word_length: WordLength) -> Self {
85        self.word_length = word_length;
86        self
87    }
88
89    pub const fn parity(mut self, parity: Parity) -> Self {
90        self.parity = parity;
91        self
92    }
93
94    pub const fn stop_bits(mut self, stop_bits: StopBits) -> Self {
95        self.stop_bits = stop_bits;
96        self
97    }
98
99    pub const fn duplex_mode(mut self, duplex_mode: DuplexMode) -> Self {
100        self.duplex_mode = duplex_mode;
101        self
102    }
103
104    pub const fn sync_mode(mut self, sync_mode: SyncMode) -> Self {
105        self.sync_mode = sync_mode;
106        self
107    }
108
109    pub const fn dma(mut self, dma: DmaConfig) -> Self {
110        self.dma = dma;
111        self
112    }
113}
114
115pub trait TxPin<UART> {}
116pub trait RxPin<UART> {}
117
118impl TxPin<Usart0> for Pin<0, 6, Func2Mode> {}
119impl RxPin<Usart0> for Pin<0, 5, Func2Mode> {}
120
121impl TxPin<Usart1> for Pin<1, 9, Func2Mode> {}
122impl RxPin<Usart1> for Pin<1, 8, Func2Mode> {}
123
124pub trait Instance {
125    fn ptr() -> *const RegisterBlock;
126    fn enable_clock();
127}
128
129impl Instance for Usart0 {
130    #[inline(always)]
131    fn ptr() -> *const RegisterBlock {
132        Usart0::ptr() as *const RegisterBlock
133    }
134
135    #[inline(always)]
136    fn enable_clock() {
137        let p = unsafe { Peripherals::steal() };
138        p.pm.clk_apb_p_set().modify(|_, w| w.uart_0().enable());
139    }
140}
141
142impl Instance for Usart1 {
143    #[inline(always)]
144    fn ptr() -> *const RegisterBlock {
145        Usart1::ptr() as *const RegisterBlock
146    }
147
148    #[inline(always)]
149    fn enable_clock() {
150        let p = unsafe { Peripherals::steal() };
151        p.pm.clk_apb_p_set().modify(|_, w| w.uart_1().enable());
152    }
153}
154
155pub struct Serial<UART, TXPIN, RXPIN>
156where
157    UART: Instance,
158    TXPIN: TxPin<UART>,
159    RXPIN: RxPin<UART>,
160{
161    uart: UART,
162    pins: (TXPIN, RXPIN),
163}
164
165pub struct Tx<UART: Instance> {
166    _uart: PhantomData<UART>,
167}
168
169pub struct Rx<UART: Instance> {
170    _uart: PhantomData<UART>,
171}
172
173impl<UART, TXPIN, RXPIN> Serial<UART, TXPIN, RXPIN>
174where
175    UART: Instance,
176    TXPIN: TxPin<UART>,
177    RXPIN: RxPin<UART>,
178{
179    pub fn new(uart: UART, pins: (TXPIN, RXPIN), config: Config) -> Self {
180        UART::enable_clock();
181
182        let serial = Self { uart, pins };
183        serial.configure(config);
184        serial
185    }
186
187    pub fn split(self) -> (Tx<UART>, Rx<UART>) {
188        let _ = self.uart;
189        let _ = self.pins;
190
191        (Tx { _uart: PhantomData }, Rx { _uart: PhantomData })
192    }
193
194    #[inline(always)]
195    fn regs(&self) -> &RegisterBlock {
196        unsafe { &*UART::ptr() }
197    }
198
199    fn configure(&self, config: Config) {
200        let regs = self.regs();
201        let baudrate_divisor = calc_baudrate_divisor(config.baudrate);
202
203        regs.control1().modify(|_, w| w.ue().disable());
204
205        regs.divider()
206            .write(|w| unsafe { w.brr().bits(baudrate_divisor) });
207
208        regs.control1().write(|w| {
209            w.idleie()
210                .disable()
211                .peie()
212                .disable()
213                .rxneie()
214                .disable()
215                .tcie()
216                .disable()
217                .txeie()
218                .disable()
219        });
220
221        regs.control2().write(|w| {
222            w.lbdie()
223                .disable()
224                .lbm()
225                .normal()
226                .swap()
227                .normal()
228                .rxinv()
229                .direct()
230                .txinv()
231                .direct()
232                .datainv()
233                .direct()
234                .msbfirst()
235                .lsb()
236        });
237
238        regs.control3().write(|w| {
239            w.eie()
240                .disable()
241                .ctsie()
242                .disable()
243                .ctse()
244                .ignored()
245                .rtse()
246                ._0()
247        });
248
249        match config.word_length {
250            WordLength::DataBits7 => regs.control1().modify(|_, w| w.m()._7bits()),
251            WordLength::DataBits8 => regs.control1().modify(|_, w| w.m()._8bits()),
252            WordLength::DataBits9 => regs.control1().modify(|_, w| w.m()._9bits()),
253        };
254
255        match config.parity {
256            Parity::None => regs.control1().modify(|_, w| w.pce().disable()),
257            Parity::Even => regs
258                .control1()
259                .modify(|_, w| w.pce().enable().ps().parity()),
260            Parity::Odd => regs.control1().modify(|_, w| w.pce().enable().ps().odd()),
261        };
262
263        match config.stop_bits {
264            StopBits::Stop1 => regs.control2().modify(|_, w| w.stop_1()._1bit()),
265            StopBits::Stop2 => regs.control2().modify(|_, w| w.stop_1()._2bits()),
266        };
267
268        match config.duplex_mode {
269            DuplexMode::Full => regs.control3().modify(|_, w| w.hdsel().duplex()),
270            DuplexMode::Half => regs.control3().modify(|_, w| w.hdsel().half_duplex()),
271        };
272
273        match config.sync_mode {
274            SyncMode::Async => regs.control2().modify(|_, w| w.clken().asynchronous()),
275            SyncMode::Sync => regs.control2().modify(|_, w| w.clken().synchronous()),
276        };
277
278        match config.dma {
279            DmaConfig::None => regs
280                .control3()
281                .modify(|_, w| w.dmat().disable().dmar().disable()),
282            DmaConfig::Tx => regs
283                .control3()
284                .modify(|_, w| w.dmat().enable().dmar().disable()),
285            DmaConfig::Rx => regs
286                .control3()
287                .modify(|_, w| w.dmat().disable().dmar().enable()),
288            DmaConfig::TxRx => regs
289                .control3()
290                .modify(|_, w| w.dmat().enable().dmar().enable()),
291        };
292
293        regs.flags().write(|w| unsafe { w.bits(0x03ff) });
294
295        regs.control1()
296            .modify(|_, w| w.te().enable().re().enable().ue().enable());
297
298        while {
299            let flags = regs.flags().read();
300            flags.teack().bit_is_clear() || flags.reack().bit_is_clear()
301        } {
302            core::hint::spin_loop();
303        }
304    }
305}
306
307impl<UART, TXPIN, RXPIN> ErrorType for Serial<UART, TXPIN, RXPIN>
308where
309    UART: Instance,
310    TXPIN: TxPin<UART>,
311    RXPIN: RxPin<UART>,
312{
313    type Error = ErrorKind;
314}
315
316impl<UART: Instance> ErrorType for Tx<UART> {
317    type Error = ErrorKind;
318}
319
320impl<UART: Instance> ErrorType for Rx<UART> {
321    type Error = ErrorKind;
322}
323
324impl<UART: Instance> Write for Tx<UART> {
325    fn write(&mut self, byte: u8) -> NbResult<(), Self::Error> {
326        let regs = regs::<UART>();
327
328        if regs.flags().read().txe().bit_is_clear() {
329            return Err(NbError::WouldBlock);
330        }
331
332        regs.txdata()
333            .write(|w| unsafe { w.tdr().bits(byte as u16) });
334
335        Ok(())
336    }
337
338    fn flush(&mut self) -> NbResult<(), Self::Error> {
339        if regs::<UART>().flags().read().tc().bit_is_clear() {
340            return Err(NbError::WouldBlock);
341        }
342
343        Ok(())
344    }
345}
346
347impl<UART: Instance> fmt::Write for Tx<UART> {
348    fn write_str(&mut self, s: &str) -> fmt::Result {
349        for byte in s.bytes() {
350            nb_block(|| self.write(byte)).map_err(|_| fmt::Error)?;
351        }
352
353        nb_block(|| self.flush()).map_err(|_| fmt::Error)
354    }
355}
356
357impl<UART: Instance> Read for Rx<UART> {
358    fn read(&mut self) -> NbResult<u8, Self::Error> {
359        let regs = regs::<UART>();
360        let flags = regs.flags().read();
361
362        if flags.pe().bit_is_set() {
363            regs.flags().write(|w| w.pe().clear_bit_by_one());
364            return Err(NbError::Other(ErrorKind::Parity));
365        }
366
367        if flags.fe().bit_is_set() {
368            regs.flags().write(|w| w.fe().clear_bit_by_one());
369            return Err(NbError::Other(ErrorKind::FrameFormat));
370        }
371
372        if flags.nf().bit_is_set() {
373            regs.flags().write(|w| w.nf().clear_bit_by_one());
374            return Err(NbError::Other(ErrorKind::Noise));
375        }
376
377        if flags.ore().bit_is_set() {
378            regs.flags().write(|w| w.ore().clear_bit_by_one());
379            return Err(NbError::Other(ErrorKind::Overrun));
380        }
381
382        if flags.rxne().bit_is_clear() {
383            return Err(NbError::WouldBlock);
384        }
385
386        Ok(regs.rxdata().read().rdr().bits() as u8)
387    }
388}
389
390#[inline(always)]
391fn regs<UART: Instance>() -> &'static RegisterBlock {
392    unsafe { &*UART::ptr() }
393}
394
395#[inline(always)]
396fn calc_baudrate_divisor(baudrate: u32) -> u16 {
397    let sys_clock: u32 = system_clock().into();
398    let clock = sys_clock / (DIV_AHB + 1) / (DIV_APB_P + 1);
399    let divisor = clock / baudrate;
400
401    divisor.clamp(16, u16::MAX as u32) as u16
402}
403
404fn nb_block<T, E>(mut f: impl FnMut() -> NbResult<T, E>) -> Result<T, E> {
405    loop {
406        match f() {
407            Ok(value) => return Ok(value),
408            Err(NbError::WouldBlock) => core::hint::spin_loop(),
409            Err(NbError::Other(error)) => return Err(error),
410        }
411    }
412}