Skip to content

Commit

Permalink
Table 2D - Initialise during constexpr construction.
Browse files Browse the repository at this point in the history
Saves flash & RAM
  • Loading branch information
adbancroft committed Oct 6, 2024
1 parent 91ab538 commit 780c44d
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 210 deletions.
67 changes: 32 additions & 35 deletions speeduino/globals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand All @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
21 changes: 5 additions & 16 deletions speeduino/idle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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;

Expand All @@ -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;
Expand All @@ -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;
Expand Down
43 changes: 1 addition & 42 deletions speeduino/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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();

Expand Down
25 changes: 0 additions & 25 deletions speeduino/table2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Loading

0 comments on commit 780c44d

Please sign in to comment.