Unit test the schedule calculations (#1010)

* Refactor: separate out schedule calcs from speeduino.ino
(so they can be unit tested)

* Add unit tests for compute_delay

* Use PROGMEM to store test input & output

* Add some 720 unit tests

* Rename unit test file

* Test ignition codepaths 2-8

* Test ign1 calcs

* Add first injector calc tests

* Add 720 deg tests
Simplify

* Simplify test_calc_inj1_timeout

* Claw back RAM

* Simplify test framework
Channel angle is part of the test data set.

* Move schedule calculation unit tests into their own harness
Competing for RAM with the rest of Speeduino
can cause them to fail,

* Performance: inline all schedule calcs.

* Unit test end angle

* Unit test calculateIgnitionAngle1

* Test start angles also
And test end angles for channel 1

* Unit test calculateIgnitionAngle3

* Unit test calculateIgnitionAngle4

* Improve unit test output

* Add Nissan360 decoder unit tests.

* Add Ford ST170 decoder unit tests

* Add NGC decoder unit tests
This commit is contained in:
tx_haggis 2023-03-06 00:23:17 -06:00 committed by GitHub
parent 311cae3fac
commit 0afffb2ca0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 2037 additions and 333 deletions

View File

@ -0,0 +1,28 @@
#include "schedule_calcs.h"
int ignition1StartAngle = 0;
int ignition2StartAngle = 0;
int ignition3StartAngle = 0;
int ignition4StartAngle = 0;
int ignition5StartAngle = 0;
int ignition6StartAngle = 0;
int ignition7StartAngle = 0;
int ignition8StartAngle = 0;
int channel1IgnDegrees = 0; /**< The number of crank degrees until cylinder 1 is at TDC (This is obviously 0 for virtually ALL engines, but there's some weird ones) */
int channel2IgnDegrees = 0; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
int channel3IgnDegrees = 0; /**< The number of crank degrees until cylinder 3 (and 5/6/7/8) is at TDC */
int channel4IgnDegrees = 0; /**< The number of crank degrees until cylinder 4 (and 5/6/7/8) is at TDC */
int channel5IgnDegrees = 0; /**< The number of crank degrees until cylinder 5 is at TDC */
int channel6IgnDegrees = 0; /**< The number of crank degrees until cylinder 6 is at TDC */
int channel7IgnDegrees = 0; /**< The number of crank degrees until cylinder 7 is at TDC */
int channel8IgnDegrees = 0; /**< The number of crank degrees until cylinder 8 is at TDC */
int channel1InjDegrees = 0; /**< The number of crank degrees until cylinder 1 is at TDC (This is obviously 0 for virtually ALL engines, but there's some weird ones) */
int channel2InjDegrees = 0; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
int channel3InjDegrees = 0; /**< The number of crank degrees until cylinder 3 (and 5/6/7/8) is at TDC */
int channel4InjDegrees = 0; /**< The number of crank degrees until cylinder 4 (and 5/6/7/8) is at TDC */
int channel5InjDegrees = 0; /**< The number of crank degrees until cylinder 5 is at TDC */
int channel6InjDegrees = 0; /**< The number of crank degrees until cylinder 6 is at TDC */
int channel7InjDegrees = 0; /**< The number of crank degrees until cylinder 7 is at TDC */
int channel8InjDegrees = 0; /**< The number of crank degrees until cylinder 8 is at TDC */

View File

@ -0,0 +1,53 @@
#pragma once
#include <stdint.h>
#include "scheduler.h"
extern int ignition1StartAngle;
extern int ignition2StartAngle;
extern int ignition3StartAngle;
extern int ignition4StartAngle;
extern int ignition5StartAngle;
extern int ignition6StartAngle;
extern int ignition7StartAngle;
extern int ignition8StartAngle;
extern int channel1IgnDegrees; /**< The number of crank degrees until cylinder 1 is at TDC (This is obviously 0 for virtually ALL engines, but there's some weird ones) */
extern int channel2IgnDegrees; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
extern int channel3IgnDegrees; /**< The number of crank degrees until cylinder 3 (and 5/6/7/8) is at TDC */
extern int channel4IgnDegrees; /**< The number of crank degrees until cylinder 4 (and 5/6/7/8) is at TDC */
extern int channel5IgnDegrees; /**< The number of crank degrees until cylinder 5 is at TDC */
extern int channel6IgnDegrees; /**< The number of crank degrees until cylinder 6 is at TDC */
extern int channel7IgnDegrees; /**< The number of crank degrees until cylinder 7 is at TDC */
extern int channel8IgnDegrees; /**< The number of crank degrees until cylinder 8 is at TDC */
extern int channel1InjDegrees; /**< The number of crank degrees until cylinder 1 is at TDC (This is obviously 0 for virtually ALL engines, but there's some weird ones) */
extern int channel2InjDegrees; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
extern int channel3InjDegrees; /**< The number of crank degrees until cylinder 3 (and 5/6/7/8) is at TDC */
extern int channel4InjDegrees; /**< The number of crank degrees until cylinder 4 (and 5/6/7/8) is at TDC */
extern int channel5InjDegrees; /**< The number of crank degrees until cylinder 5 is at TDC */
extern int channel6InjDegrees; /**< The number of crank degrees until cylinder 6 is at TDC */
extern int channel7InjDegrees; /**< The number of crank degrees until cylinder 7 is at TDC */
extern int channel8InjDegrees; /**< The number of crank degrees until cylinder 8 is at TDC */
inline uint16_t __attribute__((always_inline)) calculateInjectorStartAngle(uint16_t PWdivTimerPerDegree, int16_t injChannelDegrees);
inline uint32_t __attribute__((always_inline)) calculateInjector1Timeout(int injector1StartAngle, int crankAngle);
inline uint32_t __attribute__((always_inline)) calculateInjectorNTimeout(const FuelSchedule &schedule, int channelInjDegrees, int injectorStartAngle, int crankAngle);
inline void __attribute__((always_inline)) calculateIgnitionAngle1(int dwellAngle);
inline void __attribute__((always_inline)) calculateIgnitionAngle2(int dwellAngle);
inline void __attribute__((always_inline)) calculateIgnitionAngle3(int dwellAngle);
// ignition 3 for rotary
inline void __attribute__((always_inline)) calculateIgnitionAngle3(int dwellAngle, int rotarySplitDegrees);
inline void __attribute__((always_inline)) calculateIgnitionAngle4(int dwellAngle);
// ignition 4 for rotary
inline void __attribute__((always_inline)) calculateIgnitionAngle4(int dwellAngle, int rotarySplitDegrees);
inline void __attribute__((always_inline)) calculateIgnitionAngle5(int dwellAngle);
inline void __attribute__((always_inline)) calculateIgnitionAngle6(int dwellAngle);
inline void __attribute__((always_inline)) calculateIgnitionAngle7(int dwellAngle);
inline void __attribute__((always_inline)) calculateIgnitionAngle8(int dwellAngle);
inline uint32_t __attribute__((always_inline)) calculateIgnition1Timeout(int crankAngle);
inline uint32_t __attribute__((always_inline)) calculateIgnitionNTimeout(const Schedule &schedule, int startAngle, int channelIgnDegrees, int crankAngle);
#include "schedule_calcs.inl"

View File

@ -0,0 +1,147 @@
#include "globals.h"
#include "scheduler.h"
#include "crankMaths.h"
inline uint16_t calculateInjectorStartAngle(uint16_t PWdivTimerPerDegree, int16_t injChannelDegrees)
{
uint16_t tempInjectorStartAngle = (currentStatus.injAngle + injChannelDegrees);
if(tempInjectorStartAngle < PWdivTimerPerDegree) { tempInjectorStartAngle += CRANK_ANGLE_MAX_INJ; }
tempInjectorStartAngle -= PWdivTimerPerDegree;
while(tempInjectorStartAngle > (uint16_t)CRANK_ANGLE_MAX_INJ) { tempInjectorStartAngle -= CRANK_ANGLE_MAX_INJ; }
return tempInjectorStartAngle;
}
inline uint32_t calculateInjector1Timeout(int injector1StartAngle, int crankAngle)
{
if ( (injector1StartAngle <= crankAngle) && (fuelSchedule1.Status == RUNNING) ) { injector1StartAngle += CRANK_ANGLE_MAX_INJ; }
if (injector1StartAngle > crankAngle)
{
return ((injector1StartAngle - crankAngle) * (unsigned long)timePerDegree);
}
return 0U;
}
inline uint32_t calculateInjectorNTimeout(const FuelSchedule &schedule, int channelInjDegrees, int injectorStartAngle, int crankAngle)
{
int tempCrankAngle = crankAngle - channelInjDegrees;
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_INJ; }
int tempStartAngle = injectorStartAngle - channelInjDegrees;
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_INJ; }
if ( (tempStartAngle <= tempCrankAngle) && (schedule.Status == RUNNING) ) { tempStartAngle += CRANK_ANGLE_MAX_INJ; }
if ( tempStartAngle > tempCrankAngle )
{
return (((uint32_t)tempStartAngle - (uint32_t)tempCrankAngle) * (uint32_t)timePerDegree);
}
return 0U;
}
inline void calculateIgnitionAngle1(int dwellAngle)
{
ignition1EndAngle = CRANK_ANGLE_MAX_IGN - currentStatus.advance;
if(ignition1EndAngle > CRANK_ANGLE_MAX_IGN) {ignition1EndAngle -= CRANK_ANGLE_MAX_IGN;}
ignition1StartAngle = ignition1EndAngle - dwellAngle; // 360 - desired advance angle - number of degrees the dwell will take
if(ignition1StartAngle < 0) {ignition1StartAngle += CRANK_ANGLE_MAX_IGN;}
}
inline void calculateIgnitionAngle2(int dwellAngle)
{
ignition2EndAngle = channel2IgnDegrees - currentStatus.advance;
if(ignition2EndAngle > CRANK_ANGLE_MAX_IGN) {ignition2EndAngle -= CRANK_ANGLE_MAX_IGN;}
ignition2StartAngle = ignition2EndAngle - dwellAngle;
if(ignition2StartAngle < 0) {ignition2StartAngle += CRANK_ANGLE_MAX_IGN;}
}
inline void calculateIgnitionAngle3(int dwellAngle)
{
ignition3EndAngle = channel3IgnDegrees - currentStatus.advance;
if(ignition3EndAngle > CRANK_ANGLE_MAX_IGN) {ignition3EndAngle -= CRANK_ANGLE_MAX_IGN;}
ignition3StartAngle = ignition3EndAngle - dwellAngle;
if(ignition3StartAngle < 0) {ignition3StartAngle += CRANK_ANGLE_MAX_IGN;}
}
// ignition 3 for rotary
inline void calculateIgnitionAngle3(int dwellAngle, int rotarySplitDegrees)
{
ignition3EndAngle = ignition1EndAngle + rotarySplitDegrees;
ignition3StartAngle = ignition3EndAngle - dwellAngle;
if(ignition3StartAngle > CRANK_ANGLE_MAX_IGN) {ignition3StartAngle -= CRANK_ANGLE_MAX_IGN;}
if(ignition3StartAngle < 0) {ignition3StartAngle += CRANK_ANGLE_MAX_IGN;}
}
inline void calculateIgnitionAngle4(int dwellAngle)
{
ignition4EndAngle = channel4IgnDegrees - currentStatus.advance;
if(ignition4EndAngle > CRANK_ANGLE_MAX_IGN) {ignition4EndAngle -= CRANK_ANGLE_MAX_IGN;}
ignition4StartAngle = ignition4EndAngle - dwellAngle;
if(ignition4StartAngle < 0) {ignition4StartAngle += CRANK_ANGLE_MAX_IGN;}
}
// ignition 4 for rotary
inline void calculateIgnitionAngle4(int dwellAngle, int rotarySplitDegrees)
{
ignition4EndAngle = ignition2EndAngle + rotarySplitDegrees;
ignition4StartAngle = ignition4EndAngle - dwellAngle;
if(ignition4StartAngle > CRANK_ANGLE_MAX_IGN) {ignition4StartAngle -= CRANK_ANGLE_MAX_IGN;}
if(ignition4StartAngle < 0) {ignition4StartAngle += CRANK_ANGLE_MAX_IGN;}
}
inline void calculateIgnitionAngle5(int dwellAngle)
{
ignition5EndAngle = channel5IgnDegrees - currentStatus.advance;
if(ignition5EndAngle > CRANK_ANGLE_MAX_IGN) {ignition5EndAngle -= CRANK_ANGLE_MAX_IGN;}
ignition5StartAngle = ignition5EndAngle - dwellAngle;
if(ignition5StartAngle < 0) {ignition5StartAngle += CRANK_ANGLE_MAX_IGN;}
}
inline void calculateIgnitionAngle6(int dwellAngle)
{
ignition6EndAngle = channel6IgnDegrees - currentStatus.advance;
if(ignition6EndAngle > CRANK_ANGLE_MAX_IGN) {ignition6EndAngle -= CRANK_ANGLE_MAX_IGN;}
ignition6StartAngle = ignition6EndAngle - dwellAngle;
if(ignition6StartAngle < 0) {ignition6StartAngle += CRANK_ANGLE_MAX_IGN;}
}
inline void calculateIgnitionAngle7(int dwellAngle)
{
ignition7EndAngle = channel7IgnDegrees - currentStatus.advance;
if(ignition7EndAngle > CRANK_ANGLE_MAX_IGN) {ignition7EndAngle -= CRANK_ANGLE_MAX_IGN;}
ignition7StartAngle = ignition7EndAngle - dwellAngle;
if(ignition7StartAngle < 0) {ignition7StartAngle += CRANK_ANGLE_MAX_IGN;}
}
inline void calculateIgnitionAngle8(int dwellAngle)
{
ignition8EndAngle = channel8IgnDegrees - currentStatus.advance;
if(ignition8EndAngle > CRANK_ANGLE_MAX_IGN) {ignition8EndAngle -= CRANK_ANGLE_MAX_IGN;}
ignition8StartAngle = ignition8EndAngle - dwellAngle;
if(ignition8StartAngle < 0) {ignition8StartAngle += CRANK_ANGLE_MAX_IGN;}
}
inline uint32_t calculateIgnition1Timeout(int crankAngle)
{
if ( (ignition1StartAngle <= crankAngle) && (ignitionSchedule1.Status == RUNNING) ) { ignition1StartAngle += CRANK_ANGLE_MAX_IGN; }
if ( ignition1StartAngle > crankAngle)
{
return angleToTime((ignition1StartAngle - crankAngle), CRANKMATH_METHOD_INTERVAL_REV);
}
return 0;
}
inline uint32_t calculateIgnitionNTimeout(const Schedule &schedule, int startAngle, int channelIgnDegrees, int crankAngle)
{
int tempCrankAngle = crankAngle - channelIgnDegrees;
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_IGN; }
int tempStartAngle = startAngle - channelIgnDegrees;
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_IGN; }
if ( (tempStartAngle <= tempCrankAngle) && (schedule.Status == RUNNING) ) { tempStartAngle += CRANK_ANGLE_MAX_IGN; }
if(tempStartAngle > tempCrankAngle)
{
return angleToTime((tempStartAngle - tempCrankAngle), CRANKMATH_METHOD_INTERVAL_REV);
}
return 0U;
}

View File

