diff --git a/SHAL/Include/Core/SHAL_CORE.h b/SHAL/Include/Core/SHAL_CORE.h index 99856f8..c373dce 100644 --- a/SHAL/Include/Core/SHAL_CORE.h +++ b/SHAL/Include/Core/SHAL_CORE.h @@ -28,8 +28,10 @@ enum class SHAL_Result{ }; - -typedef bool (*condition_fn_t)(void); +#define SHAL_CALL(func) \ + if(func != SHAL_Result::OKAY){ \ + return SHAL_Result::ERROR; \ + } #define SHAL_WAIT_FOR_CONDITION_US(cond, timeout_us) \ SHAL_wait_for_condition_us([&](){ return (cond); }, (timeout_us)) @@ -68,6 +70,17 @@ bool SHAL_wait_for_condition_ms(Condition cond, uint32_t timeout_ms) { return false; // timeout } +void SHAL_set_bits(volatile uint32_t* reg, uint32_t size, uint32_t bits, uint32_t offset){ + uint32_t mask = (1 << (size)) - 1; + *reg &= ~(mask << offset); + *reg |= bits << offset; +} + +void SHAL_apply_bitmask(volatile uint32_t* reg, uint32_t mask){ + *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 f797c12..397ce30 100644 --- a/SHAL/Include/Peripheral/ADC/Reg/SHAL_ADC_REG_L432KC.h +++ b/SHAL/Include/Peripheral/ADC/Reg/SHAL_ADC_REG_L432KC.h @@ -10,12 +10,84 @@ #define SHAL_ADC1 SHAL_ADC(1) + enum class ADC_Key : uint8_t{ - S_ADC1, - NUM_ADC, - INVALID + S_ADC1 = 0, + NUM_ADC = 1, + INVALID = 255 }; +enum class ADC_Clock_Source : uint8_t { + SHAL_SYSCLK, + SHAL_PLLSAI1, + SHAL_PLL, + SHAL_MSI +}; + +static volatile ADC_TypeDef* ADC_TABLE[1] = { //Lookup table for ADCs + ADC1, +}; + +SHAL_ADC_Common_Control_Reg getADCCommonControl() { + return {&ADC1_COMMON->CCR ,ADC_CCR_VREFEN,ADC_CCR_TSEN,ADC_CCR_VBATEN}; +} + +SHAL_ADC_RCC_Enable_Reg getADCRCCEnableRegister(ADC_Key key){ + SHAL_ADC_RCC_Enable_Reg res = {nullptr, RCC_AHB2ENR_ADCEN}; + + res.reg = &(ADC_TABLE[static_cast(key)]->ISR); + return res; +} + +SHAL_ADC_Control_Reg getADCControlReg(ADC_Key key) { + + SHAL_ADC_Control_Reg res = {nullptr, ADC_CR_ADEN, ADC_CR_ADDIS, ADC_CR_ADCAL, ADC_CR_ADSTART}; + + res.reg = &(ADC_TABLE[static_cast(key)]->CR); + return res; +} + +SHAL_ADC_Config_Reg getADCConfigReg(ADC_Key key) { + + SHAL_ADC_Config_Reg res = {nullptr, ADC_CFGR_CONT, ADC_CFGR_RES_Pos, ADC_CFGR_ALIGN_Pos}; + + res.reg = &(ADC_TABLE[static_cast(key)]->CFGR); + return res; +} + +SHAL_ADC_ISR getADCISR(ADC_Key key){ + SHAL_ADC_ISR res = {nullptr, ADC_ISR_EOC}; + + res.reg = &(ADC_TABLE[static_cast(key)]->ISR); + return res; +} + +SHAL_ADC_Data_Reg getADCDataReg(ADC_Key key){ + SHAL_ADC_Data_Reg res = {nullptr, 0xFFFF}; + + res.reg = &(ADC_TABLE[static_cast(key)]->DR); + return res; +} + +SHAL_ADC_Clock_Reg getADCClockSelectRegister(ADC_Clock_Source clockSource) { + constexpr uint32_t ADCSEL_MASK = RCC_CCIPR_ADCSEL_Msk; // covers bits 29:28 + + SHAL_ADC_Clock_Reg res = {&RCC->CCIPR, ADCSEL_MASK, 1U << RCC_CCIPR_ADCSEL_Pos}; //Default to PLLSAI1 + + switch(clockSource){ + case ADC_Clock_Source::SHAL_PLLSAI1: + res.mask = 1U << RCC_CCIPR_ADCSEL_Pos; + case ADC_Clock_Source::SHAL_PLL: + res.mask = 2U << RCC_CCIPR_ADCSEL_Pos; + case ADC_Clock_Source::SHAL_SYSCLK: + res.mask = 3U << RCC_CCIPR_ADCSEL_Pos; + case ADC_Clock_Source::SHAL_MSI: + break; //TODO implement this + } + + return res; +} + constexpr ADC_TypeDef* getADCRegister(ADC_Key key){ switch(key){ case ADC_Key::S_ADC1: diff --git a/SHAL/Include/Peripheral/ADC/SHAL_ADC.h b/SHAL/Include/Peripheral/ADC/SHAL_ADC.h index 2f287d5..9bc14fe 100644 --- a/SHAL/Include/Peripheral/ADC/SHAL_ADC.h +++ b/SHAL/Include/Peripheral/ADC/SHAL_ADC.h @@ -20,18 +20,22 @@ public: SHAL_Result calibrate(); + SHAL_Result configureResolution(SHAL_ADC_Resolution resolution); + + SHAL_Result configureAlignment(SHAL_ADC_Alignment alignment); + /// Performs analog to digital conversion on a single channel, one time /// \param channel Channel to be converted /// \param time ADC_SampleTime - amount of clock cycles per conversion /// \return resulting value - uint16_t singleConvertSingle(ADC_Channel channel, ADC_SampleTime time = ADC_SampleTime::C239); + uint16_t singleConvertSingle(SHAL_ADC_Channel channel, ADC_SampleTime time = ADC_SampleTime::C239); /// Performs analog to digital conversion on multiple channels, one time /// \param channels Pointer to an array of channels to convert /// \param numChannels Number of channels to convert /// \param result Pointer to store converted channel results in /// \param time ADC_SampleTime - amount of clock cycles per conversion - void multiConvertSingle(ADC_Channel* channels, const int numChannels, uint16_t* result, ADC_SampleTime time = ADC_SampleTime::C239); + void multiConvertSingle(SHAL_ADC_Channel* channels, int numChannels, uint16_t* result, ADC_SampleTime time = ADC_SampleTime::C239); @@ -41,6 +45,9 @@ private: ADC_Key m_ADCKey = ADC_Key::INVALID; + bool isValid(); + SHAL_Result disable(); + }; diff --git a/SHAL/Include/Peripheral/ADC/SHAL_ADC_TYPES.h b/SHAL/Include/Peripheral/ADC/SHAL_ADC_TYPES.h index bfdcb0c..55a3456 100644 --- a/SHAL/Include/Peripheral/ADC/SHAL_ADC_TYPES.h +++ b/SHAL/Include/Peripheral/ADC/SHAL_ADC_TYPES.h @@ -5,26 +5,75 @@ #ifndef SHMINGO_HAL_SHAL_ADC_TYPES_H #define SHMINGO_HAL_SHAL_ADC_TYPES_H -enum class ADC_Channel : uint32_t { - CH0 = ADC_CHSELR_CHSEL0, - CH1 = ADC_CHSELR_CHSEL1, - CH2 = ADC_CHSELR_CHSEL2, - CH3 = ADC_CHSELR_CHSEL3, - CH4 = ADC_CHSELR_CHSEL4, - CH5 = ADC_CHSELR_CHSEL5, - CH6 = ADC_CHSELR_CHSEL6, - CH7 = ADC_CHSELR_CHSEL7, - CH8 = ADC_CHSELR_CHSEL8, - CH9 = ADC_CHSELR_CHSEL9, - CH10 = ADC_CHSELR_CHSEL10, - CH11 = ADC_CHSELR_CHSEL11, - CH12 = ADC_CHSELR_CHSEL12, - CH13 = ADC_CHSELR_CHSEL13, - CH14 = ADC_CHSELR_CHSEL14, - CH15 = ADC_CHSELR_CHSEL15, - CHTemp = ADC_CHSELR_CHSEL16, - CHRef = ADC_CHSELR_CHSEL17, - CHBat = ADC_CHSELR_CHSEL18 + +struct SHAL_ADC_Common_Control_Reg { + + volatile uint32_t* reg; + uint32_t VoltageRefEnable; + uint32_t TempSensorEnable; + uint32_t VBatteryEnable; + +}; + +struct SHAL_ADC_RCC_Enable_Reg { + volatile uint32_t* reg; + uint32_t mask; +}; + +struct SHAL_ADC_Control_Reg { + volatile uint32_t* reg; + uint32_t enable_mask; + uint32_t disable_mask; + uint32_t calibration_mask; + uint32_t start_mask; +}; + +struct SHAL_ADC_Config_Reg { + volatile uint32_t* reg; + uint32_t continue_mask; + + uint32_t resolution_offset; + uint32_t alignment_offset; +}; + +struct SHAL_ADC_Data_Reg { + volatile uint32_t* reg; + uint32_t mask; +}; + +struct SHAL_ADC_ISR { + + volatile uint32_t* reg; + uint32_t end_of_conversion_mask; +}; + +struct SHAL_ADC_Clock_Reg { + volatile uint32_t* reg; + uint32_t clear; + uint32_t mask; +}; + + +enum class SHAL_ADC_Channel : uint32_t { + CH0, + CH1, + CH2, + CH3, + CH4, + CH5, + CH6, + CH7, + CH8, + CH9, + CH10, + CH11, + CH12, + CH13, + CH14, + CH15, + CHTemp, + CHRef, + CHBat }; enum class ADC_SampleTime : uint32_t { @@ -38,4 +87,16 @@ enum class ADC_SampleTime : uint32_t { C239 = 0x07 //239.5 cycles }; +enum class SHAL_ADC_Resolution : uint8_t { + B12 = 0x00, + B10 = 0x01, + B8 = 0x02, + B6 = 0x03, +}; + +enum class SHAL_ADC_Alignment : uint8_t { + RIGHT = 0x00, + LEFT = 0x01, +}; + #endif //SHMINGO_HAL_SHAL_ADC_TYPES_H diff --git a/SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_REG_F072xB.h b/SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_REG_F072xB.h index 3bd4c51..e46394e 100644 --- a/SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_REG_F072xB.h +++ b/SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_REG_F072xB.h @@ -275,70 +275,70 @@ constexpr SHAL_GPIO_Port_Info getGPIOPortInfo(GPIO_Key key){ case GPIO_Key::A0: case GPIO_Key::B0: case GPIO_Key::C0: - return {0,ADC_Channel::CH0}; + return {0, SHAL_ADC_Channel::CH0}; case GPIO_Key::A1: case GPIO_Key::B1: case GPIO_Key::C1: - return {1,ADC_Channel::CH1}; + return {1, SHAL_ADC_Channel::CH1}; case GPIO_Key::A2: case GPIO_Key::B2: case GPIO_Key::C2: - return {2,ADC_Channel::CH2}; + return {2, SHAL_ADC_Channel::CH2}; case GPIO_Key::A3: case GPIO_Key::B3: case GPIO_Key::C3: - return {3,ADC_Channel::CH3}; + return {3, SHAL_ADC_Channel::CH3}; case GPIO_Key::A4: case GPIO_Key::B4: case GPIO_Key::C4: - return {4,ADC_Channel::CH4}; + return {4, SHAL_ADC_Channel::CH4}; case GPIO_Key::A5: case GPIO_Key::B5: case GPIO_Key::C5: - return {5,ADC_Channel::CH5}; + return {5, SHAL_ADC_Channel::CH5}; case GPIO_Key::A6: case GPIO_Key::B6: case GPIO_Key::C6: - return {6,ADC_Channel::CH6}; + return {6, SHAL_ADC_Channel::CH6}; case GPIO_Key::A7: case GPIO_Key::B7: case GPIO_Key::C7: - return {7,ADC_Channel::CH7}; + return {7, SHAL_ADC_Channel::CH7}; case GPIO_Key::A8: case GPIO_Key::B8: case GPIO_Key::C8: - return {8,ADC_Channel::CH8}; + return {8, SHAL_ADC_Channel::CH8}; case GPIO_Key::A9: case GPIO_Key::B9: case GPIO_Key::C9: - return {9,ADC_Channel::CH9}; + return {9, SHAL_ADC_Channel::CH9}; case GPIO_Key::A10: case GPIO_Key::B10: case GPIO_Key::C10: - return {10,ADC_Channel::CH10}; + return {10, SHAL_ADC_Channel::CH10}; case GPIO_Key::A11: case GPIO_Key::B11: case GPIO_Key::C11: - return {11,ADC_Channel::CH11}; + return {11, SHAL_ADC_Channel::CH11}; case GPIO_Key::A12: case GPIO_Key::B12: case GPIO_Key::C12: - return {12,ADC_Channel::CH12}; + return {12, SHAL_ADC_Channel::CH12}; case GPIO_Key::A13: case GPIO_Key::B13: case GPIO_Key::C13: - return {13,ADC_Channel::CH13}; + return {13, SHAL_ADC_Channel::CH13}; case GPIO_Key::A14: case GPIO_Key::B14: case GPIO_Key::C14: - return {14,ADC_Channel::CH14}; + return {14, SHAL_ADC_Channel::CH14}; case GPIO_Key::A15: case GPIO_Key::B15: case GPIO_Key::C15: - return {15,ADC_Channel::CH15}; + return {15, SHAL_ADC_Channel::CH15}; case GPIO_Key::NUM_GPIO: case GPIO_Key::INVALID: - return {0,ADC_Channel::CH0}; + return {0, SHAL_ADC_Channel::CH0}; } __builtin_unreachable(); } 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 6ee1244..36e125b 100644 --- a/SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_REG_L432KC.h +++ b/SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_REG_L432KC.h @@ -252,70 +252,70 @@ constexpr SHAL_GPIO_Port_Info getGPIOPortInfo(GPIO_Key key){ case GPIO_Key::A0: case GPIO_Key::B0: case GPIO_Key::C0: - return {0,ADC_Channel::CH0}; + return {0, SHAL_ADC_Channel::CH0}; case GPIO_Key::A1: case GPIO_Key::B1: case GPIO_Key::C1: - return {1,ADC_Channel::CH1}; + return {1, SHAL_ADC_Channel::CH1}; case GPIO_Key::A2: case GPIO_Key::B2: case GPIO_Key::C2: - return {2,ADC_Channel::CH2}; + return {2, SHAL_ADC_Channel::CH2}; case GPIO_Key::A3: case GPIO_Key::B3: case GPIO_Key::C3: - return {3,ADC_Channel::CH3}; + return {3, SHAL_ADC_Channel::CH3}; case GPIO_Key::A4: case GPIO_Key::B4: case GPIO_Key::C4: - return {4,ADC_Channel::CH4}; + return {4, SHAL_ADC_Channel::CH4}; case GPIO_Key::A5: case GPIO_Key::B5: case GPIO_Key::C5: - return {5,ADC_Channel::CH5}; + return {5, SHAL_ADC_Channel::CH5}; case GPIO_Key::A6: case GPIO_Key::B6: case GPIO_Key::C6: - return {6,ADC_Channel::CH6}; + return {6, SHAL_ADC_Channel::CH6}; case GPIO_Key::A7: case GPIO_Key::B7: case GPIO_Key::C7: - return {7,ADC_Channel::CH7}; + return {7, SHAL_ADC_Channel::CH7}; case GPIO_Key::A8: case GPIO_Key::B8: case GPIO_Key::C8: - return {8,ADC_Channel::CH8}; + return {8, SHAL_ADC_Channel::CH8}; case GPIO_Key::A9: case GPIO_Key::B9: case GPIO_Key::C9: - return {9,ADC_Channel::CH9}; + return {9, SHAL_ADC_Channel::CH9}; case GPIO_Key::A10: case GPIO_Key::B10: case GPIO_Key::C10: - return {10,ADC_Channel::CH10}; + return {10, SHAL_ADC_Channel::CH10}; case GPIO_Key::A11: case GPIO_Key::B11: case GPIO_Key::C11: - return {11,ADC_Channel::CH11}; + return {11, SHAL_ADC_Channel::CH11}; case GPIO_Key::A12: case GPIO_Key::B12: case GPIO_Key::C12: - return {12,ADC_Channel::CH12}; + return {12, SHAL_ADC_Channel::CH12}; case GPIO_Key::A13: case GPIO_Key::B13: case GPIO_Key::C13: - return {13,ADC_Channel::CH13}; + return {13, SHAL_ADC_Channel::CH13}; case GPIO_Key::A14: case GPIO_Key::B14: case GPIO_Key::C14: - return {14,ADC_Channel::CH14}; + return {14, SHAL_ADC_Channel::CH14}; case GPIO_Key::A15: case GPIO_Key::B15: case GPIO_Key::C15: - return {15,ADC_Channel::CH15}; + return {15, SHAL_ADC_Channel::CH15}; case GPIO_Key::NUM_GPIO: case GPIO_Key::INVALID: - return {0,ADC_Channel::CH0}; + return {0, SHAL_ADC_Channel::CH0}; } __builtin_unreachable(); } diff --git a/SHAL/Include/Peripheral/GPIO/SHAL_GPIO_TYPES.h b/SHAL/Include/Peripheral/GPIO/SHAL_GPIO_TYPES.h index e877ed2..9f651c8 100644 --- a/SHAL/Include/Peripheral/GPIO/SHAL_GPIO_TYPES.h +++ b/SHAL/Include/Peripheral/GPIO/SHAL_GPIO_TYPES.h @@ -27,7 +27,7 @@ struct SHAL_Peripheral_Register { struct SHAL_GPIO_Port_Info{ uint8_t number; - ADC_Channel ADCChannel; + SHAL_ADC_Channel ADCChannel; }; enum class PinMode : uint8_t{ diff --git a/SHAL/Include/Peripheral/I2C/Reg/SHAL_I2C_REG_L432KC.h b/SHAL/Include/Peripheral/I2C/Reg/SHAL_I2C_REG_L432KC.h index 0d8dae6..243f7ee 100644 --- a/SHAL/Include/Peripheral/I2C/Reg/SHAL_I2C_REG_L432KC.h +++ b/SHAL/Include/Peripheral/I2C/Reg/SHAL_I2C_REG_L432KC.h @@ -62,6 +62,9 @@ constexpr SHAL_I2C_Reset_Reg getI2CResetReg(const I2C_Pair pair){ __builtin_unreachable(); } +constexpr SHAL_I2C_Reset_Reg getI2CResetRe() { + return {&RCC->APB1RSTR1,RCC_APB1RSTR1_I2C1RST}; +} //Gets all the bits in the I2C timer register, these values should rarely be manually set, but I wanted to support it anyway constexpr SHAL_I2C_Timing_Reg getI2CTimerReg(const I2C_Pair pair){ switch(pair){ diff --git a/SHAL/Include/Peripheral/I2C/SHAL_I2C_REG.h b/SHAL/Include/Peripheral/I2C/SHAL_I2C_REG.h index 8512193..3e4f2ae 100644 --- a/SHAL/Include/Peripheral/I2C/SHAL_I2C_REG.h +++ b/SHAL/Include/Peripheral/I2C/SHAL_I2C_REG.h @@ -44,7 +44,7 @@ #elif defined(STM32L431xx) #include "stm32l431xx.h" #elif defined(STM32L432xx) - #include "stm32l432xx.h" + #include "SHAL_I2C_REG_L432KC.h" #elif defined(STM32L433xx) #include "stm32l433xx.h" #elif defined(STM32L442xx) diff --git a/SHAL/Src/STM32F0XX/Peripheral/ADC/SHAL_ADC.cpp b/SHAL/Src/STM32F0XX/Peripheral/ADC/SHAL_ADC.cpp index aab394b..d5609af 100644 --- a/SHAL/Src/STM32F0XX/Peripheral/ADC/SHAL_ADC.cpp +++ b/SHAL/Src/STM32F0XX/Peripheral/ADC/SHAL_ADC.cpp @@ -64,7 +64,7 @@ SHAL_Result SHAL_ADC::calibrate() { return SHAL_Result::OKAY; } -uint16_t SHAL_ADC::singleConvertSingle(ADC_Channel channel, ADC_SampleTime time) { +uint16_t SHAL_ADC::singleConvertSingle(SHAL_ADC_Channel channel, ADC_SampleTime time) { ADC_TypeDef* ADC_reg = getADCRegister(m_ADCKey); @@ -81,7 +81,7 @@ uint16_t SHAL_ADC::singleConvertSingle(ADC_Channel channel, ADC_SampleTime time) return result; } -void SHAL_ADC::multiConvertSingle(ADC_Channel* channels, const int numChannels, uint16_t* result, ADC_SampleTime time) { +void SHAL_ADC::multiConvertSingle(SHAL_ADC_Channel* channels, const int numChannels, uint16_t* result, 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 diff --git a/SHAL/Src/STM32F0XX/Peripheral/GPIO/SHAL_GPIO.cpp b/SHAL/Src/STM32F0XX/Peripheral/GPIO/SHAL_GPIO.cpp index 9613ab7..5dec173 100644 --- a/SHAL/Src/STM32F0XX/Peripheral/GPIO/SHAL_GPIO.cpp +++ b/SHAL/Src/STM32F0XX/Peripheral/GPIO/SHAL_GPIO.cpp @@ -109,7 +109,7 @@ void SHAL_GPIO::useAsExternalInterrupt(TriggerMode mode, EXTICallback callback) uint16_t SHAL_GPIO::analogRead(ADC_SampleTime sampleTime) { - ADC_Channel channel = getGPIOPortInfo(m_GPIO_KEY).ADCChannel; + SHAL_ADC_Channel channel = getGPIOPortInfo(m_GPIO_KEY).ADCChannel; return GPIOManager::getGPIOADC().singleConvertSingle(channel,sampleTime); } diff --git a/SHAL/Src/STM32L4XX/Peripheral/ADC/SHAL_ADC.cpp b/SHAL/Src/STM32L4XX/Peripheral/ADC/SHAL_ADC.cpp index 980f43c..ac11334 100644 --- a/SHAL/Src/STM32L4XX/Peripheral/ADC/SHAL_ADC.cpp +++ b/SHAL/Src/STM32L4XX/Peripheral/ADC/SHAL_ADC.cpp @@ -13,22 +13,19 @@ SHAL_Result SHAL_ADC::init() { ADC_TypeDef* ADC_reg = getADCRegister(m_ADCKey); + SHAL_ADC_RCC_Enable_Reg clock_reg = getADCRCCEnableRegister(m_ADCKey); //Clock enable - RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; //Enable clock - RCC->CR2 |= RCC_CR2_HSI14ON; //Start peripheral oscillator + *clock_reg.reg |= clock_reg.mask; - if(!SHAL_WAIT_FOR_CONDITION_US(((RCC->CR2 & RCC_CR2_HSI14RDY) != 0),50)){ //Wait for clock OKAY - return SHAL_Result::ERROR; - } + SHAL_ADC_Control_Reg control_reg = getADCControlReg(m_ADCKey); - if((ADC_reg->ISR & ADC_ISR_ADRDY) != 0){ //Set ADRDY to 0 - ADC_reg->ISR |= ADC_ISR_ADRDY; - } - - ADC_reg->CR |= ADC_CR_ADEN; //Enable - - if(!SHAL_WAIT_FOR_CONDITION_US(((ADC_reg->ISR & ADC_ISR_ADRDY) != 0),50)){ //Wait for disable - return SHAL_Result::ERROR; + if (*control_reg.reg & control_reg.enable_mask) { + //request disable: ADEN=1 -> set ADDIS to disable + *control_reg.reg |= control_reg.disable_mask; + //wait until ADEN cleared (ISR.ADREADY == 0) + if(!SHAL_WAIT_FOR_CONDITION_MS((*control_reg.reg & control_reg.enable_mask) == 0, 100)){ + return SHAL_Result::ERROR; + } } if(calibrate() != SHAL_Result::OKAY){ //Calibrate @@ -40,34 +37,26 @@ SHAL_Result SHAL_ADC::init() { SHAL_Result SHAL_ADC::calibrate() { - if(m_ADCKey == ADC_Key::INVALID || m_ADCKey == ADC_Key::NUM_ADC){ + if(disable() != SHAL_Result::OKAY){ //Disable the ADC return SHAL_Result::ERROR; } - ADC_TypeDef* ADC_reg = getADCRegister(m_ADCKey); + SHAL_ADC_Control_Reg control_reg = getADCControlReg(m_ADCKey); - if((ADC_reg->CR & ADC_CR_ADEN) != 0){ //Clear ADEN (enable) - ADC_reg->CR |= ADC_CR_ADDIS; - } + *control_reg.reg |= control_reg.calibration_mask; - if(!SHAL_WAIT_FOR_CONDITION_US(((ADC_reg->CR & ADC_CR_ADEN) == 0),50)){ //Wait for disable - return SHAL_Result::ERROR; - } - - ADC_reg->CFGR1 &= ~ADC_CFGR1_DMAEN; //Clear DMAEN - ADC_reg->CR |= ADC_CR_ADCAL; //Launch calibration by setting ADCAL - - if(!SHAL_WAIT_FOR_CONDITION_US(((ADC_reg->CR & ADC_CR_ADCAL) == 0),50)){ //Wait for calibration + if(!SHAL_WAIT_FOR_CONDITION_US(((*control_reg.reg & control_reg.calibration_mask) == 0),500)){ //Wait for calibration return SHAL_Result::ERROR; } return SHAL_Result::OKAY; } -uint16_t SHAL_ADC::singleConvertSingle(ADC_Channel channel, ADC_SampleTime time) { +uint16_t SHAL_ADC::singleConvertSingle(SHAL_ADC_Channel channel, 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 ADC_reg->CHSELR = static_cast(channel); //Enable channel for conversion @@ -81,7 +70,7 @@ uint16_t SHAL_ADC::singleConvertSingle(ADC_Channel channel, ADC_SampleTime time) return result; } -void SHAL_ADC::multiConvertSingle(ADC_Channel* channels, const int numChannels, uint16_t* result, ADC_SampleTime time) { +void SHAL_ADC::multiConvertSingle(SHAL_ADC_Channel* channels, const int numChannels, uint16_t* result, 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 @@ -102,6 +91,57 @@ void SHAL_ADC::multiConvertSingle(ADC_Channel* channels, const int numChannels, } } +SHAL_Result SHAL_ADC::disable() { + + if(!isValid()){ + return SHAL_Result::ERROR; + } + + SHAL_ADC_Control_Reg control_reg = getADCControlReg(m_ADCKey); + if (*control_reg.reg & control_reg.enable_mask) { + //request disable: ADEN=1 -> set ADDIS to disable + *control_reg.reg |= control_reg.disable_mask; + //wait until ADEN cleared (ISR.ADREADY == 0) + if(!SHAL_WAIT_FOR_CONDITION_MS((*control_reg.reg & control_reg.enable_mask) == 0, 100)){ + return SHAL_Result::ERROR; + } + } + + return SHAL_Result::OKAY; +} + +bool SHAL_ADC::isValid() { + if(m_ADCKey == ADC_Key::INVALID || m_ADCKey == ADC_Key::NUM_ADC){ + return false; + } + return true; +} + +SHAL_Result SHAL_ADC::configureResolution(SHAL_ADC_Resolution resolution) { + if(!isValid()){ + return SHAL_Result::ERROR; + } + + SHAL_ADC_Config_Reg config_reg = getADCConfigReg(m_ADCKey); + + SHAL_set_bits(config_reg.reg,2) + + return SHAL_Result::OKAY; +} + +SHAL_Result SHAL_ADC::configureAlignment(SHAL_ADC_Alignment alignment) { + if(!isValid()){ + return SHAL_Result::ERROR; + } + + SHAL_ADC_Config_Reg config_reg = getADCConfigReg(m_ADCKey); + + *config_reg.reg &= ~(0x1UL << config_reg.alignment_offset); //TODO check if this needs to be abstracted (Do other platforms have >2 resolution possibilities? + *config_reg.reg |= static_cast(alignment) << config_reg.alignment_offset; + + return SHAL_Result::OKAY; +} + SHAL_ADC &ADCManager::get(ADC_Key key) { return m_ADCs[static_cast(key)]; } diff --git a/SHAL/Src/STM32L4XX/Peripheral/GPIO/SHAL_GPIO.cpp b/SHAL/Src/STM32L4XX/Peripheral/GPIO/SHAL_GPIO.cpp index 9613ab7..5dec173 100644 --- a/SHAL/Src/STM32L4XX/Peripheral/GPIO/SHAL_GPIO.cpp +++ b/SHAL/Src/STM32L4XX/Peripheral/GPIO/SHAL_GPIO.cpp @@ -109,7 +109,7 @@ void SHAL_GPIO::useAsExternalInterrupt(TriggerMode mode, EXTICallback callback) uint16_t SHAL_GPIO::analogRead(ADC_SampleTime sampleTime) { - ADC_Channel channel = getGPIOPortInfo(m_GPIO_KEY).ADCChannel; + SHAL_ADC_Channel channel = getGPIOPortInfo(m_GPIO_KEY).ADCChannel; return GPIOManager::getGPIOADC().singleConvertSingle(channel,sampleTime); }