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.

28377D: SPLLFMULT problem? Wrong clock with RTOS

Other Parts Discussed in Thread: SYSBIOS, CONTROLSUITE

Hi all

With RTOS (2.12.1.33) GUI: I set the integer multiplier to 24 and the fractional multiplier to 0.5 (value in register is 2), the devider is set to /2 (value in register is 1).

The external clock is 16 MHz.

In the reset hook I set the clock source to external, because RTOS does not support this.

The measured clock on my (custom) board is 192 MHz, but is should be 196 MHz (24.5 * 16 MHz / 2). The measured clock is 24 * 16 / 2, it seems that the fractional multiplier is somehow ignored...

But if I check the register ClkCfgRegs.SYSPLLMULT with the debugger, I see the correct values (FMULT=2, IMULT=24).

Remark: If I create a non-RTOS project and do the PLL config myself, I get the desired 196 MHz.

Question: Can anybody confirm that RTOS does apply the FMULT correctly?

Thank you!

Roger

  • Hi Roger,

    Can you please attach your configuration (*.cfg) file?

    Steve
  • Hi Steve

    Thank you for your reply! I will try to reproduce this on the controlCard today.

    Roger

    Edit: This behavior can be reproduced on controlCard too. The fractional part of PLL multiplier is ignored. Also in case of "no hook function", with internal osc.

    The content of the reset hook function is:

      EALLOW;
      ClkCfgRegs.CLKSRCCTL1.bit.XTALOFF = 0;        // Turn on XTALOSC
      ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL = 1; // Clk Src = XTAL
      EDIS;

    And this is the cfg:

    var Defaults = xdc.useModule('xdc.runtime.Defaults');
    var Diags = xdc.useModule('xdc.runtime.Diags');
    var Error = xdc.useModule('xdc.runtime.Error');
    var Log = xdc.useModule('xdc.runtime.Log');
    var LoggerBuf = xdc.useModule('xdc.runtime.LoggerBuf');
    var Main = xdc.useModule('xdc.runtime.Main');
    var SysMin = xdc.useModule('xdc.runtime.SysMin');
    var System = xdc.useModule('xdc.runtime.System');
    var Text = xdc.useModule('xdc.runtime.Text');

    var BIOS = xdc.useModule('ti.sysbios.BIOS');
    var Task = xdc.useModule('ti.sysbios.knl.Task');

    var Hwi = xdc.useModule('ti.sysbios.family.c28.Hwi');
    var Boot = xdc.useModule('ti.catalog.c2800.initF2837x.Boot');
    var Idle = xdc.useModule('ti.sysbios.knl.Idle');
    var TimestampProvider = xdc.useModule('ti.sysbios.family.c28.f2837x.TimestampProvider');
    var Timestamp = xdc.useModule('xdc.runtime.Timestamp');
    var Clock = xdc.useModule('ti.sysbios.knl.Clock');

    /* Reset hook function to switch to the external clock source */
    var Reset = xdc.useModule('xdc.runtime.Reset');
    Reset.fxns[Reset.fxns.length++] = '&SYS_CTRL_config_ext_clk_source';

    /*
     * Uncomment this line to globally disable Asserts.
     * All modules inherit the default from the 'Defaults' module.  You
     * can override these defaults on a per-module basis using Module.common$.
     * Disabling Asserts will save code space and improve runtime performance.
    Defaults.common$.diags_ASSERT = Diags.ALWAYS_OFF;
     */

    /*
     * Uncomment this line to keep module names from being loaded on the target.
     * The module name strings are placed in the .const section. Setting this
     * parameter to false will save space in the .const section.  Error and
     * Assert messages will contain an "unknown module" prefix instead
     * of the actual module name.
     */
    Defaults.common$.namedModule = false;

    /*
     * Minimize exit handler array in System.  The System module includes
     * an array of functions that are registered with System_atexit() to be
     * called by System_exit().
     */
    System.maxAtexitHandlers = 4;       

    /*
     * Uncomment this line to disable the Error print function.  
     * We lose error information when this is disabled since the errors are
     * not printed.  Disabling the raiseHook will save some code space if
     * your app is not using System_printf() since the Error_print() function
     * calls System_printf().
    Error.raiseHook = null;
     */

    /*
     * Uncomment this line to keep Error, Assert, and Log strings from being
     * loaded on the target.  These strings are placed in the .const section.
     * Setting this parameter to false will save space in the .const section.
     * Error, Assert and Log message will print raw ids and args instead of
     * a formatted message.
     */
    Text.isLoaded = false;

    /*
     * Uncomment this line to disable the output of characters by SysMin
     * when the program exits.  SysMin writes characters to a circular buffer.
     * This buffer can be viewed using the SysMin Output view in ROV.
     */
    SysMin.flushAtExit = false;

    /*
     * The BIOS module will create the default heap for the system.
     * Specify the size of this default heap.
     */
    BIOS.heapSize = 0x0;

    /* System stack size (used by ISRs and Swis) */
    Program.stack = 0x100;

    /* Circular buffer size for System_printf() */
    SysMin.bufSize = 128;

    /*
     * Create and install logger for the whole system
     */
    var loggerBufParams = new LoggerBuf.Params();
    loggerBufParams.numEntries = 4;
    var logger0 = LoggerBuf.create(loggerBufParams);
    Defaults.common$.logger = logger0;
    Main.common$.diags_INFO = Diags.ALWAYS_ON;

    System.SupportProxy = SysMin;

    /*
     * Build a custom BIOS library.  The custom library will be smaller than the
     * pre-built "instrumented" (default) and "non-instrumented" libraries.
     *
     * The BIOS.logsEnabled parameter specifies whether the Logging is enabled
     * within BIOS for this custom build.  These logs are used by the RTA and
     * UIA analysis tools.
     *
     * The BIOS.assertsEnabled parameter specifies whether BIOS code will
     * include Assert() checks.  Setting this parameter to 'false' will generate
     * smaller and faster code, but having asserts enabled is recommended for
     * early development as the Assert() checks will catch lots of programming
     * errors (invalid parameters, etc.)
     */
    BIOS.libType = BIOS.LibType_Custom;
    BIOS.logsEnabled = false;
    BIOS.assertsEnabled = true;

    /*
     * Create a task.  The 'taskFxn' function can be found in main.c.
     */
    var task0Params = new Task.Params();
    var task0 = Task.create("&taskFxn", task0Params);

    BIOS.cpuFreq.lo = 196000000;
    Boot.configureClocks = true;
    Boot.SPLLIMULT = 24;
    Boot.SPLLFMULT = Boot.Fract_50;
    Boot.OSCCLK = 16;
    Boot.SYSCLKDIVSEL = 1;
    Boot.runSegment = "D01SARAM PAGE = 0";
    BIOS.customCCOpts = "-v28 -DLARGE_MODEL=1 -ml --float_support=fpu32 -q -mo --program_level_compile -o3 -g --optimize_with_debug";
    BIOS.runtimeCreatesEnabled = true;
    Hwi.dispatcherAutoNestingSupport = true;
    Idle.idleFxns[0] = "&background";
    Idle.idleFxns[1] = null;
    var hwi0Params = new Hwi.Params();
    hwi0Params.instance.name = "hwi0";
    Program.global.hwi0 = Hwi.create(198, "&USB0DeviceIntHandler", hwi0Params);
    var hwi1Params = new Hwi.Params();
    hwi1Params.instance.name = "hwi1";
    hwi1Params.maskSetting = xdc.module("ti.sysbios.interfaces.IHwi").MaskingOption_SELF;
    Program.global.hwi1 = Hwi.create(112, "&APP_interrupt_eoc", hwi1Params);
    Clock.timerId = 1;
    var clock0Params = new Clock.Params();
    clock0Params.instance.name = "timer_1ms_handle";
    clock0Params.period = 1;
    clock0Params.startFlag = true;
    Program.global.timer_1ms_handle = Clock.create("&timer_1ms", 1, clock0Params);


  • Roger44834 said:
    BIOS.cpuFreq.lo = 196000000;
    Boot.configureClocks = true;
    Boot.SPLLIMULT = 24;
    Boot.SPLLFMULT = Boot.Fract_50;
    Boot.OSCCLK = 16;
    Boot.SYSCLKDIVSEL = 1;

    These configuration settings result in the following generated function call in C code:

    extern ti_catalog_c2800_initF2837x_Boot_configurePllDivs(UInt iMult, UInt fMult, UInt sysDiv);
    
    ti_catalog_c2800_initF2837x_Boot_configurePllDivs(24, 512, 1);

    Notice that the type of iMult is UInt, so it cannot be set to 24.5.

    Roger44834 said:
    Remark: If I create a non-RTOS project and do the PLL config myself, I get the desired 196 MHz.

    Can you share the code you used to do this?

    Steve

  • Hi Steve,

    The code for a non RTOS project is found in controlSuite:

    "C:\ti\controlSUITE\device_support\F2837xD\v150\F2837xD_common\source\F2837xD_SysCtrl.c"

    Using this I can set a Syclock of 196 MHz with Imult = 24, Fmult=2,  DivSel=1 (and external OSC of 16MHz).

    Since Fmult is a defined as bit 8 and 9 in syspllmult register, the 512 makes sense.

    The function call seems to be correct: ti_catalog_c2800_initF2837x_Boot_configurePllDivs(24, 512, 1);

    But it does not work!

    To reporoduce:

    • Take a RTOS demo for 28377D, modify it to use the boot options.
    • Modify the clock settings without using the fmult (say 10MHz osc, imult = 19, fmult="fmult_is_0.0", divsel = 0)  this results in a 10*19 = 190 MHz clock.
    • Check clock (I used XCLCKOUT on GPIO73).
    • Modify clock settings to use fmult (10 MHz, imult=19, fmult="fmult_is_0.75", divsel=0). This should lead to 10*19.75 =197.5MHz
    • Check clock and compare it to last result (you will see that setting fmult has no effect)

    So 2 things which do currently not work:

    • Not possible to select XTALCLK as source from within the RTOS interface
    • Not possible to use FMULT to create PLL

    Regards,

    Roger