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");
|
||||
|
||||
/**
|
||||
* 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
|
||||
#define MAX_MAP_BUFFER_LENGTH (MAX_CYLINDER_COUNT)
|
||||
// in MAP units, not voltage!
|
||||
|
@ -54,12 +68,24 @@ static int averagedMapBufIdx = 0;
|
|||
static scheduling_s startTimers[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 startAveraging(scheduling_s *endAveragingScheduling) {
|
||||
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();
|
||||
|
||||
|
@ -67,51 +93,6 @@ static void startAveraging(scheduling_s *endAveragingScheduling) {
|
|||
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
|
||||
|
||||
/**
|
||||
|
@ -123,18 +104,23 @@ void mapAveragingAdcCallback(adcsample_t adcValue) {
|
|||
efiAssertVoid(CUSTOM_ERR_6650, getCurrentRemainingStack() > 128, "lowstck#9a");
|
||||
|
||||
float instantVoltage = adcToVoltsDivided(adcValue);
|
||||
|
||||
SensorResult mapResult = getMapAvg().submit(instantVoltage);
|
||||
|
||||
SensorResult mapResult = convertMap(instantVoltage);
|
||||
if (!mapResult) {
|
||||
// hopefully this warning is not too much CPU consumption for fast ADC callback
|
||||
warning(CUSTOM_INSTANT_MAP_DECODING, "Invalid MAP at %f", instantVoltage);
|
||||
}
|
||||
|
||||
float instantMap = mapResult.value_or(0);
|
||||
#if EFI_TUNER_STUDIO
|
||||
engine->outputChannels.instantMAPValue = instantMap;
|
||||
#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
|
||||
|
||||
|
@ -142,9 +128,32 @@ static void endAveraging(void*) {
|
|||
#if ! EFI_UNIT_TEST
|
||||
chibios_rt::CriticalSectionLocker csl;
|
||||
#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();
|
||||
}
|
||||
|
||||
|
@ -161,7 +170,9 @@ static void applyMapMinBufferLength() {
|
|||
|
||||
#if EFI_TUNER_STUDIO
|
||||
void postMapState(TunerStudioOutputChannels *tsOutputChannels) {
|
||||
tsOutputChannels->debugFloatField1 = v_averagedMapValue;
|
||||
tsOutputChannels->debugFloatField2 = engine->engineState.mapAveragingDuration;
|
||||
tsOutputChannels->debugIntField1 = mapMeasurementsCounter;
|
||||
}
|
||||
#endif /* EFI_TUNER_STUDIO */
|
||||
|
||||
|
@ -243,13 +254,13 @@ void mapAveragingTriggerCallback(
|
|||
// only if value is already prepared
|
||||
int structIndex = getRevolutionCounter() % 2;
|
||||
|
||||
scheduling_s *startTimer = &startTimers[i][structIndex];
|
||||
scheduling_s *starTimer = &startTimers[i][structIndex];
|
||||
scheduling_s *endTimer = &endTimers[i][structIndex];
|
||||
|
||||
// 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
|
||||
// todo: schedule this based on closest trigger event, same as ignition works
|
||||
scheduleByAngle(startTimer, edgeTimestamp, samplingStart,
|
||||
scheduleByAngle(starTimer, edgeTimestamp, samplingStart,
|
||||
{ startAveraging, endTimer });
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "sensor_converter_func.h"
|
||||
|
||||
#if EFI_MAP_AVERAGING
|
||||
|
||||
#if HAL_USE_ADC
|
||||
|
@ -21,40 +19,11 @@ void refreshMapAveragingPreCalc();
|
|||
void mapAveragingTriggerCallback(
|
||||
uint32_t index, efitick_t edgeTimestamp);
|
||||
|
||||
void onMapAveraged(float mapKpa, efitick_t nowNt);
|
||||
SensorResult convertMap(float volts);
|
||||
|
||||
#if EFI_TUNER_STUDIO
|
||||
void postMapState(TunerStudioOutputChannels *tsOutputChannels);
|
||||
#endif
|
||||
|
||||
// allow smoothing up to number of cylinders
|
||||
#define MAX_MAP_BUFFER_LENGTH (MAX_CYLINDER_COUNT)
|
||||
|
||||
#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 "thermistor_func.h"
|
||||
#include "identity_func.h"
|
||||
#include "map_averaging.h"
|
||||
|
||||
void ProxySensor::showInfo(const char* sensorName) const {
|
||||
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);
|
||||
}
|
||||
|
||||
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 {
|
||||
efiPrintf(" Linear function slope: %.2f offset: %.2f min: %.1f max: %.1f", m_a, m_b, m_minOutput, m_maxOutput);
|
||||
const auto value = convert(testRawValue);
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
#include "linear_func.h"
|
||||
#include "fallback_sensor.h"
|
||||
#include "functional_sensor.h"
|
||||
#include "map_averaging.h"
|
||||
#include "function_pointer_sensor.h"
|
||||
#include "identity_func.h"
|
||||
|
||||
static LinearFunc baroConverter;
|
||||
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
|
||||
// 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
|
||||
MapAverager fastMapSensor(SensorType::MapFast, MS2NT(200));
|
||||
static FunctionalSensor fastMapSensor(SensorType::MapFast, MS2NT(200));
|
||||
|
||||
MapAverager& getMapAvg() {
|
||||
return fastMapSensor;
|
||||
// This is called from the fast ADC completion callback
|
||||
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.
|
||||
static FallbackSensor mapCombiner(SensorType::Map, SensorType::MapFast, SensorType::MapSlow);
|
||||
|
@ -100,7 +106,7 @@ void initMap() {
|
|||
configureMapFunction(mapConverter, engineConfiguration->map.sensor.type);
|
||||
|
||||
slowMapSensor.setFunction(mapConverter);
|
||||
fastMapSensor.setFunction(mapConverter);
|
||||
fastMapSensor.setFunction(identityFunction);
|
||||
|
||||
slowMapSensor.Register();
|
||||
fastMapSensor.Register();
|
||||
|
|
Loading…
Reference in New Issue