@ -19,19 +19,6 @@ uint16_t PW(int REQ_FUEL, byte VE, long MAP, uint16_t corrections, int injOpen);
byte getVE1(void);
byte getAdvance1(void);
uint16_t calculateInjectorStartAngle(uint16_t PWdivTimerPerDegree, int16_t injChannelDegrees);
void calculateIgnitionAngle1(int dwellAngle);
void calculateIgnitionAngle2(int dwellAngle);
void calculateIgnitionAngle3(int dwellAngle);
void calculateIgnitionAngle3(int dwellAngle, int rotarySplitDegrees);
void calculateIgnitionAngle4(int dwellAngle);
void calculateIgnitionAngle4(int dwellAngle, int rotarySplitDegrees);
void calculateIgnitionAngle5(int dwellAngle);
void calculateIgnitionAngle6(int dwellAngle);
void calculateIgnitionAngle7(int dwellAngle);
void calculateIgnitionAngle8(int dwellAngle);
void calculateIgnitionAngles(int dwellAngle);
extern uint16_t req_fuel_uS; /**< The required fuel variable (As calculated by TunerStudio) in uS */
extern uint16_t inj_opentime_uS; /**< The injector opening time. This is set within Tuner Studio, but stored here in uS rather than mS */
@ -42,23 +29,6 @@ extern byte curRollingCut; /**< Rolling rev limiter, current ignition channel be
extern byte rollingCutCounter; /**< how many times (revolutions) the ignition has been cut in a row */
extern uint32_t rollingCutLastRev; /**< Tracks whether we're on the same or a different rev for the rolling cut */
extern int channel1IgnDegrees; /**< The number of crank degrees until cylinder 1 is at TDC (This is obviously 0 for virtually ALL engines, but there's some weird ones) */
extern int channel2IgnDegrees; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
extern int channel3IgnDegrees; /**< The number of crank degrees until cylinder 3 (and 5/6/7/8) is at TDC */
extern int channel4IgnDegrees; /**< The number of crank degrees until cylinder 4 (and 5/6/7/8) is at TDC */
extern int channel5IgnDegrees; /**< The number of crank degrees until cylinder 5 is at TDC */
extern int channel6IgnDegrees; /**< The number of crank degrees until cylinder 6 is at TDC */
extern int channel7IgnDegrees; /**< The number of crank degrees until cylinder 7 is at TDC */
extern int channel8IgnDegrees; /**< The number of crank degrees until cylinder 8 is at TDC */
extern int channel1InjDegrees; /**< The number of crank degrees until cylinder 1 is at TDC (This is obviously 0 for virtually ALL engines, but there's some weird ones) */
extern int channel2InjDegrees; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
extern int channel3InjDegrees; /**< The number of crank degrees until cylinder 3 (and 5/6/7/8) is at TDC */
extern int channel4InjDegrees; /**< The number of crank degrees until cylinder 4 (and 5/6/7/8) is at TDC */
extern int channel5InjDegrees; /**< The number of crank degrees until cylinder 5 is at TDC */
extern int channel6InjDegrees; /**< The number of crank degrees until cylinder 6 is at TDC */
extern int channel7InjDegrees; /**< The number of crank degrees until cylinder 7 is at TDC */
extern int channel8InjDegrees; /**< The number of crank degrees until cylinder 8 is at TDC */
/** @name Staging
* These values are a percentage of the total (Combined) req_fuel value that would be required for each injector channel to deliver that much fuel.
*

View File

@ -43,34 +43,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "secondaryTables.h"
#include "canBroadcast.h"
#include "SD_logger.h"
#include "schedule_calcs.h"
#include RTC_LIB_H //Defined in each boards .h file
#include BOARD_H //Note that this is not a real file, it is defined in globals.h.
int ignition1StartAngle = 0;
int ignition2StartAngle = 0;
int ignition3StartAngle = 0;
int ignition4StartAngle = 0;
int ignition5StartAngle = 0;
int ignition6StartAngle = 0;
int ignition7StartAngle = 0;
int ignition8StartAngle = 0;
int channel1IgnDegrees = 0; /**< The number of crank degrees until cylinder 1 is at TDC (This is obviously 0 for virtually ALL engines, but there's some weird ones) */
int channel2IgnDegrees = 0; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
int channel3IgnDegrees = 0; /**< The number of crank degrees until cylinder 3 (and 5/6/7/8) is at TDC */
int channel4IgnDegrees = 0; /**< The number of crank degrees until cylinder 4 (and 5/6/7/8) is at TDC */
int channel5IgnDegrees = 0; /**< The number of crank degrees until cylinder 5 is at TDC */
int channel6IgnDegrees = 0; /**< The number of crank degrees until cylinder 6 is at TDC */
int channel7IgnDegrees = 0; /**< The number of crank degrees until cylinder 7 is at TDC */
int channel8IgnDegrees = 0; /**< The number of crank degrees until cylinder 8 is at TDC */
int channel1InjDegrees = 0; /**< The number of crank degrees until cylinder 1 is at TDC (This is obviously 0 for virtually ALL engines, but there's some weird ones) */
int channel2InjDegrees = 0; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
int channel3InjDegrees = 0; /**< The number of crank degrees until cylinder 3 (and 5/6/7/8) is at TDC */
int channel4InjDegrees = 0; /**< The number of crank degrees until cylinder 4 (and 5/6/7/8) is at TDC */
int channel5InjDegrees = 0; /**< The number of crank degrees until cylinder 5 is at TDC */
int channel6InjDegrees = 0; /**< The number of crank degrees until cylinder 6 is at TDC */
int channel7InjDegrees = 0; /**< The number of crank degrees until cylinder 7 is at TDC */
int channel8InjDegrees = 0; /**< The number of crank degrees until cylinder 8 is at TDC */
uint16_t req_fuel_uS = 0; /**< The required fuel variable (As calculated by TunerStudio) in uS */
uint16_t inj_opentime_uS = 0;
@ -505,10 +481,6 @@ void loop(void)
#if INJ_CHANNELS >= 8
uint16_t injector8StartAngle = 0;
#endif
//These are used for comparisons on channels above 1 where the starting angle (for injectors or ignition) can be less than a single loop time
//(Don't ask why this is needed, it's just there)
int tempCrankAngle;
int tempStartAngle;
doCrankSpeedCalcs(); //In crankMaths.ino
@ -1047,11 +1019,11 @@ void loop(void)
{
if(currentStatus.PW1 >= inj_opentime_uS)
{
if ( (injector1StartAngle <= crankAngle) && (fuelSchedule1.Status == RUNNING) ) { injector1StartAngle += CRANK_ANGLE_MAX_INJ; }
if (injector1StartAngle > crankAngle)
uint32_t timeOut = calculateInjector1Timeout(injector1StartAngle, crankAngle);
if (timeOut>0U)
{
setFuelSchedule1(
((injector1StartAngle - crankAngle) * (unsigned long)timePerDegree),
timeOut,
(unsigned long)currentStatus.PW1
);
}
@ -1071,15 +1043,11 @@ void loop(void)
#if INJ_CHANNELS >= 2
if( (BIT_CHECK(channelInjEnabled, INJ2_CMD_BIT) == true) && (currentStatus.PW2 >= inj_opentime_uS) )
{
tempCrankAngle = crankAngle - channel2InjDegrees;
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_INJ; }
tempStartAngle = injector2StartAngle - channel2InjDegrees;
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_INJ; }
if ( (tempStartAngle <= tempCrankAngle) && (fuelSchedule2.Status == RUNNING) ) { tempStartAngle += CRANK_ANGLE_MAX_INJ; }
if ( tempStartAngle > tempCrankAngle )
uint32_t timeOut = calculateInjectorNTimeout(fuelSchedule2, channel2InjDegrees, injector2StartAngle, crankAngle);
if ( timeOut>0U )
{
setFuelSchedule2(
((tempStartAngle - tempCrankAngle) * (unsigned long)timePerDegree),
timeOut,
(unsigned long)currentStatus.PW2
);
}
@ -1089,15 +1057,11 @@ void loop(void)
#if INJ_CHANNELS >= 3
if( (BIT_CHECK(channelInjEnabled, INJ3_CMD_BIT) == true) && (currentStatus.PW3 >= inj_opentime_uS) )
{
tempCrankAngle = crankAngle - channel3InjDegrees;
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_INJ; }
tempStartAngle = injector3StartAngle - channel3InjDegrees;
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_INJ; }
if ( (tempStartAngle <= tempCrankAngle) && (fuelSchedule3.Status == RUNNING) ) { tempStartAngle += CRANK_ANGLE_MAX_INJ; }
if ( tempStartAngle > tempCrankAngle )
uint32_t timeOut = calculateInjectorNTimeout(fuelSchedule3, channel3InjDegrees, injector3StartAngle, crankAngle);
if ( timeOut>0U )
{
setFuelSchedule3(
((tempStartAngle - tempCrankAngle) * (unsigned long)timePerDegree),
timeOut,
(unsigned long)currentStatus.PW3
);
}
@ -1107,15 +1071,11 @@ void loop(void)
#if INJ_CHANNELS >= 4
if( (BIT_CHECK(channelInjEnabled, INJ4_CMD_BIT) == true) && (currentStatus.PW4 >= inj_opentime_uS) )
{
tempCrankAngle = crankAngle - channel4InjDegrees;
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_INJ; }
tempStartAngle = injector4StartAngle - channel4InjDegrees;
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_INJ; }
if ( (tempStartAngle <= tempCrankAngle) && (fuelSchedule4.Status == RUNNING) ) { tempStartAngle += CRANK_ANGLE_MAX_INJ; }
if ( tempStartAngle > tempCrankAngle )
uint32_t timeOut = calculateInjectorNTimeout(fuelSchedule4, channel4InjDegrees, injector4StartAngle, crankAngle);
if ( timeOut>0U )
{
setFuelSchedule4(
((tempStartAngle - tempCrankAngle) * (unsigned long)timePerDegree),
timeOut,
(unsigned long)currentStatus.PW4
);
}
@ -1125,23 +1085,11 @@ void loop(void)
#if INJ_CHANNELS >= 5
if( (BIT_CHECK(channelInjEnabled, INJ5_CMD_BIT) == true) && (currentStatus.PW5 >= inj_opentime_uS) )
{
tempCrankAngle = crankAngle - channel5InjDegrees;
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_INJ; }
tempStartAngle = injector5StartAngle - channel5InjDegrees;
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_INJ; }
if ( (tempStartAngle <= tempCrankAngle) && (fuelSchedule5.Status == RUNNING) ) { tempStartAngle += CRANK_ANGLE_MAX_INJ; }
if ( tempStartAngle > tempCrankAngle )
uint32_t timeOut = calculateInjectorNTimeout(fuelSchedule5, channel5InjDegrees, injector5StartAngle, crankAngle);
if ( timeOut>0U )
{
//Note the hacky use of fuel schedule 3 below
/*
setFuelSchedule3(openInjector3and5,
((unsigned long)(tempStartAngle - tempCrankAngle) * (unsigned long)timePerDegree),
(unsigned long)currentStatus.PW1,
closeInjector3and5
);*/
setFuelSchedule5(
((tempStartAngle - tempCrankAngle) * (unsigned long)timePerDegree),
timeOut,
(unsigned long)currentStatus.PW5
);
}
@ -1151,15 +1099,11 @@ void loop(void)
#if INJ_CHANNELS >= 6
if( (BIT_CHECK(channelInjEnabled, INJ6_CMD_BIT) == true) && (currentStatus.PW6 >= inj_opentime_uS) )
{
tempCrankAngle = crankAngle - channel6InjDegrees;
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_INJ; }
tempStartAngle = injector6StartAngle - channel6InjDegrees;
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_INJ; }
if ( (tempStartAngle <= tempCrankAngle) && (fuelSchedule6.Status == RUNNING) ) { tempStartAngle += CRANK_ANGLE_MAX_INJ; }
if ( tempStartAngle > tempCrankAngle )
uint32_t timeOut = calculateInjectorNTimeout(fuelSchedule6, channel6InjDegrees, injector6StartAngle, crankAngle);
if ( timeOut>0U )
{
setFuelSchedule6(
((tempStartAngle - tempCrankAngle) * (unsigned long)timePerDegree),
timeOut,
(unsigned long)currentStatus.PW6
);
}
@ -1169,15 +1113,11 @@ void loop(void)
#if INJ_CHANNELS >= 7
if( (BIT_CHECK(channelInjEnabled, INJ7_CMD_BIT) == true) && (currentStatus.PW7 >= inj_opentime_uS) )
{
tempCrankAngle = crankAngle - channel7InjDegrees;
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_INJ; }
tempStartAngle = injector7StartAngle - channel7InjDegrees;
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_INJ; }
if ( (tempStartAngle <= tempCrankAngle) && (fuelSchedule7.Status == RUNNING) ) { tempStartAngle += CRANK_ANGLE_MAX_INJ; }
if ( tempStartAngle > tempCrankAngle )
uint32_t timeOut = calculateInjectorNTimeout(fuelSchedule7, channel7InjDegrees, injector7StartAngle, crankAngle);
if ( timeOut>0U )
{
setFuelSchedule7(
((tempStartAngle - tempCrankAngle) * (unsigned long)timePerDegree),
timeOut,
(unsigned long)currentStatus.PW7
);
}
@ -1187,15 +1127,11 @@ void loop(void)
#if INJ_CHANNELS >= 8
if( (BIT_CHECK(channelInjEnabled, INJ8_CMD_BIT) == true) && (currentStatus.PW8 >= inj_opentime_uS) )
{
tempCrankAngle = crankAngle - channel8InjDegrees;
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_INJ; }
tempStartAngle = injector8StartAngle - channel8InjDegrees;
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_INJ; }
if ( (tempStartAngle <= tempCrankAngle) && (fuelSchedule8.Status == RUNNING) ) { tempStartAngle += CRANK_ANGLE_MAX_INJ; }
if ( tempStartAngle > tempCrankAngle )
uint32_t timeOut = calculateInjectorNTimeout(fuelSchedule8, channel8InjDegrees, injector8StartAngle, crankAngle);
if ( timeOut>0U )
{
setFuelSchedule8(
((tempStartAngle - tempCrankAngle) * (unsigned long)timePerDegree),
timeOut,
(unsigned long)currentStatus.PW8
);
}
@ -1233,14 +1169,13 @@ void loop(void)
while (crankAngle > CRANK_ANGLE_MAX_IGN ) { crankAngle -= CRANK_ANGLE_MAX_IGN; }
#if IGN_CHANNELS >= 1
if ( (ignition1StartAngle <= crankAngle) && (ignitionSchedule1.Status == RUNNING) ) { ignition1StartAngle += CRANK_ANGLE_MAX_IGN; }
//if ( (ignition1StartAngle > crankAngle) && (curRollingCut != 1) )
if ( (ignition1StartAngle > crankAngle) && (!BIT_CHECK(curRollingCut, IGN1_CMD_BIT)) )
uint32_t timeOut = calculateIgnition1Timeout(crankAngle);
if ( (timeOut > 0U) && (!BIT_CHECK(curRollingCut, IGN1_CMD_BIT)) )
{
setIgnitionSchedule1(ign1StartFunction,
//((unsigned long)(ignition1StartAngle - crankAngle) * (unsigned long)timePerDegree),
angleToTime((ignition1StartAngle - crankAngle), CRANKMATH_METHOD_INTERVAL_REV),
timeOut,
currentStatus.dwell + fixedCrankingOverride, //((unsigned long)((unsigned long)currentStatus.dwell* currentStatus.RPM) / newRPM) + fixedCrankingOverride,
ign1EndFunction
);
@ -1270,16 +1205,7 @@ void loop(void)
#if IGN_CHANNELS >= 2
if (maxIgnOutputs >= 2)
{
tempCrankAngle = crankAngle - channel2IgnDegrees;
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_IGN; }
tempStartAngle = ignition2StartAngle - channel2IgnDegrees;
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_IGN; }
unsigned long ignition2StartTime = 0;
if ( (tempStartAngle <= tempCrankAngle) && (ignitionSchedule2.Status == RUNNING) ) { tempStartAngle += CRANK_ANGLE_MAX_IGN; }
if(tempStartAngle > tempCrankAngle) { ignition2StartTime = angleToTime((tempStartAngle - tempCrankAngle), CRANKMATH_METHOD_INTERVAL_REV); }
//else if (tempStartAngle < tempCrankAngle) { ignition2StartTime = ((long)(360 - tempCrankAngle + tempStartAngle) * (long)timePerDegree); }
else { ignition2StartTime = 0; }
unsigned long ignition2StartTime = calculateIgnitionNTimeout(ignitionSchedule2, ignition2StartAngle, channel2IgnDegrees, crankAngle);
if ( (ignition2StartTime > 0) && (!BIT_CHECK(curRollingCut, IGN2_CMD_BIT)) )
{
@ -1295,16 +1221,7 @@ void loop(void)
#if IGN_CHANNELS >= 3
if (maxIgnOutputs >= 3)
{
tempCrankAngle = crankAngle - channel3IgnDegrees;
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_IGN; }
tempStartAngle = ignition3StartAngle - channel3IgnDegrees;
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_IGN; }
unsigned long ignition3StartTime = 0;
if ( (tempStartAngle <= tempCrankAngle) && (ignitionSchedule3.Status == RUNNING) ) { tempStartAngle += CRANK_ANGLE_MAX_IGN; }
if(tempStartAngle > tempCrankAngle) { ignition3StartTime = angleToTime((tempStartAngle - tempCrankAngle), CRANKMATH_METHOD_INTERVAL_REV); }
//else if (tempStartAngle < tempCrankAngle) { ignition3StartTime = ((long)(360 - tempCrankAngle + tempStartAngle) * (long)timePerDegree); }
else { ignition3StartTime = 0; }
unsigned long ignition3StartTime = calculateIgnitionNTimeout(ignitionSchedule3, ignition3StartAngle, channel3IgnDegrees, crankAngle);
if ( (ignition3StartTime > 0) && (!BIT_CHECK(curRollingCut, IGN3_CMD_BIT)) )
{
@ -1320,16 +1237,7 @@ void loop(void)
#if IGN_CHANNELS >= 4
if (maxIgnOutputs >= 4)
{
tempCrankAngle = crankAngle - channel4IgnDegrees;
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_IGN; }
tempStartAngle = ignition4StartAngle - channel4IgnDegrees;
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_IGN; }
unsigned long ignition4StartTime = 0;
if ( (tempStartAngle <= tempCrankAngle) && (ignitionSchedule4.Status == RUNNING) ) { tempStartAngle += CRANK_ANGLE_MAX_IGN; }
if(tempStartAngle > tempCrankAngle) { ignition4StartTime = angleToTime((tempStartAngle - tempCrankAngle), CRANKMATH_METHOD_INTERVAL_REV); }
//else if (tempStartAngle < tempCrankAngle) { ignition4StartTime = ((long)(360 - tempCrankAngle + tempStartAngle) * (long)timePerDegree); }
else { ignition4StartTime = 0; }
unsigned long ignition4StartTime = calculateIgnitionNTimeout(ignitionSchedule4, ignition4StartAngle, channel4IgnDegrees, crankAngle);
if ( (ignition4StartTime > 0) && (!BIT_CHECK(curRollingCut, IGN4_CMD_BIT)) )
{
@ -1345,16 +1253,7 @@ void loop(void)
#if IGN_CHANNELS >= 5
if (maxIgnOutputs >= 5)
{
tempCrankAngle = crankAngle - channel5IgnDegrees;
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_IGN; }
tempStartAngle = ignition5StartAngle - channel5IgnDegrees;
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_IGN; }
unsigned long ignition5StartTime = 0;
if ( (tempStartAngle <= tempCrankAngle) && (ignitionSchedule5.Status == RUNNING) ) { tempStartAngle += CRANK_ANGLE_MAX_IGN; }
if(tempStartAngle > tempCrankAngle) { ignition5StartTime = angleToTime((tempStartAngle - tempCrankAngle), CRANKMATH_METHOD_INTERVAL_REV); }
//else if (tempStartAngle < tempCrankAngle) { ignition5StartTime = ((long)(360 - tempCrankAngle + tempStartAngle) * (long)timePerDegree); }
else { ignition5StartTime = 0; }
unsigned long ignition5StartTime = calculateIgnitionNTimeout(ignitionSchedule5, ignition5StartAngle, channel5IgnDegrees, crankAngle);
if ( (ignition5StartTime > 0) && (!BIT_CHECK(curRollingCut, IGN5_CMD_BIT)) )
{
@ -1370,16 +1269,7 @@ void loop(void)
#if IGN_CHANNELS >= 6
if (maxIgnOutputs >= 6)
{
tempCrankAngle = crankAngle - channel6IgnDegrees;
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_IGN; }
tempStartAngle = ignition6StartAngle - channel6IgnDegrees;
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_IGN; }
unsigned long ignition6StartTime = 0;
if ( (tempStartAngle <= tempCrankAngle) && (ignitionSchedule6.Status == RUNNING) ) { tempStartAngle += CRANK_ANGLE_MAX_IGN; }
if(tempStartAngle > tempCrankAngle) { ignition6StartTime = angleToTime((tempStartAngle - tempCrankAngle), CRANKMATH_METHOD_INTERVAL_REV); }
//else if (tempStartAngle < tempCrankAngle) { ignition6StartTime = ((long)(360 - tempCrankAngle + tempStartAngle) * (long)timePerDegree); }
else { ignition6StartTime = 0; }
unsigned long ignition6StartTime = calculateIgnitionNTimeout(ignitionSchedule6, ignition6StartAngle, channel6IgnDegrees, crankAngle);
if ( (ignition6StartTime > 0) && (!BIT_CHECK(curRollingCut, IGN6_CMD_BIT)) )
{
@ -1395,16 +1285,7 @@ void loop(void)
#if IGN_CHANNELS >= 7
if (maxIgnOutputs >= 7)
{
tempCrankAngle = crankAngle - channel7IgnDegrees;
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_IGN; }
tempStartAngle = ignition7StartAngle - channel7IgnDegrees;
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_IGN; }
unsigned long ignition7StartTime = 0;
if ( (tempStartAngle <= tempCrankAngle) && (ignitionSchedule7.Status == RUNNING) ) { tempStartAngle += CRANK_ANGLE_MAX_IGN; }
if(tempStartAngle > tempCrankAngle) { ignition7StartTime = angleToTime((tempStartAngle - tempCrankAngle), CRANKMATH_METHOD_INTERVAL_REV); }
//else if (tempStartAngle < tempCrankAngle) { ignition7StartTime = ((long)(360 - tempCrankAngle + tempStartAngle) * (long)timePerDegree); }
else { ignition7StartTime = 0; }
unsigned long ignition7StartTime = calculateIgnitionNTimeout(ignitionSchedule7, ignition7StartAngle, channel7IgnDegrees, crankAngle);
if ( (ignition7StartTime > 0) && (!BIT_CHECK(curRollingCut, IGN7_CMD_BIT)) )
{
@ -1420,16 +1301,7 @@ void loop(void)
#if IGN_CHANNELS >= 8
if (maxIgnOutputs >= 8)
{
tempCrankAngle = crankAngle - channel8IgnDegrees;
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX_IGN; }
tempStartAngle = ignition8StartAngle - channel8IgnDegrees;
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_IGN; }
unsigned long ignition8StartTime = 0;
if ( (tempStartAngle <= tempCrankAngle) && (ignitionSchedule8.Status == RUNNING) ) { tempStartAngle += CRANK_ANGLE_MAX_IGN; }
if(tempStartAngle > tempCrankAngle) { ignition8StartTime = angleToTime((tempStartAngle - tempCrankAngle), CRANKMATH_METHOD_INTERVAL_REV); }
//else if (tempStartAngle < tempCrankAngle) { ignition8StartTime = ((long)(360 - tempCrankAngle + tempStartAngle) * (long)timePerDegree); }
else { ignition8StartTime = 0; }
unsigned long ignition8StartTime = calculateIgnitionNTimeout(ignitionSchedule8, ignition8StartAngle, channel8IgnDegrees, crankAngle);
if ( (ignition8StartTime > 0) && (!BIT_CHECK(curRollingCut, IGN8_CMD_BIT)) )
{
@ -1595,97 +1467,6 @@ byte getAdvance1(void)
return tempAdvance;
}
uint16_t calculateInjectorStartAngle(uint16_t PWdivTimerPerDegree, int16_t injChannelDegrees)
{
uint16_t tempInjectorStartAngle = (currentStatus.injAngle + injChannelDegrees);
if(tempInjectorStartAngle < PWdivTimerPerDegree) { tempInjectorStartAngle += CRANK_ANGLE_MAX_INJ; }
tempInjectorStartAngle -= PWdivTimerPerDegree;
while(tempInjectorStartAngle > (uint16_t)CRANK_ANGLE_MAX_INJ) { tempInjectorStartAngle -= CRANK_ANGLE_MAX_INJ; }
return tempInjectorStartAngle;
}
void calculateIgnitionAngle1(int dwellAngle)
{
ignition1EndAngle = CRANK_ANGLE_MAX_IGN - currentStatus.advance;
if(ignition1EndAngle > CRANK_ANGLE_MAX_IGN) {ignition1EndAngle -= CRANK_ANGLE_MAX_IGN;}
ignition1StartAngle = ignition1EndAngle - dwellAngle; // 360 - desired advance angle - number of degrees the dwell will take
if(ignition1StartAngle < 0) {ignition1StartAngle += CRANK_ANGLE_MAX_IGN;}
}
void calculateIgnitionAngle2(int dwellAngle)
{
ignition2EndAngle = channel2IgnDegrees - currentStatus.advance;
if(ignition2EndAngle > CRANK_ANGLE_MAX_IGN) {ignition2EndAngle -= CRANK_ANGLE_MAX_IGN;}
ignition2StartAngle = ignition2EndAngle - dwellAngle;
if(ignition2StartAngle < 0) {ignition2StartAngle += CRANK_ANGLE_MAX_IGN;}
}
void calculateIgnitionAngle3(int dwellAngle)
{
ignition3EndAngle = channel3IgnDegrees - currentStatus.advance;
if(ignition3EndAngle > CRANK_ANGLE_MAX_IGN) {ignition3EndAngle -= CRANK_ANGLE_MAX_IGN;}
ignition3StartAngle = ignition3EndAngle - dwellAngle;
if(ignition3StartAngle < 0) {ignition3StartAngle += CRANK_ANGLE_MAX_IGN;}
}
// ignition 3 for rotary
void calculateIgnitionAngle3(int dwellAngle, int rotarySplitDegrees)
{
ignition3EndAngle = ignition1EndAngle + rotarySplitDegrees;
ignition3StartAngle = ignition3EndAngle - dwellAngle;
if(ignition3StartAngle > CRANK_ANGLE_MAX_IGN) {ignition3StartAngle -= CRANK_ANGLE_MAX_IGN;}
if(ignition3StartAngle < 0) {ignition3StartAngle += CRANK_ANGLE_MAX_IGN;}
}
void calculateIgnitionAngle4(int dwellAngle)
{
ignition4EndAngle = channel4IgnDegrees - currentStatus.advance;
if(ignition4EndAngle > CRANK_ANGLE_MAX_IGN) {ignition4EndAngle -= CRANK_ANGLE_MAX_IGN;}
ignition4StartAngle = ignition4EndAngle - dwellAngle;
if(ignition4StartAngle < 0) {ignition4StartAngle += CRANK_ANGLE_MAX_IGN;}
}
// ignition 4 for rotary
void calculateIgnitionAngle4(int dwellAngle, int rotarySplitDegrees)
{
ignition4EndAngle = ignition2EndAngle + rotarySplitDegrees;
ignition4StartAngle = ignition4EndAngle - dwellAngle;
if(ignition4StartAngle > CRANK_ANGLE_MAX_IGN) {ignition4StartAngle -= CRANK_ANGLE_MAX_IGN;}
if(ignition4StartAngle < 0) {ignition4StartAngle += CRANK_ANGLE_MAX_IGN;}
}
void calculateIgnitionAngle5(int dwellAngle)
{
ignition5EndAngle = channel5IgnDegrees - currentStatus.advance;
if(ignition5EndAngle > CRANK_ANGLE_MAX_IGN) {ignition5EndAngle -= CRANK_ANGLE_MAX_IGN;}
ignition5StartAngle = ignition5EndAngle - dwellAngle;
if(ignition5StartAngle < 0) {ignition5StartAngle += CRANK_ANGLE_MAX_IGN;}
}
void calculateIgnitionAngle6(int dwellAngle)
{
ignition6EndAngle = channel6IgnDegrees - currentStatus.advance;
if(ignition6EndAngle > CRANK_ANGLE_MAX_IGN) {ignition6EndAngle -= CRANK_ANGLE_MAX_IGN;}
ignition6StartAngle = ignition6EndAngle - dwellAngle;
if(ignition6StartAngle < 0) {ignition6StartAngle += CRANK_ANGLE_MAX_IGN;}
}
void calculateIgnitionAngle7(int dwellAngle)
{
ignition7EndAngle = channel7IgnDegrees - currentStatus.advance;
if(ignition7EndAngle > CRANK_ANGLE_MAX_IGN) {ignition7EndAngle -= CRANK_ANGLE_MAX_IGN;}
ignition7StartAngle = ignition7EndAngle - dwellAngle;
if(ignition7StartAngle < 0) {ignition7StartAngle += CRANK_ANGLE_MAX_IGN;}
}
void calculateIgnitionAngle8(int dwellAngle)
{
ignition8EndAngle = channel8IgnDegrees - currentStatus.advance;
if(ignition8EndAngle > CRANK_ANGLE_MAX_IGN) {ignition8EndAngle -= CRANK_ANGLE_MAX_IGN;}
ignition8StartAngle = ignition8EndAngle - dwellAngle;
if(ignition8StartAngle < 0) {ignition8StartAngle += CRANK_ANGLE_MAX_IGN;}
}
/** Calculate the Ignition angles for all cylinders (based on @ref config2.nCylinders).
* both start and end angles are calculated for each channel.
* Also the mode of ignition firing - wasted spark vs. dedicated spark per cyl. - is considered here.

View File

@ -0,0 +1 @@
void testFordST170();

View File

@ -0,0 +1,178 @@
#include <decoders.h>
#include <globals.h>
#include <unity.h>
#include "FordST170.h"
#include "scheduler.h"
#include "schedule_calcs.h"
extern uint16_t ignition1EndTooth;
extern uint16_t ignition2EndTooth;
extern uint16_t ignition3EndTooth;
extern uint16_t ignition4EndTooth;
void test_fordst170_newIgn_12_trig0_1()
{
//Test the set end tooth function. Conditions:
//Trigger: 12/1
//Advance: 10
//triggerAngle=0
triggerSetup_FordST170();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = 0; //No trigger offset
currentStatus.advance = 10;
calculateIgnitionAngle1(5);
triggerSetEndTeeth_FordST170();
TEST_ASSERT_EQUAL(34, ignition1EndTooth);
//Test again with 0 degrees advance
currentStatus.advance = 0;
calculateIgnitionAngle1(5);
triggerSetEndTeeth_FordST170();
TEST_ASSERT_EQUAL(35, ignition1EndTooth);
//Test again with 35 degrees advance
currentStatus.advance = 35;
calculateIgnitionAngle1(5);
triggerSetEndTeeth_FordST170();
TEST_ASSERT_EQUAL(31, ignition1EndTooth);
}
void test_fordst170_newIgn_12_trig90_1()
{
//Test the set end tooth function. Conditions:
//Trigger: 12/1
//Advance: 10
//triggerAngle=90
triggerSetup_FordST170();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = 90; //No trigger offset
currentStatus.advance = 35;
calculateIgnitionAngle1(5);
triggerSetEndTeeth_FordST170();
TEST_ASSERT_EQUAL(22, ignition1EndTooth);
}
void test_fordst170_newIgn_12_trig180_1()
{
//Test the set end tooth function. Conditions:
//Trigger: 36-1
//Advance: 10
//triggerAngle=180
triggerSetup_FordST170();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = 180; //No trigger offset
currentStatus.advance = 10;
calculateIgnitionAngle1(5);
triggerSetEndTeeth_FordST170();
TEST_ASSERT_EQUAL(16, ignition1EndTooth);
}
void test_fordst170_newIgn_12_trig270_1()
{
//Test the set end tooth function. Conditions:
//Trigger: 36-1
//Advance: 10
//triggerAngle=270
triggerSetup_FordST170();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = 270; //No trigger offset
currentStatus.advance = 10;
calculateIgnitionAngle1(5);
triggerSetEndTeeth_FordST170();
TEST_ASSERT_EQUAL(7, ignition1EndTooth);
}
void test_fordst170_newIgn_12_trig360_1()
{
//Test the set end tooth function. Conditions:
//Trigger: 36-1
//Advance: 10
//triggerAngle=360
triggerSetup_FordST170();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = 360; //No trigger offset
currentStatus.advance = 10;
calculateIgnitionAngle1(5);
triggerSetEndTeeth_FordST170();
TEST_ASSERT_EQUAL(34, ignition1EndTooth);
}
void test_fordst170_newIgn_12_trigNeg90_1()
{
//Test the set end tooth function. Conditions:
//Trigger: 36-1
//Advance: 10
//triggerAngle=-90
triggerSetup_FordST170();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = -90; //No trigger offset
currentStatus.advance = 10;
calculateIgnitionAngle1(5);
triggerSetEndTeeth_FordST170();
TEST_ASSERT_EQUAL(7, ignition1EndTooth);
}
void test_fordst170_newIgn_12_trigNeg180_1()
{
//Test the set end tooth function. Conditions:
//Trigger: 36-1
//Advance: 10
//triggerAngle=-180
triggerSetup_FordST170();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = -180; //No trigger offset
currentStatus.advance = 10;
calculateIgnitionAngle1(5);
triggerSetEndTeeth_FordST170();
TEST_ASSERT_EQUAL(16, ignition1EndTooth);
}
void test_fordst170_newIgn_12_trigNeg270_1()
{
//Test the set end tooth function. Conditions:
//Trigger: 36-1
//Advance: 10
//triggerAngle=-270
triggerSetup_FordST170();
configPage4.sparkMode = IGN_MODE_WASTED;
currentStatus.advance = 10; //Set 10 degrees advance
configPage4.triggerAngle = -270; //No trigger offset
triggerSetEndTeeth_FordST170();
TEST_ASSERT_EQUAL(25, ignition1EndTooth);
}
void test_fordst170_newIgn_12_trigNeg360_1()
{
//Test the set end tooth function. Conditions:
//Trigger: 36-1
//Advance: 10
//triggerAngle=-360
triggerSetup_FordST170();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = -360; //No trigger offset
currentStatus.advance = 10;
calculateIgnitionAngle1(5);
triggerSetEndTeeth_FordST170();
TEST_ASSERT_EQUAL(34, ignition1EndTooth);
}
void testFordST170()
{
RUN_TEST(test_fordst170_newIgn_12_trig0_1);
RUN_TEST(test_fordst170_newIgn_12_trig90_1);
RUN_TEST(test_fordst170_newIgn_12_trig180_1);
RUN_TEST(test_fordst170_newIgn_12_trig270_1);
RUN_TEST(test_fordst170_newIgn_12_trig360_1);
RUN_TEST(test_fordst170_newIgn_12_trigNeg90_1);
RUN_TEST(test_fordst170_newIgn_12_trigNeg180_1);
RUN_TEST(test_fordst170_newIgn_12_trigNeg270_1);
RUN_TEST(test_fordst170_newIgn_12_trigNeg360_1);
}

View File

@ -0,0 +1,153 @@
#include <decoders.h>
#include <globals.h>
#include <unity.h>
#include "test_ngc.h"
#include "scheduler.h"
#include "schedule_calcs.h"
extern uint16_t ignition1EndTooth;
extern uint16_t ignition2EndTooth;
extern uint16_t ignition3EndTooth;
extern uint16_t ignition4EndTooth;
void test_ngc_newIgn_12_trig0_1()
{
triggerSetup_NGC();
CRANK_ANGLE_MAX_IGN = 360;
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = 0; //No trigger offset
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(5);
triggerSetEndTeeth_NGC();
TEST_ASSERT_EQUAL(34, ignition1EndTooth);
//Test again with 0 degrees advance
currentStatus.advance = 0;
calculateIgnitionAngle1(5);
triggerSetEndTeeth_NGC();
TEST_ASSERT_EQUAL(34, ignition1EndTooth);
//Test again with 35 degrees advance
currentStatus.advance = 35;
calculateIgnitionAngle1(5);
triggerSetEndTeeth_NGC();
TEST_ASSERT_EQUAL(31, ignition1EndTooth);
}
void test_ngc_newIgn_12_trig90_1()
{
triggerSetup_NGC();
CRANK_ANGLE_MAX_IGN = 360;
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = 90;
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(5);
triggerSetEndTeeth_NGC();
TEST_ASSERT_EQUAL(25, ignition1EndTooth);
}
void test_ngc_newIgn_12_trig180_1()
{
triggerSetup_NGC();
CRANK_ANGLE_MAX_IGN = 360;
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = 180;
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(5);
triggerSetEndTeeth_NGC();
TEST_ASSERT_EQUAL(16, ignition1EndTooth);
}
void test_ngc_newIgn_12_trig270_1()
{
triggerSetup_NGC();
CRANK_ANGLE_MAX_IGN = 360;
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = 270;
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(5);
triggerSetEndTeeth_NGC();
TEST_ASSERT_EQUAL(7, ignition1EndTooth);
}
void test_ngc_newIgn_12_trig360_1()
{
triggerSetup_NGC();
CRANK_ANGLE_MAX_IGN = 360;
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = 360;
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(5);
triggerSetEndTeeth_NGC();
TEST_ASSERT_EQUAL(34, ignition1EndTooth);
}
void test_ngc_newIgn_12_trigNeg90_1()
{
triggerSetup_NGC();
CRANK_ANGLE_MAX_IGN = 360;
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = -90;
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(5);
triggerSetEndTeeth_NGC();
TEST_ASSERT_EQUAL(7, ignition1EndTooth);
}
void test_ngc_newIgn_12_trigNeg180_1()
{
triggerSetup_NGC();
CRANK_ANGLE_MAX_IGN = 360;
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = -180;
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(5);
triggerSetEndTeeth_NGC();
TEST_ASSERT_EQUAL(16, ignition1EndTooth);
}
void test_ngc_newIgn_12_trigNeg270_1()
{
triggerSetup_NGC();
CRANK_ANGLE_MAX_IGN = 360;
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = -270;
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(5);
triggerSetEndTeeth_NGC();
TEST_ASSERT_EQUAL(25, ignition1EndTooth);
}
void test_ngc_newIgn_12_trigNeg360_1()
{
triggerSetup_NGC();
CRANK_ANGLE_MAX_IGN = 360;
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = -360;
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(5);
triggerSetEndTeeth_NGC();
TEST_ASSERT_EQUAL(34, ignition1EndTooth);
}
void testNGC()
{
RUN_TEST(test_ngc_newIgn_12_trig0_1);
RUN_TEST(test_ngc_newIgn_12_trig90_1);
RUN_TEST(test_ngc_newIgn_12_trig180_1);
RUN_TEST(test_ngc_newIgn_12_trig270_1);
RUN_TEST(test_ngc_newIgn_12_trig360_1);
RUN_TEST(test_ngc_newIgn_12_trigNeg90_1);
RUN_TEST(test_ngc_newIgn_12_trigNeg180_1);
RUN_TEST(test_ngc_newIgn_12_trigNeg270_1);
RUN_TEST(test_ngc_newIgn_12_trigNeg360_1);
}

View File

@ -0,0 +1 @@
void testNGC();

View File

@ -0,0 +1,179 @@
#include <decoders.h>
#include <globals.h>
#include <unity.h>
#include "Nissan360.h"
#include "scheduler.h"
#include "schedule_calcs.h"
extern uint16_t ignition1EndTooth;
extern uint16_t ignition2EndTooth;
extern uint16_t ignition3EndTooth;
extern uint16_t ignition4EndTooth;
void test_nissan360_newIgn_12_trig0_1()
{
//Test the set end tooth function. Conditions:
//Trigger: 12/1
//Advance: 10
//triggerAngle=0
triggerSetup_Nissan360();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = 0; //No trigger offset
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(5);
triggerSetEndTeeth_Nissan360();
TEST_ASSERT_EQUAL(171, ignition1EndTooth);
//Test again with 0 degrees advance
currentStatus.advance = 0; //Set 10deg advance
calculateIgnitionAngle1(5);
triggerSetEndTeeth_Nissan360();
TEST_ASSERT_EQUAL(176, ignition1EndTooth);
//Test again with 35 degrees advance
currentStatus.advance = 35; //Set 10deg advance
calculateIgnitionAngle1(5);
triggerSetEndTeeth_Nissan360();
TEST_ASSERT_EQUAL(158, ignition1EndTooth);
}
void test_nissan360_newIgn_12_trig90_1()
{
//Test the set end tooth function. Conditions:
//Trigger: 12/1
//Advance: 10
//triggerAngle=90
triggerSetup_Nissan360();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = 90; //No trigger offset
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(0);
triggerSetEndTeeth_Nissan360();
TEST_ASSERT_EQUAL(126, ignition1EndTooth);
}
void test_nissan360_newIgn_12_trig180_1()
{
//Test the set end tooth function. Conditions:
//Trigger: 36-1
//Advance: 10
//triggerAngle=180
triggerSetup_Nissan360();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = 180; //No trigger offset
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(0);
triggerSetEndTeeth_Nissan360();
TEST_ASSERT_EQUAL(81, ignition1EndTooth);
}
void test_nissan360_newIgn_12_trig270_1()
{
//Test the set end tooth function. Conditions:
//Trigger: 36-1
//Advance: 10
//triggerAngle=270
triggerSetup_Nissan360();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = 270; //No trigger offset
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(0);
triggerSetEndTeeth_Nissan360();
TEST_ASSERT_EQUAL(36, ignition1EndTooth);
}
void test_nissan360_newIgn_12_trig360_1()
{
//Test the set end tooth function. Conditions:
//Trigger: 36-1
//Advance: 10
//triggerAngle=360
triggerSetup_Nissan360();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = 360; //No trigger offset
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(0);
triggerSetEndTeeth_Nissan360();
TEST_ASSERT_EQUAL(351, ignition1EndTooth);
}
void test_nissan360_newIgn_12_trigNeg90_1()
{
//Test the set end tooth function. Conditions:
//Trigger: 36-1
//Advance: 10
//triggerAngle=-90
triggerSetup_Nissan360();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = -90; //No trigger offset
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(0);
triggerSetEndTeeth_Nissan360();
TEST_ASSERT_EQUAL(216, ignition1EndTooth);
}
void test_nissan360_newIgn_12_trigNeg180_1()
{
//Test the set end tooth function. Conditions:
//Trigger: 36-1
//Advance: 10
//triggerAngle=-180
triggerSetup_Nissan360();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = -180; //No trigger offset
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(0);
triggerSetEndTeeth_Nissan360();
TEST_ASSERT_EQUAL(261, ignition1EndTooth);
}
void test_nissan360_newIgn_12_trigNeg270_1()
{
//Test the set end tooth function. Conditions:
//Trigger: 36-1
//Advance: 10
//triggerAngle=-270
triggerSetup_Nissan360();
configPage4.sparkMode = IGN_MODE_WASTED;
currentStatus.advance = 10; //Set 10 degrees advance
configPage4.triggerAngle = -270; //No trigger offset
triggerSetEndTeeth_Nissan360();
TEST_ASSERT_EQUAL(306, ignition1EndTooth);
}
void test_nissan360_newIgn_12_trigNeg360_1()
{
//Test the set end tooth function. Conditions:
//Trigger: 36-1
//Advance: 10
//triggerAngle=-360
triggerSetup_Nissan360();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = -360; //No trigger offset
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(0);
triggerSetEndTeeth_Nissan360();
TEST_ASSERT_EQUAL(351, ignition1EndTooth);
}
void testNissan360()
{
RUN_TEST(test_nissan360_newIgn_12_trig0_1);
RUN_TEST(test_nissan360_newIgn_12_trig90_1);
RUN_TEST(test_nissan360_newIgn_12_trig180_1);
RUN_TEST(test_nissan360_newIgn_12_trig270_1);
RUN_TEST(test_nissan360_newIgn_12_trig360_1);
RUN_TEST(test_nissan360_newIgn_12_trigNeg90_1);
RUN_TEST(test_nissan360_newIgn_12_trigNeg180_1);
RUN_TEST(test_nissan360_newIgn_12_trigNeg270_1);
RUN_TEST(test_nissan360_newIgn_12_trigNeg360_1);
}

View File

@ -0,0 +1 @@
void testNissan360();

View File

@ -5,6 +5,9 @@
#include "missing_tooth/missing_tooth.h"
#include "dual_wheel/dual_wheel.h"
#include "Nissan360/Nissan360.h"
#include "FordST170/FordST170.h"
#include "NGC/test_ngc.h"
void setup()
{
@ -18,6 +21,9 @@ void setup()
testMissingTooth();
testDualWheel();
testNissan360();
testFordST170();
testNGC();
UNITY_END(); // stop unit testing
}

View File

@ -0,0 +1,5 @@
#pragma once
#include <stdint.h>
void setEngineSpeed(uint16_t rpm, int16_t max_ign);

View File

@ -0,0 +1,757 @@
#include <Arduino.h>
#include <unity.h>
#include "test_calcs_common.h"
#include "schedule_calcs.h"
#include "crankMaths.h"
#define _countof(x) (sizeof(x) / sizeof (x[0]))
extern volatile uint16_t degreesPeruSx2048;
constexpr uint16_t DWELL_TIME_MS = 4;
uint16_t dwellAngle;
void setEngineSpeed(uint16_t rpm, int16_t max_crank) {
timePerDegreex16 = ldiv( 2666656L, rpm).quot; //The use of a x16 value gives accuracy down to 0.1 of a degree and can provide noticeably better timing results on low resolution triggers
timePerDegree = timePerDegreex16 / 16;
degreesPeruSx2048 = 2048 / timePerDegree;
degreesPeruSx32768 = 524288L / timePerDegreex16;
revolutionTime = (60L*1000000L) / rpm;
CRANK_ANGLE_MAX_IGN = max_crank;
CRANK_ANGLE_MAX_INJ = max_crank;
dwellAngle = timeToAngle(DWELL_TIME_MS*1000UL, CRANKMATH_METHOD_INTERVAL_REV);
}
struct ign_test_parameters
{
uint16_t channelAngle; // deg
int8_t advanceAngle; // deg
uint16_t crankAngle; // deg
uint32_t pending; // Expected delay when channel status is PENDING
uint32_t running; // Expected delay when channel status is RUNNING
int16_t expectedStartAngle; // Expected start angle
int16_t expectedEndAngle; // Expected end angle
};
void test_calc_ign1_timeout(const ign_test_parameters &test_params)
{
memset(&ignitionSchedule1, 0, sizeof(ignitionSchedule1));
ignitionSchedule1.Status = PENDING;
calculateIgnitionAngle1(dwellAngle);
TEST_ASSERT_EQUAL(test_params.expectedStartAngle, ignition1StartAngle);
TEST_ASSERT_EQUAL(test_params.expectedEndAngle, ignition1EndAngle);
TEST_ASSERT_EQUAL(test_params.pending, calculateIgnition1Timeout(test_params.crankAngle));
ignitionSchedule1.Status = RUNNING;
calculateIgnitionAngle1(dwellAngle);
TEST_ASSERT_EQUAL(test_params.running, calculateIgnition1Timeout(test_params.crankAngle));
}
void test_calc_ignN_timeout(Schedule &schedule, const ign_test_parameters &test_params, const int &startAngle, void (*pEndAngleCalc)(int), const int16_t &endAngle)
{
char msg[150];
memset(&schedule, 0, sizeof(schedule));
schedule.Status = PENDING;
pEndAngleCalc(dwellAngle);
TEST_ASSERT_EQUAL_MESSAGE(test_params.expectedStartAngle, startAngle, "startAngle");
TEST_ASSERT_EQUAL_MESSAGE(test_params.expectedEndAngle, endAngle, "endAngle");
sprintf_P(msg, PSTR("PENDING advanceAngle: %" PRIi8 ", channelAngle: % " PRIu16 ", crankAngle: %" PRIu16 ", endAngle: %" PRIi16), test_params.advanceAngle, test_params.channelAngle, test_params.crankAngle, endAngle);
TEST_ASSERT_EQUAL_MESSAGE(test_params.pending, calculateIgnitionNTimeout(schedule, startAngle, test_params.channelAngle, test_params.crankAngle), msg);
schedule.Status = RUNNING;
pEndAngleCalc(dwellAngle);
sprintf_P(msg, PSTR("RUNNING advanceAngle: %" PRIi8 ", channelAngle: % " PRIu16 ", crankAngle: %" PRIu16 ", endAngle: %" PRIi16), test_params.advanceAngle, test_params.channelAngle, test_params.crankAngle, endAngle);
TEST_ASSERT_EQUAL_MESSAGE(test_params.running, calculateIgnitionNTimeout(schedule, startAngle, test_params.channelAngle, test_params.crankAngle), msg);
}
//test_params.channelAngle, local.crankAngle, local.pending, local.running, local.endAngle
void test_calc_ign_timeout(const ign_test_parameters &test_params)
{
channel2IgnDegrees = test_params.channelAngle;
test_calc_ignN_timeout(ignitionSchedule2, test_params, ignition2StartAngle, &calculateIgnitionAngle2, ignition2EndAngle);
channel3IgnDegrees = test_params.channelAngle;
test_calc_ignN_timeout(ignitionSchedule3, test_params, ignition3StartAngle, &calculateIgnitionAngle3, ignition3EndAngle);
channel4IgnDegrees = test_params.channelAngle;
test_calc_ignN_timeout(ignitionSchedule4, test_params, ignition4StartAngle, &calculateIgnitionAngle4, ignition4EndAngle);
#if (IGN_CHANNELS >= 5)
channel5IgnDegrees = test_params.channelAngle;
test_calc_ignN_timeout(ignitionSchedule5, test_params, ignition5StartAngle, &calculateIgnitionAngle5, ignition5EndAngle);
#endif
#if (IGN_CHANNELS >= 6)
channel6IgnDegrees = test_params.channelAngle;
test_calc_ignN_timeout(ignitionSchedule6, test_params, ignition6StartAngle, &calculateIgnitionAngle6, ignition6EndAngle);
#endif
#if (IGN_CHANNELS >= 7)
channel7IgnDegrees = test_params.channelAngle;
test_calc_ignN_timeout(ignitionSchedule7, test_params, ignition7StartAngle, &calculateIgnitionAngle7, ignition7EndAngle);
#endif
#if (IGN_CHANNELS >= 8)
channel8IgnDegrees = test_params.channelAngle;
test_calc_ignN_timeout(ignitionSchedule8, test_params, ignition8StartAngle, &calculateIgnitionAngle8, ignition8EndAngle);
#endif
}
void test_calc_ign_timeout(const ign_test_parameters *pStart, const ign_test_parameters *pEnd)
{
ign_test_parameters local;
while (pStart!=pEnd)
{
memcpy_P(&local, pStart, sizeof(local));
currentStatus.advance = local.advanceAngle;
test_calc_ign_timeout(local);
++pStart;
}
}
// Separate test for ign 1 - different code path, same results!
void test_calc_ign1_timeout()
{
setEngineSpeed(4000, 360);
static const ign_test_parameters test_data[] PROGMEM = {
// ChannelAngle (deg), Advance, Crank, Expected Pending, Expected Running
{ 0, -40, 0, 12666, 12666, 304, 40 },
{ 0, -40, 45, 10791, 10791, 304, 40 },
{ 0, -40, 90, 8916, 8916, 304, 40 },
{ 0, -40, 135, 7041, 7041, 304, 40 },
{ 0, -40, 180, 5166, 5166, 304, 40 },
{ 0, -40, 215, 3708, 3708, 304, 40 },
{ 0, -40, 270, 1416, 1416, 304, 40 },
{ 0, -40, 315, 0, 14541, 304, 40 },
{ 0, -40, 360, 0, 12666, 304, 40 },
{ 0, 0, 0, 11000, 11000, 264, 360 },
{ 0, 0, 45, 9125, 9125, 264, 360 },
{ 0, 0, 90, 7250, 7250, 264, 360 },
{ 0, 0, 135, 5375, 5375, 264, 360 },
{ 0, 0, 180, 3500, 3500, 264, 360 },
{ 0, 0, 215, 2041, 2041, 264, 360 },
{ 0, 0, 270, 0, 14750, 264, 360 },
{ 0, 0, 315, 0, 12875, 264, 360 },
{ 0, 0, 360, 0, 11000, 264, 360 },
{ 0, 40, 0, 9333, 9333, 224, 320 },
{ 0, 40, 45, 7458, 7458, 224, 320 },
{ 0, 40, 90, 5583, 5583, 224, 320 },
{ 0, 40, 135, 3708, 3708, 224, 320 },
{ 0, 40, 180, 1833, 1833, 224, 320 },
{ 0, 40, 215, 375, 375, 224, 320 },
{ 0, 40, 270, 0, 13083, 224, 320 },
{ 0, 40, 315, 0, 11208, 224, 320 },
{ 0, 40, 360, 0, 9333, 224, 320 },
};
const ign_test_parameters *pStart = &test_data[0];
const ign_test_parameters *pEnd = pStart + +_countof(test_data);
ign_test_parameters local;
while (pStart!=pEnd)
{
memcpy_P(&local, pStart, sizeof(local));
currentStatus.advance = local.advanceAngle;
test_calc_ign1_timeout(local);
++pStart;
}
}
void test_calc_ign_timeout_360()
{
setEngineSpeed(4000, 360);
static const ign_test_parameters test_data[] PROGMEM = {
// ChannelAngle (deg), Advance, Crank, Expected Pending, Expected Running
{ 0, -40, 0, 12666, 12666, 304, 40 },
{ 0, -40, 45, 10791, 10791, 304, 40 },
{ 0, -40, 90, 8916, 8916, 304, 40 },
{ 0, -40, 135, 7041, 7041, 304, 40 },
{ 0, -40, 180, 5166, 5166, 304, 40 },
{ 0, -40, 215, 3708, 3708, 304, 40 },
{ 0, -40, 270, 1416, 1416, 304, 40 },
{ 0, -40, 315, 0, 14541, 304, 40 },
{ 0, -40, 360, 0, 12666, 304, 40 },
{ 0, 0, 0, 11000, 11000, 264, 0 },
{ 0, 0, 45, 9125, 9125, 264, 0 },
{ 0, 0, 90, 7250, 7250, 264, 0 },
{ 0, 0, 135, 5375, 5375, 264, 0 },
{ 0, 0, 180, 3500, 3500, 264, 0 },
{ 0, 0, 215, 2041, 2041, 264, 0 },
{ 0, 0, 270, 0, 14750, 264, 0 },
{ 0, 0, 315, 0, 12875, 264, 0 },
{ 0, 0, 360, 0, 11000, 264, 0 },
{ 0, 40, 0, 9333, 9333, 224, -40 },
{ 0, 40, 45, 7458, 7458, 224, -40 },
{ 0, 40, 90, 5583, 5583, 224, -40 },
{ 0, 40, 135, 3708, 3708, 224, -40 },
{ 0, 40, 180, 1833, 1833, 224, -40 },
{ 0, 40, 215, 375, 375, 224, -40 },
{ 0, 40, 270, 0, 13083, 224, -40 },
{ 0, 40, 315, 0, 11208, 224, -40 },
{ 0, 40, 360, 0, 9333, 224, -40 },
{ 72, -40, 0, 666, 666, 16, 112 },
{ 72, -40, 45, 0, 13791, 16, 112 },
{ 72, -40, 90, 11916, 11916, 16, 112 },
{ 72, -40, 135, 10041, 10041, 16, 112 },
{ 72, -40, 180, 8166, 8166, 16, 112 },
{ 72, -40, 215, 6708, 6708, 16, 112 },
{ 72, -40, 270, 4416, 4416, 16, 112 },
{ 72, -40, 315, 2541, 2541, 16, 112 },
{ 72, -40, 360, 666, 666, 16, 112 },
{ 72, 0, 0, 0, 14000, 336, 72 },
{ 72, 0, 45, 0, 12125, 336, 72 },
{ 72, 0, 90, 10250, 10250, 336, 72 },
{ 72, 0, 135, 8375, 8375, 336, 72 },
{ 72, 0, 180, 6500, 6500, 336, 72 },
{ 72, 0, 215, 5041, 5041, 336, 72 },
{ 72, 0, 270, 2750, 2750, 336, 72 },
{ 72, 0, 315, 875, 875, 336, 72 },
{ 72, 0, 360, 0, 14000, 336, 72 },
{ 72, 40, 0, 0, 12333, 296, 32 },
{ 72, 40, 45, 0, 10458, 296, 32 },
{ 72, 40, 90, 8583, 8583, 296, 32 },
{ 72, 40, 135, 6708, 6708, 296, 32 },
{ 72, 40, 180, 4833, 4833, 296, 32 },
{ 72, 40, 215, 3375, 3375, 296, 32 },
{ 72, 40, 270, 1083, 1083, 296, 32 },
{ 72, 40, 315, 0, 14208, 296, 32 },
{ 72, 40, 360, 0, 12333, 296, 32 },
{ 90, -40, 0, 1416, 1416, 34, 130 },
{ 90, -40, 45, 0, 14541, 34, 130 },
{ 90, -40, 90, 12666, 12666, 34, 130 },
{ 90, -40, 135, 10791, 10791, 34, 130 },
{ 90, -40, 180, 8916, 8916, 34, 130 },
{ 90, -40, 215, 7458, 7458, 34, 130 },
{ 90, -40, 270, 5166, 5166, 34, 130 },
{ 90, -40, 315, 3291, 3291, 34, 130 },
{ 90, -40, 360, 1416, 1416, 34, 130 },
{ 90, 0, 0, 0, 14750, 354, 90 },
{ 90, 0, 45, 0, 12875, 354, 90 },
{ 90, 0, 90, 11000, 11000, 354, 90 },
{ 90, 0, 135, 9125, 9125, 354, 90 },
{ 90, 0, 180, 7250, 7250, 354, 90 },
{ 90, 0, 215, 5791, 5791, 354, 90 },
{ 90, 0, 270, 3500, 3500, 354, 90 },
{ 90, 0, 315, 1625, 1625, 354, 90 },
{ 90, 0, 360, 0, 14750, 354, 90 },
{ 90, 40, 0, 0, 13083, 314, 50 },
{ 90, 40, 45, 0, 11208, 314, 50 },
{ 90, 40, 90, 9333, 9333, 314, 50 },
{ 90, 40, 135, 7458, 7458, 314, 50 },
{ 90, 40, 180, 5583, 5583, 314, 50 },
{ 90, 40, 215, 4125, 4125, 314, 50 },
{ 90, 40, 270, 1833, 1833, 314, 50 },
{ 90, 40, 315, 0, 14958, 314, 50 },
{ 90, 40, 360, 0, 13083, 314, 50 },
{ 144, -40, 0, 3666, 3666, 88, 184 },
{ 144, -40, 45, 1791, 1791, 88, 184 },
{ 144, -40, 90, 0, 14916, 88, 184 },
{ 144, -40, 135, 0, 13041, 88, 184 },
{ 144, -40, 180, 11166, 11166, 88, 184 },
{ 144, -40, 215, 9708, 9708, 88, 184 },
{ 144, -40, 270, 7416, 7416, 88, 184 },
{ 144, -40, 315, 5541, 5541, 88, 184 },
{ 144, -40, 360, 3666, 3666, 88, 184 },
{ 144, 0, 0, 2000, 2000, 48, 144 },
{ 144, 0, 45, 125, 125, 48, 144 },
{ 144, 0, 90, 0, 13250, 48, 144 },
{ 144, 0, 135, 0, 11375, 48, 144 },
{ 144, 0, 180, 9500, 9500, 48, 144 },
{ 144, 0, 215, 8041, 8041, 48, 144 },
{ 144, 0, 270, 5750, 5750, 48, 144 },
{ 144, 0, 315, 3875, 3875, 48, 144 },
{ 144, 0, 360, 2000, 2000, 48, 144 },
{ 144, 40, 0, 333, 333, 8, 104 },
{ 144, 40, 45, 0, 13458, 8, 104 },
{ 144, 40, 90, 0, 11583, 8, 104 },
{ 144, 40, 135, 0, 9708, 8, 104 },
{ 144, 40, 180, 7833, 7833, 8, 104 },
{ 144, 40, 215, 6375, 6375, 8, 104 },
{ 144, 40, 270, 4083, 4083, 8, 104 },
{ 144, 40, 315, 2208, 2208, 8, 104 },
{ 144, 40, 360, 333, 333, 8, 104 },
{ 180, -40, 0, 5166, 5166, 124, 220 },
{ 180, -40, 45, 3291, 3291, 124, 220 },
{ 180, -40, 90, 1416, 1416, 124, 220 },
{ 180, -40, 135, 0, 14541, 124, 220 },
{ 180, -40, 180, 12666, 12666, 124, 220 },
{ 180, -40, 215, 11208, 11208, 124, 220 },
{ 180, -40, 270, 8916, 8916, 124, 220 },
{ 180, -40, 315, 7041, 7041, 124, 220 },
{ 180, -40, 360, 5166, 5166, 124, 220 },
{ 180, 0, 0, 3500, 3500, 84, 180 },
{ 180, 0, 45, 1625, 1625, 84, 180 },
{ 180, 0, 90, 0, 14750, 84, 180 },
{ 180, 0, 135, 0, 12875, 84, 180 },
{ 180, 0, 180, 11000, 11000, 84, 180 },
{ 180, 0, 215, 9541, 9541, 84, 180 },
{ 180, 0, 270, 7250, 7250, 84, 180 },
{ 180, 0, 315, 5375, 5375, 84, 180 },
{ 180, 0, 360, 3500, 3500, 84, 180 },
{ 180, 40, 0, 1833, 1833, 44, 140 },
{ 180, 40, 45, 0, 14958, 44, 140 },
{ 180, 40, 90, 0, 13083, 44, 140 },
{ 180, 40, 135, 0, 11208, 44, 140 },
{ 180, 40, 180, 9333, 9333, 44, 140 },
{ 180, 40, 215, 7875, 7875, 44, 140 },
{ 180, 40, 270, 5583, 5583, 44, 140 },
{ 180, 40, 315, 3708, 3708, 44, 140 },
{ 180, 40, 360, 1833, 1833, 44, 140 },
{ 270, -40, 0, 8916, 8916, 214, 310 },
{ 270, -40, 45, 7041, 7041, 214, 310 },
{ 270, -40, 90, 5166, 5166, 214, 310 },
{ 270, -40, 135, 3291, 3291, 214, 310 },
{ 270, -40, 180, 1416, 1416, 214, 310 },
{ 270, -40, 215, 0, 14958, 214, 310 },
{ 270, -40, 270, 12666, 12666, 214, 310 },
{ 270, -40, 315, 10791, 10791, 214, 310 },
{ 270, -40, 360, 8916, 8916, 214, 310 },
{ 270, 0, 0, 7250, 7250, 174, 270 },
{ 270, 0, 45, 5375, 5375, 174, 270 },
{ 270, 0, 90, 3500, 3500, 174, 270 },
{ 270, 0, 135, 1625, 1625, 174, 270 },
{ 270, 0, 180, 0, 14750, 174, 270 },
{ 270, 0, 215, 0, 13291, 174, 270 },
{ 270, 0, 270, 11000, 11000, 174, 270 },
{ 270, 0, 315, 9125, 9125, 174, 270 },
{ 270, 0, 360, 7250, 7250, 174, 270 },
{ 270, 40, 0, 5583, 5583, 134, 230 },
{ 270, 40, 45, 3708, 3708, 134, 230 },
{ 270, 40, 90, 1833, 1833, 134, 230 },
{ 270, 40, 135, 0, 14958, 134, 230 },
{ 270, 40, 180, 0, 13083, 134, 230 },
{ 270, 40, 215, 0, 11625, 134, 230 },
{ 270, 40, 270, 9333, 9333, 134, 230 },
{ 270, 40, 315, 7458, 7458, 134, 230 },
{ 270, 40, 360, 5583, 5583, 134, 230 },
{ 360, -40, 0, 12666, 12666, 304, 40 },
{ 360, -40, 45, 10791, 10791, 304, 40 },
{ 360, -40, 90, 8916, 8916, 304, 40 },
{ 360, -40, 135, 7041, 7041, 304, 40 },
{ 360, -40, 180, 5166, 5166, 304, 40 },
{ 360, -40, 215, 3708, 3708, 304, 40 },
{ 360, -40, 270, 1416, 1416, 304, 40 },
{ 360, -40, 315, 0, 14541, 304, 40 },
{ 360, -40, 360, 12666, 12666, 304, 40 },
{ 360, 0, 0, 11000, 11000, 264, 360 },
{ 360, 0, 45, 9125, 9125, 264, 360 },
{ 360, 0, 90, 7250, 7250, 264, 360 },
{ 360, 0, 135, 5375, 5375, 264, 360 },
{ 360, 0, 180, 3500, 3500, 264, 360 },
{ 360, 0, 215, 2041, 2041, 264, 360 },
{ 360, 0, 270, 0, 14750, 264, 360 },
{ 360, 0, 315, 0, 12875, 264, 360 },
{ 360, 0, 360, 11000, 11000, 264, 360 },
{ 360, 40, 0, 9333, 9333, 224, 320 },
{ 360, 40, 45, 7458, 7458, 224, 320 },
{ 360, 40, 90, 5583, 5583, 224, 320 },
{ 360, 40, 135, 3708, 3708, 224, 320 },
{ 360, 40, 180, 1833, 1833, 224, 320 },
{ 360, 40, 215, 375, 375, 224, 320 },
{ 360, 40, 270, 0, 13083, 224, 320 },
{ 360, 40, 315, 0, 11208, 224, 320 },
{ 360, 40, 360, 9333, 9333, 224, 320 },
};
test_calc_ign_timeout(&test_data[0], &test_data[0]+_countof(test_data));
}
void test_calc_ign_timeout_720()
{
setEngineSpeed(4000, 720);
static const ign_test_parameters test_data[] PROGMEM = {
// ChannelAngle (deg), Advance, Crank, Expected Pending, Expected Running
{ 0, -40, 0, 27666, 27666, 664, 40 },
{ 0, -40, 45, 25791, 25791, 664, 40 },
{ 0, -40, 90, 23916, 23916, 664, 40 },
{ 0, -40, 135, 22041, 22041, 664, 40 },
{ 0, -40, 180, 20166, 20166, 664, 40 },
{ 0, -40, 215, 18708, 18708, 664, 40 },
{ 0, -40, 270, 16416, 16416, 664, 40 },
{ 0, -40, 315, 14541, 14541, 664, 40 },
{ 0, -40, 360, 12666, 12666, 664, 40 },
{ 0, 0, 0, 26000, 26000, 624, 0 },
{ 0, 0, 45, 24125, 24125, 624, 0 },
{ 0, 0, 90, 22250, 22250, 624, 0 },
{ 0, 0, 135, 20375, 20375, 624, 0 },
{ 0, 0, 180, 18500, 18500, 624, 0 },
{ 0, 0, 215, 17041, 17041, 624, 0 },
{ 0, 0, 270, 14750, 14750, 624, 0 },
{ 0, 0, 315, 12875, 12875, 624, 0 },
{ 0, 0, 360, 11000, 11000, 624, 0 },
{ 0, 40, 0, 24333, 24333, 584, -40 },
{ 0, 40, 45, 22458, 22458, 584, -40 },
{ 0, 40, 90, 20583, 20583, 584, -40 },
{ 0, 40, 135, 18708, 18708, 584, -40 },
{ 0, 40, 180, 16833, 16833, 584, -40 },
{ 0, 40, 215, 15375, 15375, 584, -40 },
{ 0, 40, 270, 13083, 13083, 584, -40 },
{ 0, 40, 315, 11208, 11208, 584, -40 },
{ 0, 40, 360, 9333, 9333, 584, -40 },
{ 72, -40, 0, 666, 666, 16, 112 },
{ 72, -40, 45, 0, 28791, 16, 112 },
{ 72, -40, 90, 26916, 26916, 16, 112 },
{ 72, -40, 135, 25041, 25041, 16, 112 },
{ 72, -40, 180, 23166, 23166, 16, 112 },
{ 72, -40, 215, 21708, 21708, 16, 112 },
{ 72, -40, 270, 19416, 19416, 16, 112 },
{ 72, -40, 315, 17541, 17541, 16, 112 },
{ 72, -40, 360, 15666, 15666, 16, 112 },
{ 72, 0, 0, 0, 29000, 696, 72 },
{ 72, 0, 45, 0, 27125, 696, 72 },
{ 72, 0, 90, 25250, 25250, 696, 72 },
{ 72, 0, 135, 23375, 23375, 696, 72 },
{ 72, 0, 180, 21500, 21500, 696, 72 },
{ 72, 0, 215, 20041, 20041, 696, 72 },
{ 72, 0, 270, 17750, 17750, 696, 72 },
{ 72, 0, 315, 15875, 15875, 696, 72 },
{ 72, 0, 360, 14000, 14000, 696, 72 },
{ 72, 40, 0, 0, 27333, 656, 32 },
{ 72, 40, 45, 0, 25458, 656, 32 },
{ 72, 40, 90, 23583, 23583, 656, 32 },
{ 72, 40, 135, 21708, 21708, 656, 32 },
{ 72, 40, 180, 19833, 19833, 656, 32 },
{ 72, 40, 215, 18375, 18375, 656, 32 },
{ 72, 40, 270, 16083, 16083, 656, 32 },
{ 72, 40, 315, 14208, 14208, 656, 32 },
{ 72, 40, 360, 12333, 12333, 656, 32 },
{ 90, -40, 0, 1416, 1416, 34, 130 },
{ 90, -40, 45, 0, 29541, 34, 130 },
{ 90, -40, 90, 27666, 27666, 34, 130 },
{ 90, -40, 135, 25791, 25791, 34, 130 },
{ 90, -40, 180, 23916, 23916, 34, 130 },
{ 90, -40, 215, 22458, 22458, 34, 130 },
{ 90, -40, 270, 20166, 20166, 34, 130 },
{ 90, -40, 315, 18291, 18291, 34, 130 },
{ 90, -40, 360, 16416, 16416, 34, 130 },
{ 90, 0, 0, 0, 29750, 714, 90 },
{ 90, 0, 45, 0, 27875, 714, 90 },
{ 90, 0, 90, 26000, 26000, 714, 90 },
{ 90, 0, 135, 24125, 24125, 714, 90 },
{ 90, 0, 180, 22250, 22250, 714, 90 },
{ 90, 0, 215, 20791, 20791, 714, 90 },
{ 90, 0, 270, 18500, 18500, 714, 90 },
{ 90, 0, 315, 16625, 16625, 714, 90 },
{ 90, 0, 360, 14750, 14750, 714, 90 },
{ 90, 40, 0, 0, 28083, 674, 50 },
{ 90, 40, 45, 0, 26208, 674, 50 },
{ 90, 40, 90, 24333, 24333, 674, 50 },
{ 90, 40, 135, 22458, 22458, 674, 50 },
{ 90, 40, 180, 20583, 20583, 674, 50 },
{ 90, 40, 215, 19125, 19125, 674, 50 },
{ 90, 40, 270, 16833, 16833, 674, 50 },
{ 90, 40, 315, 14958, 14958, 674, 50 },
{ 90, 40, 360, 13083, 13083, 674, 50 },
{ 144, -40, 0, 3666, 3666, 88, 184 },
{ 144, -40, 45, 1791, 1791, 88, 184 },
{ 144, -40, 90, 0, 29916, 88, 184 },
{ 144, -40, 135, 0, 28041, 88, 184 },
{ 144, -40, 180, 26166, 26166, 88, 184 },
{ 144, -40, 215, 24708, 24708, 88, 184 },
{ 144, -40, 270, 22416, 22416, 88, 184 },
{ 144, -40, 315, 20541, 20541, 88, 184 },
{ 144, -40, 360, 18666, 18666, 88, 184 },
{ 144, 0, 0, 2000, 2000, 48, 144 },
{ 144, 0, 45, 125, 125, 48, 144 },
{ 144, 0, 90, 0, 28250, 48, 144 },
{ 144, 0, 135, 0, 26375, 48, 144 },
{ 144, 0, 180, 24500, 24500, 48, 144 },
{ 144, 0, 215, 23041, 23041, 48, 144 },
{ 144, 0, 270, 20750, 20750, 48, 144 },
{ 144, 0, 315, 18875, 18875, 48, 144 },
{ 144, 0, 360, 17000, 17000, 48, 144 },
{ 144, 40, 0, 333, 333, 8, 104 },
{ 144, 40, 45, 0, 28458, 8, 104 },
{ 144, 40, 90, 0, 26583, 8, 104 },
{ 144, 40, 135, 0, 24708, 8, 104 },
{ 144, 40, 180, 22833, 22833, 8, 104 },
{ 144, 40, 215, 21375, 21375, 8, 104 },
{ 144, 40, 270, 19083, 19083, 8, 104 },
{ 144, 40, 315, 17208, 17208, 8, 104 },
{ 144, 40, 360, 15333, 15333, 8, 104 },
{ 180, -40, 0, 5166, 5166, 124, 220 },
{ 180, -40, 45, 3291, 3291, 124, 220 },
{ 180, -40, 90, 1416, 1416, 124, 220 },
{ 180, -40, 135, 0, 29541, 124, 220 },
{ 180, -40, 180, 27666, 27666, 124, 220 },
{ 180, -40, 215, 26208, 26208, 124, 220 },
{ 180, -40, 270, 23916, 23916, 124, 220 },
{ 180, -40, 315, 22041, 22041, 124, 220 },
{ 180, -40, 360, 20166, 20166, 124, 220 },
{ 180, 0, 0, 3500, 3500, 84, 180 },
{ 180, 0, 45, 1625, 1625, 84, 180 },
{ 180, 0, 90, 0, 29750, 84, 180 },
{ 180, 0, 135, 0, 27875, 84, 180 },
{ 180, 0, 180, 26000, 26000, 84, 180 },
{ 180, 0, 215, 24541, 24541, 84, 180 },
{ 180, 0, 270, 22250, 22250, 84, 180 },
{ 180, 0, 315, 20375, 20375, 84, 180 },
{ 180, 0, 360, 18500, 18500, 84, 180 },
{ 180, 40, 0, 1833, 1833, 44, 140 },
{ 180, 40, 45, 0, 29958, 44, 140 },
{ 180, 40, 90, 0, 28083, 44, 140 },
{ 180, 40, 135, 0, 26208, 44, 140 },
{ 180, 40, 180, 24333, 24333, 44, 140 },
{ 180, 40, 215, 22875, 22875, 44, 140 },
{ 180, 40, 270, 20583, 20583, 44, 140 },
{ 180, 40, 315, 18708, 18708, 44, 140 },
{ 180, 40, 360, 16833, 16833, 44, 140 },
{ 270, -40, 0, 8916, 8916, 214, 310 },
{ 270, -40, 45, 7041, 7041, 214, 310 },
{ 270, -40, 90, 5166, 5166, 214, 310 },
{ 270, -40, 135, 3291, 3291, 214, 310 },
{ 270, -40, 180, 1416, 1416, 214, 310 },
{ 270, -40, 215, 0, 29958, 214, 310 },
{ 270, -40, 270, 27666, 27666, 214, 310 },
{ 270, -40, 315, 25791, 25791, 214, 310 },
{ 270, -40, 360, 23916, 23916, 214, 310 },
{ 270, 0, 0, 7250, 7250, 174, 270 },
{ 270, 0, 45, 5375, 5375, 174, 270 },
{ 270, 0, 90, 3500, 3500, 174, 270 },
{ 270, 0, 135, 1625, 1625, 174, 270 },
{ 270, 0, 180, 0, 29750, 174, 270 },
{ 270, 0, 215, 0, 28291, 174, 270 },
{ 270, 0, 270, 26000, 26000, 174, 270 },
{ 270, 0, 315, 24125, 24125, 174, 270 },
{ 270, 0, 360, 22250, 22250, 174, 270 },
{ 270, 40, 0, 5583, 5583, 134, 230 },
{ 270, 40, 45, 3708, 3708, 134, 230 },
{ 270, 40, 90, 1833, 1833, 134, 230 },
{ 270, 40, 135, 0, 29958, 134, 230 },
{ 270, 40, 180, 0, 28083, 134, 230 },
{ 270, 40, 215, 0, 26625, 134, 230 },
{ 270, 40, 270, 24333, 24333, 134, 230 },
{ 270, 40, 315, 22458, 22458, 134, 230 },
{ 270, 40, 360, 20583, 20583, 134, 230 },
{ 360, -40, 0, 12666, 12666, 304, 400 },
{ 360, -40, 45, 10791, 10791, 304, 400 },
{ 360, -40, 90, 8916, 8916, 304, 400 },
{ 360, -40, 135, 7041, 7041, 304, 400 },
{ 360, -40, 180, 5166, 5166, 304, 400 },
{ 360, -40, 215, 3708, 3708, 304, 400 },
{ 360, -40, 270, 1416, 1416, 304, 400 },
{ 360, -40, 315, 0, 29541, 304, 400 },
{ 360, -40, 360, 27666, 27666, 304, 400 },
{ 360, 0, 0, 11000, 11000, 264, 360 },
{ 360, 0, 45, 9125, 9125, 264, 360 },
{ 360, 0, 90, 7250, 7250, 264, 360 },
{ 360, 0, 135, 5375, 5375, 264, 360 },
{ 360, 0, 180, 3500, 3500, 264, 360 },
{ 360, 0, 215, 2041, 2041, 264, 360 },
{ 360, 0, 270, 0, 29750, 264, 360 },
{ 360, 0, 315, 0, 27875, 264, 360 },
{ 360, 0, 360, 26000, 26000, 264, 360 },
{ 360, 40, 0, 9333, 9333, 224, 320 },
{ 360, 40, 45, 7458, 7458, 224, 320 },
{ 360, 40, 90, 5583, 5583, 224, 320 },
{ 360, 40, 135, 3708, 3708, 224, 320 },
{ 360, 40, 180, 1833, 1833, 224, 320 },
{ 360, 40, 215, 375, 375, 224, 320 },
{ 360, 40, 270, 0, 28083, 224, 320 },
{ 360, 40, 315, 0, 26208, 224, 320 },
{ 360, 40, 360, 24333, 24333, 224, 320 },
{ 432, -40, 0, 15666, 15666, 376, 472 },
{ 432, -40, 45, 13791, 13791, 376, 472 },
{ 432, -40, 90, 11916, 11916, 376, 472 },
{ 432, -40, 135, 10041, 10041, 376, 472 },
{ 432, -40, 180, 8166, 8166, 376, 472 },
{ 432, -40, 215, 6708, 6708, 376, 472 },
{ 432, -40, 270, 4416, 4416, 376, 472 },
{ 432, -40, 315, 2541, 2541, 376, 472 },
{ 432, -40, 360, 666, 666, 376, 472 },
{ 432, 0, 0, 14000, 14000, 336, 432 },
{ 432, 0, 45, 12125, 12125, 336, 432 },
{ 432, 0, 90, 10250, 10250, 336, 432 },
{ 432, 0, 135, 8375, 8375, 336, 432 },
{ 432, 0, 180, 6500, 6500, 336, 432 },
{ 432, 0, 215, 5041, 5041, 336, 432 },
{ 432, 0, 270, 2750, 2750, 336, 432 },
{ 432, 0, 315, 875, 875, 336, 432 },
{ 432, 0, 360, 0, 29000, 336, 432 },
{ 432, 40, 0, 12333, 12333, 296, 392 },
{ 432, 40, 45, 10458, 10458, 296, 392 },
{ 432, 40, 90, 8583, 8583, 296, 392 },
{ 432, 40, 135, 6708, 6708, 296, 392 },
{ 432, 40, 180, 4833, 4833, 296, 392 },
{ 432, 40, 215, 3375, 3375, 296, 392 },
{ 432, 40, 270, 1083, 1083, 296, 392 },
{ 432, 40, 315, 0, 29208, 296, 392 },
{ 432, 40, 360, 0, 27333, 296, 392 },
{ 576, -40, 0, 21666, 21666, 520, 616 },
{ 576, -40, 45, 19791, 19791, 520, 616 },
{ 576, -40, 90, 17916, 17916, 520, 616 },
{ 576, -40, 135, 16041, 16041, 520, 616 },
{ 576, -40, 180, 14166, 14166, 520, 616 },
{ 576, -40, 215, 12708, 12708, 520, 616 },
{ 576, -40, 270, 10416, 10416, 520, 616 },
{ 576, -40, 315, 8541, 8541, 520, 616 },
{ 576, -40, 360, 6666, 6666, 520, 616 },
{ 576, 0, 0, 20000, 20000, 480, 576 },
{ 576, 0, 45, 18125, 18125, 480, 576 },
{ 576, 0, 90, 16250, 16250, 480, 576 },
{ 576, 0, 135, 14375, 14375, 480, 576 },
{ 576, 0, 180, 12500, 12500, 480, 576 },
{ 576, 0, 215, 11041, 11041, 480, 576 },
{ 576, 0, 270, 8750, 8750, 480, 576 },
{ 576, 0, 315, 6875, 6875, 480, 576 },
{ 576, 0, 360, 5000, 5000, 480, 576 },
{ 576, 40, 0, 18333, 18333, 440, 536 },
{ 576, 40, 45, 16458, 16458, 440, 536 },
{ 576, 40, 90, 14583, 14583, 440, 536 },
{ 576, 40, 135, 12708, 12708, 440, 536 },
{ 576, 40, 180, 10833, 10833, 440, 536 },
{ 576, 40, 215, 9375, 9375, 440, 536 },
{ 576, 40, 270, 7083, 7083, 440, 536 },
{ 576, 40, 315, 5208, 5208, 440, 536 },
{ 576, 40, 360, 3333, 3333, 440, 536 },
{ 600, -40, 0, 22666, 22666, 544, 640 },
{ 600, -40, 45, 20791, 20791, 544, 640 },
{ 600, -40, 90, 18916, 18916, 544, 640 },
{ 600, -40, 135, 17041, 17041, 544, 640 },
{ 600, -40, 180, 15166, 15166, 544, 640 },
{ 600, -40, 215, 13708, 13708, 544, 640 },
{ 600, -40, 270, 11416, 11416, 544, 640 },
{ 600, -40, 315, 9541, 9541, 544, 640 },
{ 600, -40, 360, 7666, 7666, 544, 640 },
{ 600, 0, 0, 21000, 21000, 504, 600 },
{ 600, 0, 45, 19125, 19125, 504, 600 },
{ 600, 0, 90, 17250, 17250, 504, 600 },
{ 600, 0, 135, 15375, 15375, 504, 600 },
{ 600, 0, 180, 13500, 13500, 504, 600 },
{ 600, 0, 215, 12041, 12041, 504, 600 },
{ 600, 0, 270, 9750, 9750, 504, 600 },
{ 600, 0, 315, 7875, 7875, 504, 600 },
{ 600, 0, 360, 6000, 6000, 504, 600 },
{ 600, 40, 0, 19333, 19333, 464, 560 },
{ 600, 40, 45, 17458, 17458, 464, 560 },
{ 600, 40, 90, 15583, 15583, 464, 560 },
{ 600, 40, 135, 13708, 13708, 464, 560 },
{ 600, 40, 180, 11833, 11833, 464, 560 },
{ 600, 40, 215, 10375, 10375, 464, 560 },
{ 600, 40, 270, 8083, 8083, 464, 560 },
{ 600, 40, 315, 6208, 6208, 464, 560 },
{ 600, 40, 360, 4333, 4333, 464, 560 },
};
test_calc_ign_timeout(&test_data[0], &test_data[0]+_countof(test_data));
}
void test_rotary_channel3_calcs(void)
{
setEngineSpeed(4000, 360);
static const int16_t test_data[][5] PROGMEM = {
{ -40, 5, 0, -40, 315 },
{ -40, 95, 0, -40, 225 },
{ -40, 185, 0, -40, 135 },
{ -40, 275, 0, -40, 45 },
{ -40, 355, 0, -40, -35 },
{ -40, 5, 40, 0, 355 },
{ -40, 95, 40, 0, 265 },
{ -40, 185, 40, 0, 175 },
{ -40, 275, 40, 0, 85 },
{ -40, 355, 40, 0, 5 },
{ 0, 5, 0, 0, 355 },
{ 0, 95, 0, 0, 265 },
{ 0, 185, 0, 0, 175 },
{ 0, 275, 0, 0, 85 },
{ 0, 355, 0, 0, 5 },
{ 0, 5, 40, 40, 35 },
{ 0, 95, 40, 40, 305 },
{ 0, 185, 40, 40, 215 },
{ 0, 275, 40, 40, 125 },
{ 0, 355, 40, 40, 45 },
{ 40, 5, 0, 40, 35 },
{ 40, 95, 0, 40, 305 },
{ 40, 185, 0, 40, 215 },
{ 40, 275, 0, 40, 125 },
{ 40, 355, 0, 40, 45 },
{ 40, 5, 40, 80, 75 },
{ 40, 95, 40, 80, 345 },
{ 40, 185, 40, 80, 255 },
{ 40, 275, 40, 80, 165 },
{ 40, 355, 40, 80, 85 },
};
const int16_t (*pStart)[5] = &test_data[0];
const int16_t (*pEnd)[5] = &test_data[0]+_countof(test_data);
channel1IgnDegrees = 0;
int16_t local[5];
while (pStart!=pEnd)
{
memcpy_P(local, pStart, sizeof(local));
ignition1EndAngle = local[0];
calculateIgnitionAngle3(local[1], local[2]);
TEST_ASSERT_EQUAL(local[3], ignition3EndAngle);
TEST_ASSERT_EQUAL(local[4], ignition3StartAngle);
++pStart;
}
}
void test_rotary_channel4_calcs(void)
{
setEngineSpeed(4000, 360);
static const int16_t test_data[][5] PROGMEM = {
{ -40, 5, 0, -40, 315 },
{ -40, 95, 0, -40, 225 },
{ -40, 185, 0, -40, 135 },
{ -40, 275, 0, -40, 45 },
{ -40, 355, 0, -40, -35 },
{ -40, 5, 40, 0, 355 },
{ -40, 95, 40, 0, 265 },
{ -40, 185, 40, 0, 175 },
{ -40, 275, 40, 0, 85 },
{ -40, 355, 40, 0, 5 },
{ 0, 5, 0, 0, 355 },
{ 0, 95, 0, 0, 265 },
{ 0, 185, 0, 0, 175 },
{ 0, 275, 0, 0, 85 },
{ 0, 355, 0, 0, 5 },
{ 0, 5, 40, 40, 35 },
{ 0, 95, 40, 40, 305 },
{ 0, 185, 40, 40, 215 },
{ 0, 275, 40, 40, 125 },
{ 0, 355, 40, 40, 45 },
{ 40, 5, 0, 40, 35 },
{ 40, 95, 0, 40, 305 },
{ 40, 185, 0, 40, 215 },
{ 40, 275, 0, 40, 125 },
{ 40, 355, 0, 40, 45 },
{ 40, 5, 40, 80, 75 },
{ 40, 95, 40, 80, 345 },
{ 40, 185, 40, 80, 255 },
{ 40, 275, 40, 80, 165 },
{ 40, 355, 40, 80, 85 },
};
const int16_t (*pStart)[5] = &test_data[0];
const int16_t (*pEnd)[5] = &test_data[0]+_countof(test_data);
channel1IgnDegrees = 0;
int16_t local[5];
while (pStart!=pEnd)
{
memcpy_P(local, pStart, sizeof(local));
ignition2EndAngle = local[0];
calculateIgnitionAngle4(local[1], local[2]);
TEST_ASSERT_EQUAL(local[3], ignition4EndAngle);
TEST_ASSERT_EQUAL(local[4], ignition4StartAngle);
++pStart;
}
}
void test_calc_ign_timeout(void)
{
RUN_TEST(test_calc_ign1_timeout);
RUN_TEST(test_calc_ign_timeout_360);
RUN_TEST(test_calc_ign_timeout_720);
RUN_TEST(test_rotary_channel3_calcs);
RUN_TEST(test_rotary_channel4_calcs);
}

View File

@ -0,0 +1,336 @@
#include <Arduino.h>
#include <unity.h>
#include "test_calcs_common.h"
#include "schedule_calcs.h"
#include "crankMaths.h"
#define _countof(x) (sizeof(x) / sizeof (x[0]))
// void printFreeRam()
// {
// char msg[128];
// sprintf(msg, "freeRam: %u", freeRam());
// TEST_MESSAGE(msg);
// }
struct inj_test_parameters
{
uint16_t channelAngle; // deg
uint16_t pw; // uS
uint16_t crankAngle; // deg
uint32_t pending; // Expected delay when channel status is PENDING
uint32_t running; // Expected delay when channel status is RUNNING
};
static void test_calc_inj1_timeout(uint16_t pw, uint16_t crankAngle, uint32_t pending, uint32_t running)
{
uint16_t PWdivTimerPerDegree = div(pw, timePerDegree).quot;
memset(&fuelSchedule1, 0, sizeof(fuelSchedule1));
fuelSchedule1.Status = PENDING;
uint16_t startAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, 0);
TEST_ASSERT_EQUAL(pending, calculateInjector1Timeout(startAngle, crankAngle));
fuelSchedule1.Status = RUNNING;
startAngle = calculateInjectorStartAngle( PWdivTimerPerDegree, 0);
TEST_ASSERT_EQUAL(running, calculateInjector1Timeout(startAngle, crankAngle));
}
static void test_calc_injN_timeout(const inj_test_parameters &parameters)
{
char msg[150];
uint16_t PWdivTimerPerDegree = div(parameters.pw, timePerDegree).quot;
memset(&fuelSchedule2, 0, sizeof(fuelSchedule2));
fuelSchedule2.Status = PENDING;
uint16_t startAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, parameters.channelAngle);
sprintf_P(msg, PSTR("PENDING channelAngle: % " PRIu16 ", pw: % " PRIu16 ", crankAngle: % " PRIu16 ", startAngle: % " PRIu16 ""), parameters.channelAngle, parameters.pw, parameters.crankAngle, startAngle);
TEST_ASSERT_EQUAL_MESSAGE(parameters.pending, calculateInjectorNTimeout(fuelSchedule2, parameters.channelAngle, startAngle, parameters.crankAngle), msg);
fuelSchedule2.Status = RUNNING;
startAngle = calculateInjectorStartAngle( PWdivTimerPerDegree, parameters.channelAngle);
sprintf_P(msg, PSTR("RUNNING channelAngle: % " PRIu16 ", pw: % " PRIu16 ", crankAngle: % " PRIu16 ", startAngle: % " PRIu16 ""), parameters.channelAngle, parameters.pw, parameters.crankAngle, startAngle);
TEST_ASSERT_EQUAL_MESSAGE(parameters.running, calculateInjectorNTimeout(fuelSchedule2, parameters.channelAngle, startAngle, parameters.crankAngle), msg);
}
static void test_calc_inj_timeout(const inj_test_parameters *pStart, const inj_test_parameters *pEnd)
{
inj_test_parameters local;
while (pStart!=pEnd)
{
memcpy_P(&local, pStart, sizeof(local));
test_calc_injN_timeout(local);
++pStart;
}
}
// Separate test for fuel 1 - different code path, same results!
static void test_calc_inj1_timeout()
{
setEngineSpeed(4000, 360);
currentStatus.injAngle = 355;
static const int16_t test_data[][4] PROGMEM = {
// ChannelAngle (deg), PW (uS), Crank (deg), Expected Pending, Expected Running
{ 3000, 0, 11562, 11562 },
{ 3000, 45, 9717, 9717 },
{ 3000, 90, 7872, 7872 },
{ 3000, 135, 6027, 6027 },
{ 3000, 180, 4182, 4182 },
{ 3000, 215, 2747, 2747 },
{ 3000, 270, 492, 492 },
{ 3000, 315, 0, 13407 },
{ 3000, 360, 0, 11562 },
{ 3000, 0, 11562, 11562 },
{ 3000, 45, 9717, 9717 },
{ 3000, 90, 7872, 7872 },
{ 3000, 135, 6027, 6027 },
{ 3000, 180, 4182, 4182 },
{ 3000, 215, 2747, 2747 },
{ 3000, 270, 492, 492 },
{ 3000, 315, 0, 13407 },
{ 3000, 360, 0, 11562 },
};
const int16_t (*pStart)[4] = &test_data[0];
const int16_t (*pEnd)[4] = &test_data[0]+_countof(test_data);
int16_t local[4];
while (pStart!=pEnd)
{
memcpy_P(local, pStart, sizeof(local));
test_calc_inj1_timeout(local[0], local[1], local[2], local[3]);
++pStart;
}
}
static void test_calc_injN_timeout_360()
{
setEngineSpeed(4000, 360);
currentStatus.injAngle = 355;
static const inj_test_parameters test_data[] PROGMEM = {
// ChannelAngle (deg), PW (uS), Crank (deg), Expected Pending (uS), Expected Running (uS)
{ 0, 3000, 0, 11562, 11562 },
{ 0, 3000, 45, 9717, 9717 },
{ 0, 3000, 90, 7872, 7872 },
{ 0, 3000, 135, 6027, 6027 },
{ 0, 3000, 180, 4182, 4182 },
{ 0, 3000, 215, 2747, 2747 },
{ 0, 3000, 270, 492, 492 },
{ 0, 3000, 315, 0, 13407 },
{ 0, 3000, 360, 0, 11562 },
{ 72, 3000, 0, 0, 14514 },
{ 72, 3000, 45, 0, 12669 },
{ 72, 3000, 90, 10824, 10824 },
{ 72, 3000, 135, 8979, 8979 },
{ 72, 3000, 180, 7134, 7134 },
{ 72, 3000, 215, 5699, 5699 },
{ 72, 3000, 270, 3444, 3444 },
{ 72, 3000, 315, 1599, 1599 },
{ 72, 3000, 360, 0, 14514 },
{ 80, 3000, 0, 82, 82 },
{ 80, 3000, 45, 0, 12997 },
{ 80, 3000, 90, 11152, 11152 },
{ 80, 3000, 135, 9307, 9307 },
{ 80, 3000, 180, 7462, 7462 },
{ 80, 3000, 215, 6027, 6027 },
{ 80, 3000, 270, 3772, 3772 },
{ 80, 3000, 315, 1927, 1927 },
{ 80, 3000, 360, 82, 82 },
{ 90, 3000, 0, 492, 492 },
{ 90, 3000, 45, 0, 13407 },
{ 90, 3000, 90, 11562, 11562 },
{ 90, 3000, 135, 9717, 9717 },
{ 90, 3000, 180, 7872, 7872 },
{ 90, 3000, 215, 6437, 6437 },
{ 90, 3000, 270, 4182, 4182 },
{ 90, 3000, 315, 2337, 2337 },
{ 90, 3000, 360, 492, 492 },
{ 144, 3000, 0, 2706, 2706 },
{ 144, 3000, 45, 861, 861 },
{ 144, 3000, 90, 0, 13776 },
{ 144, 3000, 135, 0, 11931 },
{ 144, 3000, 180, 10086, 10086 },
{ 144, 3000, 215, 8651, 8651 },
{ 144, 3000, 270, 6396, 6396 },
{ 144, 3000, 315, 4551, 4551 },
{ 144, 3000, 360, 2706, 2706 },
{ 180, 3000, 0, 4182, 4182 },
{ 180, 3000, 45, 2337, 2337 },
{ 180, 3000, 90, 492, 492 },
{ 180, 3000, 135, 0, 13407 },
{ 180, 3000, 180, 11562, 11562 },
{ 180, 3000, 215, 10127, 10127 },
{ 180, 3000, 270, 7872, 7872 },
{ 180, 3000, 315, 6027, 6027 },
{ 180, 3000, 360, 4182, 4182 },
{ 240, 3000, 0, 6642, 6642 },
{ 240, 3000, 45, 4797, 4797 },
{ 240, 3000, 90, 2952, 2952 },
{ 240, 3000, 135, 1107, 1107 },
{ 240, 3000, 180, 0, 14022 },
{ 240, 3000, 215, 0, 12587 },
{ 240, 3000, 270, 10332, 10332 },
{ 240, 3000, 315, 8487, 8487 },
{ 240, 3000, 360, 6642, 6642 },
{ 270, 3000, 0, 7872, 7872 },
{ 270, 3000, 45, 6027, 6027 },
{ 270, 3000, 90, 4182, 4182 },
{ 270, 3000, 135, 2337, 2337 },
{ 270, 3000, 180, 492, 492 },
{ 270, 3000, 215, 0, 13817 },
{ 270, 3000, 270, 11562, 11562 },
{ 270, 3000, 315, 9717, 9717 },
{ 270, 3000, 360, 7872, 7872 },
{ 360, 3000, 0, 11562, 11562 },
{ 360, 3000, 45, 9717, 9717 },
{ 360, 3000, 90, 7872, 7872 },
{ 360, 3000, 135, 6027, 6027 },
{ 360, 3000, 180, 4182, 4182 },
{ 360, 3000, 215, 2747, 2747 },
{ 360, 3000, 270, 492, 492 },
{ 360, 3000, 315, 0, 13407 },
{ 360, 3000, 360, 11562, 11562 },
};
test_calc_inj_timeout(&test_data[0], &test_data[0]+_countof(test_data));
}
static void test_calc_injN_timeout_720()
{
setEngineSpeed(4000, 720);
currentStatus.injAngle = 355;
static const inj_test_parameters test_data[] PROGMEM = {
// ChannelAngle (deg), PW (uS), Crank (deg), Expected Pending (uS), Expected Running (uS)
{ 0, 3000, 90, 7872, 7872 },
{ 0, 3000, 135, 6027, 6027 },
{ 0, 3000, 180, 4182, 4182 },
{ 0, 3000, 215, 2747, 2747 },
{ 0, 3000, 270, 492, 492 },
{ 0, 3000, 315, 0, 28167 },
{ 0, 3000, 360, 0, 26322 },
{ 72, 3000, 0, 0, 14514 },
{ 72, 3000, 45, 0, 12669 },
{ 72, 3000, 90, 10824, 10824 },
{ 72, 3000, 135, 8979, 8979 },
{ 72, 3000, 180, 7134, 7134 },
{ 72, 3000, 215, 5699, 5699 },
{ 72, 3000, 270, 3444, 3444 },
{ 72, 3000, 315, 1599, 1599 },
{ 72, 3000, 360, 0, 29274 },
{ 80, 3000, 0, 0, 14842 },
{ 80, 3000, 45, 0, 12997 },
{ 80, 3000, 90, 11152, 11152 },
{ 80, 3000, 135, 9307, 9307 },
{ 80, 3000, 180, 7462, 7462 },
{ 80, 3000, 215, 6027, 6027 },
{ 80, 3000, 270, 3772, 3772 },
{ 80, 3000, 315, 1927, 1927 },
{ 80, 3000, 360, 82, 82 },
{ 90, 3000, 0, 0, 15252 },
{ 90, 3000, 45, 0, 13407 },
{ 90, 3000, 90, 11562, 11562 },
{ 90, 3000, 135, 9717, 9717 },
{ 90, 3000, 180, 7872, 7872 },
{ 90, 3000, 215, 6437, 6437 },
{ 90, 3000, 270, 4182, 4182 },
{ 90, 3000, 315, 2337, 2337 },
{ 90, 3000, 360, 492, 492 },
{ 144, 3000, 0, 0, 17466 },
{ 144, 3000, 45, 0, 15621 },
{ 144, 3000, 90, 0, 13776 },
{ 144, 3000, 135, 0, 11931 },
{ 144, 3000, 180, 10086, 10086 },
{ 144, 3000, 215, 8651, 8651 },
{ 144, 3000, 270, 6396, 6396 },
{ 144, 3000, 315, 4551, 4551 },
{ 144, 3000, 360, 2706, 2706 },
{ 180, 3000, 0, 0, 18942 },
{ 180, 3000, 45, 0, 17097 },
{ 180, 3000, 90, 0, 15252 },
{ 180, 3000, 135, 0, 13407 },
{ 180, 3000, 180, 11562, 11562 },
{ 180, 3000, 215, 10127, 10127 },
{ 180, 3000, 270, 7872, 7872 },
{ 180, 3000, 315, 6027, 6027 },
{ 180, 3000, 360, 4182, 4182 },
{ 240, 3000, 0, 0, 21402 },
{ 240, 3000, 45, 0, 19557 },
{ 240, 3000, 90, 0, 17712 },
{ 240, 3000, 135, 0, 15867 },
{ 240, 3000, 180, 0, 14022 },
{ 240, 3000, 215, 0, 12587 },
{ 240, 3000, 270, 10332, 10332 },
{ 240, 3000, 315, 8487, 8487 },
{ 240, 3000, 360, 6642, 6642 },
{ 270, 3000, 0, 0, 22632 },
{ 270, 3000, 45, 0, 20787 },
{ 270, 3000, 90, 0, 18942 },
{ 270, 3000, 135, 0, 17097 },
{ 270, 3000, 180, 0, 15252 },
{ 270, 3000, 215, 0, 13817 },
{ 270, 3000, 270, 11562, 11562 },
{ 270, 3000, 315, 9717, 9717 },
{ 270, 3000, 360, 7872, 7872 },
{ 360, 3000, 0, 0, 26322 },
{ 360, 3000, 45, 0, 24477 },
{ 360, 3000, 90, 0, 22632 },
{ 360, 3000, 135, 0, 20787 },
{ 360, 3000, 180, 0, 18942 },
{ 360, 3000, 215, 0, 17507 },
{ 360, 3000, 270, 0, 15252 },
{ 360, 3000, 315, 0, 13407 },
{ 360, 3000, 360, 11562, 11562 },
{ 480, 3000, 0, 1722, 1722 },
{ 480, 3000, 45, 0, 29397 },
{ 480, 3000, 90, 0, 27552 },
{ 480, 3000, 135, 0, 25707 },
{ 480, 3000, 180, 0, 23862 },
{ 480, 3000, 215, 0, 22427 },
{ 480, 3000, 270, 0, 20172 },
{ 480, 3000, 315, 0, 18327 },
{ 480, 3000, 360, 0, 16482 },
{ 540, 3000, 0, 4182, 4182 },
{ 540, 3000, 45, 2337, 2337 },
{ 540, 3000, 90, 492, 492 },
{ 540, 3000, 135, 0, 28167 },
{ 540, 3000, 180, 0, 26322 },
{ 540, 3000, 215, 0, 24887 },
{ 540, 3000, 270, 0, 22632 },
{ 540, 3000, 315, 0, 20787 },
{ 540, 3000, 360, 0, 18942 },
{ 600, 3000, 0, 6642, 6642 },
{ 600, 3000, 45, 4797, 4797 },
{ 600, 3000, 90, 2952, 2952 },
{ 600, 3000, 135, 1107, 1107 },
{ 600, 3000, 180, 0, 28782 },
{ 600, 3000, 215, 0, 27347 },
{ 600, 3000, 270, 0, 25092 },
{ 600, 3000, 315, 0, 23247 },
{ 600, 3000, 360, 0, 21402 },
{ 630, 3000, 0, 7872, 7872 },
{ 630, 3000, 45, 6027, 6027 },
{ 630, 3000, 90, 4182, 4182 },
{ 630, 3000, 135, 2337, 2337 },
{ 630, 3000, 180, 492, 492 },
{ 630, 3000, 215, 0, 28577 },
{ 630, 3000, 270, 0, 26322 },
{ 630, 3000, 315, 0, 24477 },
{ 630, 3000, 360, 0, 22632 },
};
test_calc_inj_timeout(&test_data[0], &test_data[0]+_countof(test_data));
}
//
void test_calc_inj_timeout(void)
{
RUN_TEST(test_calc_inj1_timeout);
RUN_TEST(test_calc_injN_timeout_360);
RUN_TEST(test_calc_injN_timeout_720);
}

View File

@ -0,0 +1,28 @@
#include <Arduino.h>
#include <unity.h>
#include <init.h>
extern void test_calc_ign_timeout();
extern void test_calc_inj_timeout();
void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
delay(2000);
UNITY_BEGIN(); // start unit testing
test_calc_ign_timeout();
test_calc_inj_timeout();
UNITY_END(); // stop unit testing
}
void loop()
{
digitalWrite(LED_BUILTIN, HIGH);
delay(250);
digitalWrite(LED_BUILTIN, LOW);
delay(250);
}

View File

@ -56,9 +56,9 @@ void test_accuracy_duration_inj4(void)
TEST_ASSERT_UINT32_WITHIN(DELTA, DURATION, end_time - start_time);
}
#if INJ_CHANNELS >= 5
void test_accuracy_duration_inj5(void)
{
#if INJ_CHANNELS >= 5
initialiseSchedulers();
setFuelSchedule5(TIMEOUT, DURATION);
while(fuelSchedule5.Status == PENDING) /*Wait*/ ;
@ -66,12 +66,12 @@ void test_accuracy_duration_inj5(void)
while(fuelSchedule5.Status == RUNNING) /*Wait*/ ;
end_time = micros();
TEST_ASSERT_UINT32_WITHIN(DELTA, DURATION, end_time - start_time);
#endif
}
#endif
#if INJ_CHANNELS >= 6
void test_accuracy_duration_inj6(void)
{
#if INJ_CHANNELS >= 6
initialiseSchedulers();
setFuelSchedule6(TIMEOUT, DURATION);
while(fuelSchedule6.Status == PENDING) /*Wait*/ ;
@ -79,12 +79,12 @@ void test_accuracy_duration_inj6(void)
while(fuelSchedule6.Status == RUNNING) /*Wait*/ ;
end_time = micros();
TEST_ASSERT_UINT32_WITHIN(DELTA, DURATION, end_time - start_time);
#endif
}
#endif
#if INJ_CHANNELS >= 7
void test_accuracy_duration_inj7(void)
{
#if INJ_CHANNELS >= 7
initialiseSchedulers();
setFuelSchedule7(TIMEOUT, DURATION);
while(fuelSchedule7.Status == PENDING) /*Wait*/ ;
@ -92,12 +92,12 @@ void test_accuracy_duration_inj7(void)
while(fuelSchedule7.Status == RUNNING) /*Wait*/ ;
end_time = micros();
TEST_ASSERT_UINT32_WITHIN(DELTA, DURATION, end_time - start_time);
#endif
}
#endif
#if INJ_CHANNELS >= 8
void test_accuracy_duration_inj8(void)
{
#if INJ_CHANNELS >= 8
initialiseSchedulers();
setFuelSchedule8(TIMEOUT, DURATION);
while(fuelSchedule8.Status == PENDING) /*Wait*/ ;
@ -105,9 +105,8 @@ void test_accuracy_duration_inj8(void)
while(fuelSchedule8.Status == RUNNING) /*Wait*/ ;
end_time = micros();
TEST_ASSERT_UINT32_WITHIN(DELTA, DURATION, end_time - start_time);
#endif
}
#endif
void test_accuracy_duration_ign1(void)
@ -152,35 +151,35 @@ void test_accuracy_duration_ign5(void)
#endif
}
#if INJ_CHANNELS >= 6
void test_accuracy_duration_ign6(void)
{
#if INJ_CHANNELS >= 6
initialiseSchedulers();
setIgnitionSchedule6(startCallback, TIMEOUT, DURATION, endCallback);
while( (ignitionSchedule6.Status == PENDING) || (ignitionSchedule6.Status == RUNNING) ) /*Wait*/ ;
TEST_ASSERT_UINT32_WITHIN(DELTA, TIMEOUT, end_time - start_time);
#endif
}
#endif
#if INJ_CHANNELS >= 7
void test_accuracy_duration_ign7(void)
{
#if INJ_CHANNELS >= 7
initialiseSchedulers();
setIgnitionSchedule7(startCallback, TIMEOUT, DURATION, endCallback);
while( (ignitionSchedule7.Status == PENDING) || (ignitionSchedule7.Status == RUNNING) ) /*Wait*/ ;
TEST_ASSERT_UINT32_WITHIN(DELTA, TIMEOUT, end_time - start_time);
#endif
}
#endif
#if INJ_CHANNELS >= 8
void test_accuracy_duration_ign8(void)
{
#if INJ_CHANNELS >= 8
initialiseSchedulers();
setIgnitionSchedule8(startCallback, TIMEOUT, DURATION, endCallback);
while( (ignitionSchedule8.Status == PENDING) || (ignitionSchedule8.Status == RUNNING) ) /*Wait*/ ;
TEST_ASSERT_UINT32_WITHIN(DELTA, TIMEOUT, end_time - start_time);
#endif
}
#endif
void test_accuracy_duration(void)
{
@ -188,17 +187,33 @@ void test_accuracy_duration(void)
RUN_TEST(test_accuracy_duration_inj2);
RUN_TEST(test_accuracy_duration_inj3);
RUN_TEST(test_accuracy_duration_inj4);
#if INJ_CHANNELS >= 5
RUN_TEST(test_accuracy_duration_inj5);
#endif
#if INJ_CHANNELS >= 6
RUN_TEST(test_accuracy_duration_inj6);
#endif
#if INJ_CHANNELS >= 7
RUN_TEST(test_accuracy_duration_inj7);
#endif
#if INJ_CHANNELS >= 8
RUN_TEST(test_accuracy_duration_inj8);
#endif
RUN_TEST(test_accuracy_duration_ign1);
RUN_TEST(test_accuracy_duration_ign2);
RUN_TEST(test_accuracy_duration_ign3);
RUN_TEST(test_accuracy_duration_ign4);
#if INJ_CHANNELS >= 5
RUN_TEST(test_accuracy_duration_ign5);
#endif
#if INJ_CHANNELS >= 6
RUN_TEST(test_accuracy_duration_ign6);
#endif
#if INJ_CHANNELS >= 7
RUN_TEST(test_accuracy_duration_ign7);
#endif
#if INJ_CHANNELS >= 8
RUN_TEST(test_accuracy_duration_ign8);
#endif
}

