diff --git a/firmware/controllers/algo/ec2.h b/firmware/controllers/algo/ec2.h index adb82a8a5a..bfcf2f207e 100644 --- a/firmware/controllers/algo/ec2.h +++ b/firmware/controllers/algo/ec2.h @@ -26,7 +26,7 @@ public: void addFuelEvents(trigger_shape_s *s, injection_mode_e mode DECLARE_ENGINE_PARAMETER_S); - void registerInjectionEvent(trigger_shape_s *s, + void registerInjectionEvent( io_pin_e pin, float angle, bool_t isSimultanious DECLARE_ENGINE_PARAMETER_S); uint8_t hasEvents[PWM_PHASE_MAX_COUNT]; diff --git a/firmware/controllers/engine_controller.cpp b/firmware/controllers/engine_controller.cpp index 89ccca7a6a..2f22f954f5 100644 --- a/firmware/controllers/engine_controller.cpp +++ b/firmware/controllers/engine_controller.cpp @@ -94,7 +94,7 @@ engine_configuration2_s * engineConfiguration2 = &ec2; /** * todo: this should probably become 'static', i.e. private, and propagated around explicitly? */ -static Engine _engine; +Engine _engine; Engine * engine = &_engine; #endif diff --git a/firmware/controllers/math/engine_math.cpp b/firmware/controllers/math/engine_math.cpp index 7136d77345..7bcfa22bf3 100644 --- a/firmware/controllers/math/engine_math.cpp +++ b/firmware/controllers/math/engine_math.cpp @@ -33,6 +33,8 @@ EXTERN_ENGINE ; +extern OutputPin outputs[IO_PIN_COUNT]; + /* * default Volumetric Efficiency */ @@ -88,7 +90,7 @@ void setSingleCoilDwell(engine_configuration_s *engineConfiguration) { OutputSignalList injectonSignals CCM_OPTIONAL; -static void registerSparkEvent(trigger_shape_s * s, IgnitionEventList *list, io_pin_e pin, float localAdvance, +static void registerSparkEvent(IgnitionEventList *list, io_pin_e pin, float localAdvance, float dwell DECLARE_ENGINE_PARAMETER_S) { IgnitionEvent *event = list->getNextActuatorEvent(); @@ -103,7 +105,7 @@ static void registerSparkEvent(trigger_shape_s * s, IgnitionEventList *list, io_ event->advance = localAdvance; - findTriggerPosition(s, &event->dwellPosition, localAdvance - dwell PASS_ENGINE_PARAMETER); + findTriggerPosition(&event->dwellPosition, localAdvance - dwell PASS_ENGINE_PARAMETER); } void initializeIgnitionActions(float advance, float dwellAngle, @@ -113,40 +115,38 @@ void initializeIgnitionActions(float advance, float dwellAngle, list->resetEventList(); - switch (engineConfiguration->ignitionMode) { + switch (CONFIG(ignitionMode)) { case IM_ONE_COIL: - for (int i = 0; i < engineConfiguration->cylindersCount; i++) { + for (int i = 0; i < CONFIG(cylindersCount); i++) { // todo: extract method float localAdvance = advance - + (float) engineConfiguration->engineCycle * i / engineConfiguration->cylindersCount; + + (float) CONFIG(engineCycle) * i / CONFIG(cylindersCount); - registerSparkEvent(&engine->triggerShape, list, SPARKOUT_1_OUTPUT, localAdvance, + registerSparkEvent(list, SPARKOUT_1_OUTPUT, localAdvance, dwellAngle PASS_ENGINE_PARAMETER); } break; case IM_WASTED_SPARK: - for (int i = 0; i < engineConfiguration->cylindersCount; i++) { + for (int i = 0; i < CONFIG(cylindersCount); i++) { float localAdvance = advance - + (float) engineConfiguration->engineCycle * i / engineConfiguration->cylindersCount; + + (float) CONFIG(engineCycle) * i / CONFIG(cylindersCount); - int wastedIndex = i % (engineConfiguration->cylindersCount / 2); + int wastedIndex = i % (CONFIG(cylindersCount) / 2); - int id = getCylinderId(engineConfiguration->firingOrder, wastedIndex) - 1; + int id = getCylinderId(CONFIG(firingOrder), wastedIndex) - 1; io_pin_e ioPin = (io_pin_e) (SPARKOUT_1_OUTPUT + id); - registerSparkEvent(&engine->triggerShape, list, ioPin, localAdvance, - dwellAngle PASS_ENGINE_PARAMETER); - + registerSparkEvent(list, ioPin, localAdvance, dwellAngle PASS_ENGINE_PARAMETER); } break; case IM_INDIVIDUAL_COILS: - for (int i = 0; i < engineConfiguration->cylindersCount; i++) { + for (int i = 0; i < CONFIG(cylindersCount); i++) { float localAdvance = advance - + (float) engineConfiguration->engineCycle * i / engineConfiguration->cylindersCount; + + (float) CONFIG(engineCycle) * i / CONFIG(cylindersCount); - io_pin_e pin = (io_pin_e) ((int) SPARKOUT_1_OUTPUT + getCylinderId(engineConfiguration->firingOrder, i) - 1); - registerSparkEvent(&engine->triggerShape, list, pin, localAdvance, + io_pin_e pin = (io_pin_e) ((int) SPARKOUT_1_OUTPUT + getCylinderId(CONFIG(firingOrder), i) - 1); + registerSparkEvent(list, pin, localAdvance, dwellAngle PASS_ENGINE_PARAMETER); } break; @@ -156,7 +156,7 @@ void initializeIgnitionActions(float advance, float dwellAngle, } } -void FuelSchedule::registerInjectionEvent(trigger_shape_s *s, io_pin_e pin, float angle, +void FuelSchedule::registerInjectionEvent(io_pin_e pin, float angle, bool_t isSimultanious DECLARE_ENGINE_PARAMETER_S) { ActuatorEventList *list = &events; @@ -170,7 +170,7 @@ void FuelSchedule::registerInjectionEvent(trigger_shape_s *s, io_pin_e pin, floa ev->isSimultanious = isSimultanious; - efiAssertVoid(s->getSize() > 0, "uninitialized trigger_shape_s"); + efiAssertVoid(TRIGGER_SHAPE(getSize()) > 0, "uninitialized trigger_shape_s"); if (ev == NULL) { // error already reported @@ -178,7 +178,7 @@ void FuelSchedule::registerInjectionEvent(trigger_shape_s *s, io_pin_e pin, floa } ev->actuator = actuator; - findTriggerPosition(s, &ev->position, angle PASS_ENGINE_PARAMETER); + findTriggerPosition(&ev->position, angle PASS_ENGINE_PARAMETER); hasEvents[ev->position.eventIndex] = true; } @@ -203,7 +203,7 @@ void FuelSchedule::addFuelEvents(trigger_shape_s *s, injection_mode_e mode DECLA io_pin_e pin = INJECTOR_PIN_BY_INDEX(getCylinderId(engineConfiguration->firingOrder, i) - 1); float angle = baseAngle + (float) engineConfiguration->engineCycle * i / engineConfiguration->cylindersCount; - registerInjectionEvent(s, pin, angle, false PASS_ENGINE_PARAMETER); + registerInjectionEvent(pin, angle, false PASS_ENGINE_PARAMETER); } break; case IM_SIMULTANEOUS: @@ -215,7 +215,7 @@ void FuelSchedule::addFuelEvents(trigger_shape_s *s, injection_mode_e mode DECLA * We do not need injector pin here because we will control all injectors * simultaniously */ - registerInjectionEvent(s, IO_INVALID, angle, true PASS_ENGINE_PARAMETER); + registerInjectionEvent(IO_INVALID, angle, true PASS_ENGINE_PARAMETER); } break; case IM_BATCH: @@ -224,13 +224,13 @@ void FuelSchedule::addFuelEvents(trigger_shape_s *s, injection_mode_e mode DECLA io_pin_e pin = INJECTOR_PIN_BY_INDEX(index); float angle = baseAngle + i * (float) engineConfiguration->engineCycle / engineConfiguration->cylindersCount; - registerInjectionEvent(s, pin, angle, false PASS_ENGINE_PARAMETER); + registerInjectionEvent(pin, angle, false PASS_ENGINE_PARAMETER); /** * also fire the 2nd half of the injectors so that we can implement a batch mode on individual wires */ pin = INJECTOR_PIN_BY_INDEX(index + (engineConfiguration->cylindersCount / 2)); - registerInjectionEvent(s, pin, angle, false PASS_ENGINE_PARAMETER); + registerInjectionEvent(pin, angle, false PASS_ENGINE_PARAMETER); } break; default: @@ -256,21 +256,16 @@ float getSparkDwellMsT(int rpm DECLARE_ENGINE_PARAMETER_S) { return interpolate2d(rpm, engineConfiguration->sparkDwellBins, engineConfiguration->sparkDwell, DWELL_CURVE_SIZE); } -/** - * Trigger event count equals engine cycle event count if we have a cam sensor. - * Two trigger cycles make one engine cycle in case of a four stroke engine If we only have a cranksensor. - */ -int getEngineCycleEventCount2(operation_mode_e mode, trigger_shape_s * s) { - return mode == FOUR_STROKE_CAM_SENSOR ? s->getSize() : 2 * s->getSize(); -} - -void findTriggerPosition(trigger_shape_s * s, event_trigger_position_s *position, +void findTriggerPosition(event_trigger_position_s *position, float angleOffset DECLARE_ENGINE_PARAMETER_S) { - angleOffset += engineConfiguration->globalTriggerAngleOffset; + angleOffset += CONFIG(globalTriggerAngleOffset); fixAngle(angleOffset); - int engineCycleEventCount = getEngineCycleEventCount2(getOperationMode(engineConfiguration), s); + /** + * Here we rely on this to be pre-calculated, that's a performance optimization + */ + int engineCycleEventCount = engine->engineCycleEventCount; efiAssertVoid(engineCycleEventCount > 0, "engineCycleEventCount"); @@ -282,25 +277,23 @@ void findTriggerPosition(trigger_shape_s * s, event_trigger_position_s *position * Let's find the last trigger angle which is less or equal to the desired angle * todo: extract binary search as template method? */ + float eventAngle; while (true) { middle = (left + right) / 2; + eventAngle = TRIGGER_SHAPE(eventAngles[middle]); if (middle == left) { break; } - - if (angleOffset < s->eventAngles[middle]) { + if (angleOffset < eventAngle) { right = middle; - } else if (angleOffset > s->eventAngles[middle]) { + } else if (angleOffset > eventAngle) { left = middle; } else { break; } - } - float eventAngle = s->eventAngles[middle]; - if (angleOffset < eventAngle) { firmwareError("angle constraint violation in registerActuatorEventExt(): %f/%f", angleOffset, eventAngle); return; diff --git a/firmware/controllers/math/engine_math.h b/firmware/controllers/math/engine_math.h index a1f396e337..79dfee1f80 100644 --- a/firmware/controllers/math/engine_math.h +++ b/firmware/controllers/math/engine_math.h @@ -19,7 +19,7 @@ #define INJECTOR_PIN_BY_INDEX(index) (io_pin_e) ((int) INJECTOR_1_OUTPUT + (index)) -void findTriggerPosition(trigger_shape_s * s, +void findTriggerPosition( event_trigger_position_s *position, float angleOffset DECLARE_ENGINE_PARAMETER_S); int isInjectionEnabled(engine_configuration_s *engineConfiguration); diff --git a/firmware/controllers/system/efiGpio.cpp b/firmware/controllers/system/efiGpio.cpp index 22600225c9..0035fa509d 100644 --- a/firmware/controllers/system/efiGpio.cpp +++ b/firmware/controllers/system/efiGpio.cpp @@ -99,11 +99,3 @@ void setOutputPinValue(io_pin_e pin, int logicValue) { doSetOutputPinValue(pin, logicValue); } -bool isPinAssigned(io_pin_e pin) { -#if EFI_PROD_CODE - return outputs[pin].port != GPIO_NULL; -#else - return true; -#endif -} - diff --git a/firmware/controllers/system/efiGpio.h b/firmware/controllers/system/efiGpio.h index 736eee8ad8..4e63d176e8 100644 --- a/firmware/controllers/system/efiGpio.h +++ b/firmware/controllers/system/efiGpio.h @@ -76,9 +76,13 @@ extern "C" int getOutputPinValue(io_pin_e pin); void setOutputPinValue(io_pin_e pin, int logicValue); -bool isPinAssigned(io_pin_e pin); const char *getPinName(io_pin_e io_pin); +#if EFI_PROD_CODE + #define isPinAssigned(pin) (outputs[(pin)].port != GPIO_NULL) +#else + #define isPinAssigned(pin) (true) +#endif #if EFI_PROD_CODE #define doSetOutputPinValue(pin, logicValue) { \ diff --git a/firmware/controllers/trigger/main_trigger_callback.cpp b/firmware/controllers/trigger/main_trigger_callback.cpp index d9a21af253..7394d58818 100644 --- a/firmware/controllers/trigger/main_trigger_callback.cpp +++ b/firmware/controllers/trigger/main_trigger_callback.cpp @@ -219,8 +219,7 @@ static ALWAYS_INLINE void handleSparkEvent(uint32_t eventIndex, IgnitionEvent *i * TODO: improve precision */ - findTriggerPosition(&engine->triggerShape, &iEvent->sparkPosition, - iEvent->advance PASS_ENGINE_PARAMETER); + findTriggerPosition(&iEvent->sparkPosition, iEvent->advance PASS_ENGINE_PARAMETER); if (iEvent->sparkPosition.eventIndex == eventIndex) { /** diff --git a/firmware/controllers/trigger/trigger_structure.cpp b/firmware/controllers/trigger/trigger_structure.cpp index ede13bb0f9..322f0be6e4 100644 --- a/firmware/controllers/trigger/trigger_structure.cpp +++ b/firmware/controllers/trigger/trigger_structure.cpp @@ -50,9 +50,6 @@ int trigger_shape_s::getTriggerShapeSynchPointIndex() { return triggerShapeSynchPointIndex; } -// todo: clean-up! -int getEngineCycleEventCount2(operation_mode_e mode, trigger_shape_s * s); - void trigger_shape_s::calculateTriggerSynchPoint(engine_configuration_s *engineConfiguration, Engine *engine) { trigger_config_s const*triggerConfig = &engineConfiguration->triggerConfig; setTriggerShapeSynchPointIndex(engineConfiguration, findTriggerZeroEventIndex(this, triggerConfig), engine); @@ -61,16 +58,16 @@ void trigger_shape_s::calculateTriggerSynchPoint(engine_configuration_s *engineC void trigger_shape_s::setTriggerShapeSynchPointIndex(engine_configuration_s *engineConfiguration, int triggerShapeSynchPointIndex, Engine *engine) { this->triggerShapeSynchPointIndex = triggerShapeSynchPointIndex; - int engineCycleEventCount = getEngineCycleEventCount2(operationMode, this); + engine->engineCycleEventCount = getLength(); float firstAngle = getAngle(triggerShapeSynchPointIndex); - for (int i = 0; i < engineCycleEventCount; i++) { + for (int i = 0; i < engine->engineCycleEventCount; i++) { if (i == 0) { // explicit check for zero to avoid issues where logical zero is not exactly zero due to float nature eventAngles[i] = 0; } else { - float angle = getAngle((triggerShapeSynchPointIndex + i) % engineCycleEventCount) - firstAngle; + float angle = getAngle((triggerShapeSynchPointIndex + i) % engine->engineCycleEventCount) - firstAngle; fixAngle(angle); eventAngles[i] = angle; } @@ -175,6 +172,10 @@ void TriggerState::clear() { current_index = 0; } +/** + * Trigger event count equals engine cycle event count if we have a cam sensor. + * Two trigger cycles make one engine cycle in case of a four stroke engine If we only have a cranksensor. + */ uint32_t trigger_shape_s::getLength() const { return operationMode == FOUR_STROKE_CAM_SENSOR ? getSize() : 2 * getSize(); } diff --git a/firmware/global.h b/firmware/global.h index d129cd7111..78ea031bc0 100644 --- a/firmware/global.h +++ b/firmware/global.h @@ -72,7 +72,8 @@ typedef Thread thread_t; #define EXTERN_ENGINE extern Engine *engine; \ extern engine_configuration_s *engineConfiguration; \ extern board_configuration_s *boardConfiguration; \ - extern persistent_config_container_s persistentState + extern persistent_config_container_s persistentState; \ + extern Engine _engine #define DECLARE_ENGINE_PARAMETER_F void #define DECLARE_ENGINE_PARAMETER_S @@ -84,6 +85,6 @@ typedef Thread thread_t; * optimization */ #define CONFIG(x) persistentState.persistentConfiguration.engineConfiguration.x - +#define TRIGGER_SHAPE(x) _engine.triggerShape.x #endif /* GLOBAL_H_ */ diff --git a/unit_tests/global.h b/unit_tests/global.h index 09d57329cb..f040ca28dd 100644 --- a/unit_tests/global.h +++ b/unit_tests/global.h @@ -46,5 +46,6 @@ class Engine; #define PASS_ENGINE_PARAMETER , engine, engineConfiguration #define CONFIG(x) engineConfiguration->x +#define TRIGGER_SHAPE(x) engine->triggerShape.x #endif /* GLOBAL_H_ */ diff --git a/unit_tests/test_fuel_map.cpp b/unit_tests/test_fuel_map.cpp index 8d159ae3a8..f30a0045c8 100644 --- a/unit_tests/test_fuel_map.cpp +++ b/unit_tests/test_fuel_map.cpp @@ -179,14 +179,14 @@ void testAngleResolver(void) { ae.resetEventList(); printf("*************************************************** testAngleResolver 0\r\n"); - findTriggerPosition(ts, &ae.getNextActuatorEvent()->position, 53 - 175 PASS_ENGINE_PARAMETER); + findTriggerPosition(&ae.getNextActuatorEvent()->position, 53 - 175 PASS_ENGINE_PARAMETER); assertEqualsM("size", 1, ae.size); assertEquals(1, ae.events[0].position.eventIndex); assertEquals(3.1588, ae.events[0].position.angleOffset); printf("*************************************************** testAngleResolver 2\r\n"); ae.resetEventList(); - findTriggerPosition(ts, &ae.getNextActuatorEvent()->position, 51 + 180 - 175 PASS_ENGINE_PARAMETER); + findTriggerPosition(&ae.getNextActuatorEvent()->position, 51 + 180 - 175 PASS_ENGINE_PARAMETER); assertEquals(3, ae.events[0].position.eventIndex); assertEquals(2.955, ae.events[0].position.angleOffset); } diff --git a/unit_tests/test_trigger_decoder.cpp b/unit_tests/test_trigger_decoder.cpp index 6c599ef4f5..de50950375 100644 --- a/unit_tests/test_trigger_decoder.cpp +++ b/unit_tests/test_trigger_decoder.cpp @@ -123,13 +123,13 @@ static void test1995FordInline6TriggerDecoder(void) { event_trigger_position_s position; assertEqualsM("globalTriggerAngleOffset", 0, engineConfiguration->globalTriggerAngleOffset); - findTriggerPosition(shape, &position, 0 PASS_ENGINE_PARAMETER); + findTriggerPosition(&position, 0 PASS_ENGINE_PARAMETER); assertTriggerPosition(&position, 0, 0); - findTriggerPosition(shape, &position, 200 PASS_ENGINE_PARAMETER); + findTriggerPosition(&position, 200 PASS_ENGINE_PARAMETER); assertTriggerPosition(&position, 3, 20); - findTriggerPosition(shape, &position, 360 PASS_ENGINE_PARAMETER); + findTriggerPosition(&position, 360 PASS_ENGINE_PARAMETER); assertTriggerPosition(&position, 6, 0); @@ -251,39 +251,39 @@ void testMazdaMianaNbDecoder(void) { event_trigger_position_s position; assertEqualsM("globalTriggerAngleOffset", 276, ec->globalTriggerAngleOffset); - findTriggerPosition(shape, &position, 0 PASS_ENGINE_PARAMETER); + findTriggerPosition(&position, 0 PASS_ENGINE_PARAMETER); assertTriggerPosition(&position, 7, 46); - findTriggerPosition(shape, &position, 180 PASS_ENGINE_PARAMETER); + findTriggerPosition(&position, 180 PASS_ENGINE_PARAMETER); assertTriggerPosition(&position, 13, 46); - findTriggerPosition(shape, &position, 360 PASS_ENGINE_PARAMETER); + findTriggerPosition(&position, 360 PASS_ENGINE_PARAMETER); assertTriggerPosition(&position, 17, 46); - findTriggerPosition(shape, &position, 444 PASS_ENGINE_PARAMETER); + findTriggerPosition(&position, 444 PASS_ENGINE_PARAMETER); assertTriggerPosition(&position, 0, 0); - findTriggerPosition(shape, &position, 444.1 PASS_ENGINE_PARAMETER); + findTriggerPosition(&position, 444.1 PASS_ENGINE_PARAMETER); assertTriggerPosition(&position, 0, 0.1); - findTriggerPosition(shape, &position, 445 PASS_ENGINE_PARAMETER); + findTriggerPosition(&position, 445 PASS_ENGINE_PARAMETER); assertTriggerPosition(&position, 0, 1); - findTriggerPosition(shape, &position, 494 PASS_ENGINE_PARAMETER); + findTriggerPosition(&position, 494 PASS_ENGINE_PARAMETER); assertTriggerPosition(&position, 3, 0); - findTriggerPosition(shape, &position, 719 PASS_ENGINE_PARAMETER); + findTriggerPosition(&position, 719 PASS_ENGINE_PARAMETER); assertTriggerPosition(&position, 7, 45); ec->globalTriggerAngleOffset = 0; - findTriggerPosition(shape, &position, 0 PASS_ENGINE_PARAMETER); + findTriggerPosition(&position, 0 PASS_ENGINE_PARAMETER); assertTriggerPosition(&position, 0, 0); ec->globalTriggerAngleOffset = 10; - findTriggerPosition(shape, &position, 0 PASS_ENGINE_PARAMETER); + findTriggerPosition(&position, 0 PASS_ENGINE_PARAMETER); assertTriggerPosition(&position, 0, 10); - findTriggerPosition(shape, &position, -10 PASS_ENGINE_PARAMETER); + findTriggerPosition(&position, -10 PASS_ENGINE_PARAMETER); assertTriggerPosition(&position, 0, 0); } diff --git a/win32_functional_tests/simulator/global.h b/win32_functional_tests/simulator/global.h index 269bdcb450..080f3f076a 100644 --- a/win32_functional_tests/simulator/global.h +++ b/win32_functional_tests/simulator/global.h @@ -99,4 +99,4 @@ typedef EventListener event_listener_t; #define PASS_ENGINE_PARAMETER #define CONFIG(x) persistentState.persistentConfiguration.engineConfiguration.x - +#define TRIGGER_SHAPE(x) engine->triggerShape.x