updated software components for new TRNG setup

This commit is contained in:
stnolting 2020-09-11 17:59:26 +02:00
parent 89f64c9569
commit ecb803079b
3 changed files with 40 additions and 95 deletions

View file

@ -442,23 +442,17 @@ enum NEORV32_PWM_DUTY_enum {
* @name IO Device: True Random Number Generator (TRNG)
**************************************************************************/
/**@{*/
/** TRNG control register (r/w) */
/** TRNG control/data register (r/w) */
#define TRNG_CT (*(IO_REG32 0xFFFFFFC0UL))
/** TRNG data register (r/-) */
#define TRNG_DATA (*(IO_ROM32 0xFFFFFFC4UL))
/** TRNG control register bits */
/** TRNG control/data register bits */
enum NEORV32_TRNG_CT_enum {
TRNG_CT_TAP_LSB = 0, /**< TRNG control register(0) (r/w): TAP mask (16-bit) LSB */
TRNG_CT_TAP_MSB = 15, /**< TRNG control register(15) (r/w): TAP mask (16-bit) MSB */
TRNG_CT_EN = 31 /**< TRNG control register(31) (r/w): TRNG enable */
};
/** WTD data register bits */
enum NEORV32_TRNG_DUTY_enum {
TRNG_DATA_LSB = 0, /**< TRNG data register(0) (r/-): Random data (16-bit) LSB */
TRNG_DATA_MSB = 15, /**< TRNG data register(15) (r/-): Random data (16-bit) MSB */
TRNG_DATA_VALID = 31 /**< TRNG data register(31) (r/-): Random data output valid */
TRNG_CT_DATA_LSB = 0, /**< TRNG data/control register(0) (r/-): Random data (8-bit) LSB */
TRNG_CT_DATA_MSB = 7, /**< TRNG data/control register(7) (r/-): Random data (8-bit) MSB */
TRNG_CT_VALID = 15, /**< TRNG data/control register(15) (r/-): Random data output valid */
TRNG_CT_ERROR_0 = 16, /**< TRNG data/control register(16) (r/-): Stuck-at-zero error */
TRNG_CT_ERROR_1 = 17, /**< TRNG data/control register(17) (r/-): Stuck-at-one error */
TRNG_CT_EN = 31 /**< TRNG data/control register(31) (r/w): TRNG enable */
};
/**@}*/

View file

@ -46,9 +46,8 @@
// prototypes
int neorv32_trng_available(void);
int neorv32_trng_setup(uint16_t tap_mask);
uint16_t neorv32_trng_find_tap_mask(void);
void neorv32_trng_enable(void);
void neorv32_trng_disable(void);
int neorv32_trng_get(uint16_t *data);
int neorv32_trng_get(uint8_t *data);
#endif // neorv32_trng_h

View file

@ -62,29 +62,22 @@ int neorv32_trng_available(void) {
/**********************************************************************//**
* Enable and configure true random number generator. The TRNG control register bits are listed in #NEORV32_TRNG_CT_enum.
*
* @param[in] tap_mask 16-bit tap mask for GARO array.
* @return Returns 0 if the provided tap_mask works correctly (GARO-array is oscillating), returns 1 otherwise.
* Enable true random number generator. The TRNG control register bits are listed in #NEORV32_TRNG_CT_enum.
**************************************************************************/
int neorv32_trng_setup(uint16_t tap_mask) {
void neorv32_trng_enable(void) {
int i;
TRNG_CT = 0; // reset
// configure
uint32_t tap_config = (uint32_t)(tap_mask);
tap_config = tap_config << TRNG_CT_TAP_LSB;
TRNG_CT = (1 << TRNG_CT_EN) | tap_config;
neorv32_cpu_delay_ms(1);
// check if TRNG is oscillating
uint16_t trng_data;
if (neorv32_trng_get(&trng_data) == 0) {
return 0;
for (i=0; i<1000; i++) {
asm volatile ("nop");
}
else {
return 1;
TRNG_CT = 1 << TRNG_CT_EN; // activate
for (i=0; i<1000; i++) {
asm volatile ("nop");
}
}
@ -101,71 +94,30 @@ void neorv32_trng_disable(void) {
/**********************************************************************//**
* Get random data from TRNG.
*
* @param[in,out] data uint16_t pointer for storing random data word
* @return Valid data when 0, invalid data when 1
**************************************************************************/
int neorv32_trng_get(uint16_t *data) {
int i;
const int max_try = 16;
uint32_t trng_data;
uint32_t rnd_data;
for(i=0; i<max_try; i++) {
trng_data = TRNG_DATA;
rnd_data = trng_data >> TRNG_DATA_LSB;
*data = (uint16_t)rnd_data;
if (trng_data & (1<<TRNG_DATA_VALID)) { // output data valid?
return 0; // valid
}
}
return 1; // invalid
}
/**********************************************************************//**
* Try to find a valid TRNG tap configuration mask.
* @note The TRNG is automatically reset if a stuck-at-one/stuck-at-zero error is detected.
*
* @return Tap mask for configuring the TRNG. If return is zero, no valid tap mask was found.
* @param[in,out] data uint8_t pointer for storing random data word
* @return Data is valid when 0, stuck-at-zero error when 1, stuck-at-one error when 2, data not (yet) valid when 3
**************************************************************************/
uint16_t neorv32_trng_find_tap_mask(void) {
int neorv32_trng_get(uint8_t *data) {
int j;
uint16_t tap_config16 = 0xfff0; // keep the lowest inverters without feedback
uint16_t trng_data;
int success = 0;
uint32_t trng_ct_reg = TRNG_CT;
// tap mask is zero, try to find a nice one
while (1) {
// good mask found?
if ((success) || (tap_config16 <= 0x0008)) {
break;
}
// generate a new tap
tap_config16 -= 0x0008;
// install it
if (neorv32_trng_setup(tap_config16)) {
continue;
}
// does it work?
success = 1;
for (j=0; j < 100; j++) {
neorv32_cpu_delay_ms(1);
if (neorv32_trng_get(&trng_data)) { // stop testing on fail
success = 0;
break;
}
}
if (trng_ct_reg & (1<<TRNG_CT_ERROR_0)) { // stuck at zero error
neorv32_trng_enable(); // reset TRNG
return 1;
}
return (uint16_t)tap_config16;
if (trng_ct_reg & (1<<TRNG_CT_ERROR_1)) { // stuck at one error
neorv32_trng_enable(); // reset TRNG
return 2;
}
if ((trng_ct_reg & (1<<TRNG_CT_VALID)) == 0) { // output data valid (yet)?
return 3;
}
*data = (uint8_t)(trng_ct_reg >> TRNG_CT_DATA_LSB);
return 0; // valid data
}