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

RNG interrupt handler not called

RNG interrupt handler is not called.

Using nrfx_rng library to generate random numbers.

VALRDY event is generated but interrupt handler nrfx_rng_irq_handler in library is not called.

Breakpoint not hit.

Despite EVENTS_VALRDY being set.

and INTENSET/ NVIC_ISER0 having correct values.

Code which sets up RNG using nrfx_rng library

ren_status_t generateRand(uint8_t * p_challenge)
{
ren_status_t return_value = RAND_ERROR;

static const nrfx_rng_config_t RNG_CONFIG = {
.error_correction = true,
.interrupt_priority = RNG_INTERRUPT_PRIORITY
};

assert(p_challenge != NULL);

challenge_pointer = p_challenge;

/* Reset random number counter. */
random_number_index = 0U;

/* Initialise random number generator. */
if (NRF_SUCCESS == nrfx_rng_init(&RNG_CONFIG, randomNumberEventHandler))
{
/* Start random number generator. */
nrfx_rng_start();

/* Wait for required number of random numbers to be generated. */
while(random_number_index < RAND_SIZE);

/* Stop random number generator. */
nrfx_rng_stop();

/* Uninitialise random number generator. */
nrfx_rng_uninit();

return_value = RAND_SUCCESS;
}

return return_value;
}



static void randomNumberEventHandler(uint8_t rng_data)
{
assert(challenge_pointer != NULL);

/* Store random number in appropriate location in challenge. */
rand_pointer[random_number_index] = rng_data;

/* Move on to next location. */
random_number_index++;
}

Any ideas ?

  • Hello,

    I assume \nRF5_SDK_15.3.0_59ac345\examples\peripheral\rng\ can be used as reference, just make sure that you define SOFTDEVICE_PRESENT if used with the softdevice.

    Best regards,
    Kenneth

  • In the end, as this is a relatively simple peripheral, I decided to access the hardware directly. Works fine.

    void generateRandomNumbers(uint8_t * p_random_numbers)
    {
       assert(p_random_numbers != NULL);
    
       random_number_pointer = p_random_numbers;
    
       /* Reset random number counter. */
       random_number_index = 0U;
    
       /* Initialise random number generator. */
    
       /* Configure for bias correction. */
       NRF_RNG->CONFIG = RNG_CONFIG_DERCEN_Enabled << RNG_CONFIG_DERCEN_Pos;
    
       /* Enable value ready interrupt. */
       sd_nvic_EnableIRQ(RNG_IRQn);
    
       NRF_RNG->INTENSET = RNG_INTENSET_VALRDY_Enabled << RNG_INTENSET_VALRDY_Pos;
    
       /* Start random number generation. */
       NRF_RNG->TASKS_START = 1U;
    
       /* Wait for required number of random numbers to be generated. */
       while(random_number_index < CHALLENGE_LEN);
    
       /* Stop random number generator. */
       NRF_RNG->TASKS_STOP = 1U;
    }
    
    
    void RNG_IRQHandler(void)
    {
       /* Random value ready. */
    
       /* Clear event. */
       NRF_RNG->EVENTS_VALRDY = 0U;
    
       random_number_pointer[random_number_index] = NRF_RNG->VALUE;
    
       /* Move on to next location. */
       random_number_index++;
    }
    

  • Hi,

    I seem to have a similar issue with the RNG. I am not using the SoftDevice but it seems that the RNG does not run the interrupt function no matter what priotity I give it.

    The issue is when waiting for the RNG to generate the correct number of numbers.

    Using while(random_number_index < len) {}; does not work, while nrf_delay_ms(1); does!

    NRFX:

    static int random_number_index;
    static uint8_t *random_number_buf_ptr;
    static int random_number_max_len;
    
    void rng_event_handler(uint8_t rng_data)
    {
        if (random_number_index < random_number_max_len)
        {
            random_number_buf_ptr[random_number_index] = rng_data;
            random_number_index++;
        }
    }
    
    int mcu_rng_generate(int len, uint8_t *rng_buf)
    {
        // Reset random number counter
        random_number_index = 0;
    
        // Setup safety so that RNG does not fill up buffer beyound len
        random_number_max_len = len;
        random_number_buf_ptr = rng_buf;
    
        // Start random number generator
        nrfx_rng_start();
    
        // Wait for required number of random numbers to be generated
        // nrf_delay_ms(1); // <-- THIS WORKS
        while(random_number_index < len) {}; // <-- THIS DOES NOT WORK
        // NRF_LOG_INFO("%d < %d", random_number_index, len);
    
        // Stop random number generator
        nrfx_rng_stop();
    
        return NRF_SUCCESS;
    }
    
    // Random number generator
    int mcu_rng_init()
    {
        // Initialise random number generator
        nrfx_rng_config_t config = NRFX_RNG_DEFAULT_CONFIG;
        return nrfx_rng_init(&config, rng_event_handler);
    }

    Same thing when using the HW registers directly:

    int mcu_rng_generate(int len, uint8_t *rng_buf)
    {
        // Reset random number counter
        random_number_index = 0;
    
        // Setup safety so that RNG does not fill up buffer beyound len
        random_number_max_len = len;
        random_number_buf_ptr = rng_buf;
    
        /* Configure for bias correction. */
        NRF_RNG->CONFIG = RNG_CONFIG_DERCEN_Enabled << RNG_CONFIG_DERCEN_Pos;
    
        /* Enable value ready interrupt. */
        NRFX_IRQ_PRIORITY_SET(RNG_IRQn, 6);
        NRFX_IRQ_ENABLE(RNG_IRQn);
    
        NRF_RNG->INTENSET = RNG_INTENSET_VALRDY_Enabled << RNG_INTENSET_VALRDY_Pos;
    
        /* Start random number generation. */
        NRF_RNG->TASKS_START = 1U;
    
        /* Wait for required number of random numbers to be generated. */
        // nrf_delay_ms(1); // <-- THIS WORKS
        while(random_number_index < len); <-- THIS DOES NOT WORK!
    
        /* Stop random number generator. */
        NRF_RNG->TASKS_STOP = 1U;
    
        return NRF_SUCCESS;
    }
    
    
    void RNG_IRQHandler(void)
    {
        // Clear event
        NRF_RNG->EVENTS_VALRDY = 0U;
        if (random_number_index < random_number_max_len)
        {
            random_number_buf_ptr[random_number_index] = NRF_RNG->VALUE;
            random_number_index++;
        }
    }
    

    I have tried setting the NRFX_IRQ_PRIORITY_SET(RNG_IRQn, 6); to different things (0 and 12) but no difference.

    Can anybody help explaining what nrf_delay_ms(1); does differently than the busy-waiting version?

    Kind regards

  • Hi,

    the compiler optimizes (throws away) your busy-wait loop because it has no idea that random_number_index may change outside of this loop. Try to define random_number_index as volatile.

Related