diff --git a/meson.build b/meson.build index 24c0317a..5cc06fd4 100644 --- a/meson.build +++ b/meson.build @@ -227,6 +227,7 @@ stm32f405_src = ['platform/mcu/STM32F4xx/boot/startup.cpp', 'platform/mcu/STM32F4xx/drivers/SPI2.c', 'platform/mcu/STM32F4xx/drivers/USART3.cpp', 'platform/mcu/STM32F4xx/drivers/flash.c', + 'platform/mcu/STM32F4xx/drivers/rng.c', 'platform/drivers/audio/stm32_dac.cpp', 'platform/drivers/audio/stm32_adc.cpp', 'platform/drivers/audio/stm32_pwm.cpp', @@ -250,6 +251,7 @@ mk22fn512_src = ['platform/mcu/MK22FN512xxx12/boot/startup.cpp', 'platform/mcu/MK22FN512xxx12/drivers/gpio.c', 'platform/mcu/MK22FN512xxx12/drivers/delays.cpp', 'platform/mcu/MK22FN512xxx12/drivers/I2C0.c', + 'platform/mcu/MK22FN512xxx12/drivers/rng.c', 'platform/mcu/MK22FN512xxx12/drivers/usb/usb_device_cdc_acm.c', 'platform/mcu/MK22FN512xxx12/drivers/usb/usb_device_ch9.c', 'platform/mcu/MK22FN512xxx12/drivers/usb/usb_device_dci.c', @@ -280,6 +282,7 @@ linux_platform_src = ['platform/targets/linux/emulator/emulator.c', 'platform/drivers/NVM/nvmem_linux.c', 'platform/drivers/GPS/GPS_linux.c', 'platform/mcu/x86_64/drivers/delays.c', + 'platform/mcu/x86_64/drivers/rng.cpp', 'platform/drivers/baseband/radio_linux.cpp', 'platform/drivers/audio/audio_linux.c', 'platform/targets/linux/platform.c', diff --git a/openrtx/include/peripherals/rng.h b/openrtx/include/peripherals/rng.h new file mode 100644 index 00000000..a837d49f --- /dev/null +++ b/openrtx/include/peripherals/rng.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * Copyright (C) 2023 by Federico Amedeo Izzo IU2NUO, * + * Niccolò Izzo IU2KIN * + * Frederik Saraci IU2NRO * + * Silvano Seva IU2KWO * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, see * + ***************************************************************************/ + +#ifndef RNG_H +#define RNG_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Driver for Random Number Generator. + */ + +/** + * Initialise the RNG driver. + */ +void rng_init(); + +/** + * Shut down the RNG module. + */ +void rng_terminate(); + +/** + * Generate a 32 bit random number. + * + * @return random number. + */ +uint32_t rng_get(); + +#ifdef __cplusplus +} +#endif + +#endif /* INTERFACES_GPS_H */ diff --git a/platform/mcu/MK22FN512xxx12/drivers/rng.c b/platform/mcu/MK22FN512xxx12/drivers/rng.c new file mode 100644 index 00000000..8df3575f --- /dev/null +++ b/platform/mcu/MK22FN512xxx12/drivers/rng.c @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2023 by Federico Amedeo Izzo IU2NUO, * + * Niccolò Izzo IU2KIN * + * Frederik Saraci IU2NRO * + * Silvano Seva IU2KWO * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, see * + ***************************************************************************/ + +#include +#include + +void rng_init() +{ + SIM->SCGC6 |= SIM_SCGC6_RNGA(1); + RNG->CR |= RNG_CR_GO(1); +} + +void rng_terminate() +{ + SIM->SCGC6 &= ~SIM_SCGC6_RNGA(1); +} + +uint32_t rng_get() +{ + // Wait until there is some data + while((RNG->SR & RNG_SR_OREG_LVL_MASK) == 0) ; + + return RNG->OR; +} diff --git a/platform/mcu/STM32F4xx/drivers/rng.c b/platform/mcu/STM32F4xx/drivers/rng.c new file mode 100644 index 00000000..96a5afe5 --- /dev/null +++ b/platform/mcu/STM32F4xx/drivers/rng.c @@ -0,0 +1,76 @@ +/*************************************************************************** + * Copyright (C) 2023 by Federico Amedeo Izzo IU2NUO, * + * Niccolò Izzo IU2KIN * + * Frederik Saraci IU2NRO * + * Silvano Seva IU2KWO * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, see * + ***************************************************************************/ + +#include +#include +#include +#include + +static uint32_t oldValue = 0; + +void rng_init() +{ + RCC->AHB2ENR |= RCC_AHB2ENR_RNGEN; + __DSB(); +} + +void rng_terminate() +{ + RCC->AHB2ENR &= ~RCC_AHB2ENR_RNGEN; + __DSB(); +} + +uint32_t rng_get() +{ + uint32_t value; + + RNG->CR = RNG_CR_RNGEN; + + /* + * The datasheet says that the RNG takes 40 clock cycles of the 48MHz + * clock to generate a number, that is around 0.83us. It has not much + * sense to put a delay here, we can just spin a bit and wait. + */ + while(1) + { + uint32_t status = RNG->SR; + + // Got a new number, return it only if different from the previous one + if((status & RNG_SR_DRDY) != 0) + { + value = RNG->DR; + if(value != oldValue) + break; + } + + // Error, "power cycle" the RNG and retry + if((status & (RNG_SR_SECS | RNG_SR_CECS)) != 0) + { + RNG->CR = 0; + delayUs(1); + RNG->CR = RNG_CR_RNGEN; + } + } + + RNG->CR = 0; + oldValue = value; + + return value; +} diff --git a/platform/mcu/x86_64/drivers/rng.cpp b/platform/mcu/x86_64/drivers/rng.cpp new file mode 100644 index 00000000..c7df19ff --- /dev/null +++ b/platform/mcu/x86_64/drivers/rng.cpp @@ -0,0 +1,44 @@ +/*************************************************************************** + * Copyright (C) 2023 by Federico Amedeo Izzo IU2NUO, * + * Niccolò Izzo IU2KIN * + * Frederik Saraci IU2NRO * + * Silvano Seva IU2KWO * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, see * + ***************************************************************************/ + +#include +#include +#include + +static std::mt19937 rng; + +void rng_init() +{ + std::random_device seed; + rng.seed(seed()); +} + +void rng_terminate() +{ + +} + +uint32_t rng_get() +{ + std::uniform_int_distribution< uint32_t > + distribution(0, std::numeric_limits::max()); + + return distribution(rng); +}