Skip to content
Snippets Groups Projects
Commit 8f5f5649 authored by Alberto Nidasio's avatar Alberto Nidasio
Browse files

[InternalADC] More `constexpr`, added missing `volatile` qualifier and moved...

[InternalADC] More `constexpr`, added missing `volatile` qualifier and moved calibration values initialization inside the class
parent c0786207
Branches
Tags
1 merge request!102[stm32f7] Add support for stm32f7 microcontrollers
......@@ -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
......@@ -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
{
......@@ -140,6 +145,16 @@ private:
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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment