From f07b58c6d8cd1a580ac0039b553ea183d0197efc Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Thu, 12 Jan 2017 22:57:27 +0000 Subject: [PATCH] stm32:rng: add helper to actually get random numbers Simplified blocking API, with an async routine if you really need it. Follows as best as I can understand the reference manual, but testing those conditions will be difficult. --- .../libopencm3/stm32/common/rng_common_v1.h | 5 ++ lib/stm32/common/rng_common_v1.c | 47 +++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/include/libopencm3/stm32/common/rng_common_v1.h b/include/libopencm3/stm32/common/rng_common_v1.h index e0c26a81..1f226d77 100644 --- a/include/libopencm3/stm32/common/rng_common_v1.h +++ b/include/libopencm3/stm32/common/rng_common_v1.h @@ -28,6 +28,9 @@ specific memorymap.h header before including this header file.*/ #ifndef LIBOPENCM3_RNG_V1_H #define LIBOPENCM3_RNG_V1_H +#include +#include + /**@{*/ /* --- Random number generator registers ----------------------------------- */ @@ -72,6 +75,8 @@ BEGIN_DECLS void rng_enable(void); void rng_disable(void); +bool rng_get_random(uint32_t *rand_nr); +uint32_t rng_get_random_blocking(void); END_DECLS diff --git a/lib/stm32/common/rng_common_v1.c b/lib/stm32/common/rng_common_v1.c index 6808b683..7ed1e635 100644 --- a/lib/stm32/common/rng_common_v1.c +++ b/lib/stm32/common/rng_common_v1.c @@ -41,4 +41,51 @@ void rng_enable(void) RNG_CR |= RNG_CR_RNGEN; } +/** Randomizes a number (non-blocking). + * Can fail if a clock error or seed error is detected. Consult the Reference + * Manual, but "try again", potentially after resetting the peripheral + * @param pointer to a uint32_t that will be randomized. + * @returns true on success, pointer is only written to on success + * @sa rng_get_random_blocking + */ +bool rng_get_random(uint32_t *rand_nr) +{ + /* data ready */ + if (!(RNG_SR & RNG_SR_DRDY)) { + return false; + } + + /* Check for errors */ + if (RNG_SR & (RNG_SR_CECS | RNG_SR_SECS)) { + return false; + } + + *rand_nr = RNG_DR; + + return true; +} + + +/** + * Get a random number and block until it works. + * Unless you have a clock problem, this should always return "promptly" + * If you have a clock problem, you will wait here forever! + * @returns a random 32bit number + */ +uint32_t rng_get_random_blocking(void) +{ + uint32_t rv; + bool done; + do { + if (RNG_SR & RNG_SR_SECS) { + rng_disable(); + rng_enable(); + } + done = rng_get_random(&rv); + } while (!done); + + return rv; +} + + /**@}*/