From d9a3d8493cf1df85a7690737755e295de80e8578 Mon Sep 17 00:00:00 2001 From: Stephane D'Alu Date: Mon, 8 Feb 2016 23:45:59 +0100 Subject: Random Number Generator driver --- os/hal/ports/NRF51/NRF51822/platform.mk | 6 +- os/hal/ports/NRF51/NRF51822/rng_lld.c | 155 +++++++++++++++++++++++++++ os/hal/ports/NRF51/NRF51822/rng_lld.h | 178 ++++++++++++++++++++++++++++++++ 3 files changed, 338 insertions(+), 1 deletion(-) create mode 100644 os/hal/ports/NRF51/NRF51822/rng_lld.c create mode 100644 os/hal/ports/NRF51/NRF51822/rng_lld.h (limited to 'os/hal/ports') diff --git a/os/hal/ports/NRF51/NRF51822/platform.mk b/os/hal/ports/NRF51/NRF51822/platform.mk index 4fb50bc..96dd630 100644 --- a/os/hal/ports/NRF51/NRF51822/platform.mk +++ b/os/hal/ports/NRF51/NRF51822/platform.mk @@ -28,6 +28,9 @@ endif ifneq ($(findstring HAL_USE_GPT TRUE,$(HALCONF)),) PLATFORMSRC += ${CHIBIOS_CONTRIB}/os/hal/ports/NRF51/NRF51822/gpt_lld.c endif +ifneq ($(findstring HAL_USE_RNG TRUE,$(HALCONF)),) +PLATFORMSRC += ${CHIBIOS_CONTRIB}/os/hal/ports/NRF51/NRF51822/rng_lld.c +endif else PLATFORMSRC = ${CHIBIOS}/os/hal/ports/common/ARMCMx/nvic.c \ ${CHIBIOS_CONTRIB}/os/hal/ports/NRF51/NRF51822/hal_lld.c \ @@ -39,7 +42,8 @@ PLATFORMSRC = ${CHIBIOS}/os/hal/ports/common/ARMCMx/nvic.c \ ${CHIBIOS_CONTRIB}/os/hal/ports/NRF51/NRF51822/ext_lld.c \ ${CHIBIOS_CONTRIB}/os/hal/ports/NRF51/NRF51822/i2c_lld.c \ ${CHIBIOS_CONTRIB}/os/hal/ports/NRF51/NRF51822/adc_lld.c \ - ${CHIBIOS_CONTRIB}/os/hal/ports/NRF51/NRF51822/gpt_lld.c + ${CHIBIOS_CONTRIB}/os/hal/ports/NRF51/NRF51822/gpt_lld.c \ + ${CHIBIOS_CONTRIB}/os/hal/ports/NRF51/NRF51822/rng_lld.c endif # Required include directories diff --git a/os/hal/ports/NRF51/NRF51822/rng_lld.c b/os/hal/ports/NRF51/NRF51822/rng_lld.c new file mode 100644 index 0000000..b22b9fc --- /dev/null +++ b/os/hal/ports/NRF51/NRF51822/rng_lld.c @@ -0,0 +1,155 @@ +/* + RNG for ChibiOS - Copyright (C) 2016 Stephane D'Alu + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file NRF51/RNGv1/rng_lld.c + * @brief NRF51 RNG subsystem low level driver source. + * + * @addtogroup RNG + * @{ + */ + +#include "hal.h" + +#if (HAL_USE_RNG == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/** + * @brief RNG default configuration. + */ +static const RNGConfig default_config = { + .digital_error_correction = 1, + .power_on_write = 1, +}; + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** @brief RNG1 driver identifier.*/ +#if NRF51_RNG_USE_RNG1 || defined(__DOXYGEN__) +RNGDriver RNGD1; +#endif + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level RNG driver initialization. + * + * @notapi + */ +void rng_lld_init(void) { + rngObjectInit(&RNGD1); + RNGD1.rng = NRF_RNG; +} + +/** + * @brief Configures and activates the RNG peripheral. + * + * @param[in] rngp pointer to the @p RNGDriver object + * + * @notapi + */ +void rng_lld_start(RNGDriver *rngp) { + if (rngp->config == NULL) + rngp->config = &default_config; + + rngp->rng->POWER = 1; + + if (rngp->config->digital_error_correction) + rngp->rng->CONFIG |= RNG_CONFIG_DERCEN_Msk; + else + rngp->rng->CONFIG &= ~RNG_CONFIG_DERCEN_Msk; + + rngp->rng->INTENSET = RNG_INTENSET_VALRDY_Msk; + rngp->rng->TASKS_START = 1; +} + + +/** + * @brief Deactivates the RNG peripheral. + * + * @param[in] rngp pointer to the @p RNGDriver object + * + * @notapi + */ +void rng_lld_stop(RNGDriver *rngp) { + rngp->rng->TASKS_STOP = 1; + rngp->rng->POWER = 0; +} + + +/** + * @brief Write random bytes; + * + * @param[in] rngp pointer to the @p RNGDriver object + * @param[in] n size of buf in bytes + * @param[in] buf @p buffer location + * + * @notapi + */ +msg_t rng_lld_write(RNGDriver *rngp, uint8_t *buf, size_t n, + systime_t timeout) { + size_t i; + if (n == 0) + return MSG_OK; + + if (n == 1) + rngp->rng->SHORTS |= RNG_SHORTS_VALRDY_STOP_Msk; + + + + NRF_RNG->EVENTS_VALRDY = 0; + + for (i = 0 ; i < n ; i++) { + /* 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[i] = (char)NRF_RNG->VALUE; + + NRF_RNG->EVENTS_VALRDY = 0; + nvicClearPending(RNG_IRQn); + } + return MSG_OK; +} + +#endif /* HAL_USE_RNG */ + +/** @} */ diff --git a/os/hal/ports/NRF51/NRF51822/rng_lld.h b/os/hal/ports/NRF51/NRF51822/rng_lld.h new file mode 100644 index 0000000..a586ad4 --- /dev/null +++ b/os/hal/ports/NRF51/NRF51822/rng_lld.h @@ -0,0 +1,178 @@ +/* + RNG for ChibiOS - Copyright (C) 2016 Stephane D'Alu + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file NRF51/NRF51822/rng_lld.h + * @brief NRF51 RNG subsystem low level driver header. + * + * @addtogroup RNG + * @{ + */ + +#ifndef _RNG_LLD_H_ +#define _RNG_LLD_H_ + +#if (HAL_USE_RNG == TRUE) || defined(__DOXYGEN__) + +/* + * This error check must occur outsite of RNGSW_USE_RNG1 to check if + * two LLD drivers are enabled at the same time + */ +#if (NRF51_RNG_USE_RNG1 == TRUE) && (RNGSW_USE_RNG1 == TRUE) +#error "Software RNG can't be enable with NRF51_RNG_USE_RNG1" +#endif + +/** + * Allow RNG Software override. + */ +#if RNGSW_USE_RNG1 != TRUE + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief RNG1 driver enable switch. + * @details If set to @p TRUE the support for RNG1 is included. + * @note The default is @p FALSE. + */ +#if !defined(NRF51_RNG_USE_RNG1) || defined(__DOXYGEN__) +#define NRF51_RNG_USE_RNG1 FALSE +#endif + +/** + * @brief RNG1 driver enable switch. + * @details If set to @p TRUE the support for RNG1 is included. + * @note The default is @p FALSE. + */ +#if !defined(NRF51_RNG_USE_RNG1) || defined(__DOXYGEN__) +#define NRF51_RNG_USE_POWER_ON_WRITE FALSE +#endif + +/** + * @brief RNG1 interrupt priority level setting. + */ +#if !defined(NRF51_RNG_RNG1_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define NRF51_RNG_RNG1_IRQ_PRIORITY 8 +#endif + + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Type of a structure representing an RNG driver. + */ +typedef struct RNGDriver RNGDriver; + +/** + * @brief Driver configuration structure. + */ +typedef struct { + /* End of the mandatory fields.*/ + /** + * @brief Activate the digital error correction + * + * @details A digital corrector algorithm is employed to remove any + * bias toward '1' or '0'. Disabling it offers a substantial + * speed advantage, but may result in a statistical distribution + * that is not perfectly uniform. + * + * @note On average, it take 167µs to get a byte without digitial + * error correction and 677µs with, but no garantee is made + * on the necessary time to generate one byte. + */ + uint8_t digital_error_correction:1; + /** + * @brief Only power the RNG device when requeting random bytes + * + * @details Device will not be powered when started/stopped + * but only when writint bytes. + */ + uint8_t power_on_write:1; +} RNGConfig; + + +/** + * @brief Structure representing an RNG driver. + */ +struct RNGDriver { + /** + * @brief Driver state. + */ + rngstate_t state; + /** + * @brief Current configuration data. + */ + const RNGConfig *config; +#if RNG_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__) + /** + * @brief Mutex protecting the peripheral. + */ + mutex_t mutex; +#endif /* RNG_USE_MUTUAL_EXCLUSION */ + /* End of the mandatory fields.*/ + /** + * @brief Pointer to the RNGx registers block. + */ + NRF_RNG_Type *rng; +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if NRF51_RNG_USE_RNG1 && !defined(__DOXYGEN__) +extern RNGDriver RNGD1; +#endif /* NRF51_RNG_USE_RNG1 */ + +#ifdef __cplusplus +extern "C" { +#endif + void rng_lld_init(void); + void rng_lld_start(RNGDriver *rngp); + void rng_lld_stop(RNGDriver *rngp); + msg_t rng_lld_write(RNGDriver *rngp, uint8_t *buf, size_t n, + systime_t timeout); +#ifdef __cplusplus +} +#endif + +#endif /* RNGSW_USE_RNG1 */ + +#endif /* HAL_USE_RNG */ + +#endif /* _RNG_LLD_H_ */ + +/** @} */ -- cgit v1.2.3