serial.rs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. use core::marker::PhantomData;
  2. use core::ptr;
  3. use core::sync::atomic::{self, Ordering};
  4. use cast::u16;
  5. use hal;
  6. use nb;
  7. use stm32::{USART1, USART2, USART3};
  8. use void::Void;
  9. use afio::MAPR;
  10. use dma::{dma1, CircBuffer, Static, Transfer, R, W};
  11. use gpio::gpioa::{PA10, PA2, PA3, PA9};
  12. use gpio::gpiob::{PB10, PB11, PB6, PB7};
  13. use gpio::{Alternate, Floating, Input, PushPull};
  14. use rcc::{APB1, APB2, Clocks};
  15. use time::Bps;
  16. /// Interrupt event
  17. pub enum Event {
  18. /// New data has been received
  19. Rxne,
  20. /// New data can be sent
  21. Txe,
  22. }
  23. /// Serial error
  24. #[derive(Debug)]
  25. pub enum Error {
  26. /// Framing error
  27. Framing,
  28. /// Noise error
  29. Noise,
  30. /// RX buffer overrun
  31. Overrun,
  32. /// Parity check error
  33. Parity,
  34. #[doc(hidden)]
  35. _Extensible,
  36. }
  37. pub trait Pins<USART> {
  38. const REMAP: u8;
  39. }
  40. impl Pins<USART1> for (PA9<Alternate<PushPull>>, PA10<Input<Floating>>) {
  41. const REMAP: u8 = 0;
  42. }
  43. impl Pins<USART1> for (PB6<Alternate<PushPull>>, PB7<Input<Floating>>) {
  44. const REMAP: u8 = 1;
  45. }
  46. impl Pins<USART2> for (PA2<Alternate<PushPull>>, PA3<Input<Floating>>) {
  47. const REMAP: u8 = 0;
  48. }
  49. // impl Pins<USART2> for (PD5<Alternate<PushPull>>, PD6<Input<Floating>>) {
  50. // const REMAP: u8 = 0;
  51. // }
  52. impl Pins<USART3> for (PB10<Alternate<PushPull>>, PB11<Input<Floating>>) {
  53. const REMAP: u8 = 0;
  54. }
  55. // impl Pins<USART3> for (PC10<Alternate<PushPull>>, PC11<Input<Floating>>) {
  56. // const REMAP: u8 = 1;
  57. // }
  58. // impl Pins<USART3> for (PD8<Alternate<PushPull>>, PD9<Input<Floating>>) {
  59. // const REMAP: u8 = 0b11;
  60. // }
  61. /// Serial abstraction
  62. pub struct Serial<USART, PINS> {
  63. usart: USART,
  64. pins: PINS,
  65. }
  66. /// Serial receiver
  67. pub struct Rx<USART> {
  68. _usart: PhantomData<USART>,
  69. }
  70. /// Serial transmitter
  71. pub struct Tx<USART> {
  72. _usart: PhantomData<USART>,
  73. }
  74. macro_rules! hal {
  75. ($(
  76. $USARTX:ident: (
  77. $usartX:ident,
  78. $usartXen:ident,
  79. $usartXrst:ident,
  80. $usartX_remap:ident,
  81. $bit:ident,
  82. $closure:expr,
  83. $APB:ident
  84. ),
  85. )+) => {
  86. $(
  87. impl<PINS> Serial<$USARTX, PINS> {
  88. pub fn $usartX(
  89. usart: $USARTX,
  90. pins: PINS,
  91. mapr: &mut MAPR,
  92. baud_rate: Bps,
  93. clocks: Clocks,
  94. apb: &mut $APB,
  95. ) -> Self
  96. where
  97. PINS: Pins<$USARTX>,
  98. {
  99. // enable and reset $USARTX
  100. apb.enr().modify(|_, w| w.$usartXen().set_bit());
  101. apb.rstr().modify(|_, w| w.$usartXrst().set_bit());
  102. apb.rstr().modify(|_, w| w.$usartXrst().clear_bit());
  103. #[allow(unused_unsafe)]
  104. mapr.mapr()
  105. .modify(|_, w| unsafe{
  106. w.$usartX_remap().$bit(($closure)(PINS::REMAP))
  107. });
  108. // enable DMA transfers
  109. usart.cr3.write(|w| w.dmat().set_bit().dmar().set_bit());
  110. let brr = clocks.pclk2().0 / baud_rate.0;
  111. assert!(brr >= 16, "impossible baud rate");
  112. usart.brr.write(|w| unsafe { w.bits(brr) });
  113. // UE: enable USART
  114. // RE: enable receiver
  115. // TE: enable transceiver
  116. usart
  117. .cr1
  118. .write(|w| w.ue().set_bit().re().set_bit().te().set_bit());
  119. Serial { usart, pins }
  120. }
  121. pub fn listen(&mut self, event: Event) {
  122. match event {
  123. Event::Rxne => self.usart.cr1.modify(|_, w| w.rxneie().set_bit()),
  124. Event::Txe => self.usart.cr1.modify(|_, w| w.txeie().set_bit()),
  125. }
  126. }
  127. pub fn unlisten(&mut self, event: Event) {
  128. match event {
  129. Event::Rxne => self.usart.cr1.modify(|_, w| w.rxneie().clear_bit()),
  130. Event::Txe => self.usart.cr1.modify(|_, w| w.txeie().clear_bit()),
  131. }
  132. }
  133. pub fn release(self) -> ($USARTX, PINS) {
  134. (self.usart, self.pins)
  135. }
  136. pub fn split(self) -> (Tx<$USARTX>, Rx<$USARTX>) {
  137. (
  138. Tx {
  139. _usart: PhantomData,
  140. },
  141. Rx {
  142. _usart: PhantomData,
  143. },
  144. )
  145. }
  146. }
  147. impl hal::serial::Read<u8> for Rx<$USARTX> {
  148. type Error = Error;
  149. fn read(&mut self) -> nb::Result<u8, Error> {
  150. // NOTE(unsafe) atomic read with no side effects
  151. let sr = unsafe { (*$USARTX::ptr()).sr.read() };
  152. // Check for any errors
  153. let err = if sr.pe().bit_is_set() {
  154. Some(Error::Parity)
  155. } else if sr.fe().bit_is_set() {
  156. Some(Error::Framing)
  157. } else if sr.ne().bit_is_set() {
  158. Some(Error::Noise)
  159. } else if sr.ore().bit_is_set() {
  160. Some(Error::Overrun)
  161. } else {
  162. None
  163. };
  164. if let Some(err) = err {
  165. // Some error occured. In order to clear that error flag, you have to
  166. // do a read from the sr register followed by a read from the dr
  167. // register
  168. // NOTE(read_volatile) see `write_volatile` below
  169. unsafe {
  170. ptr::read_volatile(&(*$USARTX::ptr()).sr as *const _ as *const _);
  171. ptr::read_volatile(&(*$USARTX::ptr()).dr as *const _ as *const _);
  172. }
  173. Err(nb::Error::Other(err))
  174. } else {
  175. // Check if a byte is available
  176. if sr.rxne().bit_is_set() {
  177. // Read the received byte
  178. // NOTE(read_volatile) see `write_volatile` below
  179. Ok(unsafe {
  180. ptr::read_volatile(&(*$USARTX::ptr()).dr as *const _ as *const _)
  181. })
  182. } else {
  183. Err(nb::Error::WouldBlock)
  184. }
  185. }
  186. }
  187. }
  188. impl<B> ReadDma<B> for Rx<$USARTX> where B: AsMut<[u8]> {
  189. fn circ_read(self, mut chan: Self::Dma, buffer: &'static mut [B; 2],
  190. ) -> CircBuffer<B, Self::Dma>
  191. {
  192. {
  193. let buffer = buffer[0].as_mut();
  194. chan.cmar().write(|w| unsafe {
  195. w.ma().bits(buffer.as_ptr() as usize as u32)
  196. });
  197. chan.cndtr().write(|w| unsafe{
  198. w.ndt().bits(u16(buffer.len() * 2).unwrap())
  199. });
  200. chan.cpar().write(|w| unsafe {
  201. w.pa().bits(&(*$USARTX::ptr()).dr as *const _ as usize as u32)
  202. });
  203. // TODO can we weaken this compiler barrier?
  204. // NOTE(compiler_fence) operations on `buffer` should not be reordered after
  205. // the next statement, which starts the DMA transfer
  206. atomic::compiler_fence(Ordering::SeqCst);
  207. chan.ccr().modify(|_, w| {
  208. w.mem2mem()
  209. .clear_bit()
  210. .pl()
  211. .medium()
  212. .msize()
  213. .bit8()
  214. .psize()
  215. .bit8()
  216. .minc()
  217. .set_bit()
  218. .pinc()
  219. .clear_bit()
  220. .circ()
  221. .set_bit()
  222. .dir()
  223. .clear_bit()
  224. .en()
  225. .set_bit()
  226. });
  227. }
  228. CircBuffer::new(buffer, chan)
  229. }
  230. fn read_exact(self, mut chan: Self::Dma, buffer: &'static mut B,
  231. ) -> Transfer<W, &'static mut B, Self::Dma, Self>
  232. {
  233. {
  234. let buffer = buffer.as_mut();
  235. chan.cmar().write(|w| unsafe {
  236. w.ma().bits(buffer.as_ptr() as usize as u32)
  237. });
  238. chan.cndtr().write(|w| unsafe{
  239. w.ndt().bits(u16(buffer.len()).unwrap())
  240. });
  241. chan.cpar().write(|w| unsafe {
  242. w.pa().bits(&(*$USARTX::ptr()).dr as *const _ as usize as u32)
  243. });
  244. // TODO can we weaken this compiler barrier?
  245. // NOTE(compiler_fence) operations on `buffer` should not be reordered after
  246. // the next statement, which starts the DMA transfer
  247. atomic::compiler_fence(Ordering::SeqCst);
  248. chan.ccr().modify(|_, w| {
  249. w.mem2mem()
  250. .clear_bit()
  251. .pl()
  252. .medium()
  253. .msize()
  254. .bit8()
  255. .psize()
  256. .bit8()
  257. .minc()
  258. .set_bit()
  259. .pinc()
  260. .clear_bit()
  261. .circ()
  262. .clear_bit()
  263. .dir()
  264. .clear_bit()
  265. .en()
  266. .set_bit()
  267. });
  268. }
  269. Transfer::w(buffer, chan, self)
  270. }
  271. }
  272. impl<A, B> WriteDma<A, B> for Tx<$USARTX> where A: AsRef<[u8]>, B: Static<A> {
  273. fn write_all(self, mut chan: Self::Dma, buffer: B
  274. ) -> Transfer<R, B, Self::Dma, Self>
  275. {
  276. {
  277. let buffer = buffer.borrow().as_ref();
  278. chan.cmar().write(|w| unsafe {
  279. w.ma().bits(buffer.as_ptr() as usize as u32)
  280. });
  281. chan.cndtr().write(|w| unsafe{
  282. w.ndt().bits(u16(buffer.len()).unwrap())
  283. });
  284. chan.cpar().write(|w| unsafe {
  285. w.pa().bits(&(*$USARTX::ptr()).dr as *const _ as usize as u32)
  286. });
  287. // TODO can we weaken this compiler barrier?
  288. // NOTE(compiler_fence) operations on `buffer` should not be reordered after
  289. // the next statement, which starts the DMA transfer
  290. atomic::compiler_fence(Ordering::SeqCst);
  291. chan.ccr().modify(|_, w| {
  292. w.mem2mem()
  293. .clear_bit()
  294. .pl()
  295. .medium()
  296. .msize()
  297. .bit8()
  298. .psize()
  299. .bit8()
  300. .minc()
  301. .set_bit()
  302. .pinc()
  303. .clear_bit()
  304. .circ()
  305. .clear_bit()
  306. .dir()
  307. .set_bit()
  308. .en()
  309. .set_bit()
  310. });
  311. }
  312. Transfer::r(buffer, chan, self)
  313. }
  314. }
  315. impl hal::serial::Write<u8> for Tx<$USARTX> {
  316. type Error = Void;
  317. fn flush(&mut self) -> nb::Result<(), Self::Error> {
  318. // NOTE(unsafe) atomic read with no side effects
  319. let sr = unsafe { (*$USARTX::ptr()).sr.read() };
  320. if sr.tc().bit_is_set() {
  321. Ok(())
  322. } else {
  323. Err(nb::Error::WouldBlock)
  324. }
  325. }
  326. fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
  327. // NOTE(unsafe) atomic read with no side effects
  328. let sr = unsafe { (*$USARTX::ptr()).sr.read() };
  329. if sr.txe().bit_is_set() {
  330. // NOTE(unsafe) atomic write to stateless register
  331. // NOTE(write_volatile) 8-bit write that's not possible through the svd2rust API
  332. unsafe {
  333. ptr::write_volatile(&(*$USARTX::ptr()).dr as *const _ as *mut _, byte)
  334. }
  335. Ok(())
  336. } else {
  337. Err(nb::Error::WouldBlock)
  338. }
  339. }
  340. }
  341. )+
  342. }
  343. }
  344. hal! {
  345. USART1: (
  346. usart1,
  347. usart1en,
  348. usart1rst,
  349. usart1_remap,
  350. bit,
  351. |remap| remap == 1,
  352. APB2
  353. ),
  354. USART2: (
  355. usart2,
  356. usart2en,
  357. usart2rst,
  358. usart2_remap,
  359. bit,
  360. |remap| remap == 1,
  361. APB1
  362. ),
  363. USART3: (
  364. usart3,
  365. usart3en,
  366. usart3rst,
  367. usart3_remap,
  368. bits,
  369. |remap| remap,
  370. APB1
  371. ),
  372. }
  373. use dma::DmaChannel;
  374. impl DmaChannel for Rx<USART1> {
  375. type Dma = dma1::C5;
  376. }
  377. impl DmaChannel for Tx<USART1> {
  378. type Dma = dma1::C4;
  379. }
  380. impl DmaChannel for Rx<USART2> {
  381. type Dma = dma1::C6;
  382. }
  383. impl DmaChannel for Tx<USART2> {
  384. type Dma = dma1::C7;
  385. }
  386. impl DmaChannel for Rx<USART3> {
  387. type Dma = dma1::C3;
  388. }
  389. impl DmaChannel for Tx<USART3> {
  390. type Dma = dma1::C2;
  391. }
  392. pub trait ReadDma<B>: DmaChannel
  393. where
  394. B: AsMut<[u8]>,
  395. Self: core::marker::Sized,
  396. {
  397. fn circ_read(self, chan: Self::Dma, buffer: &'static mut [B; 2]) -> CircBuffer<B, Self::Dma>;
  398. fn read_exact(
  399. self,
  400. chan: Self::Dma,
  401. buffer: &'static mut B,
  402. ) -> Transfer<W, &'static mut B, Self::Dma, Self>;
  403. }
  404. pub trait WriteDma<A, B>: DmaChannel
  405. where
  406. A: AsRef<[u8]>,
  407. B: Static<A>,
  408. Self: core::marker::Sized,
  409. {
  410. fn write_all(self, chan: Self::Dma, buffer: B) -> Transfer<R, B, Self::Dma, Self>;
  411. }