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