The PLL3N field in PLL3DIVR has a bug
I had trouble setting the PLL3N field in PLL3DIVR in an STM32H533. The documentation says the field CANNOT be set if PLL 3 is enabled. I spent a whole day running iterations, trying to turn PLL 3 off, reordering writes, etc. What I FINALLY found is that the field CANNOT be set if PLL1 is enabled, i.e. the WRONG PLL.
The following code fails:
RCC->PLL1CFGR = 0x00030007 | ( XTalMHertz << 8 ); // PLL 1 Input = 1 MHz; HSE in;
RCC->PLL1DIVR = 0x00000000 | ( SystemMHertz - 1 ); // DivN = VCO Output in MHz
RCC->CR |= RCC_CR_PLL1ON; // Enable PLL 1
while(( RCC->CR & RCC_CR_PLL1RDY ) == 0 ) { } // Wait till PLL 1 is ready
RCC->PLL3CFGR = 0x00070007 | ( XTalMHertz << 8 ); // PLL 3 Input = 1 MHz; HSE in;
RCC->PLL3DIVR = 0x030306BF; // DivN = 192 (n=191); R/4, Q/4; P/4
RCC->CR |= RCC_CR_PLL3ON; // Enable PLL 3
while(( RCC->CR & RCC_CR_PLL3RDY ) == 0 ) { } // Wait till PLL 3 is ready
The PLL3CFGR, PLL3R, PLL3Q and PLL3P fields get written correctly. However the PLL3N field retains it’s default value. So instead of the desired 0x030306BF value, the PLL3DIVR register contains 0x03030680.
The following code works:
RCC->PLL1CFGR = 0x00030007 | ( XTalMHertz << 8 ); // PLL 1 Input = 1 MHz; HSE in;
RCC->PLL1DIVR = 0x00000000 | ( SystemMHertz - 1 ); // DivN = VCO Output in MHz
RCC->PLL3CFGR = 0x00070007 | ( XTalMHertz << 8 ); // PLL 3 Input = 1 MHz; HSE in;
RCC->PLL3DIVR = 0x030306BF; // DivN = 192 (n=191); R/4, Q/4; P/4
RCC->CR |= RCC_CR_PLL1ON; // Enable PLL 1
while(( RCC->CR & RCC_CR_PLL1RDY ) == 0 ) { } // Wait till PLL 1 is ready
RCC->CR |= RCC_CR_PLL3ON; // Enable PLL 3
while(( RCC->CR & RCC_CR_PLL3RDY ) == 0 ) { } // Wait till PLL 3 is ready
Apparently, there’s an internal signal that’s crossed so that a write to PLL3DIVR is partially blocked by RCC_CR_PLL1ON.
I’ve solved my problem with the above work-around but wanted to post this so that STM can note the defect in it’s errata and perhaps fix it in future revisions, and hopefully so that no one else spends the whole day banging their head against it.
