rusEFI
The most advanced open source ECU
Data Structures | Functions
map_averaging.h File Reference

Detailed Description

Date
Dec 11, 2013
Author
Andrey Belomutskiy, (c) 2012-2020

Definition in file map_averaging.h.

Data Structures

class  MapAverager
 

Functions

void mapAveragingAdcCallback (float instantVoltage)
 
void initMapAveraging ()
 
void refreshMapAveragingPreCalc ()
 
void mapAveragingTriggerCallback (uint32_t index, efitick_t edgeTimestamp)
 
void postMapState (TunerStudioOutputChannels *tsOutputChannels)
 
MapAveragergetMapAvg (size_t idx)
 

Function Documentation

◆ getMapAvg()

MapAverager& getMapAvg ( size_t  idx)

Definition at line 26 of file init_map.cpp.

26  {
27  return idx == 0 ? fastMapSensor : fastMapSensor2;
28 }
MapAverager fastMapSensor(SensorType::MapFast, MS2NT(200))
MapAverager fastMapSensor2(SensorType::MapFast2, MS2NT(200))

Referenced by mapAveragingAdcCallback(), and startAveraging().

Here is the caller graph for this function:

◆ initMapAveraging()

void initMapAveraging ( )

Definition at line 268 of file map_averaging.cpp.

268  {
270 }
static void applyMapMinBufferLength()

Referenced by commonInitEngineController().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mapAveragingAdcCallback()

void mapAveragingAdcCallback ( float  instantVoltage)

This method is invoked from ADC callback.

Note
This method is invoked OFTEN, this method is a potential bottleneck - the implementation should be as fast as possible

Definition at line 135 of file map_averaging.cpp.

135  {
136  efiAssertVoid(ObdCode::CUSTOM_ERR_6650, hasLotsOfRemainingStack(), "lowstck#9a");
137 
138  SensorResult mapResult = getMapAvg(currentMapAverager).submit(instantVoltage);
139 
140  if (!mapResult) {
141  // hopefully this warning is not too much CPU consumption for fast ADC callback
142  warning(ObdCode::CUSTOM_INSTANT_MAP_DECODING, "Invalid MAP at %f", instantVoltage);
143  }
144 
145  float instantMap = mapResult.value_or(0);
146 #if EFI_TUNER_STUDIO
147  engine->outputChannels.instantMAPValue = instantMap;
148 #endif // EFI_TUNER_STUDIO
149 }
TunerStudioOutputChannels outputChannels
Definition: engine.h:96
SensorResult submit(float sensorVolts)
Engine * engine
bool warning(ObdCode code, const char *fmt,...)
static size_t currentMapAverager
MapAverager & getMapAvg(size_t idx)
Definition: init_map.cpp:26
@ CUSTOM_ERR_6650
@ CUSTOM_INSTANT_MAP_DECODING
expected< float > SensorResult
Definition: sensor.h:55
scaled_channel< uint16_t, 30, 1 > instantMAPValue

Referenced by onFastAdcComplete().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mapAveragingTriggerCallback()

void mapAveragingTriggerCallback ( uint32_t  index,
efitick_t  edgeTimestamp 
)

Shaft Position callback used to schedule start and end of MAP averaging

Definition at line 211 of file map_averaging.cpp.

