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, USART3, USART4, USART5, USART6};
11
12use gpio::*;
13use rcc::Clocks;
14use time::Bps;
15
16pub enum Event {
18 Rxne,
20 Txe,
22}
23
24#[derive(Debug)]
26pub enum Error {
27 Framing,
29 Noise,
31 Overrun,
33 Parity,
35 #[doc(hidden)]
36 _Extensible,
37}
38
39pub trait Pins<USART> {}
40
41#[cfg(any(
44 feature = "stm32f030f4",
45 feature = "stm32f030k6",
46 feature = "stm32f030c6",
47 feature = "stm32f030c8",
48 feature = "stm32f030cc",
49 feature = "stm32f030r8",
50 feature = "stm32f030rc"
51))]
52impl Pins<USART1> for (gpioa::PA9<Alternate<AF1>>, gpioa::PA10<Alternate<AF1>>) {}
53#[cfg(any(
54 feature = "stm32f030f4",
55 feature = "stm32f030k6",
56 feature = "stm32f030c6",
57))]
58impl Pins<USART1> for (gpioa::PA2<Alternate<AF1>>, gpioa::PA3<Alternate<AF1>>) {}
59#[cfg(any(feature = "stm32f030k6", feature = "stm32f030c6",))]
60impl Pins<USART1> for (gpioa::PA14<Alternate<AF1>>, gpioa::PA15<Alternate<AF1>>) {}
61#[cfg(any(
62 feature = "stm32f030k6",
63 feature = "stm32f030c6",
64 feature = "stm32f030c8",
65 feature = "stm32f030cc",
66 feature = "stm32f030r8",
67 feature = "stm32f030rc"
68))]
69impl Pins<USART1> for (gpiob::PB6<Alternate<AF0>>, gpiob::PB7<Alternate<AF0>>) {}
70#[cfg(any(
71 feature = "stm32f030c8",
72 feature = "stm32f030cc",
73 feature = "stm32f030r8",
74 feature = "stm32f030rc"
75))]
76impl Pins<USART2> for (gpioa::PA2<Alternate<AF1>>, gpioa::PA3<Alternate<AF1>>) {}
77#[cfg(any(
78 feature = "stm32f030c8",
79 feature = "stm32f030cc",
80 feature = "stm32f030r8",
81 feature = "stm32f030rc"
82))]
83impl Pins<USART2> for (gpioa::PA14<Alternate<AF1>>, gpioa::PA15<Alternate<AF1>>) {}
84#[cfg(any(feature = "stm32f030cc", feature = "stm32f030rc"))]
86impl Pins<USART3> for (gpiob::PB10<Alternate<AF4>>, gpiob::PB11<Alternate<AF4>>) {}
87#[cfg(any(feature = "stm32f030cc", feature = "stm32f030rc"))]
88impl Pins<USART4> for (gpioa::PA0<Alternate<AF4>>, gpioa::PA1<Alternate<AF4>>) {}
89#[cfg(any(feature = "stm32f030cc", feature = "stm32f030rc"))]
90impl Pins<USART5> for (gpiob::PB3<Alternate<AF4>>, gpiob::PB4<Alternate<AF4>>) {}
91#[cfg(any(feature = "stm32f030cc", feature = "stm32f030rc"))]
92impl Pins<USART6> for (gpioa::PA4<Alternate<AF4>>, gpioa::PA5<Alternate<AF4>>) {}
93
94pub struct Serial<USART, PINS> {
96 usart: USART,
97 pins: PINS,
98}
99
100pub struct Rx<USART> {
102 _usart: PhantomData<USART>,
103}
104
105pub struct Tx<USART> {
107 _usart: PhantomData<USART>,
108}
109
110macro_rules! usart {
111 ($($USART:ident: ($usart:ident, $usartXen:ident, $apbenr:ident),)+) => {
112 $(
113 impl<PINS> Serial<$USART, PINS> {
115 pub fn $usart(usart: $USART, pins: PINS, baud_rate: Bps, clocks: Clocks) -> Self
116 where
117 PINS: Pins<$USART>,
118 {
119 let rcc = unsafe { &(*RCC::ptr()) };
121
122 rcc.$apbenr.modify(|_, w| w.$usartXen().set_bit());
124
125 let brr = clocks.pclk().0 / baud_rate.0;
127 usart.brr.write(|w| unsafe { w.bits(brr) });
128
129 usart.cr2.reset();
131 usart.cr3.reset();
132
133 usart.cr1.modify(|_, w| unsafe { w.bits(0xD) });
135
136 Serial { usart, pins }
137 }
138
139 pub fn split(self) -> (Tx<$USART>, Rx<$USART>) {
140 (
141 Tx {
142 _usart: PhantomData,
143 },
144 Rx {
145 _usart: PhantomData,
146 },
147 )
148 }
149 pub fn release(self) -> ($USART, PINS) {
150 (self.usart, self.pins)
151 }
152 }
153
154 impl hal::serial::Read<u8> for Rx<$USART> {
155 type Error = Error;
156
157 fn read(&mut self) -> nb::Result<u8, Error> {
158 let isr = unsafe { (*$USART::ptr()).isr.read() };
160
161 Err(if isr.pe().bit_is_set() {
162 nb::Error::Other(Error::Parity)
163 } else if isr.fe().bit_is_set() {
164 nb::Error::Other(Error::Framing)
165 } else if isr.nf().bit_is_set() {
166 nb::Error::Other(Error::Noise)
167 } else if isr.ore().bit_is_set() {
168 nb::Error::Other(Error::Overrun)
169 } else if isr.rxne().bit_is_set() {
170 return Ok(unsafe { ptr::read_volatile(&(*$USART::ptr()).rdr as *const _ as *const _) });
172 } else {
173 nb::Error::WouldBlock
174 })
175 }
176 }
177
178 impl hal::serial::Write<u8> for Tx<$USART> {
179 type Error = Void;
180
181 fn flush(&mut self) -> nb::Result<(), Self::Error> {
182 let isr = unsafe { (*$USART::ptr()).isr.read() };
184
185 if isr.tc().bit_is_set() {
186 Ok(())
187 } else {
188 Err(nb::Error::WouldBlock)
189 }
190 }
191
192 fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
193 let isr = unsafe { (*$USART::ptr()).isr.read() };
195
196 if isr.txe().bit_is_set() {
197 unsafe { ptr::write_volatile(&(*$USART::ptr()).tdr as *const _ as *mut _, byte) }
200 Ok(())
201 } else {
202 Err(nb::Error::WouldBlock)
203 }
204 }
205 }
206
207 )+
208 }
209}
210
211impl<USART> Write for Tx<USART>
212where
213 Tx<USART>: hal::serial::Write<u8>,
214{
215 fn write_str(&mut self, s: &str) -> Result {
216 let _ = s.as_bytes().iter().map(|c| block!(self.write(*c))).last();
217 Ok(())
218 }
219}
220
221#[cfg(any(
222 feature = "stm32f030f4",
223 feature = "stm32f030k6",
224 feature = "stm32f030c6",
225 feature = "stm32f030c8",
226 feature = "stm32f030cc",
227 feature = "stm32f030r8",
228 feature = "stm32f030rc"
229))]
230usart! {
231 USART1: (usart1, usart1en, apb2enr),
232}
233
234#[cfg(any(
235 feature = "stm32f030c8",
236 feature = "stm32f030cc",
237 feature = "stm32f030r8",
238 feature = "stm32f030rc"
239))]
240usart! {
241 USART2: (usart2, usart2en, apb1enr),
242}
243
244#[cfg(any(feature = "stm32f030cc", feature = "stm32f030rc"))]
245usart! {
246 USART3: (usart3, usart3en, apb1enr),
247 USART4: (usart4, usart4en, apb1enr),
248 USART5: (usart5, usart5en, apb1enr),
249 }