Abstracted registers for PWM and other timer modes

This commit is contained in:
Ea-r-th
2025-11-05 18:15:32 -08:00
parent aa7a041946
commit 12aedf1ff9
8 changed files with 198 additions and 9 deletions

View File

@@ -53,7 +53,6 @@ static IRQn_Type IRQN_TABLE[6] = {
#define SHAL_TIM16 TimerManager::get(Timer_Key::S_TIM16)
static inline SHAL_TIM_Status_Register getTimerStatusRegister(Timer_Key key){
SHAL_TIM_Status_Register res = {nullptr, TIM_SR_UIF};
@@ -66,7 +65,11 @@ static inline SHAL_TIM_Status_Register getTimerStatusRegister(Timer_Key key){
static inline SHAL_TIM_Control_Register_1 getTimerControlRegister1(Timer_Key key){
SHAL_TIM_Control_Register_1 res = {nullptr, TIM_CR1_CEN_Msk, TIM_CR1_UDIS, TIM_CR1_OPM, TIM_CR1_CMS_Pos};
SHAL_TIM_Control_Register_1 res = {nullptr, TIM_CR1_CEN_Msk,
TIM_CR1_UDIS,
TIM_CR1_OPM,
TIM_CR1_CMS_Pos,
TIM_CR1_ARPE};
volatile TIM_TypeDef* tim = TIM_TABLE[static_cast<uint8_t>(key)];
@@ -131,6 +134,68 @@ static inline SHAL_TIM_RCC_Register getTimerRCC(Timer_Key t) {
__builtin_unreachable();
}
static inline SHAL_TIM_Capture_Compare_Mode_Registers_Input getTimerCaptureCompareModeRegisters(Timer_Key key){
SHAL_TIM_Capture_Compare_Mode_Registers_Input res = {{nullptr,
nullptr},
TIM_CCMR1_CC1S_Pos,
TIM_CCMR1_IC1PSC_Pos,
TIM_CCMR1_IC1F_Pos,
TIM_CCMR1_CC2S_Pos,
TIM_CCMR1_IC2PSC_Pos,
TIM_CCMR1_IC2F_Pos
};
volatile TIM_TypeDef* tim = TIM_TABLE[static_cast<uint8_t>(key)];
res.regs[0] = &tim->CCMR1;
res.regs[1] = &tim->CCMR2;
return res;
}
static inline SHAL_TIM_Capture_Compare_Mode_Registers_Output
getTimerCaptureCompareModeRegistersOutput(Timer_Key key) {
SHAL_TIM_Capture_Compare_Mode_Registers_Output res = {
{nullptr, nullptr},
TIM_CCMR1_CC1S_Pos, //Channel 1 Capture/Compare selection
TIM_CCMR1_OC1FE_Pos, //Channel 1 Fast enable
TIM_CCMR1_OC1PE_Pos, //Channel 1 Preload enable
TIM_CCMR1_OC1M_Pos, //Channel 1 Mode (OC1M)
TIM_CCMR1_OC1CE_Pos, //Channel 1 Clear enable
TIM_CCMR1_CC2S_Pos, //Channel 2 Capture/Compare selection
TIM_CCMR1_OC2FE_Pos, //Channel 2 Fast enable
TIM_CCMR1_OC2PE_Pos, //Channel 2 Preload enable
TIM_CCMR1_OC2M_Pos, //Channel 2 Mode (OC2M)
TIM_CCMR1_OC2CE_Pos //Channel 2 Clear enable
};
volatile TIM_TypeDef* tim = TIM_TABLE[static_cast<uint8_t>(key)];
res.regs[0] = &tim->CCMR1;
res.regs[1] = &tim->CCMR2;
return res;
}
static inline SHAL_TIM_Break_Dead_Time_Register getBreakDeadTimeRegister(Timer_Key key){
SHAL_TIM_Break_Dead_Time_Register res = {nullptr, 1UL << 15};
volatile TIM_TypeDef* tim = TIM_TABLE[static_cast<uint8_t>(key)];
res.reg = &tim->BDTR;
return res;
}
static inline SHAL_TIM_Capture_Compare_Enable_Register getTimerCaptureCompareEnableRegister(Timer_Key key){
volatile TIM_TypeDef* tim = TIM_TABLE[static_cast<uint8_t>(key)];
return {&tim->CCER};
}
static inline SHAL_TIM_Capture_Compare_Register getTimerCaptureCompareRegister(Timer_Key key){
volatile TIM_TypeDef* tim = TIM_TABLE[static_cast<uint8_t>(key)];
return {&tim->CCR2};
}
//Get timer IRQN from lookup table
static inline IRQn_Type getTimerIRQn(Timer_Key t) {

View File

@@ -38,6 +38,8 @@ public:
//Enable interrupts
void enableInterrupt();
void setPWMMode(SHAL_Timer_Channel channel, SHAL_Timer_Channel_Main_Output_Mode mainOutputMode, SHAL_Timer_Channel_Complimentary_Output_Mode complimentaryOutputMode);
//Set TIMER_KEY IRQ callback function
void setCallbackFunc(TimerCallback callback){
registerTimerCallback(m_key, callback);

View File

@@ -18,6 +18,7 @@ struct SHAL_TIM_Control_Register_1 {
uint32_t update_disable_mask;
uint32_t one_pulse_mode_mask;
uint32_t center_align_mode_offset;
uint32_t auto_reload_preload_enable_mask;
};
struct SHAL_TIM_DMA_Interrupt_Enable_Register {
@@ -45,4 +46,81 @@ struct SHAL_TIM_Auto_Reload_Register {
uint32_t offset;
};
#endif //SHMINGO_HAL_SHAL_TIM_TYPES_H
struct SHAL_TIM_Capture_Compare_Mode_Registers_Input {
volatile uint32_t* regs[2];
uint32_t input_capture_1_filter_offset;
uint32_t input_capture_1_prescaler_offset;
uint32_t capture_compare_1_selection_offset;
uint32_t input_capture_2_filter_offset;
uint32_t input_capture_2_prescaler_offset;
uint32_t capture_compare_2_selection_offset;
};
struct SHAL_TIM_Capture_Compare_Mode_Registers_Output {
volatile uint32_t* regs[2];
uint32_t capture_compare_1_selection_offset;
uint32_t output_compare_1_fast_enable_offset;
uint32_t output_compare_1_preload_enable_offset;
uint32_t output_compare_1_mode_offset;
uint32_t output_compare_1_clear_enable_offset;
uint32_t capture_compare_2_selection_offset;
uint32_t output_compare_2_fast_enable_offset;
uint32_t output_compare_2_preload_enable_offset;
uint32_t output_compare_2_mode_offset;
uint32_t output_compare_2_clear_enable_offset;
};
struct SHAL_TIM_Break_Dead_Time_Register {
volatile uint32_t* reg;
uint32_t main_output_enable_mask;
};
struct SHAL_TIM_Capture_Compare_Enable_Register {
volatile uint32_t* reg;
};
struct SHAL_TIM_Capture_Compare_Register {
volatile uint32_t* reg;
};
enum class SHAL_TIM_Output_Compare_Mode : uint8_t {
Frozen = 0b000, //Output compare frozen
ActiveOnMatch = 0b001, //Set output to active level on match
InactiveOnMatch = 0b010, //Set output to inactive level on match
Toggle = 0b011, //Toggle output on match
ForceInactive = 0b100, //Force output to inactive
ForceActive = 0b101, //Force output to active
PWMMode1 = 0b110, //PWM mode 1 (active until compare match)
PWMMode2 = 0b111, //PWM mode 2 (inactive until compare match)
};
enum class SHAL_TIM_Output_Compare_Preload : uint8_t {
Disabled = 0b0, //CCRx register is updated immediately
Enabled = 0b1, //CCRx register is buffered; updated on update event (UEV)
};
enum class SHAL_Timer_Channel : uint8_t { //TODO change if other timers have fewer than 6 channels
CH1 = 0,
CH2 = 1,
CH3 = 2,
CH4 = 3,
CH5 = 4,
CH6 = 5,
};
enum class SHAL_Timer_Channel_Main_Output_Mode : uint8_t {
Disabled = 0b00,
Polarity_Normal = 0b01,
Polarity_Reversed = 0b11,
};
enum class SHAL_Timer_Channel_Complimentary_Output_Mode : uint8_t {
Disabled = 0b00,
Polarity_Normal = 0b01,
Polarity_Reversed = 0b11,
};
#endif //SHAL_TIM_TYPES_H