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.

Oscillator fault flag always set?

Other Parts Discussed in Thread: MSP430F5510

Hi all, I use a MSP430F5510 in my board. I use this code to set the frequency to 24MHz, taken from TI examples:

void Clock_Init(void)
{
// Increase VCore, step by step, to support 24MHz
Clock_SetVCoreUp(0x01);
Clock_SetVCoreUp(0x02);
Clock_SetVCoreUp(0x03);
UCSCTL3 = SELREF_2; // Set DCO FLL reference = REFO
UCSCTL4 |= (SELA_2 | SELS_3 | SELM_3); // Set ACLK = REFO, MCLK = DCOCLK, SMCLK = DCOCLCK
UCSCTL5 |= DIVS_3; // Set SMCLK divider = 8
__bis_SR_register(SCG0); // Disable the FLL control loop
UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx
UCSCTL1 = DCORSEL_7; // Select DCO range 50MHz operation
UCSCTL2 = FLLD_1 + 731; // Set DCO Multiplier for 24MHz: (731 + 1) * 32768 = 24MHz
__bic_SR_register(SCG0); // Enable the FLL control loop
__delay_cycles(752000); // Worst-case settling time for DCO
// Loop until XT1, XT2 and DCO stabilizes
do
{
   UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags
   SFRIFG1 &= ~OFIFG; // Clear fault flags
} while (SFRIFG1 & OFIFG); // Test oscillator fault flag
}

// Set the VCore to the specified level
void Clock_SetVCoreUp(unsigned int level)
{
PMMCTL0_H = PMMPW_H; // Open PMM registers for write
SVSMHCTL = SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level; // Set SVS/SVM high side new level
SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level; // Set SVM low side to new level
while ((PMMIFG & SVSMLDLYIFG) == 0); // Wait until SVM is settled
PMMIFG &= ~(SVMLVLRIFG + SVMLIFG); // Clear already set flags
PMMCTL0_L = PMMCOREV0 * level; // Set VCore to new level
if ((PMMIFG & SVMLIFG))
   while ((PMMIFG & SVMLVLRIFG) == 0); // Wait till new level reached
SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level; // Set SVS/SVM low side to new level
PMMCTL0_H = 0x00; // Lock PMM registers for write access
}

When I ran the code, I noticed that it was stuck at the last do-while loop, that checks for the oscillator fault flag. I thought that the problem was the too high clock frequency, so I commented the entire code except for the do-while loop. Result? Running the code, it was stuck again at the do-while loop, even if the clock was configured with default settings (2MHz if I remember correctly). So, it seems that the oscillator fault flag is always set, even with the default clock frequency.

