/* * Copyright (C) 2014-2016 Freie Universität Berlin * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level * directory for more details. */ /** * @ingroup cpu_sam3 * @ingroup drivers_periph_hwrng * @{ * * @file * @brief Low-level random number generator driver implementation * * @author Hauke Petersen * * @} */ #include "cpu.h" #include "periph/hwrng.h" /** * @name KEY needs to be written to the config register when en|disabling * random number generation */ #define KEY (0x524e4700) void hwrng_init(void) { /* no need for initialization */ } void hwrng_read(void *buf, unsigned int num) { unsigned count = 0; uint8_t *b = (uint8_t *)buf; /* enable clock signal for TRNG module */ PMC->PMC_PCER1 |= PMC_PCER1_PID41; /* enable the generation of random numbers */ TRNG->TRNG_CR |= (KEY | TRNG_CR_ENABLE); while (count < num) { /* wait until new value is generated -> takes up to 84 cycles */ while (!(TRNG->TRNG_ISR & TRNG_ISR_DATRDY)) {} /* read 4 byte of random data */ uint32_t tmp = TRNG->TRNG_ODATA; /* extract copy bytes to result */ for (int i = 0; i < 4 && count < num; i++) { b[count++] = (uint8_t)tmp; tmp = tmp >> 8; } } /* disable the generation of random numbers */ TRNG->TRNG_CR &= ~(KEY | TRNG_CR_ENABLE); /* disable clock signal for TRNG module */ PMC->PMC_PCER1 &= ~(PMC_PCER1_PID41); }