This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320F280049C: DriverLib: SysCtl_setClock() function

Part Number: TMS320F280049C

Hi,

In the C2000 DriverLib, file sysctrl.c, function "SysCtl_setClock()" I can see the following code:

//
// Set divider to produce slower output frequency to limit current
// increase.
//
divSel = (uint16_t)(config & SYSCTL_SYSDIV_M) >> SYSCTL_SYSDIV_S;

EALLOW;
if(divSel != (126U / 2U))
{
HWREGH(CLKCFG_BASE + SYSCTL_O_SYSCLKDIVSEL) =
(HWREGH(CLKCFG_BASE + SYSCTL_O_SYSCLKDIVSEL) &
~(uint16_t)SYSCTL_SYSCLKDIVSEL_PLLSYSCLKDIV_M) |
(divSel + 1U);
}
else
{
HWREGH(CLKCFG_BASE + SYSCTL_O_SYSCLKDIVSEL) =
(HWREGH(CLKCFG_BASE + SYSCTL_O_SYSCLKDIVSEL) &
~(uint16_t)SYSCTL_SYSCLKDIVSEL_PLLSYSCLKDIV_M) | divSel;
}

EDIS;

Question 1: Why setting PLLSYSCLKDIV to (divsel+1) only in the special case of (divsel != 63) prior to setting it to divsel later?

Question 2: Why is there a typecast "(uint16_t)" and later when setting PLLSYSCLKDIV to divsel (section under "Set the divider to user value") there is no typecast?

Regards,

Patrick

  • Patrick,

    Sorry for the delay in replying.  Please give me an additional day to get an answer for you.

    Best,

    Matt

  • Matt,

    That are days...(not just one ;-) Any news on this topic?

    Regards,
    Patrick

  • Patrick

    Question 1: Why setting PLLSYSCLKDIV to (divsel+1) only in the special case of (divsel != 63) prior to setting it to divsel later?

    This section of code is intentionally setting the PLL divider to a value greater than the final divider to limit the current increase when the PLL is turned on.  So, its looking at what value of divsel you are using in your system and adding 1 to that to give a current reduction.  If, in your system, you were already using the max PLL SYSCLK divider of 63(which equates to /126) then we cannot add 1 to it, so there is no alternative but to just use divsel at that point.

    Question 2: Why is there a typecast "(uint16_t)" and later when setting PLLSYSCLKDIV to divsel (section under "Set the divider to user value") there is no typecast?

    I don't have a good answer for this one, it is inconsistent as you said.  I'm assuming that since there is a ~ operator(1's complement) and then a "|" with divsel(which is a uint16_t) the code was trying to ensure that the operations stayed in the unsigned 16-bit domain.  SYSCTL_SYSCLKDIVSEL_PLLSYSCLKDIV_M is defined in hw_sysctrl.h file as

    #define SYSCTL_SYSCLKDIVSEL_PLLSYSCLKDIV_M   0x3FU   // PLLSYSCLK Divide Select

    So I think the local typecast is unnecessary, but perhaps there was a best practice to have the local typecast in case the define didn't match.  In any case to be consistent it should be there, but I don't believe it is effecting the code.

    Best,

    Matthew

  • Matt,

    Thanks for your comments. I missed that 63 ist the limit. Now it is clear to me.

    Regards,
    Patrick