From d092ccd36292364c8557c87b1daa872f3944023f Mon Sep 17 00:00:00 2001 From: Luca Date: Thu, 28 Aug 2025 22:02:08 -0700 Subject: [PATCH] Made timer constructor unaccessable by user --- Core/Include/Reg/SHAL_TIM_REG.h | 26 +++++++++++++++++++------- Core/Include/SHAL_TIM.h | 23 ++++++++++++++++++++--- Core/Src/Reg/SHAL_TIM.cpp | 19 +++++++++++++++++++ Core/Src/main.cpp | 4 ++-- 4 files changed, 60 insertions(+), 12 deletions(-) diff --git a/Core/Include/Reg/SHAL_TIM_REG.h b/Core/Include/Reg/SHAL_TIM_REG.h index 2f369bb..8295639 100644 --- a/Core/Include/Reg/SHAL_TIM_REG.h +++ b/Core/Include/Reg/SHAL_TIM_REG.h @@ -2,8 +2,10 @@ #define SHAL_TIM_REG_H #include +#include #include + enum class Bus { AHB, APB1, @@ -25,7 +27,8 @@ enum class Timer_Key { //For STM32F072 S_TIM15, S_TIM16, S_TIM17, - NUM_TIMERS + NUM_TIMERS, + S_TIM_INVALID }; @@ -39,10 +42,13 @@ constexpr RCC_Peripheral getTimerRCC(Timer_Key t) { case Timer_Key::S_TIM15: return {Bus::APB2, &RCC->APB2ENR, RCC_APB2ENR_TIM15EN}; case Timer_Key::S_TIM16: return {Bus::APB2, &RCC->APB2ENR, RCC_APB2ENR_TIM16EN}; case Timer_Key::S_TIM17: return {Bus::APB2, &RCC->APB2ENR, RCC_APB2ENR_TIM17EN}; - case Timer_Key::NUM_TIMERS: return {Bus::INVALID, nullptr, 0};; + case Timer_Key::NUM_TIMERS: + case Timer_Key::S_TIM_INVALID: + assert(false); + return {Bus::INVALID, nullptr, 0};; //Unreachable } - return {Bus::APB2, &RCC->APB2ENR, RCC_APB2ENR_TIM1EN}; + __builtin_unreachable(); } //Get actual register value based on enum @@ -55,9 +61,12 @@ constexpr volatile TIM_TypeDef* getTimerRegister(Timer_Key t) { case Timer_Key::S_TIM15: return TIM15; case Timer_Key::S_TIM16: return TIM16; case Timer_Key::S_TIM17: return TIM17; - case Timer_Key::NUM_TIMERS: return nullptr; + case Timer_Key::NUM_TIMERS: + case Timer_Key::S_TIM_INVALID: + assert(false); + return nullptr; //Unreachable } - return TIM1; + __builtin_unreachable(); } constexpr IRQn_Type getIRQn(Timer_Key t) { @@ -69,9 +78,12 @@ constexpr IRQn_Type getIRQn(Timer_Key t) { case Timer_Key::S_TIM15: return TIM15_IRQn; case Timer_Key::S_TIM16: return TIM16_IRQn; case Timer_Key::S_TIM17: return TIM17_IRQn; - case Timer_Key::NUM_TIMERS: return TIM1_BRK_UP_TRG_COM_IRQn; + case Timer_Key::NUM_TIMERS: + case Timer_Key::S_TIM_INVALID: + assert(false); + return TIM1_BRK_UP_TRG_COM_IRQn; //Unreachable } - return TIM1_BRK_UP_TRG_COM_IRQn; + __builtin_unreachable(); } diff --git a/Core/Include/SHAL_TIM.h b/Core/Include/SHAL_TIM.h index 024b38a..a1022b8 100644 --- a/Core/Include/SHAL_TIM.h +++ b/Core/Include/SHAL_TIM.h @@ -4,10 +4,11 @@ #include "SHAL_TIM_REG.h" #include "SHAL_TIM_CALLBACK.h" -class Timer { -public: +#include - explicit Timer(Timer_Key t); +class Timer { + friend class TimerManager; +public: //Starts the counter void start(); @@ -31,9 +32,25 @@ public: private: + explicit Timer(Timer_Key t); + Timer(); + Timer_Key timer; volatile TIM_TypeDef* timer_reg; }; +#define getTimer(timer_key) TimerManager::get(timer_key); + +//Manages all timers so user does not have to personally initialize +class TimerManager{ +public: + + static Timer& get(Timer_Key); + TimerManager() = delete; + +private: + inline static Timer timers[static_cast(Timer_Key::NUM_TIMERS)] = {}; +}; + #endif \ No newline at end of file diff --git a/Core/Src/Reg/SHAL_TIM.cpp b/Core/Src/Reg/SHAL_TIM.cpp index 3322ff5..cb432d0 100644 --- a/Core/Src/Reg/SHAL_TIM.cpp +++ b/Core/Src/Reg/SHAL_TIM.cpp @@ -3,12 +3,17 @@ // #include "SHAL_TIM.h" +#include Timer::Timer(Timer_Key t) : timer(t), timer_reg(getTimerRegister(t)){ RCC_Peripheral rcc = getTimerRCC(timer); *rcc.reg |= rcc.bitmask; } +Timer::Timer() : timer(Timer_Key::S_TIM_INVALID), timer_reg(nullptr){ + +} + void Timer::start() { timer_reg->CR1 |= TIM_CR1_CEN; timer_reg->EGR |= TIM_EGR_UG; //load prescaler reg and ARR @@ -33,3 +38,17 @@ void Timer::enableInterrupt() { } +Timer &TimerManager::get(Timer_Key timer_key) { + + //Ensure that we don't try to get invalid timers + assert(timer_key != Timer_Key::S_TIM_INVALID && timer_key != Timer_Key::NUM_TIMERS); + + Timer& selected = timers[static_cast(timer_key)]; + + //Timer queried is not initialized yet (defaults to invalid) + if(selected.timer == Timer_Key::S_TIM_INVALID){ + timers[static_cast(timer_key)] = Timer(timer_key); //Initialize timer + } + + return timers[static_cast(timer_key)]; +} diff --git a/Core/Src/main.cpp b/Core/Src/main.cpp index bfc4d14..035e611 100644 --- a/Core/Src/main.cpp +++ b/Core/Src/main.cpp @@ -16,10 +16,10 @@ int main() { RCC->AHBENR |= RCC_AHBENR_GPIOAEN; RCC->AHBENR |= RCC_AHBENR_GPIOBEN; - auto timer2 = Timer(Timer_Key::S_TIM2); + Timer timer2 = getTimer(Timer_Key::S_TIM2); timer2.setPrescaler(8000 - 1); - timer2.setARR(250 - 1); + timer2.setARR(500 - 1); timer2.setCallbackFunc(tim2Handler); timer2.start();