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.

Continuous reset generated after Timer_A ISR actioned - MSP430FG4619

Other Parts Discussed in Thread: MSP430FG4619

Hi all,

I'm a relative newbie with the MSP430. After 5 days solid debugging, and googling, I'm beginning to get to know the 430 and IAR IDE.
- My wife thinks I'm getting to know it too well!

I'm playing with a software RTC on the Olimex MSP430-4619LCD development board connected to an alphanumeric character display on Port 10. I know, the MSP430FG461x has it's own RTC, but a) it has it's own bugs, b) I'll possibly not use this device in any final project.

I've managed to get the character display to show static text, no problem. When I implement the Timer_A ISR for the RTC, the device resets after actioning the ISR, i.e. it resets at or close to the Timer_A (1sec) interval, and after displaying the initialised time. (Code below.)

I'm using the 'typical clock' application from SLAA290.pdf (Using the Real-Time-Clock Library), modified as per slap116.pdf (Timer_A Presentation 2006).

The dev board has a functioning 32,768Hz crystal on XIN/XOUT. I checked this using the buffered ACLK (32,768Hz) and MCLK (~2MHz) outputs on Port 1.5 and 1.1 respectively.

I'm using IAR Kickstart V4 - from slac050t.zip.

 

In this related Timer_A thread:

http://community.ti.com/forums/p/873/7684.aspx
Chrispy says, "I've also found that the ISR is only executed when I place a breakpoint within the ISR.  Otherwise the ISR does not execute.  Very strange."

That's exactly the symptom I'm seeing. The difference between that thread and my problem is I have a 32768Hz XTAL.

 

After reading about EMI problems, I checked the RST pin - it's always high.

 

I moved the 'display-writing' code from the while(1) loop to the Timer_A ISR. When I put a break in the ISR, I can see the TI_second variable is incremented and written to the display. Watching the registers, I've also noticed the WDTIFG in the IFG1 Special Function register changes from 0 to 1 after I initiate a reset (even though the WDT is stopped.) Is this normal?

 

I tried using a "__low_level_init(void)" - made no difference.

 

My only thought now is the bug notified in slaz028h.pdf (MSP430FG461x Device Erratasheet ) is responsible :

TA12 TA12 - Bug description
Module: Timer_A, Function: Interrupt is lost (slow ACLK)

Timer_A counter is running with slow clock (external TACLK or ACLK) compared to MCLK. The
compare mode is selected for the capture/compare channel and the CCRx register is incremented
by 1 with the occurring compare interrupt (if TAR = CCRx). Due to the fast MCLK, the CCRx
register increment (CCRx = CCRx + 1) happens before the Timer_A counter has incremented
again. Therefore, the next compare interrupt should happen at once with the next Timer_A counter
increment (if TAR = CCRx + 1). This interrupt is lost.

Workaround:
Switch capture/compare mode to capture mode before the CCRx register increment. Switch back
to compare mode afterwards.

 

I don't quite understand how to implement the above workaround. I had a go in the code below, but it made no difference.

 

Thanks for any suggestions.

Cheers, hairy_kiwi


//------------- ALPHANUMERIC DISPLAY RTC ---------------//

#include "msp430xG46x.h"
#include "RTC_Calendar.h"
#include "LCD_AlphaNumeric_4_20.h"

//Define global variables
..
//

