overdwell protection (#3220)

* cancel event

* looks like it works...

* some tests are happy

* add enable bit

* undo test changes

* Revert "add enable bit"

This reverts commit 000afadd3f.

* enable bit in engine

* only turn off for one test

* Revert "undo test changes"

This reverts commit 106db49e29.
This commit is contained in:
Matthew Kennedy 2021-10-01 22:10:24 -07:00 committed by GitHub
parent 13d21716db
commit 0a550a70b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 20 additions and 7 deletions

View File

@ -88,6 +88,7 @@ public:
DECLARE_ENGINE_PTR; DECLARE_ENGINE_PTR;
Engine(); Engine();
bool enableOverdwellProtection = true;
bool isPwmEnabled = true; bool isPwmEnabled = true;
int triggerActivitySecond = 0; int triggerActivitySecond = 0;

View File

@ -378,6 +378,8 @@ static void handleSparkEvent(bool limitedSpark, uint32_t trgEventIndex, Ignition
event->sparkId = engine->globalSparkIdCounter++; event->sparkId = engine->globalSparkIdCounter++;
efitick_t chargeTime = 0;
/** /**
* The start of charge is always within the current trigger event range, so just plain time-based scheduling * The start of charge is always within the current trigger event range, so just plain time-based scheduling
*/ */
@ -393,7 +395,7 @@ static void handleSparkEvent(bool limitedSpark, uint32_t trgEventIndex, Ignition
* This way we make sure that coil dwell started while spark was enabled would fire and not burn * This way we make sure that coil dwell started while spark was enabled would fire and not burn
* the coil. * the coil.
*/ */
scheduleByAngle(&event->dwellStartTimer, edgeTimestamp, angleOffset, { &turnSparkPinHigh, event } PASS_ENGINE_PARAMETER_SUFFIX); chargeTime = scheduleByAngle(&event->dwellStartTimer, edgeTimestamp, angleOffset, { &turnSparkPinHigh, event } PASS_ENGINE_PARAMETER_SUFFIX);
event->sparksRemaining = ENGINE(engineState.multispark.count); event->sparksRemaining = ENGINE(engineState.multispark.count);
} else { } else {
@ -418,10 +420,14 @@ static void handleSparkEvent(bool limitedSpark, uint32_t trgEventIndex, Ignition
#if SPARK_EXTREME_LOGGING #if SPARK_EXTREME_LOGGING
efiPrintf("to queue sparkDown ind=%d %d %s now=%d for id=%d", trgEventIndex, getRevolutionCounter(), event->getOutputForLoggins()->name, (int)getTimeNowUs(), event->sparkEvent.position.triggerEventIndex); efiPrintf("to queue sparkDown ind=%d %d %s now=%d for id=%d", trgEventIndex, getRevolutionCounter(), event->getOutputForLoggins()->name, (int)getTimeNowUs(), event->sparkEvent.position.triggerEventIndex);
#endif /* SPARK_EXTREME_LOGGING */ #endif /* SPARK_EXTREME_LOGGING */
if (!limitedSpark && engine->enableOverdwellProtection) {
// auto fire spark at 1.5x nominal dwell
efitick_t fireTime = chargeTime + MSF2NT(1.5f * dwellMs);
engine->executor.scheduleByTimestampNt("overdwell", &event->sparkEvent.scheduling, fireTime, { fireSparkAndPrepareNextSchedule, event });
}
} }
#if EFI_UNIT_TEST #if EFI_UNIT_TEST
if (verboseMode) { if (verboseMode) {
printf("spark dwell@ %d/%d spark@ %d/%d id=%d\r\n", event->dwellPosition.triggerEventIndex, (int)event->dwellPosition.angleOffsetFromTriggerEvent, printf("spark dwell@ %d/%d spark@ %d/%d id=%d\r\n", event->dwellPosition.triggerEventIndex, (int)event->dwellPosition.angleOffsetFromTriggerEvent,
@ -482,7 +488,6 @@ static void prepareIgnitionSchedule(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
initializeIgnitionActions(PASS_ENGINE_PARAMETER_SIGNATURE); initializeIgnitionActions(PASS_ENGINE_PARAMETER_SIGNATURE);
} }
static void scheduleAllSparkEventsUntilNextTriggerTooth(uint32_t trgEventIndex, efitick_t edgeTimestamp DECLARE_ENGINE_PARAMETER_SUFFIX) { static void scheduleAllSparkEventsUntilNextTriggerTooth(uint32_t trgEventIndex, efitick_t edgeTimestamp DECLARE_ENGINE_PARAMETER_SUFFIX) {
AngleBasedEvent *current, *tmp; AngleBasedEvent *current, *tmp;
@ -498,6 +503,9 @@ static void scheduleAllSparkEventsUntilNextTriggerTooth(uint32_t trgEventIndex,
efiPrintf("time to invoke ind=%d %d %d", trgEventIndex, getRevolutionCounter(), (int)getTimeNowUs()); efiPrintf("time to invoke ind=%d %d %d", trgEventIndex, getRevolutionCounter(), (int)getTimeNowUs());
#endif /* SPARK_EXTREME_LOGGING */ #endif /* SPARK_EXTREME_LOGGING */
// In case this event was scheduled by overdwell protection, cancel it so we can re-schedule at the correct time
engine->executor.cancel(sDown);
scheduleByAngle( scheduleByAngle(
sDown, sDown,
edgeTimestamp, edgeTimestamp,

View File

@ -40,6 +40,9 @@ TEST(ignition, twoCoils) {
TEST(ignition, trailingSpark) { TEST(ignition, trailingSpark) {
WITH_ENGINE_TEST_HELPER(TEST_ENGINE); WITH_ENGINE_TEST_HELPER(TEST_ENGINE);
// TODO #3220: this feature makes this test sad, eventually remove this line (and the ability to disable it altogether)
engine->enableOverdwellProtection = false;
EXPECT_CALL(eth.mockAirmass, getAirmass(_)) EXPECT_CALL(eth.mockAirmass, getAirmass(_))
.WillRepeatedly(Return(AirmassResult{0.1008f, 50.0f})); .WillRepeatedly(Return(AirmassResult{0.1008f, 50.0f}));

View File

@ -32,7 +32,8 @@ TEST(realCrankingVQ40, normalCranking) {
ASSERT_EQ(241, GET_RPM())<< reader.lineIndex(); ASSERT_EQ(241, GET_RPM())<< reader.lineIndex();
// TODO: why warnings? // TODO: why warnings?
ASSERT_EQ(2, eth.recentWarnings()->getCount()); ASSERT_EQ(3, eth.recentWarnings()->getCount());
ASSERT_EQ(CUSTOM_SYNC_COUNT_MISMATCH, eth.recentWarnings()->get(0)); ASSERT_EQ(CUSTOM_SYNC_COUNT_MISMATCH, eth.recentWarnings()->get(0));
ASSERT_EQ(CUSTOM_SYNC_ERROR, eth.recentWarnings()->get(1)); ASSERT_EQ(CUSTOM_OUT_OF_ORDER_COIL, eth.recentWarnings()->get(1)); // this is from a coil being protected by overdwell protection
ASSERT_EQ(CUSTOM_SYNC_ERROR, eth.recentWarnings()->get(2));
} }

View File

@ -1134,7 +1134,7 @@ TEST(big, testSparkReverseOrderBug319) {
ASSERT_EQ( 3000, GET_RPM()) << "testSparkReverseOrderBug319: RPM"; ASSERT_EQ( 3000, GET_RPM()) << "testSparkReverseOrderBug319: RPM";
ASSERT_EQ( 7, engine->executor.size()) << "testSparkReverseOrderBug319: queue size"; ASSERT_EQ( 8, engine->executor.size()) << "testSparkReverseOrderBug319: queue size";
eth.executeActions(); eth.executeActions();
printf("***************************************************\r\n"); printf("***************************************************\r\n");