Fixed PWM mode
This commit is contained in:
@@ -58,7 +58,7 @@ enum class GPIO_Alternate_Function_Mapping {
|
|||||||
A11_TIM1CH4 = 0x01,
|
A11_TIM1CH4 = 0x01,
|
||||||
A12_TIM1ETR = 0x01,
|
A12_TIM1ETR = 0x01,
|
||||||
A15_TIM2CH1 = 0x01,
|
A15_TIM2CH1 = 0x01,
|
||||||
B0_TIM2CH2N = 0x01,
|
B0_TIM1CH2N = 0x01,
|
||||||
B1_TIM1CH3N = 0x01,
|
B1_TIM1CH3N = 0x01,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -132,7 +132,7 @@ static inline SHAL_GPIO_Pullup_Pulldown_Register getGPIOPUPDRegister(const GPIO_
|
|||||||
|
|
||||||
static inline SHAL_GPIO_Alternate_Function_Register getGPIOAlternateFunctionRegister(const GPIO_Key key){
|
static inline SHAL_GPIO_Alternate_Function_Register getGPIOAlternateFunctionRegister(const GPIO_Key key){
|
||||||
|
|
||||||
uint32_t pinNumber = static_cast<uint8_t>(key); //Number of pin (We need 0-7 to be AFR 1 and 8-15 to be AFR 2)
|
uint32_t pinNumber = static_cast<uint8_t>(key) % 16; //Number of pin (We need 0-7 to be AFR 1 and 8-15 to be AFR 2)
|
||||||
uint32_t afrIndex = pinNumber < 8 ? 0 : 1;
|
uint32_t afrIndex = pinNumber < 8 ? 0 : 1;
|
||||||
|
|
||||||
volatile uint32_t* reg = &GPIO_TABLE[static_cast<uint8_t>(key) / 16]->AFR[afrIndex];
|
volatile uint32_t* reg = &GPIO_TABLE[static_cast<uint8_t>(key) / 16]->AFR[afrIndex];
|
||||||
|
|||||||
@@ -158,15 +158,15 @@ getTimerCaptureCompareModeRegistersOutput(Timer_Key key) {
|
|||||||
SHAL_TIM_Capture_Compare_Mode_Registers_Output res = {
|
SHAL_TIM_Capture_Compare_Mode_Registers_Output res = {
|
||||||
{nullptr, nullptr},
|
{nullptr, nullptr},
|
||||||
TIM_CCMR1_CC1S_Pos, //Channel 1 Capture/Compare selection
|
TIM_CCMR1_CC1S_Pos, //Channel 1 Capture/Compare selection
|
||||||
TIM_CCMR1_OC1FE_Pos, //Channel 1 Fast enable
|
TIM_CCMR1_OC1FE, //Channel 1 Fast enable
|
||||||
TIM_CCMR1_OC1PE_Pos, //Channel 1 Preload enable
|
TIM_CCMR1_OC1PE, //Channel 1 Preload enable
|
||||||
TIM_CCMR1_OC1M_Pos, //Channel 1 Mode (OC1M)
|
TIM_CCMR1_OC1M_Pos, //Channel 1 Mode (OC1M)
|
||||||
TIM_CCMR1_OC1CE_Pos, //Channel 1 Clear enable
|
TIM_CCMR1_OC1CE, //Channel 1 Clear enable
|
||||||
TIM_CCMR1_CC2S_Pos, //Channel 2 Capture/Compare selection
|
TIM_CCMR1_CC2S_Pos, //Channel 2 Capture/Compare selection
|
||||||
TIM_CCMR1_OC2FE_Pos, //Channel 2 Fast enable
|
TIM_CCMR1_OC2FE, //Channel 2 Fast enable
|
||||||
TIM_CCMR1_OC2PE_Pos, //Channel 2 Preload enable
|
TIM_CCMR1_OC2PE, //Channel 2 Preload enable
|
||||||
TIM_CCMR1_OC2M_Pos, //Channel 2 Mode (OC2M)
|
TIM_CCMR1_OC2M_Pos, //Channel 2 Mode (OC2M)
|
||||||
TIM_CCMR1_OC2CE_Pos //Channel 2 Clear enable
|
TIM_CCMR1_OC2CE //Channel 2 Clear enable
|
||||||
};
|
};
|
||||||
|
|
||||||
volatile TIM_TypeDef* tim = TIM_TABLE[static_cast<uint8_t>(key)];
|
volatile TIM_TypeDef* tim = TIM_TABLE[static_cast<uint8_t>(key)];
|
||||||
@@ -176,7 +176,7 @@ getTimerCaptureCompareModeRegistersOutput(Timer_Key key) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline SHAL_TIM_Break_Dead_Time_Register getBreakDeadTimeRegister(Timer_Key key){
|
static inline SHAL_TIM_Break_Dead_Time_Register getTimerBreakDeadTimeRegister(Timer_Key key){
|
||||||
|
|
||||||
SHAL_TIM_Break_Dead_Time_Register res = {nullptr, 1UL << 15};
|
SHAL_TIM_Break_Dead_Time_Register res = {nullptr, 1UL << 15};
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,11 @@ public:
|
|||||||
//Enable interrupts
|
//Enable interrupts
|
||||||
void enableInterrupt();
|
void enableInterrupt();
|
||||||
|
|
||||||
void setPWMMode(SHAL_Timer_Channel channel, SHAL_Timer_Channel_Main_Output_Mode mainOutputMode, SHAL_Timer_Channel_Complimentary_Output_Mode complimentaryOutputMode);
|
void setPWMMode(SHAL_Timer_Channel channel, SHAL_TIM_Output_Compare_Mode outputCompareMode, SHAL_Timer_Channel_Main_Output_Mode mainOutputMode, SHAL_Timer_Channel_Complimentary_Output_Mode complimentaryOutputMode);
|
||||||
|
|
||||||
|
/// Set the duty cycle for PWM
|
||||||
|
/// \param dutyCycle 10 * percentage (e.g. 500 = 50%)
|
||||||
|
void setPWMDutyCycle(uint32_t dutyCycle);
|
||||||
|
|
||||||
//Set TIMER_KEY IRQ callback function
|
//Set TIMER_KEY IRQ callback function
|
||||||
void setCallbackFunc(TimerCallback callback){
|
void setCallbackFunc(TimerCallback callback){
|
||||||
@@ -52,6 +56,7 @@ private:
|
|||||||
|
|
||||||
Timer_Key m_key;
|
Timer_Key m_key;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -59,15 +59,15 @@ struct SHAL_TIM_Capture_Compare_Mode_Registers_Input {
|
|||||||
struct SHAL_TIM_Capture_Compare_Mode_Registers_Output {
|
struct SHAL_TIM_Capture_Compare_Mode_Registers_Output {
|
||||||
volatile uint32_t* regs[2];
|
volatile uint32_t* regs[2];
|
||||||
uint32_t capture_compare_1_selection_offset;
|
uint32_t capture_compare_1_selection_offset;
|
||||||
uint32_t output_compare_1_fast_enable_offset;
|
uint32_t output_compare_1_fast_enable_mask;
|
||||||
uint32_t output_compare_1_preload_enable_offset;
|
uint32_t output_compare_1_preload_enable_mask;
|
||||||
uint32_t output_compare_1_mode_offset;
|
uint32_t output_compare_1_mode_offset;
|
||||||
uint32_t output_compare_1_clear_enable_offset;
|
uint32_t output_compare_1_clear_enable_mask;
|
||||||
uint32_t capture_compare_2_selection_offset;
|
uint32_t capture_compare_2_selection_offset;
|
||||||
uint32_t output_compare_2_fast_enable_offset;
|
uint32_t output_compare_2_fast_enable_mask;
|
||||||
uint32_t output_compare_2_preload_enable_offset;
|
uint32_t output_compare_2_preload_enable_mask;
|
||||||
uint32_t output_compare_2_mode_offset;
|
uint32_t output_compare_2_mode_offset;
|
||||||
uint32_t output_compare_2_clear_enable_offset;
|
uint32_t output_compare_2_clear_enable_mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SHAL_TIM_Break_Dead_Time_Register {
|
struct SHAL_TIM_Break_Dead_Time_Register {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ void Timer::start() {
|
|||||||
auto event_generation_reg = getTimerEventGenerationRegister(m_key);
|
auto event_generation_reg = getTimerEventGenerationRegister(m_key);
|
||||||
|
|
||||||
SHAL_apply_bitmask(control_reg.reg, control_reg.counter_enable_mask); //Enable counter
|
SHAL_apply_bitmask(control_reg.reg, control_reg.counter_enable_mask); //Enable counter
|
||||||
|
SHAL_apply_bitmask(control_reg.reg, control_reg.auto_reload_preload_enable_mask); //Preload enable (buffer)
|
||||||
SHAL_apply_bitmask(event_generation_reg.reg, event_generation_reg.update_generation_mask);
|
SHAL_apply_bitmask(event_generation_reg.reg, event_generation_reg.update_generation_mask);
|
||||||
|
|
||||||
enableInterrupt();
|
enableInterrupt();
|
||||||
@@ -54,19 +55,42 @@ void Timer::init(uint32_t prescaler, uint32_t autoReload) {
|
|||||||
setARR(autoReload);
|
setARR(autoReload);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Timer::setPWMMode(SHAL_Timer_Channel channel, SHAL_Timer_Channel_Main_Output_Mode mainOutputMode,
|
void Timer::setPWMMode(SHAL_Timer_Channel channel, SHAL_TIM_Output_Compare_Mode outputCompareMode, SHAL_Timer_Channel_Main_Output_Mode mainOutputMode,
|
||||||
SHAL_Timer_Channel_Complimentary_Output_Mode complimentaryOutputMode) {
|
SHAL_Timer_Channel_Complimentary_Output_Mode complimentaryOutputMode) {
|
||||||
|
|
||||||
uint8_t fullModeMask = static_cast<uint8_t>(mainOutputMode) | (static_cast<uint8_t>(complimentaryOutputMode) << 2);
|
|
||||||
uint32_t offset = static_cast<uint8_t>(channel) * 4;
|
|
||||||
|
|
||||||
auto ccer = getTimerCaptureCompareEnableRegister(m_key);
|
auto ccer = getTimerCaptureCompareEnableRegister(m_key);
|
||||||
|
auto ccmr1 = getTimerCaptureCompareModeRegistersOutput(m_key);
|
||||||
|
auto bdtr = getTimerBreakDeadTimeRegister(m_key);
|
||||||
|
|
||||||
if(static_cast<uint8_t>(m_key) > 3){
|
uint8_t fullChannelModeMask = static_cast<uint8_t>(mainOutputMode) | (static_cast<uint8_t>(complimentaryOutputMode) << 2);
|
||||||
fullModeMask &= (0b0011); //Clear bits for complimentary output since channels 4,5,6 don't support it
|
uint8_t channelNum = static_cast<uint8_t>(channel);
|
||||||
|
|
||||||
|
if (channelNum <= 3) {
|
||||||
|
|
||||||
|
uint32_t regNum = channelNum / 2; //TODO change later for support for channels 5 and 6
|
||||||
|
|
||||||
|
if (channelNum % 2 == 1) {
|
||||||
|
SHAL_set_bits(ccmr1.regs[regNum], 4, static_cast<uint8_t>(outputCompareMode),
|
||||||
|
ccmr1.output_compare_2_mode_offset);
|
||||||
|
} else {
|
||||||
|
SHAL_set_bits(ccmr1.regs[regNum], 4, static_cast<uint8_t>(outputCompareMode),
|
||||||
|
ccmr1.output_compare_1_mode_offset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SHAL_set_bits(ccer.reg,4,fullModeMask,offset);
|
uint32_t offset = channelNum * 4;
|
||||||
|
|
||||||
|
if (static_cast<uint8_t>(m_key) > 3) {
|
||||||
|
fullChannelModeMask &= (0b0011); //Clear bits for complimentary output since channels 4,5,6 don't support it
|
||||||
|
}
|
||||||
|
|
||||||
|
SHAL_set_bits(ccer.reg, 4, fullChannelModeMask, offset);
|
||||||
|
SHAL_apply_bitmask(bdtr.reg, bdtr.main_output_enable_mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Timer::setPWMDutyCycle(uint32_t dutyCycle) {
|
||||||
|
auto reg = getTimerCaptureCompareRegister(m_key);
|
||||||
|
SHAL_set_bits(reg.reg,16,dutyCycle,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,11 @@ GPIO_Key gpios[6] = {
|
|||||||
GPIO_Key::A7,
|
GPIO_Key::A7,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool isAlarmBeeping = false;
|
||||||
|
bool isCalibrateButtonHigh = false;
|
||||||
|
|
||||||
|
uint16_t sensorThresholds[6] = {4096,4096,4096,4096,4096,4096};
|
||||||
|
|
||||||
void timer2callback(){
|
void timer2callback(){
|
||||||
|
|
||||||
uint16_t val[6];
|
uint16_t val[6];
|
||||||
@@ -26,8 +31,24 @@ void timer2callback(){
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void b0PWM(){
|
void PWMToggle(){
|
||||||
PIN(B0).toggle();
|
|
||||||
|
if(!isAlarmBeeping){
|
||||||
|
SHAL_TIM1.start();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
SHAL_TIM1.stop();
|
||||||
|
}
|
||||||
|
isAlarmBeeping = !isAlarmBeeping;
|
||||||
|
}
|
||||||
|
|
||||||
|
void buttonCallback(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void calibrateSensors(){
|
||||||
|
PIN(B3).setHigh();
|
||||||
|
SHAL_TIM7.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
@@ -44,7 +65,10 @@ int main() {
|
|||||||
PIN(A6).setPinMode(PinMode::ANALOG_MODE);
|
PIN(A6).setPinMode(PinMode::ANALOG_MODE);
|
||||||
PIN(A7).setPinMode(PinMode::ANALOG_MODE);
|
PIN(A7).setPinMode(PinMode::ANALOG_MODE);
|
||||||
|
|
||||||
PIN(B0).setPinMode(PinMode::OUTPUT_MODE);
|
PIN(B0).setAlternateFunction(GPIO_Alternate_Function_Mapping::B0_TIM1CH2N);
|
||||||
|
|
||||||
|
PIN(B6).setPinMode(PinMode::INPUT_MODE);
|
||||||
|
PIN(B6).useAsExternalInterrupt(TriggerMode::RISING_FALLING_EDGE,buttonCallback);
|
||||||
|
|
||||||
SHAL_TIM2.init(4000000,400);
|
SHAL_TIM2.init(4000000,400);
|
||||||
|
|
||||||
@@ -52,11 +76,23 @@ int main() {
|
|||||||
SHAL_TIM2.enableInterrupt();
|
SHAL_TIM2.enableInterrupt();
|
||||||
SHAL_TIM2.start();
|
SHAL_TIM2.start();
|
||||||
|
|
||||||
SHAL_TIM6.init(4000000,1);
|
SHAL_TIM1.init(300,999);
|
||||||
SHAL_TIM6.setCallbackFunc(b0PWM);
|
SHAL_TIM1.setPWMMode(SHAL_Timer_Channel::CH2,SHAL_TIM_Output_Compare_Mode::PWMMode1,SHAL_Timer_Channel_Main_Output_Mode::Disabled,SHAL_Timer_Channel_Complimentary_Output_Mode::Polarity_Reversed);
|
||||||
|
SHAL_TIM1.setPWMDutyCycle(499);
|
||||||
|
SHAL_TIM1.start();
|
||||||
|
|
||||||
|
SHAL_TIM6.init(4000000,400);
|
||||||
|
SHAL_TIM6.setCallbackFunc(PWMToggle);
|
||||||
SHAL_TIM6.enableInterrupt();
|
SHAL_TIM6.enableInterrupt();
|
||||||
SHAL_TIM6.start();
|
SHAL_TIM6.start();
|
||||||
|
|
||||||
|
SHAL_TIM7.init(4000000,3000);
|
||||||
|
SHAL_TIM7.setCallbackFunc(calibrateSensors);
|
||||||
|
SHAL_TIM7.enableInterrupt();
|
||||||
|
|
||||||
|
PIN(B3).setPinMode(PinMode::OUTPUT_MODE); //Test
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
SHAL_UART2.sendString("HELLO\r\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user