This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Radio state machine

Hi all !

I'm struggling to get a frequency jumping protocol up and running and can't figure out how to handle the following situation (please refer to the attached "pseudo code"):

1. When I start the radio to receive(or transmit)  a packet I assert that it is "DISABLED".

2. When I get a radio interrupt I assert that the radio is "RXIDLE" (or TXIDLE).

3.When a packet has been received (or transmitted) I disable the radio.

After a couple of successful receptions (frequency changed between each one of them) I suddenly fall in to the default case of the switch in the ISR, i.e. ASSERT(false). When I check the value of the variable "state" it is 1, i.e. RXRU (In the debugger the NRF_RADIO->STATE has value 3, i.e. RXIDLE, but that seems logical).

My question is this: How can a packet be received when the radio is still in RXRU ? I guess the solution here would simply be to enable the receiver a bit earlier but still, is this behavior really to be expected ?

Cheers

Eric

void RADIO_Init(void)
{
    //...

    // Enable interrupt from END event
    NRF_RADIO->INTENSET = 0x00000008;
}


/*===========================================================================*/
void RADIO_Start(radioMode_e mode)
{

    ASSERT(NRF_RADIO->STATE == STATE_DISABLED)

    switch (mode)
    {
        case RADIO_MODE_RX:
            NRF_RADIO->TASKS_RXEN = 1;
            break;

        case RADIO_MODE_TX:
            NRF_RADIO->TASKS_TXEN = 1;
            break;

        default:
            ASSERT(false);
            break;
    }
}

/*===========================================================================*/

void RADIO_IRQHandler(void)
{
    uint32_t state; 

    if (NRF_RADIO->EVENTS_END)
    {
        NRF_RADIO->EVENTS_END = 0;
        NRF_RADIO->EVENTS_END;
        
        state = NRF_RADIO->STATE;

        switch (NRF_RADIO->STATE)
        {
            case STATE_RXIDLE:

                // Packet received....
                break;

            case STATE_TXIDLE:

                // Packet sent....
                break;

            default:
                ASSERT(false);
                break;
        }
        NRF_RADIO->TASKS_DISABLE = 1;
    }
}

Parents
  • I think you will need to debug a bit further to understand when this is occurring. For instance what radio shorts do you have enabled, a STATE value of 3 is RX (not RXIDLE), is it possible you are triggering RXEN several times without stop or disable? Are you waiting for appropriate events before triggering new task/astate?

    Best regards,
    Kenneth

Reply
  • I think you will need to debug a bit further to understand when this is occurring. For instance what radio shorts do you have enabled, a STATE value of 3 is RX (not RXIDLE), is it possible you are triggering RXEN several times without stop or disable? Are you waiting for appropriate events before triggering new task/astate?

    Best regards,
    Kenneth

Children
  • Kenneth, thank you for the attention.

    - I have only one shortcut enabled and that is between READY and START.

    - Yes, you are right; value 3 is RX which, off course, makes sense due to the shortcut.

    - Since RXEN is "protected" by an assert that the radio is disabled, multiple calls should not be possible. Besides, every radio ISR is finished with a call to TASKS_DISABLE.

    Thinking further about this I can come up with one plausable expanation:

    Since it is not certain that a packet is transmitted in every slot (or on every frequency if you like) I cannot rely on the RX ISR to switch to the next frequency. Instead this is done by a timer interrupt. However, as it stands,  this interrupt has a higher priority than the radio interrupt. Consequently; if a packet is received "too late" the timer ISR has already disabled the radio, switched to the next frequency and initiated "a ramp up". When it finishes the lower priority radio ISR gets to run and, hence , a packet is "received" in the RXRU state. What do you think ?

    In any case; what makes most sense as a design choise (and why ?):

    1. Timer IRQ has higher priority than the radio IRQ

    2. Radio IRQ has higher priority than the timer IRQ

    3. Both IRQs have the same priority

    4. Radio ISR is disabled. Everything is handled in the timer ISR.

    Any suggestion is most welcome

    \Eric

     

      

  • Eric said:
    When it finishes the lower priority radio ISR gets to run and, hence , a packet is "received" in the RXRU state. What do you think ?

    That make sense!

    I don't have any really good suggestion here how to best handle this. Though I think it is best to have the same interrupt priority in this case, since both interact with the radio peripheral.

    Best regards,
    Kenneth

Related