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.

CC430 WOR Problem Using RX_TIMEOUT/LNA_PD Interrupt

I have an ISR based on the solution I found in Dung Dang's Application Report SLAA459 to handle WOR on the CC430.  I have it set up so that the EVENT0 interrupt enables the 'packet complete' and the 'LNA_PD' interrupt.  The idea from the App Note is that the WOR EVENT0 interrupt will enter RX mode.  Then, either the RX_TIMEOUT will trigger if no packets arrive, or the 'packet complete' will trigger if a packet arrives while it is awake.  In theory this makes sense, however I am struggling to make it work.

It seems like when a packet arrives, both the 'packet complete' and LNA_PD flags are set, and since LNA_PD is a higher priority interupt it is serviced first.  So it is as if it always times out.  I added a check to the LNA_PD interrupt to see if the packet complete flag is set, and if so to handle it instead, however I would like verificatio that that will do what I expect, since it is different from the App Note.

A difference from the example code is that my bit rate is only 1.2k.  That might make a difference.... not sure.   Any Ideas???

/*
* WirelessInterrupt.cpp
*
*/
#include "io430.h"
#include "CC1101Interrupt.h"
#include "CC1101.h"
#include <stdint.h>
#include "Led.h"
#include "Event.h"
#include "Packet.h"
extern Led ErrorLed;
static unsigned char buffer[16];
//CircularBuffer<uint16_t,32> ifgbuff;
//CircularBuffer<uint16_t,32> ifgivbuf;
//uint16_t ie;
//uint16_t ifg;
//uint16_t ifg2;
char LEN;
void CC1101Interrupt::ISR() {
// Read and clear interrupt vectors
uint16_t ifiv = RF1AIFIV;
uint16_t iv = RF1AIV;
unsigned char temp;

//ie = RF1AIE;
//ifg = RF1AIFG;
//ifgbuff.putData(ifg);
//ifgivbuf.putData(iv);

// Handle Radio Interface Interrupts
switch (ifiv){
case RF1AIFIV_NONE:
break;
case RF1AIFIV_RFERRIFG:
////// Should never get here //////////
temp = RF1AIFERRV;
RF1AIFERRV = temp;

// ErrorLed.on();

switch (temp){
case RF1AIFERRV_LVERR:
// while(1);
break;
case RF1AIFERRV_OPERR:
// while(1);
break;
case RF1AIFERRV_OUTERR:
// while(1);
break;
case RF1AIFERRV_OPOVERR:
// while(1);
break;
default:
break;
}
// while(1);
break;
case RF1AIFIV_RFDOUTIFG:
/* Data is available from the radio core. If we requested a specific data then return it to the user.
* If it is data from a complete packet, then build up the packet and send it when done.
*/
break;
case RF1AIFIV_RFSTATIFG:
/* Status was updated, if this interrupt is on, then update the status variable. The variable
* should only be read while holding a mutex
*/
break;
case RF1AIFIV_RFDINIFG:
/* The radio core is ready for data, if there is any in the outgoing pipe then add it to the
* fifo in the radio core.
*/
break;
case RF1AIFIV_RFINSTRIFG:
/* The radio core is ready for an instruction
*/
break;
case RF1AIFIV_RFRXIFG:
break;
case RF1AIFIV_RFTXIFG:
break;
default:
break;
}
// Handle Radio Core Interrupts
switch (iv){
case RF1AIV_NONE:
break;
case RF1AIV_RFIFG0:
break;
case RF1AIV_RFIFG1:
// GDO1 = LNA_PD signal
// This is called when leaving RX mode
// Turn off the CC1190 now that LNA is powered down
interruptOwnerPtr->lna_en.clear();
interruptOwnerPtr->pa_en.clear();
if (RF1AIFG & BIT9) {
RF1AIE &= ~(BIT1);
break;
}

RF1AIE &= ~(BIT1+BIT9);
interruptOwnerPtr->StrobeBlock(RF_SWOR);
break;
case RF1AIV_RFIFG2:
break;
/////// ERATTA: RF1A5 - Sometimes interrupts 3 through 10 fire when there is no interrupt, check manually for each
case RF1AIV_RFIFG3:
// RX FIFO filled or above the RX FIFO threshold
break;
case RF1AIV_RFIFG4:
// RX FIFO filled or above the RX FIFO threshold or end of packet is reached
break;
case RF1AIV_RFIFG5:
// TX FIFO filled or above the TX FIFO threshold
break;
case RF1AIV_RFIFG6:
// TX FIFO full
break;
case RF1AIV_RFIFG7:
// RX FIFO overflowed
break;
case RF1AIV_RFIFG8:
// TX FIFO underflowed
break;
case RF1AIV_RFIFG9:
// Make sure the signal really is LOW for RFIFG9
// Falling: Packet received or packet sent
if ((RF1AIN & BIT9)) break;
// Make sure the signal really is HIGH for RFIFG9
// Rising: SYNC detected
//if (!(RF1AIN & BIT9)) break;

// Turn off the CC1190 now that the packet transfer is complete
interruptOwnerPtr->lna_en.clear();
interruptOwnerPtr->pa_en.clear();
if ( interruptOwnerPtr->lastActiveState == CC1101::RX ) {
RF1AIE &= ~(BIT1+BIT9);
/* Initialize the variables to read the packet from the radio */
char len = interruptOwnerPtr->ReadSingleRegBlock(RXBYTES);
static char P1 = interruptOwnerPtr->ReadSingleRegBlock(PKTCTRL1);
LEN=len;
if (len) {
interruptOwnerPtr->ReadBurstRegBlock(RF_RXFIFORD, buffer, len);
interruptOwnerPtr->packetIn.stuff(buffer[1]);
interruptOwnerPtr->packetIn.stuff(buffer[2]);
interruptOwnerPtr->packetIn.stuff(buffer[3]);
interruptOwnerPtr->packetIn.stuff(buffer[4]);
interruptOwnerPtr->packetIn.stuff(buffer[5]);
interruptOwnerPtr->packetIn.stuff(buffer[6]);
interruptOwnerPtr->packetIn.stuff(buffer[7]);
interruptOwnerPtr->packetIn.stuff(buffer[8]);
interruptOwnerPtr->packetIn.stuff(buffer[9]);
interruptOwnerPtr->packetIn.setRSSI(buffer[10]);
interruptOwnerPtr->packetIn.setLQI(buffer[11]);

if ( interruptOwnerPtr->packetIn.isCRCOK() ) {
interruptOwnerPtr->packetIn.analyze(); // Determine the relevent info for the packet
interruptOwnerPtr->mainQueue->postEvent(new Event(PACKET_ARRIVED_SIG, interruptOwnerPtr->packetIn));
} else {
interruptOwnerPtr->mainQueue->postEvent(new Event(PACKET_WAS_CORRUPT_SIG));
}

} else {
// Invalid packet size, flush the FIFO
interruptOwnerPtr->StrobeBlock(RF_SIDLE);
interruptOwnerPtr->StrobeBlock(RF_SFRX);
interruptOwnerPtr->mainQueue->postEvent(new Event(PACKET_WAS_CORRUPT_SIG));
}
} else if (interruptOwnerPtr->lastActiveState == CC1101::TX) {
// Finished sending Packet
RF1AIE &= ~BIT9; // Disable TX end-of-packet interrupt
interruptOwnerPtr->PacketSent();
} else {
while (1); // Trap
}
break;
case RF1AIV_RFIFG10:
// *********************************** NOTE ************************************
// There is an errata for this interrupt, RF1A8
// Use IFG9 instead
// *********************************** NOTE ************************************
break;
////////// END ERRATA RF1A5 /////////////////////////////////////////////////////////////////////
case RF1AIV_RFIFG11:
// Preamble quality reached (PQI) is above programmed PQT value
break;
case RF1AIV_RFIFG12:
// Clear channel assessment when RSSI level is below threshold (dependent on the current RFIFG12 CCA_MODE setting)
break;
case RF1AIV_RFIFG13:
// Carrier sense. RSSI level is above threshold
break;
case RF1AIV_RFIFG14:
// Wake on Radio 0 Event
RF1AIE |= BIT9 + BIT1; // Enable the interrupt
RF1AIFG &= ~(BIT9 + BIT1); // Clear a pending interrupt
RF1AIES |= BIT9; // Falling edge of RFIFG9 (Packet Detect)
RF1AIFG &= ~BIT9; // Clear a pending interrupt
RF1AIE |= BIT9; // Enable the interrupt
//RF1AIES |= BIT9; // Falling edge of RFIFG9 (Packet Detect)
//RF1AIFG &= ~(BIT9 + BIT1); // Clear a pending interrupt
//RF1AIE |= BIT9 + BIT1; // Enable the interrupt

interruptOwnerPtr->StrobeBlock(RF_SRX);
break;
case RF1AIV_RFIFG15:
break;
default:
break;
}

}