static int entropy_nrf5_get_entropy(struct device *device, u8_t *buf, u16_t len) { /* Mark the peripheral as being used */ atomic_inc(&DEV_DATA(device)->user_count); /* Disable the shortcut that stops the task after a byte is generated */ nrf_rng_shorts_disable(NRF_RNG_SHORT_VALRDY_STOP_MASK); /* Start the RNG generator peripheral */ nrf_rng_task_trigger(NRF_RNG_TASK_START); while (len) { *buf = entropy_nrf5_get_u8(); buf++; len--; } /* Only stop the RNG generator peripheral if we're the last user */ if (atomic_dec(&DEV_DATA(device)->user_count) == 1) { /* Disable the peripheral on the next VALRDY event */ nrf_rng_shorts_enable(NRF_RNG_SHORT_VALRDY_STOP_MASK); if (atomic_get(&DEV_DATA(device)->user_count) != 0) { /* Race condition: another thread started to use * the peripheral while we were disabling it. * Enable the peripheral again */ nrf_rng_shorts_disable(NRF_RNG_SHORT_VALRDY_STOP_MASK); nrf_rng_task_trigger(NRF_RNG_TASK_START); } } return 0; }
nrfx_err_t nrfx_rng_init(nrfx_rng_config_t const * p_config, nrfx_rng_evt_handler_t handler) { NRFX_ASSERT(p_config); if (m_rng_state != NRFX_DRV_STATE_UNINITIALIZED) { return NRFX_ERROR_ALREADY_INITIALIZED; } if (handler == NULL) { return NRFX_ERROR_INVALID_PARAM; } m_rng_hndl = handler; if (p_config->error_correction) { nrf_rng_error_correction_enable(); } nrf_rng_shorts_disable(NRF_RNG_SHORT_VALRDY_STOP_MASK); NRFX_IRQ_PRIORITY_SET(RNG_IRQn, p_config->interrupt_priority); NRFX_IRQ_ENABLE(RNG_IRQn); m_rng_state = NRFX_DRV_STATE_INITIALIZED; return NRFX_SUCCESS; }
ret_code_t nrf_drv_rng_init(nrf_drv_rng_config_t const * p_config) { uint32_t result; if (m_rng_cb.state == NRF_DRV_STATE_UNINITIALIZED) { #ifndef SOFTDEVICE_PRESENT result = app_fifo_init(&m_rng_cb.rand_pool, m_rng_cb.buffer, RNG_CONFIG_POOL_SIZE); if (p_config == NULL) { p_config = &m_default_config; } if (result == NRF_SUCCESS) { if (p_config->error_correction) { nrf_rng_error_correction_enable(); } nrf_drv_common_irq_enable(RNG_IRQn, p_config->interrupt_priority); nrf_rng_shorts_disable(NRF_RNG_SHORT_VALRDY_STOP_MASK); rng_start(); m_rng_cb.state = NRF_DRV_STATE_INITIALIZED; } #else UNUSED_VARIABLE(p_config); uint8_t softdevice_is_enabled; result = sd_softdevice_is_enabled(&softdevice_is_enabled); if (softdevice_is_enabled) { m_rng_cb.state = NRF_DRV_STATE_INITIALIZED; } else { result = NRF_ERROR_SOFTDEVICE_NOT_ENABLED; } #endif // SOFTDEVICE_PRESENT } else { result = NRF_ERROR_INVALID_STATE; } return result; }
void nrf5RandomInit(void) { uint32_t seed = 0; memset(sBuffer, 0, sizeof(sBuffer)); sReadPosition = 0; sWritePosition = 0; NVIC_SetPriority(RNG_IRQn, RNG_IRQ_PRIORITY); NVIC_ClearPendingIRQ(RNG_IRQn); NVIC_EnableIRQ(RNG_IRQn); nrf_rng_error_correction_enable(); nrf_rng_shorts_disable(NRF_RNG_SHORT_VALRDY_STOP_MASK); generatorStart(); // Wait for the first randomized 4 bytes, to randomize software generator seed. while (!bufferIsUint32Ready()) ; seed = bufferGetUint32(); srand(seed); }