From 916c3f4153975ce38231e8e9fbddffeeedb4d7ef Mon Sep 17 00:00:00 2001 From: tx_haggis <13982343+adbancroft@users.noreply.github.com> Date: Sat, 5 Oct 2024 19:51:16 -0500 Subject: [PATCH] Table 2D - Initialise during constexpr construction. Saves flash & RAM --- speeduino/globals.cpp | 67 +++++++++++------------ speeduino/idle.cpp | 21 ++----- speeduino/init.cpp | 43 +-------------- speeduino/table2d.cpp | 25 --------- speeduino/table2d.h | 85 ++++++++++++++++++----------- test/test_fuel/test_corrections.cpp | 14 ----- test/test_ign/test_corrections.cpp | 9 --- test/test_tables/test_table2d.cpp | 43 ++++----------- 8 files changed, 100 insertions(+), 207 deletions(-) diff --git a/speeduino/globals.cpp b/speeduino/globals.cpp index 0d192a3233..1bfab86bd8 100644 --- a/speeduino/globals.cpp +++ b/speeduino/globals.cpp @@ -2,6 +2,7 @@ * Instantiation of various (table2D, table3D) tables, volatile (interrupt modified) variables, Injector (1...8) enablement flags, etc. */ #include "globals.h" +#include "utilities.h" const char TSfirmwareVersion[] PROGMEM = "Speeduino"; @@ -27,34 +28,34 @@ trimTable3d trim6Table; ///< 6x6 Fuel trim 6 map trimTable3d trim7Table; ///< 6x6 Fuel trim 7 map trimTable3d trim8Table; ///< 6x6 Fuel trim 8 map struct table3d4RpmLoad dwellTable; ///< 4x4 Dwell map -struct table2D taeTable; ///< 4 bin TPS Acceleration Enrichment map (2D) -struct table2D maeTable; -struct table2D WUETable; ///< 10 bin Warm Up Enrichment map (2D) -struct table2D ASETable; ///< 4 bin After Start Enrichment map (2D) -struct table2D ASECountTable; ///< 4 bin After Start duration map (2D) -struct table2D PrimingPulseTable; ///< 4 bin Priming pulsewidth map (2D) -struct table2D crankingEnrichTable; ///< 4 bin cranking Enrichment map (2D) -struct table2D dwellVCorrectionTable; ///< 6 bin dwell voltage correction (2D) -struct table2D injectorVCorrectionTable; ///< 6 bin injector voltage correction (2D) -struct table2D injectorAngleTable; ///< 4 bin injector angle curve (2D) -struct table2D IATDensityCorrectionTable; ///< 9 bin inlet air temperature density correction (2D) -struct table2D baroFuelTable; ///< 8 bin baro correction curve (2D) -struct table2D IATRetardTable; ///< 6 bin ignition adjustment based on inlet air temperature (2D) -struct table2D idleTargetTable; ///< 10 bin idle target table for idle timing (2D) -struct table2D idleAdvanceTable; ///< 6 bin idle advance adjustment table based on RPM difference (2D) -struct table2D CLTAdvanceTable; ///< 6 bin ignition adjustment based on coolant temperature (2D) -struct table2D rotarySplitTable; ///< 8 bin ignition split curve for rotary leading/trailing (2D) -struct table2D flexFuelTable; ///< 6 bin flex fuel correction table for fuel adjustments (2D) -struct table2D flexAdvTable; ///< 6 bin flex fuel correction table for timing advance (2D) -struct table2D flexBoostTable; ///< 6 bin flex fuel correction table for boost adjustments (2D) -struct table2D fuelTempTable; ///< 6 bin flex fuel correction table for fuel adjustments (2D) -struct table2D knockWindowStartTable; -struct table2D knockWindowDurationTable; -struct table2D oilPressureProtectTable; -struct table2D wmiAdvTable; //6 bin wmi correction table for timing advance (2D) -struct table2D coolantProtectTable; -struct table2D fanPWMTable; -struct table2D rollingCutTable; +struct table2D taeTable(_countof(configPage4.taeValues), configPage4.taeValues, configPage4.taeBins); +struct table2D maeTable(_countof(configPage4.maeRates), configPage4.maeRates, configPage4.maeBins); +struct table2D WUETable(_countof(configPage2.wueValues), configPage2.wueValues, configPage4.wueBins); +struct table2D ASETable(_countof(configPage2.asePct), configPage2.asePct, configPage2.aseBins); +struct table2D ASECountTable(_countof(configPage2.aseCount), configPage2.aseCount, configPage2.aseBins); +struct table2D PrimingPulseTable(_countof(configPage2.primePulse), configPage2.primePulse, configPage2.primeBins); +struct table2D crankingEnrichTable(_countof(configPage10.crankingEnrichValues), configPage10.crankingEnrichValues, configPage10.crankingEnrichBins); +struct table2D dwellVCorrectionTable(_countof(configPage4.dwellCorrectionValues), configPage4.dwellCorrectionValues, configPage6.voltageCorrectionBins); +struct table2D injectorVCorrectionTable(_countof(configPage6.injVoltageCorrectionValues), configPage6.injVoltageCorrectionValues, configPage6.voltageCorrectionBins); +struct table2D injectorAngleTable(_countof(configPage2.injAng), configPage2.injAng, configPage2.injAngRPM); +struct table2D IATDensityCorrectionTable(_countof(configPage6.airDenRates), configPage6.airDenRates, configPage6.airDenBins); +struct table2D baroFuelTable(_countof(configPage4.baroFuelValues), configPage4.baroFuelValues, configPage4.baroFuelBins); +struct table2D IATRetardTable(_countof(configPage4.iatRetValues), configPage4.iatRetValues, configPage4.iatRetBins); +struct table2D idleTargetTable(_countof(configPage6.iacCLValues), configPage6.iacCLValues, configPage6.iacBins); +struct table2D idleAdvanceTable(_countof(configPage4.idleAdvValues), configPage4.idleAdvValues, configPage4.idleAdvBins); +struct table2D CLTAdvanceTable(_countof(configPage4.cltAdvValues), configPage4.cltAdvValues, configPage4.cltAdvBins); +struct table2D rotarySplitTable(_countof(configPage10.rotarySplitValues), configPage10.rotarySplitValues, configPage10.rotarySplitBins); +struct table2D flexFuelTable(_countof(configPage10.flexFuelAdj), configPage10.flexFuelAdj, configPage10.flexFuelBins); +struct table2D flexAdvTable(_countof(configPage10.flexAdvAdj), configPage10.flexAdvAdj, configPage10.flexAdvBins); +struct table2D flexBoostTable(_countof(configPage10.flexBoostAdj), configPage10.flexBoostAdj, configPage10.flexBoostBins); +struct table2D fuelTempTable(_countof(configPage10.fuelTempValues), configPage10.fuelTempValues, configPage10.fuelTempBins); +struct table2D knockWindowStartTable(_countof(configPage10.knock_window_angle), configPage10.knock_window_angle, configPage10.knock_window_rpms); +struct table2D knockWindowDurationTable(_countof(configPage10.knock_window_dur), configPage10.knock_window_dur, configPage10.knock_window_rpms); +struct table2D oilPressureProtectTable(_countof(configPage10.oilPressureProtMins), configPage10.oilPressureProtMins, configPage10.oilPressureProtRPM); +struct table2D wmiAdvTable(_countof(configPage10.wmiAdvAdj), configPage10.wmiAdvAdj, configPage10.wmiAdvBins); +struct table2D coolantProtectTable(_countof(configPage9.coolantProtRPM), configPage9.coolantProtRPM, configPage9.coolantProtTemp); +struct table2D fanPWMTable(_countof(configPage9.PWMFanDuty), configPage9.PWMFanDuty, configPage6.fanPWMBins); +struct table2D rollingCutTable(_countof(configPage15.rollingProtCutPercent), configPage15.rollingProtCutPercent, configPage15.rollingProtRPMDelta); /// volatile inj*_pin_port and inj*_pin_mask vars are for the direct port manipulation of the injectors, coils and aux outputs. volatile PORT_TYPE *inj1_pin_port; @@ -242,19 +243,15 @@ struct config10 configPage10; struct config13 configPage13; struct config15 configPage15; -//byte cltCalibrationTable[CALIBRATION_TABLE_SIZE]; /**< An array containing the coolant sensor calibration values */ -//byte iatCalibrationTable[CALIBRATION_TABLE_SIZE]; /**< An array containing the inlet air temperature sensor calibration values */ -//byte o2CalibrationTable[CALIBRATION_TABLE_SIZE]; /**< An array containing the O2 sensor calibration values */ - uint16_t cltCalibration_bins[32]; uint16_t cltCalibration_values[32]; -struct table2D cltCalibrationTable; +struct table2D cltCalibrationTable(_countof(cltCalibration_values), cltCalibration_values, cltCalibration_bins); uint16_t iatCalibration_bins[32]; uint16_t iatCalibration_values[32]; -struct table2D iatCalibrationTable; +struct table2D iatCalibrationTable(_countof(iatCalibration_values), iatCalibration_values, iatCalibration_bins); uint16_t o2Calibration_bins[32]; uint8_t o2Calibration_values[32]; -struct table2D o2CalibrationTable; +struct table2D o2CalibrationTable(_countof(o2Calibration_values), o2Calibration_values, o2Calibration_bins); //These function do checks on a pin to determine if it is already in use by another (higher importance) active function bool pinIsOutput(byte pin) diff --git a/speeduino/idle.cpp b/speeduino/idle.cpp index 9fc121efca..4da1d868a6 100644 --- a/speeduino/idle.cpp +++ b/speeduino/idle.cpp @@ -6,6 +6,7 @@ A full copy of the license may be found in the projects root directory #include "idle.h" #include "maths.h" #include "timers.h" +#include "utilities.h" #include "src/PID_v1/PID_v1.h" #define STEPPER_LESS_AIR_DIRECTION() ((configPage9.iacStepperInv == 0) ? STEPPER_BACKWARD : STEPPER_FORWARD) @@ -39,11 +40,11 @@ volatile PINMASK_TYPE idle2_pin_mask; volatile PORT_TYPE *idleUpOutput_pin_port; volatile PINMASK_TYPE idleUpOutput_pin_mask; -struct table2D iacPWMTable; -struct table2D iacStepTable; +static struct table2D iacPWMTable(_countof(configPage6.iacOLPWMVal), configPage6.iacOLPWMVal, configPage6.iacBins); +static struct table2D iacStepTable(_countof(configPage6.iacOLStepVal), configPage6.iacOLStepVal, configPage6.iacBins); //Open loop tables specifically for cranking -struct table2D iacCrankStepsTable; -struct table2D iacCrankDutyTable; +static struct table2D iacCrankStepsTable(_countof(configPage6.iacCrankSteps), configPage6.iacCrankSteps, configPage6.iacCrankBins); +static struct table2D iacCrankDutyTable(_countof(configPage6.iacCrankDuty), configPage6.iacCrankDuty, configPage6.iacCrankBins); /* These functions cover the PWM and stepper idle control @@ -98,8 +99,6 @@ void initialiseIdle(bool forcehoming) case IAC_ALGORITHM_PWM_OL: //Case 2 is PWM open loop - construct2dTable(iacPWMTable, configPage6.iacOLPWMVal, configPage6.iacBins); - construct2dTable(iacCrankDutyTable, configPage6.iacCrankDuty, configPage6.iacCrankBins); #if defined(CORE_AVR) idle_pwm_max_count = (uint16_t)(MICROS_PER_SEC / (16U * configPage6.idleFreq * 2U)); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle. Note that the frequency is divided by 2 coming from TS to allow for up to 512hz @@ -113,8 +112,6 @@ void initialiseIdle(bool forcehoming) case IAC_ALGORITHM_PWM_OLCL: //Case 6 is PWM closed loop with open loop table used as feed forward - construct2dTable(iacPWMTable, configPage6.iacOLPWMVal, configPage6.iacBins); - construct2dTable(iacCrankDutyTable, configPage6.iacCrankDuty, configPage6.iacCrankBins); #if defined(CORE_AVR) idle_pwm_max_count = (uint16_t)(MICROS_PER_SEC / (16U * configPage6.idleFreq * 2U)); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle. Note that the frequency is divided by 2 coming from TS to allow for up to 512hz @@ -134,8 +131,6 @@ void initialiseIdle(bool forcehoming) case IAC_ALGORITHM_PWM_CL: //Case 3 is PWM closed loop - construct2dTable(iacCrankDutyTable, configPage6.iacCrankDuty, configPage6.iacCrankBins); - #if defined(CORE_AVR) idle_pwm_max_count = (uint16_t)(MICROS_PER_SEC / (16U * configPage6.idleFreq * 2U)); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle. Note that the frequency is divided by 2 coming from TS to allow for up to 512hz #elif defined(CORE_TEENSY35) @@ -154,9 +149,6 @@ void initialiseIdle(bool forcehoming) case IAC_ALGORITHM_STEP_OL: //Case 2 is Stepper open loop - construct2dTable(iacStepTable, configPage6.iacOLStepVal, configPage6.iacBins); - construct2dTable(iacCrankStepsTable, configPage6.iacCrankSteps, configPage6.iacCrankBins); - iacStepTime_uS = configPage6.iacStepTime * 1000; iacCoolTime_uS = configPage9.iacCoolTime * 1000; @@ -173,7 +165,6 @@ void initialiseIdle(bool forcehoming) case IAC_ALGORITHM_STEP_CL: //Case 5 is Stepper closed loop - construct2dTable(iacCrankStepsTable, configPage6.iacCrankSteps, configPage6.iacCrankBins); iacStepTime_uS = configPage6.iacStepTime * 1000; iacCoolTime_uS = configPage9.iacCoolTime * 1000; @@ -197,8 +188,6 @@ void initialiseIdle(bool forcehoming) case IAC_ALGORITHM_STEP_OLCL: //Case 7 is Stepper closed loop with open loop table used as feed forward - construct2dTable(iacStepTable, configPage6.iacOLStepVal, configPage6.iacBins); - construct2dTable(iacCrankStepsTable, configPage6.iacCrankSteps, configPage6.iacCrankBins); iacStepTime_uS = configPage6.iacStepTime * 1000; iacCoolTime_uS = configPage9.iacCoolTime * 1000; diff --git a/speeduino/init.cpp b/speeduino/init.cpp index 43cde5a7f1..e4131dacae 100644 --- a/speeduino/init.cpp +++ b/speeduino/init.cpp @@ -36,44 +36,6 @@ #pragma GCC optimize ("Os") #endif -#if !defined(UNIT_TEST) -static inline -#endif -void construct2dTables(void) { - //Repoint the 2D table structs to the config pages that were just loaded - construct2dTable(taeTable, configPage4.taeValues, configPage4.taeBins); - construct2dTable(maeTable, configPage4.maeRates, configPage4.maeBins); - construct2dTable(WUETable, configPage2.wueValues, configPage4.wueBins); - construct2dTable(ASETable, configPage2.asePct, configPage2.aseBins); - construct2dTable(ASECountTable, configPage2.aseCount, configPage2.aseBins); - construct2dTable(PrimingPulseTable, configPage2.primePulse, configPage2.primeBins); - construct2dTable(crankingEnrichTable, configPage10.crankingEnrichValues, configPage10.crankingEnrichBins); - construct2dTable(dwellVCorrectionTable, configPage4.dwellCorrectionValues, configPage6.voltageCorrectionBins); - construct2dTable(injectorVCorrectionTable, configPage6.injVoltageCorrectionValues, configPage6.voltageCorrectionBins); - construct2dTable(IATDensityCorrectionTable, configPage6.airDenRates, configPage6.airDenBins); - construct2dTable(baroFuelTable, configPage4.baroFuelValues, configPage4.baroFuelBins); - construct2dTable(IATRetardTable, configPage4.iatRetValues, configPage4.iatRetBins); - construct2dTable(CLTAdvanceTable, configPage4.cltAdvValues, configPage4.cltAdvBins); - construct2dTable(idleTargetTable, configPage6.iacCLValues, configPage6.iacBins); - construct2dTable(idleAdvanceTable, configPage4.idleAdvValues, configPage4.idleAdvBins); - construct2dTable(rotarySplitTable, configPage10.rotarySplitValues, configPage10.rotarySplitBins); - construct2dTable(flexFuelTable, configPage10.flexFuelAdj, configPage10.flexFuelBins); - construct2dTable(flexAdvTable, configPage10.flexAdvAdj, configPage10.flexAdvBins); - construct2dTable(fuelTempTable, configPage10.fuelTempValues, configPage10.fuelTempBins); - construct2dTable(oilPressureProtectTable, configPage10.oilPressureProtMins, configPage10.oilPressureProtRPM); - construct2dTable(coolantProtectTable, configPage9.coolantProtRPM, configPage9.coolantProtTemp); - construct2dTable(fanPWMTable, configPage9.PWMFanDuty, configPage6.fanPWMBins); - construct2dTable(wmiAdvTable, configPage10.wmiAdvAdj, configPage10.wmiAdvBins); - construct2dTable(rollingCutTable, configPage15.rollingProtCutPercent, configPage15.rollingProtRPMDelta); - construct2dTable(injectorAngleTable, configPage2.injAng, configPage2.injAngRPM); - construct2dTable(flexBoostTable, configPage10.flexBoostAdj, configPage10.flexBoostBins); - construct2dTable(knockWindowStartTable, configPage10.knock_window_angle, configPage10.knock_window_rpms); - construct2dTable(knockWindowDurationTable, configPage10.knock_window_dur, configPage10.knock_window_rpms); - construct2dTable(cltCalibrationTable, cltCalibration_values, cltCalibration_bins); - construct2dTable(iatCalibrationTable, iatCalibration_values, iatCalibration_bins); - construct2dTable(o2CalibrationTable, o2Calibration_values, o2Calibration_bins); -} - /** Initialise Speeduino for the main loop. * Top level init entry point for all initialisations: * - Initialise and set sizes of 3D tables @@ -165,10 +127,7 @@ void initialiseAll(void) Serial.begin(115200); pPrimarySerial = &Serial; //Default to standard Serial interface BIT_SET(currentStatus.status4, BIT_STATUS4_ALLOW_LEGACY_COMMS); //Flag legacy comms as being allowed on startup - - //Repoint the 2D table structs to the config pages that were just loaded - construct2dTables(); - + //Setup the calibration tables loadCalibration(); diff --git a/speeduino/table2d.cpp b/speeduino/table2d.cpp index b42148ee93..574e4b4377 100644 --- a/speeduino/table2d.cpp +++ b/speeduino/table2d.cpp @@ -14,32 +14,7 @@ Note that this may clear some of the existing values of the table #include "globals.h" #endif -static void construct2dTable(table2D &table, OpaqueArray::TypeIndicator valueType, OpaqueArray::TypeIndicator axisType, uint8_t length, const void *values, const void *bins) { - table.values = { valueType, values }; - table.axis = { axisType, bins }; - table.length = length; - table.cache.lastInput = INT16_MAX; - table.cache.lastBinUpperIndex = 1U; -} -void _construct2dTable(table2D &table, uint8_t length, const uint8_t *values, const uint8_t *bins) { - construct2dTable(table, OpaqueArray::TYPE_UINT8, OpaqueArray::TYPE_UINT8, length, values, bins); -} -void _construct2dTable(table2D &table, uint8_t length, const uint8_t *values, const int8_t *bins) { - construct2dTable(table, OpaqueArray::TYPE_UINT8, OpaqueArray::TYPE_INT8, length, values, bins); -} -void _construct2dTable(table2D &table, uint8_t length, const uint16_t *values, const uint16_t *bins) { - construct2dTable(table, OpaqueArray::TYPE_UINT16, OpaqueArray::TYPE_UINT16, length, values, bins); -} -void _construct2dTable(table2D &table, uint8_t length, const uint8_t *values, const uint16_t *bins) { - construct2dTable(table, OpaqueArray::TYPE_UINT8, OpaqueArray::TYPE_UINT16, length, values, bins); -} -void _construct2dTable(table2D &table, uint8_t length, const uint16_t *values, const uint8_t *bins) { - construct2dTable(table, OpaqueArray::TYPE_UINT16, OpaqueArray::TYPE_UINT8, length, values, bins); -} -void _construct2dTable(table2D &table, uint8_t length, const int16_t *values, const uint8_t *bins) { - construct2dTable(table, OpaqueArray::TYPE_INT16, OpaqueArray::TYPE_UINT8, length, values, bins); -} static inline uint8_t getCacheTime(void) { #if !defined(UNIT_TEST) diff --git a/speeduino/table2d.h b/speeduino/table2d.h index 82ea864a18..84281c7cac 100644 --- a/speeduino/table2d.h +++ b/speeduino/table2d.h @@ -13,12 +13,14 @@ This file is used for everything related to maps/tables including their definiti struct Table2DCache { // Store the upper index of the bin we last found. This is used to make the next check faster // Since this is the *upper* index, it can never be 0. - uint8_t lastBinUpperIndex; + uint8_t lastBinUpperIndex = 1U; // The algorithms rely on this being less than the length of the table AND non-zero //Store the last input and output for caching - int16_t lastInput; - int16_t lastOutput; - uint8_t cacheTime; //Tracks when the last cache value was set so it can expire after x seconds. A timeout is required to pickup when a tuning value is changed, otherwise the old cached value will continue to be returned as the X value isn't changing. + int16_t lastInput = INT16_MAX; + int16_t lastOutput = 0; + uint8_t cacheTime = 0U; //Tracks when the last cache value was set so it can expire after x seconds. A timeout is required to pickup when a tuning value is changed, otherwise the old cached value will continue to be returned as the X value isn't changing. + + constexpr Table2DCache() = default; }; // Captures the concept of an opaque array @@ -30,8 +32,30 @@ struct OpaqueArray { TYPE_UINT16, TYPE_INT16, }; - TypeIndicator type; - const void *data; + TypeIndicator type = TYPE_UINT8; + const void *data = nullptr; + + explicit constexpr OpaqueArray(const uint8_t *data) + : type(TYPE_UINT8) + , data((const void *)data) + { + }; + explicit constexpr OpaqueArray(const int8_t *data) + : type(TYPE_INT8) + , data((const void *)data) + { + }; + explicit constexpr OpaqueArray(const uint16_t *data) + : type(TYPE_UINT16) + , data((const void *)data) + { + }; + explicit constexpr OpaqueArray(const int16_t *data) + : type(TYPE_INT16) + , data((const void *)data) + { + }; + }; /// @endcond @@ -54,34 +78,29 @@ struct table2D { // cppcheck-suppress ctuOneDefinitionRuleViolation; false posit OpaqueArray axis; mutable Table2DCache cache; -}; -/// @cond -// private to construct2dTable -void _construct2dTable(table2D &table, uint8_t length, const uint8_t *values, const uint8_t *bins); -void _construct2dTable(table2D &table, uint8_t length, const uint8_t *values, const int8_t *bins); -void _construct2dTable(table2D &table, uint8_t length, const uint16_t *values, const uint16_t *bins); -void _construct2dTable(table2D &table, uint8_t length, const uint8_t *values, const uint16_t *bins); -void _construct2dTable(table2D &table, uint8_t length, const uint16_t *values, const uint8_t *bins); -void _construct2dTable(table2D &table, uint8_t length, const int16_t *values, const uint8_t *bins); -/// @endcond - -/** - * @brief Wire up the 2D table struct to the axis (aka bins) and value arrays - * - * The 2 arrays must be the same length - * - * @tparam axis_t Integral type of the axis. E.g. uint8_t - * @tparam value_t Integral type of the values. E.g. uint8_t - * @tparam TSize Size of the arrays - * @param table The table to wire up - * @param values Array of values - * @param bins Array of axis values - */ -template -void construct2dTable(table2D &table, const value_t (&values)[TSize], const axis_t (&bins)[TSize]) { - _construct2dTable(table, TSize, values, bins); -} + constexpr table2D(uint8_t length, const OpaqueArray &values, const OpaqueArray &bins) + : length(length), values(values), axis(bins) { + } + constexpr table2D(uint8_t length, const uint8_t *values, const uint8_t *bins) + : table2D(length, OpaqueArray(values), OpaqueArray(bins)) { + } + constexpr table2D(uint8_t length, const uint8_t *values, const int8_t *bins) + : table2D(length, OpaqueArray(values), OpaqueArray(bins)) { + } + constexpr table2D(uint8_t length, const uint16_t *values, const uint16_t *bins) + : table2D(length, OpaqueArray(values), OpaqueArray(bins)) { + } + constexpr table2D(uint8_t length, const uint8_t *values, const uint16_t *bins) + : table2D(length, OpaqueArray(values), OpaqueArray(bins)) { + } + constexpr table2D(uint8_t length, const uint16_t *values, const uint8_t *bins) + : table2D(length, OpaqueArray(values), OpaqueArray(bins)) { + } + constexpr table2D(uint8_t length, const int16_t *values, const uint8_t *bins) + : table2D(length, OpaqueArray(values), OpaqueArray(bins)) { + } +}; int16_t table2D_getAxisValue(const struct table2D *fromTable, uint8_t index); int16_t table2D_getRawValue(const struct table2D *fromTable, uint8_t index); diff --git a/test/test_fuel/test_corrections.cpp b/test/test_fuel/test_corrections.cpp index 2a9de1a15e..2227a39ce3 100644 --- a/test/test_fuel/test_corrections.cpp +++ b/test/test_fuel/test_corrections.cpp @@ -8,12 +8,9 @@ #include "speeduino.h" #include "sensors_map_structs.h" -extern void construct2dTables(void); - extern byte correctionWUE(void); static void setup_wue_table(void) { - construct2dTables(); initialiseCorrections(); //Set some fake values in the table axis. Target value will fall between points 6 and 7 @@ -86,7 +83,6 @@ static void test_corrections_WUE(void) extern uint16_t correctionCranking(void); static void setup_correctionCranking_table(void) { - construct2dTables(); initialiseCorrections(); uint8_t values[] = { 120U / 5U, 130U / 5U, 140U / 5U, 150U / 5U }; @@ -100,7 +96,6 @@ static void setup_correctionCranking_table(void) { } static void test_corrections_cranking_inactive(void) { - construct2dTables(); initialiseCorrections(); BIT_CLEAR(currentStatus.engine, BIT_ENGINE_CRANK); BIT_CLEAR(currentStatus.engine, BIT_ENGINE_ASE); @@ -200,7 +195,6 @@ extern uint8_t correctionASE(void); static void test_corrections_ASE_inactive_cranking(void) { - construct2dTables(); initialiseCorrections(); BIT_SET(currentStatus.engine, BIT_ENGINE_CRANK); @@ -210,7 +204,6 @@ static void test_corrections_ASE_inactive_cranking(void) } static inline void setup_correctionASE(void) { - construct2dTables(); initialiseCorrections(); BIT_CLEAR(currentStatus.engine, BIT_ENGINE_CRANK); @@ -327,7 +320,6 @@ static void setup_valid_ego_cycle(void) { } static void setup_ego_simple(void) { - construct2dTables(); initialiseCorrections(); configPage6.egoType = EGO_TYPE_NARROW; @@ -613,7 +605,6 @@ static void test_corrections_closedloop(void) uint8_t correctionFlex(void); static void setupFlexFuelTable(void) { - construct2dTables(); initialiseCorrections(); TEST_DATA_P uint8_t bins[] = { 0, 10, 30, 50, 60, 70 }; @@ -638,7 +629,6 @@ static void test_corrections_flex_flex_on(void) { uint8_t correctionFuelTemp(void); static void setupFuelTempTable(void) { - construct2dTables(); initialiseCorrections(); TEST_DATA_P uint8_t bins[] = { 0, 10, 30, 50, 60, 70 }; @@ -671,7 +661,6 @@ static void test_corrections_flex(void) uint8_t correctionBatVoltage(void); static void setup_battery_correction(void) { - construct2dTables(); initialiseCorrections(); TEST_DATA_P uint8_t bins[] = { 60, 70, 80, 90, 100, 110 }; @@ -742,7 +731,6 @@ extern bool correctionDFCO(void); static void setup_DFCO_on_taper_off_no_delay() { - construct2dTables(); initialiseCorrections(); //Sets all the required conditions to have the DFCO be active @@ -948,7 +936,6 @@ static void reset_AE(void) { } static void setup_AE(void) { - construct2dTables(); initialiseCorrections(); //Divided by 100 @@ -1599,7 +1586,6 @@ static void test_corrections_correctionsFuel_ae_modes(void) { } static void test_corrections_correctionsFuel_clip_limit(void) { - construct2dTables(); initialiseCorrections(); populate_2dtable(&injectorVCorrectionTable, 255, 100); diff --git a/test/test_ign/test_corrections.cpp b/test/test_ign/test_corrections.cpp index a14359c3d7..5f839a4236 100644 --- a/test/test_ign/test_corrections.cpp +++ b/test/test_ign/test_corrections.cpp @@ -6,8 +6,6 @@ #include "../test_utils.h" #include "sensors.h" -extern void construct2dTables(void); - extern int8_t correctionFixedTiming(int8_t advance); static void test_correctionFixedTiming_inactive(void) { @@ -34,7 +32,6 @@ static void test_correctionFixedTiming(void) { extern int8_t correctionCLTadvance(int8_t advance); static void setup_clt_advance_table(void) { - construct2dTables(); initialiseCorrections(); TEST_DATA_P uint8_t bins[] = { 60, 70, 80, 90, 100, 110 }; TEST_DATA_P uint8_t values[] = { 30, 25, 20, 15, 10, 5 }; @@ -99,7 +96,6 @@ static void test_correctionCrankingFixedTiming(void) { extern int8_t correctionFlexTiming(int8_t advance); static void setup_flexAdv(void) { - construct2dTables(); initialiseCorrections(); TEST_DATA_P uint8_t bins[] = { 30, 40, 50, 60, 70, 80 }; TEST_DATA_P uint8_t values[] = { 30, 25, 20, 15, 10, 5 }; @@ -136,7 +132,6 @@ static void test_correctionFlexTiming(void) { extern int8_t correctionWMITiming(int8_t advance); static void setup_WMIAdv(void) { - construct2dTables(); initialiseCorrections(); configPage10.wmiEnabled= 1; @@ -238,7 +233,6 @@ static void test_correctionWMITiming(void) { extern int8_t correctionIATretard(int8_t advance); static void setup_IATRetard(void) { - construct2dTables(); initialiseCorrections(); TEST_DATA_P uint8_t bins[] = { 30, 40, 50, 60, 70, 80 }; @@ -275,7 +269,6 @@ static void setup_idleadv_ctps(void) { } static void setup_correctionIdleAdvance(void) { - construct2dTables(); initialiseCorrections(); TEST_DATA_P uint8_t bins[] = { 30, 40, 50, 60, 70, 80 }; @@ -412,7 +405,6 @@ static void test_correctionIdleAdvance(void) { extern int8_t correctionSoftRevLimit(int8_t advance); static void setup_correctionSoftRevLimit(void) { - construct2dTables(); initialiseCorrections(); configPage6.engineProtectType = PROTECT_CUT_IGN; @@ -765,7 +757,6 @@ static void test_correctionKnock(void) { } static void setup_correctionsDwell(void) { - construct2dTables(); initialiseCorrections(); configPage4.sparkDur = 10; diff --git a/test/test_tables/test_table2d.cpp b/test/test_tables/test_table2d.cpp index f1b8ddf639..ef5f0f09f6 100644 --- a/test/test_tables/test_table2d.cpp +++ b/test/test_tables/test_table2d.cpp @@ -25,22 +25,13 @@ static uint16_t table2d_axis_u16[TEST_TABLE2D_SIZE] = { 123, 2539, 5531, 7537, 11329, 16363, 21323, 26357, 32029, }; -static table2D table2d_u8_u8; -static table2D table2d_u8_u16; -static table2D table2d_u16_u8; -static table2D table2d_u16_u16; -static table2D table2d_u8_i8; -static table2D table2d_i16_u8; - -static void setup_test_subjects(void) -{ - construct2dTable(table2d_u8_u8, table2d_data_u8, table2d_axis_u8); - construct2dTable(table2d_u8_u16, table2d_data_u8, table2d_axis_u16); - construct2dTable(table2d_u16_u8, table2d_data_u16, table2d_axis_u8); - construct2dTable(table2d_u16_u16, table2d_data_u16, table2d_axis_u16); - construct2dTable(table2d_u8_i8, table2d_data_u8, table2d_axis_i8); - construct2dTable(table2d_i16_u8, table2d_data_i16, table2d_axis_u8); -} +static table2D table2d_u8_u8(_countof(table2d_data_u8), table2d_data_u8, table2d_axis_u8); +static table2D table2d_u8_u16(_countof(table2d_data_u8), table2d_data_u8, table2d_axis_u16); +static table2D table2d_u16_u8(_countof(table2d_data_u16), table2d_data_u16, table2d_axis_u8); +static table2D table2d_u16_u16(_countof(table2d_data_u16), table2d_data_u16, table2d_axis_u16); +static table2D table2d_u8_i8(_countof(table2d_data_u8), table2d_data_u8, table2d_axis_i8); +static table2D table2d_i16_u8(_countof(table2d_data_i16), table2d_data_i16, table2d_axis_u8); + template static void test_table2dLookup(const table2D &table, const TValue *data, const TAxis *axis, uint8_t binFrac) @@ -50,7 +41,7 @@ static void test_table2dLookup(const table2D &table, const TValue *data, const T TValue expected = map(lookupValue, axis[i], axis[i+1], data[i], data[i+1]); TValue result = (TValue)table2D_getValue(&table, lookupValue); char szMsg[128]; - sprintf(szMsg, "Loop: %d, VT %d, AT %d lookup: %d, data[i]: %d, data[i+1]: %d, binFrac %d", i, table.values.typeIndicator, table.axis.typeIndicator, lookupValue, data[i], data[i+1], binFrac); + sprintf(szMsg, "Loop: %d, VT %d, AT %d lookup: %d, data[i]: %d, data[i+1]: %d, binFrac %d", i, table.values.type, table.axis.type, lookupValue, data[i], data[i+1], binFrac); TEST_ASSERT_INT_WITHIN_MESSAGE(1U, expected, result, szMsg); TEST_ASSERT_EQUAL(i+1, table.cache.lastBinUpperIndex); } @@ -58,8 +49,6 @@ static void test_table2dLookup(const table2D &table, const TValue *data, const T static void test_table2dLookup_bin_midpoints(void) { - setup_test_subjects(); - test_table2dLookup(table2d_u8_u8, table2d_data_u8, table2d_axis_u8, 50U); test_table2dLookup(table2d_u8_u16, table2d_data_u8, table2d_axis_u16, 50U); test_table2dLookup(table2d_u16_u8, table2d_data_u16, table2d_axis_u8, 50U); @@ -70,8 +59,6 @@ static void test_table2dLookup_bin_midpoints(void) static void test_table2dLookup_bin_33(void) { - setup_test_subjects(); - test_table2dLookup(table2d_u8_u8, table2d_data_u8, table2d_axis_u8, 33U); test_table2dLookup(table2d_u8_u16, table2d_data_u8, table2d_axis_u16, 33U); test_table2dLookup(table2d_u16_u8, table2d_data_u16, table2d_axis_u8, 33U); @@ -82,8 +69,6 @@ static void test_table2dLookup_bin_33(void) static void test_table2dLookup_bin_66(void) { - setup_test_subjects(); - test_table2dLookup(table2d_u8_u8, table2d_data_u8, table2d_axis_u8, 66U); test_table2dLookup(table2d_u8_u16, table2d_data_u8, table2d_axis_u16, 66U); test_table2dLookup(table2d_u16_u8, table2d_data_u16, table2d_axis_u8, 66U); @@ -97,17 +82,15 @@ static void test_table2dLookup_bin_edges(const table2D &table, const TValue *dat for (uint8_t i=0; i