1use core::marker::PhantomData;
2use core::convert::TryFrom;
3
4use nb;
5use bitrate::{Bps, Hertz};
6use bit_field::BitField;
7use hal::serial;
8use mk20d7::{self, UART0, UART1, UART2};
9use void::Void;
10
11use mcg::MultipurposeClockGenerator;
12use gpio::{
13 Alternate, ALT2, ALT3,
14 gpioa::{PTA1, PTA2},
15 gpiob::{PTB16, PTB17},
16 gpioc::{PTC3, PTC4},
17 gpiod::{PTD2, PTD3, PTD6, PTD7},
18 gpioe::{PTE0, PTE1},
19};
20
21pub enum Event {
23 Rxne,
25
26 Txe,
28}
29
30#[derive(Debug)]
32pub enum Error {
33 Framing,
35
36 Noise,
38
39 Overrun,
41
42 Parity,
44
45 #[doc(hidden)]
46 _Extensible,
47}
48
49pub unsafe trait TxPin<UART> {}
52
53pub unsafe trait RxPin<UART> {}
56
57unsafe impl RxPin<UART0> for PTA1<Alternate<ALT2>> {}
59unsafe impl TxPin<UART0> for PTA2<Alternate<ALT2>> {}
60
61unsafe impl RxPin<UART0> for PTB17<Alternate<ALT3>> {}
63unsafe impl TxPin<UART0> for PTB16<Alternate<ALT3>> {}
64
65unsafe impl RxPin<UART0> for PTD6<Alternate<ALT3>> {}
67unsafe impl TxPin<UART0> for PTD7<Alternate<ALT3>> {}
68
69unsafe impl RxPin<UART1> for PTC3<Alternate<ALT3>> {}
71unsafe impl TxPin<UART1> for PTC4<Alternate<ALT3>> {}
72
73unsafe impl RxPin<UART1> for PTE1<Alternate<ALT3>> {}
75unsafe impl TxPin<UART1> for PTE0<Alternate<ALT3>> {}
76
77unsafe impl RxPin<UART1> for PTD2<Alternate<ALT3>> {}
79unsafe impl TxPin<UART1> for PTD3<Alternate<ALT3>> {}
80
81
82pub struct Serial<UART, PINS> {
84 uart: UART,
85 pins: PINS,
86}
87
88pub struct Rx<UART> {
90 _uart: PhantomData<UART>,
91}
92
93pub struct Tx<UART> {
95 _uart: PhantomData<UART>,
96}
97
98macro_rules! hal {
99 ($(
100 $UARTX:ident: ($uartX:ident),
101 )+) => {
102 $(
103 impl<TX, RX> Serial<$UARTX, (TX, RX)> {
104 pub fn $uartX(
107 uart: $UARTX,
108 pins: (TX, RX),
109 baud_rate: Bps<u32>,
110 mcg: &MultipurposeClockGenerator,
111 ) -> Self
112 where
113 TX: TxPin<$UARTX>,
114 RX: RxPin<$UARTX>,
115 {
116 let clock: Hertz<u32> = mcg.get_pll_frequency().into();
118 let numerator = clock.0;
119 let denominator = baud_rate.0 * mcg.external_crystal_frequency.0;
120
121 let module_clock_divisor_main = numerator / denominator;
122
123 if module_clock_divisor_main >= 8192 {
124 panic!("Invalid UART clock divider: {}", module_clock_divisor_main);
125 }
126
127 let module_clock_divisor_gcd = gcd(numerator, denominator);
128 let module_clock_divisor_fine_adjustment_denominator = {
129 denominator / module_clock_divisor_gcd
130 };
131 let module_clock_divisor_fine_adjustment_numerator = {
132 (numerator / module_clock_divisor_gcd) - (module_clock_divisor_main * module_clock_divisor_fine_adjustment_denominator)
133 };
134 let module_clock_divisor_fine_adjustment = u8::try_from(
135 module_clock_divisor_fine_adjustment_numerator * 32 /
136 module_clock_divisor_fine_adjustment_denominator
137 ).unwrap();
138
139 uart.c4.write(|w| unsafe { w.brfa().bits(module_clock_divisor_fine_adjustment) });
141
142 let module_clock_divisor_high = module_clock_divisor_main.get_bits(8..13) as u8;
144 uart.bdh.write(|w| unsafe { w.sbr().bits(module_clock_divisor_high) });
145
146 let module_clock_divisor_low = module_clock_divisor_main.get_bits(0..8) as u8;
148 uart.bdl.write(|w| unsafe { w.sbr().bits(module_clock_divisor_low) });
149
150 uart.c2.write(|w| {
152 w.re().set_bit();
153 w.te().set_bit()
154 });
155
156 Serial { uart, pins }
157 }
158
159 pub fn split(self) -> (Tx<$UARTX>, Rx<$UARTX>) {
161 (Tx { _uart: PhantomData }, Rx { _uart: PhantomData })
162 }
163
164 pub fn free(self) -> ($UARTX, (TX, RX)) {
166 (self.uart, self.pins)
167 }
168 }
169
170 fn $uartX<'a>() -> &'a mk20d7::$uartX::RegisterBlock {
171 unsafe { &(*$UARTX::ptr()) }
172 }
173
174 impl serial::Read<u8> for Rx<$UARTX> {
175 type Error = Error;
176
177 fn read(&mut self) -> nb::Result<u8, Error> {
178 let uart = $uartX();
179 let s1 = uart.s1.read();
180
181 if s1.pf().bit_is_set() {
182 return Err(nb::Error::Other(Error::Parity));
183 }
184
185 if s1.fe().bit_is_set() {
186 return Err(nb::Error::Other(Error::Framing));
187 }
188
189 if s1.nf().bit_is_set() {
190 return Err(nb::Error::Other(Error::Noise));
191 }
192
193 if s1.or().bit_is_set() {
194 return Err(nb::Error::Other(Error::Overrun));
195 }
196
197 if s1.rdrf().bit_is_clear() {
198 return Err(nb::Error::WouldBlock);
199 }
200
201 Ok(uart.d.read().rt().bits())
202 }
203 }
204
205 impl serial::Write<u8> for Tx<$UARTX> {
206 type Error = Void;
211
212 fn flush(&mut self) -> nb::Result<(), Void> {
213 if $uartX().s1.read().tc().bit_is_clear() {
214 return Err(nb::Error::WouldBlock);
215 }
216
217 Ok(())
218 }
219
220 fn write(&mut self, byte: u8) -> nb::Result<(), Void> {
221 let uart = $uartX();
222
223 if uart.s1.read().tdre().bit_is_clear() {
224 return Err(nb::Error::WouldBlock);
225 }
226
227 uart.d.write(|w| unsafe { w.bits(byte) });
228
229 Ok(())
230 }
231 }
232 )+
233 }
234}
235
236hal! {
237 UART0: (uart0),
238 UART1: (uart1),
239 UART2: (uart2),
240}
241
242fn gcd(numerator: u32, denominator: u32) -> u32 {
244 let mut numerator = numerator;
245 let mut denominator = denominator;
246 while denominator != 0 {
247 let temp = denominator;
248 denominator = numerator % denominator;
249 numerator = temp;
250 }
251 numerator
252}