Little help setting up a radio receive interrupt

Not being lazy here, but maybe you could save me just a little time with your expertise? I’m the guy who started that “Radio Reliability” thread.

I just want to TRY the approach of setting up an interrupt to handle receiving radio messages, if for no other reason than to see if I can make it more immune to other CPU activity, or interrupts related to the USB. Maybe it won’t help, but I’d like to try. Could you just tell me if I’m on the right track here? Also, I know its hard in C, but do you have any feel for how much code can actually be in an ISR, other than just to keep it short? This is not complete code, and some of it is modified from radio_test_rx. Obviously it not working or I wouldn’t be asking, but maybe you can help me get to first base? :slight_smile:

// 1. Initialization of DMA, with IRQ mask set

    #define RADIO_PACKET_SIZE 16
    static volatile XDATA uint8 packet[1 + RADIO_PACKET_SIZE + 2 ];

void init ()
 {
    radioRegistersInit();
    CHANNR = 128;      // or whatever
    PKTLEN = RADIO_PACKET_SIZE;
    MCSM0 = 0x14;    // Auto-calibrate when going from idle to RX or TX.
    MCSM1 = 0x00;    // Disable CCA.  After RX, go to IDLE.
   
    dmaConfig.radio.SRCADDRH = XDATA_SFR_ADDRESS(RFD) >> 8;
    dmaConfig.radio.SRCADDRL = XDATA_SFR_ADDRESS(RFD);
    dmaConfig.radio.DESTADDRH = (unsigned int)packet >> 8;
    dmaConfig.radio.DESTADDRL = (unsigned int)packet;
    dmaConfig.radio.LENL = 1 + RADIO_PACKET_SIZE + 2;
    dmaConfig.radio.VLEN_LENH = 0b10000000; // Transfer length is FirstByte+3

            // DC7 Bits 7:6 are SRCINC, 5:4 are DESTINC, 3 is IRQMASK, 2 is M8, 1:0 are PRIORITY.
            // I'm trying a higher priority, and enabling the interrupt
   
    dmaConfig.radio.DC7 = 0x19; // SRCINC = 0, DESTINC = 1, IRQMASK = 1 M8 = 0, PRIORITY = 1

    DMAIF =1;               // enable DMA transfer complete SFR
    DMAIRQ &= ~(1<<DMA_CHANNEL_RADIO);      // Clear any pending radio DMA interrupt
    MAARM |= (1<<DMA_CHANNEL_RADIO);  // Arm DMA channel
    RFST = 2;                          // Switch radio to RX mode.
 }


/* Have an interrupt ready to do something useful, and clear the interrupt
(By the way, if you use "DMA_VECTOR" for the 1st macro element, it gets expanded
to DMA_VECTOR_VECTOR, which obviously won't work)
*/

ISR(DMA,  0)  // macro to set up interrupt, from cc2511_map.h
    {
 
    // do something useful with data  in packet. 
   if (radioCrcPassed())
     {
     LED_RED_TOGGLE();  // toggel red each time I get a good packet  
       . . .
      } 

       DMAIRQ &= ~(1<<DMA_CHANNEL_RADIO);      // Clear radio DMA interrupt

 
    }

Hello. I see that you didn’t actually define an RF ISR in your code. You should look in the radio_mac library that comes with the Wixel SDK to see how to define that ISR and respond to various radio events.

Since the CC2511F32 has different interrupt priorities, you can get away with making the RF interrupt be pretty long. Our example apps have a lot of code running in the interrupt. It all depends on your application.

–David

Dave,

I probably didn’t title my message very well. I wasn’t trying to define an RF interrupt really, but I was trying to take advantage of the DMA transfer that was already being employed in the radio_test_rx example. I was hoping to alter it just enough to enable and utilize the DMA interrupt so that when a radio packet was received AND the DMA transfer finished, my interrupt code could then respond immediately rather than wait for me to check it by round robin looping. There is no example of the DMA interrupt usage in radio_mac, so could please take another look and help me see why its not working?

Well, I don’t think I have ever tried to use the DMA interrupt, and I’m not sure why you would want to use that instead of the RF interrupt. The radio_mac library has these lines to enable the RF interrupt and enable interrupts in general:

    IEN2 |= 0x01;    // Enable RF general interrupt
    RFIM = 0xF0;     // Enable these interrupts: DONE, RXOVF, TXUNF, TIMEOUT

    EA = 1;          // Enable interrupts in general

You should make sure you are doing the equivalent thing somewhere in your code.

–David

The reason WHY I wanted a DMA interrupt is because in a forum post entitled “1 byte as fast as possible”, YOU suggested the poster use radio_test_tx and radio_test_rx as examples of the fastest approach, citing that most of the library methods have built in delays. Since that example uses a DMA transfer to receive packets, and since its apparently possible to have a DMA transfer trigger an interrupt, it seemed like the next logical step.