Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor adc #1039

Merged
merged 2 commits into from
Sep 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion source/Core/BSP/BSP.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ void resetWatchdog();
// Accepts a output level of 0.. to use to control the tip output PWM
void setTipPWM(uint8_t pulse);
// Returns the Handle temp in C, X10
uint16_t getHandleTemperature();
uint16_t getHandleTemperature(uint8_t sample);
// Returns the Tip temperature ADC reading in raw units
uint16_t getTipRawTemp(uint8_t refresh);
// Returns the main DC input voltage, using the adjustable divisor + sample flag
Expand Down
2 changes: 1 addition & 1 deletion source/Core/BSP/MHP30/BSP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
HAL_IncTick();
}
}
uint16_t getHandleTemperature() {
uint16_t getHandleTemperature(uint8_t sample) {
int32_t result = getADC(0);
return Utils::InterpolateLookupTable(NTCHandleLookup, NTCHandleLookupItems, result);
}
Expand Down
77 changes: 11 additions & 66 deletions source/Core/BSP/Miniware/BSP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,12 @@ static const uint16_t NTCHandleLookup[] = {
};
#endif

uint16_t getHandleTemperature() {
uint16_t getHandleTemperature(uint8_t sample) {
int32_t result = getADCHandleTemp(sample);
#ifdef TEMP_NTC
// TS80P uses 100k NTC resistors instead
// NTCG104EF104FT1X from TDK
// For now not doing interpolation
int32_t result = getADC(0);
for (uint32_t i = 0; i < (sizeof(NTCHandleLookup) / (2 * sizeof(uint16_t))); i++) {
if (result > NTCHandleLookup[(i * 2) + 0]) {
return NTCHandleLookup[(i * 2) + 1] * 10;
Expand All @@ -114,80 +114,25 @@ uint16_t getHandleTemperature() {
// mV per count So we need to subtract an offset of 0.5V to center on 0C
// (4964.8 counts)
//
int32_t result = getADC(0);
result -= 4965; // remove 0.5V offset
// 10mV per C
// 99.29 counts per Deg C above 0C. Tends to read a tad over across all of my sample units
result *= 100;
result /= 994;
return result;
#endif
}

uint16_t getTipInstantTemperature() {
uint16_t sum = 0; // 12 bit readings * 8 -> 15 bits
uint16_t readings[8];
// Looking to reject the highest outlier readings.
// As on some hardware these samples can run into the op-amp recovery time
// Once this time is up the signal stabilises quickly, so no need to reject minimums
readings[0] = hadc1.Instance->JDR1;
readings[1] = hadc1.Instance->JDR2;
readings[2] = hadc1.Instance->JDR3;
readings[3] = hadc1.Instance->JDR4;
readings[4] = hadc2.Instance->JDR1;
readings[5] = hadc2.Instance->JDR2;
readings[6] = hadc2.Instance->JDR3;
readings[7] = hadc2.Instance->JDR4;

for (int i = 0; i < 8; i++) {
sum += readings[i];
}
return sum; // 8x over sample
}

uint16_t getTipRawTemp(uint8_t refresh) {
if (refresh) {
uint16_t lastSample = getTipInstantTemperature();
rawTempFilter.update(lastSample);
return lastSample;
} else {
return rawTempFilter.average();
}
return 0;
}

uint16_t getInputVoltageX10(uint16_t divisor, uint8_t sample) {
// ADC maximum is 32767 == 3.3V at input == 28.05V at VIN
// Therefore we can divide down from there
// Multiplying ADC max by 4 for additional calibration options,
// ideal term is 467
#ifdef MODEL_TS100
#define BATTFILTERDEPTH 32
#else
#define BATTFILTERDEPTH 8

#endif
static uint8_t preFillneeded = 10;
static uint32_t samples[BATTFILTERDEPTH];
static uint8_t index = 0;
if (preFillneeded) {
for (uint8_t i = 0; i < BATTFILTERDEPTH; i++)
samples[i] = getADC(1);
preFillneeded--;
}
if (sample) {
samples[index] = getADC(1);
index = (index + 1) % BATTFILTERDEPTH;
}
uint32_t sum = 0;

for (uint8_t i = 0; i < BATTFILTERDEPTH; i++)
sum += samples[i];

sum /= BATTFILTERDEPTH;
if (divisor == 0) {
divisor = 1;
}
return sum * 4 / divisor;
// ADC maximum is 32767 == 3.3V at input == 28.05V at VIN
// Therefore we can divide down from there
// Multiplying ADC max by 4 for additional calibration options,
// ideal term is 467
uint32_t res = getADCVin(sample);
res *= 4;
res /= divisor;
return res;
}

void setTipPWM(uint8_t pulse) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
* Author: Ben V. Brown
*/
#include "Setup.h"
#include "BSP.h"
#include "Pins.h"
#include "history.hpp"
#include <stdint.h>
ADC_HandleTypeDef hadc1;
ADC_HandleTypeDef hadc2;
DMA_HandleTypeDef hdma_adc1;
Expand All @@ -17,9 +20,9 @@ DMA_HandleTypeDef hdma_i2c1_tx;
IWDG_HandleTypeDef hiwdg;
TIM_HandleTypeDef htim2;
TIM_HandleTypeDef htim3;
#define ADC_CHANNELS 2
#define ADC_SAMPLES 16
uint32_t ADCReadings[ADC_SAMPLES * ADC_CHANNELS]; // room for 32 lots of the pair of readings
#define ADC_FILTER_LEN 32
#define ADC_SAMPLES 16
uint16_t ADCReadings[ADC_SAMPLES]; // Used to store the adc readings for the handle cold junction temp

// Functions
static void SystemClock_Config(void);
Expand Down Expand Up @@ -48,24 +51,53 @@ void Setup_HAL() {
MX_TIM3_Init();
MX_TIM2_Init();
MX_IWDG_Init();
HAL_ADC_Start(&hadc2);
HAL_ADCEx_MultiModeStart_DMA(&hadc1, ADCReadings, (ADC_SAMPLES * ADC_CHANNELS)); // start DMA of normal readings
HAL_ADCEx_InjectedStart(&hadc1); // enable injected readings
HAL_ADCEx_InjectedStart(&hadc2); // enable injected readings
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)ADCReadings, (ADC_SAMPLES)); // start DMA of normal readings
HAL_ADCEx_InjectedStart(&hadc1); // enable injected readings
HAL_ADCEx_InjectedStart(&hadc2); // enable injected readings
}

// channel 0 -> temperature sensor, 1-> VIN
uint16_t getADC(uint8_t channel) {
uint32_t sum = 0;
for (uint8_t i = 0; i < ADC_SAMPLES; i++) {
uint16_t adc1Sample = ADCReadings[channel + (i * ADC_CHANNELS)];
uint16_t adc2Sample = ADCReadings[channel + (i * ADC_CHANNELS)] >> 16;

sum += (adc1Sample + adc2Sample);
uint16_t getADCHandleTemp(uint8_t sample) {
static history<uint16_t, ADC_FILTER_LEN> filter = {{0}, 0, 0};
if (sample) {
uint32_t sum = 0;
for (uint8_t i = 0; i < ADC_SAMPLES; i++) {
sum += ADCReadings[i];
}
filter.update(sum);
}
return sum >> 2;
return filter.average() >> 1;
}

uint16_t getADCVin(uint8_t sample) {
static history<uint16_t, ADC_FILTER_LEN> filter = {{0}, 0, 0};
if (sample) {
uint16_t latestADC = 0;

latestADC += hadc2.Instance->JDR1;
latestADC += hadc2.Instance->JDR2;
latestADC += hadc2.Instance->JDR3;
latestADC += hadc2.Instance->JDR4;
latestADC <<= 3;
filter.update(latestADC);
}
return filter.average();
}
// Returns either average or instant value. When sample is set the samples from the injected ADC are copied to the filter and then the raw reading is returned
uint16_t getTipRawTemp(uint8_t sample) {
static history<uint16_t, ADC_FILTER_LEN> filter = {{0}, 0, 0};
if (sample) {
uint16_t latestADC = 0;

latestADC += hadc1.Instance->JDR1;
latestADC += hadc1.Instance->JDR2;
latestADC += hadc1.Instance->JDR3;
latestADC += hadc1.Instance->JDR4;
latestADC <<= 1;
filter.update(latestADC);
return latestADC;
}
return filter.average();
}
/** System Clock Configuration
*/
void SystemClock_Config(void) {
Expand Down Expand Up @@ -113,7 +145,6 @@ void SystemClock_Config(void) {

/* ADC1 init function */
static void MX_ADC1_Init(void) {
ADC_MultiModeTypeDef multimode;

ADC_ChannelConfTypeDef sConfig;
ADC_InjectionConfTypeDef sConfigInjected;
Expand All @@ -125,27 +156,16 @@ static void MX_ADC1_Init(void) {
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = ADC_CHANNELS;
hadc1.Init.NbrOfConversion = 1;
HAL_ADC_Init(&hadc1);

/**Configure the ADC multi-mode
*/
multimode.Mode = ADC_DUALMODE_REGSIMULT_INJECSIMULT;
HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode);

/**Configure Regular Channel
*/
sConfig.Channel = TMP36_ADC1_CHANNEL;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);

/**Configure Regular Channel
*/
sConfig.Channel = VIN_ADC1_CHANNEL;
sConfig.Rank = ADC_REGULAR_RANK_2;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);

/**Configure Injected Channel
*/
// F in = 10.66 MHz
Expand All @@ -157,15 +177,13 @@ static void MX_ADC1_Init(void) {
sConfigInjected.InjectedChannel = TIP_TEMP_ADC1_CHANNEL;
sConfigInjected.InjectedRank = 1;
sConfigInjected.InjectedNbrOfConversion = 4;
sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_1CYCLE_5;
sConfigInjected.ExternalTrigInjecConv = ADC_EXTERNALTRIGINJECCONV_T2_CC1;
sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_28CYCLES_5;
sConfigInjected.ExternalTrigInjecConv = ADC_EXTERNALTRIGINJECCONV_T2_TRGO;
sConfigInjected.AutoInjectedConv = DISABLE;
sConfigInjected.InjectedDiscontinuousConvMode = DISABLE;
sConfigInjected.InjectedOffset = 0;

HAL_ADCEx_InjectedConfigChannel(&hadc1, &sConfigInjected);
sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_1CYCLE_5;

sConfigInjected.InjectedRank = 2;
HAL_ADCEx_InjectedConfigChannel(&hadc1, &sConfigInjected);
sConfigInjected.InjectedRank = 3;
Expand All @@ -180,44 +198,30 @@ static void MX_ADC1_Init(void) {

/* ADC2 init function */
static void MX_ADC2_Init(void) {
ADC_ChannelConfTypeDef sConfig;
ADC_InjectionConfTypeDef sConfigInjected;

/**Common config
*/
hadc2.Instance = ADC2;
hadc2.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc2.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc2.Init.ContinuousConvMode = ENABLE;
hadc2.Init.DiscontinuousConvMode = DISABLE;
hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc2.Init.NbrOfConversion = ADC_CHANNELS;
hadc2.Init.NbrOfConversion = 0;
HAL_ADC_Init(&hadc2);

/**Configure Regular Channel
*/
sConfig.Channel = TMP36_ADC2_CHANNEL;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;
HAL_ADC_ConfigChannel(&hadc2, &sConfig);

sConfig.Channel = VIN_ADC2_CHANNEL;
sConfig.Rank = ADC_REGULAR_RANK_2;
HAL_ADC_ConfigChannel(&hadc2, &sConfig);

/**Configure Injected Channel
*/
sConfigInjected.InjectedChannel = TIP_TEMP_ADC2_CHANNEL;
sConfigInjected.InjectedChannel = VIN_ADC2_CHANNEL;
sConfigInjected.InjectedRank = ADC_INJECTED_RANK_1;
sConfigInjected.InjectedNbrOfConversion = 4;
sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_1CYCLE_5;
sConfigInjected.ExternalTrigInjecConv = ADC_EXTERNALTRIGINJECCONV_T2_CC1;
sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_28CYCLES_5;
sConfigInjected.ExternalTrigInjecConv = ADC_EXTERNALTRIGINJECCONV_T2_TRGO;
sConfigInjected.AutoInjectedConv = DISABLE;
sConfigInjected.InjectedDiscontinuousConvMode = DISABLE;
sConfigInjected.InjectedOffset = 0;
HAL_ADCEx_InjectedConfigChannel(&hadc2, &sConfigInjected);
sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_1CYCLE_5;

sConfigInjected.InjectedRank = ADC_INJECTED_RANK_2;
HAL_ADCEx_InjectedConfigChannel(&hadc2, &sConfigInjected);
sConfigInjected.InjectedRank = ADC_INJECTED_RANK_3;
Expand Down Expand Up @@ -334,7 +338,7 @@ static void MX_TIM2_Init(void) {
HAL_TIM_PWM_Init(&htim2);
HAL_TIM_OC_Init(&htim2);

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC1;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig);

Expand Down
6 changes: 3 additions & 3 deletions source/Core/BSP/Miniware/Setup.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ extern IWDG_HandleTypeDef hiwdg;
extern TIM_HandleTypeDef htim2;
extern TIM_HandleTypeDef htim3;
void Setup_HAL();
uint16_t getADC(uint8_t channel);

void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); // Since the hal header file does not define this one
uint16_t getADCHandleTemp(uint8_t sample);
uint16_t getADCVin(uint8_t sample);
void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); // Since the hal header file does not define this one

#ifdef __cplusplus
}
Expand Down
4 changes: 2 additions & 2 deletions source/Core/BSP/Miniware/stm32f1xx_hal_msp.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc) {
hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_adc1.Init.Mode = DMA_CIRCULAR;
hdma_adc1.Init.Priority = DMA_PRIORITY_MEDIUM;
HAL_DMA_Init(&hdma_adc1);
Expand Down
Loading