View File

@ -53,53 +53,53 @@ void test_accuracy_timeout_inj4(void)
TEST_ASSERT_UINT32_WITHIN(DELTA, TIMEOUT, end_time - start_time);
}
#if INJ_CHANNELS >= 5
void test_accuracy_timeout_inj5(void)
{
#if INJ_CHANNELS >= 5
initialiseSchedulers();
start_time = micros();
setFuelSchedule5(TIMEOUT, DURATION);
while(fuelSchedule5.Status == PENDING) /*Wait*/ ;
end_time = micros();
TEST_ASSERT_UINT32_WITHIN(DELTA, TIMEOUT, end_time - start_time);
#endif
}
#endif
#if INJ_CHANNELS >= 6
void test_accuracy_timeout_inj6(void)
{
#if INJ_CHANNELS >= 6
initialiseSchedulers();
start_time = micros();
setFuelSchedule6(TIMEOUT, DURATION);
while(fuelSchedule6.Status == PENDING) /*Wait*/ ;
end_time = micros();
TEST_ASSERT_UINT32_WITHIN(DELTA, TIMEOUT, end_time - start_time);
#endif
}
#endif
#if INJ_CHANNELS >= 7
void test_accuracy_timeout_inj7(void)
{
#if INJ_CHANNELS >= 7
initialiseSchedulers();
start_time = micros();
setFuelSchedule7(TIMEOUT, DURATION);
while(fuelSchedule7.Status == PENDING) /*Wait*/ ;
end_time = micros();
TEST_ASSERT_UINT32_WITHIN(DELTA, TIMEOUT, end_time - start_time);
#endif
}
#endif
#if INJ_CHANNELS >= 8
void test_accuracy_timeout_inj8(void)
{
#if INJ_CHANNELS >= 8
initialiseSchedulers();
start_time = micros();
setFuelSchedule8(TIMEOUT, DURATION);
while(fuelSchedule8.Status == PENDING) /*Wait*/ ;
end_time = micros();
TEST_ASSERT_UINT32_WITHIN(DELTA, TIMEOUT, end_time - start_time);
#endif
}
#endif
void test_accuracy_timeout_ign1(void)
@ -138,49 +138,49 @@ void test_accuracy_timeout_ign4(void)
TEST_ASSERT_UINT32_WITHIN(DELTA, TIMEOUT, end_time - start_time);
}
#if IGN_CHANNELS >= 5
void test_accuracy_timeout_ign5(void)
{
#if IGN_CHANNELS >= 5
initialiseSchedulers();
start_time = micros();
setIgnitionSchedule5(startCallback, TIMEOUT, DURATION, endCallback);
while(ignitionSchedule5.Status == PENDING) /*Wait*/ ;
TEST_ASSERT_UINT32_WITHIN(DELTA, TIMEOUT, end_time - start_time);
#endif
}
#endif
#if IGN_CHANNELS >= 6
void test_accuracy_timeout_ign6(void)
{
#if INJ_CHANNELS >= 6
initialiseSchedulers();
start_time = micros();
setIgnitionSchedule6(startCallback, TIMEOUT, DURATION, endCallback);
while(ignitionSchedule6.Status == PENDING) /*Wait*/ ;
TEST_ASSERT_UINT32_WITHIN(DELTA, TIMEOUT, end_time - start_time);
#endif
}
#endif
#if IGN_CHANNELS >= 7
void test_accuracy_timeout_ign7(void)
{
#if INJ_CHANNELS >= 7
initialiseSchedulers();
start_time = micros();
setIgnitionSchedule7(startCallback, TIMEOUT, DURATION, endCallback);
while(ignitionSchedule7.Status == PENDING) /*Wait*/ ;
TEST_ASSERT_UINT32_WITHIN(DELTA, TIMEOUT, end_time - start_time);
#endif
}
#endif
#if IGN_CHANNELS >= 8
void test_accuracy_timeout_ign8(void)
{
#if INJ_CHANNELS >= 8
initialiseSchedulers();
start_time = micros();
setIgnitionSchedule8(startCallback, TIMEOUT, DURATION, endCallback);
while(ignitionSchedule8.Status == PENDING) /*Wait*/ ;
TEST_ASSERT_UINT32_WITHIN(DELTA, TIMEOUT, end_time - start_time);
#endif
}
#endif
void test_accuracy_timeout(void)
{
@ -188,17 +188,33 @@ void test_accuracy_timeout(void)
RUN_TEST(test_accuracy_timeout_inj2);
RUN_TEST(test_accuracy_timeout_inj3);
RUN_TEST(test_accuracy_timeout_inj4);
#if INJ_CHANNELS >= 5
RUN_TEST(test_accuracy_timeout_inj5);
#endif
#if INJ_CHANNELS >= 6
RUN_TEST(test_accuracy_timeout_inj6);
#endif
#if INJ_CHANNELS >= 7
RUN_TEST(test_accuracy_timeout_inj7);
#endif
#if INJ_CHANNELS >= 8
RUN_TEST(test_accuracy_timeout_inj8);
#endif
RUN_TEST(test_accuracy_timeout_ign1);
RUN_TEST(test_accuracy_timeout_ign2);
RUN_TEST(test_accuracy_timeout_ign3);
RUN_TEST(test_accuracy_timeout_ign4);
#if IGN_CHANNELS >= 5
RUN_TEST(test_accuracy_timeout_ign5);
#endif
#if IGN_CHANNELS >= 6
RUN_TEST(test_accuracy_timeout_ign6);
#endif
#if IGN_CHANNELS >= 7
RUN_TEST(test_accuracy_timeout_ign7);
#endif
#if IGN_CHANNELS >= 8
RUN_TEST(test_accuracy_timeout_ign8);
#endif
}

