1use core::marker::PhantomData;
4use core::ptr;
5
6use hal::serial;
7use nb;
8use stm32f30x::{USART1, USART2, USART3};
9use void::Void;
10
11use gpio::gpioa::{PA10, PA2, PA3, PA9};
12use gpio::gpiob::{PB10, PB11, PB6, PB7};
13use gpio::gpioc::{PC10, PC11, PC4, PC5};
14use gpio::gpiod::{PD5, PD6, PD8, PD9};
15use gpio::gpioe::{PE0, PE1, PE15};
16use gpio::AF7;
17use rcc::{APB1, APB2, Clocks};
18use time::Bps;
19
20pub enum Event {
22 Rxne,
24 Txe,
26}
27
28#[derive(Debug)]
30pub enum Error {
31 Framing,
33 Noise,
35 Overrun,
37 Parity,
39 #[doc(hidden)]
40 _Extensible,
41}
42
43pub unsafe trait TxPin<USART> {}
46
47pub unsafe trait RxPin<USART> {}
49
50unsafe impl TxPin<USART1> for PA9<AF7> {}
51unsafe impl TxPin<USART1> for PB6<AF7> {}
52unsafe impl TxPin<USART1> for PC4<AF7> {}
53unsafe impl TxPin<USART1> for PE0<AF7> {}
54
55unsafe impl RxPin<USART1> for PA10<AF7> {}
56unsafe impl RxPin<USART1> for PB7<AF7> {}
57unsafe impl RxPin<USART1> for PC5<AF7> {}
58unsafe impl RxPin<USART1> for PE1<AF7> {}
59
60unsafe impl TxPin<USART2> for PA2<AF7> {}
61unsafe impl TxPin<USART2> for PD5<AF7> {}
64
65unsafe impl RxPin<USART2> for PA3<AF7> {}
66unsafe impl RxPin<USART2> for PD6<AF7> {}
69
70unsafe impl TxPin<USART3> for PB10<AF7> {}
71unsafe impl TxPin<USART3> for PC10<AF7> {}
72unsafe impl TxPin<USART3> for PD8<AF7> {}
73
74unsafe impl RxPin<USART3> for PB11<AF7> {}
75unsafe impl RxPin<USART3> for PC11<AF7> {}
76unsafe impl RxPin<USART3> for PD9<AF7> {}
77unsafe impl RxPin<USART3> for PE15<AF7> {}
78
79pub struct Serial<USART, PINS> {
81 usart: USART,
82 pins: PINS,
83}
84
85pub struct Rx<USART> {
87 _usart: PhantomData<USART>,
88}
89
90pub struct Tx<USART> {
92 _usart: PhantomData<USART>,
93}
94
95macro_rules! hal {
96 ($(
97 $USARTX:ident: ($usartX:ident, $APB:ident, $usartXen:ident, $usartXrst:ident, $pclkX:ident),
98 )+) => {
99 $(
100 impl<TX, RX> Serial<$USARTX, (TX, RX)> {
101 pub fn $usartX(
103 usart: $USARTX,
104 pins: (TX, RX),
105 baud_rate: Bps,
106 clocks: Clocks,
107 apb: &mut $APB,
108 ) -> Self
109 where
110 TX: TxPin<$USARTX>,
111 RX: RxPin<$USARTX>,
112 {
113 apb.enr().modify(|_, w| w.$usartXen().enabled());
115 apb.rstr().modify(|_, w| w.$usartXrst().set_bit());
116 apb.rstr().modify(|_, w| w.$usartXrst().clear_bit());
117
118 let brr = clocks.$pclkX().0 / baud_rate.0;
123 assert!(brr >= 16, "impossible baud rate");
124 usart.brr.write(|w| unsafe { w.bits(brr) });
125
126 usart
130 .cr1
131 .write(|w| w.ue().set_bit().re().set_bit().te().set_bit());
132
133 Serial { usart, pins }
134 }
135
136 pub fn listen(&mut self, event: Event) {
138 match event {
139 Event::Rxne => {
140 self.usart.cr1.modify(|_, w| w.rxneie().set_bit())
141 },
142 Event::Txe => {
143 self.usart.cr1.modify(|_, w| w.txeie().set_bit())
144 },
145 }
146 }
147
148 pub fn unlisten(&mut self, event: Event) {
150 match event {
151 Event::Rxne => {
152 self.usart.cr1.modify(|_, w| w.rxneie().clear_bit())
153 },
154 Event::Txe => {
155 self.usart.cr1.modify(|_, w| w.txeie().clear_bit())
156 },
157 }
158 }
159
160 pub fn split(self) -> (Tx<$USARTX>, Rx<$USARTX>) {
162 (
163 Tx {
164 _usart: PhantomData,
165 },
166 Rx {
167 _usart: PhantomData,
168 },
169 )
170 }
171
172 pub fn free(self) -> ($USARTX, (TX, RX)) {
174 (self.usart, self.pins)
175 }
176 }
177
178 impl serial::Read<u8> for Rx<$USARTX> {
179 type Error = Error;
180
181 fn read(&mut self) -> nb::Result<u8, Error> {
182 let isr = unsafe { (*$USARTX::ptr()).isr.read() };
184
185 Err(if isr.pe().bit_is_set() {
186 nb::Error::Other(Error::Parity)
187 } else if isr.fe().bit_is_set() {
188 nb::Error::Other(Error::Framing)
189 } else if isr.nf().bit_is_set() {
190 nb::Error::Other(Error::Noise)
191 } else if isr.ore().bit_is_set() {
192 nb::Error::Other(Error::Overrun)
193 } else if isr.rxne().bit_is_set() {
194 return Ok(unsafe {
196 ptr::read_volatile(&(*$USARTX::ptr()).rdr as *const _ as *const _)
197 });
198 } else {
199 nb::Error::WouldBlock
200 })
201 }
202 }
203
204 impl serial::Write<u8> for Tx<$USARTX> {
205 type Error = Void;
210
211 fn flush(&mut self) -> nb::Result<(), Void> {
212 let isr = unsafe { (*$USARTX::ptr()).isr.read() };
214
215 if isr.tc().bit_is_set() {
216 Ok(())
217 } else {
218 Err(nb::Error::WouldBlock)
219 }
220 }
221
222 fn write(&mut self, byte: u8) -> nb::Result<(), Void> {
223 let isr = unsafe { (*$USARTX::ptr()).isr.read() };
225
226 if isr.txe().bit_is_set() {
227 unsafe {
230 ptr::write_volatile(&(*$USARTX::ptr()).tdr as *const _ as *mut _, byte)
231 }
232 Ok(())
233 } else {
234 Err(nb::Error::WouldBlock)
235 }
236 }
237 }
238 )+
239 }
240}
241
242hal! {
243 USART1: (usart1, APB2, usart1en, usart1rst, pclk2),
244 USART2: (usart2, APB1, usart2en, usart2rst, pclk1),
245 USART3: (usart3, APB1, usart3en, usart3rst, pclk1),
246}