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.

Changing the system clock

Other Parts Discussed in Thread: MSP430F6736, MSP430F5438

I downloaded the HID Demo source and I've been trying to get it working on the MSP430F6736.  I noticed that the SetSystemClock function disables the ACLK ISR.  Any ideas on what I need to change to get it working?  Here's the original code

static void SetSystemClock(Cpu_Frequency_t CPU_Frequency)
{
Boolean_t UseDCO;
unsigned int Ratio;
unsigned int DCODivBits;
unsigned long SystemFrequency;
volatile unsigned int Counter;
BTPSCONST Frequency_Settings_t *CPU_Settings;

/* Verify that the CPU Frequency enumerated type is valid, if it is */
/* not then we will force it to a default. */
if((CPU_Frequency != cf8MHZ_t) && (CPU_Frequency != cf16MHZ_t) && (CPU_Frequency != cf20MHZ_t) && (CPU_Frequency != cf25MHZ_t))
CPU_Frequency = cf16MHZ_t;

/* Do not allow improper settings (MSP430F5438 cannot run at 20MHz or*/
/* 25 MHz). */
if((!DetermineProcessorType()) && ((CPU_Frequency == cf20MHZ_t) || (CPU_Frequency == cf25MHZ_t)))
CPU_Frequency = cf16MHZ_t;

/* Get the CPU settings for the specified frequency. */
CPU_Settings = &Frequency_Settings[CPU_Frequency - cf8MHZ_t];

/* Configure the PMM core voltage. */
ConfigureVCore(CPU_Settings->VCORE_Level);

/* Get the ratio of the system frequency to the source clock. */
Ratio = CPU_Settings->DCO_Multiplier;

/* Use a divider of at least 2 in the FLL control loop. */
DCODivBits = FLLD__2;

/* Get the system frequency that is configured. */
SystemFrequency = HAL_GetSystemSpeed();
SystemFrequency /= 1000;

/* If the requested frequency is above 16MHz we will use DCO as the */
/* source of the system clocks, otherwise we will use DCOCLKDIV. */
if(SystemFrequency > 16000)
{
Ratio >>= 1;
UseDCO = TRUE;
}
else
{
SystemFrequency <<= 1;
UseDCO = FALSE;
}

/* While needed set next higher div level. */
while (Ratio > 512)
{
DCODivBits = DCODivBits + FLLD0;
Ratio >>= 1;
}

/* Disable the FLL. */
__bis_SR_register(SCG0);

/* Set DCO to lowest Tap. */
UCSCTL0 = 0x0000;

/* Reset FN bits. */
UCSCTL2 &= ~(0x03FF);
UCSCTL2 = (DCODivBits | (Ratio - 1));

/* Set the DCO Range. */
if(SystemFrequency <= 630)
{
/* Fsystem < 630KHz. */
UCSCTL1 = DCORSEL_0;
}
else if(SystemFrequency < 1250)
{
/* 0.63MHz < fsystem < 1.25MHz. */
UCSCTL1 = DCORSEL_1;
}
else if(SystemFrequency < 2500)
{
/* 1.25MHz < fsystem < 2.5MHz. */
UCSCTL1 = DCORSEL_2;
}
else if(SystemFrequency < 5000)
{
/* 2.5MHz < fsystem < 5MHz. */
UCSCTL1 = DCORSEL_3;
}
else if(SystemFrequency < 10000)
{
/* 5MHz < fsystem < 10MHz. */
UCSCTL1 = DCORSEL_4;
}
else if(SystemFrequency < 20000)
{
/* 10MHz < fsystem < 20MHz. */
UCSCTL1 = DCORSEL_5;
}
else if(SystemFrequency < 40000)
{
/* 20MHz < fsystem < 40MHz. */
UCSCTL1 = DCORSEL_6;
}
else
UCSCTL1 = DCORSEL_7;

/* Re-enable the FLL. */
__bic_SR_register(SCG0);

/* Loop until the DCO is stabilized. */
while(UCSCTL7 & DCOFFG)
{
/* Clear DCO Fault Flag. */
UCSCTL7 &= ~DCOFFG;

/* Clear OFIFG fault flag. */
SFRIFG1 &= ~OFIFG;
}

/* Enable the FLL control loop. */
__bic_SR_register(SCG0);

/* Based on the frequency we will use either DCO or DCOCLKDIV as the */
/* source of MCLK and SMCLK. */
if (UseDCO)
{
/* Select DCOCLK for MCLK and SMCLK. */
UCSCTL4 &= ~(SELM_7 | SELS_7);
UCSCTL4 |= (SELM__DCOCLK | SELS__DCOCLK);
}
else
{
/* Select DCOCLKDIV for MCLK and SMCLK. */
UCSCTL4 &= ~(SELM_7 | SELS_7);
UCSCTL4 |= (SELM__DCOCLKDIV | SELS__DCOCLKDIV);
}

/* Delay the appropriate amount of cycles for the clock to settle. */
Counter = Ratio * 32;
while (Counter--)
__delay_cycles(30);
}

  • Daniel Garcia1 said:
    I noticed that the SetSystemClock function disables the ACLK ISR.

    What do you mean by 'ACLK ISR'? ACLK is a clock and not an interrupt source. Peripherals modules have ISRs. ACLK only has a (selectable) source oscillator and a divider, but does not cause any interrupts by itself.
    Modules clocked by ACLK may cause interrupts.

  • In a different part I do this

    TA1CCTL0 = CCIE; 
    TA1CCR0 = (32768 / 1000) + 1;
    TA1CTL = TASSEL_1 | MC_1 | TACLR;

    __bis_SR_register(GIE);

    but the ISR never gets triggered if I configure the system clock with the aforementioned code.

    #pragma vector=TIMER1_A0_VECTOR
    __interrupt void TIMER1_A0_ISR(void)
    {
    ++MSP430Ticks;

    }

  • Well, as far a sI see does the posted function never touch anything that is related to ACLK. So ACLK should be active and running on default settings (which means LFXT1 or, if XT1 is not available, REFO).

    With the timer config you posted, the timer ISR should be triggered every 34 ACLK ticks.

    How do you know the ISR is never triggered? Did you put a breakpoint on it?

    What about the MSP430Ticks variable? Did you declare it volatile?

    If you just skip the call to SetSystemClock, is the ISR triggered then?
    What parameters do you pass to SetSystemClock?

    Well, I don't understand this function at all. At the very beginning, it limits the possible parameters to one of four frequencies (8,16,20,25MHz), substituting 16MHz for any other. But then it continues as if you could set any frequency you like. Looks very weird.

  • To answer your questions,

    I did put a breakpoint, plus I'm also using MSP430Ticks to get out of a loop and it was never being updated.

    MSP430Ticks is volatile.

    Skipping the call to SetSystemClock causes the ISR to fire.

    The frequency is being set to 25MHz, PMMCOREV_3, and Ratio is being set to 762 in Ratio = CPU_Settings->DCO_Multiplier;

    This is from the HID Demo source code I got from TI's web site.

  • Does the CPU ever leave SetSystemClock at all?

    If it doesn't it will of course never configure or fire the interrupt.

    Inside SetSystemCLock there is a while loop waiting for the clock to stabilize (OFIFG and all xxOF bits clear). If this doesn't happen, including a DCO fault due to improper RSELx for the desired speed) then it will loop there forever.

**Attention** This is a public forum