2019-02-02 04:29 AM
I am trying to configure my stm32L4 device clock for 80MHz with PLL
I am trying to understand a piece of code i found online could someone explain what the c code below means
RCC->PLLCFGR = (RCC->PLLCFGR & ~RCC_PLLCFGR_PLLN) | 20U << 8;
RCC->PLLCFGR = (RCC->PLLCFGR & ~RCC_PLLCFGR_PLLM) | 1U << 4; // 000: PLLM = 1, 001: PLLM = 2, 010: PLLM = 3, 011: PLLM = 4, 100: PLLM = 5, 101: PLLM = 6, 110: PLLM
thank you
2019-02-02 05:25 AM
See Reference Manual for bit level definition of register.
Looks to be setting PLLN 20 and PLLM 2, hard to know if that would hit 80 MHz without knowing what the PLL clock source is.
Might help to actually cite the code in question, the selective edit doesn't provide much context.
The code masks out portion of register it wants to change, and then applies the desired value to the right bit position within the register.
2019-02-03 03:51 AM
thank you i selected PPL as system clock but i still get only 16MHz on the MCO pin
I am not sure why i checked the registers seems like all that needs to be check is checked
the code is supposed to produce 80MHz
this is the rest the code
void System_Clock_Init(void){
uint32_t HSITrim;
// To correctly read data from FLASH memory, the number of wait states (LATENCY)
// must be correctly programmed according to the frequency of the CPU clock
// (HCLK) and the supply voltage of the device.
FLASH->ACR &= ~FLASH_ACR_LATENCY;
FLASH->ACR |= FLASH_ACR_LATENCY_2WS;
// Enable the Internal High Speed oscillator (HSI
RCC->CR |= RCC_CR_HSION;
while((RCC->CR & RCC_CR_HSIRDY) == 0);
// Adjusts the Internal High Speed oscillator (HSI) calibration value
// RC oscillator frequencies are factory calibrated by ST for 1 % accuracy at 25oC
// After reset, the factory calibration value is loaded in HSICAL[7:0] of RCC_ICSCR
HSITrim = 16; // user-programmable trimming value that is added to HSICAL[7:0] in ICSCR.
RCC->ICSCR &= ~RCC_ICSCR_HSITRIM;
RCC->ICSCR |= HSITrim << 24;
RCC->CR &= ~RCC_CR_PLLON;
while((RCC->CR & RCC_CR_PLLRDY) == RCC_CR_PLLRDY);
// Select clock source to PLL
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLSRC;
RCC->PLLCFGR |= RCC_PLLCFGR_PLLSRC_HSI; // 00 = No clock, 01 = MSI, 10 = HSI, 11 = HSE
// Make PLL as 80 MHz
// f(VCO clock) = f(PLL clock input) * (PLLN / PLLM) = 16MHz * 20/2 = 160 MHz
// f(PLL_R) = f(VCO clock) / PLLR = 160MHz/2 = 80MHz
RCC->PLLCFGR = (RCC->PLLCFGR & ~RCC_PLLCFGR_PLLN) | 20U << 8;
RCC->PLLCFGR = (RCC->PLLCFGR & ~RCC_PLLCFGR_PLLM) | 1U << 4; // 000: PLLM = 1, 001: PLLM = 2, 010: PLLM = 3, 011: PLLM = 4, 100: PLLM = 5, 101: PLLM = 6, 110: PLLM = 7, 111: PLLM = 8
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLR; // 00: PLLR = 2, 01: PLLR = 4, 10: PLLR = 6, 11: PLLR = 8
RCC->PLLCFGR |= RCC_PLLCFGR_PLLREN; // Enable Main PLL PLLCLK output
RCC->CR |= RCC_CR_PLLON;
while((RCC->CR & RCC_CR_PLLRDY) == 0);
// Select PLL selected as system clock
RCC->CFGR &= ~RCC_CFGR_SW;
RCC->CFGR |= RCC_CFGR_SW_PLL; // 00: MSI, 01:HSI, 10: HSE, 11: PLL
// Wait until System Clock has been selected
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);
// The maximum frequency of the AHB, the APB1 and the APB2 domains is 80 MHz.
RCC->CFGR &= ~RCC_CFGR_HPRE; // AHB prescaler = 1; SYSCLK not divided
RCC->CFGR &= ~RCC_CFGR_PPRE1; // APB high-speed prescaler (APB1) = 1, HCLK not divided
RCC->CFGR &= ~RCC_CFGR_PPRE2; // APB high-speed prescaler (APB2) = 1, HCLK not divided
// RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLM;
// RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLN;
// RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLP;
// RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLQ;
// RCC->PLLCFGR |= RCC_PLLCFGR_PLLPEN; //Enable Main PLL PLLSAI3CLK output enable
// RCC->PLLCFGR |= RCC_PLLCFGR_PLLQEN; //Enable Main PLL PLL48M1CLK output enable
RCC->CR &= ~RCC_CR_PLLSAI1ON; // SAI1 PLL enable
while ( (RCC->CR & RCC_CR_PLLSAI1ON) == RCC_CR_PLLSAI1ON );
// Configure and enable PLLSAI1 clock to generate 11.294MHz
// 8 MHz * 24 / 17 = 11.294MHz
// f(VCOSAI1 clock) = f(PLL clock input) * (PLLSAI1N / PLLM)
// PLLSAI1CLK: f(PLLSAI1_P) = f(VCOSAI1 clock) / PLLSAI1P
// PLLUSB2CLK: f(PLLSAI1_Q) = f(VCOSAI1 clock) / PLLSAI1Q
// PLLADC1CLK: f(PLLSAI1_R) = f(VCOSAI1 clock) / PLLSAI1R
RCC->PLLSAI1CFGR &= ~RCC_PLLSAI1CFGR_PLLSAI1N;
RCC->PLLSAI1CFGR |= 24U<<8;
// SAI1PLL division factor for PLLSAI1CLK
// 0: PLLSAI1P = 7, 1: PLLSAI1P = 17
RCC->PLLSAI1CFGR |= RCC_PLLSAI1CFGR_PLLSAI1P;
RCC->PLLSAI1CFGR |= RCC_PLLSAI1CFGR_PLLSAI1PEN;
// SAI1PLL division factor for PLL48M2CLK (48 MHz clock)
// RCC->PLLSAI1CFGR &= ~RCC_PLLSAI1CFGR_PLLSAI1Q;
// RCC->PLLSAI1CFGR |= U1<<21;
// RCC->PLLSAI1CFGR |= RCC_PLLSAI1CFGR_PLLSAI1QEN;
// PLLSAI1 division factor for PLLADC1CLK (ADC clock)
// 00: PLLSAI1R = 2, 01: PLLSAI1R = 4, 10: PLLSAI1R = 6, 11: PLLSAI1R = 8
// RCC->PLLSAI1CFGR &= ~RCC_PLLSAI1CFGR_PLLSAI1R;
// RCC->PLLSAI1CFGR |= U<<25;
// RCC->PLLSAI1CFGR |= RCC_PLLSAI1CFGR_PLLSAI1REN;
RCC->CR |= RCC_CR_PLLSAI1ON; // SAI1 PLL enable
while ( (RCC->CR & RCC_CR_PLLSAI1ON) == 0);
// SAI1 clock source selection
// 00: PLLSAI1 "P" clock (PLLSAI1CLK) selected as SAI1 clock
// 01: PLLSAI2 "P" clock (PLLSAI2CLK) selected as SAI1 clock
// 10: PLL "P" clock (PLLSAI3CLK) selected as SAI1 clock
// 11: External input SAI1_EXTCLK selected as SAI1 clock
RCC->CCIPR &= ~RCC_CCIPR_SAI1SEL;
RCC->APB2ENR |= RCC_APB2ENR_SAI1EN;
}
2019-02-03 04:36 AM
Maybe MCO outputs HSI? You haven't shown the code that configures MCO output.
P.S. Use "Code Snippet" when posting source code.
2019-02-03 05:00 AM
thank you
I checked the code and it was HSI on the MCO pin i changed it to system clock
but then the was no signal on the pin
the i tried changing the MCOPRE[2:0]: Microcontroller clock output prescaler
from 1 to 4 and then there was a signal of 20MHz so i think the system is running at 80MHz cos when i
changed the prescaler to 8 it showed 10MHz on the scope
I am not sure tho why the MCO pin doesnt output the 80MHz i changed the prescaler back to 1 and again there was no signal
is there a speed limit on the MCO pin?
2019-02-03 07:53 AM
The device should be able to output 80 MHz on MCO, check speed settings on pin configuration, and capabilities of scope and probes.
If the divided down version can be multiplied back to the expected frequency you've proved what the system is working with internally.
You can also print out the value of SystemCoreClock to a terminal/console to see what the processor believes.