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.

Is there some kind of dependency between MCLK and SMCLK?

Other Parts Discussed in Thread: MSP430F6733

Hello!

I have problem with MCLK and SMCLK. According to the User's Guide the MCLK and SMCLK should have separate dividers, but for some reason MSP430F6733 does not seem to behave that way.

The problem here is that I want to drop MCLK frequency in order to cut some CPU current consumption and keep the SMCLK at maximum 25MHz to keep communications running smoothly at high frequency. The problem is that for some reason the MCU seem to force SMCLK <= MCLK rule. According to the datasheets and user's guides this kind of dependency shouldn't exist. Both MCLK and SMCLK are sourced from the 25MHz DCO.

I have configured a TA0 to take clock from SMCLK and use it to toggle a LED once a second when SMCLK = 25MHz. When DIVS = 001 and DIVM = 000, the timer toggles the LED in two second interval, as expected since the SMCLK is halved. But if DIVS = 000 and DIVM = 001 the timer toggles the LED in two second interval, even the SMCLK should be running at 25MHz and only the CPU clock should be halved. Why it behaves in this way?

The clock initialisation code is following:

void vMSP430_CoreInit(void)
{
    StopWatchdog;
    DisableInterrupts;

    //Set VCore = 3 for 25MHz clock
    PMM_setVCore(PMM_BASE,
        PMM_CORE_LEVEL_3
        );

    //Start the XT1 low frequency 32Khz oscillator with no timeout.
    //In case of failure, code hangs here.
    //For time-out instead of code hang use UCS_LFXT1StartWithTimeout()
    UCS_LFXT1Start(UCS_BASE,
            UCS_XT1_DRIVE3,
            UCS_XCAP_3  //12.0 pF + parasitic (ideal total is 12.5 pF)
     );

    //Set DCO FLL reference = XT1
    UCS_clockSignalInit(
        UCS_BASE,
        UCS_FLLREF,
        UCS_XT1CLK_SELECT,
        UCS_CLOCK_DIVIDER_2
        );

    //MCLK is initialized by this function.
    //Set Ratio and Desired MCLK Frequency and initialize DCO
    //If the frequency is greater than 16 MHz, the function sets the MCLK and SMCLK source to the undivided DCO frequency.
    //Otherwise, the function sets the MCLK and SMCLK source to the DCOCLKDIV frequency.
    UCS_initFLLSettle(
        UCS_BASE,
        UCS_MCLK_DESIRED_FREQUENCY_IN_KHZ,
        UCS_MCLK_FLLREF_RATIO
        );

    //MCLK = DCO. (25Mhz)
    UCS_clockSignalInit(
        UCS_BASE,
        UCS_MCLK,
        UCS_DCOCLK_SELECT,
        UCS_CLOCK_DIVIDER_2
        );

    //ACLK = DCO. (25Mhz)
    UCS_clockSignalInit(
        UCS_BASE,
        UCS_ACLK,
        UCS_DCOCLK_SELECT,
        UCS_CLOCK_DIVIDER_1
        );

    //SMCLK = DCO. (25Mhz)
    UCS_clockSignalInit(
        UCS_BASE,
        UCS_SMCLK,
        UCS_DCOCLK_SELECT,
        UCS_CLOCK_DIVIDER_1
        );

    return;
}

-Juho L

  • I am not sure what is the root cause of the problem your are facing but I suggest using a TI example code first in order to get closer to the root cause. I.e. you can try to use the below code which should generate MCLK = 4 MHz at PJ.1 and SMCLK = 8 MHz at PJ.0:

    //******************************************************************************
    //  MSP430F673x Demo - UCS, Software Toggle P1.0 with 8MHz DCO
    //
    //  Description: Toggle P1.0 by xor'ing P1.0 inside of a software loop.
    //  ACLK is brought out on pin P11.0, SMCLK is brought out on P11.2, and MCLK
    //  is brought out on pin P11.1.
    //  ACLK = REFO = 32kHz, MCLK = 4MHz, SMCLK = 8MHz
    //
    //                MSP430F673x
    //             -----------------
    //         /|\|                 |
    //          | |             PJ.3|-->ACLK
    //          --|RST          PJ.1|-->MCLK
    //            |             PJ.0|-->SMCLK
    //            |                 |
    //            |             P1.0|-->LED
    //
    //  M. Swanson
    //  Texas Instruments Inc.
    //  December 2011
    //  Built with CCS Version: 5.1.0 and IAR Embedded Workbench Version: 5.40.1
    //******************************************************************************
    #include <msp430.h>
    
    void main(void)
    {
        WDTCTL = WDTPW | WDTHOLD;              // Stop WDT
    
        // Setup P1.0 output, J1.0 SMCLK, J1.1 MCLK, J1.3 ACLK
        P1DIR |= BIT0;                         // Set P1.0 to output direction
        P1OUT &= ~BIT0;                        // Clear P1.0
        PJDIR |= BIT0 | BIT1 | BIT3;           // ACLK, MCLK, SMCLK set out to pins
        PJSEL |= BIT0 | BIT1 | BIT3;           // PJ.0,1,3 for debugging purposes.
    
    
        // Setup UCS
        UCSCTL3 |= SELREF_2;                   // Set DCO FLL reference = REFO
        UCSCTL4 |= SELA_2;                     // Set ACLK = REFO
    
        __bis_SR_register(SCG0);               // Disable the FLL control loop
        UCSCTL0 = 0x0000;                      // Set lowest possible DCOx, MODx
        UCSCTL1 = DCORSEL_5;                   // Select DCO range 16MHz operation
        UCSCTL2 = FLLD_1 | 243;                // Set DCO Multiplier for 8MHz
                                               // (N + 1) * FLLRef = Fdco
                                               // (243 + 1) * 32768 = 8MHz
                                               // Set FLL Div = fDCOCLK/2
        __bic_SR_register(SCG0);               // Enable the FLL control loop
    
        // Worst-case settling time for the DCO when the DCO range bits have been
        // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
        // UG for optimization.
        // 32 x 32 x 8 MHz / 32,768 Hz = 250000 = MCLK cycles for DCO to settle
        __delay_cycles(250000);
    
        // Loop until XT1, XT2 & DCO fault flag is cleared
        do
        {
            UCSCTL7 &= ~(XT2OFFG | XT1LFOFFG | DCOFFG);
            // Clear XT2,XT1,DCO fault flags
            SFRIFG1 &= ~OFIFG;                 // Clear fault flags
        } while (SFRIFG1 & OFIFG);             // Test oscillator fault flag
    
        UCSCTL5 = DIVM_1 | DIVS_0 | DIVA_0;
    
        while (1)
        {
            P1OUT ^= BIT0;                     // Toggle P1.0
            __delay_cycles(600000);            // Delay
        }
    }
    

    Hope this helps,

    Regards,

    Mo.

**Attention** This is a public forum