afio.rs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. //! # Alternate Function I/Os
  2. use crate::pac::{afio, AFIO};
  3. use crate::rcc::{Enable, Reset, APB2};
  4. use crate::gpio::{
  5. gpioa::PA15,
  6. gpiob::{PB3, PB4},
  7. Debugger, Floating, Input,
  8. };
  9. pub trait AfioExt {
  10. fn constrain(self, apb2: &mut APB2) -> Parts;
  11. }
  12. impl AfioExt for AFIO {
  13. fn constrain(self, apb2: &mut APB2) -> Parts {
  14. AFIO::enable(apb2);
  15. AFIO::reset(apb2);
  16. Parts {
  17. evcr: EVCR { _0: () },
  18. mapr: MAPR {
  19. _0: (),
  20. jtag_enabled: true,
  21. },
  22. exticr1: EXTICR1 { _0: () },
  23. exticr2: EXTICR2 { _0: () },
  24. exticr3: EXTICR3 { _0: () },
  25. exticr4: EXTICR4 { _0: () },
  26. mapr2: MAPR2 { _0: () },
  27. }
  28. }
  29. }
  30. /// HAL wrapper around the AFIO registers
  31. ///
  32. /// Aquired by calling [constrain](trait.AfioExt.html#constrain) on the [AFIO
  33. /// registers](../pac/struct.AFIO.html)
  34. ///
  35. /// ```rust
  36. /// let p = pac::Peripherals::take().unwrap();
  37. /// let mut rcc = p.RCC.constrain();
  38. /// let mut afio = p.AFIO.constrain(&mut rcc.apb2);
  39. pub struct Parts {
  40. pub evcr: EVCR,
  41. pub mapr: MAPR,
  42. pub exticr1: EXTICR1,
  43. pub exticr2: EXTICR2,
  44. pub exticr3: EXTICR3,
  45. pub exticr4: EXTICR4,
  46. pub mapr2: MAPR2,
  47. }
  48. pub struct EVCR {
  49. _0: (),
  50. }
  51. impl EVCR {
  52. pub fn evcr(&mut self) -> &afio::EVCR {
  53. unsafe { &(*AFIO::ptr()).evcr }
  54. }
  55. }
  56. /// AF remap and debug I/O configuration register (MAPR)
  57. ///
  58. /// Aquired through the [Parts](struct.Parts.html) struct.
  59. ///
  60. /// ```rust
  61. /// let dp = pac::Peripherals::take().unwrap();
  62. /// let mut rcc = dp.RCC.constrain();
  63. /// let mut afio = dp.AFIO.constrain(&mut rcc.apb2);
  64. /// function_using_mapr(&mut afio.mapr);
  65. /// ```
  66. pub struct MAPR {
  67. _0: (),
  68. jtag_enabled: bool,
  69. }
  70. impl MAPR {
  71. fn mapr(&mut self) -> &afio::MAPR {
  72. unsafe { &(*AFIO::ptr()).mapr }
  73. }
  74. pub fn modify_mapr<F>(&mut self, mod_fn: F)
  75. where
  76. F: for<'w> FnOnce(&afio::mapr::R, &'w mut afio::mapr::W) -> &'w mut afio::mapr::W,
  77. {
  78. let debug_bits = if self.jtag_enabled { 0b000 } else { 0b010 };
  79. self.mapr()
  80. .modify(unsafe { |r, w| mod_fn(r, w).swj_cfg().bits(debug_bits) });
  81. }
  82. /// Disables the JTAG to free up pa15, pb3 and pb4 for normal use
  83. pub fn disable_jtag(
  84. &mut self,
  85. pa15: PA15<Debugger>,
  86. pb3: PB3<Debugger>,
  87. pb4: PB4<Debugger>,
  88. ) -> (
  89. PA15<Input<Floating>>,
  90. PB3<Input<Floating>>,
  91. PB4<Input<Floating>>,
  92. ) {
  93. self.jtag_enabled = false;
  94. // Avoid duplicating swj_cfg write code
  95. self.modify_mapr(|_, w| w);
  96. // NOTE(unsafe) The pins are now in the good state.
  97. unsafe { (pa15.activate(), pb3.activate(), pb4.activate()) }
  98. }
  99. }
  100. pub struct EXTICR1 {
  101. _0: (),
  102. }
  103. impl EXTICR1 {
  104. pub fn exticr1(&mut self) -> &afio::EXTICR1 {
  105. unsafe { &(*AFIO::ptr()).exticr1 }
  106. }
  107. }
  108. pub struct EXTICR2 {
  109. _0: (),
  110. }
  111. impl EXTICR2 {
  112. pub fn exticr2(&mut self) -> &afio::EXTICR2 {
  113. unsafe { &(*AFIO::ptr()).exticr2 }
  114. }
  115. }
  116. pub struct EXTICR3 {
  117. _0: (),
  118. }
  119. impl EXTICR3 {
  120. pub fn exticr3(&mut self) -> &afio::EXTICR3 {
  121. unsafe { &(*AFIO::ptr()).exticr3 }
  122. }
  123. }
  124. pub struct EXTICR4 {
  125. _0: (),
  126. }
  127. impl EXTICR4 {
  128. pub fn exticr4(&mut self) -> &afio::EXTICR4 {
  129. unsafe { &(*AFIO::ptr()).exticr4 }
  130. }
  131. }
  132. pub struct MAPR2 {
  133. _0: (),
  134. }
  135. impl MAPR2 {
  136. pub fn mapr2(&mut self) -> &afio::MAPR2 {
  137. unsafe { &(*AFIO::ptr()).mapr2 }
  138. }
  139. }