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

nrf51822 radio interrupt ???

I have two device , one is Tx-Device the other is Rx-Device.

Tx-Device : Auto continued Send 4 bytes data to Rx-Device by Radio.

Rx-Device : Using Radio Interrupt receive data from Tx-Device Radio,if receive data then Led is action , And main loop continued print string to Uart.

But Rx-Device not still print string to Uart. only print one time.

Have somebody can tech me why ??How to sloved this question ?

[Tx-Device Source Code]

void init(void)
{   
    NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
    NRF_CLOCK->TASKS_HFCLKSTART    = 1
    while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
    {
    }

    radio_configure();
    NRF_RADIO->PACKETPTR = (uint32_t)packet;
    nrf_gpio_range_cfg_input(BUTTON_START, BUTTON_STOP, BUTTON_PULL);
}

int main(void)
{
    init();  
    while (true)
    {
        if(nrf_gpio_pin_read(BUTTON_START)==0x00)
        {
                packet[0] = 0x00;
                packet[1] = 0x01;
                packet[2] = 0x02;
                packet[3] = 0x03;
                NRF_RADIO->EVENTS_READY = 0U;
                NRF_RADIO->TASKS_TXEN   = 1;
                while (NRF_RADIO->EVENTS_READY == 0U)
                {
                }
                NRF_RADIO->TASKS_START = 1U;
                NRF_RADIO->EVENTS_END  = 0U;  
                while (NRF_RADIO->EVENTS_END == 0U)
                {
                }
                NRF_RADIO->EVENTS_DISABLED = 0U;
                NRF_RADIO->TASKS_DISABLE = 1U;
                while (NRF_RADIO->EVENTS_DISABLED == 0U)
                {
                }
                nrf_delay_ms(10);
        }
    }
}

[Rx-Device Source Code]

void Radio_init(void)
{    
    NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
    NRF_CLOCK->TASKS_HFCLKSTART = 1;
    while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
    {
    }

    radio_configure();
    NRF_RADIO->PACKETPTR = (uint32_t)packet;                     
    NRF_RADIO->INTENSET = RADIO_INTENSET_READY_Enabled << RADIO_INTENSET_READY_Pos | 
    RADIO_INTENSET_ADDRESS_Enabled << RADIO_INTENSET_ADDRESS_Pos;
    NVIC_SetPriority(RADIO_IRQn, 1);
    NVIC_ClearPendingIRQ(RADIO_IRQn);
    NVIC_EnableIRQ(RADIO_IRQn);                     
}

void RADIO_IRQHandler(void)
{
        NRF_RADIO->EVENTS_END = 0U;
        NRF_RADIO->TASKS_START = 1U;

        while(NRF_RADIO->EVENTS_END == 0U)
        {
        }
        if (NRF_RADIO->CRCSTATUS == 1U)
        {
                if (LED_IRQFlag == 0){
                        nrf_gpio_pin_clear(LED_0);
                        LED_IRQFlag ++;
                }else if (LED_IRQFlag == 1){
                        nrf_gpio_pin_set(LED_0);
                        LED_IRQFlag = 0;
                }
        }
        NRF_RADIO->EVENTS_DISABLED = 0U;
}

int main(void)
{
    Radio_init();
    Port_Init();
    NRF_RADIO->EVENTS_READY = 0U;
    NRF_RADIO->TASKS_RXEN = 1U;
    while(1)
    {
        simple_uart_putstring((const uint8_t *)"Start: \n\r");
    }
}
  • FormerMember
    0 FormerMember

    The reason why "Start" is only printed once is most likely due to the implementation of RADIO_IRQHandler:

    • In Radio_init() INSTENSET is set to trigger on the events READY and ADDRESS. However, in the interrupt handler there is no check for those events and they are never cleared. Since those events are never cleared, it will create a forever loop that calls the interrupt handler.
    • Inside RADIO_IRQHandler, there is a loop over EVENTS_END, and the interrupt handler will hang there until it receives a packet. Since the READY and ADDRESS events never are being cleared, RADIO_IRQHandler can/will be triggered without receiving a packet. In that case the EVENTS_END loop will be a forever loop.

    I would recommend you to take a look at the radio examples in the SDK ( ..examples\peripheral\radio ) and the micro ESB library on github.

    Clearing of events in RADIO_IRQHandler(..) can be done the following way:

    void RADIO_IRQHandler()
    {
        if(NRF_RADIO->EVENTS_READY && (NRF_RADIO->INTENSET & RADIO_INTENSET_READY_Msk))
        {
            NRF_RADIO->EVENTS_READY = 0;
    }
    
    if(NRF_RADIO->EVENTS_END && (NRF_RADIO->INTENSET & RADIO_INTENSET_END_Msk))
    {
        NRF_RADIO->EVENTS_END = 0;
        }
    }
    
    if(NRF_RADIO->EVENTS_ADDRESS && (NRF_RADIO->INTENSET & RADIO_INTENSET_ADDRESS_Msk))
    {
        NRF_RADIO->EVENTS_ADDRESS= 0;
    }
     ... some code 
    }
    

    In addition, I you can consider to set up the EVENTS_END event to trigger interrupt:

      NRF_RADIO->INTENSET    =  RADIO_INTENSET_END_Msk;
    
  • Thanks Kirdtin .

    How to modify in RADIO_IRQHandler to sloved ?

  • FormerMember
    0 FormerMember in reply to FormerMember

    I have updated my answer, hopefully it answers your question. I would again recommend you to take a look at micro ESB.

Related