However, just to try, I remove the do-while loop and run a simple program that makes a LED blink (in my board I have a LED connected to a I/O port), and everything works even at 24MHz. How is it possible?

  • Do you have anything connected to XT1 and/or  XT2 ?

    What is the Vcc voltage level?

    What happens if you go for lower Frequencies (i.e. 4MHz) ? Do you see any changes?

    Emanuele Bellocchia said:
    When I ran the code, I noticed that it was stuck at the last do-while loop, that checks for the oscillator fault flag.

    In the UCSCTL7 Register, can you check which exact fault Flag is set?

    BR,

    Mo.

  • Emanuele Bellocchia said:
    UCSCTL4 |= (SELA_2 | SELS_3 | SELM_3); // Set ACLK = REFO, MCLK = DCOCLK, SMCLK = DCOCLCK

    SELS_3 and SELM_3 might be the problem here.

    MCLK = DCOCLK, SMCLK = DCOCLCK are not correct. You need to select DCOCLKDIV instead.

    UCSCTL4 |= SELA_2;  //set ACLK = REFO, MCLK = DCOCLKDIV, SMCLK = DCOCLCKDIV

    This should work properly.

    (MCLK = DCOCLKDIV, SMCLK = DCOCLCKDIV are by default (after system Reset) selected in the UCSCTL4 register)

    Hope this helps,

    BR,

    Mo.

  • Yes you are right, thank you very much!

  • I know that this is not related to the previous post, but I also have a question about the I/O module. I know that port P4 can be mapped, so I can choose the specific function of each pin. Now, I map USCI A0 to port P4 pins, and I want to use USCI B0 with port P3... but from the datasheet I see that port P3 can be used both by USCI A0 and USCI B0. How can I specifiy that I want to use port P3 for USCI B0?

  • The STE signal of one A/B module and the CLK signal of the other module are mutually exclusive. If one module uses 4-wire SPI mode, the other one cannot use  SPI at all. If both use SPI, they automatically switch back to 3-wire mode.
    As you can see in the port mapping controller, PM_UCA0STE and PM_UCBCLK have the same value. The clock signal has preference if the USCI is configures to use both.

    The other 'combined' mapping settings are for the same module and are defined by the USCI operating mode (e.g. PM_UCA0RXT and PM_UCA0SOMI)

  • So, if I use USCI A0 in 4-wire SPI mode mapped on port P4, I cannot use USCI B0 in SPI mode in port P3?

  • Other way: If you want to use SPI on USCI B0, you cannot use 4-wire SPI on USCI A0. Two SPIs at work means both are 3-wire mode even if you program 4-wire mode.

    However, in ost cases people think they have to use 4-wire mdoe where they won't. 4-wire is only for salve or multi-master operation. If the MSP is the only master on the bus, 3-wire mode is the right one. The 4th wire, CS, needs to be implemented as normal software-controlled GPIO anyway, since there can be many slaves and therefore many CS signals. The SPI hardware doesn't know which slave you want to access. Even if the MSP runs in 4-wir emode as SPI slave, it still requires teh signal on STE also routed to a GPIO pin, so it can do the high-level protocol actions based on it. STE only controls the USCI pin drivers. It does not even sync the shift register.

  • My apologies for responding to such an old post - I was having similar issues,which was also fixed by selecting MCLK & SCLK as DCOCLKDIV.

    My question is, why is this necessary? I am using an MSP430f529 - the data sheet lists the DCOCLK as a selectable source for this device - however, when I used SELS_3, SELM_3 = 0x0030, 0x0003, respectively the UCSCTL4 for each filled with 111b - I don't understand why this is happening.

    Any Help is appreciated.

    Thanks,

    Courtney

  • DCOCLKDIV uses the same divider on DCOCLK that is used as additional multiplier (FLLDx) in the FLL. By default, DCOCLK is 2MHz but SCOCLKDIV is only 1MHz. It allows running the DCO on a higher frequency than needed. So why would one do that? There are multiple reasons.
    First, there is only a very limited number of real DCO frequencies. All others are created by modulating the DCO, which means switching the DCO between two frequencies. This also means that one clock cycle is higher and one i lower than the desired target clock. As a result, the maximum DCO clock frequency, when running from DCOCLK, is 23.3MHz. Else in worst case, the higher pulse might exceed 25MHz. Using DCOCLKDIV runs the DCO on 50MHz in this case, but since two adjacent clock pulses are added, the maximum DCOCLKDIV frequency is much close on 25MHz. About 24.1MHz on a factor of 2.
    The other reason is the clock jitter. Due to modulation, clock pulses aren't same frequency. Only the average frequency over a period of 32 clock pulses is stable. So if you run the DCO at an additional factor of 32 and use DCOCLKDIV, which then will be jitter-free.
    As long as you don't exceed the maximum core frequency, this is no problem. But if you use DCOCLK as cource for the peripherals, the jitter might be a problem. E.g. if using a DAC to generate a waveform, the jitter will cause distortion while an wrong average DCO speed will just cause a frequency error. Same might be true when using the SPI with maximum speed. Some devices are sensitive to clock jitter as much as (ore even more than) to a frequency error. Especially those 1-wire protocols.

    A last point is the clock system itself. When changing RSEL to switch the DCO to a different frequency range, the first single clock pulse may be shorter than intended. Much shorter. And instantly crash the CPU. Using DCOCLKDIV with a factor of at least 2 will swallow this 'peak' pulse as long as the correct undivided clock frequency of the target setting doesn't exceed the CPU maximum speed. In this case, it is only necessary to switch (or stay on, as this is the default) MCLK to DCOCLKDIV until the switch is performed. One could as well switch to REFO, but this would slow down the CPU until the switch is done.

**Attention** This is a public forum