2022-02-22 06:20 AM
STM32F746-Disco, Win 10, CubeIDE 1.8.0, CMSIS-only (no HAL), C.
I've decided to change the clock of my MCU from HSI 16MHz to full 216MHz with PLL. I've setup the correct values for PLL parameters, but whenever I actually switch system clock to PLL, the thing crashes (and doesn't crash if I don't).
It's a full empty project, only register definitions from MCU-specific headers and m7 core. For now it's an empty project that only lights up an LED - if it gets there, that is.
I change AHB, APB dividers, all is fine. As long as I'm on HSI, it still works ok. I configure PLL and make sure the values are set - debugger shows all correct values, I triple checked every single bit with pen and paper. Literally.
I noticed that HAL activates PWR peripheral during clock setup, which I don't do. Description of PWR peripheral in the reference manual gives no reason to believe it has anything to do with it, but maybe I overlooked something.
Here's the interesting part:
void rcc_init(void) {
//enable HSE
RCC->CR |= RCC_CR_HSEON;
while (!(RCC->CR & RCC_CR_HSERDY)); //wait while hardware signals HSE is stable
//configure PLL
/*
RCC->PLLCFGR |= RCC_PLLCFGR_PLLSRC_HSE; //PLL/PLL2S source = HSE
RCC->PLLCFGR &= ~0x1F<<RCC_PLLCFGR_PLLM_Pos; //reset all PLLM bits
RCC->PLLCFGR |= 0x19 << RCC_PLLCFGR_PLLM_Pos; //PLLM 25
RCC->PLLCFGR &= 0x1FF << RCC_PLLCFGR_PLLN_Pos; //reset all PLLN bits
RCC->PLLCFGR |= 0x1B0 << RCC_PLLCFGR_PLLN_Pos; //PLLN 432
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLP; //PLLP 2
*/
RCC->PLLCFGR = 0x29406C19;
RCC->CR |= RCC_CR_PLLON; //Enable PLL
while (!(RCC->CR & RCC_CR_PLLRDY)); //wait while hardware signals PLL is OK
//configure AHB/APB clocks
RCC->CFGR &= ~RCC_CFGR_HPRE_DIV1; //AHB Prescaler 1
RCC->CFGR |= RCC_CFGR_PPRE1_DIV4; //APB1 Prescaler 4
RCC->CFGR |= RCC_CFGR_PPRE2_DIV2; //APB2 Prescaler 2
//Set System Clock to PLL
RCC->CFGR |= RCC_CFGR_SW_PLL; // System Clock Mux: Select PLL as system clock
while ((RCC->CFGR & RCC_CFGR_SWS) != (RCC_CFGR_SWS_PLL)); //wait until PLL is established as system clock
}
The commented out PLL_CFGR manual configuration for whatever reason doesn't get executed, the register stays at reset value. But when I manually write the full register value, it works.
It crashes on RCC->CFGR |= RCC_CFGR_SW_PLL; If I don't execute that line (comment out), I stay on HSI and don't crash, work totally OK.
What am I missing? Why do I get an error? I can't find anything in the reference manual that would suggest I did something wrong.
EDIT
I discovered HAL enables PWR and enables overdrive and overdrive switching. So I did the same. No difference. Here is how I do that (functionally identical to HAL clock initialization code):
//enable PWR peripheral
volatile uint32_t temp;
RCC->APB1ENR |= RCC_APB1ENR_PWREN;
temp = RCC->APB1ENR & RCC_APB1ENR_PWREN;
(void) temp; //waste cycles until activated
PWR->CR1 |= PWR_CR1_VOS; //explicit default value for internal voltage regulator
(void) temp; //waste cycles until activated
PWR->CR1 |= PWR_CR1_ODEN;
while (!(PWR->CSR1 & PWR_CSR1_ODRDY)); //wait while overdrive gets ready
PWR->CR1 |= PWR_CR1_ODSWEN; //enable overdrive switching
while (!(PWR->CSR1 & PWR_CSR1_ODSWRDY)); //wait while overdrive gets ready
EDIT2:
I debugged my code and CubeMX generated code. Decided to compare RCC and PWR registers in case I missed something.
RCC:
CR - identical to the bit
PLLCFGR - identical to the bit
CFGR - identical to the bit
PWR:
CR1 - identical to the bit
CSR1 - identical to the bit
CR2 - identical to the bit
CSR2 - identical to the bit
except that my code crashes. I'm out of ideas.
Compared to CubeMX code that uses 216MHz! Functionally, I forgot to change flash latency! And it worked (I don't know much about flash yet).
Solved! Go to Solution.
2022-02-22 07:59 AM
Compared to CubeMX code that uses 216MHz! Functionally, I forgot to change flash latency! And it worked (I don't know much about flash yet).
2022-02-22 07:59 AM
Compared to CubeMX code that uses 216MHz! Functionally, I forgot to change flash latency! And it worked (I don't know much about flash yet).