fome-fw/firmware/controllers/trigger/aux_valves.cpp

124 lines
4.0 KiB
C++
Raw Normal View History

2017-11-25 22:17:37 -08:00
/*
* aux_valves.cpp
*
2017-11-27 18:49:58 -08:00
*
* Here we have two auxilary digital on/off outputs which would open once per each 360 degrees of engine crank revolution.
* The second valve is 180 degrees after the first one.
*
* Valve open and close angles are taken from fsioCurve1 and fsioCurve2 tables respectively, the position depend on TPS input.
*
* https://github.com/rusefi/rusefi/issues/490
*
2017-11-25 22:17:37 -08:00
* @date Nov 25, 2017
2018-01-20 17:55:31 -08:00
* @author Andrey Belomutskiy, (c) 2012-2018
2017-11-25 22:17:37 -08:00
*/
2019-01-20 21:10:09 -08:00
#include "engine_math.h"
2017-11-25 22:17:37 -08:00
#include "aux_valves.h"
2017-11-26 19:30:37 -08:00
#include "allsensors.h"
#include "trigger_central.h"
EXTERN_ENGINE
;
2019-11-23 19:55:21 -08:00
void plainPinTurnOn(NamedOutputPin *output) {
2017-11-27 18:49:58 -08:00
output->setHigh();
}
2017-11-26 21:06:43 -08:00
2019-11-23 19:55:21 -08:00
void plainPinTurnOff(NamedOutputPin *output) {
2017-11-27 18:49:58 -08:00
output->setLow();
2017-11-26 21:06:43 -08:00
}
2017-11-27 18:49:58 -08:00
2017-11-26 19:30:37 -08:00
static void auxValveTriggerCallback(trigger_event_e ckpSignalType,
uint32_t index DECLARE_ENGINE_PARAMETER_SUFFIX) {
UNUSED(ckpSignalType);
2019-11-19 22:42:03 -08:00
2019-11-23 19:55:21 -08:00
if (index != engine->auxSchedulingIndex) {
2017-11-26 21:06:43 -08:00
return;
}
2019-01-21 17:33:21 -08:00
int rpm = GET_RPM_VALUE;
2017-11-27 18:49:58 -08:00
if (!isValidRpm(rpm)) {
return;
}
2019-11-23 07:34:43 -08:00
/**
* Sometimes previous event has not yet been executed by the time we are scheduling new events.
* We use this array alternation in order to bring events that are scheled and waiting to be executed from
* events which are already being scheduled
*/
int engineCycleAlternation = engine->triggerCentral.triggerState.getTotalRevolutionCounter() % CYCLE_ALTERNATION;
2019-11-19 22:42:03 -08:00
for (int valveIndex = 0; valveIndex < AUX_DIGITAL_VALVE_COUNT; valveIndex++) {
2017-11-27 18:49:58 -08:00
NamedOutputPin *output = &enginePins.auxValve[valveIndex];
for (int phaseIndex = 0; phaseIndex < 2; phaseIndex++) {
/* I believe a more correct implementation is the following:
* here we properly account for trigger angle position in engine cycle coordinates
2017-12-02 18:16:42 -08:00
// todo: at the moment this logic is assuming four-stroke 720-degree engine cycle
angle_t extra = phaseIndex * 360 // cycle opens twice per 720 engine cycle
+ valveIndex * 180 // 2nd valve is operating at 180 offset to first
+ tdcPosition() // engine cycle position to trigger cycle position conversion
- ENGINE(triggerCentral.triggerShape.eventAngles[SCHEDULING_TRIGGER_INDEX])
;
*/
angle_t extra = phaseIndex * 360 + valveIndex * 180;
2017-12-01 20:25:30 -08:00
angle_t onTime = extra + engine->engineState.auxValveStart;
2019-11-23 19:55:21 -08:00
scheduling_s *onEvent = &engine->auxTurnOnEvent[valveIndex][phaseIndex][engineCycleAlternation];
scheduling_s *offEvent = &engine->auxTurnOffEvent[valveIndex][phaseIndex][engineCycleAlternation];
2019-11-22 15:50:46 -08:00
bool isOverlap = onEvent->isScheduled || offEvent->isScheduled;
if (isOverlap) {
enginePins.debugTriggerSync.setValue(1);
}
2018-07-23 18:38:05 -07:00
fixAngle(onTime, "onTime", CUSTOM_ERR_6556);
2019-11-22 15:50:46 -08:00
scheduleByAngle(rpm, onEvent,
2017-12-01 20:25:30 -08:00
onTime,
2019-11-23 19:55:21 -08:00
(schfunc_t) &plainPinTurnOn, output PASS_ENGINE_PARAMETER_SUFFIX);
2017-12-01 20:25:30 -08:00
angle_t offTime = extra + engine->engineState.auxValveEnd;
2018-07-23 18:38:05 -07:00
fixAngle(offTime, "offTime", CUSTOM_ERR_6557);
2019-11-22 15:50:46 -08:00
scheduleByAngle(rpm, offEvent,
2017-12-01 20:25:30 -08:00
offTime,
2019-11-23 19:55:21 -08:00
(schfunc_t) &plainPinTurnOff, output PASS_ENGINE_PARAMETER_SUFFIX);
2019-11-22 15:50:46 -08:00
if (isOverlap) {
enginePins.debugTriggerSync.setValue(0);
}
2017-11-27 18:49:58 -08:00
}
}
2017-11-26 19:30:37 -08:00
}
2017-11-25 22:17:37 -08:00
2019-11-19 22:42:03 -08:00
void initAuxValves(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) {
UNUSED(sharedLogger);
2017-11-26 19:30:37 -08:00
if (engineConfiguration->auxValves[0] == GPIO_UNASSIGNED) {
return;
}
addTriggerEventListener(auxValveTriggerCallback, "tach", engine);
}
void updateAuxValves(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
if (engineConfiguration->auxValves[0] == GPIO_UNASSIGNED) {
return;
}
float x = getTPS(PASS_ENGINE_PARAMETER_SIGNATURE);
2018-01-01 09:56:27 -08:00
if (cisnan(x)) {
// error should be already reported by now
return;
}
2017-11-27 18:49:58 -08:00
engine->engineState.auxValveStart = interpolate2d("aux", x,
engineConfiguration->fsioCurve1Bins,
engineConfiguration->fsioCurve1);
2017-11-25 22:17:37 -08:00
2017-11-27 18:49:58 -08:00
engine->engineState.auxValveEnd = interpolate2d("aux", x,
engineConfiguration->fsioCurve2Bins,
engineConfiguration->fsioCurve2);
2017-12-08 17:04:58 -08:00
if (engine->engineState.auxValveStart >= engine->engineState.auxValveEnd) {
// this is a fatal error to make this really visible
2018-01-23 09:05:14 -08:00
firmwareError(CUSTOM_AUX_OUT_OF_ORDER, "out of order at %.2f %.2f %.2f", x,
2017-12-08 17:04:58 -08:00
engine->engineState.auxValveStart,
engine->engineState.auxValveEnd);
}
2017-11-25 22:17:37 -08:00
}