I've been messing about with the random number generator just testing out events and interrupts. I got it working generating an interrupt but then I thought, NRF_RNG->EVENTS_VALRDY is an event, why not just wait for that instead of messing about with interrupts.
So I tried the following
uint32_t count = 0;
uint32_t wfes = 0;
NRF_RNG->EVENTS_VALRDY = 0;
NRF_RNG->TASKS_START=1;
while( 1 )
{
__WFE();
wfes++;
if( NRF_RNG->EVENTS_VALRDY != 0 )
{
count++;
}
NRF_RNG->TASKS_STOP = 1;
NRF_RNG->TASKS_START = 1;
}
expecting that the VALRDY event would wake from __WFE. The TASKS_STOP and TASKS_START are there to ensure the RNG does generate another number (PAN-28).
However it doesn't work. If I run it for a while and then breakpoint, wfes == 1, so it's had one wake from __WFE(), count is zero, so EVENTS_VALRDY wasn't ready at that time, and that's all it does.
Is NRF_RNG->EVENTS_VALRDY not the right kind of 'event' to wake from WFE()?
There's lots of other ways to do this I know, but I'd like to know why this one doesn't do what I expected.
------update after the suggestion to clear the events each time ------
With the code
NRF_RNG->EVENTS_VALRDY = 0;
NRF_RNG->TASKS_START = 1;
uint32_t wfe = 0;
uint32_t cnt = 0;
while( cnt < 200 )
{
while( NRF_RNG->EVENTS_VALRDY == 0 )
{
__WFE();
wfe++;
}
cnt++;
NRF_RNG->EVENTS_VALRDY = 0;
}
it's no better. It hangs on __WFE() and never returns even though the event has occurred. If you break into it in a debugger, that pulls you out of __WFE() and you see that VALRDY is non-zero and it continues and you can single-step it as much as you like, but as soon as you start it running, it goes into WFE() and never comes out. It seems EVENTS_VALRDY doesn't count as an 'Event' for the purposes of WFE.