MSP430 Tutorial


Unified Clock System


Unified Clock System (UCS) Introduction

  • XT1CLK: Low-frequency or high-frequency oscillator that can be used either with low-frequency 32768 Hz watch crystals, standard crystals, resonators, or external clock sources in the 4 MHz to 32 MHz range. XT1CLK can be used as a clock reference into the FLL.



    After a PUC (a system reset), the UCS module default configuration is XT1 in LF mode is selected as the oscillator source for XT1CLK. XT1CLK is selected for ACLK.

  • VLOCLK: Internal very low power, low-frequency oscillator with 10-kHz typical frequency.
  • REFOCLK: Internal, trimmed, low-frequency oscillator with 32768-Hz typical frequency, with the ability to be used as a clock reference into the FLL.



  • DCOCLK: Internal digitally controlled oscillator (DCO) that can be stabilized by the FLL.


  • XT2CLK: Optional high-frequency oscillator that can be used with standard crystals, resonators, or external clock sources in the 4 MHz to 32 MHz range. XT2CLK can be used as a clock reference into the FLL.

Three clock signals are available from the UCS module:

  • ACLK: Auxiliary clock. The ACLK is software selectable as XT1CLK, REFOCLK, VLOCLK, DCOCLK, DCOCLKDIV, and when available, XT2CLK. ACLK can be divided by 1, 2, 4, 8, 16, or 32. ACLK/n is ACLK divided by 1, 2, 4, 8, 16, or 32 and is available externally at a pin. ACLK is software selectable by individual peripheral modules.
  • MCLK: Master clock. MCLK is software selectable as XT1CLK, REFOCLK, VLOCLK, DCOCLK, DCOCLKDIV, and when available, XT2CLK. DCOCLKDIV is the DCOCLK frequency divided by 1, 2, 4, 8, 16, or 32 within the FLL block. MCLK can be divided by 1, 2, 4, 8, 16, or 32. MCLK is used by the CPU and system.
  • SMCLK: Subsystem master clock. SMCLK is software selectable as XT1CLK, REFOCLK, VLOCLK, DCOCLK, DCOCLKDIV, and when available, XT2CLK. DCOCLKDIV is the DCOCLK frequency divided by 1, 2, 4, 8, 16, or 32 within the FLL block. SMCLK can be divided by 1, 2, 4, 8, 16, or 32. SMCLK is software selectable by individual peripheral modules.

void UCS_initClockSignal(uint8_t selectedClockSignal,
                         uint16_t clockSource,
                         uint16_t clockSourceDivider)
{
    assert(
        (UCS_XT1CLK_SELECT == clockSource) ||
        (UCS_VLOCLK_SELECT == clockSource) ||
        (UCS_REFOCLK_SELECT == clockSource) ||
        (UCS_DCOCLK_SELECT == clockSource) ||
        (UCS_DCOCLKDIV_SELECT == clockSource) ||
        (UCS_XT2CLK_SELECT == clockSource)
        );

    assert(
        (UCS_CLOCK_DIVIDER_1 == clockSourceDivider) ||
        (UCS_CLOCK_DIVIDER_2 == clockSourceDivider) ||
        (UCS_CLOCK_DIVIDER_4 == clockSourceDivider) ||
        (UCS_CLOCK_DIVIDER_8 == clockSourceDivider) ||
        (UCS_CLOCK_DIVIDER_16 == clockSourceDivider) ||
        (UCS_CLOCK_DIVIDER_32 == clockSourceDivider)
        );

    uint16_t temp = HWREG16(UCS_BASE + OFS_UCSCTL5);
    switch(selectedClockSignal)
    {
    case UCS_ACLK:
        HWREG16(UCS_BASE + OFS_UCSCTL4) &= ~(SELA_7);
        clockSource = clockSource << 8;
        HWREG16(UCS_BASE + OFS_UCSCTL4) |= (clockSource);

        clockSourceDivider = clockSourceDivider << 8;
        HWREG16(UCS_BASE + OFS_UCSCTL5) = temp & ~(DIVA_7) | clockSourceDivider;
        break;
    case UCS_SMCLK:
        HWREG16(UCS_BASE + OFS_UCSCTL4) &= ~(SELS_7);
        clockSource = clockSource << 4;
        HWREG16(UCS_BASE + OFS_UCSCTL4) |= (clockSource);

        clockSourceDivider = clockSourceDivider << 4;
        HWREG16(UCS_BASE + OFS_UCSCTL5) = temp & ~(DIVS_7) | clockSourceDivider;
        break;
    case UCS_MCLK:
        HWREG16(UCS_BASE + OFS_UCSCTL4) &= ~(SELM_7);
        HWREG16(UCS_BASE + OFS_UCSCTL4) |= (clockSource);

        HWREG16(UCS_BASE + OFS_UCSCTL5) = temp & ~(DIVM_7) | clockSourceDivider;
        break;
    case UCS_FLLREF:
        assert(clockSource <= SELA_5);
        HWREG8(UCS_BASE + OFS_UCSCTL3) &= ~(SELREF_7);

        clockSource = clockSource << 4;
        HWREG8(UCS_BASE + OFS_UCSCTL3) |= (clockSource);

        temp = HWREG8(UCS_BASE + OFS_UCSCTL3) & 0x00FF;
        //Note that dividers for FLLREF are slightly different
        //Hence handled differently from other CLK signals
        switch(clockSourceDivider)
        {
        case UCS_CLOCK_DIVIDER_12:
            HWREG8(UCS_BASE +
                   OFS_UCSCTL3) = temp & ~(FLLREFDIV_7) | FLLREFDIV__12;
            break;
        case UCS_CLOCK_DIVIDER_16:
            HWREG8(UCS_BASE +
                   OFS_UCSCTL3) = temp & ~(FLLREFDIV_7) | FLLREFDIV__16;
            break;
        default:
            HWREG8(UCS_BASE +
                   OFS_UCSCTL3) = temp & ~(FLLREFDIV_7) | clockSourceDivider;
            break;
        }

        break;
    }
}