212  {
213 #if EFI_ENGINE_CONTROL && EFI_PROD_CODE
214  // this callback is invoked on interrupt thread
215  if (index != (uint32_t)engineConfiguration->mapAveragingSchedulingAtIndex)
216  return;
217 
219  if (!isValidRpm(rpm)) {
220  return;
221  }
222 
224 
227  }
228 
229  // todo: this could be pre-calculated
231 
232  for (int i = 0; i < samplingCount; i++) {
233  angle_t samplingStart = engine->engineState.mapAveragingStart[i];
234 
235  angle_t samplingDuration = engine->engineState.mapAveragingDuration;
236  // todo: this assertion could be moved out of trigger handler
237  assertAngleRange(samplingDuration, "samplingDuration", ObdCode::CUSTOM_ERR_6563);
238  if (samplingDuration <= 0) {
239  warning(ObdCode::CUSTOM_MAP_ANGLE_PARAM, "map sampling angle should be positive");
240  return;
241  }
242 
243  angle_t samplingEnd = samplingStart + samplingDuration;
244 
245  if (cisnan(samplingEnd)) {
246  // todo: when would this happen?
247  warning(ObdCode::CUSTOM_ERR_6549, "no map angles");
248  return;
249  }
250 
251  // todo: pre-calculate samplingEnd for each cylinder
252  wrapAngle(samplingEnd, "samplingEnd", ObdCode::CUSTOM_ERR_6563);
253  // only if value is already prepared
254  int structIndex = getRevolutionCounter() % 2;
255 
256  scheduling_s *startTimer = &startTimers[i][structIndex];
257  scheduling_s *endTimer = &endTimers[i][structIndex];
258 
259  // at the moment we schedule based on time prediction based on current RPM and angle
260  // we are loosing precision in case of changing RPM - the further away is the event the worse is precision
261  // todo: schedule this based on closest trigger event, same as ignition works
262  scheduleByAngle(startTimer, edgeTimestamp, samplingStart,
263  { startAveraging, endTimer });
264  }
265 #endif // EFI_ENGINE_CONTROL && EFI_PROD_CODE
266 }
EngineState engineState
Definition: engine.h:310
angle_t mapAveragingStart[MAX_CYLINDER_COUNT]
Definition: engine_state.h:52
angle_t mapAveragingDuration
Definition: engine_state.h:53
static float getOrZero(SensorType type)
Definition: sensor.h:92
static scheduling_s startTimers[MAX_CYLINDER_COUNT][2]
static scheduling_s endTimers[MAX_CYLINDER_COUNT][2]
static void startAveraging(scheduling_s *endAveragingScheduling)
int mapMinBufferLength
@ CUSTOM_ERR_6549
@ CUSTOM_MAP_ANGLE_PARAM
@ CUSTOM_ERR_6563
@ MapAveragingTriggerCallback
engine_configuration_s * engineConfiguration
efitick_t scheduleByAngle(scheduling_s *timer, efitick_t nowNt, angle_t angle, action_s action)
float angle_t
Definition: rusefi_types.h:58
void wrapAngle(angle_t &angle, const char *msg, ObdCode code)

Referenced by TriggerCentral::handleShaftSignal().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ postMapState()

void postMapState ( TunerStudioOutputChannels tsOutputChannels)

Definition at line 172 of file map_averaging.cpp.

172  {
174 }

Referenced by updateTunerStudioState().

Here is the caller graph for this function:

◆ refreshMapAveragingPreCalc()

void refreshMapAveragingPreCalc ( )

Definition at line 177 of file map_averaging.cpp.

177  {
179  if (isValidRpm(rpm)) {
181  angle_t start = interpolate2d(rpm, c->samplingAngleBins, c->samplingAngle);
182  efiAssertVoid(ObdCode::CUSTOM_ERR_MAP_START_ASSERT, !cisnan(start), "start");
183 
185  efiAssertVoid(ObdCode::CUSTOM_ERR_MAP_AVG_OFFSET, !cisnan(offsetAngle), "offsetAngle");
186 
187  for (size_t i = 0; i < engineConfiguration->cylindersCount; i++) {
188  // todo: potential micro-optimization to reuse getEngineState()->engineCycle?
189  angle_t cylinderOffset = getEngineCycle(getEngineRotationState()->getOperationMode()) * i / engineConfiguration->cylindersCount;
190  efiAssertVoid(ObdCode::CUSTOM_ERR_MAP_CYL_OFFSET, !cisnan(cylinderOffset), "cylinderOffset");
191  // part of this formula related to specific cylinder offset is never changing - we can
192  // move the loop into start-up calculation and not have this loop as part of periodic calculation
193  // todo: change the logic as described above in order to reduce periodic CPU usage?
194  float cylinderStart = start + cylinderOffset - offsetAngle + tdcPosition();
195  wrapAngle(cylinderStart, "cylinderStart", ObdCode::CUSTOM_ERR_6562);
196  engine->engineState.mapAveragingStart[i] = cylinderStart;
197  }
199  } else {
200  for (size_t i = 0; i < engineConfiguration->cylindersCount; i++) {
202  }
204  }
205 
206 }
TriggerCentral triggerCentral
Definition: engine.h:281
TriggerFormDetails triggerFormDetails
angle_t eventAngles[2 *PWM_PHASE_MAX_COUNT]
EngineRotationState * getEngineRotationState()
Definition: engine.cpp:572
@ CUSTOM_ERR_MAP_AVG_OFFSET
@ CUSTOM_ERR_6562
@ CUSTOM_ERR_MAP_CYL_OFFSET
@ CUSTOM_ERR_MAP_START_ASSERT
angle_t getEngineCycle(operation_mode_e operationMode)

Referenced by Engine::periodicFastCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

Go to the source code of this file.