From 53ebcf4c17e9918927f7e5cf3cf753d71cec04b1 Mon Sep 17 00:00:00 2001 From: rusEfi Date: Wed, 21 Sep 2016 23:03:22 -0400 Subject: [PATCH] auto-sync --- firmware/console/status_loop.cpp | 3 - firmware/controllers/algo/engine.cpp | 1 - firmware/controllers/alternatorController.cpp | 1 - firmware/controllers/electronic_throttle.cpp | 2 - firmware/controllers/idle_thread.cpp | 1 - firmware/controllers/math/engine_math.cpp | 5 - firmware/controllers/system/efiGpio.h | 2 - .../trigger/main_trigger_callback.cpp | 146 +----------------- firmware/controllers/trigger/spark_logic.cpp | 146 ++++++++++++++++++ firmware/controllers/trigger/spark_logic.h | 5 + .../controllers/trigger/trigger_decoder.cpp | 1 - firmware/global.h | 3 +- firmware/hw_layer/hardware.cpp | 1 - unit_tests/Makefile | 1 + unit_tests/global.h | 2 +- unit_tests/test_trigger_decoder.cpp | 1 + win32_functional_tests/simulator/global.h | 3 +- 17 files changed, 159 insertions(+), 165 deletions(-) diff --git a/firmware/console/status_loop.cpp b/firmware/console/status_loop.cpp index b2ad1ec566..6a64666c2d 100644 --- a/firmware/console/status_loop.cpp +++ b/firmware/console/status_loop.cpp @@ -73,8 +73,6 @@ extern bool main_loop_started; #include "vehicle_speed.h" #endif -extern engine_pins_s enginePins; - static bool subscription[(int) RO_LAST_ELEMENT]; // this 'true' value is needed for simulator @@ -521,7 +519,6 @@ static THD_WORKING_AREA(blinkingStack, 128); static OutputPin communicationPin; OutputPin warningPin; OutputPin runningPin; -extern engine_pins_s enginePins; static OutputPin *leds[] = { &warningPin, &runningPin, &enginePins.errorLedPin, &communicationPin, &enginePins.checkEnginePin }; diff --git a/firmware/controllers/algo/engine.cpp b/firmware/controllers/algo/engine.cpp index 4ac0dec96b..fc03bede50 100644 --- a/firmware/controllers/algo/engine.cpp +++ b/firmware/controllers/algo/engine.cpp @@ -29,7 +29,6 @@ static LoggingWithStorage logger("engine"); -extern engine_pins_s enginePins; extern fuel_Map3D_t veMap; extern afr_Map3D_t afrMap; diff --git a/firmware/controllers/alternatorController.cpp b/firmware/controllers/alternatorController.cpp index 58f056548d..f9f73116f2 100644 --- a/firmware/controllers/alternatorController.cpp +++ b/firmware/controllers/alternatorController.cpp @@ -26,7 +26,6 @@ EXTERN_ENGINE static Logging *logger; extern pin_output_mode_e DEFAULT_OUTPUT; -extern engine_pins_s enginePins; int alternatorPidResetCounter = 0; static SimplePwm alternatorControl; diff --git a/firmware/controllers/electronic_throttle.cpp b/firmware/controllers/electronic_throttle.cpp index 43797c35f6..1e046f4b1c 100644 --- a/firmware/controllers/electronic_throttle.cpp +++ b/firmware/controllers/electronic_throttle.cpp @@ -61,8 +61,6 @@ static float currentEtbDuty; EXTERN_ENGINE; -extern engine_pins_s enginePins; - static bool wasEtbBraking = false; static msg_t etbThread(void *arg) { diff --git a/firmware/controllers/idle_thread.cpp b/firmware/controllers/idle_thread.cpp index 0acdb5d52b..797b8d51cb 100644 --- a/firmware/controllers/idle_thread.cpp +++ b/firmware/controllers/idle_thread.cpp @@ -40,7 +40,6 @@ static THD_WORKING_AREA(ivThreadStack, UTILITY_THREAD_STACK_SIZE); static Logging *logger; extern TunerStudioOutputChannels tsOutputChannels; -extern engine_pins_s enginePins; EXTERN_ENGINE ; diff --git a/firmware/controllers/math/engine_math.cpp b/firmware/controllers/math/engine_math.cpp index 451bab28d3..8884454fd0 100644 --- a/firmware/controllers/math/engine_math.cpp +++ b/firmware/controllers/math/engine_math.cpp @@ -448,11 +448,6 @@ void setTimingLoadBin(float from, float to DECLARE_ENGINE_PARAMETER_S) { setTableBin(config->ignitionLoadBins, IGN_LOAD_COUNT, from, to); } -int isInjectionEnabled(engine_configuration_s *engineConfiguration) { - // todo: is this worth a method? should this be inlined? - return engineConfiguration->isInjectionEnabled; -} - /** * this method sets algorithm and ignition table scale */ diff --git a/firmware/controllers/system/efiGpio.h b/firmware/controllers/system/efiGpio.h index a33fb76afc..6de6e02da8 100644 --- a/firmware/controllers/system/efiGpio.h +++ b/firmware/controllers/system/efiGpio.h @@ -154,7 +154,5 @@ void seTurnPinHigh(InjectorOutputPin *output); void seTurnPinLow(InjectorOutputPin *output); void turnPinHigh(NamedOutputPin *output); void turnPinLow(NamedOutputPin *output); -void turnSparkPinHigh(NamedOutputPin *output); -void turnSparkPinLow(NamedOutputPin *output); #endif /* EFIGPIO_H_ */ diff --git a/firmware/controllers/trigger/main_trigger_callback.cpp b/firmware/controllers/trigger/main_trigger_callback.cpp index 5653149215..78b69474cb 100644 --- a/firmware/controllers/trigger/main_trigger_callback.cpp +++ b/firmware/controllers/trigger/main_trigger_callback.cpp @@ -66,17 +66,6 @@ extern bool hasFirmwareErrorFlag; static LocalVersionHolder triggerVersion; static const char *prevOutputName = NULL; -extern engine_pins_s enginePins; - -/** - * In order to archive higher event precision, we are using a hybrid approach - * where we are scheduling events based on the closest trigger event with a time offset. - * - * This queue is using global trigger event index as 'time' - */ -//static EventQueue triggerEventsQueue; -static cyclic_buffer ignitionErrorDetection; - static Logging *logger; // todo: figure out if this even helps? @@ -291,134 +280,6 @@ static ALWAYS_INLINE void handleFuel(const bool limitedFuel, uint32_t trgEventIn } } -void turnSparkPinLow(NamedOutputPin *output) { - turnPinLow(output); -#if EFI_PROD_CODE || defined(__DOXYGEN__) - if (CONFIG(dizzySparkOutputPin) != GPIO_UNASSIGNED) { - turnPinLow(&enginePins.dizzyOutput); - } -#endif /* EFI_PROD_CODE */ -} - -void turnSparkPinHigh(NamedOutputPin *output) { - turnPinHigh(output); -#if EFI_PROD_CODE || defined(__DOXYGEN__) - if (CONFIG(dizzySparkOutputPin) != GPIO_UNASSIGNED) { - turnPinHigh(&enginePins.dizzyOutput); - } -#endif /* EFI_PROD_CODE */ -} - -static ALWAYS_INLINE void handleSparkEvent(bool limitedSpark, uint32_t trgEventIndex, IgnitionEvent *iEvent, - int rpm DECLARE_ENGINE_PARAMETER_S) { - - float dwellMs = ENGINE(engineState.sparkDwell); - if (cisnan(dwellMs) || dwellMs < 0) { - warning(CUSTOM_OBD_45, "invalid dwell: %f at %d", dwellMs, rpm); - return; - } - - floatus_t chargeDelayUs = ENGINE(rpmCalculator.oneDegreeUs) * iEvent->dwellPosition.angleOffset; - int isIgnitionError = chargeDelayUs < 0; - ignitionErrorDetection.add(isIgnitionError); - if (isIgnitionError) { -#if EFI_PROD_CODE || defined(__DOXYGEN__) - scheduleMsg(logger, "Negative spark delay=%f", chargeDelayUs); -#endif - chargeDelayUs = 0; - return; - } - - if (cisnan(dwellMs)) { - firmwareError("NaN in scheduleOutput", dwellMs); - return; - } - - /** - * We are alternating two event lists in order to avoid a potential issue around revolution boundary - * when an event is scheduled within the next revolution. - */ - scheduling_s * sUp = &iEvent->signalTimerUp; - scheduling_s * sDown = &iEvent->signalTimerDown; - - /** - * The start of charge is always within the current trigger event range, so just plain time-based scheduling - */ - if (!limitedSpark) { -#if EFI_UNIT_TEST || defined(__DOXYGEN__) - printf("spark charge delay=%f\r\n", chargeDelayUs); -#endif - /** - * Note how we do not check if spark is limited or not while scheduling 'spark down' - * This way we make sure that coil dwell started while spark was enabled would fire and not burn - * the coil. - */ - scheduleTask("spark up", sUp, chargeDelayUs, (schfunc_t) &turnSparkPinHigh, iEvent->output); - } - /** - * Spark event is often happening during a later trigger event timeframe - * TODO: improve precision - */ - findTriggerPosition(&iEvent->sparkPosition, iEvent->advance PASS_ENGINE_PARAMETER); - - if (iEvent->sparkPosition.eventIndex == trgEventIndex) { - /** - * Spark should be fired before the next trigger event - time-based delay is best precision possible - */ - float timeTillIgnitionUs = ENGINE(rpmCalculator.oneDegreeUs) * iEvent->sparkPosition.angleOffset; - -#if EFI_UNIT_TEST || defined(__DOXYGEN__) - printf("spark delay=%f angle=%f\r\n", timeTillIgnitionUs, iEvent->sparkPosition.angleOffset); -#endif - - scheduleTask("spark1 down", sDown, (int) timeTillIgnitionUs, (schfunc_t) &turnSparkPinLow, iEvent->output); - } else { - /** - * Spark should be scheduled in relation to some future trigger event, this way we get better firing precision - */ - bool isPending = assertNotInList(ENGINE(iHead), iEvent); - if (isPending) - return; - - LL_APPEND(ENGINE(iHead), iEvent); - } -} - -static ALWAYS_INLINE void handleSpark(bool limitedSpark, uint32_t trgEventIndex, int rpm, - IgnitionEventList *list DECLARE_ENGINE_PARAMETER_S) { - if (!isValidRpm(rpm) || !CONFIG(isIgnitionEnabled)) { - // this might happen for instance in case of a single trigger event after a pause - return; - } - /** - * Ignition schedule is defined once per revolution - * See initializeIgnitionActions() - */ - - IgnitionEvent *current, *tmp; - - LL_FOREACH_SAFE(ENGINE(iHead), current, tmp) - { - if (current->sparkPosition.eventIndex == trgEventIndex) { - // time to fire a spark which was scheduled previously - LL_DELETE(ENGINE(iHead), current); - - scheduling_s * sDown = ¤t->signalTimerDown; - - float timeTillIgnitionUs = ENGINE(rpmCalculator.oneDegreeUs) * current->sparkPosition.angleOffset; - scheduleTask("spark 2down", sDown, (int) timeTillIgnitionUs, (schfunc_t) &turnSparkPinLow, current->output); - } - } - -// scheduleSimpleMsg(&logger, "eventId spark ", eventIndex); - for (int i = 0; i < list->size; i++) { - IgnitionEvent *event = &list->elements[i]; - if (event->dwellPosition.eventIndex != trgEventIndex) - continue; - handleSparkEvent(limitedSpark, trgEventIndex, event, rpm PASS_ENGINE_PARAMETER); - } -} - static histogram_s mainLoopHisto; void showMainHistogram(void) { @@ -572,8 +433,6 @@ void mainTriggerCallback(trigger_event_e ckpSignalType, uint32_t trgEventIndex D scheduleIgnitionAndFuelEvents(rpm, revolutionIndex PASS_ENGINE_PARAMETER); } -// triggerEventsQueue.executeAll(getCrankEventCounter()); - /** * For fuel we schedule start of injection based on trigger angle, and then inject for * specified duration of time @@ -619,6 +478,7 @@ static void showMainInfo(Engine *engine) { void initMainEventListener(Logging *sharedLogger, Engine *engine) { logger = sharedLogger; efiAssertVoid(engine!=NULL, "null engine"); + initSparkLogic(logger); #if EFI_PROD_CODE || defined(__DOXYGEN__) addConsoleAction("performanceinfo", showTriggerHistogram); @@ -636,8 +496,4 @@ void initMainEventListener(Logging *sharedLogger, Engine *engine) { addTriggerEventListener(mainTriggerCallback, "main loop", engine); } -int isIgnitionTimingError(void) { - return ignitionErrorDetection.sum(6) > 4; -} - #endif /* EFI_ENGINE_CONTROL */ diff --git a/firmware/controllers/trigger/spark_logic.cpp b/firmware/controllers/trigger/spark_logic.cpp index 27f0ed272f..2c44eef032 100644 --- a/firmware/controllers/trigger/spark_logic.cpp +++ b/firmware/controllers/trigger/spark_logic.cpp @@ -5,6 +5,152 @@ * @author Andrey Belomutskiy, (c) 2012-2016 */ +#include "engine_math.h" +#include "utlist.h" +#include "event_queue.h" +EXTERN_ENGINE; +static cyclic_buffer ignitionErrorDetection; +static Logging *logger; +int isInjectionEnabled(engine_configuration_s *engineConfiguration) { + // todo: is this worth a method? should this be inlined? + return engineConfiguration->isInjectionEnabled; +} + +int isIgnitionTimingError(void) { + return ignitionErrorDetection.sum(6) > 4; +} + +void turnSparkPinLow(NamedOutputPin *output) { + turnPinLow(output); +#if EFI_PROD_CODE || defined(__DOXYGEN__) + if (CONFIG(dizzySparkOutputPin) != GPIO_UNASSIGNED) { + turnPinLow(&enginePins.dizzyOutput); + } +#endif /* EFI_PROD_CODE */ +} + +void turnSparkPinHigh(NamedOutputPin *output) { + turnPinHigh(output); +#if EFI_PROD_CODE || defined(__DOXYGEN__) + if (CONFIG(dizzySparkOutputPin) != GPIO_UNASSIGNED) { + turnPinHigh(&enginePins.dizzyOutput); + } +#endif /* EFI_PROD_CODE */ +} + +static ALWAYS_INLINE void handleSparkEvent(bool limitedSpark, uint32_t trgEventIndex, IgnitionEvent *iEvent, + int rpm DECLARE_ENGINE_PARAMETER_S) { + + float dwellMs = ENGINE(engineState.sparkDwell); + if (cisnan(dwellMs) || dwellMs < 0) { + warning(CUSTOM_OBD_45, "invalid dwell: %f at %d", dwellMs, rpm); + return; + } + + floatus_t chargeDelayUs = ENGINE(rpmCalculator.oneDegreeUs) * iEvent->dwellPosition.angleOffset; + int isIgnitionError = chargeDelayUs < 0; + ignitionErrorDetection.add(isIgnitionError); + if (isIgnitionError) { +#if EFI_PROD_CODE || defined(__DOXYGEN__) + scheduleMsg(logger, "Negative spark delay=%f", chargeDelayUs); +#endif + chargeDelayUs = 0; + return; + } + + if (cisnan(dwellMs)) { + firmwareError("NaN in scheduleOutput", dwellMs); + return; + } + + /** + * We are alternating two event lists in order to avoid a potential issue around revolution boundary + * when an event is scheduled within the next revolution. + */ + scheduling_s * sUp = &iEvent->signalTimerUp; + scheduling_s * sDown = &iEvent->signalTimerDown; + + /** + * The start of charge is always within the current trigger event range, so just plain time-based scheduling + */ + if (!limitedSpark) { +#if EFI_UNIT_TEST || defined(__DOXYGEN__) + printf("spark charge delay=%f\r\n", chargeDelayUs); +#endif + /** + * Note how we do not check if spark is limited or not while scheduling 'spark down' + * This way we make sure that coil dwell started while spark was enabled would fire and not burn + * the coil. + */ + scheduleTask("spark up", sUp, chargeDelayUs, (schfunc_t) &turnSparkPinHigh, iEvent->output); + } + /** + * Spark event is often happening during a later trigger event timeframe + * TODO: improve precision + */ + findTriggerPosition(&iEvent->sparkPosition, iEvent->advance PASS_ENGINE_PARAMETER); + + if (iEvent->sparkPosition.eventIndex == trgEventIndex) { + /** + * Spark should be fired before the next trigger event - time-based delay is best precision possible + */ + float timeTillIgnitionUs = ENGINE(rpmCalculator.oneDegreeUs) * iEvent->sparkPosition.angleOffset; + +#if EFI_UNIT_TEST || defined(__DOXYGEN__) + printf("spark delay=%f angle=%f\r\n", timeTillIgnitionUs, iEvent->sparkPosition.angleOffset); +#endif + + scheduleTask("spark1 down", sDown, (int) timeTillIgnitionUs, (schfunc_t) &turnSparkPinLow, iEvent->output); + } else { + /** + * Spark should be scheduled in relation to some future trigger event, this way we get better firing precision + */ + bool isPending = assertNotInList(ENGINE(iHead), iEvent); + if (isPending) + return; + + LL_APPEND(ENGINE(iHead), iEvent); + } +} + +void handleSpark(bool limitedSpark, uint32_t trgEventIndex, int rpm, + IgnitionEventList *list DECLARE_ENGINE_PARAMETER_S) { + if (!isValidRpm(rpm) || !CONFIG(isIgnitionEnabled)) { + // this might happen for instance in case of a single trigger event after a pause + return; + } + /** + * Ignition schedule is defined once per revolution + * See initializeIgnitionActions() + */ + + IgnitionEvent *current, *tmp; + + LL_FOREACH_SAFE(ENGINE(iHead), current, tmp) + { + if (current->sparkPosition.eventIndex == trgEventIndex) { + // time to fire a spark which was scheduled previously + LL_DELETE(ENGINE(iHead), current); + + scheduling_s * sDown = ¤t->signalTimerDown; + + float timeTillIgnitionUs = ENGINE(rpmCalculator.oneDegreeUs) * current->sparkPosition.angleOffset; + scheduleTask("spark 2down", sDown, (int) timeTillIgnitionUs, (schfunc_t) &turnSparkPinLow, current->output); + } + } + +// scheduleSimpleMsg(&logger, "eventId spark ", eventIndex); + for (int i = 0; i < list->size; i++) { + IgnitionEvent *event = &list->elements[i]; + if (event->dwellPosition.eventIndex != trgEventIndex) + continue; + handleSparkEvent(limitedSpark, trgEventIndex, event, rpm PASS_ENGINE_PARAMETER); + } +} + +void initSparkLogic(Logging *sharedLogger) { + logger = sharedLogger; +} diff --git a/firmware/controllers/trigger/spark_logic.h b/firmware/controllers/trigger/spark_logic.h index aba8b1bf07..4af1e0e083 100644 --- a/firmware/controllers/trigger/spark_logic.h +++ b/firmware/controllers/trigger/spark_logic.h @@ -11,5 +11,10 @@ #include "engine.h" int isInjectionEnabled(engine_configuration_s *engineConfiguration); +void handleSpark(bool limitedSpark, uint32_t trgEventIndex, int rpm, + IgnitionEventList *list DECLARE_ENGINE_PARAMETER_S); +void initSparkLogic(Logging *sharedLogger); +void turnSparkPinHigh(NamedOutputPin *output); +void turnSparkPinLow(NamedOutputPin *output); #endif /* CONTROLLERS_TRIGGER_SPARK_LOGIC_H_ */ diff --git a/firmware/controllers/trigger/trigger_decoder.cpp b/firmware/controllers/trigger/trigger_decoder.cpp index 3caf1c2fe5..40529c2be7 100644 --- a/firmware/controllers/trigger/trigger_decoder.cpp +++ b/firmware/controllers/trigger/trigger_decoder.cpp @@ -49,7 +49,6 @@ EXTERN_ENGINE ; -extern engine_pins_s enginePins; static cyclic_buffer errorDetection; static bool isInitializingTrigger = false; // #286 miata NA config - sync error on startup diff --git a/firmware/global.h b/firmware/global.h index 4cb589a188..f6570b03f7 100644 --- a/firmware/global.h +++ b/firmware/global.h @@ -90,7 +90,8 @@ typedef VirtualTimer virtual_timer_t; extern persistent_config_container_s persistentState; \ extern Engine _engine; \ extern persistent_config_s *config; \ - extern engine_configuration2_s * engineConfiguration2 + extern engine_configuration2_s * engineConfiguration2; \ + extern engine_pins_s enginePins #define DECLARE_ENGINE_PARAMETER_F void #define DECLARE_ENGINE_PARAMETER_S diff --git a/firmware/hw_layer/hardware.cpp b/firmware/hw_layer/hardware.cpp index 5b58c0c32d..a3cb4d2118 100644 --- a/firmware/hw_layer/hardware.cpp +++ b/firmware/hw_layer/hardware.cpp @@ -52,7 +52,6 @@ EXTERN_ENGINE ; extern bool hasFirmwareErrorFlag; extern engine_configuration_s activeConfiguration; -extern engine_pins_s enginePins; static Mutex spiMtx; diff --git a/unit_tests/Makefile b/unit_tests/Makefile index a823658ad0..470ed3d896 100644 --- a/unit_tests/Makefile +++ b/unit_tests/Makefile @@ -105,6 +105,7 @@ CPPSRC = $(UTILSRC_CPP) \ $(SYSTEMSRC_CPP) \ $(PROJECT_DIR)/controllers/trigger/trigger_central.cpp \ $(PROJECT_DIR)/controllers/trigger/rpm_calculator.cpp \ + $(PROJECT_DIR)/controllers/trigger/spark_logic.cpp \ $(PROJECT_DIR)/controllers/trigger/main_trigger_callback.cpp \ main.cpp diff --git a/unit_tests/global.h b/unit_tests/global.h index 25913b3222..dfd213d13b 100644 --- a/unit_tests/global.h +++ b/unit_tests/global.h @@ -33,7 +33,7 @@ typedef int bool_t; #define CCM_OPTIONAL -#define EXTERN_ENGINE +#define EXTERN_ENGINE extern engine_pins_s enginePins #ifdef __cplusplus class Engine; diff --git a/unit_tests/test_trigger_decoder.cpp b/unit_tests/test_trigger_decoder.cpp index cd8567d23f..19dce8c1ac 100644 --- a/unit_tests/test_trigger_decoder.cpp +++ b/unit_tests/test_trigger_decoder.cpp @@ -29,6 +29,7 @@ #include "engine_test_helper.h" #include "speed_density.h" #include "fuel_math.h" +#include "spark_logic.h" extern int timeNow; extern float unitTestValue; diff --git a/win32_functional_tests/simulator/global.h b/win32_functional_tests/simulator/global.h index 88440ef3cd..4ddbb242cb 100644 --- a/win32_functional_tests/simulator/global.h +++ b/win32_functional_tests/simulator/global.h @@ -99,7 +99,8 @@ void applyNewConfiguration(void); extern board_configuration_s *boardConfiguration; \ extern persistent_config_s *config; \ extern persistent_config_container_s persistentState; \ - extern engine_configuration2_s * engineConfiguration2 + extern engine_configuration2_s * engineConfiguration2; \ + extern engine_pins_s enginePins #define DECLARE_ENGINE_PARAMETER_F void #define DECLARE_ENGINE_PARAMETER_S