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.

CC430F5135 Interrupt Pending.

Other Parts Discussed in Thread: CC430F5135, CC1101

I am developing an application with a microcontroller CC430F5135. She is functional but there is still a bug to solve.
The MCU initializes the radio (RF1A) with no problems  started operation OK. I usa a CCSv4. por programing.

 Upon receiving a data packet it generates an interrupt RFIFG9. This is usually served!

In the next packet received by CC430 interruption does not happen because there is still a pending interrupt RFIF10

Radio to come back it to receive packages is necessary to effect flush of the reception buffer, but this is an alternative that did not decide the case electively. In I finish in case that reset of radio Core is necessary. The application eats alimpeza of the reception buffer wheel some days without problems. but, suddenly, constraint everything is and necessary to resetar the MCU. Sege below pieces of the code source to help in the solution of the problem.

/******************************************************************************

* @Função: Interrupção

* @Finalidade: interrupt routine.

* @parametros:

* Nenhum.

* @retorno:

* Nenhum.

*******************************************************************************/

#pragma

 

 

void CC1101_ISR(void)

{

__no_operation();

 

switch(__even_in_range(RF1AIV,32)) // Prioritizing Radio Core Interrupt

{

 

case 0: break; // No RF core interrupt pending

 

case 2: break; // RFIFG0

 

case 4: break; // RFIFG1

 

case 6: break; // RFIFG2

 

case 8: break; // RFIFG3

 

case 10: break; // RFIFG4

 

case 12: break; // RFIFG5

 

case 14: break; // RFIFG6

 

case 16: break; // RFIFG7

 

case 18: break; // RFIFG8

 

case 20:

ir=0;

// RFIFG9

 

if(receiving ) // RX end of packet

{

 

 

// Read the length byte from the FIFO

RxBufferLength = ReadSingleReg( RXBYTES );

ReadBurstReg(RF_RXFIFORD, RxBuffer, RxBufferLength);

__no_operation();

// Stop here to see contents of RxBuffer

RSSIVal=RxBuffer[RxBufferLength-2];

 

 

if (RSSIVal <= 128)

RSSIVal = (RSSIVal>>1) - 74;

 

else

RSSIVal = ((RSSIVal-256)>>1) - 74;

 

 

if((RxBuffer[RxBufferLength-1] & CRC_OK))

{

RF_PacoteRecebido=1;

ReceiveOff();

ReceiveOn();

}

 

else

{

ReceiveOff();

ReceiveOn();

__bic_SR_register_on_exit(GIE);

}

}

 

else if(transmitting) // TX end of packet

{

RF1AIE &= ~BIT9;

// Disable TX end-of-packet interrupt

transmitting = 0;

TXActive=0;

ReceiveOff();

ReceiveOn();

__bic_SR_register_on_exit(GIE);

// Exit active

}

 

else

{

 

while(1); // trap

}

 

 

break;

 

case 22: break; // RFIFG10

 

case 24: break; // RFIFG11

 

case 26: break; // RFIFG12

 

case 28: break; // RFIFG13

 

case 30: break; // RFIFG14

 

case 32: break; // RFIFG15

}

__bic_SR_register_on_exit(GIE);

}

vector=CC1101_VECTOR

__interrupt

 

 

 

 

 

 

 

 

 

 

 

 

 

//in to main function.

 

 

 

 

 

 

 

 

 

 

if((RF_PacoteRecebido==1))

