1use core::fmt;
4use core::marker::PhantomData;
5use core::ops::Deref;
6use core::ops::DerefMut;
7use core::pin::Pin;
8use core::ptr;
9
10use as_slice::{AsMutSlice, AsSlice};
11
12use crate::dma;
13use crate::hal::prelude::*;
14use crate::hal::serial;
15use crate::pac;
16use crate::rcc::{BusClock, Enable, Reset};
17use crate::state;
18use nb::block;
19
20use crate::pac::{RCC, UART4, UART5, UART7, UART8, USART1, USART2, USART3, USART6};
21
22use crate::gpio::{self, Alternate};
23
24use crate::rcc::Clocks;
25use crate::{BitsPerSecond, U32Ext};
26
27#[derive(Debug)]
29#[non_exhaustive]
30pub enum Error {
31 Framing,
33 Noise,
35 Overrun,
37 Parity,
39}
40
41pub trait Pins<U> {}
42pub trait PinTx<U> {}
43pub trait PinRx<U> {}
44
45impl<U, TX, RX> Pins<U> for (TX, RX)
46where
47 TX: PinTx<U>,
48 RX: PinRx<U>,
49{
50}
51
52mod f7xx_pins {
53 use super::{PinRx, PinTx};
55 use crate::gpio::{self, Alternate};
56 use crate::pac::{UART4, UART5, UART7, USART1};
57 impl PinTx<USART1> for gpio::PB14<Alternate<4>> {}
58 impl PinRx<USART1> for gpio::PB15<Alternate<4>> {}
59
60 impl PinTx<UART4> for gpio::PA11<Alternate<6>> {}
61 impl PinRx<UART4> for gpio::PA12<Alternate<6>> {}
62
63 impl PinTx<UART4> for gpio::PD1<Alternate<8>> {}
64 impl PinRx<UART4> for gpio::PD0<Alternate<8>> {}
65
66 impl PinTx<UART4> for gpio::PH13<Alternate<8>> {}
67 impl PinRx<UART4> for gpio::PH14<Alternate<8>> {}
68
69 impl PinRx<UART4> for gpio::PI9<Alternate<8>> {}
70
71 impl PinTx<UART5> for gpio::PB6<Alternate<1>> {}
72 impl PinRx<UART5> for gpio::PB5<Alternate<1>> {}
73
74 impl PinTx<UART5> for gpio::PB9<Alternate<7>> {}
75 impl PinRx<UART5> for gpio::PB8<Alternate<7>> {}
76
77 impl PinTx<UART5> for gpio::PB13<Alternate<8>> {}
78 impl PinRx<UART5> for gpio::PB12<Alternate<8>> {}
79
80 impl PinTx<UART7> for gpio::PA15<Alternate<12>> {}
81 impl PinRx<UART7> for gpio::PA8<Alternate<12>> {}
82
83 impl PinTx<UART7> for gpio::PB4<Alternate<12>> {}
84 impl PinRx<UART7> for gpio::PB3<Alternate<12>> {}
85}
86
87impl PinTx<USART1> for gpio::PA9<Alternate<7>> {}
89impl PinTx<USART1> for gpio::PB6<Alternate<7>> {}
90
91impl PinRx<USART1> for gpio::PA10<Alternate<7>> {}
92impl PinRx<USART1> for gpio::PB7<Alternate<7>> {}
93
94impl PinTx<USART2> for gpio::PA2<Alternate<7>> {}
96impl PinTx<USART2> for gpio::PD5<Alternate<7>> {}
97
98impl PinRx<USART2> for gpio::PA3<Alternate<7>> {}
99impl PinRx<USART2> for gpio::PD6<Alternate<7>> {}
100
101impl PinTx<USART3> for gpio::PB10<Alternate<7>> {}
103impl PinTx<USART3> for gpio::PC10<Alternate<7>> {}
104impl PinTx<USART3> for gpio::PD8<Alternate<7>> {}
105
106impl PinRx<USART3> for gpio::PB11<Alternate<7>> {}
107impl PinRx<USART3> for gpio::PC11<Alternate<7>> {}
108impl PinRx<USART3> for gpio::PD9<Alternate<7>> {}
109
110impl PinTx<USART6> for gpio::PC6<Alternate<8>> {}
112impl PinTx<USART6> for gpio::PG14<Alternate<8>> {}
113
114impl PinRx<USART6> for gpio::PC7<Alternate<8>> {}
115impl PinRx<USART6> for gpio::PG9<Alternate<8>> {}
116
117impl PinTx<UART4> for gpio::PA0<Alternate<8>> {}
119impl PinTx<UART4> for gpio::PC10<Alternate<8>> {}
120
121impl PinRx<UART4> for gpio::PA1<Alternate<8>> {}
122impl PinRx<UART4> for gpio::PC11<Alternate<8>> {}
123
124impl PinTx<UART5> for gpio::PC12<Alternate<8>> {}
126impl PinRx<UART5> for gpio::PD2<Alternate<8>> {}
127
128impl PinTx<UART7> for gpio::PE8<Alternate<8>> {}
130impl PinTx<UART7> for gpio::PF7<Alternate<8>> {}
131
132impl PinRx<UART7> for gpio::PE7<Alternate<8>> {}
133impl PinRx<UART7> for gpio::PF6<Alternate<8>> {}
134
135impl PinTx<UART8> for gpio::PE1<Alternate<8>> {}
137impl PinRx<UART8> for gpio::PE0<Alternate<8>> {}
138
139pub struct Serial<U, PINS> {
141 usart: U,
142 pins: PINS,
143}
144
145impl<U, PINS> Serial<U, PINS>
146where
147 PINS: Pins<U>,
148 U: Instance,
149{
150 pub fn new(usart: U, pins: PINS, clocks: &Clocks, config: Config) -> Self {
151 let rcc = unsafe { &(*RCC::ptr()) };
153
154 U::select_sysclock(rcc, config.sysclock);
158 unsafe {
159 U::enable_unchecked();
160 }
161
162 let clk = if config.sysclock {
163 clocks.sysclk()
164 } else {
165 U::clock(clocks)
166 };
167
168 let brr = match config.oversampling {
170 Oversampling::By8 => {
171 usart.cr1.modify(|_, w| w.over8().set_bit());
172
173 let usart_div = 2 * clk / config.baud_rate;
174
175 0xfff0 & usart_div | 0x0007 & ((usart_div & 0x000f) >> 1)
176 }
177 Oversampling::By16 => {
178 usart.cr1.modify(|_, w| w.over8().clear_bit());
179
180 clk / config.baud_rate
181 }
182 };
183
184 usart.brr.write(|w| unsafe { w.bits(brr) });
185
186 let ch = config.character_match.unwrap_or(0);
188 usart.cr2.write(|w| w.add().bits(ch));
189
190 usart.cr1.modify(|_, w| {
192 w.te().enabled().re().enabled().ue().enabled();
193
194 match config.data_bits {
199 DataBits::Bits8 => w.m1().clear_bit().m0().bit8(),
200 DataBits::Bits9 => w.m1().clear_bit().m0().bit9(),
201 DataBits::Bits7 => w.m0().clear_bit().m1().bit7(),
202 };
203
204 match config.parity {
205 Parity::ParityEven => w.ps().even().pce().enabled(),
206 Parity::ParityOdd => w.ps().odd().pce().enabled(),
207 Parity::ParityNone => w.pce().disabled(),
208 }
209 });
210
211 usart.cr3.write(|w| w.dmat().enabled().dmar().enabled());
213
214 Serial { usart, pins }
215 }
216
217 pub fn listen(&mut self, event: Event) {
219 match event {
220 Event::Rxne => self.usart.cr1.modify(|_, w| w.rxneie().set_bit()),
221 Event::Txe => self.usart.cr1.modify(|_, w| w.txeie().set_bit()),
222 Event::CharacterMatch => self.usart.cr1.modify(|_, w| w.cmie().set_bit()),
223 Event::Error => self.usart.cr3.modify(|_, w| w.eie().set_bit()),
224 }
225 }
226
227 pub fn unlisten(&mut self, event: Event) {
229 match event {
230 Event::Rxne => self.usart.cr1.modify(|_, w| w.rxneie().clear_bit()),
231 Event::Txe => self.usart.cr1.modify(|_, w| w.txeie().clear_bit()),
232 Event::CharacterMatch => self.usart.cr1.modify(|_, w| w.cmie().clear_bit()),
233 Event::Error => self.usart.cr3.modify(|_, w| w.eie().clear_bit()),
234 }
235 }
236
237 pub fn split(self) -> (Tx<U>, Rx<U>) {
238 (
239 Tx {
240 _usart: PhantomData,
241 },
242 Rx {
243 _usart: PhantomData,
244 },
245 )
246 }
247
248 pub fn release(self) -> (U, PINS) {
249 (self.usart, self.pins)
250 }
251}
252
253impl<U, PINS> serial::Read<u8> for Serial<U, PINS>
254where
255 U: Instance,
256{
257 type Error = Error;
258
259 fn read(&mut self) -> nb::Result<u8, Error> {
260 let mut rx: Rx<U> = Rx {
261 _usart: PhantomData,
262 };
263 rx.read()
264 }
265}
266
267impl<U, PINS> serial::Write<u8> for Serial<U, PINS>
268where
269 U: Instance,
270{
271 type Error = Error;
272
273 fn flush(&mut self) -> nb::Result<(), Self::Error> {
274 let mut tx: Tx<U> = Tx {
275 _usart: PhantomData,
276 };
277 tx.flush()
278 }
279
280 fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
281 let mut tx: Tx<U> = Tx {
282 _usart: PhantomData,
283 };
284 tx.write(byte)
285 }
286}
287
288pub struct Rx<U> {
290 _usart: PhantomData<U>,
291}
292
293impl<U> Rx<U>
294where
295 U: Instance,
296 Self: dma::Target,
297{
298 pub fn read_all<B>(
303 self,
304 buffer: Pin<B>,
305 dma: &dma::Handle<<Self as dma::Target>::Instance, state::Enabled>,
306 stream: <Self as dma::Target>::Stream,
307 ) -> dma::Transfer<Self, B, dma::Ready>
308 where
309 B: DerefMut + 'static,
310 B::Target: AsMutSlice<Element = u8>,
311 {
312 let address = &unsafe { &*U::ptr() }.rdr as *const _ as _;
315
316 unsafe {
319 dma::Transfer::new(
320 dma,
321 stream,
322 buffer,
323 self,
324 address,
325 dma::Direction::PeripheralToMemory,
326 )
327 }
328 }
329}
330
331impl<U> serial::Read<u8> for Rx<U>
332where
333 U: Instance,
334{
335 type Error = Error;
336
337 fn read(&mut self) -> nb::Result<u8, Error> {
338 let isr = unsafe { (*U::ptr()).isr.read() };
340
341 let icr = unsafe { &(*U::ptr()).icr };
343
344 if isr.pe().bit_is_set() {
345 icr.write(|w| w.pecf().clear());
346 return Err(nb::Error::Other(Error::Parity));
347 }
348 if isr.fe().bit_is_set() {
349 icr.write(|w| w.fecf().clear());
350 return Err(nb::Error::Other(Error::Framing));
351 }
352 if isr.nf().bit_is_set() {
353 icr.write(|w| w.ncf().clear());
354 return Err(nb::Error::Other(Error::Noise));
355 }
356 if isr.ore().bit_is_set() {
357 icr.write(|w| w.orecf().clear());
358 return Err(nb::Error::Other(Error::Overrun));
359 }
360
361 if isr.rxne().bit_is_set() {
362 return Ok(unsafe {
364 (*U::ptr()).rdr.read().rdr().bits() as u8
367 });
368 }
369
370 Err(nb::Error::WouldBlock)
371 }
372}
373
374pub struct Tx<U> {
376 _usart: PhantomData<U>,
377}
378
379impl<U> Tx<U>
380where
381 Self: dma::Target,
382 U: Instance,
383{
384 pub fn write_all<B>(
389 self,
390 data: Pin<B>,
391 dma: &dma::Handle<<Self as dma::Target>::Instance, state::Enabled>,
392 stream: <Self as dma::Target>::Stream,
393 ) -> dma::Transfer<Self, B, dma::Ready>
394 where
395 B: Deref + 'static,
396 B::Target: AsSlice<Element = u8>,
397 {
398 let usart = unsafe { &*U::ptr() };
403 usart.icr.write(|w| w.tccf().clear());
404
405 unsafe {
408 dma::Transfer::new(
409 dma,
410 stream,
411 data,
412 self,
413 &usart.tdr as *const _ as _,
414 dma::Direction::MemoryToPeripheral,
415 )
416 }
417 }
418}
419
420impl<U> serial::Write<u8> for Tx<U>
421where
422 U: Instance,
423{
424 type Error = Error;
425
426 fn flush(&mut self) -> nb::Result<(), Self::Error> {
427 let isr = unsafe { (*U::ptr()).isr.read() };
429
430 if isr.tc().bit_is_set() {
431 Ok(())
432 } else {
433 Err(nb::Error::WouldBlock)
434 }
435 }
436
437 fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
438 let isr = unsafe { (*U::ptr()).isr.read() };
440
441 if isr.txe().bit_is_set() {
442 unsafe { ptr::write_volatile(core::ptr::addr_of!((*U::ptr()).tdr) as *mut u8, byte) }
445 Ok(())
446 } else {
447 Err(nb::Error::WouldBlock)
448 }
449 }
450}
451
452pub struct Config {
454 pub baud_rate: BitsPerSecond,
455 pub oversampling: Oversampling,
456 pub character_match: Option<u8>,
457 pub sysclock: bool,
458 pub parity: Parity,
459 pub data_bits: DataBits,
460}
461
462pub enum Oversampling {
463 By8,
464 By16,
465}
466
467pub enum DataBits {
469 Bits8,
471 Bits9,
473 Bits7,
475}
476
477pub enum Parity {
481 ParityNone,
483 ParityEven,
486 ParityOdd,
489}
490
491impl Default for Config {
492 fn default() -> Self {
493 Self {
494 baud_rate: 115_200.bps(),
495 oversampling: Oversampling::By16,
496 character_match: None,
497 sysclock: false,
498 parity: Parity::ParityNone,
499 data_bits: DataBits::Bits8,
500 }
501 }
502}
503
504#[derive(Debug)]
506pub enum Event {
507 Rxne,
509 Txe,
511 CharacterMatch,
513 Error,
515}
516
517pub trait Instance: Deref<Target = pac::usart1::RegisterBlock> + Enable + Reset + BusClock {
519 fn ptr() -> *const pac::usart1::RegisterBlock;
520 fn select_sysclock(rcc: &pac::rcc::RegisterBlock, sys: bool);
521}
522
523macro_rules! impl_instance {
524 ($(
525 $UARTX:ident: ($usartXsel:ident),
526 )+) => {
527 $(
528 impl Instance for $UARTX {
529 fn ptr() -> *const pac::usart1::RegisterBlock {
530 $UARTX::ptr()
531 }
532
533 fn select_sysclock(rcc: &pac::rcc::RegisterBlock, sys: bool) {
534 rcc.dckcfgr2.modify(|_, w| w.$usartXsel().bits(sys as _));
535 }
536 }
537 )+
538 }
539}
540
541#[cfg(any(feature = "device-selected",))]
542impl_instance! {
543 USART1: (usart1sel),
544 USART2: (usart2sel),
545 USART3: (usart3sel),
546 UART4: (uart4sel),
547 UART5: (uart5sel),
548 USART6: (usart6sel),
549 UART7: (uart7sel),
550}
551
552impl<U> fmt::Write for Tx<U>
553where
554 Tx<U>: serial::Write<u8>,
555{
556 fn write_str(&mut self, s: &str) -> fmt::Result {
557 let _ = s.as_bytes().iter().map(|c| block!(self.write(*c))).last();
558 Ok(())
559 }
560}