Revert "prep for multiple MAP sensors (#4677)"
This reverts commit b8c79b7881
.
This commit is contained in:
parent
6e013ce883
commit
b01082640b
|
@ -41,6 +41,20 @@
|
||||||
*/
|
*/
|
||||||
static NamedOutputPin mapAveragingPin("map");
|
static NamedOutputPin mapAveragingPin("map");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Running MAP accumulator - sum of all measurements within averaging window
|
||||||
|
*/
|
||||||
|
static volatile float mapAdcAccumulator = 0;
|
||||||
|
/**
|
||||||
|
* Running counter of measurements to consider for averaging
|
||||||
|
*/
|
||||||
|
static volatile int mapMeasurementsCounter = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* v_ for Voltage
|
||||||
|
*/
|
||||||
|
static float v_averagedMapValue;
|
||||||
|
|
||||||
// allow smoothing up to number of cylinders
|
// allow smoothing up to number of cylinders
|
||||||
#define MAX_MAP_BUFFER_LENGTH (MAX_CYLINDER_COUNT)
|
#define MAX_MAP_BUFFER_LENGTH (MAX_CYLINDER_COUNT)
|
||||||
// in MAP units, not voltage!
|
// in MAP units, not voltage!
|
||||||
|
@ -54,12 +68,24 @@ static int averagedMapBufIdx = 0;
|
||||||
static scheduling_s startTimers[MAX_CYLINDER_COUNT][2];
|
static scheduling_s startTimers[MAX_CYLINDER_COUNT][2];
|
||||||
static scheduling_s endTimers[MAX_CYLINDER_COUNT][2];
|
static scheduling_s endTimers[MAX_CYLINDER_COUNT][2];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* that's a performance optimization: let's not bother averaging
|
||||||
|
* if we are outside of of the window
|
||||||
|
*/
|
||||||
|
static bool isAveraging = false;
|
||||||
|
|
||||||
static void endAveraging(void *arg);
|
static void endAveraging(void *arg);
|
||||||
|
|
||||||
static void startAveraging(scheduling_s *endAveragingScheduling) {
|
static void startAveraging(scheduling_s *endAveragingScheduling) {
|
||||||
efiAssertVoid(CUSTOM_ERR_6649, getCurrentRemainingStack() > 128, "lowstck#9");
|
efiAssertVoid(CUSTOM_ERR_6649, getCurrentRemainingStack() > 128, "lowstck#9");
|
||||||
|
|
||||||
getMapAvg().start();
|
{
|
||||||
|
// with locking we will have a consistent state
|
||||||
|
chibios_rt::CriticalSectionLocker csl;
|
||||||
|
mapAdcAccumulator = 0;
|
||||||
|
mapMeasurementsCounter = 0;
|
||||||
|
isAveraging = true;
|
||||||
|
}
|
||||||
|
|
||||||
mapAveragingPin.setHigh();
|
mapAveragingPin.setHigh();
|
||||||
|
|
||||||
|
@ -67,51 +93,6 @@ static void startAveraging(scheduling_s *endAveragingScheduling) {
|
||||||
endAveraging);
|
endAveraging);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapAverager::start() {
|
|
||||||
chibios_rt::CriticalSectionLocker csl;
|
|
||||||
|
|
||||||
m_counter = 0;
|
|
||||||
m_sum = 0;
|
|
||||||
m_isAveraging = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
SensorResult MapAverager::submit(float volts) {
|
|
||||||
auto result = m_function ? m_function->convert(volts) : unexpected;
|
|
||||||
|
|
||||||
if (m_isAveraging && result) {
|
|
||||||
chibios_rt::CriticalSectionLocker csl;
|
|
||||||
|
|
||||||
m_counter++;
|
|
||||||
m_sum += result.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapAverager::stop() {
|
|
||||||
m_isAveraging = false;
|
|
||||||
|
|
||||||
if (m_counter > 0) {
|
|
||||||
float averageMap = m_sum / m_counter;
|
|
||||||
m_lastCounter = m_counter;
|
|
||||||
|
|
||||||
// TODO: this should be per-sensor, not one for all MAP sensors
|
|
||||||
averagedMapRunningBuffer[averagedMapBufIdx] = averageMap;
|
|
||||||
// increment circular running buffer index
|
|
||||||
averagedMapBufIdx = (averagedMapBufIdx + 1) % mapMinBufferLength;
|
|
||||||
// find min. value (only works for pressure values, not raw voltages!)
|
|
||||||
float minPressure = averagedMapRunningBuffer[0];
|
|
||||||
for (int i = 1; i < mapMinBufferLength; i++) {
|
|
||||||
if (averagedMapRunningBuffer[i] < minPressure)
|
|
||||||
minPressure = averagedMapRunningBuffer[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
setValidValue(minPressure, getTimeNowNt());
|
|
||||||
} else {
|
|
||||||
warning(CUSTOM_UNEXPECTED_MAP_VALUE, "No MAP values");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if HAL_USE_ADC
|
#if HAL_USE_ADC
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -123,18 +104,23 @@ void mapAveragingAdcCallback(adcsample_t adcValue) {
|
||||||
efiAssertVoid(CUSTOM_ERR_6650, getCurrentRemainingStack() > 128, "lowstck#9a");
|
efiAssertVoid(CUSTOM_ERR_6650, getCurrentRemainingStack() > 128, "lowstck#9a");
|
||||||
|
|
||||||
float instantVoltage = adcToVoltsDivided(adcValue);
|
float instantVoltage = adcToVoltsDivided(adcValue);
|
||||||
|
SensorResult mapResult = convertMap(instantVoltage);
|
||||||
SensorResult mapResult = getMapAvg().submit(instantVoltage);
|
|
||||||
|
|
||||||
if (!mapResult) {
|
if (!mapResult) {
|
||||||
// hopefully this warning is not too much CPU consumption for fast ADC callback
|
// hopefully this warning is not too much CPU consumption for fast ADC callback
|
||||||
warning(CUSTOM_INSTANT_MAP_DECODING, "Invalid MAP at %f", instantVoltage);
|
warning(CUSTOM_INSTANT_MAP_DECODING, "Invalid MAP at %f", instantVoltage);
|
||||||
}
|
}
|
||||||
|
|
||||||
float instantMap = mapResult.value_or(0);
|
float instantMap = mapResult.value_or(0);
|
||||||
#if EFI_TUNER_STUDIO
|
#if EFI_TUNER_STUDIO
|
||||||
engine->outputChannels.instantMAPValue = instantMap;
|
engine->outputChannels.instantMAPValue = instantMap;
|
||||||
#endif // EFI_TUNER_STUDIO
|
#endif // EFI_TUNER_STUDIO
|
||||||
|
|
||||||
|
/* Calculates the average values from the ADC samples.*/
|
||||||
|
if (isAveraging) {
|
||||||
|
// with locking we will have a consistent state
|
||||||
|
chibios_rt::CriticalSectionLocker csl;
|
||||||
|
mapAdcAccumulator += adcValue;
|
||||||
|
mapMeasurementsCounter++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -142,9 +128,32 @@ static void endAveraging(void*) {
|
||||||
#if ! EFI_UNIT_TEST
|
#if ! EFI_UNIT_TEST
|
||||||
chibios_rt::CriticalSectionLocker csl;
|
chibios_rt::CriticalSectionLocker csl;
|
||||||
#endif
|
#endif
|
||||||
|
isAveraging = false;
|
||||||
|
// with locking we would have a consistent state
|
||||||
|
#if HAL_USE_ADC
|
||||||
|
if (mapMeasurementsCounter > 0) {
|
||||||
|
v_averagedMapValue = adcToVoltsDivided(mapAdcAccumulator / mapMeasurementsCounter);
|
||||||
|
|
||||||
getMapAvg().stop();
|
SensorResult mapValue = convertMap(v_averagedMapValue);
|
||||||
|
|
||||||
|
// Skip update if conversion invalid
|
||||||
|
if (mapValue) {
|
||||||
|
averagedMapRunningBuffer[averagedMapBufIdx] = mapValue.Value;
|
||||||
|
// increment circular running buffer index
|
||||||
|
averagedMapBufIdx = (averagedMapBufIdx + 1) % mapMinBufferLength;
|
||||||
|
// find min. value (only works for pressure values, not raw voltages!)
|
||||||
|
float minPressure = averagedMapRunningBuffer[0];
|
||||||
|
for (int i = 1; i < mapMinBufferLength; i++) {
|
||||||
|
if (averagedMapRunningBuffer[i] < minPressure)
|
||||||
|
minPressure = averagedMapRunningBuffer[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
onMapAveraged(minPressure, getTimeNowNt());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
warning(CUSTOM_UNEXPECTED_MAP_VALUE, "No MAP values");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
mapAveragingPin.setLow();
|
mapAveragingPin.setLow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +170,9 @@ static void applyMapMinBufferLength() {
|
||||||
|
|
||||||
#if EFI_TUNER_STUDIO
|
#if EFI_TUNER_STUDIO
|
||||||
void postMapState(TunerStudioOutputChannels *tsOutputChannels) {
|
void postMapState(TunerStudioOutputChannels *tsOutputChannels) {
|
||||||
|
tsOutputChannels->debugFloatField1 = v_averagedMapValue;
|
||||||
tsOutputChannels->debugFloatField2 = engine->engineState.mapAveragingDuration;
|
tsOutputChannels->debugFloatField2 = engine->engineState.mapAveragingDuration;
|
||||||
|
tsOutputChannels->debugIntField1 = mapMeasurementsCounter;
|
||||||
}
|
}
|
||||||
#endif /* EFI_TUNER_STUDIO */
|
#endif /* EFI_TUNER_STUDIO */
|
||||||
|
|
||||||
|
@ -243,13 +254,13 @@ void mapAveragingTriggerCallback(
|
||||||
// only if value is already prepared
|
// only if value is already prepared
|
||||||
int structIndex = getRevolutionCounter() % 2;
|
int structIndex = getRevolutionCounter() % 2;
|
||||||
|
|
||||||
scheduling_s *startTimer = &startTimers[i][structIndex];
|
scheduling_s *starTimer = &startTimers[i][structIndex];
|
||||||
scheduling_s *endTimer = &endTimers[i][structIndex];
|
scheduling_s *endTimer = &endTimers[i][structIndex];
|
||||||
|
|
||||||
// at the moment we schedule based on time prediction based on current RPM and angle
|
// at the moment we schedule based on time prediction based on current RPM and angle
|
||||||
// we are loosing precision in case of changing RPM - the further away is the event the worse is precision
|
// we are loosing precision in case of changing RPM - the further away is the event the worse is precision
|
||||||
// todo: schedule this based on closest trigger event, same as ignition works
|
// todo: schedule this based on closest trigger event, same as ignition works
|
||||||
scheduleByAngle(startTimer, edgeTimestamp, samplingStart,
|
scheduleByAngle(starTimer, edgeTimestamp, samplingStart,
|
||||||
{ startAveraging, endTimer });
|
{ startAveraging, endTimer });
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "sensor_converter_func.h"
|
|
||||||
|
|
||||||
#if EFI_MAP_AVERAGING
|
#if EFI_MAP_AVERAGING
|
||||||
|
|
||||||
#if HAL_USE_ADC
|
#if HAL_USE_ADC
|
||||||
|
@ -21,40 +19,11 @@ void refreshMapAveragingPreCalc();
|
||||||
void mapAveragingTriggerCallback(
|
void mapAveragingTriggerCallback(
|
||||||
uint32_t index, efitick_t edgeTimestamp);
|
uint32_t index, efitick_t edgeTimestamp);
|
||||||
|
|
||||||
|
void onMapAveraged(float mapKpa, efitick_t nowNt);
|
||||||
|
SensorResult convertMap(float volts);
|
||||||
|
|
||||||
#if EFI_TUNER_STUDIO
|
#if EFI_TUNER_STUDIO
|
||||||
void postMapState(TunerStudioOutputChannels *tsOutputChannels);
|
void postMapState(TunerStudioOutputChannels *tsOutputChannels);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// allow smoothing up to number of cylinders
|
|
||||||
#define MAX_MAP_BUFFER_LENGTH (MAX_CYLINDER_COUNT)
|
|
||||||
|
|
||||||
#endif /* EFI_MAP_AVERAGING */
|
#endif /* EFI_MAP_AVERAGING */
|
||||||
|
|
||||||
class MapAverager : public StoredValueSensor {
|
|
||||||
public:
|
|
||||||
MapAverager(SensorType type, efitick_t timeout)
|
|
||||||
: StoredValueSensor(type, timeout)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void start();
|
|
||||||
void stop();
|
|
||||||
|
|
||||||
SensorResult submit(float sensorVolts);
|
|
||||||
|
|
||||||
void setFunction(SensorConverter& func) {
|
|
||||||
m_function = &func;
|
|
||||||
}
|
|
||||||
|
|
||||||
void showInfo(const char* sensorName) const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
SensorConverter* m_function = nullptr;
|
|
||||||
|
|
||||||
bool m_isAveraging = false;
|
|
||||||
size_t m_counter = 0;
|
|
||||||
size_t m_lastCounter = 0;
|
|
||||||
float m_sum = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
MapAverager& getMapAvg();
|
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include "resistance_func.h"
|
#include "resistance_func.h"
|
||||||
#include "thermistor_func.h"
|
#include "thermistor_func.h"
|
||||||
#include "identity_func.h"
|
#include "identity_func.h"
|
||||||
#include "map_averaging.h"
|
|
||||||
|
|
||||||
void ProxySensor::showInfo(const char* sensorName) const {
|
void ProxySensor::showInfo(const char* sensorName) const {
|
||||||
efiPrintf("Sensor \"%s\" proxied from sensor \"%s\"", sensorName, getSensorName(m_proxiedSensor));
|
efiPrintf("Sensor \"%s\" proxied from sensor \"%s\"", sensorName, getSensorName(m_proxiedSensor));
|
||||||
|
@ -67,11 +66,6 @@ void Lps25Sensor::showInfo(const char* sensorName) const {
|
||||||
efiPrintf("%s: LPS25 baro %.2f kPa", sensorName, get().Value);
|
efiPrintf("%s: LPS25 baro %.2f kPa", sensorName, get().Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapAverager::showInfo(const char* sensorName) const {
|
|
||||||
const auto value = get();
|
|
||||||
efiPrintf("Sensor \"%s\" is MAP averager: valid: %s value: %.2f averaged sample count: %d", sensorName, boolToString(value.Valid), value.Value, m_lastCounter);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LinearFunc::showInfo(float testRawValue) const {
|
void LinearFunc::showInfo(float testRawValue) const {
|
||||||
efiPrintf(" Linear function slope: %.2f offset: %.2f min: %.1f max: %.1f", m_a, m_b, m_minOutput, m_maxOutput);
|
efiPrintf(" Linear function slope: %.2f offset: %.2f min: %.1f max: %.1f", m_a, m_b, m_minOutput, m_maxOutput);
|
||||||
const auto value = convert(testRawValue);
|
const auto value = convert(testRawValue);
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
#include "linear_func.h"
|
#include "linear_func.h"
|
||||||
#include "fallback_sensor.h"
|
#include "fallback_sensor.h"
|
||||||
#include "functional_sensor.h"
|
#include "functional_sensor.h"
|
||||||
#include "map_averaging.h"
|
#include "function_pointer_sensor.h"
|
||||||
|
#include "identity_func.h"
|
||||||
|
|
||||||
static LinearFunc baroConverter;
|
static LinearFunc baroConverter;
|
||||||
static FunctionalSensor baroSensor(SensorType::BarometricPressure, MS2NT(50));
|
static FunctionalSensor baroSensor(SensorType::BarometricPressure, MS2NT(50));
|
||||||
|
@ -17,12 +18,17 @@ static FunctionalSensor slowMapSensor(SensorType::MapSlow, MS2NT(50));
|
||||||
// lowest reasonable idle is maybe 600 rpm
|
// lowest reasonable idle is maybe 600 rpm
|
||||||
// one sample per cycle (1 cylinder, or "sample one cyl" mode) gives a period of 100ms
|
// one sample per cycle (1 cylinder, or "sample one cyl" mode) gives a period of 100ms
|
||||||
// add some margin -> 200ms timeout for fast MAP sampling
|
// add some margin -> 200ms timeout for fast MAP sampling
|
||||||
MapAverager fastMapSensor(SensorType::MapFast, MS2NT(200));
|
static FunctionalSensor fastMapSensor(SensorType::MapFast, MS2NT(200));
|
||||||
|
|
||||||
MapAverager& getMapAvg() {
|
// This is called from the fast ADC completion callback
|
||||||
return fastMapSensor;
|
void onMapAveraged(float mapKpa, efitick_t nowNt) {
|
||||||
|
// This sensor uses identity function, so it's kPa in, kPa out
|
||||||
|
fastMapSensor.postRawValue(mapKpa, nowNt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SensorResult convertMap(float volts) {
|
||||||
|
return mapConverter.convert(volts);
|
||||||
|
}
|
||||||
|
|
||||||
// Combine MAP sensors: prefer fast sensor, but use slow if fast is unavailable.
|
// Combine MAP sensors: prefer fast sensor, but use slow if fast is unavailable.
|
||||||
static FallbackSensor mapCombiner(SensorType::Map, SensorType::MapFast, SensorType::MapSlow);
|
static FallbackSensor mapCombiner(SensorType::Map, SensorType::MapFast, SensorType::MapSlow);
|
||||||
|
@ -100,7 +106,7 @@ void initMap() {
|
||||||
configureMapFunction(mapConverter, engineConfiguration->map.sensor.type);
|
configureMapFunction(mapConverter, engineConfiguration->map.sensor.type);
|
||||||
|
|
||||||
slowMapSensor.setFunction(mapConverter);
|
slowMapSensor.setFunction(mapConverter);
|
||||||
fastMapSensor.setFunction(mapConverter);
|
fastMapSensor.setFunction(identityFunction);
|
||||||
|
|
||||||
slowMapSensor.Register();
|
slowMapSensor.Register();
|
||||||
fastMapSensor.Register();
|
fastMapSensor.Register();
|
||||||
|
|
Loading…
Reference in New Issue