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.

Initialization of oscillator and timer on the MSP430

Other Parts Discussed in Thread: MSP430F5438A, SIMPLICITI, CC1120

I'm having some problems using one of the built in timers on the MSP430F5438A.  Let me first explain what I'm trying to do and how. Low power usage is the main concern here, I want to use a timer which fires an interrupt with periodicity T, an ISR sets a semaphore, if the semaphore is set, some code executes in the main work loop and an extremely simple message is sent. My code is based on the example code "AP_As_Data_Hub" which is distributed along with SimpliciTI 1.2. Below is an excerpt of the code, If required I can post the whole thing, but hopefully this is enough. I use the CC1120 as a radio.

void main (void)
{

/* some code */

/* part which seems to be incorrect */

UCSCTL4 |= SELA__VLOCLK; // set VLOCLK as source to ACLK
TA0CCTL0 |= CCIE; // turning on its CCIE bit makes it fire an interrupt when its counter value finally matches the value stored in TA0CCR0
TA0CCR0 = 37600; // ~ 4 sec (with VLOCLK as source, 6s is max)
TA0CTL |= TASSEL_1 + MC_1; // ACLK is source for timer, counts in upmode

uint8_t msg[1] = {1};
uint8_t *pMsg = &msg[0];

/* main work loop */
while(1)
{
/* Go to sleep while waiting for sAliveSem to be set by ISR */
__bis_SR_register(LPM3_bits+GIE); // LPM3 with interrupts enabled

/* the Alive semaphore has been set by an ISR and an "I'm alive" message is sent */
if(sAliveSem)
{
/* get radio ready...awakens in idle state */
SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0);

/* Send message */
SMPL_Send(sLinkID1, pMsg, sizeof(msg));

/* radio off */
SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0);
}

/* some code */

}

/* ISR */

#pragma vector = TIMER0_A1_VECTOR // timer0_A5
__interrupt void Timer_A (void)
{
sAliveSem = 1;
__bic_SR_register_on_exit(LPM3_bits); // exit LPM3
}

  • Assuming the problem is that the code gated on sAliveSem never gets run, try changing TIMER0_A1_VECTOR to TIMER0_A0_VECTOR.

  • Wow, you Sir are amazing! Worked like a charm, would like to know why though. Does it have to to with the fact that I've used TA0CCTL0, TA0CCR0 and TA0CTL instead of the TA1CCTL0 etc. alternatives? Just a wild guess from my side. Might I be so bold as to ask for another piece of advice? Is it possible/advicable to use LPM4 or even LPM4.5 instead of LPM3? I've read something, somewhere about VLO can always be used on MSP430 5x families, but according to the datasheet for mye device LPM4 and LPM4.5 is off mode and shutdown mode. Can the device be woken up from one of those modes by the use of a interrupt as done previously?

  • sigurd stoll said:

    Worked like a charm, would like to know why though. Does it have to to with the fact that I've used TA0CCTL0, TA0CCR0 and TA0CTL instead of the TA1CCTL0 etc. alternatives?

    Close, but not quite :)

    Each timer module has two interrupt vectors. For example, TimerA0 has TIMER0_A0_VECTOR and TIMER0_A1_VECTOR. The first is triggered by the CCIFG bit of TA0CCTL0, the other is triggered for TAIFG, as well as CCIFG for TA0CCTL1, TA0CCTL2, etc... The TIMER0_A1_VECTOR uses a special register called TA0IV to allow the ISR to find out which flag caused the interrupt to fire. Reading TA0IV also clears the IFG bit that triggered the interrupt.

    Since your program sets the CCIE bit of TA0CCTL0 it will try to trigger the TIMER0_A0_VECTOR when TA0R counts up to the value in TA0CCR0. Therefore you need to use TIMER0_A0_VECTOR.

    If you were using TA0CCTL1 you'd need to use TIMER0_A1_VECTOR instead, and would need to make sure the appropriate IFG bit got cleared before returning (reading TA0IV is an easy way to do that). If you were using TA1CCTL0, that's TimerA1 and the correct vector would be TIMER1_A0_VECTOR. For full details take a look at Section 17.2.6 of the MSP430x5xx and MSP430x6xx Family User's Guide.

    sigurd stoll said:

    Is it possible/advicable to use LPM4 or even LPM4.5 instead of LPM3? I've read something, somewhere about VLO can always be used on MSP430 5x families, but according to the datasheet for mye device LPM4 and LPM4.5 is off mode and shutdown mode. Can the device be woken up from one of those modes by the use of a interrupt as done previously?

    I'm not familiar with the 5x family, but it doesn't look promising. As far as I can tell the only way to wake from LPM4 or LPM4.5 is with a GPIO pin interrupt or by resetting the device.

  • Robert Cowsill said:
    I'm not familiar with the 5x family, but it doesn't look promising. As far as I can tell the only way to wake from LPM4 or LPM4.5 is with a GPIO pin interrupt or by resetting the device.

    Close, but not quite :)

    LPM4.5 shuts off everything, including ram retention, except for the plain port interupt logic. Not even the port registers are retained. After a port interrupt, the CPU starts as if after power-up, except that the port registers are jammed, and the port pins are locked in their current state, so you may reconfigure the registers before you unlock the connection between port registers and port logic.

    LPM4, however, tries to shut of ACLK in addition to SMCLK. Unless they are used unconditionally by a module (which would prevent entering LPM4, ending up in LPM3 or 2 instead). Of course, if ACLK isn't running, the timers aren't running. But you can still wakeup by I2C or SPI (slave) interrupt, ADC, comparator or whatever needs neitehjr SMCLK nor ACLK.

    sigurd stoll said:
    Is it possible/advicable to use LPM4 or even LPM4.5 instead of LPM3? I've read something, somewhere about VLO can always be used on MSP430 5x families

    Yes, VLO is always available. But since you cannot select VLO directly (but rather use VLO as souce to ACLK or SMCLK), LPM4 will still be between VLO and the peripherals. An exception is the watchdog timer, which can direcly use VLO as clock source. So you can use the WDT in interval mode (while losing watchdog protection against ESD crashes) and wake the MSP by the watchdog timer interrupt.

**Attention** This is a public forum