Finished timer refactor

This commit is contained in:
Ea-r-th
2025-10-17 01:16:11 -07:00
parent 6c8fa459f8
commit d846897296
4 changed files with 67 additions and 36 deletions

View File

@@ -36,6 +36,15 @@ static volatile TIM_TypeDef* TIM_TABLE[6] = {
TIM16,
};
static IRQn_Type IRQN_TABLE[6] = {
TIM1_TRG_COM_IRQn,
TIM2_IRQn,
TIM6_DAC_IRQn,
TIM7_IRQn,
TIM1_BRK_TIM15_IRQn,
TIM1_UP_TIM16_IRQn
};
#define SHAL_TIM1 TimerManager::get(Timer_Key::S_TIM1)
#define SHAL_TIM2 TimerManager::get(Timer_Key::S_TIM2)
#define SHAL_TIM6 TimerManager::get(Timer_Key::S_TIM6)
@@ -71,7 +80,7 @@ static inline SHAL_TIM_DMA_Interrupt_Enable_Register getTimerDMAInterruptEnableR
volatile TIM_TypeDef* tim = TIM_TABLE[static_cast<uint8_t>(key)];
res.reg = &tim->CR1;
res.reg = &tim->DIER;
return res;
}
@@ -81,19 +90,39 @@ static inline SHAL_TIM_Event_Generation_Register getTimerEventGenerationRegister
volatile TIM_TypeDef* tim = TIM_TABLE[static_cast<uint8_t>(key)];
res.reg = &tim->CR1;
res.reg = &tim->EGR;
return res;
}
static inline SHAL_TIM_Prescaler_Register getTimerPrescalerRegister(Timer_Key key){
SHAL_TIM_Prescaler_Register res = {nullptr, 1UL << 15};
volatile TIM_TypeDef* tim = TIM_TABLE[static_cast<uint8_t>(key)];
res.reg = &tim->PSC;
return res;
}
static inline SHAL_TIM_Auto_Reload_Register getTimerAutoReloadRegister(Timer_Key key){
SHAL_TIM_Auto_Reload_Register res = {nullptr, 1UL << 15};
volatile TIM_TypeDef* tim = TIM_TABLE[static_cast<uint8_t>(key)];
res.reg = &tim->ARR;
return res;
}
//Get TIMER_KEY peripheral struct including bus register, enable mask, TIMER_KEY mask
static inline SHAL_TIM_RCC_Register getTimerRCC(Timer_Key t) {
switch(t) {
case Timer_Key::S_TIM1: return {&RCC->APB2ENR, RCC_APB2ENR_TIM1EN_Pos};
case Timer_Key::S_TIM2: return {&RCC->APB1ENR1, RCC_APB1ENR1_TIM2EN_Pos};
case Timer_Key::S_TIM6: return {&RCC->APB1ENR1, RCC_APB1ENR1_TIM6EN_Pos};
case Timer_Key::S_TIM7: return {&RCC->APB1ENR1, RCC_APB1ENR1_TIM7EN_Pos};
case Timer_Key::S_TIM15: return {&RCC->APB2ENR, RCC_APB2ENR_TIM15EN_Pos};
case Timer_Key::S_TIM16: return {&RCC->APB2ENR, RCC_APB2ENR_TIM16EN_Pos};
case Timer_Key::S_TIM1: return {&RCC->APB2ENR, RCC_APB2ENR_TIM1EN};
case Timer_Key::S_TIM2: return {&RCC->APB1ENR1, RCC_APB1ENR1_TIM2EN};
case Timer_Key::S_TIM6: return {&RCC->APB1ENR1, RCC_APB1ENR1_TIM6EN};
case Timer_Key::S_TIM7: return {&RCC->APB1ENR1, RCC_APB1ENR1_TIM7EN};
case Timer_Key::S_TIM15: return {&RCC->APB2ENR, RCC_APB2ENR_TIM15EN};
case Timer_Key::S_TIM16: return {&RCC->APB2ENR, RCC_APB2ENR_TIM16EN};
case Timer_Key::NUM_TIMERS:
case Timer_Key::S_TIM_INVALID:
assert(false);
@@ -103,20 +132,9 @@ static inline SHAL_TIM_RCC_Register getTimerRCC(Timer_Key t) {
}
//Get timer IRQN from lookup table
static inline IRQn_Type getTimerIRQn(Timer_Key t) {
switch(t) {
case Timer_Key::S_TIM1: return TIM1_TRG_COM_IRQn;
case Timer_Key::S_TIM2: return TIM2_IRQn;
case Timer_Key::S_TIM6: return TIM6_DAC_IRQn;
case Timer_Key::S_TIM7: return TIM7_IRQn;
case Timer_Key::S_TIM15: return TIM1_BRK_TIM15_IRQn;
case Timer_Key::S_TIM16: return TIM1_UP_TIM16_IRQn;
case Timer_Key::NUM_TIMERS:
case Timer_Key::S_TIM_INVALID:
__builtin_unreachable();
}
__builtin_unreachable();
return IRQN_TABLE[static_cast<uint8_t>(t)];
}
#endif

View File

@@ -15,9 +15,9 @@
#define DEFINE_TIMER_IRQ(key, irq_handler) \
extern "C" void irq_handler(void) { \
auto tim_reg = getTimerRegister(key); \
if (tim_reg->SR & TIM_SR_UIF) { \
tim_reg->SR &= ~TIM_SR_UIF; /* clear flag */ \
auto tim_status_reg = getTimerStatusRegister(key) \
if (*tim_status_reg.reg & tim_status_reg.update_interrupt_flag_mask) { \
SHAL_clear_mask(tim_status_reg.reg,tim_status_reg.update_interrupt_flag_mask) /* clear flag */ \
auto cb = timer_callbacks[static_cast<int>(key)]; \
if (cb) cb(); \
}; \

View File

@@ -9,7 +9,7 @@
struct SHAL_TIM_RCC_Register{
volatile uint32_t* reg;
uint32_t offset;
uint32_t enable_mask;
};
struct SHAL_TIM_Control_Register_1 {
@@ -35,4 +35,14 @@ struct SHAL_TIM_Event_Generation_Register {
uint32_t update_generation_mask;
};
struct SHAL_TIM_Prescaler_Register {
volatile uint32_t* reg;
uint32_t offset;
};
struct SHAL_TIM_Auto_Reload_Register {
volatile uint32_t* reg;
uint32_t offset;
};
#endif //SHMINGO_HAL_SHAL_TIM_TYPES_H

View File

@@ -25,25 +25,30 @@ void Timer::start() {
}
void Timer::stop() {
getTimerRegister(TIMER_KEY)->CR1 &= ~TIM_CR1_CEN;
auto control_reg = getTimerControlRegister1(m_key);
SHAL_clear_bitmask(control_reg.reg, control_reg.counter_enable_mask); //Enable counter
}
void Timer::setPrescaler(uint16_t presc) {
getTimerRegister(TIMER_KEY)->PSC = presc;
auto prescaler_reg = getTimerPrescalerRegister(m_key);
SHAL_set_bits(prescaler_reg.reg, 16, presc, prescaler_reg.offset);
}
void Timer::setARR(uint16_t arr) {
getTimerRegister(TIMER_KEY)->ARR = arr;
auto autoreload_reg = getTimerAutoReloadRegister(m_key);
SHAL_set_bits(autoreload_reg.reg, 16, arr, autoreload_reg.offset);
}
void Timer::enableInterrupt() {
getTimerRegister(TIMER_KEY)->DIER |= TIM_DIER_UIE;
NVIC_EnableIRQ(getTimerIRQn(TIMER_KEY));
auto dma_ier = getTimerDMAInterruptEnableRegister(m_key);
SHAL_apply_bitmask(dma_ier.reg,dma_ier.update_interrupt_enable_mask);
NVIC_EnableIRQ(getTimerIRQn(m_key)); //Enable the IRQn in the NVIC
}
void Timer::init(uint32_t prescaler, uint32_t autoReload) {
TIM_RCC_Enable rcc = getTimerRCC(TIMER_KEY);
*rcc.busEnableReg |= (1 << rcc.offset);
SHAL_TIM_RCC_Register rcc = getTimerRCC(m_key);
SHAL_apply_bitmask(rcc.reg,rcc.enable_mask);
setPrescaler(prescaler);
setARR(autoReload);
@@ -58,11 +63,9 @@ Timer &TimerManager::get(Timer_Key timer_key) {
Timer& selected = timers[static_cast<int>(timer_key)];
//Timer queried is not initialized yet (defaults to invalid)
if(selected.TIMER_KEY == Timer_Key::S_TIM_INVALID){
if(selected.m_key == Timer_Key::S_TIM_INVALID){
timers[static_cast<int>(timer_key)] = Timer(timer_key); //Initialize TIMER_KEY
}
return timers[static_cast<int>(timer_key)];
}
}