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 */