void main ( void )
{
  // Watchdog Timer //
  WDTCTL = WDTPW + WDTHOLD;                                 // Stop watchdog timer     write WDTCTL =  0x5A80; READ as: 0x6980

  // FLL+ Control Register 0 //
  FLL_CTL0 |= DCOPLUS + XCAP18PF;                           // DCO+ set so freq = xtal 2 x N+1 (Where SCFQCTL is set with N), Oscillator capacitor ~18 pF

  // System Clock Control Register //
  SCFQCTL = 30;                                             // fDCOCLK = (N + 1) * fcrystal ~ fDCOCLK = (30+1) * 32768  = 2 031 616 Hz ~ 2MHz

  // FLL+ Control Register 1 //
  FLL_CTL1 = SMCLKOFF + XT2OFF + SELM0 + FLL_DIV_1;         // SMCLK off, XT2 off, DCO for main oscilator, ACLK By 1

  P1DIR |= 0x66;                                            // Test Purposes ONLY - P1.1, 1.2, 1.4, 1.5 outputs
  P1SEL |= 0x36;                                            // Test Purposes ONLY - Configure outputs P1.1 = MCLK, P1.2 = TA1 (Not Used), 1.4 = TBCLK, 1.5 = ACLK

  LCD_InitPort();
  LCD_Init();

  // Until LFXTL is stable, wait, by continuosly clearing the OSCFault flag //
  int f;
  do
  {
  IFG1 &= ~OFIFG; // Clear OSCFault flag
  for (f = 0xFF; f > 0; f--);                               // Time for flag to set
  }
  while ((IFG1 & OFIFG));                                   // OSCFault flag still set?



  setTime( 0x12, 0x11, 0x24, 1 );                    //initialise time to 12:00:00 AM
  setDate( 2008, 12, 15 );
   


  /* From Slau290 Documentation **************************
  CCR0 = 32768-1;
  TACTL = TASSEL_1 + MC_1;                            //Timer A clock source select: 1 - ACLK, UP Mode
  CCTL0 |= CCIE;                        //enable CCR0 interupt
  _EINT();
  */

 
  /* From Timer A Presentation **************************
  TACTL = TASSEL_1 + TACLR;                            //Clock = ACLK(32768), Clear
  TACCTL0 |= CCIE;                        //CCR0 interupt enabled
  TACCR0 = 32768-1;                            //Number of counts for 1s
  TACTL |= MC_1;                        //Setting Mode Bits starts timer
  _BIS_SR(GIE);
  */


  // Timer A Presentation - TRIAL MODIFICATION as per Errata - DOESN'T HAVE DESIRED EFFECT
  TACTL = TASSEL_1 + TACLR;                            //Clock = ACLK(32768), Clear
  TACCTL0 |= CCIE;                                    //CCR0 interupt enabled
  TACCTL0 |= CAP;                                           // Enable capture Mode - Here???
  TACCTL0 |= CM0;                                           //Capture on rising edge
  TACCR0 = 32768-1;                            //Number of counts for 1s
  TACTL |= MC_1;                        //Setting Mode Bits starts timer
  TACCTL0 &= ~CAP;                                          //No capture  - Here???
  TACCTL0 &= ~CM0;                                          //No capture  - Here/Required???
  _BIS_SR(GIE);



  while( 1 )
  {
    LPM3;
    _NOP();                                                          //Only for debug
  }
}


//Timer A0 Interrupt Service Routine
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
  incrementSeconds();
  //Output code placed here to see SOMETHING on display
  BCDtoStr(TI_second,TimeStringSecs);                      
  LCD_PosnCursor ( LCD_Line_1 );
  LCD_Print( TimeStringSecs );
  LPM3_EXIT;
}

  • Update.

    I tried the code example in TI's "msp430x20x3_ta_05.c", (Timer_A, Toggle P1.0, CCR0 Up Mode ISR, 32kHz ACLK) with the addition of the RTC in an ez430-F2013 and, unsurprisingly, it works; TI_second increments.

    If I run identical code in the MSP430FG4619, (with correct includes) I see TI_second increments once then the device resets, (continuously) as per my first post.

     

    I then ran the code in simulation mode for both devices. The 2013 works fine. The MSP430FG4619 generated the following error:

    "User error: Instruction found on an odd address 219"


    Then I came across this thread: https://community.ti.com/forums/t/2081.aspx . So I installed the latest kickstart version 4.20.1 (4.20.1.50017). Made no difference.

     

    I generated a linker listing, (below) which shows the correct address for the interrupt as per the MSP430xG461x datasheet :

    INTVEC
      Common segment, address: FFC0 - FFED (0x2e bytes), align: 1
      Segment part 13. ROOT.
               ENTRY                   ADDRESS         REF BY
               =====                   =======         ======
               Timer_A::??INTVEC 44    FFEC

     

    So what am I doing wrong?

     

    Thanks again for reading.

  • Cracked it! It appears to be a Stack Pointer error.

    I added "asm("INCD SP");" to the Timer_A interrupt, immediately before the closing brace. (This worked in IAR but CCE didn't like "INCD", but I probably don't have the latest version of CCE.)

     

    But shouldn't the assembler take care of this???

**Attention** This is a public forum