void UCS_initFLLSettle(uint16_t fsystem,
                       uint16_t ratio)
{
    volatile uint16_t x = ratio * 32;

    UCS_initFLL(fsystem, ratio);

    while(x--)
    {
        __delay_cycles(30);
    }
}
void USBHAL_initClocks(uint32_t mclkFreq)
{
        UCS_initClockSignal(
                UCS_FLLREF,
                UCS_REFOCLK_SELECT,
                UCS_CLOCK_DIVIDER_1);

        UCS_initClockSignal(
                UCS_ACLK,
                UCS_REFOCLK_SELECT,
                UCS_CLOCK_DIVIDER_1);

        UCS_initFLLSettle(
                mclkFreq / 1000,
                mclkFreq / 32768);
}

The FLL is similar to the PLL (phase lock loop), except that, rather than locking to phase it locks to frequency. The frequency it locks to, is some reference frequency clock source, such as a watch 32768 Hz crystal. The FLL, in conjunction with the modulator, is used to provide a much more stable DCO frequency. The required frequency is set as some multiple of the reference frequency, so, for example with XT1CLK 32768 Hz setting the FLL value to 200 gives a 6.5536MHz clock. Unfortunately not all desired clock frequencies are a convenient integer multiple. This is where the modulator comes in. It provides, if you like, the fractional part of the result FLL value Fd/Fs, where Fd is the desired frequency and Fs is the stable source frequency.

XIN and XOUT are inputs for the 32.768 kHz LF clock.


XT2IN and XT2OUT are inputs for the 4.0000 MHz XT2CLK clock.

After a PUC, the UCS module default configuration is:

  • XT1 in LF mode is selected as the oscillator source for XT1CLK. XT1CLK is selected for ACLK.
  • DCOCLKDIV is selected for MCLK.
  • DCOCLKDIV is selected for SMCLK.
  • FLL operation is enabled and XT1CLK is selected as the FLL reference clock, FLLREFCLK.
  • On devices that have XIN and XOUT shared with general-purpose I/O, XIN and XOUT pins are set to general-purpose I/Os and XT1 remains disabled until the I/O ports are configured for XT1 operation. If XIN and XOUT are not shared with general-purpose I/Os, XT1 is enabled.

FLL operation with XT1 is selected by default. If the crystal pins (XIN, XOUT) are shared with general-purpose I/Os, XT1 will remain disabled until the PSEL bits associated with the crystal pins are set. If XIN and XOUT are not shared with general-purpose I/O, XT1 is enabled. When a 32768 Hz crystal is used for XT1CLK, the fault control logic immediately causes ACLK to be sourced by the REFOCLK, because XT1 is not stable immediately (see Section 1.2.12). When crystal startup is obtained and settled, the FLL stabilizes MCLK and SMCLK to 1.048576 MHz and fDCO = 2.097152 MHz.