diff --git a/cpu/cortexm_common/cortexm_init.c b/cpu/cortexm_common/cortexm_init.c index 5419d92db..39ff3a908 100644 --- a/cpu/cortexm_common/cortexm_init.c +++ b/cpu/cortexm_common/cortexm_init.c @@ -49,4 +49,7 @@ void cortexm_init(void) for (IRQn_Type i = 0; i < (int) CPU_IRQ_NUMOF; i++) { NVIC_SetPriority(i, CPU_DEFAULT_IRQ_PRIO); } + + /* enable wake up on events for __WFE CPU sleep */ + SCB->SCR |= SCB_SCR_SEVONPEND_Msk; } diff --git a/cpu/cortexm_common/include/cpu.h b/cpu/cortexm_common/include/cpu.h index c2a79cbac..fbffb0f2d 100644 --- a/cpu/cortexm_common/include/cpu.h +++ b/cpu/cortexm_common/include/cpu.h @@ -102,6 +102,18 @@ static inline void cpu_print_last_instruction(void) printf("%p\n", (void*) lr_ptr); } +/** + * @brief Put the CPU into the 'wait for event' sleep mode + * + * This function is meant to be used for short periods of time, where it is not + * feasible to switch to the idle thread and back. + */ +static inline void cpu_sleep_until_event(void) +{ + __SEV(); + __WFE(); +} + #ifdef __cplusplus } #endif diff --git a/cpu/nrf51/periph/hwrng.c b/cpu/nrf51/periph/hwrng.c deleted file mode 100644 index fa234290c..000000000 --- a/cpu/nrf51/periph/hwrng.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2014-2016 Freie Universität Berlin - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License v2.1. See the file LICENSE in the top level - * directory for more details. - */ - -/** - * @ingroup cpu_nrf51 - * @{ - * - * @file - * @brief Driver for the NRF51822 random number generator - * - * @author Hauke Petersen - * @author Frank Holtz - * - * @} - */ - -#include "cpu.h" -#include "periph/hwrng.h" - -void hwrng_init(void) -{ - /* The RNG is initiated every time when RNG read is called - * This reduces power consumption when RNG is not needed - */ -} - -void hwrng_read(uint8_t *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) { - /* 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++] = (uint8_t)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; -} diff --git a/cpu/nrf52/periph/hwrng.c b/cpu/nrf5x_common/periph/hwrng.c similarity index 56% rename from cpu/nrf52/periph/hwrng.c rename to cpu/nrf5x_common/periph/hwrng.c index c7ec673ce..832d1378b 100644 --- a/cpu/nrf52/periph/hwrng.c +++ b/cpu/nrf5x_common/periph/hwrng.c @@ -1,6 +1,6 @@ /* - * Copyright (C) 2015 Jan Wagner - * 2016 Freie Universität Berlin + * Copyright (C) 2014-2016 Freie Universität Berlin + * 2015 Jan Wagner * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -8,13 +8,14 @@ */ /** - * @ingroup cpu_nrf52 + * @ingroup cpu_nrf5x_common * @{ * * @file * @brief Implementation of the hardware random number generator interface * * @author Hauke Petersen + * @author Frank Holtz * @author Jan Wagner * * @} @@ -32,14 +33,27 @@ void hwrng_read(uint8_t *buf, unsigned int num) { unsigned int count = 0; + /* power on RNG */ +#ifdef CPU_FAM_NRF51 + NRF_RNG->POWER = 1; +#endif NRF_RNG->TASKS_START = 1; + /* read the actual random data */ while (count < num) { - while (NRF_RNG->EVENTS_VALRDY == 0); + /* sleep until number is generated */ + while (NRF_RNG->EVENTS_VALRDY == 0) { + cpu_sleep_until_event(); + } - NRF_RNG->EVENTS_VALRDY = 0; buf[count++] = (uint8_t)NRF_RNG->VALUE; + /* NRF51 PAN #21 -> read value before clearing VALRDY */ + NRF_RNG->EVENTS_VALRDY = 0; } + /* power off RNG */ NRF_RNG->TASKS_STOP = 1; +#ifdef CPU_FAM_NRF51 + NRF_RNG->POWER = 0; +#endif }