View File

@ -19,7 +19,7 @@ void setup()
//test_status_running_to_off();
test_accuracy_timeout();
test_accuracy_duration();
UNITY_END(); // stop unit testing
}

View File

@ -7,8 +7,9 @@ void test_status_off_to_pending(void);
void test_status_pending_to_running(void);
void test_status_running_to_off(void);
void test_status_running_to_pending(void);
void test_accuracy_timeout(void);
void test_accuracy_duration(void);
void test_accuracy_timeout(void);
#endif // __TEST_SCHEDULE_H__

View File

@ -28,29 +28,37 @@ void test_status_initial_off_inj4(void)
TEST_ASSERT_EQUAL(OFF, fuelSchedule4.Status);
}
#if INJ_CHANNELS >= 5
void test_status_initial_off_inj5(void)
{
initialiseSchedulers();
TEST_ASSERT_EQUAL(OFF, fuelSchedule5.Status);
}
#endif
#if INJ_CHANNELS >= 6
void test_status_initial_off_inj6(void)
{
initialiseSchedulers();
TEST_ASSERT_EQUAL(OFF, fuelSchedule6.Status);
}
#endif
#if INJ_CHANNELS >= 7
void test_status_initial_off_inj7(void)
{
initialiseSchedulers();
TEST_ASSERT_EQUAL(OFF, fuelSchedule7.Status);
}
#endif
#if INJ_CHANNELS >= 8
void test_status_initial_off_inj8(void)
{
initialiseSchedulers();
TEST_ASSERT_EQUAL(OFF, fuelSchedule8.Status);
}
#endif
void test_status_initial_off_ign1(void)
@ -77,29 +85,37 @@ void test_status_initial_off_ign4(void)
TEST_ASSERT_EQUAL(OFF, ignitionSchedule4.Status);
}
#if IGN_CHANNELS >= 5
void test_status_initial_off_ign5(void)
{
initialiseSchedulers();
TEST_ASSERT_EQUAL(OFF, ignitionSchedule5.Status);
}
#endif
#if IGN_CHANNELS >= 6
void test_status_initial_off_ign6(void)
{
initialiseSchedulers();
TEST_ASSERT_EQUAL(OFF, ignitionSchedule6.Status);
}
#endif
#if IGN_CHANNELS >= 7
void test_status_initial_off_ign7(void)
{
initialiseSchedulers();
TEST_ASSERT_EQUAL(OFF, ignitionSchedule7.Status);
}
#endif
#if IGN_CHANNELS >= 8
void test_status_initial_off_ign8(void)
{
initialiseSchedulers();
TEST_ASSERT_EQUAL(OFF, ignitionSchedule8.Status);
}
#endif
void test_status_initial_off(void)
{
@ -107,17 +123,33 @@ void test_status_initial_off(void)
RUN_TEST(test_status_initial_off_inj2);
RUN_TEST(test_status_initial_off_inj3);
RUN_TEST(test_status_initial_off_inj4);
#if INJ_CHANNELS >= 5
RUN_TEST(test_status_initial_off_inj5);
#endif
#if INJ_CHANNELS >= 6
RUN_TEST(test_status_initial_off_inj6);
#endif
#if INJ_CHANNELS >= 7
RUN_TEST(test_status_initial_off_inj7);
#endif
#if INJ_CHANNELS >= 8
RUN_TEST(test_status_initial_off_inj8);
#endif
RUN_TEST(test_status_initial_off_ign1);
RUN_TEST(test_status_initial_off_ign2);
RUN_TEST(test_status_initial_off_ign3);
RUN_TEST(test_status_initial_off_ign4);
#if IGN_CHANNELS >= 5
RUN_TEST(test_status_initial_off_ign5);
#endif
#if IGN_CHANNELS >= 6
RUN_TEST(test_status_initial_off_ign6);
#endif
#if IGN_CHANNELS >= 7
RUN_TEST(test_status_initial_off_ign7);
#endif
#if IGN_CHANNELS >= 8
RUN_TEST(test_status_initial_off_ign8);
#endif
}

