diff --git a/cpu/nrf51822/periph/random.c b/cpu/nrf51822/periph/random.c index c3d9f41a0d..d9fd3187cc 100644 --- a/cpu/nrf51822/periph/random.c +++ b/cpu/nrf51822/periph/random.c @@ -14,6 +14,7 @@ * @brief Driver for the NRF51822 random number generator * * @author Hauke Petersen + * @author Frank Holtz * * @} */ @@ -27,31 +28,56 @@ void random_init(void) { - NRF_RNG->POWER = 1; - NRF_RNG->TASKS_START = 1; + /* The RNG is initiated every time when RNG read is called + * This reduces power consumption when RNG is not needed + */ } int random_read(char *buf, unsigned int num) { unsigned int count = 0; + /* power on RNG */ + NRF_RNG->POWER = 1; + /* Generate events when RNG is finished */ + NRF_RNG->INTENSET = RNG_INTENSET_VALRDY_Msk; + /* Start Task */ + NRF_RNG->TASKS_START = 1; + /* NRF51 PAN #21 */ + NRF_RNG->EVENTS_VALRDY = 0; + while (count < num) { - while (NRF_RNG->EVENTS_VALRDY == 0); - NRF_RNG->EVENTS_VALRDY = 0; + /* sleep until number is generated */ + while (NRF_RNG->EVENTS_VALRDY == 0) { + /* enable wake up on events for __WFE CPU sleep */ + SCB->SCR |= SCB_SCR_SEVONPEND_Msk; + /* sleep until next event */ + __SEV(); + __WFE(); + __WFE(); + } + buf[count++] = (char)NRF_RNG->VALUE; + /* NRF51 PAN #21 */ + NRF_RNG->EVENTS_VALRDY = 0; + /* clear interrupt state */ + NVIC_ClearPendingIRQ(RNG_IRQn); } + /* power off RNG */ + NRF_RNG->POWER = 0; + return count; } void random_poweron(void) { - NRF_RNG->POWER = 1; + /* RNG is powered on when needed */ } void random_poweroff(void) { - NRF_RNG->POWER = 0; + /* RNG is powered off automaticly */ } #endif /* RANDOM_NUMOF */