fome-fw/firmware/hw_layer/adc/adc_inputs.cpp

105 lines
2.6 KiB
C++

/**
* @file adc_inputs.cpp
* @brief Low level ADC code
*
* 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
* any ADC pins, only the hardcoded choice of 16 pins.
*
* Slow ADC group is used for IAT, CLT, AFR, VBATT etc - this one is currently sampled at 500Hz
*
* Fast ADC group is used for MAP, MAF HIP - this one is currently sampled at 10KHz
* We need frequent MAP for map_averaging.cpp
*
* 10KHz equals one measurement every 3.6 degrees at 6000 RPM
*
* @date Jan 14, 2013
* @author Andrey Belomutskiy, (c) 2012-2020
*/
#include "pch.h"
float __attribute__((weak)) getAnalogInputDividerCoefficient(adc_channel_e) {
return engineConfiguration->analogInputDividerCoefficient;
}
#if HAL_USE_ADC
#include "adc_subscription.h"
#include "AdcConfiguration.h"
#include "mpu_util.h"
#include "periodic_thread_controller.h"
#include "protected_gpio.h"
// Board voltage, with divider coefficient accounted for
float getVoltageDivided(const char *msg, adc_channel_e hwChannel) {
return getVoltage(msg, hwChannel) * getAnalogInputDividerCoefficient(hwChannel);
}
// voltage in MCU universe, from zero to VDD
float getVoltage(const char *msg, adc_channel_e hwChannel) {
return adcToVolts(getSlowAdcValue(msg, hwChannel));
}
static uint32_t slowAdcCounter = 0;
static float mcuTemperature;
float getMCUInternalTemperature() {
return mcuTemperature;
}
int getSlowAdcValue(const char *msg, adc_channel_e hwChannel) {
if (!isAdcChannelValid(hwChannel)) {
warning(ObdCode::CUSTOM_OBD_ANALOG_INPUT_NOT_CONFIGURED, "ADC: %s input is not configured", msg);
return -1;
}
return getSlowAdcSample(hwChannel);
}
void waitForSlowAdc() {
// Wait for a few slow adc updates to happen
while (slowAdcCounter < 5) {
chThdSleepMilliseconds(1);
}
}
void updateSlowAdc(efitick_t nowNt) {
{
ScopePerf perf(PE::AdcConversionSlow);
if (!readSlowAnalogInputs()) {
return;
}
// Ask the port to sample the MCU temperature
mcuTemperature = getMcuTemperature();
}
{
ScopePerf perf(PE::AdcProcessSlow);
AdcSubscription::UpdateSubscribers(nowNt);
protectedGpio_check(nowNt);
}
slowAdcCounter++;
}
#else /* not HAL_USE_ADC */
__attribute__((weak)) float getVoltageDivided(const char*, adc_channel_e) {
return 0;
}
// voltage in MCU universe, from zero to VDD
__attribute__((weak)) float getVoltage(const char*, adc_channel_e) {
return 0;
}
#endif