From cbbd97e1bd1ac6c7bcdc5b4ad9e56272c7471d84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Mon, 7 Sep 2020 20:47:56 +0200 Subject: [PATCH] Issue #20: Implement driver for RNG --- stm-firmware/Makefile | 1 + stm-firmware/include/stm-periph/rng.h | 42 ++++++++++++++++ stm-firmware/stm-periph/rng.c | 70 +++++++++++++++++++++++++++ 3 files changed, 113 insertions(+) create mode 100644 stm-firmware/include/stm-periph/rng.h create mode 100644 stm-firmware/stm-periph/rng.c diff --git a/stm-firmware/Makefile b/stm-firmware/Makefile index 701f726..ebd77b1 100644 --- a/stm-firmware/Makefile +++ b/stm-firmware/Makefile @@ -36,6 +36,7 @@ DEFINES += -DSHELLMATTA_HELP_ALIAS=\"?\" # RCC Manager CFILES += stm-periph/clock-enable-manager.c CFILES += stm-periph/uart.c stm-periph/dma-ring-buffer.c stm-periph/backup-ram.c +CFILES += stm-periph/rng.c CFILES += digio.c CFILES += stm-periph/unique-id.c CFILES += calibration.c diff --git a/stm-firmware/include/stm-periph/rng.h b/stm-firmware/include/stm-periph/rng.h new file mode 100644 index 0000000..e8d9d7a --- /dev/null +++ b/stm-firmware/include/stm-periph/rng.h @@ -0,0 +1,42 @@ +/* Reflow Oven Controller + * + * Copyright (C) 2020 Mario Hüttel + * + * This file is part of the Reflow Oven Controller Project. + * + * The reflow oven controller is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * GDSII-Converter 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 the reflow oven controller project. + * If not, see . + */ + +#ifndef __STM_RNG_H__ +#define __STM_RNG_H__ + +#include +#include + +enum random_number_error { + RNG_ERROR_OK = 0, + RNG_ERROR_INACT, + RNG_ERROR_INTERNAL_ERROR, + RNG_ERROR_NOT_READY +}; + +void random_number_gen_init(bool int_enable); + +void random_number_gen_deinit(); + +void random_number_gen_reset(bool int_en); + +enum random_number_error random_number_gen_get_number(uint32_t *random_number, bool wait_for_valid_value); + +#endif /* __STM_RNG_H__ */ diff --git a/stm-firmware/stm-periph/rng.c b/stm-firmware/stm-periph/rng.c new file mode 100644 index 0000000..042e061 --- /dev/null +++ b/stm-firmware/stm-periph/rng.c @@ -0,0 +1,70 @@ +/* Reflow Oven Controller + * + * Copyright (C) 2020 Mario Hüttel + * + * This file is part of the Reflow Oven Controller Project. + * + * The reflow oven controller is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * The Reflow Oven Control Firmware 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 the reflow oven controller project. + * If not, see . + */ + +#include +#include +#include + +void random_number_gen_init(bool int_enable) +{ + rcc_manager_enable_clock(&RCC->AHB2ENR, BITMASK_TO_BITNO(RCC_AHB2ENR_RNGEN)); + __DSB(); + + random_number_gen_reset(int_enable); +} + +void random_number_gen_deinit() +{ + RNG->CR = 0; + __DSB(); + rcc_manager_disable_clock(&RCC->AHB2ENR, BITMASK_TO_BITNO(RCC_AHB2ENR_RNGEN)); +} + +void random_number_gen_reset(bool int_en) +{ + RNG->CR = 0; + __DSB(); + RNG->CR = RNG_CR_RNGEN | (int_en ? RNG_CR_IE : 0U); +} + +enum random_number_error random_number_gen_get_number(uint32_t *random_number, bool wait_for_valid_value) +{ + bool value_ready; + + if (!(RNG->CR & RNG_CR_RNGEN)) + return RNG_ERROR_INACT; + + if (RNG->SR & RNG_SR_SEIS || RNG->SR & RNG_SR_CEIS) { + /* Error detected */ + return RNG_ERROR_INTERNAL_ERROR; + } + + /* Check if the value is ready. Wait if wait_for_valid_value is true */ + do { + value_ready = !!(RNG->SR & RNG_SR_DRDY); + } while (!value_ready && wait_for_valid_value); + + /* If the value is valid, return it */ + if (value_ready && random_number) + *random_number = RNG->DR; + + /* Return from function with proper status */ + return (value_ready ? RNG_ERROR_OK : RNG_ERROR_NOT_READY); +}