Hi,
when SystemCoreClockUpdate is called while the system clock is configured as external clock (e.g. CLOCK_SetupExtClocking(12000000U)), SystemCoreClock will have the wrong value (16000000U instead of 12000000U).
This is because GetExtClkFreq in system_LPC5526.c returns the hardcoded CLK_CLK_IN.
I would say CLOCK_GetExtClkFreq() should be called here to get the correct frequency.
Can this be changed in the API?
Hello Jan,
Hope you are doing well.
Could you please provide the code snippet of where you are referring to? Is this in a specific driver or part of an SDK example?
Please also confirm the SDK version you are using and the MCUXpresso IDE version.
Best Regards,
Sabina
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi Sabina,
I'm OK, thank you.
And you?
Sorry about not mentioning my environment.
I'm using LPC5526 with SDK v2.8.0 with Eclipse IDE (2020-06) (so not MCUXpresso)
I'm talking about the function SystemCoreClockUpdate in system_LPC5526.c (snippet):
void SystemCoreClockUpdate (void) {
uint32_t clkRate = 0;
uint32_t prediv, postdiv;
uint64_t workRate;
uint64_t workRate1;
switch (SYSCON->MAINCLKSELB & SYSCON_MAINCLKSELB_SEL_MASK)
{
case 0x00: /* MAINCLKSELA clock (main_clk_a)*/
switch (SYSCON->MAINCLKSELA & SYSCON_MAINCLKSELA_SEL_MASK)
{
case 0x00: /* FRO 12 MHz (fro_12m) */
clkRate = GetFro12MFreq();
break;
case 0x01: /* CLKIN (clk_in) */
clkRate = GetExtClkFreq();
break;
case 0x02: /* Fro 1MHz (fro_1m) */
clkRate = GetFro1MFreq();
break;
default: /* = 0x03 = FRO 96 MHz (fro_hf) */
clkRate = GetFroHfFreq();
break;
}
break;
...
default:
clkRate = 0UL;
break;
}
SystemCoreClock = clkRate / ((SYSCON->AHBCLKDIV & 0xFFUL) + 1UL);
}
Since I'm using the external crystal (clk_in), GetExtClkFreq will be called:
static uint32_t GetExtClkFreq(void)
{
return ((ANACTRL->XO32M_CTRL & ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK) != 0UL) ? CLK_CLK_IN : 0U;
}
This will return CLK_CLK_IN:
#define CLK_CLK_IN 16000000u /* Default CLK_IN pin clock */
So hardcoded 16MHz, regardless of what I setup as crystal frequency
The function CLOCK_GetExtClkFreq from fsl_clock.c will return the correct frequency:
uint32_t CLOCK_GetExtClkFreq(void)
{
return ((ANACTRL->XO32M_CTRL & ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK) != 0UL) ? s_Ext_Clk_Freq : 0U;
}
since s_Ext_Clk_Freq is set to the correct frequency in the function CLOCK_SetupExtClocking, which I use to setup the frequency ():
status_t CLOCK_SetupExtClocking(uint32_t iFreq)
{
if (iFreq >= 32000000U)
{
return kStatus_Fail;
}
/* Turn on power for crystal 32 MHz */
POWER_DisablePD(kPDRUNCFG_PD_XTAL32M);
POWER_DisablePD(kPDRUNCFG_PD_LDOXO32M);
/* Enable clock_in clock for clock module. */
SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK;
s_Ext_Clk_Freq = iFreq;
return kStatus_Success;
}
Note: External crystal is connected to Main clock with:
CLOCK_AttachClk(kEXT_CLK_to_MAIN_CLK);
in my code.
I'm well too thank you.
I'd recommend using the clock configuration tool, instead of manually configuring the clock. You may see that regardless of using an external clock to the main clock using the configuration tool, the SystemCoreClockUpdate function is not called to update the SystemCoreClock. Which you are correct if you use it directly then you will be reading the default value which is hard-coded at 16 MHz.
For example, here it is showing 12 MHz from the external clk source, the I selected both MAINCLKSELA and MAINCLKSELB to be from external clock and this is transmitted to my system clock. On the right hand side you will have the code preview of how this is correctly configured and attaches the clocks, the PLL and other peripherals that you may use.
I'd recommend to use the functions in the fsl_clock drivers. If you need to return the core system frequency you may use, CLOCK_GetCoreSysClkFreq.
Best Regards,
Sabina
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi Sabina,
thanks for your response.
Well, I understood that SystemCoreClockUpdate is a CMSIS standard function, which is recommended to update the SystemCoreClock variable with the correct frequency.
Of course we can update this variable ourselves (which we now do to work around this issue), but what is the use for this function if it does not always provide the correct frequency?
Also I understood SystemCoreClockUpdate may be used anywhere throughout the initialization.
I couldn't find a call to this function anywhere in the NXP source code (SDK), but it may be somewhere in hidden (ROM) functions, so we can't be sure it isn't called (which may overwrite the SystemCoreClock variable after we manually set it).
Best regards,
Jan Pieter de Ruiter
Hello Jan,
Hope you are doing well.
The SystemCoreClockUpdate function is part of the system_LPC55Sxx_cm33_core0 file. It is not recommend to make any modifications to these files.
If you would like to update the SystemCoreClock variable please refer to the functions in fsl_clock.c/.h. You may also use the clock config tool to update the clock configurations to fit your needs.
Best Regards,
Sabina
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------