1use core::marker::PhantomData;
4use core::ptr;
5use core::sync::atomic::{self, Ordering};
6
7use crate::pac::{Interrupt, RCC, USART1, USART2, USART3};
8use hal::serial::{self, Write};
9use nb;
10use void::Void;
11
12use crate::dma::{dma1, CircBuffer, Static, Transfer, R, W};
13use crate::gpio::{AltFn, HighSpeed, PinMode, PullType, PushPull, AF7};
14use crate::gpio::{PA10, PA14, PA15, PA2, PA3, PA9};
15use crate::gpio::{PB10, PB11, PB3, PB4, PB6, PB7};
16use crate::gpio::{PC10, PC11, PC4, PC5};
17use crate::gpio::{PD5, PD6, PD8, PD9};
18use crate::gpio::{PE0, PE1, PE15};
19use crate::rcc::Clocks;
20use crate::time::Bps;
21
22pub enum Event {
24 Rxne,
26 Txe,
28}
29
30#[derive(Debug)]
32pub enum Error {
33 Framing,
35 Noise,
37 Overrun,
39 Parity,
41 #[doc(hidden)]
42 _Extensible,
43}
44
45pub struct Serial<USART, PINS> {
47 usart: USART,
48 pins: PINS,
49}
50
51pub struct Rx<USART> {
53 _usart: PhantomData<USART>,
54}
55
56pub struct Tx<USART> {
58 _usart: PhantomData<USART>,
59}
60
61pub trait SerialExt<USART, ITX, IRX, TX, RX> {
63 fn serial(self,
70 pins: (ITX, IRX),
71 baud_rate: Bps<u32>,
72 clocks: Clocks)
73 -> Serial<USART, (TX, RX)>;
74}
75
76macro_rules! serial {
77 ($USARTX:ident,
78 $INTNAME:ident,
79 $apbenr:ident,
80 $apbrstr:ident,
81 $usartXen:ident,
82 $usartXrst:ident,
83 $pclkX:ident,
84 $afn:ident,
85 $speed:ident,
86 [$($txpin: ident, )+],
87 $restrx: tt
88 ) => {
89 serial!{$USARTX,
90 $INTNAME,
91 $apbenr,
92 $apbrstr,
93 $usartXen,
94 $usartXrst,
95 $pclkX,
96 $afn,
97 $speed,
98 [$(
99 ($txpin, $restrx),
100 )+]}
101 };
102 ($USARTX:ident,
103 $INTNAME:ident,
104 $apbenr:ident,
105 $apbrstr:ident,
106 $usartXen:ident,
107 $usartXrst:ident,
108 $pclkX:ident,
109 $afn:ident,
110 $speed:ident,
111 [$(($txpin: ident, [$($rxpin: ident,)+]), )+]
112 ) => {
113 $(
114 $(
115 impl <PT: PullType,
116 PM: PinMode>
117 SerialExt<$USARTX,
118 $txpin<PT, PM>,
119 $rxpin<PT, PM>,
120 $txpin<PT, AltFn<$afn, PushPull, $speed>>,
121 $rxpin<PT, AltFn<$afn, PushPull, $speed>>>
122 for $USARTX {
123 fn serial(self,
124 pins: ($txpin<PT, PM>, $rxpin<PT, PM>),
125 baud_rate: Bps<u32>,
126 clocks: Clocks)
127 -> Serial<$USARTX, ($txpin<PT, AltFn<$afn, PushPull, $speed>>,
128 $rxpin<PT, AltFn<$afn, PushPull, $speed>>)>
129 {
130 let outpins = (
131 pins.0
132 .alternating($afn)
133 .output_speed($speed),
134 pins.1
135 .alternating($afn)
136 .output_speed($speed),
137 );
138
139 let apbenr = unsafe { &(*RCC::ptr()).$apbenr };
141 let apbrstr = unsafe { &(*RCC::ptr()).$apbrstr };
142 apbenr.modify(|_, w| w.$usartXen().enabled());
143 apbrstr.modify(|_, w| w.$usartXrst().set_bit());
144 apbrstr.modify(|_, w| w.$usartXrst().clear_bit());
145 self.cr3.write(|w| w.dmat().set_bit().dmar().set_bit());
146
147 let brr = clocks.$pclkX().0 / baud_rate.0;
148 assert!(brr >= 16, "impossible baud rate");
149 self.brr.write(|w| unsafe { w.bits(brr) });
150
151 self.cr1.write(|w| {
155 w.ue()
156 .set_bit()
157 .re()
158 .set_bit()
159 .te()
160 .set_bit()
161 });
162
163 Serial { usart: self,
164 pins: outpins, }
165 }
166 }
167 )+
168 )+
169
170 impl<TX, RX> Serial<$USARTX, (TX, RX)> {
171 pub fn get_interrupt(&self) -> Interrupt {
173 Interrupt::$INTNAME
174 }
175
176 pub fn listen(&mut self, event: Event) {
178 match event {
179 Event::Rxne => {
180 self.usart.cr1.modify(|_, w| w.rxneie().set_bit())
181 }
182 Event::Txe => {
183 self.usart.cr1.modify(|_, w| w.txeie().set_bit())
184 }
185 }
186 }
187
188 pub fn unlisten(&mut self, event: Event) {
190 match event {
191 Event::Rxne => {
192 self.usart.cr1.modify(|_, w| w.rxneie().clear_bit())
193 }
194 Event::Txe => {
195 self.usart.cr1.modify(|_, w| w.txeie().clear_bit())
196 }
197 }
198 }
199
200 pub fn split(self) -> (Tx<$USARTX>, Rx<$USARTX>) {
203 (Tx { _usart: PhantomData, }, Rx { _usart: PhantomData, })
204 }
205
206 pub fn free(self) -> ($USARTX, (TX, RX)) {
208 (self.usart, self.pins)
209 }
210 }
211
212 impl Rx<$USARTX> {
213 pub fn clear_overrun_error(&mut self) -> u8 {
215 unsafe { (*$USARTX::ptr()).icr.write(|w| w.orecf().set_bit()) };
216 let rdr = unsafe { (*$USARTX::ptr()).rdr.read() };
217 (rdr.bits() & 0xFF) as u8
218 }
219
220 pub fn clear_framing_error(&mut self) -> u8 {
222 unsafe { (*$USARTX::ptr()).icr.write(|w| w.fecf().set_bit()) };
223 let rdr = unsafe { (*$USARTX::ptr()).rdr.read() };
224 (rdr.bits() & 0xFF) as u8
225 }
226
227 pub fn clear_noise_error(&mut self) -> u8 {
229 unsafe { (*$USARTX::ptr()).icr.write(|w| w.ncf().set_bit()) };
230 let rdr = unsafe { (*$USARTX::ptr()).rdr.read() };
231 (rdr.bits() & 0xFF) as u8
232 }
233 }
234
235 impl serial::Read<u8> for Rx<$USARTX> {
236 type Error = Error;
237
238 fn read(&mut self) -> nb::Result<u8, Error> {
239 let isr = unsafe { (*$USARTX::ptr()).isr.read() };
241
242 Err(if isr.pe().bit_is_set() {
243 nb::Error::Other(Error::Parity)
244 } else if isr.fe().bit_is_set() {
245 self.clear_framing_error();
246 nb::Error::Other(Error::Framing)
247 } else if isr.nf().bit_is_set() {
248 self.clear_noise_error();
249 nb::Error::Other(Error::Noise)
250 } else if isr.ore().bit_is_set() {
251 self.clear_overrun_error();
252 nb::Error::Other(Error::Overrun)
253 } else if isr.rxne().bit_is_set() {
254 return Ok(unsafe {
256 ptr::read_volatile(&(*$USARTX::ptr()).rdr as *const _
257 as *const _)
258 });
259 } else {
260 nb::Error::WouldBlock
261 })
262 }
263 }
264
265 impl serial::Write<u8> for Tx<$USARTX> {
266 type Error = Void;
272
273 fn flush(&mut self) -> nb::Result<(), Void> {
274 let isr = unsafe { (*$USARTX::ptr()).isr.read() };
276
277 if isr.tc().bit_is_set() {
278 Ok(())
279 } else {
280 Err(nb::Error::WouldBlock)
281 }
282 }
283
284 fn write(&mut self, byte: u8) -> nb::Result<(), Void> {
285 let isr = unsafe { (*$USARTX::ptr()).isr.read() };
287
288 if isr.txe().bit_is_set() {
289 unsafe {
293 ptr::write_volatile(&(*$USARTX::ptr()).tdr as *const _
294 as *mut _,
295 byte)
296 }
297 Ok(())
298 } else {
299 Err(nb::Error::WouldBlock)
300 }
301 }
302 }
303
304 impl core::fmt::Write for Tx<$USARTX>
305 {
306 fn write_str(&mut self, s: &str) -> core::fmt::Result {
307 for c in s.chars() {
308 match self.write_char(c) {
309 Ok(_) => {},
310 Err(_) => {},
311 }
312 }
313 match self.flush() {
314 Ok(_) => {},
315 Err(_) => {},
316 };
317 Ok(())
318 }
319
320 fn write_char(&mut self, s: char) -> core::fmt::Result {
321 match nb::block!(self.write(s as u8)) {
322 Ok(_) => {},
323 Err(_) => {},
324 }
325 Ok(())
326 }
327 }
328
329 impl<B> ReadDma<B> for Rx<$USARTX> where B: AsMut<[u8]> {
330 fn circ_read(self, mut chan: Self::Dma, buffer: &'static mut [B; 2],
331 ) -> CircBuffer<B, Self::Dma>
332 {
333 {
334 let buffer = buffer[0].as_mut();
335 chan.ch().mar.write(|w| unsafe {
336 w.ma().bits(buffer.as_ptr() as usize as u32)
337 }
338 );
339 chan.ch().ndtr.write(|w|
340 w.ndt().bits((buffer.len() * 2) as u16)
341 );
342 chan.ch().par.write(|w| unsafe {
343 w.pa().bits(&(*$USARTX::ptr()).rdr as *const _ as usize as u32)
344 });
345
346 atomic::compiler_fence(Ordering::SeqCst);
350
351 unsafe {
352 chan.ch().cr.modify(|_, w| {
353 w.mem2mem()
354 .clear_bit()
355 .pl()
356 .bits(0b01)
357 .msize()
358 .bits(0b0) .psize()
360 .bits(0b0)
361 .minc()
362 .set_bit()
363 .pinc()
364 .clear_bit()
365 .circ()
366 .set_bit()
367 .dir()
368 .clear_bit()
369 });
370 chan.ch().cr.modify(|_, w| w.en().set_bit() )
371 }
372 }
373
374 CircBuffer::new(buffer, chan)
375 }
376
377 fn read_exact(self, mut chan: Self::Dma, buffer: &'static mut B,
378 ) -> Transfer<W, &'static mut B, Self::Dma, Self>
379 {
380 {
381 let buffer = buffer.as_mut();
382 chan.ch().mar.write(|w| unsafe {
383 w.ma().bits(buffer.as_ptr() as usize as u32)
384 });
385 chan.ch().ndtr.write(|w|
386 w.ndt().bits(buffer.len() as u16)
387 );
388 chan.ch().par.write(|w| unsafe {
389 w.pa().bits(&(*$USARTX::ptr()).rdr as *const _ as usize as u32)
390 });
391
392 atomic::compiler_fence(Ordering::SeqCst);
396
397 unsafe {
398 chan.ch().cr.modify(|_, w| {
399 w.mem2mem()
400 .clear_bit()
401 .pl()
402 .bits(0b01)
403 .msize()
404 .bits(0b0)
405 .psize()
406 .bits(0b0)
407 .minc()
408 .set_bit()
409 .pinc()
410 .clear_bit()
411 .circ()
412 .clear_bit()
413 .dir()
414 .clear_bit()
415 .en()
416 .set_bit()
417 });
418 }
419 }
420
421 Transfer::w(buffer, chan, self)
422 }
423 }
424
425 impl<A, B> WriteDma<A, B> for Tx<$USARTX> where A: AsRef<[u8]>, B: Static<A> {
426 fn write_all(self, mut chan: Self::Dma, buffer: B
427 ) -> Transfer<R, B, Self::Dma, Self>
428 {
429 {
430 let buffer = buffer.borrow().as_ref();
431 chan.ch().par.write(|w| unsafe {
432 w.pa().bits(&(*$USARTX::ptr()).tdr as *const _ as usize as u32)
433 });
434
435 chan.ch().mar.write(|w| unsafe {
436 w.ma().bits(buffer.as_ptr() as usize as u32)
437 });
438
439 chan.ch().ndtr.write(|w|
440 w.ndt().bits(buffer.len() as u16)
441 );
442
443 atomic::compiler_fence(Ordering::SeqCst);
447
448 unsafe {
449 chan.ch().cr.modify(|_, w| {
450 w.mem2mem()
451 .clear_bit()
452 .pl()
453 .bits(0b01)
454 .msize()
455 .bits(0b0)
456 .psize()
457 .bits(0b0)
458 .minc()
459 .set_bit()
460 .pinc()
461 .clear_bit()
462 .circ()
463 .clear_bit()
464 .dir()
465 .set_bit()
466 .en()
467 .set_bit()
468 });
469 }
470 }
471
472 Transfer::r(buffer, chan, self)
473 }
474 }
475 };
476}
477
478use crate::dma::DmaChannel;
479
480impl DmaChannel for Rx<USART1> {
481 type Dma = dma1::C5;
482}
483
484impl DmaChannel for Tx<USART1> {
485 type Dma = dma1::C4;
486}
487
488impl DmaChannel for Rx<USART2> {
489 type Dma = dma1::C6;
490}
491
492impl DmaChannel for Tx<USART2> {
493 type Dma = dma1::C7;
494}
495
496impl DmaChannel for Rx<USART3> {
497 type Dma = dma1::C3;
498}
499
500impl DmaChannel for Tx<USART3> {
501 type Dma = dma1::C2;
502}
503
504pub trait ReadDma<B>: DmaChannel
506 where B: AsMut<[u8]>,
507 Self: core::marker::Sized
508{
509 fn circ_read(self,
511 chan: Self::Dma,
512 buffer: &'static mut [B; 2])
513 -> CircBuffer<B, Self::Dma>;
514 fn read_exact(self,
516 chan: Self::Dma,
517 buffer: &'static mut B)
518 -> Transfer<W, &'static mut B, Self::Dma, Self>;
519}
520
521pub trait WriteDma<A, B>: DmaChannel
523 where A: AsRef<[u8]>,
524 B: Static<A>,
525 Self: core::marker::Sized
526{
527 fn write_all(self,
529 chan: Self::Dma,
530 buffer: B)
531 -> Transfer<R, B, Self::Dma, Self>;
532}
533
534serial!(USART1,
536 USART1_EXTI25,
537 apb2enr,
538 apb2rstr,
539 usart1en,
540 usart1rst,
541 pclk2,
542 AF7,
543 HighSpeed, [PA9, PB6, PC4, PE0,],
545 [PA10, PB7, PC5, PE1,]);
546serial!(USART2,
547 USART2_EXTI26,
548 apb1enr,
549 apb1rstr,
550 usart2en,
551 usart2rst,
552 pclk1,
553 AF7,
554 HighSpeed,
555 [PA2, PA14, PB3, PD5,],
556 [PA3, PA15, PB4, PD6,]);
557serial!(USART3,
558 USART3_EXTI28,
559 apb1enr,
560 apb1rstr,
561 usart3en,
562 usart3rst,
563 pclk1,
564 AF7,
565 HighSpeed,
566 [PB10, PC10, PD8,],
567 [PB11, PC11, PD9, PE15,]);