Save 600+ bytes RAM (step 3 of 9) - remove per-channel schedule calculation functions, use generic equivalents instead (#1018)

* calculateInjector1Timeout proxies calculateInjectorNTimeout
Unit test still pass.

* Remove calculateInjector1Timeout,
Replace with call to calculateInjectorTimeout
All unit tests still pass.

* Remove unecassary unit test

* calculateIgnition1Timeout proxies calculateIgnitionNTimeout
Unit test all pass

* Remove calculateIgnition1Timeout,
Replace with call to calculateIgnitionTimeout
All unit tests still pass.

* Remove unecassary unit test

* calculateIgnitionAngle\d proxies
calculateIgnitionAngle
Unit tests all pass

* Remove calculateIgnitionAngle\d
Just call calculateIgnitionAngle() directly

* Route rotary ignition angle calcs
through generic calculateIgnitionTrailingRotary
function.

* Remove calculateIgnitionAngle\d
Just call calculateIgnitionTrailingRotary() directly

* calculateInjectorStartAngle: inject all parameters
Do not rely on global state
Easier unit testing.

* calculateIgnitionAngle: inject all parameters
Do not rely on global state
Easier unit testing.

* Pull all ignition global vars into schedule_calcs

* Conditional compile for schedule calc vars
Saves memory

* Optimize: break out angleToTimeIntervalRev
from angleToTime. The new function will
always be inlined.

* Optimize - simpler code path
when no channel offset (zero)

Some optimization of arithmetic operations.

* Fix unit tests

* Fix bug on injector angle calculations
Need while loops to correctly bring intermediate
values into range

---------

Co-authored-by: Josh Stewart <josh@noisymime.org>
This commit is contained in:
tx_haggis 2023-06-25 21:13:53 -05:00 committed by GitHub
parent 2a6c6bd8ed
commit d9b5554a8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 533 additions and 715 deletions

View File

@ -1,6 +1,8 @@
#ifndef CRANKMATHS_H
#define CRANKMATHS_H
#include "maths.h"
#define CRANKMATH_METHOD_INTERVAL_DEFAULT 0
#define CRANKMATH_METHOD_INTERVAL_REV 1
#define CRANKMATH_METHOD_INTERVAL_TOOTH 2
@ -17,7 +19,10 @@
#define ignitionLimits(angle) ( (((int16_t)(angle)) >= CRANK_ANGLE_MAX_IGN) ? ((angle) - CRANK_ANGLE_MAX_IGN) : ( ((int16_t)(angle) < 0) ? ((angle) + CRANK_ANGLE_MAX_IGN) : (angle)) )
unsigned long angleToTime(int16_t angle, byte method);
unsigned long angleToTime(uint16_t angle, byte method);
inline unsigned long angleToTimeIntervalRev(uint16_t angle) {
return div360(angle * revolutionTime);
}
uint16_t timeToAngle(unsigned long time, byte method);
void doCrankSpeedCalcs(void);

View File

@ -25,13 +25,13 @@ int rpmDelta;
* 3) Closed loop error correction (Alpha-beta filter)
* 4) 2nd derivative prediction (Speed + acceleration)
*/
unsigned long angleToTime(int16_t angle, byte method)
unsigned long angleToTime(uint16_t angle, byte method)
{
unsigned long returnTime = 0;
if( (method == CRANKMATH_METHOD_INTERVAL_REV) || (method == CRANKMATH_METHOD_INTERVAL_DEFAULT) )
{
returnTime = div360(angle * revolutionTime);
returnTime = angleToTimeIntervalRev(angle);
//returnTime = angle * (unsigned long)timePerDegree;
}
else if (method == CRANKMATH_METHOD_INTERVAL_TOOTH)

View File

@ -39,6 +39,7 @@ A full copy of the license may be found in the projects root directory
#include "scheduler.h"
#include "crankMaths.h"
#include "timers.h"
#include "schedule_calcs.h"
void (*triggerHandler)(void); ///Pointer for the trigger function (Gets pointed to the relevant decoder)
void (*triggerSecondaryHandler)(void); ///Pointer for the secondary trigger function (Gets pointed to the relevant decoder)

View File

@ -555,24 +555,6 @@ extern byte triggerInterrupt;
extern byte triggerInterrupt2;
extern byte triggerInterrupt3;
extern int ignition1EndAngle;
extern int ignition2EndAngle;
extern int ignition3EndAngle;
extern int ignition4EndAngle;
extern int ignition5EndAngle;
extern int ignition6EndAngle;
extern int ignition7EndAngle;
extern int ignition8EndAngle;
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 bool initialisationComplete; //Tracks whether the setup() function has run completely
extern byte fpPrimeTime; //The time (in seconds, based on currentStatus.secl) that the fuel pump started priming
extern uint8_t softLimitTime; //The time (in 0.1 seconds, based on seclx10) that the soft limiter started

View File

@ -106,15 +106,6 @@ volatile PINMASK_TYPE triggerSec_pin_mask;
volatile PORT_TYPE *triggerThird_pin_port;
volatile PINMASK_TYPE triggerThird_pin_mask;
int ignition1EndAngle = 0;
int ignition2EndAngle = 0;
int ignition3EndAngle = 0;
int ignition4EndAngle = 0;
int ignition5EndAngle = 0;
int ignition6EndAngle = 0;
int ignition7EndAngle = 0;
int ignition8EndAngle = 0;
//These are variables used across multiple files
bool initialisationComplete = false; ///< Tracks whether the setup() function has run completely (true = has run)
byte fpPrimeTime = 0; ///< The time (in seconds, based on @ref statuses.secl) that the fuel pump started priming

View File

@ -465,10 +465,18 @@ void initialiseAll(void)
ignition2EndAngle = 0;
ignition3EndAngle = 0;
ignition4EndAngle = 0;
#if IGN_CHANNELS >= 5
ignition5EndAngle = 0;
#endif
#if IGN_CHANNELS >= 6
ignition6EndAngle = 0;
#endif
#if IGN_CHANNELS >= 7
ignition7EndAngle = 0;
#endif
#if IGN_CHANNELS >= 8
ignition8EndAngle = 0;
#endif
if(configPage2.strokes == FOUR_STROKE) { CRANK_ANGLE_MAX_INJ = 720 / currentStatus.nSquirts; }
else { CRANK_ANGLE_MAX_INJ = 360 / currentStatus.nSquirts; }
@ -717,8 +725,10 @@ void initialiseAll(void)
#else
//This is an invalid config as there are not enough outputs to support sequential + staging
//Put the staging output to the non-existant channel 5
#if (INJ_CHANNELS >= 5)
maxInjOutputs = 5;
channel5InjDegrees = channel1InjDegrees;
#endif
#endif
}
else
@ -758,7 +768,9 @@ void initialiseAll(void)
channel2InjDegrees = 0;
channel3InjDegrees = 0;
channel4InjDegrees = 0;
#if (INJ_CHANNELS >= 5)
channel5InjDegrees = 0;
#endif
}
else
{
@ -766,7 +778,9 @@ void initialiseAll(void)
channel2InjDegrees = 72;
channel3InjDegrees = 144;
channel4InjDegrees = 216;
#if (INJ_CHANNELS >= 5)
channel5InjDegrees = 288;
#endif
//Divide by currentStatus.nSquirts ?
}

View File

@ -1,28 +1,59 @@
#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;
byte channelInjEnabled = 0;
int ignition1StartAngle;
int ignition1EndAngle;
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) */
int ignition2StartAngle;
int ignition2EndAngle;
int channel2IgnDegrees; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
int ignition3StartAngle;
int ignition3EndAngle;
int channel3IgnDegrees; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
int ignition4StartAngle;
int ignition4EndAngle;
int channel4IgnDegrees; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
#if (IGN_CHANNELS >= 5)
int ignition5StartAngle;
int ignition5EndAngle;
int channel5IgnDegrees; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
#endif
#if (IGN_CHANNELS >= 6)
int ignition6StartAngle;
int ignition6EndAngle;
int channel6IgnDegrees; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
#endif
#if (IGN_CHANNELS >= 7)
int ignition7StartAngle;
int ignition7EndAngle;
int channel7IgnDegrees; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
#endif
#if (IGN_CHANNELS >= 8)
int ignition8StartAngle;
int ignition8EndAngle;
int channel8IgnDegrees; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
#endif
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) */
int channel2InjDegrees; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
int channel3InjDegrees; /**< The number of crank degrees until cylinder 3 (and 5/6/7/8) is at TDC */
int channel4InjDegrees; /**< The number of crank degrees until cylinder 4 (and 5/6/7/8) is at TDC */
#if (INJ_CHANNELS >= 5)
int channel5InjDegrees; /**< The number of crank degrees until cylinder 5 is at TDC */
#endif
#if (INJ_CHANNELS >= 6)
int channel6InjDegrees; /**< The number of crank degrees until cylinder 6 is at TDC */
#endif
#if (INJ_CHANNELS >= 7)
int channel7InjDegrees; /**< The number of crank degrees until cylinder 7 is at TDC */
#endif
#if (INJ_CHANNELS >= 8)
int channel8InjDegrees; /**< The number of crank degrees until cylinder 8 is at TDC */
#endif
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

