Finished timer refactor
This commit is contained in:
@@ -36,6 +36,15 @@ static volatile TIM_TypeDef* TIM_TABLE[6] = {
|
|||||||
TIM16,
|
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_TIM1 TimerManager::get(Timer_Key::S_TIM1)
|
||||||
#define SHAL_TIM2 TimerManager::get(Timer_Key::S_TIM2)
|
#define SHAL_TIM2 TimerManager::get(Timer_Key::S_TIM2)
|
||||||
#define SHAL_TIM6 TimerManager::get(Timer_Key::S_TIM6)
|
#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)];
|
volatile TIM_TypeDef* tim = TIM_TABLE[static_cast<uint8_t>(key)];
|
||||||
|
|
||||||
res.reg = &tim->CR1;
|
res.reg = &tim->DIER;
|
||||||
return res;
|
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)];
|
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;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Get TIMER_KEY peripheral struct including bus register, enable mask, TIMER_KEY mask
|
//Get TIMER_KEY peripheral struct including bus register, enable mask, TIMER_KEY mask
|
||||||
static inline SHAL_TIM_RCC_Register getTimerRCC(Timer_Key t) {
|
static inline SHAL_TIM_RCC_Register getTimerRCC(Timer_Key t) {
|
||||||
switch(t) {
|
switch(t) {
|
||||||
case Timer_Key::S_TIM1: return {&RCC->APB2ENR, RCC_APB2ENR_TIM1EN_Pos};
|
case Timer_Key::S_TIM1: return {&RCC->APB2ENR, RCC_APB2ENR_TIM1EN};
|
||||||
case Timer_Key::S_TIM2: return {&RCC->APB1ENR1, RCC_APB1ENR1_TIM2EN_Pos};
|
case Timer_Key::S_TIM2: return {&RCC->APB1ENR1, RCC_APB1ENR1_TIM2EN};
|
||||||
case Timer_Key::S_TIM6: return {&RCC->APB1ENR1, RCC_APB1ENR1_TIM6EN_Pos};
|
case Timer_Key::S_TIM6: return {&RCC->APB1ENR1, RCC_APB1ENR1_TIM6EN};
|
||||||
case Timer_Key::S_TIM7: return {&RCC->APB1ENR1, RCC_APB1ENR1_TIM7EN_Pos};
|
case Timer_Key::S_TIM7: return {&RCC->APB1ENR1, RCC_APB1ENR1_TIM7EN};
|
||||||
case Timer_Key::S_TIM15: return {&RCC->APB2ENR, RCC_APB2ENR_TIM15EN_Pos};
|
case Timer_Key::S_TIM15: return {&RCC->APB2ENR, RCC_APB2ENR_TIM15EN};
|
||||||
case Timer_Key::S_TIM16: return {&RCC->APB2ENR, RCC_APB2ENR_TIM16EN_Pos};
|
case Timer_Key::S_TIM16: return {&RCC->APB2ENR, RCC_APB2ENR_TIM16EN};
|
||||||
case Timer_Key::NUM_TIMERS:
|
case Timer_Key::NUM_TIMERS:
|
||||||
case Timer_Key::S_TIM_INVALID:
|
case Timer_Key::S_TIM_INVALID:
|
||||||
assert(false);
|
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) {
|
static inline IRQn_Type getTimerIRQn(Timer_Key t) {
|
||||||
switch(t) {
|
return IRQN_TABLE[static_cast<uint8_t>(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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -15,9 +15,9 @@
|
|||||||
|
|
||||||
#define DEFINE_TIMER_IRQ(key, irq_handler) \
|
#define DEFINE_TIMER_IRQ(key, irq_handler) \
|
||||||
extern "C" void irq_handler(void) { \
|
extern "C" void irq_handler(void) { \
|
||||||
auto tim_reg = getTimerRegister(key); \
|
auto tim_status_reg = getTimerStatusRegister(key) \
|
||||||
if (tim_reg->SR & TIM_SR_UIF) { \
|
if (*tim_status_reg.reg & tim_status_reg.update_interrupt_flag_mask) { \
|
||||||
tim_reg->SR &= ~TIM_SR_UIF; /* clear flag */ \
|
SHAL_clear_mask(tim_status_reg.reg,tim_status_reg.update_interrupt_flag_mask) /* clear flag */ \
|
||||||
auto cb = timer_callbacks[static_cast<int>(key)]; \
|
auto cb = timer_callbacks[static_cast<int>(key)]; \
|
||||||
if (cb) cb(); \
|
if (cb) cb(); \
|
||||||
}; \
|
}; \
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
struct SHAL_TIM_RCC_Register{
|
struct SHAL_TIM_RCC_Register{
|
||||||
volatile uint32_t* reg;
|
volatile uint32_t* reg;
|
||||||
uint32_t offset;
|
uint32_t enable_mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SHAL_TIM_Control_Register_1 {
|
struct SHAL_TIM_Control_Register_1 {
|
||||||
@@ -35,4 +35,14 @@ struct SHAL_TIM_Event_Generation_Register {
|
|||||||
uint32_t update_generation_mask;
|
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
|
#endif //SHMINGO_HAL_SHAL_TIM_TYPES_H
|
||||||
|
|||||||
@@ -25,25 +25,30 @@ void Timer::start() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Timer::stop() {
|
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) {
|
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) {
|
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() {
|
void Timer::enableInterrupt() {
|
||||||
getTimerRegister(TIMER_KEY)->DIER |= TIM_DIER_UIE;
|
auto dma_ier = getTimerDMAInterruptEnableRegister(m_key);
|
||||||
NVIC_EnableIRQ(getTimerIRQn(TIMER_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) {
|
void Timer::init(uint32_t prescaler, uint32_t autoReload) {
|
||||||
TIM_RCC_Enable rcc = getTimerRCC(TIMER_KEY);
|
SHAL_TIM_RCC_Register rcc = getTimerRCC(m_key);
|
||||||
*rcc.busEnableReg |= (1 << rcc.offset);
|
SHAL_apply_bitmask(rcc.reg,rcc.enable_mask);
|
||||||
|
|
||||||
setPrescaler(prescaler);
|
setPrescaler(prescaler);
|
||||||
setARR(autoReload);
|
setARR(autoReload);
|
||||||
@@ -58,11 +63,9 @@ Timer &TimerManager::get(Timer_Key timer_key) {
|
|||||||
Timer& selected = timers[static_cast<int>(timer_key)];
|
Timer& selected = timers[static_cast<int>(timer_key)];
|
||||||
|
|
||||||
//Timer queried is not initialized yet (defaults to invalid)
|
//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
|
timers[static_cast<int>(timer_key)] = Timer(timer_key); //Initialize TIMER_KEY
|
||||||
}
|
}
|
||||||
|
|
||||||
return timers[static_cast<int>(timer_key)];
|
return timers[static_cast<int>(timer_key)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user