diff --git a/firmware/controllers/algo/signal_executor.cpp b/firmware/controllers/algo/signal_executor.cpp index 63a5c4462a..ec4f842d04 100644 --- a/firmware/controllers/algo/signal_executor.cpp +++ b/firmware/controllers/algo/signal_executor.cpp @@ -122,8 +122,8 @@ void seTurnPinHigh(NamedOutputPin *output) { #endif /* FUEL_MATH_EXTREME_LOGGING */ #if EFI_UNIT_TEST -// if (output->currentLogicValue == 1) -// firmwareError("Already high"); + if (output->currentLogicValue == 1) + firmwareError("Already high"); #endif turnPinHigh(output); diff --git a/firmware/controllers/system/efiGpio.cpp b/firmware/controllers/system/efiGpio.cpp index 9d3cf80f04..9f0fb14d3b 100644 --- a/firmware/controllers/system/efiGpio.cpp +++ b/firmware/controllers/system/efiGpio.cpp @@ -33,6 +33,8 @@ InjectorOutputPin::InjectorOutputPin() : NamedOutputPin() { void InjectorOutputPin::reset() { overlappingScheduleOffTime = 0; cancelNextTurningInjectorOff = false; + // todo: this could be refactored by calling some super-reset method + currentLogicValue = INITIAL_PIN_STATE; } OutputPin::OutputPin() { diff --git a/firmware/controllers/system/event_queue.cpp b/firmware/controllers/system/event_queue.cpp index aa25507595..8aa3c79ddc 100644 --- a/firmware/controllers/system/event_queue.cpp +++ b/firmware/controllers/system/event_queue.cpp @@ -44,8 +44,13 @@ bool EventQueue::insertTask(scheduling_s *scheduling, efitime_t timeX, schfunc_t #endif /* EFI_UNIT_TEST */ efiAssert(callback != NULL, "NULL callback", false); - if (scheduling->isScheduled) + if (scheduling->isScheduled) { +#if EFI_UNIT_TEST + printf("Already scheduled was %d\r\n", scheduling->momentX); + printf("Already scheduled now %d\r\n", timeX); +#endif return false; + } scheduling->momentX = timeX; scheduling->callback = callback; diff --git a/firmware/controllers/trigger/main_trigger_callback.cpp b/firmware/controllers/trigger/main_trigger_callback.cpp index 10a5280389..8fd4c5e313 100644 --- a/firmware/controllers/trigger/main_trigger_callback.cpp +++ b/firmware/controllers/trigger/main_trigger_callback.cpp @@ -98,7 +98,7 @@ static void endSimultaniousInjection(Engine *engine) { } } -static void scheduleFuelInjection(int eventIndex, OutputSignal *signal, efitimeus_t nowUs, float delayUs, float durationUs, InjectorOutputPin *output DECLARE_ENGINE_PARAMETER_S) { +static void scheduleFuelInjection(int injEventIndex, OutputSignal *signal, efitimeus_t nowUs, float delayUs, float durationUs, InjectorOutputPin *output DECLARE_ENGINE_PARAMETER_S) { if (durationUs < 0) { warning(CUSTOM_OBD_3, "duration cannot be negative: %d", durationUs); return; @@ -131,7 +131,7 @@ static void scheduleFuelInjection(int eventIndex, OutputSignal *signal, efitimeu seScheduleByTime("out down", sDown, turnOffTime, (schfunc_t) &seTurnPinLow, output); } -static ALWAYS_INLINE void handleFuelInjectionEvent(int eventIndex, InjectionEvent *event, +static ALWAYS_INLINE void handleFuelInjectionEvent(int injEventIndex, InjectionEvent *event, int rpm DECLARE_ENGINE_PARAMETER_S) { /** @@ -179,9 +179,9 @@ static ALWAYS_INLINE void handleFuelInjectionEvent(int eventIndex, InjectionEven getRevolutionCounter()); #endif /* EFI_DEFAILED_LOGGING */ - OutputSignal *signal = &ENGINE(engineConfiguration2)->fuelActuators[eventIndex]; + OutputSignal *signal = &ENGINE(engineConfiguration2)->fuelActuators[injEventIndex]; - engine->engineConfiguration2->wasOverlapping[eventIndex] = event->isOverlapping; + engine->engineConfiguration2->wasOverlapping[injEventIndex] = event->isOverlapping; if (event->isSimultanious) { /** @@ -213,7 +213,7 @@ static ALWAYS_INLINE void handleFuelInjectionEvent(int eventIndex, InjectionEven prevOutputName = outputName; } - scheduleFuelInjection(eventIndex, signal, getTimeNowUs(), injectionStartDelayUs, MS2US(injectionDuration), event->output PASS_ENGINE_PARAMETER); + scheduleFuelInjection(injEventIndex, signal, getTimeNowUs(), injectionStartDelayUs, MS2US(injectionDuration), event->output PASS_ENGINE_PARAMETER); } } diff --git a/firmware/controllers/trigger/rpm_calculator.cpp b/firmware/controllers/trigger/rpm_calculator.cpp index dab4dc331e..dccc3e976a 100644 --- a/firmware/controllers/trigger/rpm_calculator.cpp +++ b/firmware/controllers/trigger/rpm_calculator.cpp @@ -44,6 +44,8 @@ extern bool hasFirmwareErrorFlag; static Logging * logger; +int revolutionCounterSinceBootForUnitTest = 0; + RpmCalculator::RpmCalculator() { #if !EFI_PROD_CODE mockRpm = MOCK_UNDEFINED; @@ -54,7 +56,7 @@ RpmCalculator::RpmCalculator() { // we need this initial to have not_running at first invocation lastRpmEventTimeNt = (efitime_t) -10 * US2NT(US_PER_SECOND_LL); revolutionCounterSinceStart = 0; - revolutionCounterSinceBoot = 0; + revolutionCounterSinceBootForUnitTest = revolutionCounterSinceBoot = 0; lastRpmEventTimeNt = 0; oneDegreeUs = NAN; @@ -113,6 +115,9 @@ void RpmCalculator::setRpmValue(int value DECLARE_ENGINE_PARAMETER_S) { void RpmCalculator::onNewEngineCycle() { revolutionCounterSinceBoot++; revolutionCounterSinceStart++; +#if EFI_UNIT_TEST + revolutionCounterSinceBootForUnitTest = revolutionCounterSinceBoot; +#endif } uint32_t RpmCalculator::getRevolutionCounter(void) { diff --git a/unit_tests/main.cpp b/unit_tests/main.cpp index e5d5bbd7a2..a81fa83a52 100644 --- a/unit_tests/main.cpp +++ b/unit_tests/main.cpp @@ -117,8 +117,10 @@ void chDbgAssert(int c, char *msg, void *arg) { } } +extern int revolutionCounterSinceBootForUnitTest; + int getRevolutionCounter(void) { - return 0; + return revolutionCounterSinceBootForUnitTest; } int main(void) { diff --git a/unit_tests/test_trigger_decoder.cpp b/unit_tests/test_trigger_decoder.cpp index 30511efcf5..603b847119 100644 --- a/unit_tests/test_trigger_decoder.cpp +++ b/unit_tests/test_trigger_decoder.cpp @@ -776,8 +776,13 @@ void testFuelSchedulerBug299smallAndMedium(void) { assertEqualsM("qs#1", 4, schedulingQueue.size()); timeNow += MS2US(20); - schedulingQueue.executeAll(timeNow); + assertEqualsM("exec#2#0", 4, schedulingQueue.executeAll(timeNow)); + assertEqualsM("qs#1#2", 0, schedulingQueue.size()); + + + assertEqualsM("rev cnt#4#0", 4, engine->rpmCalculator.getRevolutionCounter()); eth.firePrimaryTriggerRise(); + assertEqualsM("rev cnt#4#1", 5, engine->rpmCalculator.getRevolutionCounter()); // time...|0.......|10......|20......|30......|40......|50......|60......| // inj #0 |########|##...###|########|.....###|########|........|........| // inj #1 |.....###|########|....####|########|........|........|........| @@ -793,6 +798,12 @@ void testFuelSchedulerBug299smallAndMedium(void) { assertInjectorDownEvent("04@8", 8, MS2US(40.0), 1); assertInjectorDownEvent("04@9", 9, MS2US(50.0), 0); + { + scheduling_s *ev = schedulingQueue.getForUnitText(9); + assertEqualsM("rev cnt#4#2", 5, engine->rpmCalculator.getRevolutionCounter()); + assertTrueM("down 50", ev == &engine->engineConfiguration2->fuelActuators[2].signalTimerDown[1]); + } + assertEqualsM("exec#4", 1, schedulingQueue.executeAll(timeNow)); @@ -844,7 +855,7 @@ void testFuelSchedulerBug299smallAndMedium(void) { assertInjectorDownEvent("26@0", 0, MS2US(10.0), 0); eth.firePrimaryTriggerRise(); - assertEqualsM("qs#2", 8, schedulingQueue.size()); + assertEqualsM("qs#2#2", 9, schedulingQueue.size()); assertEqualsM("rev cnt6", 6, engine->rpmCalculator.getRevolutionCounter()); // time...|-20.....|-10.....|0.......|10......|20......|30......|40......| // inj #0 |########|.....###|########|....####|........|........|........| @@ -862,7 +873,7 @@ void testFuelSchedulerBug299smallAndMedium(void) { // time...|-20.....|-10.....|0.......|10......|20......|30......|40......| // inj #0 |########|.......#|........|........|........|........|........| // inj #1 |....####|########|........|........|........|........|........| - assertEqualsM("qs#022", 8, schedulingQueue.size()); + assertEqualsM("qs#022", 9, schedulingQueue.size()); assertInjectorUpEvent("7@0", 0, MS2US(-12.5), 1); assertInjectorDownEvent("7@1", 1, MS2US(-10.0), 0); assertInjectorUpEvent("7@2", 2, MS2US(-2.5), 0); @@ -871,42 +882,45 @@ void testFuelSchedulerBug299smallAndMedium(void) { assertInjectorDownEvent("7@5", 5, MS2US(10.0), 0); assertInjectorUpEvent("7@6", 6, MS2US(17.5), 0); assertInjectorDownEvent("7@7", 7, MS2US(20), 1); + // todo index 8 assertEqualsM("executed #06", 4, schedulingQueue.executeAll(timeNow)); assertInjectors("#4", 1, 0); - assertEqualsM("qs#06", 4, schedulingQueue.size()); + assertEqualsM("qs#06", 5, schedulingQueue.size()); assertInjectorUpEvent("17@0", 0, MS2US(7.5), 1); assertInjectorDownEvent("17@1", 1, MS2US(10.0), 0); assertInjectorUpEvent("17@2", 2, MS2US(17.5), 0); assertInjectorDownEvent("17@3", 3, MS2US(20), 1); + // todo index 4 eth.firePrimaryTriggerFall(); - assertEqualsM("qs#3", 4, schedulingQueue.size()); + assertEqualsM("qs#3", 5, schedulingQueue.size()); assertEqualsM("rev cnt6", 6, engine->rpmCalculator.getRevolutionCounter()); assertEqualsM("executed #6", 0, schedulingQueue.executeAll(timeNow)); timeNow += MS2US(20); assertEqualsM("executed #06", 4, schedulingQueue.executeAll(timeNow)); - assertEqualsM("qs#06", 0, schedulingQueue.size()); + assertEqualsM("qs#06", 1, schedulingQueue.size()); assertInjectors("#2", 1, 0); eth.firePrimaryTriggerRise(); - assertEqualsM("Queue.size#03", 8, schedulingQueue.size()); + assertEqualsM("Queue.size#03", 9, schedulingQueue.size()); engine->periodicFastCallback(PASS_ENGINE_PARAMETER_F); assertInjectorUpEvent("07@0", 0, MS2US(7.5), 1); - assertInjectorUpEvent("07@1", 1, MS2US(17.5), 0); - assertInjectorDownEvent("07@2", 2, MS2US(20), 1); - assertInjectorUpEvent("07@3", 3, MS2US(27.5), 1); - assertInjectorDownEvent("07@4", 4, MS2US(30), 0); - assertInjectorUpEvent("07@5", 5, MS2US(37.5), 0); - assertInjectorDownEvent("07@6", 6, MS2US(40), 1); - assertInjectorDownEvent("07@7", 7, MS2US(50), 0); + // todo index 1 + assertInjectorUpEvent("07@2", 2, MS2US(17.5), 0); + assertInjectorDownEvent("07@3", 3, MS2US(20), 1); + assertInjectorUpEvent("07@4", 4, MS2US(27.5), 1); + assertInjectorDownEvent("07@5", 5, MS2US(30), 0); + assertInjectorUpEvent("07@6", 6, MS2US(37.5), 0); + assertInjectorDownEvent("07@7", 7, MS2US(40), 1); + assertInjectorDownEvent("07@8", 8, MS2US(50), 0); assertEqualsM("executeAll#3", 0, schedulingQueue.executeAll(timeNow)); timeNow += MS2US(20); - assertEqualsM("executeAll#4", 3, schedulingQueue.executeAll(timeNow)); + assertEqualsM("executeAll#4", 4, schedulingQueue.executeAll(timeNow)); t = ENGINE(engineConfiguration2)->injectionEvents; @@ -947,7 +961,7 @@ void testFuelSchedulerBug299smallAndMedium(void) { timeNow += MS2US(20); eth.firePrimaryTriggerRise(); - assertEqualsM("Queue.size#05", 8, schedulingQueue.size()); + assertEqualsM("Queue.size#05", 13, schedulingQueue.size()); schedulingQueue.executeAll(timeNow); timeNow += MS2US(20); @@ -955,6 +969,7 @@ void testFuelSchedulerBug299smallAndMedium(void) { schedulingQueue.executeAll(timeNow); timeNow += MS2US(20); + schedulingQueue.executeAll(timeNow); eth.firePrimaryTriggerRise(); engine->periodicFastCallback(PASS_ENGINE_PARAMETER_F); @@ -968,15 +983,16 @@ void testFuelSchedulerBug299smallAndMedium(void) { // todo: what's what? a mix of new something and old something? - assertEqualsM("qs#5", 8, schedulingQueue.size()); - assertInjectorDownEvent("8@0", 0, MS2US(-15.0), 1); + assertEqualsM("qs#5", 10, schedulingQueue.size()); + assertInjectorDownEvent("8@0", 0, MS2US(5.0), 1); assertInjectorUpEvent("8@1", 1, MS2US(7.5), 1); - assertInjectorUpEvent("8@2", 2, MS2US(17.5), 0); - assertInjectorUpEvent("8@3", 3, MS2US(27.5), 1); - assertInjectorDownEvent("8@4", 4, MS2US(35), 0); - assertInjectorUpEvent("8@5", 5, MS2US(37.5), 0); - assertInjectorDownEvent("8@6", 6, MS2US(45), 1); - assertInjectorDownEvent("8@7", 7, MS2US(55), 0); + assertInjectorDownEvent("8@2", 2, MS2US(15.0), 0); + assertInjectorUpEvent("8@3", 3, MS2US(17.5), 0); + assertInjectorDownEvent("8@4", 4, MS2US(25), 1); + assertInjectorUpEvent("8@5", 5, MS2US(27.5), 1); + assertInjectorDownEvent("8@6", 6, MS2US(35), 0); + assertInjectorUpEvent("8@7", 7, MS2US(37.5), 0); + // todo index 8 9 schedulingQueue.executeAll(timeNow);