diff --git a/meson.build b/meson.build index 925a7011..b3ec0582 100644 --- a/meson.build +++ b/meson.build @@ -214,6 +214,7 @@ stm32f405_src = ['platform/mcu/STM32F4xx/boot/startup.cpp', 'platform/mcu/STM32F4xx/drivers/USART3.cpp', 'platform/mcu/STM32F4xx/drivers/flash.c', 'platform/mcu/STM32F4xx/drivers/rng.c', + 'platform/mcu/STM32F4xx/drivers/rcc.c', 'platform/mcu/STM32F4xx/drivers/i2c_stm32.c', 'platform/mcu/STM32F4xx/drivers/spi_stm32.c', 'platform/mcu/STM32F4xx/drivers/adc_stm32.c', diff --git a/platform/mcu/STM32F4xx/drivers/rcc.c b/platform/mcu/STM32F4xx/drivers/rcc.c new file mode 100644 index 00000000..07fd03f9 --- /dev/null +++ b/platform/mcu/STM32F4xx/drivers/rcc.c @@ -0,0 +1,68 @@ +/*************************************************************************** + * Copyright (C) 2024 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 "rcc.h" + +static uint32_t busClockFreq[PERIPH_BUS_NUM] = {0}; + +static void updateBusClockFreq(const uint8_t bus) +{ + uint32_t preBits; + uint32_t clkDiv = 1; + + switch(bus) + { + case PERIPH_BUS_AHB: + preBits = (RCC->CFGR >> 4) & 0x0F; + if((preBits & 0x08) != 0) + clkDiv = 1 << ((preBits & 0x07) + 1); + break; + + case PERIPH_BUS_APB1: + preBits = (RCC->CFGR >> 10) & 0x07; + if((preBits & 0x04) != 0) + clkDiv = 1 << ((preBits & 0x03) + 1); + break; + + case PERIPH_BUS_APB2: + preBits = (RCC->CFGR >> 13) & 0x07; + if((preBits & 0x04) != 0) + clkDiv = 1 << ((preBits & 0x03) + 1); + break; + + default: + break; + } + + busClockFreq[bus] = SystemCoreClock / clkDiv; +} + +uint32_t rcc_getBusClock(const uint8_t bus) +{ + if(bus >= PERIPH_BUS_NUM) + return 0; + + if(busClockFreq[bus] == 0) + updateBusClockFreq(bus); + + return busClockFreq[bus]; +} diff --git a/platform/mcu/STM32F4xx/drivers/rcc.h b/platform/mcu/STM32F4xx/drivers/rcc.h new file mode 100644 index 00000000..2161ce0a --- /dev/null +++ b/platform/mcu/STM32F4xx/drivers/rcc.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (C) 2024 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 RCC_H +#define RCC_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Enumeration type for STM32 internal busses. + */ +enum PeriphBus +{ + PERIPH_BUS_AHB = 0, + PERIPH_BUS_APB1 = 1, + PERIPH_BUS_APB2 = 2, + + PERIPH_BUS_NUM +}; + +/** + * Get the clock frequency of a given peripheral bus. + * + * @param bus: bus identifier. + * @return bus clock frequency in Hz or zero in case of errors. + */ +uint32_t rcc_getBusClock(const uint8_t bus); + +#ifdef __cplusplus +} +#endif + +#endif /* RCC_H */