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.

SysCtlClockSet() does not work?



I was having issues with the F28377D misbehaving while executing main() before call BIOS_start() and it took me a while to track it down.  I tried to use the F2837xD Peripheral Driver Library System Control SysCtlClockSet() on a F28377D, but it seems like it does not work.  I tried making the following call:

SysCtlClockSet(SYSCTL_SYSDIV(1) | SYSCTL_IMULT(9) | SYSCTL_FMULT_0 | SYSCTL_OSCSRC_XTAL);

with a 20 MHz crystal oscillator to get a 90 MHz clock.  The processor starts misbehaving whether I halt after running for a while or stepping through code.  If I use the TI-RTOS Boot Clock Configuration, everything works fine.

 

I noticed a couple of problems with SysCtlClockSet().  First, the setting of  CLKSRCCTL1.OSCCLKSRCSEL does not work.  clock_source is set as follows:

uint32_t clock_source = (ui32Config & SYSCTL_OSCSRC_M) >> SYSCTL_OSCSRC_S;

So clock_source is the value that should be written into OSCCLKSRCSEL, i.e. 0, 1, or 2.  However, the setting of OSCCLKSRCSEL is as follows:

switch (clock_source)
{
    case SYSCTL_OSCSRC_OSC2:
        ClkCfgRegs.CLKSRCCTL1.bit.INTOSC2OFF=0; // Turn on INTOSC2
        ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL = 0; // Clk Src = INTOSC2
        break;

    case SYSCTL_OSCSRC_XTAL:
        ClkCfgRegs.CLKSRCCTL1.bit.XTALOFF=0; // Turn on XTALOSC
        ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL = 1; // Clk Src = XTAL
        break;

    case SYSCTL_OSCSRC_OSC1:
        ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL = 2; // Clk Src = INTOSC1
        break;
}

where:

#define SYSCTL_OSCSRC_OSC2 0x00000000
#define SYSCTL_OSCSRC_XTAL 0x00010000
#define SYSCTL_OSCSRC_OSC1 0x00020000

Only SYSCTL_OSCSRC_OSC2 matches, while the other two cases never match.

Second, the TRM SPRUHM8E for OSCCLKSRCSEL states: "The user must wait 10 OSCCLK cycles before writing to SYSPLLMULT or disabling the previous clock source to allow the change to complete.."  I don't see this being done in SysCtlClockSet().  I tried disabling OSC2 by setting CLKSRCCTL1.INTOSC2OFF to 1, but then the SYSPLL never locks.

Anyhow, that is as far as I got trying to debug this issue.  I considered copying Boot_configurePllDivs() from Boot.c, but it does not set CLKSRCCTL1.OSCCLKSRCSEL to switch to the external crystal so only uses the internal INTOSC2.

  • Joseph,

    Looks like there's a bug in the function. I've filed a report with our software team.

    The misbehavior is probably due to violating the PLLRAWCLK frequency limits (120 - 400 MHz).

    There's no explicit 10 cycle delay in the code, but there are enough instructions between the clock source selection and the PLLMULT write to ensure that the clock switch happens.

    All you really need to do before the PLL setup is set OSCCLKSRCSEL to 1. You don't need to disable INTOSC2. Replacing the switch statement with this code by itself should work:

    ClkCfgRegs.CLKSRCCTL1.bit.XTALOFF=0; // Turn on XTALOSC
    ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL = 1; // Clk Src = XTAL
  • I appreciate the info and it's good to confirm the bug and upcoming fix.

    Adam Haun said:
    The misbehavior is probably due to violating the PLLRAWCLK frequency limits (120 - 400 MHz).

    It turns out I was violating PLLSYSCLK frequency limits of 2-200 MHz because I was calling:

    SysCtlClockSet(SYSCTL_SYSDIV(1) | SYSCTL_IMULT(18) | SYSCTL_FMULT_0 | SYSCTL_OSCSRC_XTAL);

    with a 20MHz external crystal, which would generate 360 MHz PLLRAWCLK and PLLSYSCLK.  I posted at some point when I to SYS_CTL_IMULT(9) because it seemed like the clock frequency was wrong.  This was caused by the confusion of SysCtlClockSet() not switching from INTOSC2 to the XTAL but at some point I did fix SysCtrlClockSet() so the PLL input was switching between 10MHz INTOSC2 to 20MHz XTAL then back again at some point.  Anyhow, I think it's all cleared up now.

  • Hi Adam,

    the issue was not solved in v210. I discovered the bug in the usb_dev_bulk example. Please report the issue to your software team again.

    Kind regards,

    Jan

  • Jan,

    Can you please clarify what you mean? The header file has definitely been fixed in v210:

    #define SYSCTL_OSCSRC_OSC2      0x00000000
    #define SYSCTL_OSCSRC_XTAL      0x00000001
    #define SYSCTL_OSCSRC_OSC1      0x00000002
    

    Thanks,

  • Hi Adam,
    please read my other post for more details but the defines you posted break the bit order scheme used for ui32Config.
    In particular this means all examples with

    SysCtlClockSet(SYSCTL_OSCSRC_XTAL | SYSCTL_PLL_ENABLE | SYSCTL_IMULT(20) | SYSCTL_SYSDIV(2));

    do not work. These examples are:

    • v210\F2837xD_examples_Cpu1\usb_dev_bulk\cpu01\usb_dev_bulk.c : Line 470
    • v210\F2837xD_examples_Cpu1\usb_dev_keyboard\cpu01\usb_dev_keyboard.c : Line 515
    • v210\F2837xD_examples_Cpu1\usb_dev_mouse\cpu01\usb_dev_mouse.c : Line 360
    • v210\F2837xD_examples_Cpu1\usb_dev_serial\cpu01\usb_dev_serial.c : Line 1032
    • v210\F2837xD_examples_Cpu1\usb_dual_detect\cpu01\dual_detect.c : Line 204
    • v210\F2837xD_examples_Cpu1\usb_host_keyboard\cpu01\usb_host_keyboard.c : Line 675
    • v210\F2837xD_examples_Cpu1\usb_host_mouse\cpu01\usb_host_mouse.c : Line 585
    • v210\F2837xD_examples_Cpu1\usb_host_msc\cpu01\usb_host_msc.c : Line 1266

    The examples fail because sysctl.c . Line 499 as part of SysCtlClockSet:

    uint32_t clock_source = (ui32Config & SYSCTL_OSCSRC_M) >> SYSCTL_OSCSRC_S;

    is always zero and the IMULT value is changed by SYSCTL_OSCSRC_XTAL . A solution is posted in the other thread. 

    Kind regards,

    Jan

  • Jan,

    Our software team has reopened the bug to fix the case statements. Sorry for the error.