1use core::fmt::{Result, Write};
2use core::marker::PhantomData;
3use core::ptr;
4
5use hal;
6use hal::prelude::*;
7use nb;
8use void::Void;
9
10use stm32::{RCC, USART1, USART2};
11
12use gpio::gpioa::{PA10, PA14, PA15, PA2, PA3, PA9};
13use gpio::gpiob::{PB6, PB7};
14use gpio::{Alternate, AF0, AF1};
15use rcc::Clocks;
16use time::Bps;
17
18pub enum Event {
20 Rxne,
22 Txe,
24}
25
26#[derive(Debug)]
28pub enum Error {
29 Framing,
31 Noise,
33 Overrun,
35 Parity,
37 #[doc(hidden)]
38 _Extensible,
39}
40
41pub trait Pins<USART> {}
42
43impl Pins<USART1> for (PA9<Alternate<AF1>>, PA10<Alternate<AF1>>) {}
44impl Pins<USART1> for (PB6<Alternate<AF0>>, PB7<Alternate<AF0>>) {}
45impl Pins<USART1> for (PA9<Alternate<AF1>>, PB7<Alternate<AF0>>) {}
46impl Pins<USART1> for (PB6<Alternate<AF0>>, PA10<Alternate<AF1>>) {}
47
48impl Pins<USART2> for (PA2<Alternate<AF1>>, PA3<Alternate<AF1>>) {}
49impl Pins<USART2> for (PA2<Alternate<AF1>>, PA15<Alternate<AF1>>) {}
50impl Pins<USART2> for (PA14<Alternate<AF1>>, PA15<Alternate<AF1>>) {}
51impl Pins<USART2> for (PA14<Alternate<AF1>>, PA3<Alternate<AF1>>) {}
52
53pub struct Serial<USART, PINS> {
55 usart: USART,
56 pins: PINS,
57}
58
59pub struct Rx<USART> {
61 _usart: PhantomData<USART>,
62}
63
64pub struct Tx<USART> {
66 _usart: PhantomData<USART>,
67}
68
69impl<PINS> Serial<USART1, PINS> {
71 pub fn usart1(usart: USART1, pins: PINS, baud_rate: Bps, clocks: Clocks) -> Self
72 where
73 PINS: Pins<USART1>,
74 {
75 let rcc = unsafe { &(*RCC::ptr()) };
77
78 rcc.apb2enr.modify(|_, w| w.usart1en().set_bit());
80
81 let brr = clocks.pclk().0 / baud_rate.0;
83 usart.brr.write(|w| unsafe { w.bits(brr) });
84
85 usart.cr2.reset();
87 usart.cr3.reset();
88
89 usart.cr1.modify(|_, w| unsafe { w.bits(0xD) });
91
92 Serial { usart, pins }
93 }
94
95 pub fn split(self) -> (Tx<USART1>, Rx<USART1>) {
96 (
97 Tx {
98 _usart: PhantomData,
99 },
100 Rx {
101 _usart: PhantomData,
102 },
103 )
104 }
105 pub fn release(self) -> (USART1, PINS) {
106 (self.usart, self.pins)
107 }
108}
109
110impl hal::serial::Read<u8> for Rx<USART1> {
111 type Error = Error;
112
113 fn read(&mut self) -> nb::Result<u8, Error> {
114 let isr = unsafe { (*USART1::ptr()).isr.read() };
116
117 Err(if isr.pe().bit_is_set() {
118 nb::Error::Other(Error::Parity)
119 } else if isr.fe().bit_is_set() {
120 nb::Error::Other(Error::Framing)
121 } else if isr.nf().bit_is_set() {
122 nb::Error::Other(Error::Noise)
123 } else if isr.ore().bit_is_set() {
124 nb::Error::Other(Error::Overrun)
125 } else if isr.rxne().bit_is_set() {
126 return Ok(unsafe { ptr::read_volatile(&(*USART1::ptr()).rdr as *const _ as *const _) });
128 } else {
129 nb::Error::WouldBlock
130 })
131 }
132}
133
134impl hal::serial::Write<u8> for Tx<USART1> {
135 type Error = Void;
136
137 fn flush(&mut self) -> nb::Result<(), Self::Error> {
138 let isr = unsafe { (*USART1::ptr()).isr.read() };
140
141 if isr.tc().bit_is_set() {
142 Ok(())
143 } else {
144 Err(nb::Error::WouldBlock)
145 }
146 }
147
148 fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
149 let isr = unsafe { (*USART1::ptr()).isr.read() };
151
152 if isr.txe().bit_is_set() {
153 unsafe { ptr::write_volatile(&(*USART1::ptr()).tdr as *const _ as *mut _, byte) }
156 Ok(())
157 } else {
158 Err(nb::Error::WouldBlock)
159 }
160 }
161}
162
163impl<PINS> Serial<USART2, PINS> {
165 pub fn usart2(usart: USART2, pins: PINS, baud_rate: Bps, clocks: Clocks) -> Self
166 where
167 PINS: Pins<USART2>,
168 {
169 let rcc = unsafe { &(*RCC::ptr()) };
171
172 rcc.apb1enr.modify(|_, w| w.usart2en().set_bit());
174
175 let brr = clocks.pclk().0 / baud_rate.0;
177 usart.brr.write(|w| unsafe { w.bits(brr) });
178
179 usart.cr2.reset();
181 usart.cr3.reset();
182
183 usart.cr1.modify(|_, w| unsafe { w.bits(0xD) });
185
186 Serial { usart, pins }
187 }
188
189 pub fn split(self) -> (Tx<USART2>, Rx<USART2>) {
190 (
191 Tx {
192 _usart: PhantomData,
193 },
194 Rx {
195 _usart: PhantomData,
196 },
197 )
198 }
199 pub fn release(self) -> (USART2, PINS) {
200 (self.usart, self.pins)
201 }
202}
203
204impl hal::serial::Read<u8> for Rx<USART2> {
205 type Error = Error;
206
207 fn read(&mut self) -> nb::Result<u8, Error> {
208 let isr = unsafe { (*USART2::ptr()).isr.read() };
210
211 Err(if isr.pe().bit_is_set() {
212 nb::Error::Other(Error::Parity)
213 } else if isr.fe().bit_is_set() {
214 nb::Error::Other(Error::Framing)
215 } else if isr.nf().bit_is_set() {
216 nb::Error::Other(Error::Noise)
217 } else if isr.ore().bit_is_set() {
218 nb::Error::Other(Error::Overrun)
219 } else if isr.rxne().bit_is_set() {
220 return Ok(unsafe { ptr::read_volatile(&(*USART2::ptr()).rdr as *const _ as *const _) });
222 } else {
223 nb::Error::WouldBlock
224 })
225 }
226}
227
228impl hal::serial::Write<u8> for Tx<USART2> {
229 type Error = Void;
230
231 fn flush(&mut self) -> nb::Result<(), Self::Error> {
232 let isr = unsafe { (*USART2::ptr()).isr.read() };
234
235 if isr.tc().bit_is_set() {
236 Ok(())
237 } else {
238 Err(nb::Error::WouldBlock)
239 }
240 }
241
242 fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
243 let isr = unsafe { (*USART2::ptr()).isr.read() };
245
246 if isr.txe().bit_is_set() {
247 unsafe { ptr::write_volatile(&(*USART2::ptr()).tdr as *const _ as *mut _, byte) }
250 Ok(())
251 } else {
252 Err(nb::Error::WouldBlock)
253 }
254 }
255}
256
257impl<USART> Write for Tx<USART>
258where
259 Tx<USART>: hal::serial::Write<u8>,
260{
261 fn write_str(&mut self, s: &str) -> Result {
262 let _ = s
263 .as_bytes()
264 .iter()
265 .map(|c| block!(self.write(*c)))
266 .last();
267 Ok(())
268 }
269}