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.

CCS/MSP430FR5949: Debugger stuck on function call

Part Number: MSP430FR5949

Tool/software: Code Composer Studio

Hi,

I'm starting to develop a fairly simple code for MSP430FR5949. I started by creating some functions libraries and then the main file. After some basic configurations (which I still not know very well), imported from other projects, I call some functions to configure the RTC current time, i2c pins, etc. Thing is: the MSP stops when calling any of these functions. I've put breakpoints whenever I call any functions and on each function's first line, and realized that the MSP seems to call the function, but do not execute the function first line, it goes somewhere esse instead. When I pause the execution, most of the times it is at ZI_FUNCTION, stuck at the loop while at the last line. I can't understand why it cannot call any function properly.

Code:

#include <msp430.h>
#include <stdio.h>
#include <string.h>
#include "serial.h"
#include "serialparalelo.h"
#include "i2c.h"
#include "controlador.h"

volatile uint16_t cont_timeout_rx;
volatile uint16_t ind_rx0, ind_rx1, cont_rx0, cont_rx1;
volatile uint8_t uart = 1;
volatile uint8_t rx0_buff[tmn_buffer_rx0], rx1_buff[tmn_buffer_rx1];
// RTC
uint8_t current_time[6] = {0,0,0,0,0,0};
// I2C variable
volatile uint16_t i2c_timeout = 0;
// Variaveis noinit e persistent na FRAM
#pragma SET_DATA_SECTION(".TI.noinit")
Controle controlador;
#pragma SET_DATA_SECTION(".TI.persistent")
volatile uint16_t counter_plan = 0;
#pragma SET_DATA_SECTION()

#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer_A (void)
{
 if(counter_plan)
  counter_plan--;
 if(i2c_timeout)
  i2c_timeout--;
}

//  Timer B0
#pragma vector = TIMER0_B0_VECTOR
__interrupt void Timer_B0_ISR (void)
{
 TB0CTL  &= ~(TBIE);
}
// UART 0
#pragma vector = USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)  // MODEM
{
 UCA0IFG &= ~UCRXIFG;                      // Clear interrupt
 rx0_buff[ind_rx0]=UCA0RXBUF;
 ind_rx0++;
 if(ind_rx0==tmn_buffer_rx0)
  ind_rx0=0;
 cont_timeout_rx=0;      // limpa o cont_time_rx
}
//  UART 1
#pragma vector = USCI_A1_VECTOR
__interrupt void USCI_A1_ISR(void)  //USB
{
 UCA1IFG &=~ UCRXIFG;                      // Clear interrupt
 rx1_buff[ind_rx1]=UCA1RXBUF;
 ind_rx1++;
 if(ind_rx1==tmn_buffer_rx1)
     ind_rx1=0;
 cont_timeout_rx=0;
}

// Functions
void set_time()
{
 RTCCTL01 |= RTCHOLD;                    // Stop RTC calendar
 RTCYEAR = current_time[2];           // Year
 RTCMON = current_time[1];               // Month
 RTCDAY = current_time[0];               // Day
 //RTCDOW = 0x01;               // Day of week = 0x01 = Monday
 RTCHOUR = current_time[3];           // Hour
 RTCMIN = current_time[4];               // Minute
 RTCSEC = current_time[5];            // Seconds
 RTCCTL01 &= ~(RTCHOLD);           // Start RTC calendar mode
}
///////////////////////////////////////////////////////////////////////////
void get_time(void)
{
 while(!(RTCCTL01 & RTCRDY));
 current_time[2] = RTCYEAR;           // Year
 current_time[1] = RTCMON;            // Month
 current_time[0] = RTCDAY;            // Day
 // RTCDOW = 0x01;                   // Day of week = 0x01 = Monday
 current_time[3] = RTCHOUR;           // Hour
 current_time[4] = RTCMIN;            // Minute
 current_time[5] = RTCSEC;            // Seconds
}