@ -3,51 +3,71 @@
#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 byte channelInjEnabled;
extern int ignition1StartAngle;
extern int ignition1EndAngle;
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 ignition2StartAngle;
extern int ignition2EndAngle;
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 ignition3StartAngle;
extern int ignition3EndAngle;
extern int channel3IgnDegrees; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
extern int ignition4StartAngle;
extern int ignition4EndAngle;
extern int channel4IgnDegrees; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
#if (IGN_CHANNELS >= 5)
extern int ignition5StartAngle;
extern int ignition5EndAngle;
extern int channel5IgnDegrees; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
#endif
#if (IGN_CHANNELS >= 6)
extern int ignition6StartAngle;
extern int ignition6EndAngle;
extern int channel6IgnDegrees; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
#endif
#if (IGN_CHANNELS >= 7)
extern int ignition7StartAngle;
extern int ignition7EndAngle;
extern int channel7IgnDegrees; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
#endif
#if (IGN_CHANNELS >= 8)
extern int ignition8StartAngle;
extern int ignition8EndAngle;
extern int channel8IgnDegrees; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
#endif
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 */
#if (INJ_CHANNELS >= 5)
extern int channel5InjDegrees; /**< The number of crank degrees until cylinder 5 is at TDC */
#endif
#if (INJ_CHANNELS >= 6)
extern int channel6InjDegrees; /**< The number of crank degrees until cylinder 6 is at TDC */
#endif
#if (INJ_CHANNELS >= 7)
extern int channel7InjDegrees; /**< The number of crank degrees until cylinder 7 is at TDC */
#endif
#if (INJ_CHANNELS >= 8)
extern int channel8InjDegrees; /**< The number of crank degrees until cylinder 8 is at TDC */
#endif
inline uint16_t __attribute__((always_inline)) calculateInjectorStartAngle(uint16_t PWdivTimerPerDegree, int16_t injChannelDegrees);
inline uint16_t __attribute__((always_inline)) calculateInjectorStartAngle(uint16_t PWdivTimerPerDegree, int16_t injChannelDegrees, uint16_t injAngle);
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 uint32_t __attribute__((always_inline)) calculateInjectorTimeout(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 void __attribute__((always_inline)) calculateIgnitionAngle(const int dwellAngle, const uint16_t channelIgnDegrees, int8_t advance, int *pEndAngle, int *pStartAngle);
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);
// Ignition for rotary.
inline void __attribute__((always_inline)) calculateIgnitionTrailingRotary(int dwellAngle, int rotarySplitDegrees, int leadIgnitionAngle, int *pEndAngle, int *pStartAngle);
inline uint32_t __attribute__((always_inline)) calculateIgnitionTimeout(const Schedule &schedule, int startAngle, int channelIgnDegrees, int crankAngle);
#include "schedule_calcs.hpp"

View File

@ -1,147 +1,103 @@
#include "globals.h"
// Note that all functions with an underscore prefix are NOT part
// of the public API. They are only here so we can inline them.
#include "scheduler.h"
#include "crankMaths.h"
inline uint16_t calculateInjectorStartAngle(uint16_t PWdivTimerPerDegree, int16_t injChannelDegrees)
inline uint16_t calculateInjectorStartAngle(uint16_t pwDegrees, int16_t injChannelDegrees, uint16_t injAngle)
{
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; }
// 0<=injAngle<=720°
// 0<=injChannelDegrees<=720°
// 0<pwDegrees<=??? (could be many crank rotations in the worst case!)
// 45<=CRANK_ANGLE_MAX_INJ<=720
// (CRANK_ANGLE_MAX_INJ can be as small as 360/nCylinders. E.g. 45° for 8 cylinder)
return tempInjectorStartAngle;
uint16_t startAngle = injAngle + injChannelDegrees;
// Avoid underflow
while (startAngle<pwDegrees) { startAngle = startAngle + CRANK_ANGLE_MAX_INJ; }
// Guarenteed to be >=0.
startAngle = startAngle - pwDegrees;
// Clamp to 0<=startAngle<=CRANK_ANGLE_MAX_INJ
while (startAngle>(uint16_t)CRANK_ANGLE_MAX_INJ) { startAngle = startAngle - CRANK_ANGLE_MAX_INJ; }
return startAngle;
}
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)
inline uint32_t _calculateInjectorTimeout(const FuelSchedule &schedule, uint16_t openAngle, uint16_t crankAngle) {
int16_t delta = openAngle - crankAngle;
if (delta<0)
{
if ((schedule.Status == RUNNING) && (delta>-CRANK_ANGLE_MAX_INJ))
{
return angleToTime((tempStartAngle - tempCrankAngle), CRANKMATH_METHOD_INTERVAL_REV);
// Guarenteed to be >0
delta = delta + CRANK_ANGLE_MAX_INJ;
}
return 0U;
else
{
return 0;
}
}
return ((uint32_t)(delta) * (uint32_t)timePerDegree);
}
static inline int _adjustToInjChannel(int angle, int channelInjDegrees) {
angle = angle - channelInjDegrees;
if( angle < 0) { return angle + CRANK_ANGLE_MAX_INJ; }
return angle;
}
inline uint32_t calculateInjectorTimeout(const FuelSchedule &schedule, int channelInjDegrees, int openAngle, int crankAngle)
{
if (channelInjDegrees==0) {
return _calculateInjectorTimeout(schedule, openAngle, crankAngle);
}
return _calculateInjectorTimeout(schedule, _adjustToInjChannel(openAngle, channelInjDegrees), _adjustToInjChannel(crankAngle, channelInjDegrees));
}
inline void calculateIgnitionAngle(const int dwellAngle, const uint16_t channelIgnDegrees, int8_t advance, int *pEndAngle, int *pStartAngle)
{
*pEndAngle = (channelIgnDegrees==0 ? CRANK_ANGLE_MAX_IGN : channelIgnDegrees) - advance;
if(*pEndAngle > CRANK_ANGLE_MAX_IGN) {*pEndAngle -= CRANK_ANGLE_MAX_IGN;}
*pStartAngle = *pEndAngle - dwellAngle;
if(*pStartAngle < 0) {*pStartAngle += CRANK_ANGLE_MAX_IGN;}
}
inline void calculateIgnitionTrailingRotary(int dwellAngle, int rotarySplitDegrees, int leadIgnitionAngle, int *pEndAngle, int *pStartAngle)
{
*pEndAngle = leadIgnitionAngle + rotarySplitDegrees;
*pStartAngle = *pEndAngle - dwellAngle;
if(*pStartAngle > CRANK_ANGLE_MAX_IGN) {*pStartAngle -= CRANK_ANGLE_MAX_IGN;}
if(*pStartAngle < 0) {*pStartAngle += CRANK_ANGLE_MAX_IGN;}
}
inline uint32_t _calculateIgnitionTimeout(const Schedule &schedule, int16_t startAngle, int16_t crankAngle) {
int16_t delta = startAngle - crankAngle;
if (delta<0)
{
if ((schedule.Status == RUNNING) && (delta>-CRANK_ANGLE_MAX_IGN))
{
// Msut be >0
delta = delta + CRANK_ANGLE_MAX_IGN;
}
else
{
return 0;
}
}
return angleToTimeIntervalRev(delta);
}
static inline uint16_t _adjustToIgnChannel(int angle, int channelInjDegrees) {
angle = angle - channelInjDegrees;
if( angle < 0) { return angle + CRANK_ANGLE_MAX_IGN; }
return angle;
}
inline uint32_t calculateIgnitionTimeout(const Schedule &schedule, int startAngle, int channelIgnDegrees, int crankAngle)
{
if (channelIgnDegrees==0) {
return _calculateIgnitionTimeout(schedule, startAngle, crankAngle);
}
return _calculateIgnitionTimeout(schedule, _adjustToIgnChannel(startAngle, channelIgnDegrees), _adjustToIgnChannel(crankAngle, channelIgnDegrees));
}

View File

