|
|
|
/**
|
|
|
|
* TODO file description
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "main.h"
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "app_temp.h"
|
|
|
|
#include "adc.h"
|
|
|
|
#include "snprintf.h"
|
|
|
|
|
|
|
|
/* DMA dest */
|
|
|
|
static volatile uint16_t adc_values[4];
|
|
|
|
|
|
|
|
const float V_REFINT = 1.23f;
|
|
|
|
|
|
|
|
#define AVERAGEBUF_DEPTH 8
|
|
|
|
#define OVENTEMP_HISTORY_DEPTH 5
|
|
|
|
|
|
|
|
static struct App {
|
|
|
|
float oven_temp;
|
|
|
|
float soc_temp;
|
|
|
|
float v_sensor;
|
|
|
|
uint16_t adc_averagebuf[AVERAGEBUF_DEPTH * 4];
|
|
|
|
uint8_t averagebuf_ptr;
|
|
|
|
float adc_averages[4];
|
|
|
|
float oventemp_history[OVENTEMP_HISTORY_DEPTH];
|
|
|
|
uint8_t oventemp_history_ptr;
|
|
|
|
} s_analog = {};
|
|
|
|
|
|
|
|
#define TSENSE_LOOKUP_LEN 101
|
|
|
|
#define TSENSE_T_STEP 5.0f
|
|
|
|
#define TSENSE_T_MIN 0.0f
|
|
|
|
#define TSENSE_T_MAX 500.0f
|
|
|
|
static const float TSENSE_LOOKUP[TSENSE_LOOKUP_LEN] = {
|
|
|
|
0.092678405931418f,
|
|
|
|
0.0943174479327356f,
|
|
|
|
0.095948157844312f,
|
|
|
|
0.0975706768542549f,
|
|
|
|
0.0991848957506647f,
|
|
|
|
0.100791037522732f,
|
|
|
|
0.102388993070241f,
|
|
|
|
0.103978983136042f,
|
|
|
|
0.105560980458654f,
|
|
|
|
0.107135039851509f,
|
|
|
|
0.108701215616829f,
|
|
|
|
0.110259642413441f,
|
|
|
|
0.111810211533421f,
|
|
|
|
0.113353137226489f,
|
|
|
|
0.114888310929339f,
|
|
|
|
0.11641594480226f,
|
|
|
|
0.117936009906507f,
|
|
|
|
0.119448557132363f,
|
|
|
|
0.120953636903929f,
|
|
|
|
0.122451377845456f,
|
|
|
|
0.12394167187544f,
|
|
|
|
0.125424725109556f,
|
|
|
|
0.126900429638119f,
|
|
|
|
0.128368989630084f,
|
|
|
|
0.129830374697352f,
|
|
|
|
0.131284632150064f,
|
|
|
|
0.132731808872517f,
|
|
|
|
0.134172027901771f,
|
|
|
|
0.135605181883591f,
|
|
|
|
0.13703146935069f,
|
|
|
|
0.138450783142958f,
|
|
|
|
0.139863319976468f,
|
|
|
|
0.14126904821384f,
|
|
|
|
0.142668011892657f,
|
|
|
|
0.144060254660872f,
|
|
|
|
0.145445894373796f,
|
|
|
|
0.146824824486877f,
|
|
|
|
0.14819723645253f,
|
|
|
|
0.149563023938454f,
|
|
|
|
0.150922376699229f,
|
|
|
|
0.15227526202401f,
|
|
|
|
0.153621720954182f,
|
|
|
|
0.15496179417407f,
|
|
|
|
0.156295594725426f,
|
|
|
|
0.157623016940038f,
|
|
|
|
0.158944245649448f,
|
|
|
|
0.160259175412251f,
|
|
|
|
0.16156798947087f,
|
|
|
|
0.162870654195634f,
|
|
|
|
0.164167207880495f,
|
|
|
|
0.165457688491696f,
|
|
|
|
0.166742204592451f,
|
|
|
|
0.168020651444079f,
|
|
|
|
0.169293207677971f,
|
|
|
|
0.170559768793747f,
|
|
|
|
0.171820511933356f,
|
|
|
|
0.173075402684405f,
|
|
|
|
0.174324476817747f,
|
|
|
|
0.175567769803026f,
|
|
|
|
0.176805386030345f,
|
|
|
|
0.178037221732226f,
|
|
|
|
0.179263449725904f,
|
|
|
|
0.180483966491086f,
|
|
|
|
0.181698943447122f,
|
|
|
|
0.182908345518766f,
|
|
|
|
0.184112206156428f,
|
|
|
|
0.185310558533273f,
|
|
|
|
0.186503503145257f,
|
|
|
|
0.187690937227925f,
|
|
|
|
0.188873028139146f,
|
|
|
|
0.190049673368296f,
|
|
|
|
0.191221038959601f,
|
|
|
|
0.192387089280576f,
|
|
|
|
0.193547855644572f,
|
|
|
|
0.194703369109397f,
|
|
|
|
0.195853726532112f,
|
|
|
|
0.196998826174689f,
|
|
|
|
0.19813883026229f,
|
|
|
|
0.199273637315452f,
|
|
|
|
0.200403408323351f,
|
|
|
|
0.201528107189346f,
|
|
|
|
0.20264776325594f,
|
|
|
|
0.203762405629782f,
|
|
|
|
0.204872127762998f,
|
|
|
|
0.205976828960191f,
|
|
|
|
0.207076666615101f,
|
|
|
|
0.208171540293999f,
|
|
|
|
0.209261606226334f,
|
|
|
|
0.210346827933364f,
|
|
|
|
0.211427232937629f,
|
|
|
|
0.212502848543705f,
|
|
|
|
0.213573765013592f,
|
|
|
|
0.214639882704581f,
|
|
|
|
0.215701354457324f,
|
|
|
|
0.216758080892489f,
|
|
|
|
0.217810213752734f,
|
|
|
|
0.218857716249547f,
|
|
|
|
0.219900614222686f,
|
|
|
|
0.220938933310224f,
|
|
|
|
0.221972760781578f,
|
|
|
|
0.223001998051553f,
|
|
|
|
};
|
|
|
|
|
|
|
|
void app_analog_init()
|
|
|
|
{
|
|
|
|
LL_ADC_Enable(ADC_TEMP);
|
|
|
|
|
|
|
|
LL_ADC_StartCalibration(ADC_TEMP);
|
|
|
|
while (LL_ADC_IsCalibrationOnGoing(ADC_TEMP)) {}
|
|
|
|
|
|
|
|
LL_DMA_ConfigAddresses(DMA1, LL_DMA_CHANNEL_1,
|
|
|
|
LL_ADC_DMA_GetRegAddr(ADC1, LL_ADC_DMA_REG_REGULAR_DATA),
|
|
|
|
(uint32_t) (void *) adc_values,
|
|
|
|
LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
|
|
|
|
|
|
|
|
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, 4);
|
|
|
|
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
|
|
|
|
|
|
|
|
LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1);
|
|
|
|
|
|
|
|
LL_ADC_REG_StartConversionExtTrig(ADC_TEMP, LL_ADC_REG_TRIG_EXT_RISING);
|
|
|
|
// LL_ADC_REG_StartConversionSWStart(ADC_TEMP);
|
|
|
|
|
|
|
|
// this timer runs with 1 kHz clock
|
|
|
|
LL_TIM_SetTriggerOutput(TIM1, LL_TIM_TRGO_CC1IF);
|
|
|
|
LL_TIM_CC_EnableChannel(TIM1, LL_TIM_CHANNEL_CH1);
|
|
|
|
LL_TIM_EnableAllOutputs(TIM1); // TIM1 needs outputs specially enabled - it's "advanced timer"
|
|
|
|
LL_TIM_EnableCounter(TIM1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static float val_to_c(float val)
|
|
|
|
{
|
|
|
|
// TODO use binary search.. lol
|
|
|
|
for (int i = 1; i < TSENSE_LOOKUP_LEN; i++) {
|
|
|
|
float cur = TSENSE_LOOKUP[i];
|
|
|
|
if (cur >= val) {
|
|
|
|
float prev = TSENSE_LOOKUP[i - 1];
|
|
|
|
|
|
|
|
float ratio = (val - prev) / (cur - prev);
|
|
|
|
return TSENSE_T_MIN + ((float) i + ratio) * TSENSE_T_STEP;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return TSENSE_T_MAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
void app_temp_sample()
|
|
|
|
{
|
|
|
|
uint32_t sums[4] = {};
|
|
|
|
int count = 0;
|
|
|
|
for (int i = 0; i < AVERAGEBUF_DEPTH * 4; i += 4) {
|
|
|
|
if (s_analog.adc_averagebuf[i + 3] != 0) {
|
|
|
|
sums[0] += s_analog.adc_averagebuf[i];
|
|
|
|
sums[1] += s_analog.adc_averagebuf[i + 1];
|
|
|
|
sums[2] += s_analog.adc_averagebuf[i + 2];
|
|
|
|
sums[3] += s_analog.adc_averagebuf[i + 3];
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (count == 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
s_analog.adc_averages[0] = (float) sums[0] / count;
|
|
|
|
s_analog.adc_averages[1] = (float) sums[1] / count;
|
|
|
|
s_analog.adc_averages[2] = (float) sums[2] / count;
|
|
|
|
s_analog.adc_averages[3] = (float) sums[3] / count;
|
|
|
|
|
|
|
|
/* r_pt100, r_ref, internal_temp, v_ref_int */
|
|
|
|
float refint = s_analog.adc_averages[3];
|
|
|
|
float scale = V_REFINT / refint;
|
|
|
|
|
|
|
|
const float avg_slope = 4.3f * scale;
|
|
|
|
const float v25 = 1.43f;
|
|
|
|
const float v_tsen = s_analog.adc_averages[2] * scale;
|
|
|
|
|
|
|
|
s_analog.soc_temp = (v25 - v_tsen) / avg_slope + 25.f;
|
|
|
|
s_analog.v_sensor = s_analog.adc_averages[0] * scale; // good for debug/tuning
|
|
|
|
|
|
|
|
|
|
|
|
// using a voltage divider, so assuming the reference resistor is measured well,
|
|
|
|
// we can just use the ratio and the exact voltage value is not important.
|
|
|
|
float actual_temp = val_to_c(s_analog.adc_averages[0] / s_analog.adc_averages[1]);
|
|
|
|
|
|
|
|
s_analog.oventemp_history[s_analog.oventemp_history_ptr] = actual_temp;
|
|
|
|
s_analog.oventemp_history_ptr = (s_analog.oventemp_history_ptr + 1) % OVENTEMP_HISTORY_DEPTH;
|
|
|
|
|
|
|
|
float sum = 0;
|
|
|
|
int depth = 0;
|
|
|
|
for (int i = 0; i < OVENTEMP_HISTORY_DEPTH; i++) {
|
|
|
|
if (s_analog.oventemp_history[i] > 0.0f) {
|
|
|
|
sum += s_analog.oventemp_history[i];
|
|
|
|
depth++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (depth > 0) {
|
|
|
|
sum /= depth;
|
|
|
|
}
|
|
|
|
s_analog.oven_temp = sum;
|
|
|
|
}
|
|
|
|
|
|
|
|
float app_temp_read_oven()
|
|
|
|
{
|
|
|
|
return s_analog.oven_temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
float app_temp_read_soc()
|
|
|
|
{
|
|
|
|
return s_analog.soc_temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
void app_temp_adc_eos()
|
|
|
|
{
|
|
|
|
//PUTCHAR('a');
|
|
|
|
|
|
|
|
// notify
|
|
|
|
memcpy((void *) &s_analog.adc_averagebuf[s_analog.averagebuf_ptr * 4], (const void *) adc_values, 4 * sizeof(uint16_t));
|
|
|
|
s_analog.averagebuf_ptr = (s_analog.averagebuf_ptr + 1) % AVERAGEBUF_DEPTH;
|
|
|
|
}
|
|
|
|
|
|
|
|
void app_temp_show_buf()
|
|
|
|
{
|
|
|
|
PRINTF("%d,%d,%d,%d\r\n", adc_values[0], adc_values[1], adc_values[2], adc_values[3]);
|
|
|
|
}
|