diff --git a/src/shared/drivers/adc/InternalADC.cpp b/src/shared/drivers/adc/InternalADC.cpp index c39f7d886e9fb2375d8542bc8ec27f898aceb331..eba199a638bffb9f2284cf002c6ff65af028b52d 100644 --- a/src/shared/drivers/adc/InternalADC.cpp +++ b/src/shared/drivers/adc/InternalADC.cpp @@ -27,31 +27,33 @@ static constexpr int ADC_RESOLUTION = 4095; +namespace Boardcore +{ + #if defined(STM32F407xx) || defined(STM32F429xx) -#define CAL_PT1_VALUE ((uint16_t *)((uint32_t)0x1FFF7A2C)) -#define CAL_PT2_VALUE ((uint16_t *)((uint32_t)0x1FFF7A2E)) -static constexpr float CAL_PT1_TEMP = 30; -static constexpr float CAL_PT2_TEMP = 110; -static constexpr float CAL_V_DDA = 3.3f; +#define CAL_PT1_VALUE ((uint16_t volatile *)((uint32_t)0x1FFF7A2C)) +#define CAL_PT2_VALUE ((uint16_t volatile *)((uint32_t)0x1FFF7A2E)) +static const float CAL_PT1_TEMP = 30; +static const float CAL_PT2_TEMP = 110; +static const float CAL_V_DDA = 3.3f; #elif defined(STM32F767xx) || defined(STM32F769xx) -#define CAL_PT1_VALUE ((uint16_t *)((uint32_t)0x1FF0F44C)) -#define CAL_PT2_VALUE ((uint16_t *)((uint32_t)0x1FF0F44E)) -static constexpr float CAL_PT1_TEMP = 30; -static constexpr float CAL_PT2_TEMP = 110; -static constexpr float CAL_V_DDA = 3.3f; +#define CAL_PT1_VALUE ((uint16_t volatile *)((uint32_t)0x1FF0F44C)) +#define CAL_PT2_VALUE ((uint16_t volatile *)((uint32_t)0x1FF0F44E)) +static const float CAL_PT1_TEMP = 30; +static const float CAL_PT2_TEMP = 110; +static const float CAL_V_DDA = 3.3f; #else #warning This micro controller does not have a calibrated temperature sensor or is not currently supported by this driver -#define WITHOUT_CALIBRATION #endif #if defined(STM32F407xx) || defined(STM32F205xx) -#define TEMP_CH InternalADC::CH16 -#define VBAT_CH InternalADC::CH18 -static constexpr float VBAT_DIV = 2.0f; +static const InternalADC::Channel TEMP_CH = InternalADC::CH16; +static const InternalADC::Channel VBAT_CH = InternalADC::CH18; +static const float VBAT_DIV = 2.0f; #elif defined(STM32F429xx) || defined(STM32F767xx) || defined(STM32F769xx) -#define TEMP_CH InternalADC::CH18 -#define VBAT_CH InternalADC::CH18 -static constexpr float VBAT_DIV = 4.0f; +static const InternalADC::Channel TEMP_CH = InternalADC::CH18; +static const InternalADC::Channel VBAT_CH = InternalADC::CH18; +static const float VBAT_DIV = 4.0f; #endif // Error the user if the current target is missing the V_DDA_VOLTAGE macro @@ -61,37 +63,12 @@ static constexpr float VBAT_DIV = 4.0f; #error Missing V_DDA_VOLTAGE definition for current target #endif -// Factory calibration values -// Read "Temperature sensor characteristics" chapter in the datasheet -#ifndef WITHOUT_CALIBRATION - -float getCalPt1Voltage() -{ - static float pt1Voltage = - static_cast<float>(*CAL_PT1_VALUE) * CAL_V_DDA / ADC_RESOLUTION; - return pt1Voltage; -} - -float getCalPt2Voltage() -{ - static float pt2Voltage = - static_cast<float>(*CAL_PT2_VALUE) * CAL_V_DDA / ADC_RESOLUTION; - return pt2Voltage; -} - -float getCalSlope() +InternalADC::InternalADC(ADC_TypeDef *adc) : adc(adc) { - static float slope = (getCalPt2Voltage() - getCalPt1Voltage()) / - (CAL_PT2_TEMP - CAL_PT1_TEMP); - return slope; -} +#ifndef INTERNAL_ADC_WITHOUT_CALIBRATION + loadCalibrationValues(); #endif -namespace Boardcore -{ - -InternalADC::InternalADC(ADC_TypeDef *adc) : adc(adc) -{ resetRegisters(); ClockUtils::enablePeripheralClock(adc); @@ -167,13 +144,13 @@ InternalADCData InternalADC::sampleImpl() V_DDA_VOLTAGE // cppcheck-suppress ConfigurationNotChecked / ADC_RESOLUTION; -#ifdef WITHOUT_CALIBRATION +#ifdef INTERNAL_ADC_WITHOUT_CALIBRATION // Default conversion newData.temperature = ((newData.temperature - 0.76) / 0.0025) + 25; #else // Factory calibration - newData.temperature = newData.temperature - getCalPt1Voltage(); - newData.temperature /= getCalSlope(); + newData.temperature = newData.temperature - calPt1Voltage; + newData.temperature /= calSlope; newData.temperature += CAL_PT1_TEMP; #endif } @@ -312,4 +289,18 @@ uint16_t InternalADC::readChannel(Channel channel) return static_cast<uint16_t>(adc->DR); } +#ifndef INTERNAL_ADC_WITHOUT_CALIBRATION +void InternalADC::loadCalibrationValues() +{ + calPt1Voltage = static_cast<float>(*CAL_PT1_VALUE); + calPt1Voltage *= CAL_V_DDA / ADC_RESOLUTION; + + calPt2Voltage = static_cast<float>(*CAL_PT2_VALUE); + calPt2Voltage *= CAL_V_DDA / ADC_RESOLUTION; + + calSlope = calPt1Voltage - calPt2Voltage; + calSlope /= CAL_PT2_TEMP - CAL_PT1_TEMP; +} +#endif + } // namespace Boardcore diff --git a/src/shared/drivers/adc/InternalADC.h b/src/shared/drivers/adc/InternalADC.h index ac094ec820fe7f369019cec23278bdca04ab893d..46e5fdee493d4a06a8d5abe643f4e1368bdbc1fc 100644 --- a/src/shared/drivers/adc/InternalADC.h +++ b/src/shared/drivers/adc/InternalADC.h @@ -27,6 +27,11 @@ #include "InternalADCData.h" +#if not defined(STM32F407xx) && not defined(STM32F429xx) && \ + not defined(STM32F767xx) && not defined(STM32F769xx) +#define INTERNAL_ADC_WITHOUT_CALIBRATION +#endif + namespace Boardcore { @@ -93,7 +98,7 @@ public: * @brief Resets the ADC configuration and automatically enables the * peripheral clock. */ - explicit InternalADC(ADC_TypeDef* adc); + explicit InternalADC(ADC_TypeDef *adc); ~InternalADC(); @@ -135,11 +140,21 @@ private: uint16_t readChannel(Channel channel); - ADC_TypeDef* adc; + ADC_TypeDef *adc; bool channelsEnabled[CH_NUM]; bool tempEnabled = false; bool vbatEnabled = false; + +#ifndef INTERNAL_ADC_WITHOUT_CALIBRATION + void loadCalibrationValues(); + + // Factory calibration values + // Read "Temperature sensor characteristics" chapter in the datasheet + float calPt1Voltage; + float calPt2Voltage; + float calSlope; +#endif }; } // namespace Boardcore