Added core tools, added ADC abstractions for different registers

This commit is contained in:
Ea-r-th
2025-10-12 20:53:40 -07:00
parent c76dbee94c
commit cba6c00562
13 changed files with 291 additions and 95 deletions

View File

@@ -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;
}
//---------------------------------------------------------

View File

@@ -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<uint8_t>(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<uint8_t>(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<uint8_t>(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<uint8_t>(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<uint8_t>(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:

View File

@@ -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();
};

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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{

View File

@@ -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){

View File

@@ -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)

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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<uint32_t>(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<uint8_t>(alignment) << config_reg.alignment_offset;
return SHAL_Result::OKAY;
}
SHAL_ADC &ADCManager::get(ADC_Key key) {
return m_ADCs[static_cast<uint8_t>(key)];
}

View File

@@ -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);
}