diff --git a/SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_REG_L432KC.h b/SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_REG_L432KC.h index d24d6ad..0f28136 100644 --- a/SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_REG_L432KC.h +++ b/SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_REG_L432KC.h @@ -44,6 +44,24 @@ enum class GPIO_Key : uint8_t { INVALID }; +enum class GPIO_Alternate_Function_Mapping { + A0_TIM2CH1 = 0x01, + A1_TIM2CH2 = 0x01, + A2_TIM2CH3 = 0x01, + A3_TIM2CH4 = 0x01, + A5_TIM2CH1 = 0x01, + A6_TIM1BKIN = 0x01, + A7_TIM1CH1N = 0x01, + A8_TIM1CH1 = 0x01, + A9_TIM1CH2 = 0x01, + A10_TIM1CH3 = 0x01, + A11_TIM1CH4 = 0x01, + A12_TIM1ETR = 0x01, + A15_TIM2CH1 = 0x01, + B0_TIM2CH2N = 0x01, + B1_TIM1CH3N = 0x01, +}; + static volatile GPIO_TypeDef * GPIO_TABLE[2] = { //Lookup table for ADCs GPIOA, GPIOB @@ -114,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){ - uint32_t pinNumber = static_cast(key); //Number of pin (We need 0-7 to be AFR 1 and 8-15 to be AFR 2 + uint32_t pinNumber = static_cast(key); //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; volatile uint32_t* reg = &GPIO_TABLE[static_cast(key) / 16]->AFR[afrIndex]; diff --git a/SHAL/Include/Peripheral/GPIO/SHAL_GPIO.h b/SHAL/Include/Peripheral/GPIO/SHAL_GPIO.h index e084aa0..c2be634 100644 --- a/SHAL/Include/Peripheral/GPIO/SHAL_GPIO.h +++ b/SHAL/Include/Peripheral/GPIO/SHAL_GPIO.h @@ -31,6 +31,7 @@ public: void setAlternateFunction(GPIO_Alternate_Function AF) volatile; + void setAlternateFunction(GPIO_Alternate_Function_Mapping AF) volatile; void setOutputType(PinType type) volatile; @@ -38,7 +39,6 @@ public: void setInternalResistor(InternalResistorType type) volatile; - void useAsExternalInterrupt(TriggerMode mode, EXTICallback callback); SHAL_Result setPinMode(PinMode mode) volatile; diff --git a/SHAL/Include/Peripheral/Timer/Reg/SHAL_TIM_REG_L432KC.h b/SHAL/Include/Peripheral/Timer/Reg/SHAL_TIM_REG_L432KC.h index 5510a88..3d6c677 100644 --- a/SHAL/Include/Peripheral/Timer/Reg/SHAL_TIM_REG_L432KC.h +++ b/SHAL/Include/Peripheral/Timer/Reg/SHAL_TIM_REG_L432KC.h @@ -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(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(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(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(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(key)]; + return {&tim->CCER}; +} + +static inline SHAL_TIM_Capture_Compare_Register getTimerCaptureCompareRegister(Timer_Key key){ + volatile TIM_TypeDef* tim = TIM_TABLE[static_cast(key)]; + return {&tim->CCR2}; +} + //Get timer IRQN from lookup table static inline IRQn_Type getTimerIRQn(Timer_Key t) { diff --git a/SHAL/Include/Peripheral/Timer/SHAL_TIM.h b/SHAL/Include/Peripheral/Timer/SHAL_TIM.h index ad62abc..93fe682 100644 --- a/SHAL/Include/Peripheral/Timer/SHAL_TIM.h +++ b/SHAL/Include/Peripheral/Timer/SHAL_TIM.h @@ -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); diff --git a/SHAL/Include/Peripheral/Timer/SHAL_TIM_TYPES.h b/SHAL/Include/Peripheral/Timer/SHAL_TIM_TYPES.h index e7b3d33..07143cc 100644 --- a/SHAL/Include/Peripheral/Timer/SHAL_TIM_TYPES.h +++ b/SHAL/Include/Peripheral/Timer/SHAL_TIM_TYPES.h @@ -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 diff --git a/SHAL/Src/STM32L4XX/Peripheral/GPIO/SHAL_GPIO.cpp b/SHAL/Src/STM32L4XX/Peripheral/GPIO/SHAL_GPIO.cpp index 93d7b75..bf460e2 100644 --- a/SHAL/Src/STM32L4XX/Peripheral/GPIO/SHAL_GPIO.cpp +++ b/SHAL/Src/STM32L4XX/Peripheral/GPIO/SHAL_GPIO.cpp @@ -109,6 +109,12 @@ uint16_t SHAL_GPIO::analogRead(SHAL_ADC_SampleTime sampleTime) { return GPIOManager::getGPIOADC().singleConvertSingle(channel,sampleTime); } +void SHAL_GPIO::setAlternateFunction(GPIO_Alternate_Function_Mapping AF) volatile { + setPinMode(PinMode::ALTERNATE_FUNCTION_MODE); + auto alternateFunctionReg = getGPIOAlternateFunctionRegister(m_GPIO_KEY); + SHAL_set_bits(alternateFunctionReg.reg,4,static_cast(AF),alternateFunctionReg.offset); +} + SHAL_GPIO& GPIOManager::get(GPIO_Key key) { diff --git a/SHAL/Src/STM32L4XX/Peripheral/Timer/SHAL_TIM.cpp b/SHAL/Src/STM32L4XX/Peripheral/Timer/SHAL_TIM.cpp index 838544a..5cbe49d 100644 --- a/SHAL/Src/STM32L4XX/Peripheral/Timer/SHAL_TIM.cpp +++ b/SHAL/Src/STM32L4XX/Peripheral/Timer/SHAL_TIM.cpp @@ -54,6 +54,21 @@ void Timer::init(uint32_t prescaler, uint32_t autoReload) { setARR(autoReload); } +void Timer::setPWMMode(SHAL_Timer_Channel channel, SHAL_Timer_Channel_Main_Output_Mode mainOutputMode, + SHAL_Timer_Channel_Complimentary_Output_Mode complimentaryOutputMode) { + + uint8_t fullModeMask = static_cast(mainOutputMode) | (static_cast(complimentaryOutputMode) << 2); + uint32_t offset = static_cast(channel) * 4; + + auto ccer = getTimerCaptureCompareEnableRegister(m_key); + + if(static_cast(m_key) > 3){ + fullModeMask &= (0b0011); //Clear bits for complimentary output since channels 4,5,6 don't support it + } + + SHAL_set_bits(ccer.reg,4,fullModeMask,offset); +} + Timer &TimerManager::get(Timer_Key timer_key) { diff --git a/SHAL/Src/main.cpp b/SHAL/Src/main.cpp index 86be62e..491b741 100644 --- a/SHAL/Src/main.cpp +++ b/SHAL/Src/main.cpp @@ -26,6 +26,10 @@ void timer2callback(){ } +void b0PWM(){ + PIN(B0).toggle(); +} + int main() { SHAL_init(); @@ -33,8 +37,6 @@ int main() { SHAL_UART2.init(UART_Pair_Key::Tx2A2_Rx2A3); SHAL_UART2.begin(115200); - SHAL_UART2.sendString("Begin\r\n"); - PIN(A0).setPinMode(PinMode::ANALOG_MODE); PIN(A1).setPinMode(PinMode::ANALOG_MODE); PIN(A4).setPinMode(PinMode::ANALOG_MODE); @@ -42,7 +44,7 @@ int main() { PIN(A6).setPinMode(PinMode::ANALOG_MODE); PIN(A7).setPinMode(PinMode::ANALOG_MODE); - SHAL_UART2.sendString("Hello\r\n"); + PIN(B0).setPinMode(PinMode::OUTPUT_MODE); SHAL_TIM2.init(4000000,400); @@ -50,7 +52,10 @@ int main() { SHAL_TIM2.enableInterrupt(); SHAL_TIM2.start(); - SHAL_UART2.sendString("Hello\r\n"); + SHAL_TIM6.init(4000000,1); + SHAL_TIM6.setCallbackFunc(b0PWM); + SHAL_TIM6.enableInterrupt(); + SHAL_TIM6.start(); while (true) { }