@ -135,75 +135,110 @@ void initialiseSchedulers(void)
FUEL8_TIMER_ENABLE();
#endif
ignitionSchedule1.schedulesSet = 0;
ignitionSchedule2.schedulesSet = 0;
ignitionSchedule3.schedulesSet = 0;
ignitionSchedule4.schedulesSet = 0;
ignitionSchedule5.schedulesSet = 0;
ignitionSchedule6.schedulesSet = 0;
ignitionSchedule7.schedulesSet = 0;
ignitionSchedule8.schedulesSet = 0;
ignitionSchedule1.schedulesSet = 0;
ignitionSchedule2.schedulesSet = 0;
ignitionSchedule3.schedulesSet = 0;
ignitionSchedule4.schedulesSet = 0;
ignitionSchedule5.schedulesSet = 0;
ignitionSchedule6.schedulesSet = 0;
ignitionSchedule7.schedulesSet = 0;
ignitionSchedule8.schedulesSet = 0;
ignition1StartAngle = 0;
ignition2StartAngle = 0;
ignition3StartAngle = 0;
ignition4StartAngle = 0;
ignition5StartAngle = 0;
ignition6StartAngle = 0;
ignition7StartAngle = 0;
ignition8StartAngle = 0;
inj1StartFunction = nullCallback;
inj1EndFunction = nullCallback;
inj2StartFunction = nullCallback;
inj2EndFunction = nullCallback;
inj3StartFunction = nullCallback;
inj3EndFunction = nullCallback;
inj4StartFunction = nullCallback;
inj4EndFunction = nullCallback;
#if INJ_CHANNELS>=5
inj5StartFunction = nullCallback;
inj5EndFunction = nullCallback;
#endif
#if INJ_CHANNELS>=6
inj6StartFunction = nullCallback;
inj6EndFunction = nullCallback;
#endif
#if INJ_CHANNELS>=7
inj7StartFunction = nullCallback;
inj7EndFunction = nullCallback;
#endif
#if INJ_CHANNELS>=8
inj8StartFunction = nullCallback;
inj8EndFunction = nullCallback;
#endif
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) */
channel2IgnDegrees = 0; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
channel3IgnDegrees = 0; /**< The number of crank degrees until cylinder 3 (and 5/6/7/8) is at TDC */
channel4IgnDegrees = 0; /**< The number of crank degrees until cylinder 4 (and 5/6/7/8) is at TDC */
channel5IgnDegrees = 0; /**< The number of crank degrees until cylinder 5 is at TDC */
channel6IgnDegrees = 0; /**< The number of crank degrees until cylinder 6 is at TDC */
channel7IgnDegrees = 0; /**< The number of crank degrees until cylinder 7 is at TDC */
channel8IgnDegrees = 0; /**< The number of crank degrees until cylinder 8 is at TDC */
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) */
channel2InjDegrees = 0; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
channel3InjDegrees = 0; /**< The number of crank degrees until cylinder 3 (and 5/6/7/8) is at TDC */
channel4InjDegrees = 0; /**< The number of crank degrees until cylinder 4 (and 5/6/7/8) is at TDC */
channel5InjDegrees = 0; /**< The number of crank degrees until cylinder 5 is at TDC */
channel6InjDegrees = 0; /**< The number of crank degrees until cylinder 6 is at TDC */
channel7InjDegrees = 0; /**< The number of crank degrees until cylinder 7 is at TDC */
channel8InjDegrees = 0; /**< The number of crank degrees until cylinder 8 is at TDC */
ign1StartFunction = nullCallback;
ign1EndFunction = nullCallback;
ignition1StartAngle=0;
ignition1EndAngle=0;
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) */
inj1StartFunction = nullCallback;
inj1EndFunction = nullCallback;
inj2StartFunction = nullCallback;
inj2EndFunction = nullCallback;
inj3StartFunction = nullCallback;
inj3EndFunction = nullCallback;
inj4StartFunction = nullCallback;
inj4EndFunction = nullCallback;
inj5StartFunction = nullCallback;
inj5EndFunction = nullCallback;
inj6StartFunction = nullCallback;
inj6EndFunction = nullCallback;
inj7StartFunction = nullCallback;
inj7EndFunction = nullCallback;
inj8StartFunction = nullCallback;
inj8EndFunction = nullCallback;
ign2StartFunction = nullCallback;
ign2EndFunction = nullCallback;
ignition2StartAngle=0;
ignition2EndAngle=0;
channel2IgnDegrees=0; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
ign3StartFunction = nullCallback;
ign3EndFunction = nullCallback;
ignition3StartAngle=0;
ignition3EndAngle=0;
channel3IgnDegrees=0; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
ign4StartFunction = nullCallback;
ign4EndFunction = nullCallback;
ignition4StartAngle=0;
ignition4EndAngle=0;
channel4IgnDegrees=0; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
#if (IGN_CHANNELS >= 5)
ign5StartFunction = nullCallback;
ign5EndFunction = nullCallback;
ignition5StartAngle=0;
ignition5EndAngle=0;
channel5IgnDegrees=0; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
#endif
#if (IGN_CHANNELS >= 6)
ign6StartFunction = nullCallback;
ign6EndFunction = nullCallback;
ignition6StartAngle=0;
ignition6EndAngle=0;
channel6IgnDegrees=0; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
#endif
#if (IGN_CHANNELS >= 7)
ign7StartFunction = nullCallback;
ign7EndFunction = nullCallback;
ignition7StartAngle=0;
ignition7EndAngle=0;
channel7IgnDegrees=0; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
#endif
#if (IGN_CHANNELS >= 8)
ign8StartFunction = nullCallback;
ign8EndFunction = nullCallback;
ignition8StartAngle=0;
ignition8EndAngle=0;
channel8IgnDegrees=0; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
#endif
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) */
channel2InjDegrees = 0; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
channel3InjDegrees = 0; /**< The number of crank degrees until cylinder 3 (and 5/6/7/8) is at TDC */
channel4InjDegrees = 0; /**< The number of crank degrees until cylinder 4 (and 5/6/7/8) is at TDC */
#if (INJ_CHANNELS >= 5)
channel5InjDegrees = 0; /**< The number of crank degrees until cylinder 5 is at TDC */
#endif
#if (INJ_CHANNELS >= 6)
channel6InjDegrees = 0; /**< The number of crank degrees until cylinder 6 is at TDC */
#endif
#if (INJ_CHANNELS >= 7)
channel7InjDegrees = 0; /**< The number of crank degrees until cylinder 7 is at TDC */
#endif
#if (INJ_CHANNELS >= 8)
channel8InjDegrees = 0; /**< The number of crank degrees until cylinder 8 is at TDC */
#endif
ign1StartFunction = nullCallback;
ign1EndFunction = nullCallback;
ign2StartFunction = nullCallback;
ign2EndFunction = nullCallback;
ign3StartFunction = nullCallback;
ign3EndFunction = nullCallback;
ign4StartFunction = nullCallback;
ign4EndFunction = nullCallback;
ign5StartFunction = nullCallback;
ign5EndFunction = nullCallback;
ign6StartFunction = nullCallback;
ign6EndFunction = nullCallback;
ign7StartFunction = nullCallback;
ign7EndFunction = nullCallback;
ign8StartFunction = nullCallback;
ign8EndFunction = nullCallback;
}
/*

View File

@ -508,7 +508,7 @@ void loop(void)
currentStatus.injAngle = table2D_getValue(&injectorAngleTable, currentStatus.RPMdiv100);
unsigned int PWdivTimerPerDegree = div(currentStatus.PW1, timePerDegree).quot; //How many crank degrees the calculated PW will take at the current speed
injector1StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel1InjDegrees);
injector1StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel1InjDegrees, currentStatus.injAngle);
//Repeat the above for each cylinder
switch (configPage2.nCylinders)
@ -520,13 +520,13 @@ void loop(void)
{
PWdivTimerPerDegree = div(currentStatus.PW2, timePerDegree).quot; //Need to redo this for PW2 as it will be dramatically different to PW1 when staging
//injector3StartAngle = calculateInjector3StartAngle(PWdivTimerPerDegree);
injector2StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel1InjDegrees);
injector2StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel1InjDegrees, currentStatus.injAngle);
}
break;
//2 cylinders
case 2:
//injector2StartAngle = calculateInjector2StartAngle(PWdivTimerPerDegree);
injector2StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees);
injector2StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees, currentStatus.injAngle);
if ( (configPage2.injLayout == INJ_SEQUENTIAL) && (configPage6.fuelTrimEnabled > 0) )
{
@ -536,8 +536,8 @@ void loop(void)
else if( (configPage10.stagingEnabled == true) && (BIT_CHECK(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE) == true) )
{
PWdivTimerPerDegree = div(currentStatus.PW3, timePerDegree).quot; //Need to redo this for PW3 as it will be dramatically different to PW1 when staging
injector3StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel1InjDegrees);
injector4StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees);
injector3StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel1InjDegrees, currentStatus.injAngle);
injector4StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees, currentStatus.injAngle);
injector4StartAngle = injector3StartAngle + (CRANK_ANGLE_MAX_INJ / 2); //Phase this either 180 or 360 degrees out from inj3 (In reality this will always be 180 as you can't have sequential and staged currently)
if(injector4StartAngle > (uint16_t)CRANK_ANGLE_MAX_INJ) { injector4StartAngle -= CRANK_ANGLE_MAX_INJ; }
@ -547,8 +547,8 @@ void loop(void)
case 3:
//injector2StartAngle = calculateInjector2StartAngle(PWdivTimerPerDegree);
//injector3StartAngle = calculateInjector3StartAngle(PWdivTimerPerDegree);
injector2StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees);
injector3StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees);
injector2StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees, currentStatus.injAngle);
injector3StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees, currentStatus.injAngle);
if ( (configPage2.injLayout == INJ_SEQUENTIAL) && (configPage6.fuelTrimEnabled > 0) )
{
@ -560,41 +560,41 @@ void loop(void)
if( (configPage10.stagingEnabled == true) && (BIT_CHECK(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE) == true) )
{
PWdivTimerPerDegree = div(currentStatus.PW4, timePerDegree).quot; //Need to redo this for PW4 as it will be dramatically different to PW1 when staging
injector4StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel1InjDegrees);
injector5StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees);
injector6StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees);
injector4StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel1InjDegrees, currentStatus.injAngle);
injector5StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees, currentStatus.injAngle);
injector6StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees, currentStatus.injAngle);
}
#endif
}
else if( (configPage10.stagingEnabled == true) && (BIT_CHECK(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE) == true) )
{
PWdivTimerPerDegree = div(currentStatus.PW4, timePerDegree).quot; //Need to redo this for PW3 as it will be dramatically different to PW1 when staging
injector4StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel1InjDegrees);
injector4StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel1InjDegrees, currentStatus.injAngle);
#if INJ_CHANNELS >= 6
injector5StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees);
injector6StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees);
injector5StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees, currentStatus.injAngle);
injector6StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees, currentStatus.injAngle);
#endif
}
break;
//4 cylinders
case 4:
//injector2StartAngle = calculateInjector2StartAngle(PWdivTimerPerDegree);
injector2StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees);
injector2StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees, currentStatus.injAngle);
if((configPage2.injLayout == INJ_SEQUENTIAL) && currentStatus.hasSync)
{
if( CRANK_ANGLE_MAX_INJ != 720 ) { changeHalfToFullSync(); }
injector3StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees);
injector4StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel4InjDegrees);
injector3StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees, currentStatus.injAngle);
injector4StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel4InjDegrees, currentStatus.injAngle);
#if INJ_CHANNELS >= 8
if( (configPage10.stagingEnabled == true) && (BIT_CHECK(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE) == true) )
{
PWdivTimerPerDegree = div(currentStatus.PW5, timePerDegree).quot; //Need to redo this for PW5 as it will be dramatically different to PW1 when staging
injector5StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel1InjDegrees);
injector6StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees);
injector7StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees);
injector8StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel4InjDegrees);
injector5StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel1InjDegrees, currentStatus.injAngle);
injector6StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees, currentStatus.injAngle);
injector7StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees, currentStatus.injAngle);
injector8StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel4InjDegrees, currentStatus.injAngle);
}
#endif
@ -609,8 +609,8 @@ void loop(void)
else if( (configPage10.stagingEnabled == true) && (BIT_CHECK(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE) == true) )
{
PWdivTimerPerDegree = div(currentStatus.PW3, timePerDegree).quot; //Need to redo this for PW3 as it will be dramatically different to PW1 when staging
injector3StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel1InjDegrees);
injector4StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees);
injector3StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel1InjDegrees, currentStatus.injAngle);
injector4StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees, currentStatus.injAngle);
}
else
{
@ -619,11 +619,11 @@ void loop(void)
break;
//5 cylinders
case 5:
injector2StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees);
injector3StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees);
injector4StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel4InjDegrees);
injector2StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees, currentStatus.injAngle);
injector3StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees, currentStatus.injAngle);
injector4StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel4InjDegrees, currentStatus.injAngle);
#if INJ_CHANNELS >= 5
injector5StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel5InjDegrees);
injector5StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel5InjDegrees, currentStatus.injAngle);
#endif
//Staging is possible by using the 6th channel if available
@ -631,7 +631,7 @@ void loop(void)
if( (configPage10.stagingEnabled == true) && (BIT_CHECK(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE) == true) )
{
PWdivTimerPerDegree = div(currentStatus.PW6, timePerDegree).quot;
injector6StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel6InjDegrees);
injector6StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel6InjDegrees, currentStatus.injAngle);
}
#endif
@ -641,17 +641,17 @@ void loop(void)
//injector2StartAngle = calculateInjector2StartAngle(PWdivTimerPerDegree);
//injector3StartAngle = calculateInjector3StartAngle(PWdivTimerPerDegree);
injector2StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees);
injector3StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees);
injector2StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees, currentStatus.injAngle);
injector3StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees, currentStatus.injAngle);
#if INJ_CHANNELS >= 6
if((configPage2.injLayout == INJ_SEQUENTIAL) && currentStatus.hasSync)
{
if( CRANK_ANGLE_MAX_INJ != 720 ) { changeHalfToFullSync(); }
injector4StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel4InjDegrees);
injector5StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel5InjDegrees);
injector6StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel6InjDegrees);
injector4StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel4InjDegrees, currentStatus.injAngle);
injector5StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel5InjDegrees, currentStatus.injAngle);
injector6StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel6InjDegrees, currentStatus.injAngle);
if(configPage6.fuelTrimEnabled > 0)
{
@ -668,9 +668,9 @@ void loop(void)
if( (configPage10.stagingEnabled == true) && (BIT_CHECK(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE) == true) )
{
PWdivTimerPerDegree = div(currentStatus.PW4, timePerDegree).quot; //Need to redo this for staging PW as it will be dramatically different to PW1 when staging
injector4StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel1InjDegrees);
injector5StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees);
injector6StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees);
injector4StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel1InjDegrees, currentStatus.injAngle);
injector5StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees, currentStatus.injAngle);
injector6StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees, currentStatus.injAngle);
}
#endif
}
@ -681,9 +681,9 @@ void loop(void)
if( (configPage10.stagingEnabled == true) && (BIT_CHECK(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE) == true) )
{
PWdivTimerPerDegree = div(currentStatus.PW4, timePerDegree).quot; //Need to redo this for staging PW as it will be dramatically different to PW1 when staging
injector4StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel1InjDegrees);
injector5StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees);
injector6StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees);
injector4StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel1InjDegrees, currentStatus.injAngle);
injector5StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees, currentStatus.injAngle);
injector6StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees, currentStatus.injAngle);
}
}
#endif
@ -696,19 +696,19 @@ void loop(void)
injector4StartAngle = calculateInjector4StartAngle(PWdivTimerPerDegree);
*/
injector2StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees);
injector3StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees);
injector4StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel4InjDegrees);
injector2StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees, currentStatus.injAngle);
injector3StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees, currentStatus.injAngle);
injector4StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel4InjDegrees, currentStatus.injAngle);
#if INJ_CHANNELS >= 8
if((configPage2.injLayout == INJ_SEQUENTIAL) && currentStatus.hasSync)
{
if( CRANK_ANGLE_MAX_INJ != 720 ) { changeHalfToFullSync(); }
injector5StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel5InjDegrees);
injector6StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel6InjDegrees);
injector7StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel7InjDegrees);
injector8StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel8InjDegrees);
injector5StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel5InjDegrees, currentStatus.injAngle);
injector6StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel6InjDegrees, currentStatus.injAngle);
injector7StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel7InjDegrees, currentStatus.injAngle);
injector8StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel8InjDegrees, currentStatus.injAngle);
if(configPage6.fuelTrimEnabled > 0)
{
@ -729,10 +729,10 @@ void loop(void)
if( (configPage10.stagingEnabled == true) && (BIT_CHECK(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE) == true) )
{
PWdivTimerPerDegree = div(currentStatus.PW5, timePerDegree).quot; //Need to redo this for PW3 as it will be dramatically different to PW1 when staging
injector5StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel1InjDegrees);
injector6StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees);
injector7StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees);
injector8StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel4InjDegrees);
injector5StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel1InjDegrees, currentStatus.injAngle);
injector6StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees, currentStatus.injAngle);
injector7StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees, currentStatus.injAngle);
injector8StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel4InjDegrees, currentStatus.injAngle);
}
}
@ -901,7 +901,7 @@ void loop(void)
{
if(currentStatus.PW1 >= inj_opentime_uS)
{
uint32_t timeOut = calculateInjector1Timeout(injector1StartAngle, crankAngle);
uint32_t timeOut = calculateInjectorTimeout(fuelSchedule1, channel1InjDegrees, injector1StartAngle, crankAngle);
if (timeOut>0U)
{
setFuelSchedule1(
@ -925,7 +925,7 @@ void loop(void)
#if INJ_CHANNELS >= 2
if( (maxInjOutputs >= 2) && (currentStatus.PW2 >= inj_opentime_uS) )
{
uint32_t timeOut = calculateInjectorNTimeout(fuelSchedule2, channel2InjDegrees, injector2StartAngle, crankAngle);
uint32_t timeOut = calculateInjectorTimeout(fuelSchedule2, channel2InjDegrees, injector2StartAngle, crankAngle);
if ( timeOut>0U )
{
setFuelSchedule2(
@ -939,7 +939,7 @@ void loop(void)
#if INJ_CHANNELS >= 3
if( (maxInjOutputs >= 3) && (currentStatus.PW3 >= inj_opentime_uS) )
{
uint32_t timeOut = calculateInjectorNTimeout(fuelSchedule3, channel3InjDegrees, injector3StartAngle, crankAngle);
uint32_t timeOut = calculateInjectorTimeout(fuelSchedule3, channel3InjDegrees, injector3StartAngle, crankAngle);
if ( timeOut>0U )
{
setFuelSchedule3(
@ -953,7 +953,7 @@ void loop(void)
#if INJ_CHANNELS >= 4
if( (maxInjOutputs >= 4) && (currentStatus.PW4 >= inj_opentime_uS) )
{
uint32_t timeOut = calculateInjectorNTimeout(fuelSchedule4, channel4InjDegrees, injector4StartAngle, crankAngle);
uint32_t timeOut = calculateInjectorTimeout(fuelSchedule4, channel4InjDegrees, injector4StartAngle, crankAngle);
if ( timeOut>0U )
{
setFuelSchedule4(
@ -967,7 +967,7 @@ void loop(void)
#if INJ_CHANNELS >= 5
if( (maxInjOutputs >= 5) && (currentStatus.PW5 >= inj_opentime_uS) )
{
uint32_t timeOut = calculateInjectorNTimeout(fuelSchedule5, channel5InjDegrees, injector5StartAngle, crankAngle);
uint32_t timeOut = calculateInjectorTimeout(fuelSchedule5, channel5InjDegrees, injector5StartAngle, crankAngle);
if ( timeOut>0U )
{
setFuelSchedule5(
@ -981,7 +981,7 @@ void loop(void)
#if INJ_CHANNELS >= 6
if( (maxInjOutputs >= 6) && (currentStatus.PW6 >= inj_opentime_uS) )
{
uint32_t timeOut = calculateInjectorNTimeout(fuelSchedule6, channel6InjDegrees, injector6StartAngle, crankAngle);
uint32_t timeOut = calculateInjectorTimeout(fuelSchedule6, channel6InjDegrees, injector6StartAngle, crankAngle);
if ( timeOut>0U )
{
setFuelSchedule6(
@ -995,7 +995,7 @@ void loop(void)
#if INJ_CHANNELS >= 7
if( (maxInjOutputs >= 7) && (currentStatus.PW7 >= inj_opentime_uS) )
{
uint32_t timeOut = calculateInjectorNTimeout(fuelSchedule7, channel7InjDegrees, injector7StartAngle, crankAngle);
uint32_t timeOut = calculateInjectorTimeout(fuelSchedule7, channel7InjDegrees, injector7StartAngle, crankAngle);
if ( timeOut>0U )
{
setFuelSchedule7(
@ -1009,7 +1009,7 @@ void loop(void)
#if INJ_CHANNELS >= 8
if( (maxInjOutputs >= 8) && (currentStatus.PW8 >= inj_opentime_uS) )
{
uint32_t timeOut = calculateInjectorNTimeout(fuelSchedule8, channel8InjDegrees, injector8StartAngle, crankAngle);
uint32_t timeOut = calculateInjectorTimeout(fuelSchedule8, channel8InjDegrees, injector8StartAngle, crankAngle);
if ( timeOut>0U )
{
setFuelSchedule8(
@ -1035,10 +1035,18 @@ void loop(void)
ignition2StartAngle -= 5;
ignition3StartAngle -= 5;
ignition4StartAngle -= 5;
#if IGN_CHANNELS >= 5
ignition5StartAngle -= 5;
#endif
#if IGN_CHANNELS >= 6
ignition6StartAngle -= 5;
#endif
#if IGN_CHANNELS >= 7
ignition7StartAngle -= 5;
#endif
#if IGN_CHANNELS >= 8
ignition8StartAngle -= 5;
#endif
}
}
else { fixedCrankingOverride = 0; }
@ -1051,7 +1059,7 @@ void loop(void)
while (crankAngle > CRANK_ANGLE_MAX_IGN ) { crankAngle -= CRANK_ANGLE_MAX_IGN; }
#if IGN_CHANNELS >= 1
uint32_t timeOut = calculateIgnition1Timeout(crankAngle);
uint32_t timeOut = calculateIgnitionTimeout(ignitionSchedule1, ignition1StartAngle, channel1IgnDegrees, crankAngle);
if ( (timeOut > 0U) && (BIT_CHECK(ignitionChannelsOn, IGN1_CMD_BIT)) )
{
@ -1087,7 +1095,7 @@ void loop(void)
#if IGN_CHANNELS >= 2
if (maxIgnOutputs >= 2)
{
unsigned long ignition2StartTime = calculateIgnitionNTimeout(ignitionSchedule2, ignition2StartAngle, channel2IgnDegrees, crankAngle);
unsigned long ignition2StartTime = calculateIgnitionTimeout(ignitionSchedule2, ignition2StartAngle, channel2IgnDegrees, crankAngle);
if ( (ignition2StartTime > 0) && (BIT_CHECK(ignitionChannelsOn, IGN2_CMD_BIT)) )
{
@ -1103,7 +1111,7 @@ void loop(void)
#if IGN_CHANNELS >= 3
if (maxIgnOutputs >= 3)
{
unsigned long ignition3StartTime = calculateIgnitionNTimeout(ignitionSchedule3, ignition3StartAngle, channel3IgnDegrees, crankAngle);
unsigned long ignition3StartTime = calculateIgnitionTimeout(ignitionSchedule3, ignition3StartAngle, channel3IgnDegrees, crankAngle);
if ( (ignition3StartTime > 0) && (BIT_CHECK(ignitionChannelsOn, IGN3_CMD_BIT)) )
{
@ -1119,7 +1127,7 @@ void loop(void)
#if IGN_CHANNELS >= 4
if (maxIgnOutputs >= 4)
{
unsigned long ignition4StartTime = calculateIgnitionNTimeout(ignitionSchedule4, ignition4StartAngle, channel4IgnDegrees, crankAngle);
unsigned long ignition4StartTime = calculateIgnitionTimeout(ignitionSchedule4, ignition4StartAngle, channel4IgnDegrees, crankAngle);
if ( (ignition4StartTime > 0) && (BIT_CHECK(ignitionChannelsOn, IGN4_CMD_BIT)) )
{
@ -1135,7 +1143,7 @@ void loop(void)
#if IGN_CHANNELS >= 5
if (maxIgnOutputs >= 5)
{
unsigned long ignition5StartTime = calculateIgnitionNTimeout(ignitionSchedule5, ignition5StartAngle, channel5IgnDegrees, crankAngle);
unsigned long ignition5StartTime = calculateIgnitionTimeout(ignitionSchedule5, ignition5StartAngle, channel5IgnDegrees, crankAngle);
if ( (ignition5StartTime > 0) && (BIT_CHECK(ignitionChannelsOn, IGN5_CMD_BIT)) )
{
@ -1151,7 +1159,7 @@ void loop(void)
#if IGN_CHANNELS >= 6
if (maxIgnOutputs >= 6)
{
unsigned long ignition6StartTime = calculateIgnitionNTimeout(ignitionSchedule6, ignition6StartAngle, channel6IgnDegrees, crankAngle);
unsigned long ignition6StartTime = calculateIgnitionTimeout(ignitionSchedule6, ignition6StartAngle, channel6IgnDegrees, crankAngle);
if ( (ignition6StartTime > 0) && (BIT_CHECK(ignitionChannelsOn, IGN6_CMD_BIT)) )
{
@ -1167,7 +1175,7 @@ void loop(void)
#if IGN_CHANNELS >= 7
if (maxIgnOutputs >= 7)
{
unsigned long ignition7StartTime = calculateIgnitionNTimeout(ignitionSchedule7, ignition7StartAngle, channel7IgnDegrees, crankAngle);
unsigned long ignition7StartTime = calculateIgnitionTimeout(ignitionSchedule7, ignition7StartAngle, channel7IgnDegrees, crankAngle);
if ( (ignition7StartTime > 0) && (BIT_CHECK(ignitionChannelsOn, IGN7_CMD_BIT)) )
{
@ -1183,7 +1191,7 @@ void loop(void)
#if IGN_CHANNELS >= 8
if (maxIgnOutputs >= 8)
{
unsigned long ignition8StartTime = calculateIgnitionNTimeout(ignitionSchedule8, ignition8StartAngle, channel8IgnDegrees, crankAngle);
unsigned long ignition8StartTime = calculateIgnitionTimeout(ignitionSchedule8, ignition8StartAngle, channel8IgnDegrees, crankAngle);
if ( (ignition8StartTime > 0) && (BIT_CHECK(ignitionChannelsOn, IGN8_CMD_BIT)) )
{
@ -1362,31 +1370,31 @@ void calculateIgnitionAngles(int dwellAngle)
{
//1 cylinder
case 1:
calculateIgnitionAngle1(dwellAngle);
calculateIgnitionAngle(dwellAngle, channel1IgnDegrees, currentStatus.advance, &ignition1EndAngle, &ignition1StartAngle);
break;
//2 cylinders
case 2:
calculateIgnitionAngle1(dwellAngle);
calculateIgnitionAngle2(dwellAngle);
calculateIgnitionAngle(dwellAngle, channel1IgnDegrees, currentStatus.advance, &ignition1EndAngle, &ignition1StartAngle);
calculateIgnitionAngle(dwellAngle, channel2IgnDegrees, currentStatus.advance, &ignition2EndAngle, &ignition2StartAngle);
break;
//3 cylinders
case 3:
calculateIgnitionAngle1(dwellAngle);
calculateIgnitionAngle2(dwellAngle);
calculateIgnitionAngle3(dwellAngle);
calculateIgnitionAngle(dwellAngle, channel1IgnDegrees, currentStatus.advance, &ignition1EndAngle, &ignition1StartAngle);
calculateIgnitionAngle(dwellAngle, channel2IgnDegrees, currentStatus.advance, &ignition2EndAngle, &ignition2StartAngle);
calculateIgnitionAngle(dwellAngle, channel3IgnDegrees, currentStatus.advance, &ignition3EndAngle, &ignition3StartAngle);
break;
//4 cylinders
case 4:
calculateIgnitionAngle1(dwellAngle);
calculateIgnitionAngle2(dwellAngle);
calculateIgnitionAngle(dwellAngle, channel1IgnDegrees, currentStatus.advance, &ignition1EndAngle, &ignition1StartAngle);
calculateIgnitionAngle(dwellAngle, channel2IgnDegrees, currentStatus.advance, &ignition2EndAngle, &ignition2StartAngle);
#if IGN_CHANNELS >= 4
if((configPage4.sparkMode == IGN_MODE_SEQUENTIAL) && currentStatus.hasSync)
{
if( CRANK_ANGLE_MAX_IGN != 720 ) { changeHalfToFullSync(); }
calculateIgnitionAngle3(dwellAngle);
calculateIgnitionAngle4(dwellAngle);
calculateIgnitionAngle(dwellAngle, channel3IgnDegrees, currentStatus.advance, &ignition3EndAngle, &ignition3StartAngle);
calculateIgnitionAngle(dwellAngle, channel4IgnDegrees, currentStatus.advance, &ignition4EndAngle, &ignition4StartAngle);
}
else if(configPage4.sparkMode == IGN_MODE_ROTARY)
{
@ -1394,8 +1402,8 @@ void calculateIgnitionAngles(int dwellAngle)
splitDegrees = table2D_getValue(&rotarySplitTable, currentStatus.ignLoad);
//The trailing angles are set relative to the leading ones
calculateIgnitionAngle3(dwellAngle, splitDegrees);
calculateIgnitionAngle4(dwellAngle, splitDegrees);
calculateIgnitionTrailingRotary(dwellAngle, splitDegrees, ignition1EndAngle, &ignition3EndAngle, &ignition3StartAngle);
calculateIgnitionTrailingRotary(dwellAngle, splitDegrees, ignition2EndAngle, &ignition4EndAngle, &ignition4StartAngle);
}
else
{
@ -1405,26 +1413,26 @@ void calculateIgnitionAngles(int dwellAngle)
break;
//5 cylinders
case 5:
calculateIgnitionAngle1(dwellAngle);
calculateIgnitionAngle2(dwellAngle);
calculateIgnitionAngle3(dwellAngle);
calculateIgnitionAngle4(dwellAngle);
calculateIgnitionAngle5(dwellAngle);
calculateIgnitionAngle(dwellAngle, channel1IgnDegrees, currentStatus.advance, &ignition1EndAngle, &ignition1StartAngle);
calculateIgnitionAngle(dwellAngle, channel2IgnDegrees, currentStatus.advance, &ignition2EndAngle, &ignition2StartAngle);
calculateIgnitionAngle(dwellAngle, channel3IgnDegrees, currentStatus.advance, &ignition3EndAngle, &ignition3StartAngle);
calculateIgnitionAngle(dwellAngle, channel4IgnDegrees, currentStatus.advance, &ignition4EndAngle, &ignition4StartAngle);
calculateIgnitionAngle(dwellAngle, channel5IgnDegrees, currentStatus.advance, &ignition5EndAngle, &ignition5StartAngle);
break;
//6 cylinders
case 6:
calculateIgnitionAngle1(dwellAngle);
calculateIgnitionAngle2(dwellAngle);
calculateIgnitionAngle3(dwellAngle);
calculateIgnitionAngle(dwellAngle, channel1IgnDegrees, currentStatus.advance, &ignition1EndAngle, &ignition1StartAngle);
calculateIgnitionAngle(dwellAngle, channel2IgnDegrees, currentStatus.advance, &ignition2EndAngle, &ignition2StartAngle);
calculateIgnitionAngle(dwellAngle, channel3IgnDegrees, currentStatus.advance, &ignition3EndAngle, &ignition3StartAngle);
#if IGN_CHANNELS >= 6
if((configPage4.sparkMode == IGN_MODE_SEQUENTIAL) && currentStatus.hasSync)
{
if( CRANK_ANGLE_MAX_IGN != 720 ) { changeHalfToFullSync(); }
calculateIgnitionAngle4(dwellAngle);
calculateIgnitionAngle5(dwellAngle);
calculateIgnitionAngle6(dwellAngle);
calculateIgnitionAngle(dwellAngle, channel4IgnDegrees, currentStatus.advance, &ignition4EndAngle, &ignition4StartAngle);
calculateIgnitionAngle(dwellAngle, channel5IgnDegrees, currentStatus.advance, &ignition5EndAngle, &ignition5StartAngle);
calculateIgnitionAngle(dwellAngle, channel6IgnDegrees, currentStatus.advance, &ignition6EndAngle, &ignition6StartAngle);
}
else
{
@ -1434,20 +1442,20 @@ void calculateIgnitionAngles(int dwellAngle)
break;
//8 cylinders
case 8:
calculateIgnitionAngle1(dwellAngle);
calculateIgnitionAngle2(dwellAngle);
calculateIgnitionAngle3(dwellAngle);
calculateIgnitionAngle4(dwellAngle);
calculateIgnitionAngle(dwellAngle, channel1IgnDegrees, currentStatus.advance, &ignition1EndAngle, &ignition1StartAngle);
calculateIgnitionAngle(dwellAngle, channel2IgnDegrees, currentStatus.advance, &ignition2EndAngle, &ignition2StartAngle);
calculateIgnitionAngle(dwellAngle, channel3IgnDegrees, currentStatus.advance, &ignition3EndAngle, &ignition3StartAngle);
calculateIgnitionAngle(dwellAngle, channel4IgnDegrees, currentStatus.advance, &ignition4EndAngle, &ignition4StartAngle);
#if IGN_CHANNELS >= 8
if((configPage4.sparkMode == IGN_MODE_SEQUENTIAL) && currentStatus.hasSync)
{
if( CRANK_ANGLE_MAX_IGN != 720 ) { changeHalfToFullSync(); }
calculateIgnitionAngle5(dwellAngle);
calculateIgnitionAngle6(dwellAngle);
calculateIgnitionAngle7(dwellAngle);
calculateIgnitionAngle8(dwellAngle);
calculateIgnitionAngle(dwellAngle, channel5IgnDegrees, currentStatus.advance, &ignition5EndAngle, &ignition5StartAngle);
calculateIgnitionAngle(dwellAngle, channel6IgnDegrees, currentStatus.advance, &ignition6EndAngle, &ignition6StartAngle);
calculateIgnitionAngle(dwellAngle, channel7IgnDegrees, currentStatus.advance, &ignition7EndAngle, &ignition7StartAngle);
calculateIgnitionAngle(dwellAngle, channel8IgnDegrees, currentStatus.advance, &ignition8EndAngle, &ignition8StartAngle);
}
else
{

View File

@ -19,20 +19,20 @@ void test_fordst170_newIgn_12_trig0_1()
triggerSetup_FordST170();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = 0; //No trigger offset
currentStatus.advance = 10;
calculateIgnitionAngle1(5);
calculateIgnitionAngle(5, 0, 10, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_FordST170();
TEST_ASSERT_EQUAL(34, ignition1EndTooth);
//Test again with 0 degrees advance
currentStatus.advance = 0;
calculateIgnitionAngle1(5);
calculateIgnitionAngle(5, 0, 0, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_FordST170();
TEST_ASSERT_EQUAL(35, ignition1EndTooth);
//Test again with 35 degrees advance
currentStatus.advance = 35;
calculateIgnitionAngle1(5);
calculateIgnitionAngle(5, 0, 35, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_FordST170();
TEST_ASSERT_EQUAL(31, ignition1EndTooth);
}
@ -46,9 +46,8 @@ void test_fordst170_newIgn_12_trig90_1()
triggerSetup_FordST170();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = 90; //No trigger offset
currentStatus.advance = 35;
calculateIgnitionAngle1(5);
calculateIgnitionAngle(5, 0, 35, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_FordST170();
TEST_ASSERT_EQUAL(22, ignition1EndTooth);
}
@ -62,9 +61,8 @@ void test_fordst170_newIgn_12_trig180_1()
triggerSetup_FordST170();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = 180; //No trigger offset
currentStatus.advance = 10;
calculateIgnitionAngle1(5);
calculateIgnitionAngle(5, 0, 10, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_FordST170();
TEST_ASSERT_EQUAL(16, ignition1EndTooth);
}
@ -78,9 +76,8 @@ void test_fordst170_newIgn_12_trig270_1()
triggerSetup_FordST170();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = 270; //No trigger offset
currentStatus.advance = 10;
calculateIgnitionAngle1(5);
calculateIgnitionAngle(5, 0, 10, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_FordST170();
TEST_ASSERT_EQUAL(7, ignition1EndTooth);
}
@ -94,8 +91,7 @@ void test_fordst170_newIgn_12_trig360_1()
triggerSetup_FordST170();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = 360; //No trigger offset
currentStatus.advance = 10;
calculateIgnitionAngle1(5);
calculateIgnitionAngle(5, 0, 10, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_FordST170();
TEST_ASSERT_EQUAL(34, ignition1EndTooth);
@ -110,9 +106,8 @@ void test_fordst170_newIgn_12_trigNeg90_1()
triggerSetup_FordST170();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = -90; //No trigger offset
currentStatus.advance = 10;
calculateIgnitionAngle1(5);
calculateIgnitionAngle(5, 0, 10, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_FordST170();
TEST_ASSERT_EQUAL(7, ignition1EndTooth);
}
@ -126,9 +121,8 @@ void test_fordst170_newIgn_12_trigNeg180_1()
triggerSetup_FordST170();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = -180; //No trigger offset
currentStatus.advance = 10;
calculateIgnitionAngle1(5);
calculateIgnitionAngle(5, 0, 10, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_FordST170();
TEST_ASSERT_EQUAL(16, ignition1EndTooth);
}
@ -141,8 +135,8 @@ void test_fordst170_newIgn_12_trigNeg270_1()
//triggerAngle=-270
triggerSetup_FordST170();
configPage4.sparkMode = IGN_MODE_WASTED;
currentStatus.advance = 10; //Set 10 degrees advance
configPage4.triggerAngle = -270; //No trigger offset
calculateIgnitionAngle(5, 0, 10, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_FordST170();
TEST_ASSERT_EQUAL(25, ignition1EndTooth);
@ -157,9 +151,8 @@ void test_fordst170_newIgn_12_trigNeg360_1()
triggerSetup_FordST170();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = -360; //No trigger offset
currentStatus.advance = 10;
calculateIgnitionAngle1(5);
calculateIgnitionAngle(5, 0, 10, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_FordST170();
TEST_ASSERT_EQUAL(34, ignition1EndTooth);
}

View File

@ -16,21 +16,18 @@ void test_ngc_newIgn_12_trig0_1()
CRANK_ANGLE_MAX_IGN = 360;
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = 0; //No trigger offset
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(5);
calculateIgnitionAngle(5, 0, 10, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_NGC();
TEST_ASSERT_EQUAL(34, ignition1EndTooth);
//Test again with 0 degrees advance
currentStatus.advance = 0;
calculateIgnitionAngle1(5);
calculateIgnitionAngle(5, 0, 0, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_NGC();
TEST_ASSERT_EQUAL(34, ignition1EndTooth);
//Test again with 35 degrees advance
currentStatus.advance = 35;
calculateIgnitionAngle1(5);
calculateIgnitionAngle(5, 0, 35, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_NGC();
TEST_ASSERT_EQUAL(31, ignition1EndTooth);
}
@ -41,9 +38,8 @@ void test_ngc_newIgn_12_trig90_1()
CRANK_ANGLE_MAX_IGN = 360;
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = 90;
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(5);
calculateIgnitionAngle(5, 0, 10, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_NGC();
TEST_ASSERT_EQUAL(25, ignition1EndTooth);
}
@ -54,8 +50,10 @@ void test_ngc_newIgn_12_trig180_1()
CRANK_ANGLE_MAX_IGN = 360;
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = 180;
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(5);
calculateIgnitionAngle(5, 0, 10, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_NGC();
TEST_ASSERT_EQUAL(16, ignition1EndTooth);
@ -67,9 +65,8 @@ void test_ngc_newIgn_12_trig270_1()
CRANK_ANGLE_MAX_IGN = 360;
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = 270;
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(5);
calculateIgnitionAngle(5, 0, 10, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_NGC();
TEST_ASSERT_EQUAL(7, ignition1EndTooth);
}
@ -80,9 +77,8 @@ void test_ngc_newIgn_12_trig360_1()
CRANK_ANGLE_MAX_IGN = 360;
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = 360;
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(5);
calculateIgnitionAngle(5, 0, 10, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_NGC();
TEST_ASSERT_EQUAL(34, ignition1EndTooth);
}
@ -93,9 +89,8 @@ void test_ngc_newIgn_12_trigNeg90_1()
CRANK_ANGLE_MAX_IGN = 360;
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = -90;
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(5);
calculateIgnitionAngle(5, 0, 10, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_NGC();
TEST_ASSERT_EQUAL(7, ignition1EndTooth);
}
@ -106,9 +101,8 @@ void test_ngc_newIgn_12_trigNeg180_1()
CRANK_ANGLE_MAX_IGN = 360;
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = -180;
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(5);
calculateIgnitionAngle(5, 0, 10, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_NGC();
TEST_ASSERT_EQUAL(16, ignition1EndTooth);
}
@ -119,9 +113,8 @@ void test_ngc_newIgn_12_trigNeg270_1()
CRANK_ANGLE_MAX_IGN = 360;
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = -270;
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(5);
calculateIgnitionAngle(5, 0, 10, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_NGC();
TEST_ASSERT_EQUAL(25, ignition1EndTooth);
}
@ -132,9 +125,8 @@ void test_ngc_newIgn_12_trigNeg360_1()
CRANK_ANGLE_MAX_IGN = 360;
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = -360;
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(5);
calculateIgnitionAngle(5, 0, 10, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_NGC();
TEST_ASSERT_EQUAL(34, ignition1EndTooth);
}

View File

@ -19,21 +19,18 @@ void test_nissan360_newIgn_12_trig0_1()
triggerSetup_Nissan360();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = 0; //No trigger offset
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(5);
calculateIgnitionAngle(5, 0, 10, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_Nissan360();
TEST_ASSERT_EQUAL(171, ignition1EndTooth);
//Test again with 0 degrees advance
currentStatus.advance = 0; //Set 10deg advance
calculateIgnitionAngle1(5);
calculateIgnitionAngle(5, 0, 0, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_Nissan360();
TEST_ASSERT_EQUAL(176, ignition1EndTooth);
//Test again with 35 degrees advance
currentStatus.advance = 35; //Set 10deg advance
calculateIgnitionAngle1(5);
calculateIgnitionAngle(5, 0, 35, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_Nissan360();
TEST_ASSERT_EQUAL(158, ignition1EndTooth);
}
@ -47,9 +44,8 @@ void test_nissan360_newIgn_12_trig90_1()
triggerSetup_Nissan360();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = 90; //No trigger offset
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(0);
calculateIgnitionAngle(5, 0, 10, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_Nissan360();
TEST_ASSERT_EQUAL(126, ignition1EndTooth);
}
@ -63,9 +59,8 @@ void test_nissan360_newIgn_12_trig180_1()
triggerSetup_Nissan360();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = 180; //No trigger offset
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(0);
calculateIgnitionAngle(5, 0, 10, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_Nissan360();
TEST_ASSERT_EQUAL(81, ignition1EndTooth);
}
@ -79,9 +74,8 @@ void test_nissan360_newIgn_12_trig270_1()
triggerSetup_Nissan360();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = 270; //No trigger offset
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(0);
calculateIgnitionAngle(5, 0, 10, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_Nissan360();
TEST_ASSERT_EQUAL(36, ignition1EndTooth);
}
@ -95,9 +89,8 @@ void test_nissan360_newIgn_12_trig360_1()
triggerSetup_Nissan360();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = 360; //No trigger offset
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(0);
calculateIgnitionAngle(5, 0, 10, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_Nissan360();
TEST_ASSERT_EQUAL(351, ignition1EndTooth);
}
@ -111,9 +104,8 @@ void test_nissan360_newIgn_12_trigNeg90_1()
triggerSetup_Nissan360();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = -90; //No trigger offset
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(0);
calculateIgnitionAngle(5, 0, 10, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_Nissan360();
TEST_ASSERT_EQUAL(216, ignition1EndTooth);
}
@ -127,9 +119,8 @@ void test_nissan360_newIgn_12_trigNeg180_1()
triggerSetup_Nissan360();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = -180; //No trigger offset
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(0);
calculateIgnitionAngle(5, 0, 10, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_Nissan360();
TEST_ASSERT_EQUAL(261, ignition1EndTooth);
}
@ -142,9 +133,9 @@ void test_nissan360_newIgn_12_trigNeg270_1()
//triggerAngle=-270
triggerSetup_Nissan360();
configPage4.sparkMode = IGN_MODE_WASTED;
currentStatus.advance = 10; //Set 10 degrees advance
configPage4.triggerAngle = -270; //No trigger offset
calculateIgnitionAngle(5, 0, 10, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_Nissan360();
TEST_ASSERT_EQUAL(306, ignition1EndTooth);
}
@ -158,9 +149,8 @@ void test_nissan360_newIgn_12_trigNeg360_1()
triggerSetup_Nissan360();
configPage4.sparkMode = IGN_MODE_WASTED;
configPage4.triggerAngle = -360; //No trigger offset
currentStatus.advance = 10; //Set 10deg advance
calculateIgnitionAngle1(0);
calculateIgnitionAngle(5, 0, 10, &ignition1EndAngle, &ignition1StartAngle);
triggerSetEndTeeth_Nissan360();
TEST_ASSERT_EQUAL(351, ignition1EndTooth);
}

View File

@ -2,6 +2,7 @@
#include <globals.h>
#include <unity.h>
#include "dual_wheel.h"
#include "schedule_calcs.h"
void test_setup_dualwheel_12_1()

View File

@ -2,7 +2,7 @@
#include <globals.h>
#include <unity.h>
#include "missing_tooth.h"
#include "schedule_calcs.h"
void test_setup_36_1()
{

View File

@ -2,7 +2,7 @@
#include <globals.h>
#include <unity.h>
#include "renix.h"
#include "schedule_calcs.h"
void test_setup_renix44()
{

View File

@ -33,67 +33,27 @@ struct ign_test_parameters
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)
void test_calc_ign_timeout(const ign_test_parameters &test_params)
{
char msg[150];
Schedule schedule;
memset(&schedule, 0, sizeof(schedule));
schedule.Status = PENDING;
pEndAngleCalc(dwellAngle);
int startAngle;
int endAngle;
calculateIgnitionAngle(dwellAngle, test_params.channelAngle, test_params.advanceAngle, &endAngle, &startAngle);
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 = PENDING;
TEST_ASSERT_EQUAL_MESSAGE(test_params.pending, calculateIgnitionTimeout(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
schedule.Status = RUNNING;
TEST_ASSERT_EQUAL_MESSAGE(test_params.running, calculateIgnitionTimeout(schedule, startAngle, test_params.channelAngle, test_params.crankAngle), msg);
}
void test_calc_ign_timeout(const ign_test_parameters *pStart, const ign_test_parameters *pEnd)
@ -102,14 +62,12 @@ void test_calc_ign_timeout(const ign_test_parameters *pStart, const ign_test_par
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()
void test_calc_ign_timeout_360()
{
setEngineSpeed(4000, 360);
@ -142,54 +100,6 @@ void test_calc_ign1_timeout()
{ 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 },
@ -374,24 +284,24 @@ void test_calc_ign_timeout_720()
{ 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 },
{ 0, 0, 0, 26000, 26000, 624, 720 },
{ 0, 0, 45, 24125, 24125, 624, 720 },
{ 0, 0, 90, 22250, 22250, 624, 720 },
{ 0, 0, 135, 20375, 20375, 624, 720 },
{ 0, 0, 180, 18500, 18500, 624, 720 },
{ 0, 0, 215, 17041, 17041, 624, 720 },
{ 0, 0, 270, 14750, 14750, 624, 720 },
{ 0, 0, 315, 12875, 12875, 624, 720 },
{ 0, 0, 360, 11000, 11000, 624, 720 },
{ 0, 40, 0, 24333, 24333, 584, 680 },
{ 0, 40, 45, 22458, 22458, 584, 680 },
{ 0, 40, 90, 20583, 20583, 584, 680 },
{ 0, 40, 135, 18708, 18708, 584, 680 },
{ 0, 40, 180, 16833, 16833, 584, 680 },
{ 0, 40, 215, 15375, 15375, 584, 680 },
{ 0, 40, 270, 13083, 13083, 584, 680 },
{ 0, 40, 315, 11208, 11208, 584, 680 },
{ 0, 40, 360, 9333, 9333, 584, 680 },
{ 72, -40, 0, 666, 666, 16, 112 },
{ 72, -40, 45, 0, 28791, 16, 112 },
{ 72, -40, 90, 26916, 26916, 16, 112 },
@ -640,11 +550,12 @@ void test_calc_ign_timeout_720()
test_calc_ign_timeout(&test_data[0], &test_data[0]+_countof(test_data));
}
void test_rotary_channel3_calcs(void)
void test_rotary_channel_calcs(void)
{
setEngineSpeed(4000, 360);
static const int16_t test_data[][5] PROGMEM = {
// End Angle (deg), Dwell Angle, rotary split degrees, expected start angle, expected end angle
{ -40, 5, 0, -40, 315 },
{ -40, 95, 0, -40, 225 },
{ -40, 185, 0, -40, 135 },
@ -680,68 +591,15 @@ void test_rotary_channel3_calcs(void)
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 endAngle, startAngle;
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);
calculateIgnitionTrailingRotary(local[1], local[2], local[0], &endAngle, &startAngle);
TEST_ASSERT_EQUAL(local[3], endAngle);
TEST_ASSERT_EQUAL(local[4], startAngle);
++pStart;
}
@ -749,9 +607,7 @@ void test_rotary_channel4_calcs(void)
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);
RUN_TEST(test_rotary_channel_calcs);
}

View File

@ -22,38 +22,23 @@ struct inj_test_parameters
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)
static void test_calc_inj_timeout(const inj_test_parameters &parameters)
{
static constexpr uint16_t injAngle = 355;
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);
uint16_t startAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, parameters.channelAngle, injAngle);
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);
TEST_ASSERT_EQUAL_MESSAGE(parameters.pending, calculateInjectorTimeout(fuelSchedule2, parameters.channelAngle, startAngle, parameters.crankAngle), msg);
fuelSchedule2.Status = RUNNING;
startAngle = calculateInjectorStartAngle( PWdivTimerPerDegree, parameters.channelAngle);
startAngle = calculateInjectorStartAngle( PWdivTimerPerDegree, parameters.channelAngle, injAngle);
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);
TEST_ASSERT_EQUAL_MESSAGE(parameters.running, calculateInjectorTimeout(fuelSchedule2, parameters.channelAngle, startAngle, parameters.crankAngle), msg);
}
@ -63,54 +48,14 @@ static void test_calc_inj_timeout(const inj_test_parameters *pStart, const inj_t
while (pStart!=pEnd)
{
memcpy_P(&local, pStart, sizeof(local));
test_calc_injN_timeout(local);
test_calc_inj_timeout(local);
++pStart;
}
}
// Separate test for fuel 1 - different code path, same results!
static void test_calc_inj1_timeout()
static void test_calc_inj_timeout_360()
{
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)
@ -200,11 +145,10 @@ static void test_calc_injN_timeout_360()
test_calc_inj_timeout(&test_data[0], &test_data[0]+_countof(test_data));
}
static void test_calc_injN_timeout_720()
static void test_calc_inj_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 },
@ -330,7 +274,6 @@ static void test_calc_injN_timeout_720()
//
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);
RUN_TEST(test_calc_inj_timeout_360);
RUN_TEST(test_calc_inj_timeout_720);
}