From 5bfbd1eb2801bc3c5b50107bd51d4e7bb26aae6c Mon Sep 17 00:00:00 2001 From: Josh Stewart Date: Fri, 16 Feb 2024 09:56:24 +1100 Subject: [PATCH] Align scheduler timeout checks on fuel match those on ignition Potential fix for #1181 --- speeduino/board_teensy35.h | 2 +- speeduino/scheduler.cpp | 7 ++++++- speeduino/scheduler.h | 18 +++++++++--------- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/speeduino/board_teensy35.h b/speeduino/board_teensy35.h index 018182a2..5da03d91 100644 --- a/speeduino/board_teensy35.h +++ b/speeduino/board_teensy35.h @@ -112,7 +112,7 @@ static inline void IGN7_TIMER_DISABLE(void) {FTM3_C6SC &= ~FTM_CSC_CHIE;} static inline void IGN8_TIMER_DISABLE(void) {FTM3_C7SC &= ~FTM_CSC_CHIE;} - #define MAX_TIMER_PERIOD 139808 // 2.13333333uS * 65535 + #define MAX_TIMER_PERIOD 139808UL // 2.13333333uS * 65535 #define uS_TO_TIMER_COMPARE(uS) ((uS * 15) >> 5) //Converts a given number of uS into the required number of timer ticks until that time has passed. /* diff --git a/speeduino/scheduler.cpp b/speeduino/scheduler.cpp index edeea4cc..c48aef99 100644 --- a/speeduino/scheduler.cpp +++ b/speeduino/scheduler.cpp @@ -214,9 +214,14 @@ void _setFuelScheduleRunning(FuelSchedule &schedule, unsigned long timeout, unsi { schedule.duration = duration; + //Need to check that the timeout doesn't exceed the overflow + COMPARE_TYPE timeout_timer_compare; + if (timeout > MAX_TIMER_PERIOD) { timeout_timer_compare = uS_TO_TIMER_COMPARE( (MAX_TIMER_PERIOD - 1) ); } // If the timeout is >4x (Each tick represents 4uS on a mega2560, other boards will be different) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when applied causing erratic behaviour such as erroneous squirts + else { timeout_timer_compare = uS_TO_TIMER_COMPARE(timeout); } //Normal case + //The following must be enclosed in the noInterupts block to avoid contention caused if the relevant interrupt fires before the state is fully set noInterrupts(); - schedule.startCompare = schedule.counter + uS_TO_TIMER_COMPARE(timeout); + schedule.startCompare = schedule.counter + timeout_timer_compare; schedule.endCompare = schedule.startCompare + uS_TO_TIMER_COMPARE(duration); SET_COMPARE(schedule.compare, schedule.startCompare); //Use the B compare unit of timer 3 schedule.Status = PENDING; //Turn this schedule on diff --git a/speeduino/scheduler.h b/speeduino/scheduler.h index a8a527e9..d83b41cf 100644 --- a/speeduino/scheduler.h +++ b/speeduino/scheduler.h @@ -200,15 +200,15 @@ struct FuelSchedule { void _setFuelScheduleRunning(FuelSchedule &schedule, unsigned long timeout, unsigned long duration); void _setFuelScheduleNext(FuelSchedule &schedule, unsigned long timeout, unsigned long duration); -inline __attribute__((always_inline)) void setFuelSchedule(FuelSchedule &schedule, unsigned long timeout, unsigned long duration) { - //Check whether timeout exceeds the maximum future time. This can potentially occur on sequential setups when below ~115rpm - if(timeout < MAX_TIMER_PERIOD) { - if(schedule.Status != RUNNING) { //Check that we're not already part way through a schedule - _setFuelScheduleRunning(schedule, timeout, duration); - } - else { - _setFuelScheduleNext(schedule, timeout, duration); - } +inline __attribute__((always_inline)) void setFuelSchedule(FuelSchedule &schedule, unsigned long timeout, unsigned long duration) +{ + if(schedule.Status != RUNNING) + { //Check that we're not already part way through a schedule + _setFuelScheduleRunning(schedule, timeout, duration); + } + else if(timeout < MAX_TIMER_PERIOD) + { + _setFuelScheduleNext(schedule, timeout, duration); } }