speeduino/speeduino/schedule_calcs.h

72 lines
3.5 KiB
C
Raw Normal View History

#pragma once
#include <stdint.h>
#include "scheduler.h"
extern int ignition1StartAngle;
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>
2023-06-25 19:13:53 -07:00
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;
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>
2023-06-25 19:13:53 -07:00
extern int ignition2EndAngle;
extern int channel2IgnDegrees; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
extern int ignition3StartAngle;
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>
2023-06-25 19:13:53 -07:00
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;
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>
2023-06-25 19:13:53 -07:00
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;
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>
2023-06-25 19:13:53 -07:00
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;
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>
2023-06-25 19:13:53 -07:00
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;
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>
2023-06-25 19:13:53 -07:00
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;
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>
2023-06-25 19:13:53 -07:00
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 */
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>
2023-06-25 19:13:53 -07:00
#if (INJ_CHANNELS >= 5)
extern int channel5InjDegrees; /**< The number of crank degrees until cylinder 5 is at TDC */
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>
2023-06-25 19:13:53 -07:00
#endif
#if (INJ_CHANNELS >= 6)
extern int channel6InjDegrees; /**< The number of crank degrees until cylinder 6 is at TDC */
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>
2023-06-25 19:13:53 -07:00
#endif
#if (INJ_CHANNELS >= 7)
extern int channel7InjDegrees; /**< The number of crank degrees until cylinder 7 is at TDC */
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>
2023-06-25 19:13:53 -07:00
#endif
#if (INJ_CHANNELS >= 8)
extern int channel8InjDegrees; /**< The number of crank degrees until cylinder 8 is at TDC */
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>
2023-06-25 19:13:53 -07:00
#endif
Performance: optimize division (#1082) * Add udiv_32_16 * Apply udiv_32_16() where possible * Convert udiv_32_16 to assembler It's worth 20 loop/s * Remove unused functions * Remove degreesPeruSx2048 - unused * Remove angleToTime - replace with direct calls 1. Drop angleToTime() It's slow, only partially implemented and adds zero value (and has MISRA violations) 2. Consistent function naming 3. Doxygen * triggerPri_Nissan360 shouldn't set timePerDegree. It will be overwritten every loop by doCrankSpeedCalcs() * Use angleToTimeMicroSecPerDegree() instead of timePerDegree No loss in performance Increased injection open/close time accuracy (so unit test values must change) Can remove timePerDegree global. * Hide (encapsulate) crank math globals. * Base all angle to time conversions on decoder computed variables. This is within 2us of the revolution based method and is much faster - which is essentially zero percent change. * Performance: move calculation of degreesPeruSx32768 into decoders. Remove doCrankSpeedCalcs() - it's doing nothing at the moment. * Apply libdivide to triggerSetEndTeeth functions. Since triggerToothAngle is set once at initialization time, we can generate the libdivide struct once and reuse it many times. * Remove lastToothCalcAdvance - unused * Replace 16-bit division with shift * Replace 32-bit divison with 16-bit division * Avoid 32-bit division; use div100() * inline percentage() * Optimize div100() * MISRA fixes * Replace magic numbers with #defs * Replace libdivide structs with inline constants No perf or memory changes * Use fixed types for PWM max count variables * Accurate rounded integer division * Formalise rounding behavior (DIV_ROUND_CORRECT) * Apply DIV_ROUND_CORRECT to DIV_ROUND_CLOSEST(), UDIV_ROUND_CLOSEST(), div100(), div360(), percentage() & halfPercentage() * Add, fix & improve unit tests * Add udiv_32_16_closest() * Perf: Limit percentage calculations to 16-bits * MISRA fixes * Add compare_executiontime() to encapsulate common perf testing code * Signed to unsigned division * Convert ignitionLimits() to an inline function. Slight speed up, probably due to removing multiple evaluations of macro arguments. * Split unit tests up. * udiv_32_16 - check for valid parameters
2023-11-05 14:10:08 -08:00
static inline uint16_t __attribute__((always_inline)) calculateInjectorStartAngle(uint16_t PWdivTimerPerDegree, int16_t injChannelDegrees, uint16_t injAngle);
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>
2023-06-25 19:13:53 -07:00
Performance: optimize division (#1082) * Add udiv_32_16 * Apply udiv_32_16() where possible * Convert udiv_32_16 to assembler It's worth 20 loop/s * Remove unused functions * Remove degreesPeruSx2048 - unused * Remove angleToTime - replace with direct calls 1. Drop angleToTime() It's slow, only partially implemented and adds zero value (and has MISRA violations) 2. Consistent function naming 3. Doxygen * triggerPri_Nissan360 shouldn't set timePerDegree. It will be overwritten every loop by doCrankSpeedCalcs() * Use angleToTimeMicroSecPerDegree() instead of timePerDegree No loss in performance Increased injection open/close time accuracy (so unit test values must change) Can remove timePerDegree global. * Hide (encapsulate) crank math globals. * Base all angle to time conversions on decoder computed variables. This is within 2us of the revolution based method and is much faster - which is essentially zero percent change. * Performance: move calculation of degreesPeruSx32768 into decoders. Remove doCrankSpeedCalcs() - it's doing nothing at the moment. * Apply libdivide to triggerSetEndTeeth functions. Since triggerToothAngle is set once at initialization time, we can generate the libdivide struct once and reuse it many times. * Remove lastToothCalcAdvance - unused * Replace 16-bit division with shift * Replace 32-bit divison with 16-bit division * Avoid 32-bit division; use div100() * inline percentage() * Optimize div100() * MISRA fixes * Replace magic numbers with #defs * Replace libdivide structs with inline constants No perf or memory changes * Use fixed types for PWM max count variables * Accurate rounded integer division * Formalise rounding behavior (DIV_ROUND_CORRECT) * Apply DIV_ROUND_CORRECT to DIV_ROUND_CLOSEST(), UDIV_ROUND_CLOSEST(), div100(), div360(), percentage() & halfPercentage() * Add, fix & improve unit tests * Add udiv_32_16_closest() * Perf: Limit percentage calculations to 16-bits * MISRA fixes * Add compare_executiontime() to encapsulate common perf testing code * Signed to unsigned division * Convert ignitionLimits() to an inline function. Slight speed up, probably due to removing multiple evaluations of macro arguments. * Split unit tests up. * udiv_32_16 - check for valid parameters
2023-11-05 14:10:08 -08:00
static inline uint32_t __attribute__((always_inline)) calculateInjectorTimeout(const FuelSchedule &schedule, int channelInjDegrees, int injectorStartAngle, int crankAngle);
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>
2023-06-25 19:13:53 -07:00
static inline void __attribute__((always_inline)) calculateIgnitionAngle(const uint16_t dwellAngle, const uint16_t channelIgnDegrees, int8_t advance, int *pEndAngle, int *pStartAngle);
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>
2023-06-25 19:13:53 -07:00
// Ignition for rotary.
static inline void __attribute__((always_inline)) calculateIgnitionTrailingRotary(uint16_t dwellAngle, int rotarySplitDegrees, int leadIgnitionAngle, int *pEndAngle, int *pStartAngle);
Performance: optimize division (#1082) * Add udiv_32_16 * Apply udiv_32_16() where possible * Convert udiv_32_16 to assembler It's worth 20 loop/s * Remove unused functions * Remove degreesPeruSx2048 - unused * Remove angleToTime - replace with direct calls 1. Drop angleToTime() It's slow, only partially implemented and adds zero value (and has MISRA violations) 2. Consistent function naming 3. Doxygen * triggerPri_Nissan360 shouldn't set timePerDegree. It will be overwritten every loop by doCrankSpeedCalcs() * Use angleToTimeMicroSecPerDegree() instead of timePerDegree No loss in performance Increased injection open/close time accuracy (so unit test values must change) Can remove timePerDegree global. * Hide (encapsulate) crank math globals. * Base all angle to time conversions on decoder computed variables. This is within 2us of the revolution based method and is much faster - which is essentially zero percent change. * Performance: move calculation of degreesPeruSx32768 into decoders. Remove doCrankSpeedCalcs() - it's doing nothing at the moment. * Apply libdivide to triggerSetEndTeeth functions. Since triggerToothAngle is set once at initialization time, we can generate the libdivide struct once and reuse it many times. * Remove lastToothCalcAdvance - unused * Replace 16-bit division with shift * Replace 32-bit divison with 16-bit division * Avoid 32-bit division; use div100() * inline percentage() * Optimize div100() * MISRA fixes * Replace magic numbers with #defs * Replace libdivide structs with inline constants No perf or memory changes * Use fixed types for PWM max count variables * Accurate rounded integer division * Formalise rounding behavior (DIV_ROUND_CORRECT) * Apply DIV_ROUND_CORRECT to DIV_ROUND_CLOSEST(), UDIV_ROUND_CLOSEST(), div100(), div360(), percentage() & halfPercentage() * Add, fix & improve unit tests * Add udiv_32_16_closest() * Perf: Limit percentage calculations to 16-bits * MISRA fixes * Add compare_executiontime() to encapsulate common perf testing code * Signed to unsigned division * Convert ignitionLimits() to an inline function. Slight speed up, probably due to removing multiple evaluations of macro arguments. * Split unit tests up. * udiv_32_16 - check for valid parameters
2023-11-05 14:10:08 -08:00
static inline uint32_t __attribute__((always_inline)) calculateIgnitionTimeout(const IgnitionSchedule &schedule, int startAngle, int channelIgnDegrees, int crankAngle);
#include "schedule_calcs.hpp"