Browse Source

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.
pull/758/head
Karl Palsson 8 years ago
parent
commit
f07b58c6d8
  1. 5
      include/libopencm3/stm32/common/rng_common_v1.h
  2. 47
      lib/stm32/common/rng_common_v1.c

5
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 <stdbool.h>
#include <stdint.h>
/**@{*/
/* --- 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

47
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;
}
/**@}*/

Loading…
Cancel
Save