2020-12-27 10:20 AM
I'm trying to set up the clock tree, and D1CKRDY becomes ready, but for some reason D2CKRDY does not. Here is the code:
// Clock setup
RCC->CR |= RCC_CR_HSEBYP; // Set HSE as external clock [8 Mhz]
RCC->CR |= RCC_CR_HSEON; // Enable HSE
while (!(RCC->CR & RCC_CR_HSERDY)); // Wait for HSE clock to be ready
// PLL source
RCC->PLLCKSELR = (RCC->PLLCKSELR & ~RCC_PLLCKSELR_PLLSRC_Msk) | RCC_PLLCKSELR_PLLSRC_HSE ; // Set PLL source as HSE
RCC->PLLCKSELR = (RCC->PLLCKSELR & ~RCC_PLLCKSELR_DIVM1_Msk) | (1 << RCC_PLLCKSELR_DIVM1_Pos); // Divider DIVM1 = 1
RCC->PLLCKSELR = (RCC->PLLCKSELR & ~RCC_PLLCKSELR_DIVM2_Msk) | (1 << RCC_PLLCKSELR_DIVM2_Pos); // Divider DIVM2 = 1
RCC->PLLCKSELR = (RCC->PLLCKSELR & ~RCC_PLLCKSELR_DIVM3_Msk) | (1 << RCC_PLLCKSELR_DIVM3_Pos); // Divider DIVM3 = 1
// PLL 1
RCC->PLLCFGR &= RCC_PLLCFGR_PLL1VCOSEL; // Use VCOH (input frequency: 2 - 16 Mhz range) on PLL1 [8 Mhz]
RCC->PLLCFGR = (RCC->PLLCFGR & ~RCC_PLLCFGR_PLL1RGE_Msk) | RCC_PLLCFGR_PLL1RGE_2; // Set RGE to the 4 - 8 Mhz range [8 Mhz]
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLL1FRACEN; // Disable PLL fractional divider
RCC->PLLCFGR |= RCC_PLLCFGR_DIVP1EN; // Enable divider P
RCC->PLLCFGR |= RCC_PLLCFGR_DIVQ1EN; // Enable divider Q
RCC->PLLCFGR |= RCC_PLLCFGR_DIVR1EN; // Enable divider R
RCC->PLL1DIVR = (RCC->PLL1DIVR & ~RCC_PLL1DIVR_N1_Msk) | (99 << RCC_PLL1DIVR_N1_Pos); // Set multiplier DIVN1 = 100 [8 / 1 * 100 = 800 Mhz]
RCC->PLL1DIVR = (RCC->PLL1DIVR & ~RCC_PLL1DIVR_P1_Msk) | (1 << RCC_PLL1DIVR_P1_Pos); // Set divider DIVR = 2 [8 / 1 * 100 / 2 = 400 Mhz]
RCC->PLL1DIVR = (RCC->PLL1DIVR & ~RCC_PLL1DIVR_Q1_Msk) | (1 << RCC_PLL1DIVR_Q1_Pos); // Set divider DIVQ = 2 [8 / 1 * 100 / 2 = 400 Mhz]
RCC->PLL1DIVR = (RCC->PLL1DIVR & ~RCC_PLL1DIVR_R1_Msk) | (1 << RCC_PLL1DIVR_R1_Pos); // Set divider DIVR = 2 [8 / 1 * 100 / 2 = 400 Mhz]
RCC->CR |= RCC_CR_PLL1ON; // Turn PLL on
while (!(RCC->CR & RCC_CR_PLL1RDY)); // Wait for PLL to be ready
// PLL 2
RCC->PLLCFGR &= RCC_PLLCFGR_PLL2VCOSEL; // Use VCOH (input frequency: 2 - 16 Mhz range) on PLL1 [8 Mhz]
RCC->PLLCFGR = (RCC->PLLCFGR & ~RCC_PLLCFGR_PLL2RGE_Msk) | RCC_PLLCFGR_PLL2RGE_2; // Set RGE to the 4 - 8 Mhz range [8 Mhz]
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLL2FRACEN; // Disable PLL fractional divider
RCC->PLLCFGR |= RCC_PLLCFGR_DIVP2EN; // Enable divider P
RCC->PLLCFGR |= RCC_PLLCFGR_DIVQ2EN; // Enable divider Q
RCC->PLLCFGR |= RCC_PLLCFGR_DIVR2EN; // Enable divider R
RCC->PLL2DIVR = (RCC->PLL2DIVR & ~RCC_PLL2DIVR_N2_Msk) | (89 << RCC_PLL2DIVR_N2_Pos); // Set multiplier DIVN1 = 90 [8 / 1 * 90 = 720 Mhz]
RCC->PLL2DIVR = (RCC->PLL2DIVR & ~RCC_PLL2DIVR_P2_Msk) | (59 << RCC_PLL2DIVR_P2_Pos); // Set divider DIVR = 80 [8 / 1 * 90 / 60 = 12 Mhz]
RCC->PLL2DIVR = (RCC->PLL2DIVR & ~RCC_PLL2DIVR_Q2_Msk) | (59 << RCC_PLL2DIVR_Q2_Pos); // Set divider DIVQ = 80 [8 / 1 * 90 / 60 = 12 Mhz]
RCC->PLL2DIVR = (RCC->PLL2DIVR & ~RCC_PLL2DIVR_R2_Msk) | (59 << RCC_PLL2DIVR_R2_Pos); // Set divider DIVR = 80 [8 / 1 * 90 / 60 = 12 Mhz]
RCC->CR |= RCC_CR_PLL2ON; // Turn PLL on
while (!(RCC->CR & RCC_CR_PLL2RDY)); // Wait for PLL to be ready
// PLL 3
RCC->PLLCFGR &= RCC_PLLCFGR_PLL3VCOSEL; // Use VCOH (input frequency: 2 - 16 Mhz range) on PLL1 [8 Mhz]
RCC->PLLCFGR = (RCC->PLLCFGR & ~RCC_PLLCFGR_PLL3RGE_Msk) | RCC_PLLCFGR_PLL3RGE_3; // Set RGE to the 4 - 8 Mhz range [8 Mhz]
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLL3FRACEN; // Disable PLL fractional divider
RCC->PLLCFGR |= RCC_PLLCFGR_DIVP3EN; // Enable divider P
RCC->PLLCFGR |= RCC_PLLCFGR_DIVQ3EN; // Enable divider Q
RCC->PLLCFGR |= RCC_PLLCFGR_DIVR3EN; // Enable divider R
RCC->PLL3DIVR = (RCC->PLL3DIVR & ~RCC_PLL3DIVR_N3_Msk) | (99 << RCC_PLL3DIVR_N3_Pos); // Set multiplier DIVN1 = 100 [8 / 1 * 100 = 800 Mhz]
RCC->PLL3DIVR = (RCC->PLL3DIVR & ~RCC_PLL3DIVR_P3_Msk) | (1 << RCC_PLL3DIVR_P3_Pos); // Set divider DIVR = 2 [8 / 1 * 100 / 2 = 400 Mhz]
RCC->PLL3DIVR = (RCC->PLL3DIVR & ~RCC_PLL3DIVR_Q3_Msk) | (1 << RCC_PLL3DIVR_Q3_Pos); // Set divider DIVQ = 2 [8 / 1 * 100 / 2 = 400 Mhz]
RCC->PLL3DIVR = (RCC->PLL3DIVR & ~RCC_PLL3DIVR_R3_Msk) | (1 << RCC_PLL3DIVR_R3_Pos); // Set divider DIVR = 2 [8 / 1 * 100 / 2 = 400 Mhz]
RCC->CR |= RCC_CR_PLL3ON; // Turn PLL on
while (!(RCC->CR & RCC_CR_PLL3RDY)); // Wait for PLL to be ready
// System clock tree
RCC->D1CFGR = (RCC->D1CFGR & ~RCC_D1CFGR_D1CPRE_Msk) | RCC_D1CFGR_D1CPRE_DIV1; // Set prescaler D1CPRE = 1 [8 / 1 * 100 / 2 / 1 = 400 Mhz]
RCC->D1CFGR = (RCC->D1CFGR & ~RCC_D1CFGR_HPRE_Msk) | RCC_D1CFGR_HPRE_DIV2; // Set prescaler HPRE = 2 [8 / 1 * 100 / 2 / 1 / 2 = 200 Mhz]
RCC->D1CFGR = (RCC->D1CFGR & ~RCC_D1CFGR_D1PPRE_Msk) | RCC_D1CFGR_D1PPRE_DIV2; // Set prescaler D1PPRE = 2 [8 / 1 * 100 / 2 / 1 / 2 / 2 = 100 Mhz]
RCC->D2CFGR = (RCC->D2CFGR & ~RCC_D2CFGR_D2PPRE1_Msk) | RCC_D2CFGR_D2PPRE1_DIV2; // Set prescaler D2PPRE1 = 2 [8 / 1 * 100 / 2 / 1 / 2 / 2 = 100 Mhz]
RCC->D2CFGR = (RCC->D2CFGR & ~RCC_D2CFGR_D2PPRE2_Msk) | RCC_D2CFGR_D2PPRE2_DIV2; // Set prescaler D2PPRE2 = 2 [8 / 1 * 100 / 2 / 1 / 2 / 2 = 100 Mhz]
RCC->D3CFGR = (RCC->D3CFGR & ~RCC_D3CFGR_D3PPRE_Msk) | RCC_D3CFGR_D3PPRE_DIV2; // Set prescaler D3PPRE = 2 [8 / 1 * 100 / 2 / 1 / 2 / 2 = 100 Mhz]
RCC->CFGR &= ~RCC_CFGR_TIMPRE; // Set timer clock prescaler for the APB1 and ABP2 domains (more info in reference)
RCC->CFGR |= RCC_CFGR_HRTIMSEL; // Set high resolution timer prescaler source to the CPU clock
// Set the system clock switch to PLL1 P clock
RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_SW_Msk) | RCC_CFGR_SW_PLL1; // Set system clock source to PLL1
while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_PLL1); // Wait until the switch to PLL1 finishes
while (!(RCC->CR & RCC_CR_D1CKRDY) || !(RCC->CR & RCC_CR_D2CKRDY)); // Wait until D1 and D2 domain clocks are ready
// Enable ADC 1/2
RCC->D3CCIPR = (RCC->D3CCIPR & ~RCC_D3CCIPR_ADCSEL_Msk) | (0 << RCC_D3CCIPR_ADCSEL_Pos); // Select PLL2 P
RCC->AHB1ENR |= RCC_AHB1ENR_ADC12EN;