Search code examples
cmicrocontrollermsp430texas-instrumentscode-composer

MSP430: __delay_cycles() is slow/MCLK might be slow


I am afraid there may be something wrong with my MSP430F5529 launchpad because I can't get __delay_cycles to behave properly. It always use to work fine but now suddenly seems to have an issue. I would just use a timer module to cause a delay but the current program is already using all of them and I would prefer to keep them dedicated to their tasks. I only need a couple delays during initialization so the typical warning of "try not to use __delay_cycles" because it halts the program isn't really a problem here.

So the issue is that using __delay_cycles() is taking way longer than it should despite the fact I've recently used it on another program with no issues. I've tried using the same code on a different project with default settings, and to make sure my code wasn't doing something weird I made a quick program that just turns on an LED after what should be a one second delay:

void main(void){

WDTCTL = WDTPW | WDTHOLD;     // Stop watchdog timer

P1OUT &= ~(BIT0);
P1DIR |= BIT0;
P1REN |= BIT0;

__delay_cycles(25000000);

P1OUT |= BIT0;
}

Since MCLK runs at 25MHz delaying by 25 Million cycles should give about a 1 second delay, but instead, it takes the LED about 25 seconds to turn on after starting the program in the debugger. This has made me fear that there is something wrong with the MCLK on my microcontroller, and although I feel that would be very unlikely, I cannot seem to find another reason why this is happening after I, to my knowledge, didn't change anything. Since it takes 25 seconds for the LED to turn on it almost seems like MCLK is running at 1MHz, or that for some reason the function is sourcing from SMCLK.

Have I just been high this whole time and MCLK always runs at 1MHz while using __delay_cycles()? And I just didn't notice because the delays I was using "successfully" before were only a couple milliseconds? I swore that the frequency of MCLK was 25MHz by default and the only way to have that change was to set it via code. So it seems to me that either:

  • A) The MSP430 doesn't run at 25MHz by default and nothing I have codded has made that apparent
  • B) __delay_cycles() changes the speed of MCLCK during execution and I never noticed because the delays I needed were so quick
  • C) I accidentally changed some setting in my compiler, or for some reason the compilers optimizer is messing up the compilation of __delay_cycles()
  • D) My MCLK is broken/half broken

My compiler is Code Composer Studio 6.1.0.00104 by the way, if that information is pertinent.

Does anyone have an wisdom to share on what might be wrong?

Thanks.


Solution

  • The User's Guide says in section 5.2:

    After a PUC, the UCS module default configuration is:

    • XT1 in LF mode is selected as the oscillator source for XT1CLK.
    • DCOCLKDIV is selected for MCLK.
    • FLL operation is enabled and XT1CLK is selected as the FLL reference clock, FLLREFCLK.

    […] XT1 will remain disabled until the PSEL bits associated with the crystal pins are set.

    and in section 5.2.12:

    When using XT1 operation in LF mode as the reference source into the FLL (SELREF = {0}), a crystal fault automatically causes the FLL reference source, FLLREFCLK, to be sourced by the REFO.

    The default FLL configuration (FLLN = 0x1F, FLLD = 1) results in a DCO frequency of 64 × 32768 Hz = 2.097152 MHz, and a MCLK frequency of 1.048576 MHz (well, if REFO were accurate enough to justify this precision).

    To run the CPU at 25 MHz, you must reprogram the FLL (and increase PMMCOREV).