rusefi/signal_executor.c

164 lines
4.3 KiB
C

/**
* @file signal_executor.c
*
* todo: we should split this file into two:
* one for pure scheduling and another one for signal output which would
* use the scheduling
*
* @date Dec 4, 2013
* @author Andrey Belomutskiy, (c) 2012-2014
*
* This file is part of rusEfi - see http://rusefi.com
*
* rusEfi is free software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "main.h"
#include "signal_executor.h"
#if EFI_WAVE_CHART
#include "rpm_calculator.h"
#endif
#if EFI_WAVE_ANALYZER
/**
* Signal executors feed digital events right into WaveChart used by Sniffer tab of Dev Console
*/
#include "wave_analyzer.h"
#endif /* EFI_WAVE_ANALYZER */
#if EFI_PROD_CODE || EFI_SIMULATOR
static Logging logger;
#endif
void initSignalExecutor(void) {
#if EFI_PROD_CODE || EFI_SIMULATOR
initLogging(&logger, "s exec");
#endif
initSignalExecutorImpl();
}
void initOutputSignalBase(OutputSignal *signal) {
signal->status = IDLE;
// signal->last_scheduling_time = 0;
signal->initialized = TRUE;
}
static void turnHigh(OutputSignal *signal) {
#if EFI_DEFAILED_LOGGING
// signal->hi_time = hTimeNow();
#endif /* EFI_DEFAILED_LOGGING */
io_pin_e pin = signal->io_pin;
// turn the output level ACTIVE
// todo: this XOR should go inside the setOutputPinValue method
setOutputPinValue(pin, TRUE);
// sleep for the needed duration
#if EFI_PROD_CODE || EFI_SIMULATOR
if(
pin == SPARKOUT_1_OUTPUT ||
pin == SPARKOUT_3_OUTPUT) {
// time_t now = hTimeNow();
// float an = getCrankshaftAngle(now);
// scheduleMsg(&logger, "spark up%d %d", pin, now);
// scheduleMsg(&logger, "spark angle %d %f", (int)an, an);
}
#endif
#if EFI_WAVE_CHART
addWaveChartEvent(signal->name, "up", "");
#endif /* EFI_WAVE_ANALYZER */
}
static void turnLow(OutputSignal *signal) {
// turn off the output
// todo: this XOR should go inside the setOutputPinValue method
setOutputPinValue(signal->io_pin, FALSE);
#if EFI_DEFAILED_LOGGING
systime_t after = hTimeNow();
debugInt(&signal->logging, "a_time", after - signal->hi_time);
scheduleLogging(&signal->logging);
#endif /* EFI_DEFAILED_LOGGING */
#if EFI_WAVE_CHART
addWaveChartEvent(signal->name, "down", "");
#endif /* EFI_WAVE_ANALYZER */
}
/**
*
* @param delay the number of ticks before the output signal
* immediate output if delay is zero
* @param dwell the number of ticks of output duration
*
*/
int getRevolutionCounter(void);
void scheduleOutput(OutputSignal *signal, float delayMs, float durationMs) {
if (durationMs < 0) {
firmwareError("duration cannot be negative: %d", durationMs);
return;
}
scheduleOutputBase(signal, delayMs, durationMs);
int index = getRevolutionCounter() % 2;
scheduling_s * sUp = &signal->signalTimerUp[index];
scheduling_s * sDown = &signal->signalTimerDown[index];
scheduleTask(sUp, MS2US(delayMs), (schfunc_t) &turnHigh, (void *) signal);
scheduleTask(sDown, MS2US(delayMs + durationMs), (schfunc_t) &turnLow, (void*)signal);
// signal->last_scheduling_time = now;
}
void scheduleOutputBase(OutputSignal *signal, float delayMs, float durationMs) {
/**
* it's better to check for the exact 'TRUE' value since otherwise
* we would accept any memory garbage
*/
chDbgCheck(signal->initialized == TRUE, "Signal not initialized");
// signal->offset = offset;
// signal->duration = duration;
}
char *getPinName(io_pin_e io_pin) {
switch (io_pin) {
case SPARKOUT_1_OUTPUT:
return "Spark 1";
case SPARKOUT_2_OUTPUT:
return "Spark 2";
case SPARKOUT_3_OUTPUT:
return "Spark 3";
case SPARKOUT_4_OUTPUT:
return "Spark 4";
case INJECTOR_1_OUTPUT:
return "Injector 1";
case INJECTOR_2_OUTPUT:
return "Injector 2";
case INJECTOR_3_OUTPUT:
return "Injector 3";
case INJECTOR_4_OUTPUT:
return "Injector 4";
case INJECTOR_5_OUTPUT:
return "Injector 5";
default:
return "No name";
}
}