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.

Why does the program run to the position of 0x3FFE?

Other Parts Discussed in Thread: RF430FRL152H, TPS22919

My program is like this, I use TimerA0_ISR to count every second, every 5 minutes will start VDD2X for 30 seconds and then turn off VDD2X. While VDD2X outputs 3V for 30 seconds I will read the ADC value at the 10th second.
But the program will crash after running for a period of time. After I debug with CCS, I found that the return address of the program has been changed to 0x3FFE, so the program cannot return to the normal execution program after the execution of TimerA0_ISR.

I would like to ask why the return address becomes 0x3FFE, and what are the possible reasons for the return address to be changed?
Does the stability of the VDDSW voltage affect the return address? ??
Does 0x3FFE have any special meaning in memory locations?

  • Hello Chen, 

    Please indicate what processor you are using. 

    Thank you,

    ~Leonard  

  • I use RF430FRL152H

  • Below is a snippet of my program for your reference.
    The main reason is that when I set P1.3 to output 1 to enable TPS22919 SC70-6, it may happen that the subsequent program execution will jump to 0x3FFE, causing the program to fail to execute correctly. But the timing of TimerA0 can still work, but it will jump to 0x3FFE after leaving TimerA0_ISR.

    #pragma vector = TIMER0_A0_VECTOR
    __interrupt void TimerA0_ISR(void)
    {
    nfc_sys_data.timerCnt += 1;
    cgmMsgHeader.timer_sec += 1;

    if(nfc_sys_data.timerCnt >= INTERVAL_TIMER_MINUTE) {
    nfc_sys_data.timerCnt = 0;
    nfc_sys_data.adcProc_Start = 1;
    nfc_sys_data.State = START_SETUP_STATE;
    __bic_SR_register_on_exit(LPM3_bits); //exit LPM mode after this interrupt

    cgmMsgHeader.timer_sec = 0;
    }

    if(nfc_sys_data.V_DOUB_flag) {
    nfc_sys_data.V_DOUB_time += 1;
    __bic_SR_register_on_exit(LPM3_bits); //exit LPM mode after this interrupt
    }

    if(nfc_sys_data.State == ADC1_KEEP_STATE) {
    nfc_sys_data.ADC1_keepTime += 1;
    }

    if(nfc_sys_data.State == IDLE_STATE) {
    nfc_sys_data.Vdd2x_keepTime += 1;
    }

    {
    // WatchDog timer counter reset
    WDTCTL = WDTPW + WDTIS0 + WDTIS1 + WDTCNTCL + WDTSSEL0;
    }

    if(nfc_sys_data.adcProc_Start == 0)
    {
    Vdd2x_Setting(0);
    }

    }

    void adcProcess(void)
    {
    switch(nfc_sys_data.State) {
    case START_SETUP_STATE: //step 1
    Vdd2x_Setting(1);
    nfc_sys_data.State = ADC1_REFERENCE_SAMPLE_STATE; //goto step 2
    break;
    case ADC0_SAMPLE_STATE: //step 5
    // Set and Read ADC0
    SetupSD14(ADC0_CHANNEL);
    delay_cycles_ms(DELAY_CYCLE_CNT);
    while(!(SD14CTL0 & SD14IFG)) {
    };
    //delay_cycles_ms(128);
    nfc_sys_data.ADC0_Buffer = SD14MEM0;
    SD14CTL0 &= ~SD14IFG; // clear the data available interrupt
    nfc_sys_data.State = ADC_SAVE_STATE; //goto step 6
    break;
    case ADC1_REFERENCE_SAMPLE_STATE: //step 2
    SetupSD14(REFERENCE_ADC1_CHANNEL);//setup ADC and start the conversion
    while(!(SD14CTL0 & SD14IFG)) {
    };
    SD14CTL0 &= ~SD14IFG; // clear the data available interrupt
    nfc_sys_data.ADC1_keepTime = 0;
    nfc_sys_data.State = ADC1_KEEP_STATE; //goto step 3
    break;
    case ADC1_KEEP_STATE: //step 3
    if( nfc_sys_data.ADC1_keepTime >= ADC1_KEEP_TIME) {
    nfc_sys_data.State = ADC2_THERMISTOR_SAMPLE_STATE; //goto step 4
    }
    break;
    case ADC2_THERMISTOR_SAMPLE_STATE: //step 4
    SetupSD14(THERMISTOR_ADC2_CHANNEL); //setup ADC and start the conversion
    delay_cycles_ms(DELAY_CYCLE_CNT);
    while(!(SD14CTL0 & SD14IFG)) {
    };
    nfc_sys_data.ADC2_Buffer = SD14MEM0;
    SD14CTL0 &= ~SD14IFG; // clear the data available interrupt
    nfc_sys_data.State = ADC0_SAMPLE_STATE; //goto step 5
    break;
    case ADC_SAVE_STATE: //step 6
    {
    // Save ADC data to FRAM
    updateADCData();
    updateHeaderDataCnt();
    }
    nfc_sys_data.Vdd2x_keepTime = 0;
    nfc_sys_data.State = IDLE_STATE; //goto step 7
    break;
    case IDLE_STATE: //step 7
    if(nfc_sys_data.Vdd2x_keepTime >= Vdd2x_KEEP_TIME)
    {
    DisableSD14();
    Vdd2x_Setting(0);
    nfc_sys_data.adcProc_Start = 0;
    }
    default:
    break;
    }
    }


    void Vdd2x_Setting(u08_t enable)
    {
    RFPMMCTL0 = PMMPW; //Unlock RFPMM
    RFPMMCTL0_L |= RFPMM_EN_BATSWITCH; //Enable the battery switch
    if(enable == 1) {
    RFPMMCTL0_L |= RFPMMCTL0EN_VFREG_VDOUB;
    nfc_sys_data.V_DOUB_flag = 1;
    nfc_sys_data.V_DOUB_time = 0;
    } else {
    RFPMMCTL0_L &= ~RFPMMCTL0EN_VFREG_VDOUB;
    nfc_sys_data.V_DOUB_flag = 0;
    }
    RFPMMCTL0_H |= 0xFF; //Lock RFPMM

    //Set pin 1.3 to output -(Enable/Disable VDD2x)
    P1DIR |= 0x08;
    //Toggle Output High/Low
    P1OUT = (enable<<3);
    }

  • I tried to analyze this situation myself and found that if I remove the TPS22919 SC70-6 first to decouple the load behind the RF430FRL152H and the TPS22919 SC70-6, that is, if I don’t control the output of the TPS22919 SC70-6 first, the program jump will not occur. 0x3FFE.
    So I am guessing whether the instantaneous load current is too large to cause stack confusion.

    Schematic.pdf