serial.rs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  1. //! # Serial Communication (USART)
  2. //! This module contains the functions to utilize the USART (Universal
  3. //! synchronous asynchronous receiver transmitter)
  4. //!
  5. //!
  6. //! ## Example usage:
  7. //! ```rust
  8. //! // prelude: create handles to the peripherals and registers
  9. //! let p = crate::pac::Peripherals::take().unwrap();
  10. //! let cp = cortex_m::Peripherals::take().unwrap();
  11. //! let mut flash = p.FLASH.constrain();
  12. //! let mut rcc = p.RCC.constrain();
  13. //! let clocks = rcc.cfgr.freeze(&mut flash.acr);
  14. //! let mut afio = p.AFIO.constrain(&mut rcc.apb2);
  15. //! let mut gpioa = p.GPIOA.split(&mut rcc.apb2);
  16. //!
  17. //! // USART1 on Pins A9 and A10
  18. //! let pin_tx = gpioa.pa9.into_alternate_push_pull(&mut gpioa.crh);
  19. //! let pin_rx = gpioa.pa10;
  20. //! // Create an interface struct for USART1 with 9600 Baud
  21. //! let serial = Serial::usart1(
  22. //! p.USART1,
  23. //! (pin_tx, pin_rx),
  24. //! &mut afio.mapr,
  25. //! 9_600.bps(),
  26. //! clocks,
  27. //! &mut rcc.apb2,
  28. //! );
  29. //!
  30. //! // separate into tx and rx channels
  31. //! let (mut tx, mut rx) = serial.split();
  32. //!
  33. //! // Write 'R' to the USART
  34. //! block!(tx.write(b'R')).ok();
  35. //! // Receive a byte from the USART and store it in "received"
  36. //! let received = block!(rx.read()).unwrap();
  37. //! ```
  38. use core::marker::PhantomData;
  39. use core::ptr;
  40. use core::sync::atomic::{self, Ordering};
  41. use cast::u16;
  42. use crate::hal;
  43. use nb;
  44. use crate::pac::{USART1, USART2, USART3};
  45. use void::Void;
  46. use crate::afio::MAPR;
  47. //use crate::dma::{dma1, CircBuffer, Static, Transfer, R, W};
  48. use crate::dma::{CircBuffer, Static, Transfer, R, W};
  49. use crate::gpio::gpioa::{PA10, PA2, PA3, PA9};
  50. use crate::gpio::gpiob::{PB10, PB11, PB6, PB7};
  51. use crate::gpio::{Alternate, Floating, Input, PushPull};
  52. use crate::rcc::{Clocks, APB1, APB2};
  53. use crate::time::Bps;
  54. /// Interrupt event
  55. pub enum Event {
  56. /// New data has been received
  57. Rxne,
  58. /// New data can be sent
  59. Txe,
  60. }
  61. /// Serial error
  62. #[derive(Debug)]
  63. pub enum Error {
  64. /// Framing error
  65. Framing,
  66. /// Noise error
  67. Noise,
  68. /// RX buffer overrun
  69. Overrun,
  70. /// Parity check error
  71. Parity,
  72. #[doc(hidden)]
  73. _Extensible,
  74. }
  75. pub trait Pins<USART> {
  76. const REMAP: u8;
  77. }
  78. impl Pins<USART1> for (PA9<Alternate<PushPull>>, PA10<Input<Floating>>) {
  79. const REMAP: u8 = 0;
  80. }
  81. impl Pins<USART1> for (PB6<Alternate<PushPull>>, PB7<Input<Floating>>) {
  82. const REMAP: u8 = 1;
  83. }
  84. impl Pins<USART2> for (PA2<Alternate<PushPull>>, PA3<Input<Floating>>) {
  85. const REMAP: u8 = 0;
  86. }
  87. // impl Pins<USART2> for (PD5<Alternate<PushPull>>, PD6<Input<Floating>>) {
  88. // const REMAP: u8 = 0;
  89. // }
  90. impl Pins<USART3> for (PB10<Alternate<PushPull>>, PB11<Input<Floating>>) {
  91. const REMAP: u8 = 0;
  92. }
  93. // impl Pins<USART3> for (PC10<Alternate<PushPull>>, PC11<Input<Floating>>) {
  94. // const REMAP: u8 = 1;
  95. // }
  96. // impl Pins<USART3> for (PD8<Alternate<PushPull>>, PD9<Input<Floating>>) {
  97. // const REMAP: u8 = 0b11;
  98. // }
  99. /// Serial abstraction
  100. pub struct Serial<USART, PINS> {
  101. usart: USART,
  102. pins: PINS,
  103. }
  104. /// Serial receiver
  105. pub struct Rx<USART> {
  106. _usart: PhantomData<USART>,
  107. }
  108. /// Serial transmitter
  109. pub struct Tx<USART> {
  110. _usart: PhantomData<USART>,
  111. }
  112. macro_rules! hal {
  113. ($(
  114. $(#[$meta:meta])*
  115. $USARTX:ident: (
  116. $usartX:ident,
  117. $usartXen:ident,
  118. $usartXrst:ident,
  119. $usartX_remap:ident,
  120. $pclk:ident,
  121. $bit:ident,
  122. $closure:expr,
  123. $APB:ident
  124. ),
  125. )+) => {
  126. $(
  127. $(#[$meta])*
  128. /// The behaviour of the functions is equal for all three USARTs.
  129. /// Except that they are using the corresponding USART hardware and pins.
  130. impl<PINS> Serial<$USARTX, PINS> {
  131. /// Configures the serial interface and creates the interface
  132. /// struct.
  133. ///
  134. /// `Bps` is the baud rate of the interface.
  135. ///
  136. /// `Clocks` passes information about the current frequencies of
  137. /// the clocks. The existence of the struct ensures that the
  138. /// clock settings are fixed.
  139. ///
  140. /// The `serial` struct takes ownership over the `USARTX` device
  141. /// registers and the specified `PINS`
  142. ///
  143. /// `MAPR` and `APBX` are register handles which are passed for
  144. /// configuration. (`MAPR` is used to map the USART to the
  145. /// corresponding pins. `APBX` is used to reset the USART.)
  146. pub fn $usartX(
  147. usart: $USARTX,
  148. pins: PINS,
  149. mapr: &mut MAPR,
  150. baud_rate: Bps,
  151. clocks: Clocks,
  152. apb: &mut $APB,
  153. ) -> Self
  154. where
  155. PINS: Pins<$USARTX>,
  156. {
  157. // enable and reset $USARTX
  158. apb.enr().modify(|_, w| w.$usartXen().set_bit());
  159. apb.rstr().modify(|_, w| w.$usartXrst().set_bit());
  160. apb.rstr().modify(|_, w| w.$usartXrst().clear_bit());
  161. #[allow(unused_unsafe)]
  162. mapr.mapr()
  163. .modify(|_, w| unsafe{
  164. w.$usartX_remap().$bit(($closure)(PINS::REMAP))
  165. });
  166. // enable DMA transfers
  167. usart.cr3.write(|w| w.dmat().set_bit().dmar().set_bit());
  168. let brr = clocks.$pclk().0 / baud_rate.0;
  169. assert!(brr >= 16, "impossible baud rate");
  170. usart.brr.write(|w| unsafe { w.bits(brr) });
  171. // UE: enable USART
  172. // RE: enable receiver
  173. // TE: enable transceiver
  174. usart
  175. .cr1
  176. .write(|w| w.ue().set_bit().re().set_bit().te().set_bit());
  177. Serial { usart, pins }
  178. }
  179. /// Starts listening to the USART by enabling the _Received data
  180. /// ready to be read (RXNE)_ interrupt and _Transmit data
  181. /// register empty (TXE)_ interrupt
  182. pub fn listen(&mut self, event: Event) {
  183. match event {
  184. Event::Rxne => self.usart.cr1.modify(|_, w| w.rxneie().set_bit()),
  185. Event::Txe => self.usart.cr1.modify(|_, w| w.txeie().set_bit()),
  186. }
  187. }
  188. /// Stops listening to the USART by disabling the _Received data
  189. /// ready to be read (RXNE)_ interrupt and _Transmit data
  190. /// register empty (TXE)_ interrupt
  191. pub fn unlisten(&mut self, event: Event) {
  192. match event {
  193. Event::Rxne => self.usart.cr1.modify(|_, w| w.rxneie().clear_bit()),
  194. Event::Txe => self.usart.cr1.modify(|_, w| w.txeie().clear_bit()),
  195. }
  196. }
  197. /// Returns ownership of the borrowed register handles
  198. pub fn release(self) -> ($USARTX, PINS) {
  199. (self.usart, self.pins)
  200. }
  201. /// Separates the serial struct into separate channel objects for sending (Tx) and
  202. /// receiving (Rx)
  203. pub fn split(self) -> (Tx<$USARTX>, Rx<$USARTX>) {
  204. (
  205. Tx {
  206. _usart: PhantomData,
  207. },
  208. Rx {
  209. _usart: PhantomData,
  210. },
  211. )
  212. }
  213. }
  214. impl crate::hal::serial::Read<u8> for Rx<$USARTX> {
  215. type Error = Error;
  216. fn read(&mut self) -> nb::Result<u8, Error> {
  217. // NOTE(unsafe) atomic read with no side effects
  218. let sr = unsafe { (*$USARTX::ptr()).sr.read() };
  219. // Check for any errors
  220. let err = if sr.pe().bit_is_set() {
  221. Some(Error::Parity)
  222. } else if sr.fe().bit_is_set() {
  223. Some(Error::Framing)
  224. } else if sr.ne().bit_is_set() {
  225. Some(Error::Noise)
  226. } else if sr.ore().bit_is_set() {
  227. Some(Error::Overrun)
  228. } else {
  229. None
  230. };
  231. if let Some(err) = err {
  232. // Some error occured. In order to clear that error flag, you have to
  233. // do a read from the sr register followed by a read from the dr
  234. // register
  235. // NOTE(read_volatile) see `write_volatile` below
  236. unsafe {
  237. ptr::read_volatile(&(*$USARTX::ptr()).sr as *const _ as *const _);
  238. ptr::read_volatile(&(*$USARTX::ptr()).dr as *const _ as *const _);
  239. }
  240. Err(nb::Error::Other(err))
  241. } else {
  242. // Check if a byte is available
  243. if sr.rxne().bit_is_set() {
  244. // Read the received byte
  245. // NOTE(read_volatile) see `write_volatile` below
  246. Ok(unsafe {
  247. ptr::read_volatile(&(*$USARTX::ptr()).dr as *const _ as *const _)
  248. })
  249. } else {
  250. Err(nb::Error::WouldBlock)
  251. }
  252. }
  253. }
  254. }
  255. /*
  256. impl<B> ReadDma<B> for Rx<$USARTX> where B: AsMut<[u8]> {
  257. fn circ_read(self, mut chan: Self::Dma, buffer: &'static mut [B; 2],
  258. ) -> CircBuffer<B, Self::Dma>
  259. {
  260. {
  261. let buffer = buffer[0].as_mut();
  262. chan.cmar().write(|w| {
  263. w.ma().bits(buffer.as_ptr() as usize as u32)
  264. });
  265. chan.cndtr().write(|w| {
  266. w.ndt().bits(u16(buffer.len() * 2).unwrap())
  267. });
  268. chan.cpar().write(|w| unsafe {
  269. w.pa().bits(&(*$USARTX::ptr()).dr as *const _ as usize as u32)
  270. });
  271. // TODO can we weaken this compiler barrier?
  272. // NOTE(compiler_fence) operations on `buffer` should not be reordered after
  273. // the next statement, which starts the DMA transfer
  274. atomic::compiler_fence(Ordering::SeqCst);
  275. chan.ccr().modify(|_, w| {
  276. w.mem2mem()
  277. .clear_bit()
  278. .pl()
  279. .medium()
  280. .msize()
  281. .bit8()
  282. .psize()
  283. .bit8()
  284. .minc()
  285. .set_bit()
  286. .pinc()
  287. .clear_bit()
  288. .circ()
  289. .set_bit()
  290. .dir()
  291. .clear_bit()
  292. .en()
  293. .set_bit()
  294. });
  295. }
  296. CircBuffer::new(buffer, chan)
  297. }
  298. fn read_exact(self, mut chan: Self::Dma, buffer: &'static mut B,
  299. ) -> Transfer<W, &'static mut B, Self::Dma, Self>
  300. {
  301. {
  302. let buffer = buffer.as_mut();
  303. chan.cmar().write(|w| {
  304. w.ma().bits(buffer.as_ptr() as usize as u32)
  305. });
  306. chan.cndtr().write(|w| {
  307. w.ndt().bits(u16(buffer.len()).unwrap())
  308. });
  309. chan.cpar().write(|w| unsafe {
  310. w.pa().bits(&(*$USARTX::ptr()).dr as *const _ as usize as u32)
  311. });
  312. // TODO can we weaken this compiler barrier?
  313. // NOTE(compiler_fence) operations on `buffer` should not be reordered after
  314. // the next statement, which starts the DMA transfer
  315. atomic::compiler_fence(Ordering::SeqCst);
  316. chan.ccr().modify(|_, w| {
  317. w.mem2mem()
  318. .clear_bit()
  319. .pl()
  320. .medium()
  321. .msize()
  322. .bit8()
  323. .psize()
  324. .bit8()
  325. .minc()
  326. .set_bit()
  327. .pinc()
  328. .clear_bit()
  329. .circ()
  330. .clear_bit()
  331. .dir()
  332. .clear_bit()
  333. .en()
  334. .set_bit()
  335. });
  336. }
  337. Transfer::w(buffer, chan, self)
  338. }
  339. }
  340. */
  341. /*
  342. impl<A, B> WriteDma<A, B> for Tx<$USARTX> where A: AsRef<[u8]>, B: Static<A> {
  343. fn write_all(self, mut chan: Self::Dma, buffer: B
  344. ) -> Transfer<R, B, Self::Dma, Self>
  345. {
  346. {
  347. let buffer = buffer.borrow().as_ref();
  348. chan.cmar().write(|w| {
  349. w.ma().bits(buffer.as_ptr() as usize as u32)
  350. });
  351. chan.cndtr().write(|w| {
  352. w.ndt().bits(u16(buffer.len()).unwrap())
  353. });
  354. chan.cpar().write(|w| unsafe {
  355. w.pa().bits(&(*$USARTX::ptr()).dr as *const _ as usize as u32)
  356. });
  357. // TODO can we weaken this compiler barrier?
  358. // NOTE(compiler_fence) operations on `buffer` should not be reordered after
  359. // the next statement, which starts the DMA transfer
  360. atomic::compiler_fence(Ordering::SeqCst);
  361. chan.ccr().modify(|_, w| {
  362. w.mem2mem()
  363. .clear_bit()
  364. .pl()
  365. .medium()
  366. .msize()
  367. .bit8()
  368. .psize()
  369. .bit8()
  370. .minc()
  371. .set_bit()
  372. .pinc()
  373. .clear_bit()
  374. .circ()
  375. .clear_bit()
  376. .dir()
  377. .set_bit()
  378. .en()
  379. .set_bit()
  380. });
  381. }
  382. Transfer::r(buffer, chan, self)
  383. }
  384. }
  385. */
  386. impl crate::hal::serial::Write<u8> for Tx<$USARTX> {
  387. type Error = Void;
  388. fn flush(&mut self) -> nb::Result<(), Self::Error> {
  389. // NOTE(unsafe) atomic read with no side effects
  390. let sr = unsafe { (*$USARTX::ptr()).sr.read() };
  391. if sr.tc().bit_is_set() {
  392. Ok(())
  393. } else {
  394. Err(nb::Error::WouldBlock)
  395. }
  396. }
  397. fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
  398. // NOTE(unsafe) atomic read with no side effects
  399. let sr = unsafe { (*$USARTX::ptr()).sr.read() };
  400. if sr.txe().bit_is_set() {
  401. // NOTE(unsafe) atomic write to stateless register
  402. // NOTE(write_volatile) 8-bit write that's not possible through the svd2rust API
  403. unsafe {
  404. ptr::write_volatile(&(*$USARTX::ptr()).dr as *const _ as *mut _, byte)
  405. }
  406. Ok(())
  407. } else {
  408. Err(nb::Error::WouldBlock)
  409. }
  410. }
  411. }
  412. )+
  413. }
  414. }
  415. hal! {
  416. /// # USART1 functions
  417. USART1: (
  418. usart1,
  419. usart1en,
  420. usart1rst,
  421. usart1_remap,
  422. pclk2,
  423. bit,
  424. |remap| remap == 1,
  425. APB2
  426. ),
  427. /// # USART2 functions
  428. USART2: (
  429. usart2,
  430. usart2en,
  431. usart2rst,
  432. usart2_remap,
  433. pclk1,
  434. bit,
  435. |remap| remap == 1,
  436. APB1
  437. ),
  438. /// # USART3 functions
  439. USART3: (
  440. usart3,
  441. usart3en,
  442. usart3rst,
  443. usart3_remap,
  444. pclk1,
  445. bits,
  446. |remap| remap,
  447. APB1
  448. ),
  449. }
  450. /*
  451. use dma::DmaChannel;
  452. impl DmaChannel for Rx<USART1> {
  453. type Dma = dma1::C5;
  454. }
  455. impl DmaChannel for Tx<USART1> {
  456. type Dma = dma1::C4;
  457. }
  458. impl DmaChannel for Rx<USART2> {
  459. type Dma = dma1::C6;
  460. }
  461. impl DmaChannel for Tx<USART2> {
  462. type Dma = dma1::C7;
  463. }
  464. impl DmaChannel for Rx<USART3> {
  465. type Dma = dma1::C3;
  466. }
  467. impl DmaChannel for Tx<USART3> {
  468. type Dma = dma1::C2;
  469. }
  470. pub trait ReadDma<B>: DmaChannel
  471. where
  472. B: AsMut<[u8]>,
  473. Self: core::marker::Sized,
  474. {
  475. fn circ_read(self, chan: Self::Dma, buffer: &'static mut [B; 2]) -> CircBuffer<B, Self::Dma>;
  476. fn read_exact(
  477. self,
  478. chan: Self::Dma,
  479. buffer: &'static mut B,
  480. ) -> Transfer<W, &'static mut B, Self::Dma, Self>;
  481. }
  482. pub trait WriteDma<A, B>: DmaChannel
  483. where
  484. A: AsRef<[u8]>,
  485. B: Static<A>,
  486. Self: core::marker::Sized,
  487. {
  488. fn write_all(self, chan: Self::Dma, buffer: B) -> Transfer<R, B, Self::Dma, Self>;
  489. }
  490. */