2017-03-24 10:41:36 -07:00
|
|
|
/**
|
|
|
|
* @file adc_inputs.cpp
|
|
|
|
* @brief Low level ADC code
|
|
|
|
*
|
2019-05-15 01:16:41 -07:00
|
|
|
* rusEfi uses two ADC devices on the same 16 pins at the moment. Two ADC devices are used in orde to distinguish between
|
|
|
|
* fast and slow devices. The idea is that but only having few channels in 'fast' mode we can sample those faster?
|
|
|
|
*
|
|
|
|
* At the moment rusEfi does not allow to have more than 16 ADC channels combined. At the moment there is no flexibility to use
|
2019-05-28 15:19:51 -07:00
|
|
|
* any ADC pins, only the hardcoded choice of 16 pins.
|
2019-05-15 01:16:41 -07:00
|
|
|
*
|
2020-09-18 00:04:07 -07:00
|
|
|
* Slow ADC group is used for IAT, CLT, AFR, VBATT etc - this one is currently sampled at 500Hz
|
2017-03-24 10:41:36 -07:00
|
|
|
*
|
2020-09-18 00:04:07 -07:00
|
|
|
* Fast ADC group is used for MAP, MAF HIP - this one is currently sampled at 10KHz
|
2018-04-08 08:38:14 -07:00
|
|
|
* We need frequent MAP for map_averaging.cpp
|
2017-03-24 10:41:36 -07:00
|
|
|
*
|
2018-12-23 20:29:19 -08:00
|
|
|
* 10KHz equals one measurement every 3.6 degrees at 6000 RPM
|
|
|
|
*
|
2017-03-24 10:41:36 -07:00
|
|
|
* @date Jan 14, 2013
|
2020-01-13 18:57:43 -08:00
|
|
|
* @author Andrey Belomutskiy, (c) 2012-2020
|
2017-03-24 10:41:36 -07:00
|
|
|
*/
|
|
|
|
|
2018-09-16 19:26:57 -07:00
|
|
|
#include "global.h"
|
2017-03-24 10:41:36 -07:00
|
|
|
|
2019-04-12 17:52:51 -07:00
|
|
|
#if HAL_USE_ADC
|
2019-07-04 00:57:21 -07:00
|
|
|
#include "os_access.h"
|
2017-03-24 10:41:36 -07:00
|
|
|
|
|
|
|
#include "engine.h"
|
|
|
|
#include "adc_inputs.h"
|
2019-09-21 11:33:38 -07:00
|
|
|
#include "adc_subscription.h"
|
2017-03-24 10:41:36 -07:00
|
|
|
#include "AdcConfiguration.h"
|
|
|
|
#include "mpu_util.h"
|
2019-12-11 06:28:11 -08:00
|
|
|
#include "periodic_thread_controller.h"
|
2017-03-24 10:41:36 -07:00
|
|
|
|
|
|
|
#include "pin_repository.h"
|
|
|
|
#include "engine_math.h"
|
|
|
|
#include "engine_controller.h"
|
|
|
|
#include "maf.h"
|
2019-10-11 17:43:21 -07:00
|
|
|
#include "perf_trace.h"
|
2017-03-24 10:41:36 -07:00
|
|
|
|
2020-09-08 14:20:55 -07:00
|
|
|
// on F7 this must be aligned on a 32-byte boundary, and be a multiple of 32 bytes long.
|
|
|
|
// When we invalidate the cache line(s) for ADC samples, we don't want to nuke any
|
|
|
|
// adjacent data.
|
|
|
|
// F4 does not care
|
|
|
|
static __ALIGNED(32) adcsample_t slowAdcSampleBuf[ADC_BUF_DEPTH_SLOW * ADC_MAX_CHANNELS_COUNT];
|
|
|
|
static __ALIGNED(32) adcsample_t fastAdcSampleBuf[ADC_BUF_DEPTH_FAST * ADC_MAX_CHANNELS_COUNT];
|
|
|
|
|
|
|
|
static_assert(sizeof(slowAdcSampleBuf) % 32 == 0, "Slow ADC sample buffer size must be a multiple of 32 bytes");
|
|
|
|
static_assert(sizeof(fastAdcSampleBuf) % 32 == 0, "Fast ADC sample buffer size must be a multiple of 32 bytes");
|
|
|
|
|
2017-03-24 10:41:36 -07:00
|
|
|
static adc_channel_mode_e adcHwChannelEnabled[HW_MAX_ADC_INDEX];
|
|
|
|
|
2019-09-22 06:56:06 -07:00
|
|
|
EXTERN_ENGINE;
|
|
|
|
|
|
|
|
// Board voltage, with divider coefficient accounted for
|
|
|
|
float getVoltageDivided(const char *msg, adc_channel_e hwChannel DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
2019-09-22 07:02:07 -07:00
|
|
|
return getVoltage(msg, hwChannel PASS_ENGINE_PARAMETER_SUFFIX) * engineConfiguration->analogInputDividerCoefficient;
|
2019-09-22 06:56:06 -07:00
|
|
|
}
|
|
|
|
|
2019-09-22 13:41:10 -07:00
|
|
|
// voltage in MCU universe, from zero to VDD
|
|
|
|
float getVoltage(const char *msg, adc_channel_e hwChannel DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
|
|
|
return adcToVolts(getAdcValue(msg, hwChannel));
|
|
|
|
}
|
|
|
|
|
2020-09-08 14:20:55 -07:00
|
|
|
AdcDevice::AdcDevice(ADCConversionGroup* hwConfig, adcsample_t *buf) {
|
2017-03-24 10:41:36 -07:00
|
|
|
this->hwConfig = hwConfig;
|
2020-09-08 14:20:55 -07:00
|
|
|
this->samples = buf;
|
2017-03-24 10:41:36 -07:00
|
|
|
channelCount = 0;
|
|
|
|
conversionCount = 0;
|
|
|
|
errorsCount = 0;
|
|
|
|
|
|
|
|
hwConfig->sqr1 = 0;
|
|
|
|
hwConfig->sqr2 = 0;
|
|
|
|
hwConfig->sqr3 = 0;
|
2020-09-12 06:04:26 -07:00
|
|
|
#if ADC_MAX_CHANNELS_COUNT > 16
|
|
|
|
hwConfig->sqr4 = 0;
|
|
|
|
hwConfig->sqr5 = 0;
|
|
|
|
#endif /* ADC_MAX_CHANNELS_COUNT */
|
2020-09-08 14:20:55 -07:00
|
|
|
memset(hardwareIndexByIndernalAdcIndex, EFI_ADC_NONE, sizeof(hardwareIndexByIndernalAdcIndex));
|
2017-03-24 10:41:36 -07:00
|
|
|
memset(internalAdcIndexByHardwareIndex, 0xFFFFFFFF, sizeof(internalAdcIndexByHardwareIndex));
|
|
|
|
}
|
|
|
|
|
2020-04-23 19:50:18 -07:00
|
|
|
#if !defined(GPT_FREQ_FAST) || !defined(GPT_PERIOD_FAST)
|
2017-03-24 10:41:36 -07:00
|
|
|
/**
|
|
|
|
* 8000 RPM is 133Hz
|
|
|
|
* If we want to sample MAP once per 5 degrees we need 133Hz * (360 / 5) = 9576Hz of fast ADC
|
|
|
|
*/
|
|
|
|
// todo: migrate to continues ADC mode? probably not - we cannot afford the callback in
|
|
|
|
// todo: continues mode. todo: look into our options
|
2020-04-23 19:50:18 -07:00
|
|
|
#define GPT_FREQ_FAST 100000 /* PWM clock frequency. I wonder what does this setting mean? */
|
|
|
|
#define GPT_PERIOD_FAST 10 /* PWM period (in PWM ticks). */
|
|
|
|
#endif /* GPT_FREQ_FAST GPT_PERIOD_FAST */
|
2017-03-24 10:41:36 -07:00
|
|
|
|
2019-05-14 13:38:14 -07:00
|
|
|
// is there a reason to have this configurable at runtime?
|
2019-03-28 19:46:10 -07:00
|
|
|
#ifndef ADC_SLOW_DEVICE
|
2017-03-24 10:41:36 -07:00
|
|
|
#define ADC_SLOW_DEVICE ADCD1
|
2019-03-28 19:46:10 -07:00
|
|
|
#endif /* ADC_SLOW_DEVICE */
|
2017-03-24 10:41:36 -07:00
|
|
|
|
2019-05-14 13:38:14 -07:00
|
|
|
// is there a reason to have this configurable at runtime?
|
2019-03-28 19:46:10 -07:00
|
|
|
#ifndef ADC_FAST_DEVICE
|
2017-03-24 10:41:36 -07:00
|
|
|
#define ADC_FAST_DEVICE ADCD2
|
2019-03-28 19:46:10 -07:00
|
|
|
#endif /* ADC_FAST_DEVICE */
|
2017-03-24 10:41:36 -07:00
|
|
|
|
2017-08-07 04:28:21 -07:00
|
|
|
static volatile int slowAdcCounter = 0;
|
2017-03-24 10:41:36 -07:00
|
|
|
static LoggingWithStorage logger("ADC");
|
|
|
|
|
|
|
|
// todo: move this flag to Engine god object
|
|
|
|
static int adcDebugReporting = false;
|
|
|
|
|
|
|
|
EXTERN_ENGINE;
|
|
|
|
|
|
|
|
static adcsample_t getAvgAdcValue(int index, adcsample_t *samples, int bufDepth, int numChannels) {
|
2019-12-11 06:28:11 -08:00
|
|
|
uint32_t result = 0;
|
2017-03-24 10:41:36 -07:00
|
|
|
for (int i = 0; i < bufDepth; i++) {
|
|
|
|
result += samples[index];
|
|
|
|
index += numChannels;
|
|
|
|
}
|
2019-12-11 06:28:11 -08:00
|
|
|
|
|
|
|
// this truncation is guaranteed to not be lossy - the average can't be larger than adcsample_t
|
|
|
|
return static_cast<adcsample_t>(result / bufDepth);
|
2017-03-24 10:41:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-10-19 05:01:28 -07:00
|
|
|
// See https://github.com/rusefi/rusefi/issues/976 for discussion on these values
|
|
|
|
#define ADC_SAMPLING_SLOW ADC_SAMPLE_56
|
2017-03-24 10:41:36 -07:00
|
|
|
#define ADC_SAMPLING_FAST ADC_SAMPLE_28
|
|
|
|
/*
|
|
|
|
* ADC conversion group.
|
|
|
|
*/
|
2020-09-01 04:38:35 -07:00
|
|
|
static ADCConversionGroup adcgrpcfgSlow = {
|
|
|
|
.circular = FALSE,
|
|
|
|
.num_channels = 0,
|
|
|
|
.end_cb = nullptr,
|
|
|
|
.error_cb = nullptr,
|
|
|
|
/* HW dependent part.*/
|
|
|
|
.cr1 = 0,
|
|
|
|
.cr2 = ADC_CR2_SWSTART,
|
|
|
|
/**
|
|
|
|
* here we configure all possible channels for slow mode. Some channels would not actually
|
|
|
|
* be used hopefully that's fine to configure all possible channels.
|
|
|
|
*/
|
|
|
|
// sample times for channels 10...18
|
|
|
|
.smpr1 =
|
2017-03-24 10:41:36 -07:00
|
|
|
ADC_SMPR1_SMP_AN10(ADC_SAMPLING_SLOW) |
|
|
|
|
ADC_SMPR1_SMP_AN11(ADC_SAMPLING_SLOW) |
|
|
|
|
ADC_SMPR1_SMP_AN12(ADC_SAMPLING_SLOW) |
|
|
|
|
ADC_SMPR1_SMP_AN13(ADC_SAMPLING_SLOW) |
|
|
|
|
ADC_SMPR1_SMP_AN14(ADC_SAMPLING_SLOW) |
|
|
|
|
ADC_SMPR1_SMP_AN15(ADC_SAMPLING_SLOW) |
|
2020-09-01 04:38:35 -07:00
|
|
|
ADC_SMPR1_SMP_SENSOR(ADC_SAMPLE_144),
|
|
|
|
// In this field must be specified the sample times for channels 0...9
|
|
|
|
.smpr2 =
|
2017-03-24 10:41:36 -07:00
|
|
|
ADC_SMPR2_SMP_AN0(ADC_SAMPLING_SLOW) |
|
|
|
|
ADC_SMPR2_SMP_AN1(ADC_SAMPLING_SLOW) |
|
|
|
|
ADC_SMPR2_SMP_AN2(ADC_SAMPLING_SLOW) |
|
|
|
|
ADC_SMPR2_SMP_AN3(ADC_SAMPLING_SLOW) |
|
|
|
|
ADC_SMPR2_SMP_AN4(ADC_SAMPLING_SLOW) |
|
|
|
|
ADC_SMPR2_SMP_AN5(ADC_SAMPLING_SLOW) |
|
|
|
|
ADC_SMPR2_SMP_AN6(ADC_SAMPLING_SLOW) |
|
|
|
|
ADC_SMPR2_SMP_AN7(ADC_SAMPLING_SLOW) |
|
|
|
|
ADC_SMPR2_SMP_AN8(ADC_SAMPLING_SLOW) |
|
2020-09-01 04:38:35 -07:00
|
|
|
ADC_SMPR2_SMP_AN9(ADC_SAMPLING_SLOW),
|
|
|
|
.htr = 0,
|
|
|
|
.ltr = 0,
|
|
|
|
.sqr1 = 0, // Conversion group sequence 13...16 + sequence length
|
|
|
|
.sqr2 = 0, // Conversion group sequence 7...12
|
2020-09-12 06:04:26 -07:00
|
|
|
.sqr3 = 0, // Conversion group sequence 1...6
|
|
|
|
#if ADC_MAX_CHANNELS_COUNT > 16
|
|
|
|
.sqr4 = 0, // Conversion group sequence 19...24
|
|
|
|
.sqr5 = 0 // Conversion group sequence 25...30
|
|
|
|
#endif /* ADC_MAX_CHANNELS_COUNT */
|
2020-09-01 04:38:35 -07:00
|
|
|
};
|
2017-03-24 10:41:36 -07:00
|
|
|
|
2020-09-08 14:20:55 -07:00
|
|
|
AdcDevice slowAdc(&adcgrpcfgSlow, slowAdcSampleBuf);
|
2017-03-24 10:41:36 -07:00
|
|
|
|
2019-07-05 17:34:41 -07:00
|
|
|
void adc_callback_fast(ADCDriver *adcp, adcsample_t *buffer, size_t n);
|
|
|
|
|
2020-09-08 14:20:55 -07:00
|
|
|
static ADCConversionGroup adcgrpcfgFast = {
|
2020-09-01 04:38:35 -07:00
|
|
|
.circular = FALSE,
|
|
|
|
.num_channels = 0,
|
|
|
|
.end_cb = adc_callback_fast,
|
|
|
|
.error_cb = nullptr,
|
|
|
|
/* HW dependent part.*/
|
|
|
|
.cr1 = 0,
|
|
|
|
.cr2 = ADC_CR2_SWSTART,
|
2017-05-01 04:39:32 -07:00
|
|
|
/**
|
|
|
|
* here we configure all possible channels for fast mode. Some channels would not actually
|
|
|
|
* be used hopefully that's fine to configure all possible channels.
|
|
|
|
*
|
|
|
|
*/
|
2020-09-01 04:38:35 -07:00
|
|
|
// sample times for channels 10...18
|
|
|
|
.smpr1 =
|
2017-05-01 04:39:32 -07:00
|
|
|
ADC_SMPR1_SMP_AN10(ADC_SAMPLING_FAST) |
|
|
|
|
ADC_SMPR1_SMP_AN11(ADC_SAMPLING_FAST) |
|
|
|
|
ADC_SMPR1_SMP_AN12(ADC_SAMPLING_FAST) |
|
|
|
|
ADC_SMPR1_SMP_AN13(ADC_SAMPLING_FAST) |
|
|
|
|
ADC_SMPR1_SMP_AN14(ADC_SAMPLING_FAST) |
|
2020-09-01 04:38:35 -07:00
|
|
|
ADC_SMPR1_SMP_AN15(ADC_SAMPLING_FAST),
|
|
|
|
// In this field must be specified the sample times for channels 0...9
|
|
|
|
.smpr2 =
|
2017-05-01 04:39:32 -07:00
|
|
|
ADC_SMPR2_SMP_AN0(ADC_SAMPLING_FAST) |
|
|
|
|
ADC_SMPR2_SMP_AN1(ADC_SAMPLING_FAST) |
|
|
|
|
ADC_SMPR2_SMP_AN2(ADC_SAMPLING_FAST) |
|
|
|
|
ADC_SMPR2_SMP_AN3(ADC_SAMPLING_FAST) |
|
|
|
|
ADC_SMPR2_SMP_AN4(ADC_SAMPLING_FAST) |
|
|
|
|
ADC_SMPR2_SMP_AN5(ADC_SAMPLING_FAST) |
|
|
|
|
ADC_SMPR2_SMP_AN6(ADC_SAMPLING_FAST) |
|
|
|
|
ADC_SMPR2_SMP_AN7(ADC_SAMPLING_FAST) |
|
|
|
|
ADC_SMPR2_SMP_AN8(ADC_SAMPLING_FAST) |
|
2020-09-01 04:38:35 -07:00
|
|
|
ADC_SMPR2_SMP_AN9(ADC_SAMPLING_FAST),
|
|
|
|
.htr = 0,
|
|
|
|
.ltr = 0,
|
|
|
|
.sqr1 = 0, // Conversion group sequence 13...16 + sequence length
|
|
|
|
.sqr2 = 0, // Conversion group sequence 7...12
|
2020-09-12 06:04:26 -07:00
|
|
|
.sqr3 = 0, // Conversion group sequence 1...6
|
|
|
|
#if ADC_MAX_CHANNELS_COUNT > 16
|
|
|
|
.sqr4 = 0, // Conversion group sequence 19...24
|
|
|
|
.sqr5 = 0 // Conversion group sequence 25...30
|
|
|
|
#endif /* ADC_MAX_CHANNELS_COUNT */
|
2020-09-01 04:38:35 -07:00
|
|
|
};
|
2017-03-24 10:41:36 -07:00
|
|
|
|
2020-09-08 14:20:55 -07:00
|
|
|
AdcDevice fastAdc(&adcgrpcfgFast, fastAdcSampleBuf);
|
2017-03-24 10:41:36 -07:00
|
|
|
|
2020-04-23 19:50:18 -07:00
|
|
|
#if HAL_USE_GPT
|
|
|
|
static void fast_adc_callback(GPTDriver*) {
|
2019-04-12 17:52:51 -07:00
|
|
|
#if EFI_INTERNAL_ADC
|
2017-03-24 10:41:36 -07:00
|
|
|
/*
|
|
|
|
* Starts an asynchronous ADC conversion operation, the conversion
|
|
|
|
* will be executed in parallel to the current PWM cycle and will
|
|
|
|
* terminate before the next PWM cycle.
|
|
|
|
*/
|
2017-03-30 06:01:28 -07:00
|
|
|
chSysLockFromISR()
|
2017-03-24 10:41:36 -07:00
|
|
|
;
|
|
|
|
if (ADC_FAST_DEVICE.state != ADC_READY &&
|
|
|
|
ADC_FAST_DEVICE.state != ADC_COMPLETE &&
|
|
|
|
ADC_FAST_DEVICE.state != ADC_ERROR) {
|
|
|
|
fastAdc.errorsCount++;
|
|
|
|
// todo: when? why? firmwareError(OBD_PCM_Processor_Fault, "ADC fast not ready?");
|
2017-03-30 06:01:28 -07:00
|
|
|
chSysUnlockFromISR()
|
2017-03-24 10:41:36 -07:00
|
|
|
;
|
|
|
|
return;
|
|
|
|
}
|
2019-10-11 17:43:21 -07:00
|
|
|
|
2020-09-08 14:20:55 -07:00
|
|
|
adcStartConversionI(&ADC_FAST_DEVICE, &adcgrpcfgFast, fastAdc.samples, ADC_BUF_DEPTH_FAST);
|
2017-03-30 06:01:28 -07:00
|
|
|
chSysUnlockFromISR()
|
2017-03-24 10:41:36 -07:00
|
|
|
;
|
|
|
|
fastAdc.conversionCount++;
|
2017-11-27 18:49:58 -08:00
|
|
|
#endif /* EFI_INTERNAL_ADC */
|
2017-03-24 10:41:36 -07:00
|
|
|
}
|
2020-04-23 19:50:18 -07:00
|
|
|
#endif /* HAL_USE_GPT */
|
2017-03-24 10:41:36 -07:00
|
|
|
|
2020-10-14 19:39:16 -07:00
|
|
|
float getMCUInternalTemperature() {
|
2019-04-12 17:52:51 -07:00
|
|
|
#if defined(ADC_CHANNEL_SENSOR)
|
2020-10-14 19:39:16 -07:00
|
|
|
float TemperatureValue = adcToVolts(slowAdc.getAdcValueByHwChannel(EFI_ADC_TEMP_SENSOR));
|
|
|
|
TemperatureValue -= 0.760f; // Subtract the reference voltage at 25 deg C
|
|
|
|
TemperatureValue /= 0.0025f; // Divide by slope 2.5mV
|
2017-03-24 10:41:36 -07:00
|
|
|
|
2019-06-23 06:21:12 -07:00
|
|
|
TemperatureValue += 25.0; // Add the 25 deg C
|
2020-10-14 19:39:16 -07:00
|
|
|
|
|
|
|
if (TemperatureValue > 150.0f || TemperatureValue < -50.0f) {
|
|
|
|
firmwareError(OBD_PCM_Processor_Fault, "Invalid CPU temperature measured!");
|
|
|
|
}
|
|
|
|
|
2017-03-24 10:41:36 -07:00
|
|
|
return TemperatureValue;
|
2019-03-28 19:46:10 -07:00
|
|
|
#else
|
|
|
|
return 0;
|
|
|
|
#endif /* ADC_CHANNEL_SENSOR */
|
2017-03-24 10:41:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
int getInternalAdcValue(const char *msg, adc_channel_e hwChannel) {
|
|
|
|
if (hwChannel == EFI_ADC_NONE) {
|
2017-04-12 04:57:52 -07:00
|
|
|
warning(CUSTOM_OBD_ANALOG_INPUT_NOT_CONFIGURED, "ADC: %s input is not configured", msg);
|
2017-03-24 10:41:36 -07:00
|
|
|
return -1;
|
|
|
|
}
|
2017-11-27 18:49:58 -08:00
|
|
|
#if EFI_ENABLE_MOCK_ADC
|
2017-03-24 10:41:36 -07:00
|
|
|
if (engine->engineState.mockAdcState.hasMockAdc[hwChannel])
|
|
|
|
return engine->engineState.mockAdcState.getMockAdcValue(hwChannel);
|
|
|
|
|
2017-11-27 18:49:58 -08:00
|
|
|
#endif /* EFI_ENABLE_MOCK_ADC */
|
2017-03-24 10:41:36 -07:00
|
|
|
|
|
|
|
|
|
|
|
if (adcHwChannelEnabled[hwChannel] == ADC_FAST) {
|
|
|
|
int internalIndex = fastAdc.internalAdcIndexByHardwareIndex[hwChannel];
|
|
|
|
// todo if ADC_BUF_DEPTH_FAST EQ 1
|
|
|
|
// return fastAdc.samples[internalIndex];
|
|
|
|
int value = getAvgAdcValue(internalIndex, fastAdc.samples, ADC_BUF_DEPTH_FAST, fastAdc.size());
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
if (adcHwChannelEnabled[hwChannel] != ADC_SLOW) {
|
2020-05-23 14:13:46 -07:00
|
|
|
// todo: make this not happen during hardware continues integration
|
|
|
|
warning(CUSTOM_OBD_WRONG_ADC_MODE, "ADC is off [%s] index=%d", msg, hwChannel);
|
2017-03-24 10:41:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return slowAdc.getAdcValueByHwChannel(hwChannel);
|
|
|
|
}
|
|
|
|
|
2020-04-23 19:50:18 -07:00
|
|
|
#if HAL_USE_GPT
|
|
|
|
static GPTConfig fast_adc_config = {
|
|
|
|
GPT_FREQ_FAST,
|
|
|
|
fast_adc_callback,
|
|
|
|
0, 0
|
|
|
|
};
|
|
|
|
#endif /* HAL_USE_GPT */
|
2017-03-24 10:41:36 -07:00
|
|
|
|
2020-09-08 14:20:55 -07:00
|
|
|
adc_channel_mode_e getAdcMode(adc_channel_e hwChannel) {
|
2017-03-24 10:41:36 -07:00
|
|
|
if (slowAdc.isHwUsed(hwChannel)) {
|
2020-09-08 14:20:55 -07:00
|
|
|
return ADC_SLOW;
|
2017-03-24 10:41:36 -07:00
|
|
|
}
|
|
|
|
if (fastAdc.isHwUsed(hwChannel)) {
|
2020-09-08 14:20:55 -07:00
|
|
|
return ADC_FAST;
|
2017-03-24 10:41:36 -07:00
|
|
|
}
|
2020-09-08 14:20:55 -07:00
|
|
|
return ADC_OFF;
|
2017-03-24 10:41:36 -07:00
|
|
|
}
|
|
|
|
|
2019-06-08 06:51:36 -07:00
|
|
|
int AdcDevice::size() const {
|
2017-03-24 10:41:36 -07:00
|
|
|
return channelCount;
|
|
|
|
}
|
|
|
|
|
2019-06-08 06:51:36 -07:00
|
|
|
int AdcDevice::getAdcValueByHwChannel(int hwChannel) const {
|
2017-03-24 10:41:36 -07:00
|
|
|
int internalIndex = internalAdcIndexByHardwareIndex[hwChannel];
|
|
|
|
return values.adc_data[internalIndex];
|
|
|
|
}
|
|
|
|
|
2019-06-08 06:51:36 -07:00
|
|
|
int AdcDevice::getAdcValueByIndex(int internalIndex) const {
|
2017-03-24 10:41:36 -07:00
|
|
|
return values.adc_data[internalIndex];
|
|
|
|
}
|
|
|
|
|
2019-06-23 06:21:12 -07:00
|
|
|
void AdcDevice::invalidateSamplesCache() {
|
2019-06-23 07:34:49 -07:00
|
|
|
#if defined(STM32F7XX)
|
2019-06-23 06:21:12 -07:00
|
|
|
// The STM32F7xx has a data cache
|
|
|
|
// DMA operations DO NOT invalidate cache lines, since the ARM m7 doesn't have
|
|
|
|
// anything like a CCI that maintains coherency across multiple bus masters.
|
|
|
|
// As a result, we have to manually invalidate the D-cache any time we (the CPU)
|
|
|
|
// would like to read something that somebody else wrote (ADC via DMA, in this case)
|
|
|
|
SCB_InvalidateDCache_by_Addr(reinterpret_cast<uint32_t*>(samples), sizeof(samples));
|
2020-03-18 08:37:53 -07:00
|
|
|
#endif /* STM32F7XX */
|
2019-06-23 06:21:12 -07:00
|
|
|
}
|
|
|
|
|
2017-03-24 10:41:36 -07:00
|
|
|
void AdcDevice::init(void) {
|
|
|
|
hwConfig->num_channels = size();
|
2020-09-08 14:20:55 -07:00
|
|
|
/* driver does this internally */
|
|
|
|
//hwConfig->sqr1 += ADC_SQR1_NUM_CH(size());
|
2017-03-24 10:41:36 -07:00
|
|
|
}
|
|
|
|
|
2019-06-08 06:51:36 -07:00
|
|
|
bool AdcDevice::isHwUsed(adc_channel_e hwChannelIndex) const {
|
2017-03-24 10:41:36 -07:00
|
|
|
for (int i = 0; i < channelCount; i++) {
|
|
|
|
if (hardwareIndexByIndernalAdcIndex[i] == hwChannelIndex) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AdcDevice::enableChannel(adc_channel_e hwChannel) {
|
2020-09-21 02:37:51 -07:00
|
|
|
if (channelCount >= efi::size(values.adc_data)) {
|
|
|
|
firmwareError(OBD_PCM_Processor_Fault, "Too many ADC channels configured");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-03-24 10:41:36 -07:00
|
|
|
int logicChannel = channelCount++;
|
|
|
|
|
2020-09-06 15:25:26 -07:00
|
|
|
size_t channelAdcIndex = hwChannel - 1;
|
|
|
|
|
2017-03-24 10:41:36 -07:00
|
|
|
internalAdcIndexByHardwareIndex[hwChannel] = logicChannel;
|
|
|
|
hardwareIndexByIndernalAdcIndex[logicChannel] = hwChannel;
|
|
|
|
if (logicChannel < 6) {
|
2020-09-06 15:25:26 -07:00
|
|
|
hwConfig->sqr3 += (channelAdcIndex) << (5 * logicChannel);
|
2017-03-24 10:41:36 -07:00
|
|
|
} else if (logicChannel < 12) {
|
2020-09-06 15:25:26 -07:00
|
|
|
hwConfig->sqr2 += (channelAdcIndex) << (5 * (logicChannel - 6));
|
2020-09-12 06:04:26 -07:00
|
|
|
} else if (logicChannel < 18) {
|
2020-09-06 15:25:26 -07:00
|
|
|
hwConfig->sqr1 += (channelAdcIndex) << (5 * (logicChannel - 12));
|
2017-03-24 10:41:36 -07:00
|
|
|
}
|
2020-09-12 06:04:26 -07:00
|
|
|
#if ADC_MAX_CHANNELS_COUNT > 16
|
|
|
|
else if (logicChannel < 24) {
|
|
|
|
hwConfig->sqr4 += (channelAdcIndex) << (5 * (logicChannel - 18));
|
|
|
|
}
|
|
|
|
else if (logicChannel < 30) {
|
|
|
|
hwConfig->sqr5 += (channelAdcIndex) << (5 * (logicChannel - 24));
|
|
|
|
}
|
|
|
|
#endif /* ADC_MAX_CHANNELS_COUNT */
|
2017-03-24 10:41:36 -07:00
|
|
|
}
|
|
|
|
|
2020-04-17 13:26:51 -07:00
|
|
|
void AdcDevice::enableChannelAndPin(const char *msg, adc_channel_e hwChannel) {
|
2017-03-24 10:41:36 -07:00
|
|
|
enableChannel(hwChannel);
|
|
|
|
|
2020-04-17 13:26:51 -07:00
|
|
|
brain_pin_e pin = getAdcChannelBrainPin(msg, hwChannel);
|
|
|
|
efiSetPadMode(msg, pin, PAL_MODE_INPUT_ANALOG);
|
2017-03-24 10:41:36 -07:00
|
|
|
}
|
|
|
|
|
2019-03-02 15:41:25 -08:00
|
|
|
static void printAdcValue(int channel) {
|
|
|
|
int value = getAdcValue("print", (adc_channel_e)channel);
|
2017-03-24 10:41:36 -07:00
|
|
|
float volts = adcToVoltsDivided(value);
|
2018-01-23 09:05:14 -08:00
|
|
|
scheduleMsg(&logger, "adc voltage : %.2f", volts);
|
2017-03-24 10:41:36 -07:00
|
|
|
}
|
|
|
|
|
2019-06-08 06:51:36 -07:00
|
|
|
adc_channel_e AdcDevice::getAdcHardwareIndexByInternalIndex(int index) const {
|
2017-03-24 10:41:36 -07:00
|
|
|
return hardwareIndexByIndernalAdcIndex[index];
|
|
|
|
}
|
|
|
|
|
|
|
|
static void printFullAdcReport(Logging *logger) {
|
|
|
|
scheduleMsg(logger, "fast %d slow %d", fastAdc.conversionCount, slowAdc.conversionCount);
|
|
|
|
|
2020-09-08 14:20:55 -07:00
|
|
|
for (int index = 0; index < fastAdc.size(); index++) {
|
|
|
|
appendMsgPrefix(logger);
|
|
|
|
|
|
|
|
adc_channel_e hwIndex = fastAdc.getAdcHardwareIndexByInternalIndex(index);
|
|
|
|
|
|
|
|
if (hwIndex != EFI_ADC_NONE && hwIndex != EFI_ADC_ERROR) {
|
|
|
|
ioportid_t port = getAdcChannelPort("print", hwIndex);
|
|
|
|
int pin = getAdcChannelPin(hwIndex);
|
|
|
|
|
|
|
|
int adcValue = getAvgAdcValue(hwIndex, fastAdc.samples, ADC_BUF_DEPTH_FAST, fastAdc.size());
|
2020-09-13 01:49:25 -07:00
|
|
|
logger->appendPrintf(" F ch%d %s%d", index, portname(port), pin);
|
|
|
|
logger->appendPrintf(" ADC%d 12bit=%d", hwIndex, adcValue);
|
2020-09-08 14:20:55 -07:00
|
|
|
float volts = adcToVolts(adcValue);
|
2020-09-13 01:49:25 -07:00
|
|
|
logger->appendPrintf(" v=%.2f", volts);
|
2020-09-08 14:20:55 -07:00
|
|
|
|
|
|
|
appendMsgPostfix(logger);
|
|
|
|
scheduleLogging(logger);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-24 10:41:36 -07:00
|
|
|
for (int index = 0; index < slowAdc.size(); index++) {
|
|
|
|
appendMsgPrefix(logger);
|
|
|
|
|
|
|
|
adc_channel_e hwIndex = slowAdc.getAdcHardwareIndexByInternalIndex(index);
|
|
|
|
|
2019-11-19 15:17:03 -08:00
|
|
|
if (hwIndex != EFI_ADC_NONE && hwIndex != EFI_ADC_ERROR) {
|
2017-08-29 07:03:24 -07:00
|
|
|
ioportid_t port = getAdcChannelPort("print", hwIndex);
|
|
|
|
int pin = getAdcChannelPin(hwIndex);
|
2017-03-24 10:41:36 -07:00
|
|
|
|
2017-08-29 07:03:24 -07:00
|
|
|
int adcValue = slowAdc.getAdcValueByIndex(index);
|
2020-09-13 01:49:25 -07:00
|
|
|
logger->appendPrintf(" S ch%d %s%d", index, portname(port), pin);
|
|
|
|
logger->appendPrintf(" ADC%d 12bit=%d", hwIndex, adcValue);
|
2017-08-29 07:03:24 -07:00
|
|
|
float volts = adcToVolts(adcValue);
|
2020-09-13 01:49:25 -07:00
|
|
|
logger->appendPrintf(" v=%.2f", volts);
|
2017-08-29 07:03:24 -07:00
|
|
|
|
|
|
|
appendMsgPostfix(logger);
|
|
|
|
scheduleLogging(logger);
|
|
|
|
}
|
2017-03-24 10:41:36 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void setAdcDebugReporting(int value) {
|
|
|
|
adcDebugReporting = value;
|
|
|
|
scheduleMsg(&logger, "adcDebug=%d", adcDebugReporting);
|
|
|
|
}
|
|
|
|
|
2018-01-22 14:45:10 -08:00
|
|
|
void waitForSlowAdc(int lastAdcCounter) {
|
2020-09-12 06:04:26 -07:00
|
|
|
// don't halt the firmware if there are no slow channels assigned
|
|
|
|
if (slowAdc.size() < 1)
|
|
|
|
return;
|
|
|
|
|
2017-08-07 04:28:21 -07:00
|
|
|
// we use slowAdcCounter instead of slowAdc.conversionCount because we need ADC_COMPLETE state
|
|
|
|
// todo: use sync.objects?
|
2018-01-22 14:45:10 -08:00
|
|
|
while (slowAdcCounter <= lastAdcCounter) {
|
2017-08-07 04:28:21 -07:00
|
|
|
chThdSleepMilliseconds(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-22 14:45:10 -08:00
|
|
|
int getSlowAdcCounter() {
|
|
|
|
return slowAdcCounter;
|
|
|
|
}
|
|
|
|
|
2019-10-11 17:43:21 -07:00
|
|
|
|
2019-12-11 06:28:11 -08:00
|
|
|
class SlowAdcController : public PeriodicController<256> {
|
|
|
|
public:
|
|
|
|
SlowAdcController()
|
2020-08-21 16:47:12 -07:00
|
|
|
: PeriodicController("ADC", NORMALPRIO + 5, SLOW_ADC_RATE)
|
2019-12-11 06:28:11 -08:00
|
|
|
{
|
|
|
|
}
|
2019-10-08 17:44:59 -07:00
|
|
|
|
2019-12-21 18:11:09 -08:00
|
|
|
void PeriodicTask(efitick_t nowNt) override {
|
2019-12-11 06:28:11 -08:00
|
|
|
{
|
|
|
|
ScopePerf perf(PE::AdcConversionSlow);
|
2019-10-08 17:44:59 -07:00
|
|
|
|
2019-12-11 06:28:11 -08:00
|
|
|
slowAdc.conversionCount++;
|
|
|
|
msg_t result = adcConvert(&ADC_SLOW_DEVICE, &adcgrpcfgSlow, slowAdc.samples, ADC_BUF_DEPTH_SLOW);
|
2017-03-24 10:41:36 -07:00
|
|
|
|
2019-12-11 06:28:11 -08:00
|
|
|
// If something went wrong - try again later
|
|
|
|
if (result == MSG_RESET || result == MSG_TIMEOUT) {
|
|
|
|
slowAdc.errorsCount++;
|
|
|
|
return;
|
|
|
|
}
|
2019-12-17 05:34:56 -08:00
|
|
|
|
|
|
|
#ifdef USE_ADC3_VBATT_HACK
|
|
|
|
void proteusAdcHack();
|
|
|
|
proteusAdcHack();
|
|
|
|
#endif
|
2017-03-24 10:41:36 -07:00
|
|
|
}
|
2019-09-21 11:33:38 -07:00
|
|
|
|
2019-12-11 06:28:11 -08:00
|
|
|
{
|
|
|
|
ScopePerf perf(PE::AdcProcessSlow);
|
|
|
|
|
|
|
|
slowAdc.invalidateSamplesCache();
|
|
|
|
|
|
|
|
/* Calculates the average values from the ADC samples.*/
|
|
|
|
for (int i = 0; i < slowAdc.size(); i++) {
|
|
|
|
adcsample_t value = getAvgAdcValue(i, slowAdc.samples, ADC_BUF_DEPTH_SLOW, slowAdc.size());
|
|
|
|
adcsample_t prev = slowAdc.values.adc_data[i];
|
|
|
|
float result = (slowAdcCounter == 0) ? value :
|
|
|
|
CONFIG(slowAdcAlpha) * value + (1 - CONFIG(slowAdcAlpha)) * prev;
|
|
|
|
|
|
|
|
slowAdc.values.adc_data[i] = (adcsample_t)result;
|
|
|
|
}
|
|
|
|
slowAdcCounter++;
|
|
|
|
|
2020-02-08 14:48:15 -08:00
|
|
|
AdcSubscription::UpdateSubscribers(nowNt);
|
2019-12-11 06:28:11 -08:00
|
|
|
}
|
2019-10-08 17:44:59 -07:00
|
|
|
}
|
2019-12-11 06:28:11 -08:00
|
|
|
};
|
2017-03-24 10:41:36 -07:00
|
|
|
|
2019-03-28 19:46:10 -07:00
|
|
|
void addChannel(const char *name, adc_channel_e setting, adc_channel_mode_e mode) {
|
2017-03-24 10:41:36 -07:00
|
|
|
if (setting == EFI_ADC_NONE) {
|
|
|
|
return;
|
|
|
|
}
|
2019-12-02 17:32:21 -08:00
|
|
|
if (/*type-limited (int)setting < 0 || */(int)setting>=HW_MAX_ADC_INDEX) {
|
|
|
|
firmwareError(CUSTOM_INVALID_ADC, "Invalid ADC setting %s", name);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-03-24 10:41:36 -07:00
|
|
|
adcHwChannelEnabled[setting] = mode;
|
2020-04-17 13:26:51 -07:00
|
|
|
|
|
|
|
AdcDevice& dev = (mode == ADC_SLOW) ? slowAdc : fastAdc;
|
|
|
|
dev.enableChannelAndPin(name, setting);
|
2017-03-24 10:41:36 -07:00
|
|
|
}
|
|
|
|
|
2019-03-28 19:46:10 -07:00
|
|
|
void removeChannel(const char *name, adc_channel_e setting) {
|
2019-04-14 10:19:36 -07:00
|
|
|
(void)name;
|
2019-03-28 19:46:10 -07:00
|
|
|
if (setting == EFI_ADC_NONE) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
adcHwChannelEnabled[setting] = ADC_OFF;
|
|
|
|
}
|
|
|
|
|
2017-03-24 10:41:36 -07:00
|
|
|
static void configureInputs(void) {
|
|
|
|
memset(adcHwChannelEnabled, 0, sizeof(adcHwChannelEnabled));
|
|
|
|
|
2019-12-03 20:55:18 -08:00
|
|
|
/**
|
|
|
|
* order of analog channels here is totally random and has no meaning
|
|
|
|
* we also have some weird implementation with internal indices - that all has no meaning, it's just a random implementation
|
|
|
|
* which does not mean anything.
|
|
|
|
*/
|
|
|
|
|
2017-03-24 10:41:36 -07:00
|
|
|
addChannel("MAP", engineConfiguration->map.sensor.hwChannel, ADC_FAST);
|
2020-03-29 16:07:07 -07:00
|
|
|
addChannel("MAF", engineConfiguration->mafAdcChannel, ADC_FAST);
|
|
|
|
|
|
|
|
addChannel("HIP9011", engineConfiguration->hipOutputChannel, ADC_FAST);
|
2017-03-24 10:41:36 -07:00
|
|
|
|
2020-03-29 16:07:07 -07:00
|
|
|
addChannel("Baro Press", engineConfiguration->baroSensor.hwChannel, ADC_SLOW);
|
2020-03-20 06:53:45 -07:00
|
|
|
|
2020-03-29 16:07:07 -07:00
|
|
|
addChannel("TPS 1 Primary", engineConfiguration->tps1_1AdcChannel, ADC_SLOW);
|
|
|
|
addChannel("TPS 1 Secondary", engineConfiguration->tps1_2AdcChannel, ADC_SLOW);
|
|
|
|
addChannel("TPS 2 Primary", engineConfiguration->tps2_1AdcChannel, ADC_SLOW);
|
|
|
|
addChannel("TPS 2 Secondary", engineConfiguration->tps2_2AdcChannel, ADC_SLOW);
|
2020-03-20 06:53:45 -07:00
|
|
|
|
2020-09-18 00:04:07 -07:00
|
|
|
addChannel("Wastegate Position", engineConfiguration->wastegatePositionSensor, ADC_SLOW);
|
|
|
|
addChannel("Idle Position Sensor", engineConfiguration->idlePositionSensor, ADC_SLOW);
|
|
|
|
|
2020-03-29 16:07:07 -07:00
|
|
|
addChannel("Fuel Level", engineConfiguration->fuelLevelSensor, ADC_SLOW);
|
2020-08-18 21:46:57 -07:00
|
|
|
addChannel("Acc Pedal1", engineConfiguration->throttlePedalPositionAdcChannel, ADC_SLOW);
|
|
|
|
addChannel("Acc Pedal2", engineConfiguration->throttlePedalPositionSecondAdcChannel, ADC_SLOW);
|
2017-03-24 10:41:36 -07:00
|
|
|
addChannel("VBatt", engineConfiguration->vbattAdcChannel, ADC_SLOW);
|
|
|
|
// not currently used addChannel("Vref", engineConfiguration->vRefAdcChannel, ADC_SLOW);
|
|
|
|
addChannel("CLT", engineConfiguration->clt.adcChannel, ADC_SLOW);
|
|
|
|
addChannel("IAT", engineConfiguration->iat.adcChannel, ADC_SLOW);
|
2020-03-29 16:07:07 -07:00
|
|
|
addChannel("AUX Temp 1", engineConfiguration->auxTempSensor1.adcChannel, ADC_SLOW);
|
|
|
|
addChannel("AUX Temp 2", engineConfiguration->auxTempSensor2.adcChannel, ADC_SLOW);
|
2020-09-21 03:10:25 -07:00
|
|
|
|
|
|
|
addChannel("AUXF#1", engineConfiguration->auxFastSensor1_adcChannel, ADC_FAST);
|
|
|
|
|
2017-03-24 10:41:36 -07:00
|
|
|
addChannel("AFR", engineConfiguration->afr.hwChannel, ADC_SLOW);
|
2020-03-29 16:07:07 -07:00
|
|
|
addChannel("Oil Pressure", engineConfiguration->oilPressure.hwChannel, ADC_SLOW);
|
2020-09-21 03:10:25 -07:00
|
|
|
|
2020-10-23 04:31:47 -07:00
|
|
|
addChannel("LFP", engineConfiguration->lowPressureFuel.hwChannel, ADC_SLOW);
|
|
|
|
addChannel("HFP", engineConfiguration->highPressureFuel.hwChannel, ADC_SLOW);
|
2020-09-21 03:10:25 -07:00
|
|
|
|
2017-03-24 10:41:36 -07:00
|
|
|
|
2019-12-11 14:48:55 -08:00
|
|
|
if (CONFIG(isCJ125Enabled)) {
|
2020-03-29 16:07:07 -07:00
|
|
|
addChannel("CJ125 UR", engineConfiguration->cj125ur, ADC_SLOW);
|
|
|
|
addChannel("CJ125 UA", engineConfiguration->cj125ua, ADC_SLOW);
|
2018-01-22 14:45:10 -08:00
|
|
|
}
|
|
|
|
|
2017-08-06 16:43:01 -07:00
|
|
|
for (int i = 0; i < FSIO_ANALOG_INPUT_COUNT ; i++) {
|
2017-03-24 10:41:36 -07:00
|
|
|
addChannel("FSIOadc", engineConfiguration->fsioAdc[i], ADC_SLOW);
|
|
|
|
}
|
2019-03-28 19:46:10 -07:00
|
|
|
|
|
|
|
setAdcChannelOverrides();
|
2017-03-24 10:41:36 -07:00
|
|
|
}
|
|
|
|
|
2019-12-11 06:28:11 -08:00
|
|
|
static SlowAdcController slowAdcController;
|
|
|
|
|
2019-08-01 22:36:02 -07:00
|
|
|
void initAdcInputs() {
|
2020-09-12 06:04:26 -07:00
|
|
|
scheduleMsg(&logger, "initAdcInputs()");
|
2017-03-24 10:41:36 -07:00
|
|
|
if (ADC_BUF_DEPTH_FAST > MAX_ADC_GRP_BUF_DEPTH)
|
|
|
|
firmwareError(CUSTOM_ERR_ADC_DEPTH_FAST, "ADC_BUF_DEPTH_FAST too high");
|
|
|
|
if (ADC_BUF_DEPTH_SLOW > MAX_ADC_GRP_BUF_DEPTH)
|
|
|
|
firmwareError(CUSTOM_ERR_ADC_DEPTH_SLOW, "ADC_BUF_DEPTH_SLOW too high");
|
|
|
|
|
|
|
|
configureInputs();
|
|
|
|
|
|
|
|
// migrate to 'enable adcdebug'
|
2017-04-04 20:17:56 -07:00
|
|
|
addConsoleActionI("adcdebug", &setAdcDebugReporting);
|
2017-03-24 10:41:36 -07:00
|
|
|
|
2019-04-12 17:52:51 -07:00
|
|
|
#if EFI_INTERNAL_ADC
|
2017-03-24 10:41:36 -07:00
|
|
|
/*
|
|
|
|
* Initializes the ADC driver.
|
|
|
|
*/
|
|
|
|
adcStart(&ADC_SLOW_DEVICE, NULL);
|
|
|
|
adcStart(&ADC_FAST_DEVICE, NULL);
|
|
|
|
adcSTM32EnableTSVREFE(); // Internal temperature sensor
|
|
|
|
|
2020-09-08 14:20:55 -07:00
|
|
|
/* Enable this code only when you absolutly sure
|
|
|
|
* that there is no possible errors from ADC */
|
|
|
|
#if 0
|
|
|
|
/* All ADC use DMA and DMA calls end_cb from its IRQ
|
|
|
|
* If none of ADC users need error callback - we can disable
|
|
|
|
* shared ADC IRQ and save some CPU ticks */
|
|
|
|
if ((adcgrpcfgSlow.error_cb == NULL) &&
|
|
|
|
(adcgrpcfgFast.error_cb == NULL)
|
|
|
|
/* TODO: Add ADC3? */) {
|
|
|
|
nvicDisableVector(STM32_ADC_NUMBER);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2019-04-12 17:52:51 -07:00
|
|
|
#if defined(ADC_CHANNEL_SENSOR)
|
2017-03-24 10:41:36 -07:00
|
|
|
// Internal temperature sensor, Available on ADC1 only
|
2020-10-14 19:39:16 -07:00
|
|
|
slowAdc.enableChannel(EFI_ADC_TEMP_SENSOR);
|
2019-04-01 11:02:19 -07:00
|
|
|
#endif /* ADC_CHANNEL_SENSOR */
|
2017-03-24 10:41:36 -07:00
|
|
|
|
|
|
|
slowAdc.init();
|
2019-12-11 06:28:11 -08:00
|
|
|
|
|
|
|
// Start the slow ADC thread
|
|
|
|
slowAdcController.Start();
|
2017-04-05 19:41:51 -07:00
|
|
|
|
2020-09-29 03:34:39 -07:00
|
|
|
fastAdc.init();
|
|
|
|
/*
|
|
|
|
* Initializes the PWM driver.
|
|
|
|
*/
|
2020-04-23 19:50:18 -07:00
|
|
|
#if HAL_USE_GPT
|
2020-09-29 03:34:39 -07:00
|
|
|
gptStart(EFI_INTERNAL_FAST_ADC_GPT, &fast_adc_config);
|
|
|
|
gptStartContinuous(EFI_INTERNAL_FAST_ADC_GPT, GPT_PERIOD_FAST);
|
2020-04-23 19:50:18 -07:00
|
|
|
#endif /* HAL_USE_GPT */
|
2017-03-24 10:41:36 -07:00
|
|
|
|
|
|
|
addConsoleActionI("adc", (VoidInt) printAdcValue);
|
|
|
|
#else
|
2020-09-12 06:04:26 -07:00
|
|
|
scheduleMsg(&logger, "ADC disabled");
|
2017-03-24 10:41:36 -07:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void printFullAdcReportIfNeeded(Logging *logger) {
|
|
|
|
if (!adcDebugReporting)
|
|
|
|
return;
|
|
|
|
printFullAdcReport(logger);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* HAL_USE_ADC */
|