2023-12-15 10:20 AM - edited 2023-12-15 11:40 AM
I'm attempting to set the clock to PLL on the board mentioned and view the output on MCO2.
This is some of the defines I use
#define REG_SET_BIT(reg,pos) ((reg) |= (1U << (pos)))
#define REG_CLR_BIT(reg,pos) ((reg) &= ~(1U << (pos)))
#define REG_READ_BIT(reg,pos) ((reg) & (1U << (pos)))
#define REG_CLR_VAL(reg,clrmask,pos) ((reg) &= ~((clrmask) << (pos)))
#define REG_SET_VAL(reg,val,setmask,pos) do {\
REG_CLR_VAL(reg,setmask,pos);\
((reg) |= ((val) << (pos))); \
}while(0)
#define REG_READ_VAL(reg,rdmask,pos) ((REG_READ(reg) >> (pos)) & (rdmask))
This is the code to configure MCO2
RCC->AHB1ENR |= 4;
// RCC->CFGR |= RCC_CFGR_MCO2_1 | RCC_CFGR_MCO2_0;
RCC->CFGR |= (3U << 27);
GPIOC->MODER &= ~(3U << 18);
GPIOC->MODER |= (2 << 18);
GPIOC->OSPEEDR |= (3U << 18);
GPIOC->AFR[1] &= ~(0x0f << 4);
}
and the code I use to configure clock
RCC_TypeDef* pRCC = RCC;
FLASH_TypeDef* pFlash = FLASH;
PWR_TypeDef* pPWR = PWR;
// VOS setting
REG_SET_BIT(pRCC->APB1ENR,RCC_APB1ENR_PWREN_Pos); /*Enable clock for PWR register access*/
REG_SET_VAL(pPWR->CR1, 0x03U, 0x03U, PWR_CR1_VOS_Pos); /*VOS = 1*/
// SET to use HSE clock
REG_SET_BIT(pRCC->CR, RCC_CR_HSEON_Pos);
while(!REG_READ_BIT(pRCC->CR, RCC_CR_HSERDY_Pos));
REG_SET_BIT(pRCC->CR, RCC_CR_HSEBYP_Pos);
// Main clock
REG_SET_VAL(pRCC->PLLCFGR, 0x4U, 0x3FU, RCC_PLLCFGR_PLLM_Pos);
REG_SET_VAL(pRCC->PLLCFGR, 160U, 0x1ffU, RCC_PLLCFGR_PLLN_Pos);
REG_SET_VAL(pRCC->PLLCFGR, 0x00U, 0x3U, RCC_PLLCFGR_PLLP_Pos);
REG_SET_VAL(pRCC->PLLCFGR, 8U, 0x0fU, RCC_PLLCFGR_PLLQ_Pos);
// PLL On
REG_SET_BIT(pRCC->CR, RCC_CR_PLLON_Pos);
while(!REG_READ_BIT(pRCC->CR, RCC_CR_PLLRDY_Pos));
// Enable overdrive
REG_SET_BIT(pPWR->CR1, PWR_CR1_ODEN_Pos);
while(!REG_READ_BIT(pPWR->CSR1, PWR_CSR1_ODRDY_Pos));
REG_SET_BIT(pPWR->CR1, PWR_CR1_ODSWEN_Pos);
// Flash prefetch buffer
REG_SET_VAL(pFlash->ACR, 6U, 0x7fU, FLASH_ACR_LATENCY_Pos);
REG_SET_VAL(pRCC->CFGR, 0x2U, 0x3U, RCC_CFGR_SW_Pos);
while(!(REG_READ_VAL(pRCC->CFGR, 0x3U, RCC_CFGR_SW_Pos) == 0x2U));
// AHB, APB1 and AP{B2 bus dividers
REG_SET_VAL(pRCC->CFGR, 0U, 0xfU, RCC_CFGR_HPRE_Pos);
REG_SET_VAL(pRCC->CFGR, 5U, 0x07U, RCC_CFGR_PPRE1_Pos);
REG_SET_VAL(pRCC->CFGR, 4U, 0x07U, RCC_CFGR_PPRE2_Pos);
When I configure MCO2 to output either SYSCLK or PLL I get nothing.
I'm thinking I should at least get a reading from SYSCLK.
I'm assuming that PLL is not being configured correctly and is using HSE as the system clock.
I'm wondering what I'm doing wrong configuring PLL as the system clock.
Any help appreciated.
Solved! Go to Solution.
2023-12-15 02:57 PM
I found the solution after many hours of foundering and for those that wish to know the solution, here it is;
The solution is configuring the PLL as the clock source;
RCC_TypeDef* pRCC = RCC;
FLASH_TypeDef* pFlash = FLASH;
PWR_TypeDef* pPWR = PWR;
// VOS setting
REG_SET_BIT(pRCC->APB1ENR,RCC_APB1ENR_PWREN_Pos); /*Enable clock for PWR register access*/
REG_SET_VAL(pPWR->CR1, 0x02U, 0x03U, PWR_CR1_VOS_Pos); /*VOS = 1*/
// SET to use HSE clock
REG_SET_BIT(pRCC->CR, RCC_CR_HSEON_Pos);
while(!REG_READ_BIT(pRCC->CR, RCC_CR_HSERDY_Pos));
REG_SET_BIT(pRCC->CR, RCC_CR_HSEBYP_Pos);
// Main clock
REG_SET_VAL(pRCC->PLLCFGR, 0x4U, 0x3FU, RCC_PLLCFGR_PLLM_Pos);
REG_SET_VAL(pRCC->PLLCFGR, 150U, 0x1ffU, RCC_PLLCFGR_PLLN_Pos);
REG_SET_VAL(pRCC->PLLCFGR, 0x00U, 0x3U, RCC_PLLCFGR_PLLP_Pos);
REG_SET_VAL(pRCC->PLLCFGR, 8U, 0x0fU, RCC_PLLCFGR_PLLQ_Pos);
REG_SET_BIT(pRCC->PLLCFGR, RCC_PLLCFGR_PLLSRC_Pos);
// PLL On
REG_SET_BIT(pRCC->CR, RCC_CR_PLLON_Pos);
while(!REG_READ_BIT(pRCC->CR, RCC_CR_PLLRDY_Pos));
// Enable overdrive
REG_SET_BIT(pPWR->CR1, PWR_CR1_ODEN_Pos);
while(!REG_READ_BIT(pPWR->CSR1, PWR_CSR1_ODRDY_Pos));
REG_SET_BIT(pPWR->CR1, PWR_CR1_ODSWEN_Pos);
// Flash prefetch buffer
REG_SET_VAL(pFlash->ACR, 5U, 0x7fU, FLASH_ACR_LATENCY_Pos);
FLASH->ACR |= FLASH_ACR_PRFTEN;
// AHB, APB1 and AP{B2 bus dividers
REG_SET_VAL(pRCC->CFGR, 0U, 0xfU, RCC_CFGR_HPRE_Pos);
REG_SET_VAL(pRCC->CFGR, 5U, 0x07U, RCC_CFGR_PPRE1_Pos);
REG_SET_VAL(pRCC->CFGR, 4U, 0x07U, RCC_CFGR_PPRE2_Pos);
REG_SET_VAL(pRCC->CFGR, 0x2U, 0x3U, RCC_CFGR_SW_Pos);
while(!(REG_READ_VAL(pRCC->CFGR, 0x3U, RCC_CFGR_SW_Pos) == 0x2U));
2023-12-15 10:39 AM
Hello @MHank.1
I suggest you to use the following example wish configure SYSCLK to the maximum frequency using PLL and output the SYSCLK on the MCO1.
Best Regards.
STTwo-32
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2023-12-15 12:31 PM
Thanks for the link but I'm no t using HAL. I tried creating a HAL project and tried configuring per HAL but when I downloaded the HAL it didn't work either.
2023-12-15 02:57 PM
I found the solution after many hours of foundering and for those that wish to know the solution, here it is;
The solution is configuring the PLL as the clock source;
RCC_TypeDef* pRCC = RCC;
FLASH_TypeDef* pFlash = FLASH;
PWR_TypeDef* pPWR = PWR;
// VOS setting
REG_SET_BIT(pRCC->APB1ENR,RCC_APB1ENR_PWREN_Pos); /*Enable clock for PWR register access*/
REG_SET_VAL(pPWR->CR1, 0x02U, 0x03U, PWR_CR1_VOS_Pos); /*VOS = 1*/
// SET to use HSE clock
REG_SET_BIT(pRCC->CR, RCC_CR_HSEON_Pos);
while(!REG_READ_BIT(pRCC->CR, RCC_CR_HSERDY_Pos));
REG_SET_BIT(pRCC->CR, RCC_CR_HSEBYP_Pos);
// Main clock
REG_SET_VAL(pRCC->PLLCFGR, 0x4U, 0x3FU, RCC_PLLCFGR_PLLM_Pos);
REG_SET_VAL(pRCC->PLLCFGR, 150U, 0x1ffU, RCC_PLLCFGR_PLLN_Pos);
REG_SET_VAL(pRCC->PLLCFGR, 0x00U, 0x3U, RCC_PLLCFGR_PLLP_Pos);
REG_SET_VAL(pRCC->PLLCFGR, 8U, 0x0fU, RCC_PLLCFGR_PLLQ_Pos);
REG_SET_BIT(pRCC->PLLCFGR, RCC_PLLCFGR_PLLSRC_Pos);
// PLL On
REG_SET_BIT(pRCC->CR, RCC_CR_PLLON_Pos);
while(!REG_READ_BIT(pRCC->CR, RCC_CR_PLLRDY_Pos));
// Enable overdrive
REG_SET_BIT(pPWR->CR1, PWR_CR1_ODEN_Pos);
while(!REG_READ_BIT(pPWR->CSR1, PWR_CSR1_ODRDY_Pos));
REG_SET_BIT(pPWR->CR1, PWR_CR1_ODSWEN_Pos);
// Flash prefetch buffer
REG_SET_VAL(pFlash->ACR, 5U, 0x7fU, FLASH_ACR_LATENCY_Pos);
FLASH->ACR |= FLASH_ACR_PRFTEN;
// AHB, APB1 and AP{B2 bus dividers
REG_SET_VAL(pRCC->CFGR, 0U, 0xfU, RCC_CFGR_HPRE_Pos);
REG_SET_VAL(pRCC->CFGR, 5U, 0x07U, RCC_CFGR_PPRE1_Pos);
REG_SET_VAL(pRCC->CFGR, 4U, 0x07U, RCC_CFGR_PPRE2_Pos);
REG_SET_VAL(pRCC->CFGR, 0x2U, 0x3U, RCC_CFGR_SW_Pos);
while(!(REG_READ_VAL(pRCC->CFGR, 0x3U, RCC_CFGR_SW_Pos) == 0x2U));