1#![no_std]
4#![deny(missing_docs, warnings)]
5#![allow(deprecated)]
6
7pub mod bb;
8pub mod delay;
9pub mod eeprom;
10pub mod gpio;
11pub mod i2c;
12pub mod serial;
13pub mod sysctl;
14pub mod time;
15
16#[macro_export]
18macro_rules! gpio_macro {
19 ($chip_crate:ident, $GPIOX:ident, $gpiox:ident, $iopd:ident, $PXx:ident, [
20 $($PXi:ident: ($pxi:ident, $i:expr, $MODE:ty),)+
21 ]) => {
22 pub mod $gpiox {
24 use super::*;
25 use $chip_crate::$GPIOX;
26
27 pub struct GpioControl {
30 _0: (),
31 }
32
33 pub struct Parts {
35 pub control: GpioControl,
37 $(
38 pub $pxi: $PXi<$MODE>,
40 )+
41 }
42
43 impl GpioExt for $GPIOX {
44 type Parts = Parts;
45
46 fn split(self, pc: &sysctl::PowerControl) -> Parts {
48 sysctl::control_power(
49 pc, sysctl::Domain::$iopd,
50 sysctl::RunMode::Run, sysctl::PowerState::On);
51 sysctl::reset(pc, sysctl::Domain::$iopd);
52
53 Parts {
54 control: GpioControl { _0: () },
55 $(
56 $pxi: $PXi { _mode: PhantomData },
57 )+
58 }
59 }
60 }
61
62 pub struct $PXx<MODE> {
64 i: u8,
65 _mode: PhantomData<MODE>,
66 }
67
68 impl<MODE> StatefulOutputPin for $PXx<Output<MODE>> where MODE: OutputMode {
69 fn is_set_high(&self) -> bool {
70 let p = unsafe { &*$GPIOX::ptr() };
71 bb::read_bit(&p.data, self.i)
72 }
73
74 fn is_set_low(&self) -> bool {
75 !self.is_set_high()
76 }
77 }
78
79 impl<MODE> OutputPin for $PXx<Output<MODE>> where MODE: OutputMode {
80 fn set_high(&mut self) {
81 let p = unsafe { &*$GPIOX::ptr() };
82 unsafe { bb::change_bit(&p.data, self.i, true); }
83 }
84
85 fn set_low(&mut self) {
86 let p = unsafe { &*$GPIOX::ptr() };
87 unsafe { bb::change_bit(&p.data, self.i, false); }
88 }
89 }
90
91 impl<MODE> InputPin for $PXx<Input<MODE>> where MODE: InputMode {
92 fn is_high(&self) -> bool {
93 let p = unsafe { &*$GPIOX::ptr() };
94 bb::read_bit(&p.data, self.i)
95 }
96
97 fn is_low(&self) -> bool {
98 !self.is_high()
99 }
100 }
101
102 impl<MODE> $PXx<Input<MODE>> where MODE: InputMode {
103 pub fn set_interrupt_mode(&mut self, mode: InterruptMode) {
105 let p = unsafe { &*$GPIOX::ptr() };
106 unsafe { bb::change_bit(&p.im, self.i, false); }
107 match mode {
108 InterruptMode::LevelHigh => {
109 unsafe { bb::change_bit(&p.im, self.i, false); }
111 unsafe { bb::change_bit(&p.is, self.i, true); }
113 unsafe { bb::change_bit(&p.ibe, self.i, false); }
115 unsafe { bb::change_bit(&p.iev, self.i, true); }
117 unsafe { bb::change_bit(&p.im, self.i, true); }
119 },
120 InterruptMode::LevelLow => {
121 unsafe { bb::change_bit(&p.im, self.i, false); }
123 unsafe { bb::change_bit(&p.is, self.i, true); }
125 unsafe { bb::change_bit(&p.ibe, self.i, false); }
127 unsafe { bb::change_bit(&p.iev, self.i, false); }
129 unsafe { bb::change_bit(&p.im, self.i, true); }
131 },
132 InterruptMode::EdgeRising => {
133 unsafe { bb::change_bit(&p.im, self.i, false); }
135 unsafe { bb::change_bit(&p.is, self.i, false); }
137 unsafe { bb::change_bit(&p.ibe, self.i, false); }
139 unsafe { bb::change_bit(&p.iev, self.i, true); }
141 unsafe { bb::change_bit(&p.im, self.i, true); }
143 },
144 InterruptMode::EdgeFalling => {
145 unsafe { bb::change_bit(&p.im, self.i, false); }
147 unsafe { bb::change_bit(&p.is, self.i, false); }
149 unsafe { bb::change_bit(&p.ibe, self.i, false); }
151 unsafe { bb::change_bit(&p.iev, self.i, false); }
153 unsafe { bb::change_bit(&p.im, self.i, true); }
155 },
156 InterruptMode::EdgeBoth => {
157 unsafe { bb::change_bit(&p.im, self.i, false); }
159 unsafe { bb::change_bit(&p.is, self.i, false); }
161 unsafe { bb::change_bit(&p.ibe, self.i, true); }
163 unsafe { bb::change_bit(&p.iev, self.i, true); }
165 unsafe { bb::change_bit(&p.im, self.i, true); }
167 },
168 InterruptMode::Disabled => {
169 unsafe { bb::change_bit(&p.im, self.i, false); }
171 },
172 }
173 }
174
175 pub fn get_interrupt_status(&self) -> bool {
177 let p = unsafe { &*$GPIOX::ptr() };
178 bb::read_bit(&p.mis, self.i)
179 }
180
181 pub fn clear_interrupt(&self) {
184 let p = unsafe { &*$GPIOX::ptr() };
185 unsafe { bb::change_bit(&p.icr, self.i, true); }
186 }
187 }
188
189 $(
190 pub struct $PXi<MODE> {
192 _mode: PhantomData<MODE>,
193 }
194
195 impl<MODE> crate::Sealed for $PXi<MODE> {}
196
197 impl<MODE> $PXi<MODE> where MODE: IsUnlocked {
198 pub fn into_af_push_pull<AF>(
201 self,
202 _gpio_control: &mut GpioControl,
203 ) -> $PXi<AlternateFunction<AF, PushPull>> where AF: AlternateFunctionChoice {
204 let p = unsafe { &*$GPIOX::ptr() };
205 let mask = 0xF << ($i * 4);
206 let bits = AF::number() << ($i * 4);
207 unsafe {
208 p.pctl.modify(|r, w| w.bits((r.bits() & !mask) | bits));
209 }
210 unsafe { bb::change_bit(&p.afsel, $i, true); }
211 unsafe { bb::change_bit(&p.dir, $i, false); }
212 unsafe { bb::change_bit(&p.odr, $i, false); }
213 unsafe { bb::change_bit(&p.pur, $i, false); }
214 unsafe { bb::change_bit(&p.pdr, $i, false); }
215 unsafe { bb::change_bit(&p.den, $i, true); }
216 $PXi { _mode: PhantomData }
217 }
218
219 pub fn into_af_pull_up<AF>(
222 self,
223 _gpio_control: &mut GpioControl,
224 ) -> $PXi<AlternateFunction<AF, PullUp>> where AF: AlternateFunctionChoice {
225 let p = unsafe { &*$GPIOX::ptr() };
226 let mask = 0xF << ($i * 4);
227 let bits = AF::number() << ($i * 4);
228 unsafe {
229 p.pctl.modify(|r, w| w.bits((r.bits() & !mask) | bits));
230 }
231 unsafe { bb::change_bit(&p.afsel, $i, true); }
232 unsafe { bb::change_bit(&p.dir, $i, false); }
233 unsafe { bb::change_bit(&p.odr, $i, false); }
234 unsafe { bb::change_bit(&p.pur, $i, true); }
235 unsafe { bb::change_bit(&p.pdr, $i, false); }
236 unsafe { bb::change_bit(&p.den, $i, true); }
237 $PXi { _mode: PhantomData }
238 }
239
240 pub fn into_af_pull_down<AF>(
243 self,
244 _gpio_control: &mut GpioControl,
245 ) -> $PXi<AlternateFunction<AF, PullDown>> where AF: AlternateFunctionChoice {
246 let p = unsafe { &*$GPIOX::ptr() };
247 let mask = 0xF << ($i * 4);
248 let bits = AF::number() << ($i * 4);
249 unsafe {
250 p.pctl.modify(|r, w| w.bits((r.bits() & !mask) | bits));
251 }
252 unsafe { bb::change_bit(&p.afsel, $i, true); }
253 unsafe { bb::change_bit(&p.dir, $i, false); }
254 unsafe { bb::change_bit(&p.odr, $i, false); }
255 unsafe { bb::change_bit(&p.pur, $i, false); }
256 unsafe { bb::change_bit(&p.pdr, $i, true); }
257 unsafe { bb::change_bit(&p.den, $i, true); }
258 $PXi { _mode: PhantomData }
259 }
260
261 pub fn into_af_open_drain<AF, ODM>(
264 self,
265 _gpio_control: &mut GpioControl,
266 ) -> $PXi<AlternateFunction<AF, OpenDrain<ODM>>> where AF: AlternateFunctionChoice, ODM: OpenDrainMode {
267 let p = unsafe { &*$GPIOX::ptr() };
268 let mask = 0xF << ($i * 4);
269 let bits = AF::number() << ($i * 4);
270 unsafe {
271 p.pctl.modify(|r, w| w.bits((r.bits() & !mask) | bits));
272 }
273 unsafe { bb::change_bit(&p.afsel, $i, true); }
274 unsafe { bb::change_bit(&p.dir, $i, false); }
275 unsafe { bb::change_bit(&p.odr, $i, true); }
276 unsafe { bb::change_bit(&p.pur, $i, ODM::pup()); }
277 unsafe { bb::change_bit(&p.pdr, $i, false); }
278 unsafe { bb::change_bit(&p.den, $i, true); }
279 $PXi { _mode: PhantomData }
280 }
281
282 pub fn into_floating_input(
284 self
285 ) -> $PXi<Input<Floating>> {
286 let p = unsafe { &*$GPIOX::ptr() };
287 unsafe { bb::change_bit(&p.afsel, $i, false); }
288 unsafe { bb::change_bit(&p.dir, $i, false); }
289 unsafe { bb::change_bit(&p.odr, $i, false); }
290 unsafe { bb::change_bit(&p.pur, $i, false); }
291 unsafe { bb::change_bit(&p.pdr, $i, false); }
292 unsafe { bb::change_bit(&p.den, $i, true); }
293 $PXi { _mode: PhantomData }
294 }
295
296 pub fn into_pull_down_input(
298 self
299 ) -> $PXi<Input<PullDown>> {
300 let p = unsafe { &*$GPIOX::ptr() };
301 unsafe { bb::change_bit(&p.afsel, $i, false); }
302 unsafe { bb::change_bit(&p.dir, $i, false); }
303 unsafe { bb::change_bit(&p.odr, $i, false); }
304 unsafe { bb::change_bit(&p.pur, $i, false); }
305 unsafe { bb::change_bit(&p.pdr, $i, true); }
306 unsafe { bb::change_bit(&p.den, $i, true); }
307 $PXi { _mode: PhantomData }
308 }
309
310 pub fn into_pull_up_input(
312 self
313 ) -> $PXi<Input<PullUp>> {
314 let p = unsafe { &*$GPIOX::ptr() };
315 unsafe { bb::change_bit(&p.afsel, $i, false); }
316 unsafe { bb::change_bit(&p.dir, $i, false); }
317 unsafe { bb::change_bit(&p.odr, $i, false); }
318 unsafe { bb::change_bit(&p.pur, $i, true); }
319 unsafe { bb::change_bit(&p.pdr, $i, false); }
320 unsafe { bb::change_bit(&p.den, $i, true); }
321 $PXi { _mode: PhantomData }
322 }
323
324 pub fn into_open_drain_output<ODM>(
326 self
327 ) -> $PXi<Output<OpenDrain<ODM>>> where ODM: OpenDrainMode {
328 let p = unsafe { &*$GPIOX::ptr() };
329 unsafe { bb::change_bit(&p.afsel, $i, false); }
330 unsafe { bb::change_bit(&p.dir, $i, true); }
331 unsafe { bb::change_bit(&p.odr, $i, true); }
332 unsafe { bb::change_bit(&p.pur, $i, ODM::pup()); }
333 unsafe { bb::change_bit(&p.pdr, $i, false); }
334 unsafe { bb::change_bit(&p.den, $i, true); }
335 $PXi { _mode: PhantomData }
336 }
337
338 pub fn into_push_pull_output(
340 self
341 ) -> $PXi<Output<PushPull>> {
342 let p = unsafe { &*$GPIOX::ptr() };
343 unsafe { bb::change_bit(&p.afsel, $i, false); }
344 unsafe { bb::change_bit(&p.dir, $i, true); }
345 unsafe { bb::change_bit(&p.odr, $i, false); }
346 unsafe { bb::change_bit(&p.pur, $i, false); }
347 unsafe { bb::change_bit(&p.pdr, $i, false); }
348 unsafe { bb::change_bit(&p.den, $i, true); }
349 $PXi { _mode: PhantomData }
350 }
351
352 pub fn into_tri_state(
354 self
355 ) -> $PXi<Tristate> {
356 let p = unsafe { &*$GPIOX::ptr() };
357 unsafe { bb::change_bit(&p.den, $i, false); }
358 unsafe { bb::change_bit(&p.afsel, $i, false); }
359 unsafe { bb::change_bit(&p.dir, $i, false); }
360 unsafe { bb::change_bit(&p.odr, $i, false); }
361 unsafe { bb::change_bit(&p.pur, $i, false); }
362 unsafe { bb::change_bit(&p.pdr, $i, false); }
363 $PXi { _mode: PhantomData }
364 }
365
366 }
367
368 impl<MODE> $PXi<MODE> {
369 pub fn downgrade(self) -> $PXx<MODE> {
374 $PXx {
375 i: $i,
376 _mode: self._mode,
377 }
378 }
379 }
380
381 impl<MODE> StatefulOutputPin for $PXi<Output<MODE>> where MODE: OutputMode {
382 fn is_set_high(&self) -> bool {
383 let p = unsafe { &*$GPIOX::ptr() };
384 bb::read_bit(&p.data, $i)
385 }
386
387 fn is_set_low(&self) -> bool {
388 !self.is_set_high()
389 }
390 }
391
392 impl<MODE> OutputPin for $PXi<Output<MODE>> where MODE: OutputMode {
393 fn set_high(&mut self) {
394 let p = unsafe { &*$GPIOX::ptr() };
395 unsafe { bb::change_bit(&p.data, $i, true); }
396 }
397
398 fn set_low(&mut self) {
399 let p = unsafe { &*$GPIOX::ptr() };
400 unsafe { bb::change_bit(&p.data, $i, false); }
401 }
402 }
403
404 impl<MODE> InputPin for $PXi<Input<MODE>> where MODE: InputMode {
405 fn is_high(&self) -> bool {
406 let p = unsafe { &*$GPIOX::ptr() };
407 bb::read_bit(&p.data, $i)
408 }
409
410 fn is_low(&self) -> bool {
411 !self.is_high()
412 }
413 }
414
415 impl<MODE> $PXi<Input<MODE>> where MODE: InputMode {
416 pub fn set_interrupt_mode(&mut self, mode: InterruptMode) {
418 let p = unsafe { &*$GPIOX::ptr() };
419 unsafe { bb::change_bit(&p.im, $i, false); }
420 match mode {
421 InterruptMode::LevelHigh => {
422 unsafe { bb::change_bit(&p.im, $i, false); }
424 unsafe { bb::change_bit(&p.is, $i, true); }
426 unsafe { bb::change_bit(&p.ibe, $i, false); }
428 unsafe { bb::change_bit(&p.iev, $i, true); }
430 unsafe { bb::change_bit(&p.im, $i, true); }
432 },
433 InterruptMode::LevelLow => {
434 unsafe { bb::change_bit(&p.im, $i, false); }
436 unsafe { bb::change_bit(&p.is, $i, true); }
438 unsafe { bb::change_bit(&p.ibe, $i, false); }
440 unsafe { bb::change_bit(&p.iev, $i, false); }
442 unsafe { bb::change_bit(&p.im, $i, true); }
444 },
445 InterruptMode::EdgeRising => {
446 unsafe { bb::change_bit(&p.im, $i, false); }
448 unsafe { bb::change_bit(&p.is, $i, false); }
450 unsafe { bb::change_bit(&p.ibe, $i, false); }
452 unsafe { bb::change_bit(&p.iev, $i, true); }
454 unsafe { bb::change_bit(&p.im, $i, true); }
456 },
457 InterruptMode::EdgeFalling => {
458 unsafe { bb::change_bit(&p.im, $i, false); }
460 unsafe { bb::change_bit(&p.is, $i, false); }
462 unsafe { bb::change_bit(&p.ibe, $i, false); }
464 unsafe { bb::change_bit(&p.iev, $i, false); }
466 unsafe { bb::change_bit(&p.im, $i, true); }
468 },
469 InterruptMode::EdgeBoth => {
470 unsafe { bb::change_bit(&p.im, $i, false); }
472 unsafe { bb::change_bit(&p.is, $i, false); }
474 unsafe { bb::change_bit(&p.ibe, $i, true); }
476 unsafe { bb::change_bit(&p.iev, $i, true); }
478 unsafe { bb::change_bit(&p.im, $i, true); }
480 },
481 InterruptMode::Disabled => {
482 unsafe { bb::change_bit(&p.im, $i, false); }
484 },
485 }
486 }
487
488 pub fn get_interrupt_status(&self) -> bool {
490 let p = unsafe { &*$GPIOX::ptr() };
491 bb::read_bit(&p.mis, $i)
492 }
493
494 pub fn clear_interrupt(&self) {
497 let p = unsafe { &*$GPIOX::ptr() };
498 unsafe { bb::change_bit(&p.icr, $i, true); }
499 }
500 }
501
502 impl $PXi<Locked> {
503 pub fn unlock(self, _gpio_control: &mut GpioControl) -> $PXi<Tristate> {
507 let p = unsafe { &*$GPIOX::ptr() };
508 p.lock.write(|w| w.lock().key());
509 p.cr.modify(|_, w| unsafe { w.bits(1 << $i) });
510 p.lock.write(|w| w.lock().unlocked());
511 unsafe { bb::change_bit(&p.den, $i, false); }
512 unsafe { bb::change_bit(&p.afsel, $i, false); }
513 unsafe { bb::change_bit(&p.dir, $i, false); }
514 unsafe { bb::change_bit(&p.odr, $i, false); }
515 unsafe { bb::change_bit(&p.pur, $i, false); }
516 unsafe { bb::change_bit(&p.pdr, $i, false); }
517 $PXi { _mode: PhantomData }
518 }
519 }
520 )+
521 }
522 }
523}
524
525#[macro_export]
527macro_rules! uart_hal_macro {
528 ($(
529 $UARTX:ident: ($powerDomain:ident, $uartX:ident),
530 )+) => {
531 $crate::uart_traits_macro!();
532
533 $(
534 impl<TX, RX, RTS, CTS> Serial<$UARTX, TX, RX, RTS, CTS> {
535 pub fn $uartX(
537 mut uart: $UARTX,
538 tx_pin: TX,
539 rx_pin: RX,
540 mut rts_pin: RTS,
541 mut cts_pin: CTS,
542 baud_rate: Bps,
543 nl_mode: NewlineMode,
544 clocks: &Clocks,
545 pc: &sysctl::PowerControl
546 ) -> Self
547 where
548 TX: TxPin<$UARTX>,
549 RX: RxPin<$UARTX>,
550 CTS: CtsPin<$UARTX>,
551 RTS: RtsPin<$UARTX>,
552 {
553 sysctl::control_power(
555 pc, sysctl::Domain::$powerDomain,
556 sysctl::RunMode::Run, sysctl::PowerState::On);
557 sysctl::reset(pc, sysctl::Domain::$powerDomain);
558
559 uart.ctl.reset();
561
562 let baud_int: u32 = (((clocks.sysclk.0 * 8) / baud_rate.0) + 1) / 2;
567
568 uart.ibrd.write(|w|
570 unsafe { w.divint().bits((baud_int / 64) as u16) });
571 uart.fbrd.write(|w|
572 unsafe { w.divfrac().bits((baud_int % 64) as u8) });
573
574 uart.lcrh.write(|w| w.wlen()._8().fen().bit(true));
576
577 rts_pin.enable(&mut uart);
579 cts_pin.enable(&mut uart);
580
581 uart.ctl.modify(|_, w| w.rxe().bit(true).txe().bit(true).uarten().bit(true));
583
584 Serial { uart, tx_pin, rx_pin, rts_pin, cts_pin, nl_mode }
585 }
586
587 pub fn change_baud_rate(&mut self, baud_rate: Bps, clocks: &Clocks) {
591 self.uart.ctl.modify(|_, w| w.uarten().bit(false));
593
594 let baud_int: u32 = (((clocks.sysclk.0 * 8) / baud_rate.0) + 1) / 2;
596
597 self.uart.ibrd.write(|w|
599 unsafe { w.divint().bits((baud_int / 64) as u16) });
600 self.uart.fbrd.write(|w|
601 unsafe { w.divfrac().bits((baud_int % 64) as u8) });
602
603 self.uart.lcrh.write(|w| w.wlen()._8().fen().bit(true));
606
607 self.uart.ctl.modify(|_, w| w.uarten().bit(true));
609 }
610
611 pub fn split(self) -> (Tx<$UARTX, TX, RTS>, Rx<$UARTX, RX, CTS>) {
615 (
616 Tx {
617 uart: self.uart,
618 pin: self.tx_pin,
619 nl_mode: self.nl_mode,
620 flow_pin: self.rts_pin,
621 },
622 Rx {
623 _uart: PhantomData,
624 pin: self.rx_pin,
625 flow_pin: self.cts_pin,
626 },
627 )
628 }
629
630 pub fn write_all<I: ?Sized>(&mut self, data: &I)
632 where
633 I: AsRef<[u8]>,
634 {
635 for octet in data.as_ref().iter() {
636 block!(self.write(*octet)).unwrap(); }
638 }
639
640 pub fn combine(tx: Tx<$UARTX, TX, RTS>, rx: Rx<$UARTX, RX, CTS>) -> Serial<$UARTX, TX, RX, RTS, CTS> {
642 Serial {
643 uart: tx.uart,
644 nl_mode: tx.nl_mode,
645 rx_pin: rx.pin,
646 tx_pin: tx.pin,
647 rts_pin: tx.flow_pin,
648 cts_pin: rx.flow_pin,
649 }
650 }
651
652 pub fn free(self) -> ($UARTX, TX, RX, RTS, CTS) {
654 (self.uart, self.tx_pin, self.rx_pin, self.rts_pin, self.cts_pin)
655 }
656 }
657
658 impl<TX, RTS> Tx<$UARTX, TX, RTS> {
659 pub fn write_all<I: ?Sized>(&mut self, data: &I)
661 where
662 I: AsRef<[u8]>,
663 {
664 for octet in data.as_ref().iter() {
665 block!(self.write(*octet)).unwrap(); }
667 }
668 }
669
670 impl<TX, RX, RTS, CTS> serial::Read<u8> for Serial<$UARTX, TX, RX, RTS, CTS> {
671 type Error = Void;
672
673 fn read(&mut self) -> nb::Result<u8, Self::Error> {
674 if self.uart.fr.read().rxfe().bit() {
675 return Err(nb::Error::WouldBlock);
676 }
677 Ok(self.uart.dr.read().data().bits())
678 }
679 }
680
681 impl<RX, CTS> serial::Read<u8> for Rx<$UARTX, RX, CTS> {
682 type Error = Void;
683
684 fn read(&mut self) -> nb::Result<u8, Self::Error> {
685 let p = unsafe { &*$UARTX::ptr() };
687 if p.fr.read().rxfe().bit() {
688 return Err(nb::Error::WouldBlock);
689 }
690 Ok(p.dr.read().data().bits())
691 }
692 }
693
694 impl<TX, RX, RTS, CTS> serial::Write<u8> for Serial<$UARTX, TX, RX, RTS, CTS> {
695 type Error = Void;
696
697 fn flush(&mut self) -> nb::Result<(), Void> {
698 if self.uart.fr.read().txff().bit() {
699 return Err(nb::Error::WouldBlock);
700 }
701 Ok(())
702 }
703
704 fn write(&mut self, byte: u8) -> nb::Result<(), Void> {
705 if self.uart.fr.read().txff().bit() {
706 return Err(nb::Error::WouldBlock);
707 }
708 self.uart.dr.write(|w| unsafe { w.data().bits(byte) });
709 Ok(())
710 }
711 }
712
713 impl<TX, RTS> serial::Write<u8> for Tx<$UARTX, TX, RTS> {
714 type Error = Void;
715
716 fn flush(&mut self) -> nb::Result<(), Void> {
717 if self.uart.fr.read().txff().bit() {
718 return Err(nb::Error::WouldBlock);
719 }
720 Ok(())
721 }
722
723 fn write(&mut self, byte: u8) -> nb::Result<(), Void> {
724 if self.uart.fr.read().txff().bit() {
725 return Err(nb::Error::WouldBlock);
726 }
727 self.uart.dr.write(|w| unsafe { w.data().bits(byte) });
728 Ok(())
729 }
730 }
731
732 impl<TX, RX, RTS, CTS> fmt::Write for Serial<$UARTX, TX, RX, RTS, CTS> {
734 fn write_str(&mut self, s: &str) -> fmt::Result {
735 match self.nl_mode {
736 NewlineMode::Binary => self.write_all(s),
737 NewlineMode::SwapLFtoCRLF => {
738 for byte in s.bytes() {
739 if byte == 0x0A {
740 block!(self.write(0x0D)).unwrap(); }
743 block!(self.write(byte)).unwrap(); }
745 }
746 }
747 Ok(())
748 }
749 }
750
751 impl<TX, RTS> fmt::Write for Tx<$UARTX, TX, RTS> {
753 fn write_str(&mut self, s: &str) -> fmt::Result {
754 match self.nl_mode {
755 NewlineMode::Binary => self.write_all(s),
756 NewlineMode::SwapLFtoCRLF => {
757 for byte in s.bytes() {
758 if byte == 0x0A {
759 block!(self.write(0x0D)).unwrap(); }
762 block!(self.write(byte)).unwrap(); }
764 }
765 }
766 Ok(())
767 }
768 }
769
770 )+
771 }
772}
773
774#[macro_export]
776macro_rules! uart_pin_macro {
777 ($UARTn:ident,
778 cts: [$(($($ctsgpio: ident)::*, $ctsaf: ident)),*],
779 rts: [$(($($rtsgpio: ident)::*, $rtsaf: ident)),*],
784 rx: [$(($($rxgpio: ident)::*, $rxaf: ident)),*],
785 tx: [$(($($txgpio: ident)::*, $txaf: ident)),*],
786 ) => {
787 $(
788 impl<T> CtsPin<$UARTn> for $($ctsgpio)::*<AlternateFunction<$ctsaf, T>>
789 where
790 T: OutputMode,
791 {
792 fn enable(&mut self, uart: &mut $UARTn) {
793 uart.ctl.modify(|_, w| w.ctsen().set_bit());
794 }
795 }
796 )*
797
798 $(
799 impl<T> RtsPin<$UARTn> for $($rtsgpio)::*<AlternateFunction<$rtsaf, T>>
800 where
801 T: OutputMode,
802 {
803 fn enable(&mut self, uart: &mut $UARTn) {
804 uart.ctl.modify(|_, w| w.rtsen().set_bit());
805 }
806 }
807 )*
808
809 $(
810 impl <T> RxPin<$UARTn> for $($rxgpio)::*<AlternateFunction<$rxaf, T>>
811 where
812 T: OutputMode,
813 {}
814 )*
815
816 $(
817 impl <T> TxPin<$UARTn> for $($txgpio)::*<AlternateFunction<$txaf, T>>
818 where
819 T: OutputMode,
820 {}
821 )*
822 }
823}