View File

@ -37,41 +37,41 @@ void test_status_off_to_pending_inj4(void)
TEST_ASSERT_EQUAL(PENDING, fuelSchedule4.Status);
}
#if INJ_CHANNELS >= 5
void test_status_off_to_pending_inj5(void)
{
#if INJ_CHANNELS >= 5
initialiseSchedulers();
setFuelSchedule5(TIMEOUT, DURATION);
TEST_ASSERT_EQUAL(PENDING, fuelSchedule5.Status);
#endif
}
#endif
#if INJ_CHANNELS >= 6
void test_status_off_to_pending_inj6(void)
{
#if INJ_CHANNELS >= 6
initialiseSchedulers();
setFuelSchedule6(TIMEOUT, DURATION);
TEST_ASSERT_EQUAL(PENDING, fuelSchedule6.Status);
#endif
}
#endif
#if INJ_CHANNELS >= 7
void test_status_off_to_pending_inj7(void)
{
#if INJ_CHANNELS >= 7
initialiseSchedulers();
setFuelSchedule7(TIMEOUT, DURATION);
TEST_ASSERT_EQUAL(PENDING, fuelSchedule7.Status);
#endif
}
#endif
#if INJ_CHANNELS >= 8
void test_status_off_to_pending_inj8(void)
{
#if INJ_CHANNELS >= 8
initialiseSchedulers();
setFuelSchedule8(TIMEOUT, DURATION);
TEST_ASSERT_EQUAL(PENDING, fuelSchedule8.Status);
#endif
}
#endif
void test_status_off_to_pending_ign1(void)
@ -102,41 +102,41 @@ void test_status_off_to_pending_ign4(void)
TEST_ASSERT_EQUAL(PENDING, ignitionSchedule4.Status);
}
#if IGN_CHANNELS >= 5
void test_status_off_to_pending_ign5(void)
{
#if IGN_CHANNELS >= 5
initialiseSchedulers();
setIgnitionSchedule5(emptyCallback, TIMEOUT, DURATION, emptyCallback);
TEST_ASSERT_EQUAL(PENDING, ignitionSchedule5.Status);
#endif
}
#endif
#if IGN_CHANNELS >= 6
void test_status_off_to_pending_ign6(void)
{
#if INJ_CHANNELS >= 6
initialiseSchedulers();
setIgnitionSchedule6(emptyCallback, TIMEOUT, DURATION, emptyCallback);
TEST_ASSERT_EQUAL(PENDING, ignitionSchedule6.Status);
#endif
}
#endif
#if IGN_CHANNELS >= 7
void test_status_off_to_pending_ign7(void)
{
#if INJ_CHANNELS >= 7
initialiseSchedulers();
setIgnitionSchedule7(emptyCallback, TIMEOUT, DURATION, emptyCallback);
TEST_ASSERT_EQUAL(PENDING, ignitionSchedule7.Status);
#endif
}
#endif
#if IGN_CHANNELS >= 8
void test_status_off_to_pending_ign8(void)
{
#if INJ_CHANNELS >= 8
initialiseSchedulers();
setIgnitionSchedule8(emptyCallback, TIMEOUT, DURATION, emptyCallback);
TEST_ASSERT_EQUAL(PENDING, ignitionSchedule8.Status);
#endif
}
#endif
void test_status_off_to_pending(void)
{
@ -144,17 +144,33 @@ void test_status_off_to_pending(void)
RUN_TEST(test_status_off_to_pending_inj2);
RUN_TEST(test_status_off_to_pending_inj3);
RUN_TEST(test_status_off_to_pending_inj4);
#if INJ_CHANNELS >= 5
RUN_TEST(test_status_off_to_pending_inj5);
#endif
#if INJ_CHANNELS >= 6
RUN_TEST(test_status_off_to_pending_inj6);
#endif
#if INJ_CHANNELS >= 7
RUN_TEST(test_status_off_to_pending_inj7);
#endif
#if INJ_CHANNELS >= 8
RUN_TEST(test_status_off_to_pending_inj8);
#endif
RUN_TEST(test_status_off_to_pending_ign1);
RUN_TEST(test_status_off_to_pending_ign2);
RUN_TEST(test_status_off_to_pending_ign3);
RUN_TEST(test_status_off_to_pending_ign4);
#if IGN_CHANNELS >= 5
RUN_TEST(test_status_off_to_pending_ign5);
#endif
#if IGN_CHANNELS >= 6
RUN_TEST(test_status_off_to_pending_ign6);
#endif
#if IGN_CHANNELS >= 7
RUN_TEST(test_status_off_to_pending_ign7);
#endif
#if IGN_CHANNELS >= 8
RUN_TEST(test_status_off_to_pending_ign8);
#endif
}