rcc.rs 10 KB

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