diff --git a/firmware/controllers/algo/event_registry.h b/firmware/controllers/algo/event_registry.h index cecae6d4bb..9b1616e8b8 100644 --- a/firmware/controllers/algo/event_registry.h +++ b/firmware/controllers/algo/event_registry.h @@ -14,6 +14,7 @@ #include "trigger_structure.h" struct AngleBasedEventOld; +struct AngleBasedEventNew; struct AngleBasedEventBase { scheduling_s scheduling; @@ -28,7 +29,10 @@ struct AngleBasedEventBase { virtual bool shouldSchedule(uint32_t trgEventIndex, float currentPhase, float nextPhase) const = 0; virtual float getAngleFromNow(float currentPhase) const = 0; - virtual AngleBasedEventOld* asOld() { return nullptr; } + // Virtual functions to get these as old/new variants, since we don't have RTTI for dynamic casts to work + // (this is poor man's RTTI) + virtual const AngleBasedEventOld* asOld() const { return nullptr; } + virtual const AngleBasedEventNew* asNew() const { return nullptr; } }; /** @@ -50,7 +54,7 @@ struct AngleBasedEventOld : public AngleBasedEventBase { bool shouldSchedule(uint32_t trgEventIndex, float currentPhase, float nextPhase) const override; float getAngleFromNow(float currentPhase) const override; - AngleBasedEventOld* asOld() override { return this; } + virtual const AngleBasedEventOld* asOld() const override { return this; } }; struct AngleBasedEventNew : public AngleBasedEventBase { @@ -60,6 +64,8 @@ struct AngleBasedEventNew : public AngleBasedEventBase { bool shouldSchedule(uint32_t trgEventIndex, float currentPhase, float nextPhase) const override; bool shouldSchedule(float currentPhase, float nextPhase) const; float getAngleFromNow(float currentPhase) const override; + + virtual const AngleBasedEventNew* asNew() const override { return this; } }; #define MAX_OUTPUTS_FOR_IGNITION 2 @@ -119,8 +125,8 @@ public: int valveIndex; angle_t extra; - AngleBasedEventOld open; - AngleBasedEventOld close; + AngleBasedEventNew open; + AngleBasedEventNew close; }; diff --git a/firmware/controllers/engine_cycle/high_pressure_fuel_pump.h b/firmware/controllers/engine_cycle/high_pressure_fuel_pump.h index 97b09ae5ba..d7260464ca 100644 --- a/firmware/controllers/engine_cycle/high_pressure_fuel_pump.h +++ b/firmware/controllers/engine_cycle/high_pressure_fuel_pump.h @@ -84,7 +84,7 @@ public: #if !EFI_UNIT_TEST private: #endif // EFI_UNIT_TEST - AngleBasedEventOld m_event; + AngleBasedEventNew m_event; HpfpQuantity m_quantity; HpfpLobe m_lobe; diff --git a/unit_tests/engine_test_helper.cpp b/unit_tests/engine_test_helper.cpp index d0f6916074..5fb019c34b 100644 --- a/unit_tests/engine_test_helper.cpp +++ b/unit_tests/engine_test_helper.cpp @@ -308,7 +308,7 @@ scheduling_s * EngineTestHelper::assertEvent5(const char *msg, int index, void * return event; } -AngleBasedEventBase * EngineTestHelper::assertTriggerEvent(const char *msg, +const AngleBasedEventBase * EngineTestHelper::assertTriggerEvent(const char *msg, int index, AngleBasedEventBase *expected, void *callback, int triggerEventIndex, angle_t angleOffsetFromTriggerEvent) { @@ -324,6 +324,23 @@ AngleBasedEventBase * EngineTestHelper::assertTriggerEvent(const char *msg, return event; } +const AngleBasedEventBase * EngineTestHelper::assertTriggerEvent(const char *msg, + int index, AngleBasedEventBase *expected, + void *callback, + angle_t enginePhase) { + AngleBasedEventBase * event2 = + engine.module()->getElementAtIndexForUnitTest(index); + + auto event = event2->asNew(); + + if (callback) { + assertEqualsM4(msg, " callback up/down", (void*)event->action.getCallback() == (void*) callback, 1); + } + + assertEqualsM4(msg, " angle", enginePhase, event->enginePhase); + return event; +} + scheduling_s * EngineTestHelper::assertScheduling(const char *msg, int index, scheduling_s *expected, void *callback, efitimeus_t expectedTimestamp) { scheduling_s * actual = assertEvent5(msg, index, callback, expectedTimestamp); return actual; diff --git a/unit_tests/engine_test_helper.h b/unit_tests/engine_test_helper.h index ecddd57b89..6836e5847f 100644 --- a/unit_tests/engine_test_helper.h +++ b/unit_tests/engine_test_helper.h @@ -84,7 +84,8 @@ public: scheduling_s * assertEvent5(const char *msg, int index, void *callback, efitimeus_t expectedTimestamp); scheduling_s * assertScheduling(const char *msg, int index, scheduling_s *expected, void *callback, efitimeus_t expectedTimestamp); - AngleBasedEventBase * assertTriggerEvent(const char *msg, int index, AngleBasedEventBase *expected, void *callback, int triggerEventIndex, angle_t angleOffsetFromTriggerEvent); + const AngleBasedEventBase* assertTriggerEvent(const char *msg, int index, AngleBasedEventBase *expected, void *callback, int triggerEventIndex, angle_t angleOffsetFromTriggerEvent); + const AngleBasedEventBase* assertTriggerEvent(const char *msg, int index, AngleBasedEventBase *expected, void *callback, angle_t enginePhase); void assertEvent(const char *msg, int index, void *callback, efitimeus_t momentX, InjectionEvent *event); void assertInjectorUpEvent(const char *msg, int eventIndex, efitimeus_t momentX, long injectorIndex); diff --git a/unit_tests/tests/actuators/test_aux_valves.cpp b/unit_tests/tests/actuators/test_aux_valves.cpp index 5c29e6c862..af324672d8 100644 --- a/unit_tests/tests/actuators/test_aux_valves.cpp +++ b/unit_tests/tests/actuators/test_aux_valves.cpp @@ -14,15 +14,30 @@ TEST(Actuators, AuxValves) { EngineTestHelper eth(NISSAN_PRIMERA); - engine->needTdcCallback = false; + // Engine must be "spinning" for scheduleByAngle to work + engine->rpmCalculator.setRpmValue(1000); - setupSimpleTestEngineWithMafAndTT_ONE_trigger(ð, IM_SEQUENTIAL); - engineConfiguration->isInjectionEnabled = false; + eth.assertTriggerEvent("a0", 0, &engine->auxValves[0][0].open, (void*)&auxPlainPinTurnOn, 0); + eth.assertTriggerEvent("a1", 1, &engine->auxValves[0][1].open, (void*)&auxPlainPinTurnOn, 360); + eth.assertTriggerEvent("a2", 2, &engine->auxValves[1][0].open, (void*)&auxPlainPinTurnOn, 180); + eth.assertTriggerEvent("a3", 3, &engine->auxValves[1][1].open, (void*)&auxPlainPinTurnOn, 540); - eth.fireTriggerEvents2(2 /* count */ , 600 /* ms */); - ASSERT_EQ( 100, round(Sensor::getOrZero(SensorType::Rpm))) << "spinning-RPM#1"; + // Execute the first one, ensure scheduling for the "close" event happens + engine->module()->scheduleEventsUntilNextTriggerTooth(1000, 0, 0, 0, 1); - eth.assertTriggerEvent("a0", 0, &engine->auxValves[0][0].open, (void*)&auxPlainPinTurnOn, 7, 86); - eth.assertTriggerEvent("a1", 1, &engine->auxValves[0][1].open, (void*)&auxPlainPinTurnOn, 3, 86); - eth.assertTriggerEvent("a2", 2, &engine->auxValves[1][0].open, (void*)&auxPlainPinTurnOn, 5, 86); + // Old head should now be missing - we just ran it + eth.assertTriggerEvent("a1", 0, &engine->auxValves[0][1].open, (void*)&auxPlainPinTurnOn, 360); + eth.assertTriggerEvent("a2", 1, &engine->auxValves[1][0].open, (void*)&auxPlainPinTurnOn, 180); + eth.assertTriggerEvent("a3", 2, &engine->auxValves[1][1].open, (void*)&auxPlainPinTurnOn, 540); + + // Execute the action it put on the regular scheduler + eth.executeUntil(999999); + + eth.assertTriggerEvent("a1", 0, &engine->auxValves[0][1].open, (void*)&auxPlainPinTurnOn, 360); + eth.assertTriggerEvent("a2", 1, &engine->auxValves[1][0].open, (void*)&auxPlainPinTurnOn, 180); + eth.assertTriggerEvent("a3", 2, &engine->auxValves[1][1].open, (void*)&auxPlainPinTurnOn, 540); + // same event is back at the end of the list + eth.assertTriggerEvent("a0", 3, &engine->auxValves[0][0].open, (void*)&auxPlainPinTurnOn, 0); + // PLUS the turn off event! + eth.assertTriggerEvent("off", 4, &engine->auxValves[0][0].close, nullptr, 30); } diff --git a/unit_tests/tests/test_hpfp.cpp b/unit_tests/tests/test_hpfp.cpp index 7fbb15ab47..49cd4b39ab 100755 --- a/unit_tests/tests/test_hpfp.cpp +++ b/unit_tests/tests/test_hpfp.cpp @@ -272,22 +272,20 @@ TEST(HPFP, Schedule) { hpfp.onFastCallback(); // First event was scheduled by setRpmValue with 0 injection mass. So, it's off. - eth.assertTriggerEvent("h0", 0, &hpfp.m_event, (void*)&HpfpController::pinTurnOff, - 1, angle0 - 0); + eth.assertTriggerEvent("h0", 0, &hpfp.m_event, (void*)&HpfpController::pinTurnOff, 270); // Make the previous event happen, schedule the next. engine->module()->scheduleEventsUntilNextTriggerTooth( - 1000, 1, tick_per_deg * 0, 0, 0); + 1000, 1, tick_per_deg * 0, 180, 360); // Mock executor doesn't run events, so we run it manually HpfpController::pinTurnOff(&hpfp); // Now we should have a regular on/off event. - eth.assertTriggerEvent("h1", 0, &hpfp.m_event, (void*)&HpfpController::pinTurnOn, - 2, angle1 - 180); + eth.assertTriggerEvent("h1", 0, &hpfp.m_event, (void*)&HpfpController::pinTurnOn, 450 - 37.6923065f); // Make it happen engine->module()->scheduleEventsUntilNextTriggerTooth( - 1000, 2, tick_per_deg * 180, 0, 0); + 1000, 2, tick_per_deg * 180, 360, 540); // Since we have a mock scheduler, lets insert the correct timestamp in the scheduling // struct.