diff --git a/SHAL/Include/Core/SHAL_CORE.h b/SHAL/Include/Core/SHAL_CORE.h index c373dce..68ac2a0 100644 --- a/SHAL/Include/Core/SHAL_CORE.h +++ b/SHAL/Include/Core/SHAL_CORE.h @@ -76,11 +76,17 @@ void SHAL_set_bits(volatile uint32_t* reg, uint32_t size, uint32_t bits, uint32_ *reg |= bits << offset; } -void SHAL_apply_bitmask(volatile uint32_t* reg, uint32_t mask){ +void SHAL_clear_bitmask(volatile uint32_t* reg, uint32_t mask){ *reg &= ~(mask); +} + +void SHAL_apply_bitmask(volatile uint32_t* reg, uint32_t mask){ + SHAL_clear_bitmask(reg,mask); *reg |= mask; } + + //--------------------------------------------------------- diff --git a/SHAL/Include/Peripheral/ADC/Reg/SHAL_ADC_REG_L432KC.h b/SHAL/Include/Peripheral/ADC/Reg/SHAL_ADC_REG_L432KC.h index ac1b8d0..246d87f 100644 --- a/SHAL/Include/Peripheral/ADC/Reg/SHAL_ADC_REG_L432KC.h +++ b/SHAL/Include/Peripheral/ADC/Reg/SHAL_ADC_REG_L432KC.h @@ -81,8 +81,8 @@ SHAL_ADC_Config_Reg getADCConfigReg(ADC_Key key) { return res; } -SHAL_ADC_ISR getADCISR(ADC_Key key){ - SHAL_ADC_ISR res = {nullptr, ADC_ISR_EOC}; +SHAL_ADC_ISR_Reg getADCISRReg(ADC_Key key){ + SHAL_ADC_ISR_Reg res = {nullptr, ADC_ISR_EOC, ADC_ISR_EOS, ADC_ISR_ADRDY}; res.reg = &(ADC_TABLE[static_cast(key)]->ISR); return res; diff --git a/SHAL/Include/Peripheral/ADC/SHAL_ADC.h b/SHAL/Include/Peripheral/ADC/SHAL_ADC.h index a019616..c80224a 100644 --- a/SHAL/Include/Peripheral/ADC/SHAL_ADC.h +++ b/SHAL/Include/Peripheral/ADC/SHAL_ADC.h @@ -35,7 +35,7 @@ public: /// \param numChannels Number of channels to convert /// \param result Pointer to store converted channel results in /// \param time SHAL_ADC_SampleTime - amount of clock cycles per conversion - void multiConvertSingle(SHAL_ADC_Channel* channels, int numChannels, uint16_t* result, SHAL_ADC_SampleTime time = SHAL_ADC_SampleTime::C8); + SHAL_Result multiConvertSingle(SHAL_ADC_Channel* channels, int numChannels, uint16_t* result, SHAL_ADC_SampleTime time = SHAL_ADC_SampleTime::C8); @@ -48,9 +48,14 @@ private: //Checks to see if instance is initialized with a proper ADC peripheral tag bool isValid(); + //Enabled peripheral + SHAL_Result enable(); + //Disables peripheral SHAL_Result disable(); + SHAL_Result startConversion(); + /// Adds an ADC channel to the conversion sequence /// \param channel Channel to add /// \param index Index to add channel to (ADC channel will be the nth channel to convert diff --git a/SHAL/Include/Peripheral/ADC/SHAL_ADC_TYPES.h b/SHAL/Include/Peripheral/ADC/SHAL_ADC_TYPES.h index 6a79eb2..90df597 100644 --- a/SHAL/Include/Peripheral/ADC/SHAL_ADC_TYPES.h +++ b/SHAL/Include/Peripheral/ADC/SHAL_ADC_TYPES.h @@ -44,9 +44,11 @@ struct SHAL_ADC_Data_Reg { }; //Register for the interrupt service routine for ADCs -struct SHAL_ADC_ISR { +struct SHAL_ADC_ISR_Reg { volatile uint32_t* reg; uint32_t end_of_conversion_mask; + uint32_t end_of_sequence_mask; + uint32_t ready_mask; }; //Register controlling the clock source for the ADC 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 36e125b..582bcd0 100644 --- a/SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_REG_L432KC.h +++ b/SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_REG_L432KC.h @@ -16,8 +16,7 @@ #define AVAILABLE_GPIO \ X(A0) X(A1) X(A2) X(A3) X(A4) X(A5) X(A6) X(A7) X(A8) X(A9) X(A10) X(A11) X(A12) X(A13) X(A14) X(A15) \ - X(B0) X(B1) X(B2) X(B3) X(B4) X(B5) X(B6) X(B7) X(B8) X(B9) X(B10) X(B11) X(B12) X(B13) X(B14) X(B15) \ - X(C0) X(C1) X(C2) X(C3) X(C4) X(C5) X(C6) X(C7) X(C8) X(C9) X(C10) X(C11) X(C12) X(C13) X(C14) X(C15) + X(B0) X(B1) X(B3) X(B4) X(B5) X(B6) X(B7) //Build enum map of available SHAL_GPIO pins @@ -29,8 +28,6 @@ enum class GPIO_Key : uint8_t { INVALID }; - - constexpr SHAL_GPIO_Peripheral getGPIORegister(const GPIO_Key g){ switch(g) { case GPIO_Key::A0: return {GPIOA,0}; @@ -51,36 +48,11 @@ constexpr SHAL_GPIO_Peripheral getGPIORegister(const GPIO_Key g){ case GPIO_Key::A15: return {GPIOA,15}; case GPIO_Key::B0: return {GPIOB,0}; case GPIO_Key::B1: return {GPIOB,1}; - case GPIO_Key::B2: return {GPIOB,2}; case GPIO_Key::B3: return {GPIOB,3}; case GPIO_Key::B4: return {GPIOB,4}; case GPIO_Key::B5: return {GPIOB,5}; case GPIO_Key::B6: return {GPIOB,6}; case GPIO_Key::B7: return {GPIOB,7}; - case GPIO_Key::B8: return {GPIOB,8}; - case GPIO_Key::B9: return {GPIOB,9}; - case GPIO_Key::B10: return {GPIOB,10}; - case GPIO_Key::B11: return {GPIOB,11}; - case GPIO_Key::B12: return {GPIOB,12}; - case GPIO_Key::B13: return {GPIOB,13}; - case GPIO_Key::B14: return {GPIOB,14}; - case GPIO_Key::B15: return {GPIOB,15}; - case GPIO_Key::C0: return {GPIOC,0}; - case GPIO_Key::C1: return {GPIOC,1}; - case GPIO_Key::C2: return {GPIOC,2}; - case GPIO_Key::C3: return {GPIOC,3}; - case GPIO_Key::C4: return {GPIOC,4}; - case GPIO_Key::C5: return {GPIOC,5}; - case GPIO_Key::C6: return {GPIOC,6}; - case GPIO_Key::C7: return {GPIOC,7}; - case GPIO_Key::C8: return {GPIOC,8}; - case GPIO_Key::C9: return {GPIOC,9}; - case GPIO_Key::C10: return {GPIOC,10}; - case GPIO_Key::C11: return {GPIOC,11}; - case GPIO_Key::C12: return {GPIOC,12}; - case GPIO_Key::C13: return {GPIOC,13}; - case GPIO_Key::C14: return {GPIOC,14}; - case GPIO_Key::C15: return {GPIOC,15}; case GPIO_Key::INVALID: case GPIO_Key::NUM_GPIO: assert(false); @@ -114,8 +86,7 @@ constexpr SHAL_GPIO_EXTI_Register getGPIOEXTICR(const GPIO_Key g){ case GPIO_Key::B5: return {&SYSCFG->EXTICR[1],SYSCFG_EXTICR2_EXTI5_PB,EXTI9_5_IRQn}; case GPIO_Key::B6: return {&SYSCFG->EXTICR[1],SYSCFG_EXTICR2_EXTI6_PB,EXTI9_5_IRQn}; case GPIO_Key::B7: return {&SYSCFG->EXTICR[1],SYSCFG_EXTICR2_EXTI7_PB,EXTI9_5_IRQn}; - case GPIO_Key::C14: return {&SYSCFG->EXTICR[3],SYSCFG_EXTICR4_EXTI14_PC,EXTI15_10_IRQn}; - case GPIO_Key::C15: return {&SYSCFG->EXTICR[3],SYSCFG_EXTICR4_EXTI15_PC,EXTI15_10_IRQn}; + case GPIO_Key::INVALID: case GPIO_Key::NUM_GPIO: @@ -146,38 +117,12 @@ constexpr SHAL_Peripheral_Register getGPIORCCEnable(const GPIO_Key g){ return {&RCC->AHB2ENR, RCC_AHB2ENR_GPIOAEN_Pos}; case GPIO_Key::B0: case GPIO_Key::B1: - case GPIO_Key::B2: case GPIO_Key::B3: case GPIO_Key::B4: case GPIO_Key::B5: case GPIO_Key::B6: case GPIO_Key::B7: - case GPIO_Key::B8: - case GPIO_Key::B9: - case GPIO_Key::B10: - case GPIO_Key::B11: - case GPIO_Key::B12: - case GPIO_Key::B13: - case GPIO_Key::B14: - case GPIO_Key::B15: return {&RCC->AHB2ENR, RCC_AHB2ENR_GPIOBEN_Pos}; - case GPIO_Key::C0: - case GPIO_Key::C1: - case GPIO_Key::C2: - case GPIO_Key::C3: - case GPIO_Key::C4: - case GPIO_Key::C5: - case GPIO_Key::C6: - case GPIO_Key::C7: - case GPIO_Key::C8: - case GPIO_Key::C9: - case GPIO_Key::C10: - case GPIO_Key::C11: - case GPIO_Key::C12: - case GPIO_Key::C13: - case GPIO_Key::C14: - case GPIO_Key::C15: - return {&RCC->AHB2ENR, RCC_AHB2ENR_GPIOCEN_Pos}; case GPIO_Key::INVALID: case GPIO_Key::NUM_GPIO: assert(false); @@ -207,38 +152,11 @@ constexpr uint32_t getGPIOPortNumber(const GPIO_Key g){ return 0; case GPIO_Key::B0: case GPIO_Key::B1: - case GPIO_Key::B2: case GPIO_Key::B3: case GPIO_Key::B4: case GPIO_Key::B5: case GPIO_Key::B6: case GPIO_Key::B7: - case GPIO_Key::B8: - case GPIO_Key::B9: - case GPIO_Key::B10: - case GPIO_Key::B11: - case GPIO_Key::B12: - case GPIO_Key::B13: - case GPIO_Key::B14: - case GPIO_Key::B15: - return 1; - case GPIO_Key::C0: - case GPIO_Key::C1: - case GPIO_Key::C2: - case GPIO_Key::C3: - case GPIO_Key::C4: - case GPIO_Key::C5: - case GPIO_Key::C6: - case GPIO_Key::C7: - case GPIO_Key::C8: - case GPIO_Key::C9: - case GPIO_Key::C10: - case GPIO_Key::C11: - case GPIO_Key::C12: - case GPIO_Key::C13: - case GPIO_Key::C14: - case GPIO_Key::C15: - return 2; case GPIO_Key::INVALID: case GPIO_Key::NUM_GPIO: assert(false); @@ -251,67 +169,42 @@ constexpr SHAL_GPIO_Port_Info getGPIOPortInfo(GPIO_Key key){ switch(key){ case GPIO_Key::A0: case GPIO_Key::B0: - case GPIO_Key::C0: return {0, SHAL_ADC_Channel::CH0}; case GPIO_Key::A1: case GPIO_Key::B1: - case GPIO_Key::C1: return {1, SHAL_ADC_Channel::CH1}; case GPIO_Key::A2: - case GPIO_Key::B2: - case GPIO_Key::C2: return {2, SHAL_ADC_Channel::CH2}; case GPIO_Key::A3: case GPIO_Key::B3: - case GPIO_Key::C3: return {3, SHAL_ADC_Channel::CH3}; case GPIO_Key::A4: case GPIO_Key::B4: - case GPIO_Key::C4: return {4, SHAL_ADC_Channel::CH4}; case GPIO_Key::A5: case GPIO_Key::B5: - case GPIO_Key::C5: return {5, SHAL_ADC_Channel::CH5}; case GPIO_Key::A6: case GPIO_Key::B6: - case GPIO_Key::C6: return {6, SHAL_ADC_Channel::CH6}; case GPIO_Key::A7: case GPIO_Key::B7: - case GPIO_Key::C7: return {7, SHAL_ADC_Channel::CH7}; case GPIO_Key::A8: - case GPIO_Key::B8: - case GPIO_Key::C8: return {8, SHAL_ADC_Channel::CH8}; case GPIO_Key::A9: - case GPIO_Key::B9: - case GPIO_Key::C9: return {9, SHAL_ADC_Channel::CH9}; case GPIO_Key::A10: - case GPIO_Key::B10: - case GPIO_Key::C10: return {10, SHAL_ADC_Channel::CH10}; case GPIO_Key::A11: - case GPIO_Key::B11: - case GPIO_Key::C11: return {11, SHAL_ADC_Channel::CH11}; case GPIO_Key::A12: - case GPIO_Key::B12: - case GPIO_Key::C12: return {12, SHAL_ADC_Channel::CH12}; case GPIO_Key::A13: - case GPIO_Key::B13: - case GPIO_Key::C13: return {13, SHAL_ADC_Channel::CH13}; case GPIO_Key::A14: - case GPIO_Key::B14: - case GPIO_Key::C14: return {14, SHAL_ADC_Channel::CH14}; case GPIO_Key::A15: - case GPIO_Key::B15: - case GPIO_Key::C15: return {15, SHAL_ADC_Channel::CH15}; case GPIO_Key::NUM_GPIO: case GPIO_Key::INVALID: @@ -320,6 +213,4 @@ constexpr SHAL_GPIO_Port_Info getGPIOPortInfo(GPIO_Key key){ __builtin_unreachable(); } - - -#endif //SHAL_GPIO_REG_F072XB_H +#endif //SHAL_GPIO_REG_F072XB_H \ No newline at end of file diff --git a/SHAL/Include/Peripheral/GPIO/SHAL_GPIO.h b/SHAL/Include/Peripheral/GPIO/SHAL_GPIO.h index 265ebb5..6b1de08 100644 --- a/SHAL/Include/Peripheral/GPIO/SHAL_GPIO.h +++ b/SHAL/Include/Peripheral/GPIO/SHAL_GPIO.h @@ -27,7 +27,7 @@ public: /// Uses the ADC to read an analog voltage value /// \param sampleTime The amount of clock cycles to use for the ADC /// \return ADC result - uint16_t analogRead(SHAL_ADC_SampleTime sampleTime = SHAL_ADC_SampleTime::C239); + uint16_t analogRead(SHAL_ADC_SampleTime sampleTime = SHAL_ADC_SampleTime::C8); void setPinMode(PinMode mode) volatile; diff --git a/SHAL/Include/Peripheral/Timer/Reg/SHAL_TIM_REG_F072xB.h b/SHAL/Include/Peripheral/Timer/Reg/SHAL_TIM_REG_F072xB.h index f4bf7cd..113d7bb 100644 --- a/SHAL/Include/Peripheral/Timer/Reg/SHAL_TIM_REG_F072xB.h +++ b/SHAL/Include/Peripheral/Timer/Reg/SHAL_TIM_REG_F072xB.h @@ -6,8 +6,8 @@ ****************************************************************************** */ -#ifndef SHAL_TIM_REG_H -#define SHAL_TIM_REG_H +#ifndef SHAL_TIM_REG_F072XB_H +#define SHAL_TIM_REG_F072XB_H #include #include diff --git a/SHAL/Include/Peripheral/Timer/Reg/SHAL_TIM_REG_L432KC.h b/SHAL/Include/Peripheral/Timer/Reg/SHAL_TIM_REG_L432KC.h new file mode 100644 index 0000000..e004468 --- /dev/null +++ b/SHAL/Include/Peripheral/Timer/Reg/SHAL_TIM_REG_L432KC.h @@ -0,0 +1,122 @@ +/** + ****************************************************************************** + * @file SHAL_TIM_REG.h + * @author Luca Lizaranzu + * @brief Defines universal macros and objects used across all STM32 families + ****************************************************************************** + */ + +#ifndef SHAL_TIM_REG_L432KC_H +#define SHAL_TIM_REG_L432KC_H + +#include +#include + +#include "SHAL_CORE.h" +#include "SHAL_TIM_TYPES.h" + +enum class Timer_Key : uint8_t { //For STM32L432 + S_TIM1, + S_TIM2, + S_TIM6, + S_TIM7, + S_TIM15, + S_TIM16, + NUM_TIMERS, + S_TIM_INVALID +}; + +//Lookup table for timer typedefs +static volatile TIM_TypeDef* TIM_TABLE[6] = { + TIM1, + TIM2, + TIM6, + TIM7, + TIM15, + TIM16, +}; + +#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) +#define SHAL_TIM7 TimerManager::get(Timer_Key::S_TIM7) +#define SHAL_TIM15 TimerManager::get(Timer_Key::S_TIM15) +#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}; + + volatile TIM_TypeDef* tim = TIM_TABLE[static_cast(key)]; + + res.reg = &tim->SR; + return res; +} + +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}; + + volatile TIM_TypeDef* tim = TIM_TABLE[static_cast(key)]; + + res.reg = &tim->CR1; + return res; +} + +static inline SHAL_TIM_DMA_Interrupt_Enable_Register getTimerDMAInterruptEnableRegister(Timer_Key key){ + + SHAL_TIM_DMA_Interrupt_Enable_Register res = {nullptr, TIM_DIER_UIE}; + + volatile TIM_TypeDef* tim = TIM_TABLE[static_cast(key)]; + + res.reg = &tim->CR1; + return res; +} + +static inline SHAL_TIM_Event_Generation_Register getTimerEventGenerationRegister(Timer_Key key){ + + SHAL_TIM_Event_Generation_Register res = {nullptr, TIM_EGR_UG}; + + volatile TIM_TypeDef* tim = TIM_TABLE[static_cast(key)]; + + res.reg = &tim->CR1; + 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::NUM_TIMERS: + case Timer_Key::S_TIM_INVALID: + assert(false); + } + + __builtin_unreachable(); +} + + + +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(); +} + +#endif \ No newline at end of file diff --git a/SHAL/Include/Peripheral/Timer/SHAL_TIM.h b/SHAL/Include/Peripheral/Timer/SHAL_TIM.h index 8c431d0..ad62abc 100644 --- a/SHAL/Include/Peripheral/Timer/SHAL_TIM.h +++ b/SHAL/Include/Peripheral/Timer/SHAL_TIM.h @@ -9,7 +9,7 @@ #ifndef SHAL_TIM_H #define SHAL_TIM_H -#include "SHAL_TIM_REG_F072xB.h" +#include "SHAL_TIM_REG.h" #include "SHAL_TIM_CALLBACK.h" #include @@ -18,7 +18,7 @@ class Timer { friend class TimerManager; public: - /// + /// Initializes a timer /// \param prescaler The amount of times the base clock has to cycle before the timer adds one to the count /// \param autoReload The number of timer counts before the count is reset and IRQ is called void init(uint32_t prescaler, uint32_t autoReload); @@ -40,7 +40,7 @@ public: //Set TIMER_KEY IRQ callback function void setCallbackFunc(TimerCallback callback){ - registerTimerCallback(TIMER_KEY, callback); + registerTimerCallback(m_key, callback); } private: @@ -48,7 +48,7 @@ private: explicit Timer(Timer_Key t); Timer(); - Timer_Key TIMER_KEY; + Timer_Key m_key; }; diff --git a/SHAL/Include/Peripheral/Timer/SHAL_TIM_REG.h b/SHAL/Include/Peripheral/Timer/SHAL_TIM_REG.h index 250d173..3521dc7 100644 --- a/SHAL/Include/Peripheral/Timer/SHAL_TIM_REG.h +++ b/SHAL/Include/Peripheral/Timer/SHAL_TIM_REG.h @@ -2,8 +2,8 @@ // Created by Luca on 9/7/2025. // -#ifndef SHMINGO_HAL_SHAL_TIM_REG_H -#define SHMINGO_HAL_SHAL_TIM_REG_H +#ifndef SHAL_TIM_REG_H +#define SHAL_TIM_REG_H #if defined(STM32F030x6) #include "stm32f030x6.h" @@ -46,7 +46,7 @@ #elif defined(STM32L431xx) #include "stm32l431xx.h" #elif defined(STM32L432xx) -#include "stm32l432xx.h" +#include "SHAL_TIM_REG_L432KC.h" #elif defined(STM32L433xx) #include "stm32l433xx.h" #elif defined(STM32L442xx) @@ -92,4 +92,4 @@ #error "Please select first the target STM32F0xx device used in your application (in stm32f0xx.h file)" #endif -#endif //SHMINGO_HAL_SHAL_TIM_REG_H +#endif //SHAL_TIM_REG_H diff --git a/SHAL/Include/Peripheral/Timer/SHAL_TIM_TYPES.h b/SHAL/Include/Peripheral/Timer/SHAL_TIM_TYPES.h index eee07fd..505bdae 100644 --- a/SHAL/Include/Peripheral/Timer/SHAL_TIM_TYPES.h +++ b/SHAL/Include/Peripheral/Timer/SHAL_TIM_TYPES.h @@ -2,14 +2,37 @@ // Created by Luca on 9/7/2025. // -#ifndef SHMINGO_HAL_SHAL_TIM_TYPES_H -#define SHMINGO_HAL_SHAL_TIM_TYPES_H +#ifndef SHAL_TIM_TYPES_H +#define SHAL_TIM_TYPES_H #include "SHAL_CORE.h" -struct TIM_RCC_Enable{ - volatile uint32_t* busEnableReg; +struct SHAL_TIM_RCC_Register{ + volatile uint32_t* reg; uint32_t offset; }; +struct SHAL_TIM_Control_Register_1 { + volatile uint32_t* reg; + uint32_t counter_enable_mask; + uint32_t update_disable_mask; + uint32_t one_pulse_mode_mask; + uint32_t center_align_mode_offset; +}; + +struct SHAL_TIM_DMA_Interrupt_Enable_Register { + volatile uint32_t* reg; + uint32_t update_interrupt_enable_mask; +}; + +struct SHAL_TIM_Status_Register { + volatile uint32_t* reg; + uint32_t update_interrupt_flag_mask; +}; + +struct SHAL_TIM_Event_Generation_Register { + volatile uint32_t* reg; + uint32_t update_generation_mask; +}; + #endif //SHMINGO_HAL_SHAL_TIM_TYPES_H diff --git a/SHAL/Src/STM32L4XX/Peripheral/ADC/SHAL_ADC.cpp b/SHAL/Src/STM32L4XX/Peripheral/ADC/SHAL_ADC.cpp index 843bdb5..42025e2 100644 --- a/SHAL/Src/STM32L4XX/Peripheral/ADC/SHAL_ADC.cpp +++ b/SHAL/Src/STM32L4XX/Peripheral/ADC/SHAL_ADC.cpp @@ -11,8 +11,6 @@ SHAL_Result SHAL_ADC::init() { return SHAL_Result::ERROR; } - ADC_TypeDef* ADC_reg = getADCRegister(m_ADCKey); - SHAL_ADC_RCC_Enable_Reg clock_reg = getADCRCCEnableRegister(m_ADCKey); //Clock enable *clock_reg.reg |= clock_reg.mask; @@ -57,43 +55,82 @@ SHAL_Result SHAL_ADC::calibrate() { uint16_t SHAL_ADC::singleConvertSingle(SHAL_ADC_Channel channel, SHAL_ADC_SampleTime time) { + auto data_reg = getADCDataReg(m_ADCKey); //Where our output will be stored + auto sampleTimeReg = getADCChannelSamplingTimeRegister(m_ADCKey,channel); SHAL_set_bits(sampleTimeReg.reg,3,static_cast(time),sampleTimeReg.channel_offset); //Set sample time register TODO un-hardcode bit width? - auto sequenceReg = getADCSequenceRegisters(m_ADCKey); - addADCChannelToSequence(channel,0); //Use index 0 to convert channel - setADCSequenceAmount(1); //Since we're using single convert, convert 1 channel - if(!SHAL_WAIT_FOR_CONDITION_US(((ADC_reg->ISR & ADC_ISR_EOC) != 0),500)){ //Wait for conversion + if(enable() != SHAL_Result::OKAY){ + return 0; + } + + startConversion(); //Start ADC conversion + + auto ISR_reg = getADCISRReg(m_ADCKey); + + if(!SHAL_WAIT_FOR_CONDITION_US(((*ISR_reg.reg & ISR_reg.end_of_conversion_mask) != 0),500)){ //Wait for conversion return 0; //Failed } - uint16_t result = ADC_reg->DR; - return result; + return *data_reg.reg; } -void SHAL_ADC::multiConvertSingle(SHAL_ADC_Channel* channels, const int numChannels, uint16_t* result, SHAL_ADC_SampleTime time) { - ADC_TypeDef* ADC_reg = getADCRegister(m_ADCKey); - - ADC->CCR |= ADC_CCR_VREFEN | ADC_CCR_TSEN; //Enable VREFINT and Temp sensor in global ADC struct - - for(int i = 0; i < numChannels; i++){ //Enable all channels - ADC_reg->CHSELR = static_cast(channels[i]); - } - - ADC_reg->SMPR |= static_cast(time); //Set sampling time +SHAL_Result SHAL_ADC::multiConvertSingle(SHAL_ADC_Channel* channels, const int numChannels, uint16_t* result, SHAL_ADC_SampleTime time) { + auto data_reg = getADCDataReg(m_ADCKey); //Where our output will be stored + setADCSequenceAmount(numChannels); //Convert the correct amount of channels for(int i = 0; i < numChannels; i++){ - if(!SHAL_WAIT_FOR_CONDITION_US(((ADC_reg->ISR & ADC_ISR_EOC) != 0),500)){ //Wait for conversion - continue; //Failed - } + auto channel = channels[i]; - result[i] = ADC_reg->DR; + auto sampleTimeReg = getADCChannelSamplingTimeRegister(m_ADCKey,channel); + + SHAL_set_bits(sampleTimeReg.reg,3,static_cast(time),sampleTimeReg.channel_offset); //Set sample time register TODO un-hardcode bit width? + + addADCChannelToSequence(channel,i); //Use index 0 to convert channel + + if(enable() != SHAL_Result::OKAY){ + return SHAL_Result::ERROR; + } } + + startConversion(); //Start ADC conversion + + auto ISR_reg = getADCISRReg(m_ADCKey); + + for(int i = 0; i < numChannels; i++) { + if (!SHAL_WAIT_FOR_CONDITION_US(((*ISR_reg.reg & ISR_reg.end_of_conversion_mask) != 0),500)) { //Wait for conversion + return SHAL_Result::ERROR; //Failed conversion + } + result[i] = *data_reg.reg; + } + + if (!SHAL_WAIT_FOR_CONDITION_US(((*ISR_reg.reg & ISR_reg.end_of_sequence_mask) != 0),500)) { //Wait for conversion + return SHAL_Result::ERROR; //Failed sequence + } + + return SHAL_Result::OKAY; +} + +SHAL_Result SHAL_ADC::enable() { + if(!isValid()){ + return SHAL_Result::ERROR; + } + + SHAL_ADC_Control_Reg control_reg = getADCControlReg(m_ADCKey); + SHAL_ADC_ISR_Reg ISR_reg = getADCISRReg(m_ADCKey); + + *control_reg.reg |= control_reg.enable_mask; //Enable + + if(!SHAL_WAIT_FOR_CONDITION_MS((*ISR_reg.reg & ISR_reg.ready_mask) != 0, 100)){ + return SHAL_Result::ERROR; + } + + return SHAL_Result::OKAY; } SHAL_Result SHAL_ADC::disable() { @@ -115,6 +152,14 @@ SHAL_Result SHAL_ADC::disable() { return SHAL_Result::OKAY; } +SHAL_Result SHAL_ADC::startConversion() { + auto control_reg = getADCControlReg(m_ADCKey); + + SHAL_apply_bitmask(control_reg.reg,control_reg.start_mask); + + return SHAL_Result::OKAY; +} + bool SHAL_ADC::isValid() { if(m_ADCKey == ADC_Key::INVALID || m_ADCKey == ADC_Key::NUM_ADC){ return false; @@ -150,9 +195,13 @@ SHAL_Result SHAL_ADC::configureAlignment(SHAL_ADC_Alignment alignment) { SHAL_Result SHAL_ADC::setADCSequenceAmount(uint32_t amount) { if(!isValid()){return SHAL_Result::ERROR;} + if(amount == 0){ + return SHAL_Result::ERROR; + } + SHAL_ADC_Sequence_Amount_Reg sequence_amount_reg = getADCSequenceAmountRegister(m_ADCKey); - SHAL_set_bits(sequence_amount_reg.reg, 4, amount, sequence_amount_reg.offset); + SHAL_set_bits(sequence_amount_reg.reg, 4, amount - 1, sequence_amount_reg.offset); return SHAL_Result::OKAY; } @@ -173,6 +222,7 @@ SHAL_Result SHAL_ADC::addADCChannelToSequence(SHAL_ADC_Channel channel, uint32_t SHAL_set_bits(sequenceReg,5,channelNum,bitSectionOffset); } + SHAL_ADC &ADCManager::get(ADC_Key key) { return m_ADCs[static_cast(key)]; } diff --git a/SHAL/Src/STM32L4XX/Peripheral/Timer/SHAL_TIM.cpp b/SHAL/Src/STM32L4XX/Peripheral/Timer/SHAL_TIM.cpp index 24b39b2..ac57326 100644 --- a/SHAL/Src/STM32L4XX/Peripheral/Timer/SHAL_TIM.cpp +++ b/SHAL/Src/STM32L4XX/Peripheral/Timer/SHAL_TIM.cpp @@ -5,17 +5,22 @@ #include "SHAL_TIM.h" #include -Timer::Timer(Timer_Key t) : TIMER_KEY(t){ +Timer::Timer(Timer_Key key) : m_key(key){ } -Timer::Timer() : TIMER_KEY(Timer_Key::S_TIM_INVALID){ +Timer::Timer() : m_key(Timer_Key::S_TIM_INVALID){ } void Timer::start() { - getTimerRegister(TIMER_KEY)->CR1 |= TIM_CR1_CEN; - getTimerRegister(TIMER_KEY)->EGR |= TIM_EGR_UG; //load prescaler reg and ARR + + auto control_reg = getTimerControlRegister1(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(event_generation_reg.reg, event_generation_reg.update_generation_mask); + enableInterrupt(); } @@ -33,7 +38,7 @@ void Timer::setARR(uint16_t arr) { void Timer::enableInterrupt() { getTimerRegister(TIMER_KEY)->DIER |= TIM_DIER_UIE; - NVIC_EnableIRQ(getIRQn(TIMER_KEY)); + NVIC_EnableIRQ(getTimerIRQn(TIMER_KEY)); } void Timer::init(uint32_t prescaler, uint32_t autoReload) { diff --git a/SHAL/Src/STM32L4XX/Peripheral/Timer/SHAL_TIM_CALLBACK.cpp b/SHAL/Src/STM32L4XX/Peripheral/Timer/SHAL_TIM_CALLBACK.cpp index c8d957c..4ad8484 100644 --- a/SHAL/Src/STM32L4XX/Peripheral/Timer/SHAL_TIM_CALLBACK.cpp +++ b/SHAL/Src/STM32L4XX/Peripheral/Timer/SHAL_TIM_CALLBACK.cpp @@ -4,13 +4,12 @@ #include "SHAL_TIM_CALLBACK.h" -DEFINE_TIMER_IRQ(Timer_Key::S_TIM1, TIM1_BRK_UP_TRG_COM_IRQHandler) +DEFINE_TIMER_IRQ(Timer_Key::S_TIM1, TIM1_IRQHandler) DEFINE_TIMER_IRQ(Timer_Key::S_TIM2, TIM2_IRQHandler) -DEFINE_TIMER_IRQ(Timer_Key::S_TIM3, TIM3_IRQHandler) -DEFINE_TIMER_IRQ(Timer_Key::S_TIM14, TIM14_IRQHandler) +DEFINE_TIMER_IRQ(Timer_Key::S_TIM6, TIM6_IRQHandler) +DEFINE_TIMER_IRQ(Timer_Key::S_TIM7, TIM7_IRQHandler) DEFINE_TIMER_IRQ(Timer_Key::S_TIM15, TIM15_IRQHandler) DEFINE_TIMER_IRQ(Timer_Key::S_TIM16, TIM16_IRQHandler) -DEFINE_TIMER_IRQ(Timer_Key::S_TIM17, TIM17_IRQHandler) void registerTimerCallback(Timer_Key key, TimerCallback callback){ timer_callbacks[static_cast(key)] = callback;