LPC55xx SystemCoreClockUpdate with external clock

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC55xx SystemCoreClockUpdate with external clock

1,258 Views
janpieterderuit
Contributor IV

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?

Labels (1)
0 Kudos
5 Replies

1,149 Views
Sabina_Bruce
NXP Employee
NXP Employee

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!

----------------------------------------------------------------------------------------------------------------------- 

0 Kudos

1,149 Views
janpieterderuit
Contributor IV

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.

0 Kudos

1,149 Views
Sabina_Bruce
NXP Employee
NXP Employee

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. 

pastedImage_3.png

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!

----------------------------------------------------------------------------------------------------------------------- 

0 Kudos

1,149 Views
janpieterderuit
Contributor IV

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

0 Kudos

1,149 Views
Sabina_Bruce
NXP Employee
NXP Employee

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!

----------------------------------------------------------------------------------------------------------------------- 

0 Kudos