summaryrefslogtreecommitdiff
path: root/ucoo/arch/rcc.stm32f4.cc
diff options
context:
space:
mode:
authorNicolas Schodet2016-08-01 15:19:00 +0200
committerNicolas Schodet2019-10-09 23:05:50 +0200
commit3e4d6ce0beb81b99bcba9192e3855e1753599733 (patch)
treecd3c68303f561588378e2319a9289a520560128f /ucoo/arch/rcc.stm32f4.cc
parent23950b079fa441e7ace347a82898f45ef10b0578 (diff)
ucoo: add support for STM32F4[67]9
Diffstat (limited to 'ucoo/arch/rcc.stm32f4.cc')
-rw-r--r--ucoo/arch/rcc.stm32f4.cc37
1 files changed, 36 insertions, 1 deletions
diff --git a/ucoo/arch/rcc.stm32f4.cc b/ucoo/arch/rcc.stm32f4.cc
index 36e31b6..37aaaa1 100644
--- a/ucoo/arch/rcc.stm32f4.cc
+++ b/ucoo/arch/rcc.stm32f4.cc
@@ -36,6 +36,7 @@ int rcc_apb2_freq_hz = hsi_freq_hz;
int rcc_apb1_timer_freq_hz = hsi_freq_hz;
int rcc_apb2_timer_freq_hz = hsi_freq_hz;
int rcc_pll48_freq_hz = 0;
+int rcc_lcd_freq_hz = 0;
void
rcc_sys_clock_setup_pll (int sys_freq_hz, int hse_freq_hz,
@@ -95,7 +96,8 @@ rcc_sys_clock_setup_pll (int sys_freq_hz, int hse_freq_hz,
| pllm << RCC_PLLCFGR_PLLM_Pos
| plln << RCC_PLLCFGR_PLLN_Pos
| (pllp / 2 - 1) << RCC_PLLCFGR_PLLP_Pos
- | pllq << RCC_PLLCFGR_PLLQ_Pos;
+ | pllq << RCC_PLLCFGR_PLLQ_Pos
+ | (reg::RCC->PLLCFGR & RCC_PLLCFGR_PLLR);
reg::RCC->CR |= RCC_CR_PLLON;
while (!(reg::RCC->CR & RCC_CR_PLLRDY))
;
@@ -122,4 +124,37 @@ rcc_sys_clock_setup_pll (int sys_freq_hz, int hse_freq_hz,
rcc_pll48_freq_hz = pll_in_freq_hz / pllm * plln / pllq;
}
+void
+rcc_sai_pll_setup (int hse_freq_hz,
+ int pllm, int plln, int pllp, int pllq, int pllq_div,
+ int pllr, int pllr_div)
+{
+ // Stop PLL.
+ reg::RCC->CR &= ~RCC_CR_PLLSAION;
+ while (reg::RCC->CR & RCC_CR_PLLSAIRDY)
+ ;
+ // Start PLL.
+ static const LookupTable<int, uint32_t> pllr_div_table[] =
+ {
+ { 2, RCC_DCKCFGR_PLLSAIDIVR_Div2 },
+ { 4, RCC_DCKCFGR_PLLSAIDIVR_Div4 },
+ { 8, RCC_DCKCFGR_PLLSAIDIVR_Div8 },
+ { 16, RCC_DCKCFGR_PLLSAIDIVR_Div16 },
+ };
+ reg::RCC->PLLSAICFGR =
+ plln * RCC_PLLSAICFGR_PLLSAIN_0
+ | (pllp / 2 - 1) * RCC_PLLSAICFGR_PLLSAIP_0
+ | pllq * RCC_PLLSAICFGR_PLLSAIQ_0
+ | pllr * RCC_PLLSAICFGR_PLLSAIR_0;
+ reg::RCC->DCKCFGR =
+ (pllq_div - 1) << RCC_DCKCFGR_PLLSAIDIVQ_Pos
+ | simple_table_lookup (pllr_div_table, pllr_div);
+ ucoo::reg::RCC->CR |= RCC_CR_PLLSAION;
+ while (!(ucoo::reg::RCC->CR & RCC_CR_PLLSAIRDY))
+ ;
+ // Update frequencies.
+ int vco_out = hse_freq_hz / pllm * plln;
+ rcc_lcd_freq_hz = vco_out / pllr / pllr_div;
+}
+
} // namespace ucoo