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.

Looking Up Clock Frequencies?

Other Parts Discussed in Thread: MSP430F5529, SYSBIOS

From Code Composer, I see that my SMCLK is 8.2MHz and ACLK is 32kHz in my MSP430F5529. ROV -> ... -> msp430 -> ClockFreqs.

I am not sure. Is the SMCLK value of 8.2MHz right? The physical high frequency oscillator is suppose to be a cstcr4m00g15l99 which runs at 4MHz. How can the SMCLK be so fast?

Also, I couldn't find any info about MCLK. I suppose it is the same as SMCLK by default.

Looking forward to your reply.

 

  • Can you show us the clock setup code in main. Use the  button to insert the code in your reply for better readability.

    Info about all clock’s, including MCLK & SMLK, can be found in the User’s Guide which is available on the product page of your MCU.

  • Here is the code. It's quite long so I inserted it as a file instead of using syntaxhighlighter. Also included is the config file for the BIOS. 

    clock_forum_main.c
    /*
     *  ======== main.c ========
     */
    
    #include <xdc/std.h>
    #include <ti/sysbios/BIOS.h>
    #include <xdc/cfg/global.h>
    #include <xdc/runtime/System.h>
    #include <xdc/runtime/Log.h>
    
    #include <driverlib.h>
    
    #define GPIO_ALL	GPIO_PIN0|GPIO_PIN1|GPIO_PIN2|GPIO_PIN3| \
    					GPIO_PIN4|GPIO_PIN5|GPIO_PIN6|GPIO_PIN7
    
    uint8_t returnValue = 0x00;
    uint8_t transmitData = 0x00,
    		receiveData = 0x00;
    
    void init_GPIO(void);
    int init_SPI(void);
    void start_SPI(void);
    void SPI_ISR(void);
    
    //-----------------------------------------
    // Globals
    //-----------------------------------------
    volatile int16_t i16ToggleCount = 0;
    
    /*
     *  ======== main ========
     */
    Int main()
    { 
    	init_GPIO();
    	init_SPI();
    	
    	System_printf("You are in!");
    	System_flush();
    
        BIOS_start();    /* does not return */
        return(0);
    }

    clock_forum_cfg.c
    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 Idle = xdc.useModule('ti.sysbios.knl.Idle');
    var Hwi = xdc.useModule('ti.sysbios.hal.Hwi');
    var Swi = xdc.useModule('ti.sysbios.knl.Swi');
    
    /*
     * 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 = 0x200;
    
    /* 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;
    
    Idle.idleFxns[0] = null;
    var swi0Params = new Swi.Params();
    swi0Params.instance.name = "SPISwi";
    swi0Params.priority = 1;
    Program.global.SPISwi = Swi.create("&start_SPI", swi0Params);
    var hwi0Params = new Hwi.Params();
    hwi0Params.instance.name = "SPIHwi";
    Program.global.SPIHwi = Hwi.create(56, "&SPI_ISR", hwi0Params);
    

  • The files doesn’t contain much information, and are missing the initialization functions.
    From here there isn’t much to say about your clock.
  • The clocks most be in default then, no?
  • I see only a few lines. Download your files from here and you can check it yourself.
  • That is really most of the code. I don't set any clocks or nothing. The main thing I do is add sys/bios.

    For more reference, the whole main is included. Hope this could show you more. Looking forward for you reply.

    42618.main.c
    /*
     *  ======== main.c ========
     */
    
    #include <xdc/std.h>
    #include <xdc/runtime/System.h>
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    
    #include <xdc/runtime/Log.h>
    
    #include "driverlib.h"
    
    #define GPIO_ALL	GPIO_PIN0|GPIO_PIN1|GPIO_PIN2|GPIO_PIN3| \
    					GPIO_PIN4|GPIO_PIN5|GPIO_PIN6|GPIO_PIN7
    
    uint8_t returnValue = 0x00;
    uint8_t transmitData = 0x00,
    		receiveData = 0x00;
    
    void init_GPIO(void);
    int init_SPI(void);
    void start_SPI(void);
    
    //-----------------------------------------
    // Globals
    //-----------------------------------------
    volatile int16_t i16ToggleCount = 0;
    
    /*
     *  ======== main ========
     */
    Int main()
    { 
    	init_GPIO();
    	init_SPI();
    	
        BIOS_start();    /* does not return */
        return(0);
    }
    
    void start_SPI(){
    	// USCI_A0 TX buffer ready?
    //    while(!USCI_A_SPI_getInterruptStatus(USCI_A0_BASE,USCI_A_SPI_TRANSMIT_INTERRUPT))
    //    {;}
    
        // check for message
        if( !GPIO_getInputPinValue(GPIO_PORT_P6,GPIO_PIN6) ){
          	if( USCI_A_SPI_receiveData(USCI_A0_BASE) == 0x50){
          		GPIO_toggleOutputOnPin(GPIO_PORT_P4,GPIO_PIN7);
           	} else{
           		GPIO_toggleOutputOnPin(GPIO_PORT_P1,GPIO_PIN0);
           	}
        }
    
        USCI_A_SPI_clearInterrupt(USCI_A0_BASE, USCI_A_SPI_RECEIVE_INTERRUPT); // Flag may be needed or not
    //    i16ToggleCount += 1;					// keep track of #toggles
    //
    //    Log_info1("TOGGLED LED [%U] TIMES", i16ToggleCount);
    }
    
    int init_SPI(){
    	// Configure for SPI
    	// P3.4 as MISO
    	GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P3,GPIO_PIN4);
    	// P3.3 as MOSI
    	GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P3,GPIO_PIN3);
    	// P2.7 as SCLK
    	GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2,GPIO_PIN7);
        // P6.6 Chip select
        GPIO_setAsInputPin(GPIO_PORT_P6,GPIO_PIN6);
    
        returnValue = USCI_A_SPI_initSlave( USCI_A0_BASE, USCI_A_SPI_MSB_FIRST, USCI_A_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT,
        		USCI_A_SPI_CLOCKPOLARITY_INACTIVITY_LOW );
    
        if(STATUS_FAIL == returnValue){
        	return 0;
        }
    
        // Enable SPI Module
        USCI_A_SPI_enable(USCI_A0_BASE);
    
        // Enable Receive Interrupt
        USCI_A_SPI_clearInterrupt(USCI_A0_BASE, USCI_A_SPI_RECEIVE_INTERRUPT); // Flag may be needed or not
        USCI_A_SPI_enableInterrupt(USCI_A0_BASE, USCI_A_SPI_RECEIVE_INTERRUPT);
    
        return 1;
    }
    
    void init_GPIO(void){
    	// Disable the Watchdog Timer (important, as this is enabled by default)
    	WDT_A_hold( WDT_A_BASE );
    
    	// Set GPIO ports to low-level outputs
        GPIO_setAsOutputPin( GPIO_PORT_P1, GPIO_PIN0 );
        GPIO_setAsOutputPin( GPIO_PORT_P4, GPIO_PIN7 );
        GPIO_setOutputLowOnPin( GPIO_PORT_P1, GPIO_PIN0 );
        GPIO_setOutputLowOnPin( GPIO_PORT_P4, GPIO_PIN7 );
    }
    
    
    

  • A little bit more code but still no clock setup.

    If the default clock setup is used the DCO will have a frequency of ~2MHz and SMCLK=MCLK=DCO/2 =~1MHZ.
    The DCO is using FLL to generate a clock frequency synchronized to XT1CLK (LFXTCLK ~32KHz).

    The DCO can also generate a frequency of ~8MHz using the FLL and referenced by XT2CLK (cstcr4m00g15l99 4MHz). But this must be specified in the software.
  • Rodney Wong said:
    From Code Composer, I see that my SMCLK is 8.2MHz and ACLK is 32kHz in my MSP430F5529. ROV -> ... -> msp430 -> ClockFreqs.

    The ROV shows the SMCLK which has been set on the TI-RTOS configuration, and for MSP430Fxxxx devices the default SMCLK is 8192000 Hz:

    From looking at the TI-RTOS 2.12.00.24 UART Console example for an MSP-EXP430F5529, while the SMCLK can be changed on the TI-RTOS configuration GUI it looks like the driver files assume a hard-coded default SMCLK of 8192000 Hz. E.g. the Boot_configureDCO function in <tirtos_msp430_install_root>/products/bios_6_41_03_51/packages/ti/catalog/msp430/init/Boot.c sets SMCLK to a hard-coded value of 8192000 Hz rather than the SMLCK configuration parameter:

    /*
     *  ======== Boot_configureDCO ========
     *  Initializes MSP430F5xxx clocks and DCO for:
     *      ACLK = REFO = 32768Hz 
     *      MCLK = SMCLK = 8.192MHz
     *  Derived from the msp430x54x_UCS_3.c and MSP430F552x_UCS_03.c examples. 
     */
    #if defined(__ICC430__)
        #pragma location="CSTART"
    #endif
    Void Boot_configureDCO(Void)
    {
        REG(UCSCTL3) |= SELREF_2;           /* set FLL ref to REF0 */
        REG(UCSCTL4) |= SELA_2;             /* set ACLK to REF0 */
    
        __bis_SR_register(SCG0);            /* disable FLL */
        REG(UCSCTL0) = 0x0000;              /* set lowest DCOx and MODx bits */
        REG(UCSCTL1) = DCORSEL_5;           /* select 24 MHz range */
        
        REG(UCSCTL2)  = FLLD_1 + 249;       /* 
                                             * set multiplier for 8.192MHz:
                                             *     (N + 1) * FLLRef = Fdco 
                                             *   (249 + 1) * 32768  = 8.192 MHz
                                             *      FLL Div = fDCOCLK/2  
                                             */
    
        __bic_SR_register(SCG0);            /* enable FLL */
    
        /* 
         * worst-case settling time (MCLK cylces)
         *    =  N x 32 x 32 x f_MCLK / f_FLL_ref 
         *
         * 250000 =  32 x 32 x 8 MHz / 32768 Hz
         */
        __delay_cycles(250000);
    
        /* wait until XT1, XT2, and DCO fault flags are cleared... */
        do {
           REG(UCSCTL7) &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG);
           REG(SFRIFG1) &= ~OFIFG;
        } while (REG(SFRIFG1) &OFIFG); 
    
    }
    

    So, while changing the SMLCK to 4000000 Hz in the TI-RTOS changes the SMCLK value reported in the ROV it doesn't necessarily change the actual SMCLK on the running target. Which TI-RTOS platform are you using?

  • Rodney Wong said:
    Also, I couldn't find any info about MCLK. I suppose it is the same as SMCLK by default.

    The documentation for the module ti.sysbios.family.msp430.ClockFreqs says that the MCLK is configured by the configuration parameter BIOS.cpuFreq.lo

    Rodney Wong said:
    I am not sure. Is the SMCLK value of 8.2MHz right? The physical high frequency oscillator is suppose to be a cstcr4m00g15l99 which runs at 4MHz. How can the SMCLK be so fast?

    The MSP430F5529 has a Unified Clock System (UCS) Introduction which allows MCLK to run at a higher frequency than the external crystal on XT2 - see the UCS section in the MSP430x5xx and MSP430x6xx Family User's Guide for details.

    The SMCLK value of 8.2MHz is correct for the default clock frequency selected by SYS-BIOS (TI-RTOS) for MSP430F5xxx devices.

    The documentation for ti.sysbios.family.msp430.ClockFreqs indicates it is the responsibility of the application to set the clocks to the corresponding frequencies if non-default values are used. Therefore, if say your project needs MCLK and SMCLK to be 4MHz from an external crystal on XT2, and ACLK to be 32.768KHz from an external crystal on XT1, then the steps are:

    a) Add the following to the .cfg script:

    var ClockFreqs = xdc.useModule('ti.sysbios.family.msp430.ClockFreqs');
    var Boot = xdc.useModule('ti.catalog.msp430.init.Boot');
    ClockFreqs.SMCLK = 4000000;
    ClockFreqs.ACLK = 32768;
    BIOS.cpuFreq.lo = 4000000;
    BIOS.cpuFreq.hi = 0;
    Boot.configureDCO = false;

    Setting Boot.configureDCO disables the TI-RTOS start-up code from initializing it's default clock settings. The values for BIOS.cpuFreq (MCLK), ClockFreqs.SMCLK and ClockFreqs.ACLK set the TI-RTOS parameters for the clock frequencies. E.g. allows the TI-RTOS UART driver to obtain the correct SMCLK frequency when selecting the baud-rate divisors.

    b) Add code at the start of main() to configure the UCS before initializing other peripherals and before calling BIOS_start()

  • Yes, the RTOS sets the clocks differently than regular boot loader.

    Without RTOS the UCSCTL regs with this code are:

    #include "driverlib.h"
    
    int main(void) {
    
        WDT_A_hold(WDT_A_BASE);
    
        return (0);
    }

    UCSCTL0 - 0x13F8

    UCSCTL1 - 0x0020

    UCSCTL2 - 0x101F

    UCSCTL3 - 0x0000

    UCSCTL4 - 0x0044

    UCSCTL5 - 0x0000

    UCSCTL6 - 0xC1CD

    UCSCTL7 - 0x0403

    UCSCTL8 - 0x0707

    With RTOS the UCSCTL regs with this code are:

    /*
     *  ======== main.c ========
     */
    
    #include <xdc/std.h>
    
    #include <xdc/runtime/System.h>
    
    #include <ti/sysbios/BIOS.h>
    
    #include <ti/sysbios/knl/Task.h>
    
    /*
     *  ======== taskFxn ========
     */
    Void taskFxn(UArg a0, UArg a1)
    {
        System_printf("enter taskFxn()\n");
    	
        Task_sleep(10);
    	
        System_printf("exit taskFxn()\n");
    }
    
    /*
     *  ======== main ========
     */
    Int main()
    { 
        /*
         * use ROV->SysMin to view the characters in the circular buffer
         */
        System_printf("enter main()\n");
    	
        BIOS_start();    /* does not return */
        return(0);
    }

    UCSCTL0 - 0x1388

    UCSCTL1 - 0x0050

    UCSCTL2 - 0x10F9

    UCSCTL3 - 0x0020

    UCSCTL4 - 0x0244

    UCSCTL5 - 0x0000

    UCSCTL6 - 0xC1CD

    UCSCTL7 - 0x0400

    UCSCTL8 - 0x0707

    Thanks for the info. I am getting to understand the clocking in this micro more fully.

**Attention** This is a public forum