{

         RF_PacoteRecebido=0/

 

         // It treats information. received from the RFA1

 

 

 

 

        ReceiveOn();

        receiving = 1;

        __bis_SR_register( GIE);

}

 

 

 

 

 

  • I don't see anything obvious in your code except this line:

    Davenir kohlrausch said:
    __bic_SR_register_on_exit(GIE);

    This means, after leaving the ISR, interrupts are globally disabled.
    That's bad programming style as it also disables timer interrupts and anyhting else.
    The correct way would be to clear the IE bit(s) that enables the particular interrupt(s) that belong to this ISR or this part of the ISR.
    And later in the code, set the required IE bits again and not GIE globally.

    You set GIE later in the 'start receive' if-case, so this is possibly not the cause of your problem. It is, however, suspicious and will likely cause problems when your project grows and you add other interrupt-driven functionality.

  • To add to Jens-Michael Gross' point, when you clear only the GIE bit when you exit from the ISR, you only disable the interrupt and still stay in the power mode [low power or active mode] that you were previously in prior to the interrupt. This could render the device permanently in the LPMx since no further interrupts/wake-up events can be serviced.

    Regards,

    Dung

  • So if the best bit is clear the only bit regarding the interrupt that has been met. Andbreak out of this:

    __bic_SR_register_on_exit (LPM_X);

    So my application back to the power mode requested. And there is the possibility todisable the global interrupt the process.

    Many thanks to colleagues will be implementing the adjustments.


    A hug the size of Brazil.

  • Davenir kohlrausch said:
    So if the best bit is clear the only bit regarding the interrupt that has been met.

    If you clear the IE bit, this means that the ISR won't be called anymore (which is the right thing to do if you don't want any more interrupts). If you jsut want to tell teh hardware module that the interrupt has been served, so this is done by clearing teh IFG bit that has been set due to the event. It will be set agian on the next event and (if the matching IE bit is still set) then cause another interrupt. Which is the wanted behavior in most cases (but not all). THE IF Gbit can be cleared by manually settin git to 0, but also automatically. Some interrupt swhich have only one interrupt source (like the TImer CCR0 itnerrupt) will automatically clear this bit once the ISR has been called. Also, reading the xxxIV register will not only return the topmost interrupt cause (for the switch statement), but at the same time clear the IFG bit associated with this. So the next read of this register will return the next interrupt cause (or 0 if no more unhandled events are pending). Writing to teh xxxIV registers will clear it and reset all IFG bits of this hardware module. However, some IFG bits cannot be reset without appropriate action. e.g. the TXIFG bits won't reset if you don't write something to TXBUF. Here you usually clear the IE bit if you don't have anything to send anymore, and set it again once you have something to send again.

    Davenir kohlrausch said:
    Andbreak out of this:
    __bic_SR_register_on_exit (LPM_X);

    If you want to exit an LPM after handling the interrupt (so that main will continue), yes. Clearign GIE a tthis point when no LPM was active before the interrupt won't hurt if you do not forget to enable it again when you need it. However, clearing GIE and not the LPM bits when an LPM was active will return to LPM on ISR exit and at the same time prevent that any ISR will be called again (eternal sleep).

    Good luck with your project.

  • Hello everyone!

    I changed my firmware according to the suggestions of the colleagues of the forum.
    However I still have problems with the wireless system.

        I am using the kit EM430F6137RF900 boards. Where a teacher needs to receive and transmit information to several slaves. Slaves initiates communication and master receives a frame with a request and responds with the requested information.

    The master works with an appreciable requncia requests, but when the master gets requests cease and no activity for a long time (hours). This fails to answer requests.

    As the routines posted in my first post, I was wandering in the treatment of interruptions, but now I'm doing the treatment properly. As can be seen in the attached Code.

     This program receives data by radio (RF1A) and relays the UART. And on the contrary, the UART receives and transmits data received through the radio.

    I'm really having problems getting the basics of the transceiver CC430Fxxxx work properly. I would like to help a fellow of the forum to solve this problem. What drives me crazy is the fact that the system works for a while and then stop working.

    Thanks to all.

     


    #pragma vector=CC1101_VECTOR
    __interrupt void CC1101_ISR(void)
    {
        switch(__even_in_range(RF1AIV,32))        // Prioritizing Radio Core Interrupt
        {
            case  0: break;                         // No RF core interrupt pending                                           
            case  2: break;                         // RFIFG0
            case  4: break;                         // RFIFG1
            case  6: break;                         // RFIFG2
            case  8: break;                         // RFIFG3
            case 10: break;                         // RFIFG4
            case 12: break;                         // RFIFG5
            case 14: break;                         // RFIFG6         
            case 16: break;                         // RFIFG7
            case 18: break;                         // RFIFG8
            case 20:                                // RFIFG9
            if(RF_RecebendoPacote)               // RX end of packet
            {
                // Read the length byte from the FIFO      
                RF_RxBufferLength = ReadSingleReg( RXBYTES );
                ReadBurstReg(RF_RXFIFORD, RF_RxBuffer, RF_RxBufferLength);
           
                // Stop here to see contents of RxBuffer
                __no_operation();

                // Check the CRC results
                if(RF_RxBuffer[CRC_LQI_IDX] & CRC_OK)
                {
                    RF_PacoteRecebido=1;

                }
                  
                 RF1AIES |= BIT9;                          // Falling edge of RFIFG9
                 RF1AIFG &= ~BIT9;                         // Clear a pending interrupt
                 RF1AIE  |= BIT9;                          // Enable the interrupt
            }
            else if( RF_TransmitindoPacote)           // TX end of packet
            {
               RF1AIES |= BIT9;                          // Falling edge of RFIFG9
                RF1AIFG &= ~BIT9;                         // Clear a pending interrupt
                RF1AIE  |= BIT9;                          // Enable the interrupt                  // Disable TX end-of-packet interrupt
                RF_TransmitindoPacote=0;
           
            }
            else while(1);              // trap
            break;
            case 22: break;                         // RFIFG10
            case 24: break;                         // RFIFG11
            case 26: break;                         // RFIFG12
            case 28: break;                         // RFIFG13
            case 30: break;                         // RFIFG14
            case 32: break;                         // RFIFG15
        }

        RF1AIES |= BIT9;                          // Falling edge of RFIFG9
        RF1AIFG &= ~BIT9;                         // Clear a pending interrupt
        RF1AIE  |= BIT9;                          // Enable the interrupt

    }

     

     

     

     

     

     

     
    /**************************************************************************************
     * Função:
     *
     * Descrição:
     *
     * Parametros de entrada: Nenhum
     *
     * Parametrose de saída: Nenhum
     *
    ***************************************************************************************/
    void Transmit(unsigned char *buffer, unsigned char length)
    {
        RF1AIES |= BIT9;                         
        RF1AIFG &= ~BIT9;                         // Clear pending interrupts
        RF1AIE |= BIT9;                           // Enable TX end-of-packet interrupt

        WriteBurstReg(RF_TXFIFOWR, buffer, length);

        Strobe( RF_STX );                         // Strobe STX
        RF_PacoteTransmitido=0;
        RF_TransmitindoPacote=1;
    }

    /**************************************************************************************
     * Função:
     *
     * Descrição:
     *
     * Parametros de entrada: Nenhum
     *
     * Parametrose de saída: Nenhum
     *
    ***************************************************************************************/
    void ReceiveOn(void)
    {
      Strobe( RF_SRX );
      RF1AIES |= BIT9;                          // Falling edge of RFIFG9
      RF1AIFG &= ~BIT9;                         // Clear a pending interrupt
      RF1AIE  |= BIT9;                          // Enable the interrupt

    RF_RecebendoPacote;

      // Radio is in IDLE following a TX, so strobe SRX to enter Receive Mode
      Strobe( RF_SRX );
    }

    void main(void) {
        // Stop watchdog timer to prevent time out reset
        WDTCTL = WDTPW + WDTHOLD;

        // Increase PMMCOREV level to 2 for proper radio operation
        SetVCore(2);
     
        ResetRadioCore();
        InitRadio();

        ReceiveOn();
        receiving = 1;
        UART_Config(1);

         __bis_SR_register( LPM3_bits + GIE );

        while(1)
        {

           
            if(RF_PacoteRecebido)//Recebido pacote pelo radio
            {
                RF_PacoteRecebido=0;
                UART_PutString(RF_RxBuffer,RF_RxBufferLength-2);

     
             ReceiveOff();       //FLUSH
             ReceiveOn();

            }

         if(UART_PacoteRecebido)//Recebido Pacote pela UART.
          {

          UART_PacoteRecebido=0;
            ReceiveOff();
            receiving = 0;

            RF_TransmitindoPacote=1;

            Transmit(UART_BUFFER,UART_BUFFER_LEN);
            while(RF_TransmitindoPacote);

            }
        }

    }

     

  • I believe that it is making all the procedure of treatment of interrupões of correct form, then why the radio this stopping to function? Exists lagum detail that I am forgetting?

  • In your ISR, you three times configure the interrupt. All three times you enable the same interrupt after setting the same edge and clearing pending interrupt flags.
    First, this is superfluous. YOu don'T need to configure this in the if and else cases if you do it at the end of the ISR anyway.
    Then it does not match the comments. The second instance the comment is 'disable'. However, if you'd disable the interrupt here, it ould be enabled by teh third instance at the end of the ISR.

    Then, it is not a good idea to generally clear pending interrupts. I don'T know what your expected flow is, but it might be that there already was an event you might want to react to, while you are executing your ISR. YOu should check whether this might happen. Only you can know.

    I'm totally unexperienced with the RF part, so I cannot help you with a deeper analysis.

**Attention** This is a public forum