rcc.rs 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. use core::cmp;
  2. use cast::u32;
  3. use stm32::rcc::cfgr::{SWW, USBPREW};
  4. use stm32::{rcc, RCC};
  5. use flash::ACR;
  6. use time::Hertz;
  7. /// Extension trait that constrains the `RCC` peripheral
  8. pub trait RccExt {
  9. /// Constrains the `RCC` peripheral so it plays nicely with the other abstractions
  10. fn constrain(self) -> Rcc;
  11. }
  12. impl RccExt for RCC {
  13. fn constrain(self) -> Rcc {
  14. Rcc {
  15. ahb: AHB { _0: () },
  16. apb1: APB1 { _0: () },
  17. apb2: APB2 { _0: () },
  18. cfgr: CFGR {
  19. hse: None,
  20. hclk: None,
  21. pclk1: None,
  22. pclk2: None,
  23. sysclk: None,
  24. },
  25. }
  26. }
  27. }
  28. /// Constrained RCC peripheral
  29. pub struct Rcc {
  30. /// AMBA High-performance Bus (AHB) registers
  31. pub ahb: AHB,
  32. /// Advanced Peripheral Bus 1 (APB1) registers
  33. pub apb1: APB1,
  34. /// Advanced Peripheral Bus 2 (APB2) registers
  35. pub apb2: APB2,
  36. pub cfgr: CFGR,
  37. }
  38. /// AMBA High-performance Bus (AHB) registers
  39. pub struct AHB {
  40. _0: (),
  41. }
  42. impl AHB {
  43. pub(crate) fn enr(&mut self) -> &rcc::AHBENR {
  44. // NOTE(unsafe) this proxy grants exclusive access to this register
  45. unsafe { &(*RCC::ptr()).ahbenr }
  46. }
  47. }
  48. /// Advanced Peripheral Bus 1 (APB1) registers
  49. pub struct APB1 {
  50. _0: (),
  51. }
  52. impl APB1 {
  53. pub(crate) fn enr(&mut self) -> &rcc::APB1ENR {
  54. // NOTE(unsafe) this proxy grants exclusive access to this register
  55. unsafe { &(*RCC::ptr()).apb1enr }
  56. }
  57. pub(crate) fn rstr(&mut self) -> &rcc::APB1RSTR {
  58. // NOTE(unsafe) this proxy grants exclusive access to this register
  59. unsafe { &(*RCC::ptr()).apb1rstr }
  60. }
  61. }
  62. /// Advanced Peripheral Bus 2 (APB2) registers
  63. pub struct APB2 {
  64. _0: (),
  65. }
  66. impl APB2 {
  67. pub(crate) fn enr(&mut self) -> &rcc::APB2ENR {
  68. // NOTE(unsafe) this proxy grants exclusive access to this register
  69. unsafe { &(*RCC::ptr()).apb2enr }
  70. }
  71. pub(crate) fn rstr(&mut self) -> &rcc::APB2RSTR {
  72. // NOTE(unsafe) this proxy grants exclusive access to this register
  73. unsafe { &(*RCC::ptr()).apb2rstr }
  74. }
  75. }
  76. const HSI: u32 = 8_000_000; // Hz
  77. pub struct CFGR {
  78. hse: Option<u32>,
  79. hclk: Option<u32>,
  80. pclk1: Option<u32>,
  81. pclk2: Option<u32>,
  82. sysclk: Option<u32>,
  83. }
  84. impl CFGR {
  85. /// Uses HSE (external oscillator) instead of HSI (internal RC oscillator) as the clock source.
  86. /// Will result in a hang if an external oscillator is not connected or it fails to start.
  87. pub fn use_hse<F>(mut self, freq: F) -> Self
  88. where
  89. F: Into<Hertz>,
  90. {
  91. self.hse = Some(freq.into().0);
  92. self
  93. }
  94. /// Sets the desired frequency for the HCLK clock
  95. pub fn hclk<F>(mut self, freq: F) -> Self
  96. where
  97. F: Into<Hertz>,
  98. {
  99. self.hclk = Some(freq.into().0);
  100. self
  101. }
  102. /// Sets the desired frequency for the PCKL1 clock
  103. pub fn pclk1<F>(mut self, freq: F) -> Self
  104. where
  105. F: Into<Hertz>,
  106. {
  107. self.pclk1 = Some(freq.into().0);
  108. self
  109. }
  110. /// Sets the desired frequency for the PCLK2 clock
  111. pub fn pclk2<F>(mut self, freq: F) -> Self
  112. where
  113. F: Into<Hertz>,
  114. {
  115. self.pclk2 = Some(freq.into().0);
  116. self
  117. }
  118. /// Sets the desired frequency for the SYSCLK clock
  119. pub fn sysclk<F>(mut self, freq: F) -> Self
  120. where
  121. F: Into<Hertz>,
  122. {
  123. self.sysclk = Some(freq.into().0);
  124. self
  125. }
  126. pub fn freeze(self, acr: &mut ACR) -> Clocks {
  127. // TODO ADC clock
  128. let pllsrcclk = self.hse.unwrap_or(HSI / 2);
  129. let pllmul = self.sysclk.unwrap_or(pllsrcclk) / pllsrcclk;
  130. let pllmul = cmp::min(cmp::max(pllmul, 1), 16);
  131. let (pllmul_bits, sysclk) = if pllmul == 1 {
  132. (None, self.hse.unwrap_or(HSI))
  133. } else {
  134. (Some(pllmul as u8 - 2), pllsrcclk * pllmul)
  135. };
  136. assert!(sysclk <= 72_000_000);
  137. let hpre_bits = self.hclk
  138. .map(|hclk| match sysclk / hclk {
  139. 0 => unreachable!(),
  140. 1 => 0b0111,
  141. 2 => 0b1000,
  142. 3...5 => 0b1001,
  143. 6...11 => 0b1010,
  144. 12...39 => 0b1011,
  145. 40...95 => 0b1100,
  146. 96...191 => 0b1101,
  147. 192...383 => 0b1110,
  148. _ => 0b1111,
  149. })
  150. .unwrap_or(0b0111);
  151. let hclk = sysclk / (1 << (hpre_bits - 0b0111));
  152. assert!(hclk <= 72_000_000);
  153. let ppre1_bits = self.pclk1
  154. .map(|pclk1| match hclk / pclk1 {
  155. 0 => unreachable!(),
  156. 1 => 0b011,
  157. 2 => 0b100,
  158. 3...5 => 0b101,
  159. 6...11 => 0b110,
  160. _ => 0b111,
  161. })
  162. .unwrap_or(0b011);
  163. let ppre1 = 1 << (ppre1_bits - 0b011);
  164. let pclk1 = hclk / u32(ppre1);
  165. assert!(pclk1 <= 36_000_000);
  166. let ppre2_bits = self.pclk2
  167. .map(|pclk2| match hclk / pclk2 {
  168. 0 => unreachable!(),
  169. 1 => 0b011,
  170. 2 => 0b100,
  171. 3...5 => 0b101,
  172. 6...11 => 0b110,
  173. _ => 0b111,
  174. })
  175. .unwrap_or(0b011);
  176. let ppre2 = 1 << (ppre2_bits - 0b011);
  177. let pclk2 = hclk / u32(ppre2);
  178. assert!(pclk2 <= 72_000_000);
  179. // adjust flash wait states
  180. unsafe {
  181. acr.acr().write(|w| {
  182. w.latency().bits(if sysclk <= 24_000_000 {
  183. 0b000
  184. } else if sysclk <= 48_000_000 {
  185. 0b001
  186. } else {
  187. 0b010
  188. })
  189. })
  190. }
  191. // the USB clock is only valid if an external crystal is used, the PLL is enabled, and the
  192. // PLL output frequency is a supported one.
  193. let (usbpre, usbclk_valid) = match (self.hse, pllmul_bits, sysclk) {
  194. (Some(_), Some(_), 72_000_000) => (USBPREW::DIV15, true),
  195. (Some(_), Some(_), 48_000_000) => (USBPREW::NODIV, true),
  196. _ => (USBPREW::NODIV, false),
  197. };
  198. let rcc = unsafe { &*RCC::ptr() };
  199. if self.hse.is_some() {
  200. // enable HSE and wait for it to be ready
  201. rcc.cr.modify(|_, w| w.hseon().set_bit());
  202. while rcc.cr.read().hserdy().bit_is_clear() {}
  203. }
  204. if let Some(pllmul_bits) = pllmul_bits {
  205. // enable PLL and wait for it to be ready
  206. rcc.cfgr.modify(|_, w| unsafe {
  207. w.pllmul()
  208. .bits(pllmul_bits)
  209. .pllsrc()
  210. .bit(if self.hse.is_some() {
  211. true
  212. } else {
  213. false
  214. })
  215. });
  216. rcc.cr.modify(|_, w| w.pllon().set_bit());
  217. while rcc.cr.read().pllrdy().bit_is_clear() {}
  218. }
  219. // set prescalers and clock source
  220. rcc.cfgr.modify(|_, w| unsafe {
  221. w.ppre2()
  222. .bits(ppre2_bits)
  223. .ppre1()
  224. .bits(ppre1_bits)
  225. .hpre()
  226. .bits(hpre_bits)
  227. .usbpre()
  228. .variant(usbpre)
  229. .sw()
  230. .variant(if pllmul_bits.is_some() {
  231. SWW::PLL
  232. } else if self.hse.is_some() {
  233. SWW::HSE
  234. } else {
  235. SWW::HSI
  236. })
  237. });
  238. Clocks {
  239. hclk: Hertz(hclk),
  240. pclk1: Hertz(pclk1),
  241. pclk2: Hertz(pclk2),
  242. ppre1,
  243. ppre2,
  244. sysclk: Hertz(sysclk),
  245. usbclk_valid,
  246. }
  247. }
  248. }
  249. /// Frozen clock frequencies
  250. ///
  251. /// The existence of this value indicates that the clock configuration can no longer be changed
  252. #[derive(Clone, Copy)]
  253. pub struct Clocks {
  254. hclk: Hertz,
  255. pclk1: Hertz,
  256. pclk2: Hertz,
  257. ppre1: u8,
  258. ppre2: u8,
  259. sysclk: Hertz,
  260. usbclk_valid: bool,
  261. }
  262. impl Clocks {
  263. /// Returns the frequency of the AHB
  264. pub fn hclk(&self) -> Hertz {
  265. self.hclk
  266. }
  267. /// Returns the frequency of the APB1
  268. pub fn pclk1(&self) -> Hertz {
  269. self.pclk1
  270. }
  271. /// Returns the frequency of the APB2
  272. pub fn pclk2(&self) -> Hertz {
  273. self.pclk2
  274. }
  275. pub(crate) fn ppre1(&self) -> u8 {
  276. self.ppre1
  277. }
  278. // TODO remove `allow`
  279. #[allow(dead_code)]
  280. pub(crate) fn ppre2(&self) -> u8 {
  281. self.ppre2
  282. }
  283. /// Returns the system (core) frequency
  284. pub fn sysclk(&self) -> Hertz {
  285. self.sysclk
  286. }
  287. /// Returns whether the USBCLK clock frequency is valid for the USB peripheral
  288. pub fn usbclk_valid(&self) -> bool {
  289. self.usbclk_valid
  290. }
  291. }