int main(void)
{
 WDTCTL = WDTPW + WDTHOLD; // Stop WDT
 PM5CTL0 &= ~LOCKLPM5;
 // FRAM Configuração
 //FRCTL0_H = 0XA5;  // Unlock FRAM registers
 //FRCTL0_L = NWAITS0;
 //FRCTL0_H = 0;
 //Clock Configuration
 CSCTL0_H = 0xA5;                                        // Unlock clock registers
 CSCTL1 = DCOFSEL_3 | DCORSEL;                           // Set DCO to 8MHz
 CSCTL2 = SELA__LFXTCLK | SELS__DCOCLK | SELM__DCOCLK;   // ACLK = SMCLK = MCLK = DCO
 CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;                   // f(ACLK)/1; f(SMCLK)/1; f(MCLK)/1
 CSCTL0_H = 0;                                           // Lock CS registers
 //---
 /*  Px.7 Px.6 Px.5 Px.4 Px.3 Px.2 Px.1 Px.0    */
 PJDIR = 0b00000000;
 P1DIR = 0b00000000;
 P2DIR = 0b00000000;
 P3DIR = 0b00000000;

 // TimerA Configuration
 TA0CCTL0 = CCIE | CAP;     // TACCR0 interrupt enabled, compare mode
 TA0CCR0 = 12500;         // Timer A counts until 12500 (12500 = 100ms)
 TA0CTL = TASSEL_2 | MC_1 | ID_3; // SMCLK, up mode, TCLK/8
 TA0EX0 |= TAIDEX_7;        // TCLK/8


 // TimerB Configuration
 TB0CCTL0 = CCIE; // TBCCR0 interrupt enabled
 TB0CTL= MC_0;
 // UART0 Configuration
 P2SEL0 &= ~(BIT0 + BIT1); //Pins P2.0 e P2.1 as UART
 P2SEL1 |= BIT0 + BIT1; //Pins P2.0 e P2.1 as UART
 UCA0CTLW0 = UCSWRST;                      // Put eUSCI in reset
 UCA0CTLW0 |= UCSSEL__SMCLK;               // BRCLK = SMCLK
 UCA0BR0 = 52;                             // int(BRCLK/16/9600)
 UCA0BR1 = 0x00;
 UCA0MCTLW |= UCOS16 | UCBRF_1;
 UCA0CTLW0 &= ~UCSWRST;                    // Initialize eUSCI
 UCA0IE |= UCRXIE;                         // Enable USCI_A1 RX interrupt
 //---
 // UART1 Configuration
 P2SEL0 &= ~(BIT5 + BIT6); //Pins P2.5 e P2.6 as UART
 P2SEL1 |= BIT5 + BIT6; //Pins P2.5 e P2.6 as UART
 UCA1CTLW0 = UCSWRST;                      // Put eUSCI in reset
 UCA1CTLW0 |= UCSSEL__SMCLK;               // BRCLK = SMCLK
 UCA1BR0 = 52;                             // int(BRCLK/16/9600)
 UCA1BR1 = 0x00;
 UCA1MCTLW |= UCOS16 | UCBRF_1;
 UCA1CTLW0 &= ~UCSWRST;                    // Initialize eUSCI
 UCA1IE |= UCRXIE;                         // Enable USCI_A1 RX interrupt
 //RTC Configuration
 PJSEL1 &= ~(BIT4 + BIT5);
 PJSEL0 |= BIT4 + BIT5;
 __bis_SR_register(GIE);   // Habilita interrupção global
 current_time[0] = 17;
 current_time[1] = 1;
 current_time[2] = 16;
 current_time[3] = 19;
 current_time[4] = 55;
 current_time[5] = 00;

 set_time();  // it usually stops execution here
 i2c_init();
 serialparalelo_init();

Code goes on...

  • Hi Marco,

    The only information I have on ZI_FUNCTION:

    Clearly you are not supposed to be stuck in this loop.  Try reducing your code until it gets to a working state, then add on functionality until it breaks again.  You can use this information to further debug the specific issue at hand.  For example, this simplified version of your code correctly accesses the set_time(); function.

    #include <msp430.h>
    #include <stdint.h>
    #include <stdio.h>
    #include <string.h>
    
    volatile uint16_t cont_timeout_rx;
    volatile uint16_t ind_rx0, ind_rx1, cont_rx0, cont_rx1;
    volatile uint8_t uart = 1;
    volatile uint8_t tmn_buffer_rx0 = 128, tmn_buffer_rx1 = 128;
    volatile uint8_t rx0_buff[128], rx1_buff[128];
    // RTC
    uint8_t current_time[6] = {0,0,0,0,0,0};
    // I2C variable
    volatile uint16_t i2c_timeout = 0;
    // Variaveis noinit e persistent na FRAM
    #pragma SET_DATA_SECTION(".TI.persistent")
    volatile uint16_t counter_plan = 0;
    #pragma SET_DATA_SECTION()
    
    #pragma vector = TIMER0_A0_VECTOR
    __interrupt void Timer_A (void)
    {
     if(counter_plan)
      counter_plan--;
     if(i2c_timeout)
      i2c_timeout--;
    }
    
    //  Timer B0
    #pragma vector = TIMER0_B0_VECTOR
    __interrupt void Timer_B0_ISR (void)
    {
     TB0CTL  &= ~(TBIE);
    }
    // UART 0
    #pragma vector = USCI_A0_VECTOR
    __interrupt void USCI_A0_ISR(void)  // MODEM
    {
     UCA0IFG &= ~UCRXIFG;                      // Clear interrupt
     rx0_buff[ind_rx0]=UCA0RXBUF;
     ind_rx0++;
     if(ind_rx0==tmn_buffer_rx0)
      ind_rx0=0;
     cont_timeout_rx=0;      // limpa o cont_time_rx
    }
    //  UART 1
    #pragma vector = USCI_A1_VECTOR
    __interrupt void USCI_A1_ISR(void)  //USB
    {
     UCA1IFG &=~ UCRXIFG;                      // Clear interrupt
     rx1_buff[ind_rx1]=UCA1RXBUF;
     ind_rx1++;
     if(ind_rx1==tmn_buffer_rx1)
         ind_rx1=0;
     cont_timeout_rx=0;
    }
    
    // Functions
    void set_time()
    {
     RTCCTL01 |= RTCHOLD;                    // Stop RTC calendar
     RTCYEAR = current_time[2];           // Year
     RTCMON = current_time[1];               // Month
     RTCDAY = current_time[0];               // Day
     //RTCDOW = 0x01;               // Day of week = 0x01 = Monday
     RTCHOUR = current_time[3];           // Hour
     RTCMIN = current_time[4];               // Minute
     RTCSEC = current_time[5];            // Seconds
     RTCCTL01 &= ~(RTCHOLD);           // Start RTC calendar mode
    }
    ///////////////////////////////////////////////////////////////////////////
    void get_time(void)
    {
     while(!(RTCCTL01 & RTCRDY));
     current_time[2] = RTCYEAR;           // Year
     current_time[1] = RTCMON;            // Month
     current_time[0] = RTCDAY;            // Day
     // RTCDOW = 0x01;                   // Day of week = 0x01 = Monday
     current_time[3] = RTCHOUR;           // Hour
     current_time[4] = RTCMIN;            // Minute
     current_time[5] = RTCSEC;            // Seconds
    }
    
    int main(void)
    {
        WDTCTL = WDTPW + WDTHOLD; // Stop WDT
         PM5CTL0 &= ~LOCKLPM5;
         // FRAM Configuração
         //FRCTL0_H = 0XA5;  // Unlock FRAM registers
         //FRCTL0_L = NWAITS0;
         //FRCTL0_H = 0;
         //Clock Configuration
         CSCTL0_H = 0xA5;                                        // Unlock clock registers
         CSCTL1 = DCOFSEL_3 | DCORSEL;                           // Set DCO to 8MHz
         CSCTL2 = SELA__LFXTCLK | SELS__DCOCLK | SELM__DCOCLK;   // ACLK = SMCLK = MCLK = DCO
         CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;                   // f(ACLK)/1; f(SMCLK)/1; f(MCLK)/1
         CSCTL0_H = 0;                                           // Lock CS registers
         //---
         /*  Px.7 Px.6 Px.5 Px.4 Px.3 Px.2 Px.1 Px.0    */
         PJDIR = 0b00000000;
         P1DIR = 0b00000000;
         P2DIR = 0b00000000;
         P3DIR = 0b00000000;
    
         // TimerA Configuration
         TA0CCTL0 = CCIE | CAP;     // TACCR0 interrupt enabled, compare mode
         TA0CCR0 = 12500;         // Timer A counts until 12500 (12500 = 100ms)
         TA0CTL = TASSEL_2 | MC_1 | ID_3; // SMCLK, up mode, TCLK/8
         TA0EX0 |= TAIDEX_7;        // TCLK/8
    
    
         // TimerB Configuration
         TB0CCTL0 = CCIE; // TBCCR0 interrupt enabled
         TB0CTL= MC_0;
         // UART0 Configuration
         P2SEL0 &= ~(BIT0 + BIT1); //Pins P2.0 e P2.1 as UART
         P2SEL1 |= BIT0 + BIT1; //Pins P2.0 e P2.1 as UART
         UCA0CTLW0 = UCSWRST;                      // Put eUSCI in reset
         UCA0CTLW0 |= UCSSEL__SMCLK;               // BRCLK = SMCLK
         UCA0BR0 = 52;                             // int(BRCLK/16/9600)
         UCA0BR1 = 0x00;
         UCA0MCTLW |= UCOS16 | UCBRF_1;
         UCA0CTLW0 &= ~UCSWRST;                    // Initialize eUSCI
         UCA0IE |= UCRXIE;                         // Enable USCI_A1 RX interrupt
         //---
         // UART1 Configuration
         P2SEL0 &= ~(BIT5 + BIT6); //Pins P2.5 e P2.6 as UART
         P2SEL1 |= BIT5 + BIT6; //Pins P2.5 e P2.6 as UART
         UCA1CTLW0 = UCSWRST;                      // Put eUSCI in reset
         UCA1CTLW0 |= UCSSEL__SMCLK;               // BRCLK = SMCLK
         UCA1BR0 = 52;                             // int(BRCLK/16/9600)
         UCA1BR1 = 0x00;
         UCA1MCTLW |= UCOS16 | UCBRF_1;
         UCA1CTLW0 &= ~UCSWRST;                    // Initialize eUSCI
         UCA1IE |= UCRXIE;                         // Enable USCI_A1 RX interrupt
         //RTC Configuration
         PJSEL1 &= ~(BIT4 + BIT5);
         PJSEL0 |= BIT4 + BIT5;
         __bis_SR_register(GIE);   // Habilita interrupção global
         current_time[0] = 17;
         current_time[1] = 1;
         current_time[2] = 16;
         current_time[3] = 19;
         current_time[4] = 55;
         current_time[5] = 00;
    
         set_time();  // it usually stops execution here
    }

    Regards, Ryan

  • Thanks for your fast answer Ryan.

    My work mate did exactly as you recommended and she tracked the error to the Controle struct. It seems that whenever we assign any value to a Controle's variable or its variables, the program stops at the first function in main's code (set_time() in our case). Funny thing: even if we assign a value to one of its variables at the bottom of the code, it get stuck.

    Edit:

    Posting both structs:

    typedef struct
    {
      // unsigned int ngrupos;
      uint16_t nestagios;
      uint16_t estado;
      unsigned char nome[SIZENAME];
      uint8_t flag_agendamento;
      uint8_t ano_esp, mes_esp, dia_esp, hora_esp, min_esp;
      uint8_t hora_ini, minuto_ini, segundo_ini, dow;
      Grupo estagios[NMAXPSTAG][NMAXPGRPS];
      uint16_t duracao[NMAXPSTAG];
      uint16_t defasagem;
    } Plano;
    typedef struct
    {
      uint8_t ngrupos;
      uint8_t conflitos[15];
      uint8_t nplanos;
      uint8_t estado;
      uint8_t erro;
      Plano planos[10];
    } Controle;

    We managed to get the code running by decreasing the number of planos' vector to 4, but we're not sure why.

    Right now, the only thing that comes is that the amount of memory used may be too much.

  • I'm glad to hear that the problem has been narrowed to variable assignments. I would have expected a compiler error if the array memory exceeded what was allowed, but you could further investigate your MAP file to verify the memory contents. This could also be a stack overflow issue since the problem occurs during a function call.

    Regards,
    Ryan
  • Yeah.
    We moved most of the variables (including the structs) to the FRAM mem and the program is running.
    I can only think that it was a stack overvlow problem.

    Regards,
    Marco

**Attention** This is a public forum