Add unit tests for staging and update other tests
This commit is contained in:
parent
e44f4c7b54
commit
2a6c6bd8ed
|
@ -13,6 +13,7 @@ void testPW(void)
|
|||
RUN_TEST(test_PW_AFR_Multiply);
|
||||
RUN_TEST(test_PW_Large_Correction);
|
||||
RUN_TEST(test_PW_Very_Large_Correction);
|
||||
RUN_TEST(test_PW_4Cyl_PW0);
|
||||
}
|
||||
|
||||
int16_t REQ_FUEL;
|
||||
|
@ -125,4 +126,19 @@ void test_PW_Very_Large_Correction()
|
|||
|
||||
uint16_t result = PW(REQ_FUEL, VE, MAP, corrections, injOpen);
|
||||
TEST_ASSERT_UINT16_WITHIN(PW_ALLOWED_ERROR+30, 21670, result); //Additional allowed error here
|
||||
}
|
||||
|
||||
//Test that unused pulse width values are set to 0
|
||||
//This test is for a 4 cylinder using paired injection where only INJ 1 and 2 should have PW > 0
|
||||
void test_PW_4Cyl_PW0(void)
|
||||
{
|
||||
test_PW_setCommon();
|
||||
|
||||
configPage2.nCylinders = 4;
|
||||
configPage2.injLayout = INJ_PAIRED;
|
||||
configPage10.stagingEnabled = false; //Staging must be off or channels 3 and 4 will be used
|
||||
|
||||
loop();
|
||||
TEST_ASSERT_EQUAL(0, currentStatus.PW3);
|
||||
TEST_ASSERT_EQUAL(0, currentStatus.PW4);
|
||||
}
|
|
@ -5,4 +5,5 @@ void test_PW_AFR_Multiply(void);
|
|||
void test_PW_MAP_Multiply_Compatibility(void);
|
||||
void test_PW_ALL_Multiply(void);
|
||||
void test_PW_Large_Correction();
|
||||
void test_PW_Very_Large_Correction();
|
||||
void test_PW_Very_Large_Correction();
|
||||
void test_PW_4Cyl_PW0(void);
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "test_corrections.h"
|
||||
#include "test_PW.h"
|
||||
#include "test_staging.h"
|
||||
|
||||
#define UNITY_EXCLUDE_DETAILS
|
||||
|
||||
|
@ -21,6 +22,7 @@ void setup()
|
|||
initialiseAll(); //Run the main initialise function
|
||||
testCorrections();
|
||||
testPW();
|
||||
testStaging();
|
||||
|
||||
UNITY_END(); // stop unit testing
|
||||
}
|
||||
|
|
|
@ -0,0 +1,175 @@
|
|||
#include <globals.h>
|
||||
#include <speeduino.h>
|
||||
#include <unity.h>
|
||||
#include "test_staging.h"
|
||||
|
||||
void testStaging(void)
|
||||
{
|
||||
RUN_TEST(test_Staging_Off);
|
||||
RUN_TEST(test_Staging_4cyl_Auto_Inactive);
|
||||
RUN_TEST(test_Staging_4cyl_Table_Inactive);
|
||||
RUN_TEST(test_Staging_4cyl_Auto_50pct);
|
||||
RUN_TEST(test_Staging_4cyl_Auto_33pct);
|
||||
RUN_TEST(test_Staging_4cyl_Table_50pct);
|
||||
}
|
||||
|
||||
void test_Staging_setCommon()
|
||||
{
|
||||
configPage2.nCylinders = 4;
|
||||
currentStatus.RPM = 3000;
|
||||
currentStatus.fuelLoad = 50;
|
||||
inj_opentime_uS = 1000; //1ms inj open time
|
||||
|
||||
/*
|
||||
These values are a percentage of the req_fuel value that would be required for each injector channel to deliver that much fuel.
|
||||
Eg:
|
||||
Pri injectors are 250cc
|
||||
Sec injectors are 500cc
|
||||
Total injector capacity = 750cc
|
||||
|
||||
staged_req_fuel_mult_pri = 300% (The primary injectors would have to run 3x the overall PW in order to be the equivalent of the full 750cc capacity
|
||||
staged_req_fuel_mult_sec = 150% (The secondary injectors would have to run 1.5x the overall PW in order to be the equivalent of the full 750cc capacity
|
||||
*/
|
||||
configPage10.stagedInjSizePri = 250;
|
||||
configPage10.stagedInjSizeSec = 500;
|
||||
uint32_t totalInjector = configPage10.stagedInjSizePri + configPage10.stagedInjSizeSec;
|
||||
|
||||
staged_req_fuel_mult_pri = (100 * totalInjector) / configPage10.stagedInjSizePri;
|
||||
staged_req_fuel_mult_sec = (100 * totalInjector) / configPage10.stagedInjSizeSec;
|
||||
}
|
||||
|
||||
void test_Staging_Off(void)
|
||||
{
|
||||
test_Staging_setCommon();
|
||||
|
||||
BIT_SET(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE);
|
||||
configPage10.stagingEnabled = false;
|
||||
|
||||
uint32_t pwLimit = 9000; //90% duty cycle at 6000rpm
|
||||
calculateStaging(pwLimit);
|
||||
TEST_ASSERT_FALSE(BIT_CHECK(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE));
|
||||
}
|
||||
|
||||
void test_Staging_4cyl_Auto_Inactive(void)
|
||||
{
|
||||
test_Staging_setCommon();
|
||||
uint16_t testPW = 3000;
|
||||
|
||||
BIT_SET(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE);
|
||||
configPage2.injLayout = INJ_PAIRED;
|
||||
configPage10.stagingEnabled = true;
|
||||
configPage10.stagingMode = STAGING_MODE_AUTO;
|
||||
currentStatus.PW1 = testPW; //Over open time but below the pwLimit set below
|
||||
|
||||
|
||||
uint32_t pwLimit = 9000; //90% duty cycle at 6000rpm
|
||||
calculateStaging(pwLimit);
|
||||
//PW 1 and 2 should be normal, 3 and 4 should be 0 as that testPW is below the pwLimit
|
||||
//PW1/2 should be (PW - openTime) * staged_req_fuel_mult_pri = (3000 - 1000) * 3.0 = 6000
|
||||
TEST_ASSERT_EQUAL(6000, currentStatus.PW1);
|
||||
TEST_ASSERT_EQUAL(6000, currentStatus.PW2);
|
||||
TEST_ASSERT_EQUAL(0, currentStatus.PW3);
|
||||
TEST_ASSERT_EQUAL(0, currentStatus.PW4);
|
||||
TEST_ASSERT_FALSE(BIT_CHECK(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE));
|
||||
}
|
||||
|
||||
void test_Staging_4cyl_Table_Inactive(void)
|
||||
{
|
||||
test_Staging_setCommon();
|
||||
uint16_t testPW = 3000;
|
||||
|
||||
BIT_SET(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE);
|
||||
configPage2.injLayout = INJ_PAIRED;
|
||||
configPage10.stagingEnabled = true;
|
||||
configPage10.stagingMode = STAGING_MODE_TABLE;
|
||||
currentStatus.PW1 = testPW; //Over open time but below the pwLimit set below
|
||||
|
||||
//Load the staging table with all 0
|
||||
//For this test it doesn't matter what the X and Y axis are, as the table is all 0 values
|
||||
for(byte x=0; x<64; x++) { stagingTable.values.values[x] = 0; }
|
||||
|
||||
|
||||
uint32_t pwLimit = 9000; //90% duty cycle at 6000rpm
|
||||
calculateStaging(pwLimit);
|
||||
//PW 1 and 2 should be normal, 3 and 4 should be 0 as that testPW is below the pwLimit
|
||||
//PW1/2 should be (PW - openTime) * staged_req_fuel_mult_pri = (3000 - 1000) * 3.0 = 6000
|
||||
TEST_ASSERT_EQUAL(7000, currentStatus.PW1);
|
||||
TEST_ASSERT_EQUAL(7000, currentStatus.PW2);
|
||||
TEST_ASSERT_EQUAL(0, currentStatus.PW3);
|
||||
TEST_ASSERT_EQUAL(0, currentStatus.PW4);
|
||||
TEST_ASSERT_FALSE(BIT_CHECK(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE));
|
||||
}
|
||||
|
||||
void test_Staging_4cyl_Auto_50pct(void)
|
||||
{
|
||||
test_Staging_setCommon();
|
||||
uint16_t testPW = 9000;
|
||||
|
||||
BIT_CLEAR(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE);
|
||||
configPage2.injLayout = INJ_PAIRED;
|
||||
configPage10.stagingEnabled = true;
|
||||
configPage10.stagingMode = STAGING_MODE_AUTO;
|
||||
currentStatus.PW1 = testPW; //Over open time but below the pwLimit set below
|
||||
|
||||
|
||||
uint32_t pwLimit = 9000; //90% duty cycle at 6000rpm
|
||||
calculateStaging(pwLimit);
|
||||
//PW 1 and 2 should be maxed out at the pwLimit, 3 and 4 should be based on their relative size
|
||||
TEST_ASSERT_EQUAL(pwLimit, currentStatus.PW1); //PW1/2 run at maximum available limit
|
||||
TEST_ASSERT_EQUAL(pwLimit, currentStatus.PW2);
|
||||
TEST_ASSERT_EQUAL(9000, currentStatus.PW3);
|
||||
TEST_ASSERT_EQUAL(9000, currentStatus.PW4);
|
||||
TEST_ASSERT_TRUE(BIT_CHECK(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE));
|
||||
}
|
||||
|
||||
void test_Staging_4cyl_Auto_33pct(void)
|
||||
{
|
||||
test_Staging_setCommon();
|
||||
uint16_t testPW = 7000;
|
||||
|
||||
BIT_CLEAR(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE);
|
||||
configPage2.injLayout = INJ_PAIRED;
|
||||
configPage10.stagingEnabled = true;
|
||||
configPage10.stagingMode = STAGING_MODE_AUTO;
|
||||
currentStatus.PW1 = testPW; //Over open time but below the pwLimit set below
|
||||
|
||||
|
||||
uint32_t pwLimit = 9000; //90% duty cycle at 6000rpm
|
||||
calculateStaging(pwLimit);
|
||||
//PW 1 and 2 should be maxed out at the pwLimit, 3 and 4 should be based on their relative size
|
||||
TEST_ASSERT_EQUAL(pwLimit, currentStatus.PW1); //PW1/2 run at maximum available limit
|
||||
TEST_ASSERT_EQUAL(pwLimit, currentStatus.PW2);
|
||||
TEST_ASSERT_EQUAL(6000, currentStatus.PW3);
|
||||
TEST_ASSERT_EQUAL(6000, currentStatus.PW4);
|
||||
TEST_ASSERT_TRUE(BIT_CHECK(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE));
|
||||
}
|
||||
|
||||
void test_Staging_4cyl_Table_50pct(void)
|
||||
{
|
||||
test_Staging_setCommon();
|
||||
uint16_t testPW = 3000;
|
||||
|
||||
BIT_CLEAR(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE);
|
||||
configPage2.injLayout = INJ_PAIRED;
|
||||
configPage10.stagingEnabled = true;
|
||||
configPage10.stagingMode = STAGING_MODE_TABLE;
|
||||
currentStatus.PW1 = testPW; //Over open time but below the pwLimit set below
|
||||
|
||||
//Load the staging table with all 0
|
||||
//For this test it doesn't matter what the X and Y axis are, as the table is all 50 values
|
||||
for(byte x=0; x<64; x++) { stagingTable.values.values[x] = 50; }
|
||||
|
||||
|
||||
uint32_t pwLimit = 9000; //90% duty cycle at 6000rpm
|
||||
//Need to change the lookup values so we don't get a cached value
|
||||
currentStatus.RPM += 1;
|
||||
currentStatus.fuelLoad += 1;
|
||||
|
||||
calculateStaging(pwLimit);
|
||||
|
||||
TEST_ASSERT_EQUAL(4000, currentStatus.PW1);
|
||||
TEST_ASSERT_EQUAL(4000, currentStatus.PW2);
|
||||
TEST_ASSERT_EQUAL(2500, currentStatus.PW3);
|
||||
TEST_ASSERT_EQUAL(2500, currentStatus.PW4);
|
||||
TEST_ASSERT_TRUE(BIT_CHECK(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE));
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
void testStaging();
|
||||
void test_Staging_Off(void);
|
||||
void test_Staging_4cyl_Auto_Inactive(void);
|
||||
void test_Staging_4cyl_Table_Inactive(void);
|
||||
void test_Staging_4cyl_Auto_50pct(void);
|
||||
void test_Staging_4cyl_Auto_33pct(void);
|
||||
void test_Staging_4cyl_Table_50pct(void);
|
|
@ -13,15 +13,15 @@ static constexpr uint16_t reqFuel = 86; // ms * 10
|
|||
|
||||
static void __attribute__((noinline)) assert_fuel_channel(bool enabled, uint16_t angle, uint8_t cmdBit, int channelInjDegrees, voidVoidCallback startFunction, voidVoidCallback endFunction)
|
||||
{
|
||||
char msg[32];
|
||||
char msg[39];
|
||||
|
||||
sprintf_P(msg, PSTR("channel%" PRIu8 "InjDegrees.isEnabled"), cmdBit+1);
|
||||
TEST_ASSERT_EQUAL_MESSAGE(enabled, BIT_CHECK(channelInjEnabled, cmdBit), msg);
|
||||
sprintf_P(msg, PSTR("channe%" PRIu8 "InjDegrees"), cmdBit+1);
|
||||
sprintf_P(msg, PSTR("channel%" PRIu8 ".InjChannelIsEnabled. Max:%" PRIu8), cmdBit+1, maxInjOutputs);
|
||||
TEST_ASSERT_TRUE_MESSAGE(!enabled || (cmdBit+1)<=maxInjOutputs, msg);
|
||||
sprintf_P(msg, PSTR("channe%" PRIu8 ".InjDegrees"), cmdBit+1);
|
||||
TEST_ASSERT_EQUAL_MESSAGE(angle, channelInjDegrees, msg);
|
||||
sprintf_P(msg, PSTR("inj%" PRIu8 "StartFunction"), cmdBit+1);
|
||||
sprintf_P(msg, PSTR("inj%" PRIu8 ".StartFunction"), cmdBit+1);
|
||||
TEST_ASSERT_TRUE_MESSAGE(!enabled || (startFunction!=nullCallback), msg);
|
||||
sprintf_P(msg, PSTR("inj%" PRIu8 "EndFunction"), cmdBit+1);
|
||||
sprintf_P(msg, PSTR("inj%" PRIu8 ".EndFunction"), cmdBit+1);
|
||||
TEST_ASSERT_TRUE_MESSAGE(!enabled || (endFunction!=nullCallback), msg);
|
||||
}
|
||||
|
||||
|
@ -308,7 +308,8 @@ static void cylinder3_stroke4_semiseq_nostage(void)
|
|||
initialiseAll(); //Run the main initialise function
|
||||
const bool enabled[] = {true, true, true, false, false, false, false, false};
|
||||
const uint16_t angle[] = {0,80,160,0,0,0,0,0};
|
||||
assert_fuel_schedules(240U, reqFuel * 50U, enabled, angle);
|
||||
//assert_fuel_schedules(240U, reqFuel * 50U, enabled, angle);
|
||||
assert_fuel_schedules(720U, reqFuel * 50U, enabled, angle); //Special case as 3 squirts per cycle MUST be over 720 degrees
|
||||
}
|
||||
|
||||
static void cylinder3_stroke4_seq_staged(void)
|
||||
|
@ -340,7 +341,8 @@ static void cylinder3_stroke4_semiseq_staged(void)
|
|||
#else
|
||||
const bool enabled[] = {true, true, true, true, false, false, false, false};
|
||||
const uint16_t angle[] = {0,80,160,0,0,0,0,0};
|
||||
assert_fuel_schedules(240U, reqFuel * 50U, enabled, angle);
|
||||
//assert_fuel_schedules(240U, reqFuel * 50U, enabled, angle);
|
||||
assert_fuel_schedules(720U, reqFuel * 50U, enabled, angle); //Special case as 3 squirts per cycle MUST be over 720 degrees
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -350,7 +352,7 @@ static void run_3_cylinder_4stroke_tests(void)
|
|||
configPage2.strokes = FOUR_STROKE;
|
||||
configPage2.engineType = EVEN_FIRE;
|
||||
configPage2.reqFuel = reqFuel;
|
||||
configPage2.divider = 1;
|
||||
configPage2.divider = 1; //3 squirts per cycle for a 3 cylinder
|
||||
|
||||
RUN_TEST_P(cylinder3_stroke4_seq_nostage);
|
||||
RUN_TEST_P(cylinder3_stroke4_semiseq_nostage);
|
||||
|
@ -364,8 +366,8 @@ static void cylinder3_stroke2_seq_nostage(void)
|
|||
configPage10.stagingEnabled = false;
|
||||
initialiseAll(); //Run the main initialise function
|
||||
const bool enabled[] = {true, true, true, false, false, false, false, false};
|
||||
const uint16_t angle[] = {0,80,160,0,0,0,0,0};
|
||||
assert_fuel_schedules(120U, reqFuel * 100U, enabled, angle);
|
||||
const uint16_t angle[] = {0,120,240,0,0,0,0,0};
|
||||
assert_fuel_schedules(360U, reqFuel * 100U, enabled, angle);
|
||||
}
|
||||
|
||||
static void cylinder3_stroke2_semiseq_nostage(void)
|
||||
|
@ -385,12 +387,12 @@ static void cylinder3_stroke2_seq_staged(void)
|
|||
initialiseAll(); //Run the main initialise function
|
||||
#if INJ_CHANNELS>=6
|
||||
const bool enabled[] = {true, true, true, true, true, true, false, false};
|
||||
const uint16_t angle[] = {0,80,160,0,80,160,0,0};
|
||||
assert_fuel_schedules(120U, reqFuel * 100U, enabled, angle);
|
||||
const uint16_t angle[] = {0,120,240,0,120,240,0,0};
|
||||
assert_fuel_schedules(360U, reqFuel * 100U, enabled, angle);
|
||||
#else
|
||||
const bool enabled[] = {true, true, true, true, false, false, false, false};
|
||||
const uint16_t angle[] = {0,80,160,0,0,0,0,0};
|
||||
assert_fuel_schedules(120U, reqFuel * 100U, enabled, angle);
|
||||
const uint16_t angle[] = {0,120,240,0,0,0,0,0};
|
||||
assert_fuel_schedules(360U, reqFuel * 100U, enabled, angle);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue