From bf4d96a5e3f5779d1ede3048ad79ebba6a24a673 Mon Sep 17 00:00:00 2001
From: Alberto Nidasio <alberto.nidasio@skywarder.eu>
Date: Wed, 20 Jul 2022 08:57:48 +0000
Subject: [PATCH] [InternalTemp] Temperature sensor now working

---
 .vscode/c_cpp_properties.json            |  2 +-
 src/shared/drivers/adc/InternalADC.cpp   | 10 +++----
 src/shared/drivers/adc/InternalADC.h     |  2 ++
 src/shared/drivers/adc/InternalTemp.cpp  | 38 +++++++++++++++++-------
 src/shared/drivers/adc/InternalTemp.h    |  2 +-
 src/tests/drivers/test-internal-adc.cpp  |  8 ++---
 src/tests/drivers/test-internal-temp.cpp |  5 ++--
 7 files changed, 42 insertions(+), 25 deletions(-)

diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json
index a41cd2089..85f847299 100644
--- a/.vscode/c_cpp_properties.json
+++ b/.vscode/c_cpp_properties.json
@@ -8,7 +8,7 @@
             "defines": [
                 "DEBUG",
                 "_ARCH_CORTEXM4_STM32F4",
-                "_BOARD_STM32F407VG_STM32F4DISCOVERY",
+                "_BOARD_STM32F4DISCOVERY",
                 "_MIOSIX_BOARDNAME=stm32f407vg_stm32f4discovery",
                 "HSE_VALUE=8000000",
                 "SYSCLK_FREQ_168MHz=168000000",
diff --git a/src/shared/drivers/adc/InternalADC.cpp b/src/shared/drivers/adc/InternalADC.cpp
index 3f0efa629..7204cee1a 100644
--- a/src/shared/drivers/adc/InternalADC.cpp
+++ b/src/shared/drivers/adc/InternalADC.cpp
@@ -88,13 +88,13 @@ bool InternalADC::init()
     adc->CR2 |= ADC_CR2_ADON;
 
     // Set single conversion mode
-    adc->CR2 &= ~ADC_CR2_CONT;
+    // adc->CR2 &= ~ADC_CR2_CONT;
 
     // Set scan mode
-    adc->CR1 |= ADC_CR1_SCAN;
+    // adc->CR1 |= ADC_CR1_SCAN;
 
     // Data alignment
-    adc->CR2 &= ~ADC_CR2_ALIGN;  // right
+    // adc->CR2 &= ~ADC_CR2_ALIGN;  // right
 
     if (isUsingDMA)
     {
@@ -161,8 +161,6 @@ bool InternalADC::addRegularChannel(Channel channel)
     if (activeChannels >= 16)
         return false;
 
-    printf("Active channels %d\n", activeChannels);
-
     // Add the channel to the sequence
     volatile uint32_t* sqrPtr;
     switch (activeChannels / 6)
@@ -279,6 +277,8 @@ ADCData InternalADC::sampleImpl()
     return lastSample;
 }
 
+float InternalADC::getSupplyVoltage() { return supplyVoltage; }
+
 inline void InternalADC::resetRegisters()
 {
     // Reset the ADC configuration
diff --git a/src/shared/drivers/adc/InternalADC.h b/src/shared/drivers/adc/InternalADC.h
index 12ba9e638..feee9e21b 100644
--- a/src/shared/drivers/adc/InternalADC.h
+++ b/src/shared/drivers/adc/InternalADC.h
@@ -145,6 +145,8 @@ public:
 
     ADCData sampleImpl() override;
 
+    float getSupplyVoltage();
+
 private:
     inline void resetRegisters();
 
diff --git a/src/shared/drivers/adc/InternalTemp.cpp b/src/shared/drivers/adc/InternalTemp.cpp
index 89a791406..39a41d4ed 100644
--- a/src/shared/drivers/adc/InternalTemp.cpp
+++ b/src/shared/drivers/adc/InternalTemp.cpp
@@ -22,10 +22,10 @@
 
 #include "InternalTemp.h"
 
-#define TEMP110_CAL_VALUE ((uint16_t*)((uint32_t)0x1FFF7A2E))
 #define TEMP30_CAL_VALUE ((uint16_t*)((uint32_t)0x1FFF7A2C))
-#define TEMP110 110
+#define TEMP110_CAL_VALUE ((uint16_t*)((uint32_t)0x1FFF7A2E))
 #define TEMP30 30
+#define TEMP110 110
 
 namespace Boardcore
 {
@@ -39,6 +39,14 @@ InternalTemp::InternalTemp(InternalADC::SampleTime sampleTime,
 bool InternalTemp::init()
 {
     bool result = adc.init();
+
+#ifdef _BOARD_STM32F4DISCOVERY
+    adc.addRegularChannel(InternalADC::CH16);
+#else
+    adc.addRegularChannel(InternalADC::CH18);
+#endif
+
+    ADC->CCR &= ~ADC_CCR_VBATE;
     ADC->CCR |= ADC_CCR_TSVREFE;
 
     return result;
@@ -48,17 +56,25 @@ bool InternalTemp::selfTest() { return adc.selfTest(); }
 
 InternalTempData InternalTemp::sampleImpl()
 {
-    auto adcData = adc.readChannel(InternalADC::CH16);
-    printf("%2.3f \n", adcData.voltage);
+#ifdef _BOARD_STM32F4DISCOVERY
+    auto adcData = adc.readChannel(InternalADC::CH16, sampleTime);
+#else
+    auto adcData = adc.readChannel(InternalADC::CH18, sampleTime);
+#endif
+
     InternalTempData data;
     data.temperatureTimestamp = adcData.voltageTimestamp;
-    data.temperature          = ((adcData.voltage - 0.76) / 0.0025) + 25;
-    // data.temperature          = (int32_t)(
-    //    (TEMP110 - TEMP30) /
-    //        ((float)(*TEMP110_CAL_VALUE) - (float)(*TEMP30_CAL_VALUE)) *
-    //        (adcData.voltage - (float)(*TEMP30_CAL_VALUE)) +
-    //    TEMP30);
+
+    // Default conversion
+    // data.temperature          = ((adcData.voltage - 0.76) / 0.0025) + 25;
+
+    // Factory calibration
+    float voltage30  = static_cast<float>(*TEMP30_CAL_VALUE) * 3.3 / 4095;
+    float voltage110 = static_cast<float>(*TEMP110_CAL_VALUE) * 3.3 / 4095;
+    float slope      = (voltage110 - voltage30) / (TEMP110 - TEMP30);
+    data.temperature = ((adcData.voltage - voltage30) / slope) + TEMP30;
+
     return data;
 }
 
-}  // namespace Boardcore
\ No newline at end of file
+}  // namespace Boardcore
diff --git a/src/shared/drivers/adc/InternalTemp.h b/src/shared/drivers/adc/InternalTemp.h
index 280deb38e..a66e32caf 100644
--- a/src/shared/drivers/adc/InternalTemp.h
+++ b/src/shared/drivers/adc/InternalTemp.h
@@ -32,7 +32,7 @@ class InternalTemp : public Sensor<InternalTempData>
 {
 public:
     explicit InternalTemp(
-        InternalADC::SampleTime sampleTime = InternalADC::CYCLES_3,
+        InternalADC::SampleTime sampleTime = InternalADC::CYCLES_480,
         const float supplyVoltage          = 5.0);
 
     bool init() override;
diff --git a/src/tests/drivers/test-internal-adc.cpp b/src/tests/drivers/test-internal-adc.cpp
index 40bbf4f97..351505ab0 100644
--- a/src/tests/drivers/test-internal-adc.cpp
+++ b/src/tests/drivers/test-internal-adc.cpp
@@ -35,9 +35,9 @@ int main()
     // parent clock
 
     InternalADC adc(ADC3, 3.3);
-    adc.enableChannel(InternalADC::CH18);  // PF6
-    adc.enableChannel(InternalADC::CH5);   // PF7
-    adc.enableChannel(InternalADC::CH6);   // PF8
+    adc.enableChannel(InternalADC::CH4);  // PF6
+    adc.enableChannel(InternalADC::CH5);  // PF7
+    adc.enableChannel(InternalADC::CH6);  // PF8
     adc.init();
 
     printf("Configuration completed\n");
@@ -47,7 +47,7 @@ int main()
         adc.sample();
 
         printf("CH4:%1.3f\tCH5:%1.3f\tCH6:%1.3f\n",
-               adc.getVoltage(InternalADC::CH18).voltage,
+               adc.getVoltage(InternalADC::CH4).voltage,
                adc.getVoltage(InternalADC::CH5).voltage,
                adc.getVoltage(InternalADC::CH6).voltage);
 
diff --git a/src/tests/drivers/test-internal-temp.cpp b/src/tests/drivers/test-internal-temp.cpp
index 209f8aade..2d6c7dcf4 100644
--- a/src/tests/drivers/test-internal-temp.cpp
+++ b/src/tests/drivers/test-internal-temp.cpp
@@ -30,10 +30,9 @@ using namespace Boardcore;
 int main()
 {
     ADC->CCR |= ADC_CCR_ADCPRE_0 | ADC_CCR_ADCPRE_1;
+
     InternalTemp temp(InternalADC::CYCLES_480, 3.0);
     temp.init();
-    printf("Init done %ld\n",
-           ClockUtils::getAPBFrequency(ClockUtils::APB::APB2));
 
     for (;;)
     {
@@ -42,4 +41,4 @@ int main()
 
         miosix::delayMs(1000);
     }
-}
\ No newline at end of file
+}
-- 
GitLab