diff --git a/speeduino/comms_legacy.cpp b/speeduino/comms_legacy.cpp index ec406576..ccf8980d 100644 --- a/speeduino/comms_legacy.cpp +++ b/speeduino/comms_legacy.cpp @@ -842,7 +842,7 @@ void sendValuesLegacy(void) bytestosend -= Serial.write(temp >> 8); // MAPdot bytestosend -= Serial.write(temp); // MAPdot - temp = currentStatus.dwell * 10; + temp = currentStatus.dwell * 10U; bytestosend -= Serial.write(temp>>8); // dwell bytestosend -= Serial.write(temp); // dwell diff --git a/speeduino/globals.h b/speeduino/globals.h index 260c0ffd..399b8778 100644 --- a/speeduino/globals.h +++ b/speeduino/globals.h @@ -607,8 +607,8 @@ struct statuses { int batADC; int O2ADC; int O2_2ADC; - int dwell; ///< dwell (coil primary winding/circuit on) time (in ms * 10 ? See @ref correctionsDwell) - volatile int16_t actualDwell; ///< actual dwell time if new ignition mode is used (in uS) + uint16_t dwell; ///< dwell (coil primary winding/circuit on) time (in ms * 10 ? See @ref correctionsDwell) + volatile uint16_t actualDwell; ///< actual dwell time if new ignition mode is used (in uS) byte dwellCorrection; /**< The amount of correction being applied to the dwell time (in unit ...). */ byte battery10; /**< The current BRV in volts (multiplied by 10. Eg 12.5V = 125) */ int8_t advance; /**< The current advance value being used in the spark calculation. Can be the same as advance1 or advance2, or a calculated value of both */ @@ -909,8 +909,8 @@ struct config4 { byte triggerFilter : 2; //The mode of trigger filter being used (0=Off, 1=Light (Not currently used), 2=Normal, 3=Aggressive) byte ignCranklock : 1; //Whether or not the ignition timing during cranking is locked to a CAS (crank) pulse. Only currently valid for Basic distributor and 4G63. - byte dwellCrank; ///< Dwell time whilst cranking - byte dwellRun; ///< Dwell time whilst running + uint8_t dwellCrank; ///< Dwell time whilst cranking + uint8_t dwellRun; ///< Dwell time whilst running byte triggerTeeth; ///< The full count of teeth on the trigger wheel if there were no gaps byte triggerMissingTeeth; ///< The size of the tooth gap (ie number of missing teeth) byte crankRPM; ///< RPM below which the engine is considered to be cranking diff --git a/speeduino/logger.cpp b/speeduino/logger.cpp index 1438828e..47ec667e 100644 --- a/speeduino/logger.cpp +++ b/speeduino/logger.cpp @@ -269,7 +269,7 @@ int16_t getReadableLogEntry(uint16_t logIndex) case 60: statusValue = currentStatus.fuelLoad; break; case 61: statusValue = currentStatus.ignLoad; break; - case 62: statusValue = currentStatus.dwell; break; + case 62: statusValue = (int16_t)currentStatus.dwell; break; case 63: statusValue = currentStatus.CLIdleTarget; break; case 64: statusValue = currentStatus.mapDOT; break; case 65: statusValue = currentStatus.vvt1Angle; break; diff --git a/speeduino/maths.h b/speeduino/maths.h index e9949098..d0bafbea 100644 --- a/speeduino/maths.h +++ b/speeduino/maths.h @@ -144,7 +144,7 @@ static inline uint32_t div100(uint32_t n) { #endif } -#if defined(__arm__) +#if defined(__arm__) && !defined(CORE_TEENSY) static inline int div100(int n) { return DIV_ROUND_CLOSEST(n, 100U, int); } @@ -156,7 +156,7 @@ static inline int32_t div100(int32_t n) { } return libdivide::libdivide_s32_do_raw(n + (DIV_ROUND_CORRECT(UINT16_C(100), uint32_t) * (n<0 ? -1 : 1)), 1374389535L, 5); #else - return DIV_ROUND_CLOSEST(n, UINT32_C(100), int32_t); + return DIV_ROUND_CLOSEST(n, INT32_C(100), int32_t); #endif } #endif diff --git a/speeduino/schedule_calcs.h b/speeduino/schedule_calcs.h index fe854533..77ed78b2 100644 --- a/speeduino/schedule_calcs.h +++ b/speeduino/schedule_calcs.h @@ -61,10 +61,10 @@ static inline uint16_t __attribute__((always_inline)) calculateInjectorStartAngl static inline uint32_t __attribute__((always_inline)) calculateInjectorTimeout(const FuelSchedule &schedule, int channelInjDegrees, int injectorStartAngle, int crankAngle); -static inline void __attribute__((always_inline)) calculateIgnitionAngle(const int dwellAngle, const uint16_t channelIgnDegrees, int8_t advance, int *pEndAngle, int *pStartAngle); +static inline void __attribute__((always_inline)) calculateIgnitionAngle(const uint16_t dwellAngle, const uint16_t channelIgnDegrees, int8_t advance, int *pEndAngle, int *pStartAngle); // Ignition for rotary. -static inline void __attribute__((always_inline)) calculateIgnitionTrailingRotary(int dwellAngle, int rotarySplitDegrees, int leadIgnitionAngle, int *pEndAngle, int *pStartAngle); +static inline void __attribute__((always_inline)) calculateIgnitionTrailingRotary(uint16_t dwellAngle, int rotarySplitDegrees, int leadIgnitionAngle, int *pEndAngle, int *pStartAngle); static inline uint32_t __attribute__((always_inline)) calculateIgnitionTimeout(const IgnitionSchedule &schedule, int startAngle, int channelIgnDegrees, int crankAngle); diff --git a/speeduino/schedule_calcs.hpp b/speeduino/schedule_calcs.hpp index 265aa83e..58436d38 100644 --- a/speeduino/schedule_calcs.hpp +++ b/speeduino/schedule_calcs.hpp @@ -57,7 +57,7 @@ static inline uint32_t calculateInjectorTimeout(const FuelSchedule &schedule, in return _calculateInjectorTimeout(schedule, _adjustToInjChannel(openAngle, channelInjDegrees), _adjustToInjChannel(crankAngle, channelInjDegrees)); } -static inline void calculateIgnitionAngle(const int dwellAngle, const uint16_t channelIgnDegrees, int8_t advance, int *pEndAngle, int *pStartAngle) +static inline void calculateIgnitionAngle(const uint16_t dwellAngle, const uint16_t channelIgnDegrees, int8_t advance, int *pEndAngle, int *pStartAngle) { *pEndAngle = (int16_t)(channelIgnDegrees==0U ? (uint16_t)CRANK_ANGLE_MAX_IGN : channelIgnDegrees) - (int16_t)advance; if(*pEndAngle > CRANK_ANGLE_MAX_IGN) {*pEndAngle -= CRANK_ANGLE_MAX_IGN;} @@ -65,7 +65,7 @@ static inline void calculateIgnitionAngle(const int dwellAngle, const uint16_t c if(*pStartAngle < 0) {*pStartAngle += CRANK_ANGLE_MAX_IGN;} } -static inline void calculateIgnitionTrailingRotary(int dwellAngle, int rotarySplitDegrees, int leadIgnitionAngle, int *pEndAngle, int *pStartAngle) +static inline void calculateIgnitionTrailingRotary(uint16_t dwellAngle, int rotarySplitDegrees, int leadIgnitionAngle, int *pEndAngle, int *pStartAngle) { *pEndAngle = leadIgnitionAngle + rotarySplitDegrees; *pStartAngle = *pEndAngle - dwellAngle; diff --git a/speeduino/speeduino.h b/speeduino/speeduino.h index 6a6bbbc6..2587f791 100644 --- a/speeduino/speeduino.h +++ b/speeduino/speeduino.h @@ -22,7 +22,7 @@ byte getVE1(void); byte getAdvance1(void); uint16_t calculatePWLimit(); void calculateStaging(uint32_t); -void calculateIgnitionAngles(int dwellAngle); +void calculateIgnitionAngles(uint16_t dwellAngle); void checkLaunchAndFlatShift(); extern uint16_t req_fuel_uS; /**< The required fuel variable (As calculated by TunerStudio) in uS */ diff --git a/speeduino/speeduino.ino b/speeduino/speeduino.ino index 5041f0be..2daa891c 100644 --- a/speeduino/speeduino.ino +++ b/speeduino/speeduino.ino @@ -716,24 +716,23 @@ void loop(void) //Set dwell //Dwell is stored as ms * 10. ie Dwell of 4.3ms would be 43 in configPage4. This number therefore needs to be multiplied by 100 to get dwell in uS if ( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) ) { - currentStatus.dwell = (configPage4.dwellCrank * 100); //use cranking dwell + currentStatus.dwell = (configPage4.dwellCrank * 100U); //use cranking dwell } else { if ( configPage2.useDwellMap == true ) { - currentStatus.dwell = (get3DTableValue(&dwellTable, currentStatus.ignLoad, currentStatus.RPM) * 100); //use running dwell from map + currentStatus.dwell = (get3DTableValue(&dwellTable, currentStatus.ignLoad, currentStatus.RPM) * 100U); //use running dwell from map } else { - currentStatus.dwell = (configPage4.dwellRun * 100); //use fixed running dwell + currentStatus.dwell = (configPage4.dwellRun * 100U); //use fixed running dwell } } currentStatus.dwell = correctionsDwell(currentStatus.dwell); - int dwellAngle = timeToAngleDegPerMicroSec(currentStatus.dwell); //Convert the dwell time to dwell angle based on the current engine speed - - calculateIgnitionAngles(dwellAngle); + // Convert the dwell time to dwell angle based on the current engine speed + calculateIgnitionAngles(timeToAngleDegPerMicroSec(currentStatus.dwell)); //If ignition timing is being tracked per tooth, perform the calcs to get the end teeth //This only needs to be run if the advance figure has changed, otherwise the end teeth will still be the same @@ -1323,10 +1322,8 @@ byte getAdvance1(void) * both start and end angles are calculated for each channel. * Also the mode of ignition firing - wasted spark vs. dedicated spark per cyl. - is considered here. */ -void calculateIgnitionAngles(int dwellAngle) +void calculateIgnitionAngles(uint16_t dwellAngle) { - - //This test for more cylinders and do the same thing switch (configPage2.nCylinders) { diff --git a/test/test_math/test_division.cpp b/test/test_math/test_division.cpp index d2f930ed..4822988c 100644 --- a/test/test_math/test_division.cpp +++ b/test/test_math/test_division.cpp @@ -63,7 +63,7 @@ void test_maths_div100_S16(void) void test_maths_div100_S32(void) { //Check both the signed and unsigned results -#if defined(__arm__) +#if defined(__arm__) && !defined(CORE_TEENSY) test_div100_Seed(100U); test_div100_Seed(10000U); test_div100_Seed(100000000UL); @@ -107,6 +107,7 @@ void assert_udiv_32_16(uint32_t dividend, uint16_t divisor) { void test_maths_udiv_32_16(void) { +#if defined(ARDUINO_ARCH_AVR) // Divide by zero TEST_ASSERT_EQUAL_UINT16(UINT16_MAX, udiv_32_16(0, 0)); @@ -121,6 +122,7 @@ void test_maths_udiv_32_16(void) assert_udiv_32_16(MICROS_PER_MIN, 7590); // 7905 RPM assert_udiv_32_16(MICROS_PER_MIN, 7715); // 7777 RPM assert_udiv_32_16(MICROS_PER_MIN, 3333); // 18000 RPM +#endif } @@ -130,6 +132,7 @@ void assert_udiv_32_16_closest(uint32_t dividend, uint16_t divisor) { void test_maths_udiv_32_16_closest(void) { +#if defined(ARDUINO_ARCH_AVR) // Divide by zero TEST_ASSERT_EQUAL_UINT16(UINT16_MAX, udiv_32_16_closest(0, 0)); @@ -145,6 +148,7 @@ void test_maths_udiv_32_16_closest(void) assert_udiv_32_16(MICROS_PER_MIN, 7590); // 7905 RPM assert_udiv_32_16(MICROS_PER_MIN, 7715); // 7777 RPM assert_udiv_32_16(MICROS_PER_MIN, 3333); // 18000 RPM +#endif } static uint32_t indexToDividend(int16_t index) { @@ -152,6 +156,7 @@ static uint32_t indexToDividend(int16_t index) { } void test_maths_udiv_32_16_perf(void) { +#if defined(ARDUINO_ARCH_AVR) uint16_t iters = 32; uint16_t start_index = UINT16_MAX/3; uint16_t end_index = UINT16_MAX/3*2; @@ -167,10 +172,12 @@ void test_maths_udiv_32_16_perf(void) TEST_ASSERT_INT32_WITHIN(UINT32_MAX/2, comparison.timeA.result, comparison.timeB.result); TEST_ASSERT_LESS_THAN(comparison.timeA.durationMicros, comparison.timeB.durationMicros); +#endif } void test_maths_div100_s16_perf(void) { +#if defined(ARDUINO_ARCH_AVR) constexpr int16_t iters = 1; constexpr int16_t start_index = -10000; constexpr int16_t end_index = -1; @@ -186,11 +193,13 @@ void test_maths_div100_s16_perf(void) TEST_ASSERT_INT32_WITHIN(UINT32_MAX/2, comparison.timeA.result, comparison.timeB.result); TEST_ASSERT_LESS_THAN(comparison.timeA.durationMicros, comparison.timeB.durationMicros); +#endif } void test_maths_div100_s32_perf(void) { +#if defined(ARDUINO_ARCH_AVR) constexpr int32_t iters = 1; constexpr int32_t start_index = -1439190; constexpr int32_t end_index = -1; @@ -206,6 +215,7 @@ void test_maths_div100_s32_perf(void) TEST_ASSERT_INT32_WITHIN(UINT32_MAX/2, comparison.timeA.result, comparison.timeB.result); TEST_ASSERT_LESS_THAN(comparison.timeA.durationMicros, comparison.timeB.durationMicros); +#endif } void testDivision(void) { diff --git a/test/test_math/test_fp_support.cpp b/test/test_math/test_fp_support.cpp index 80e09071..9c732659 100644 --- a/test/test_math/test_fp_support.cpp +++ b/test/test_math/test_fp_support.cpp @@ -1,14 +1,37 @@ +#include +#include #include "test_fp_support.h" -float64_t floatDivision(int32_t a, int32_t b) { +#if defined(ARDUINO_ARCH_AVR) +#include +using test_float_t = float64_t; +#else +using test_float_t = double; +#endif + +test_float_t floatDivision(int32_t a, int32_t b) { +#if defined(ARDUINO_ARCH_AVR) return fp64_div(fp64_int32_to_float64(a), fp64_int32_to_float64(b)); +#else + return (double)a/(double)b; +#endif } -void assert_rounded_div(int32_t a, int32_t b, int32_t actual) { - float64_t fExpected = floatDivision(a, b); - int32_t expected = fp64_lround(fExpected); +int32_t round_float(test_float_t f) { +#if defined(ARDUINO_ARCH_AVR) + return fp64_lround(f); +#else + return round(f); +#endif +} - char msg[64]; - sprintf(msg, "a: %" PRIi32 ", b: %" PRIi32 " fExpected: %s", a, b, fp64_to_string(fExpected, 17, 15)); - TEST_ASSERT_EQUAL_MESSAGE(expected, actual, msg); + +void assert_rounded_div(int32_t a, int32_t b, int32_t actual) { + test_float_t fExpected = floatDivision(a, b); + int32_t expected = round_float(fExpected); + + // char msg[64]; + // sprintf(msg, "a: %" PRIi32 ", b: %" PRIi32 " fExpected: %s", a, b, fp64_to_string(fExpected, 17, 15)); + // TEST_ASSERT_EQUAL_MESSAGE(expected, actual, msg); + TEST_ASSERT_EQUAL(expected, actual); } \ No newline at end of file diff --git a/test/test_math/test_fp_support.h b/test/test_math/test_fp_support.h index d6881b3a..02b04453 100644 --- a/test/test_math/test_fp_support.h +++ b/test/test_math/test_fp_support.h @@ -1,8 +1,4 @@ #pragma once -#include -#include -#include - -float64_t floatDivision(int32_t a, int32_t b); +#include void assert_rounded_div(int32_t a, int32_t b, int32_t actual); \ No newline at end of file diff --git a/test/test_math/tests_percent.cpp b/test/test_math/tests_percent.cpp index c74dd007..e5ae9cd0 100644 --- a/test/test_math/tests_percent.cpp +++ b/test/test_math/tests_percent.cpp @@ -62,6 +62,7 @@ void test_maths_halfpercent_U16(void) void test_maths_halfPercentage_perf(void) { +#if defined(ARDUINO_ARCH_AVR) constexpr int16_t iters = 4; constexpr uint8_t start_index = 3; constexpr uint8_t end_index = 99; @@ -78,11 +79,13 @@ void test_maths_halfPercentage_perf(void) TEST_ASSERT_INT32_WITHIN(UINT32_MAX/2, comparison.timeA.result, comparison.timeB.result); TEST_ASSERT_LESS_THAN(comparison.timeA.durationMicros, comparison.timeB.durationMicros); +#endif } void test_maths_percentage_perf(void) { +#if defined(ARDUINO_ARCH_AVR) constexpr uint16_t iters = 4; constexpr uint8_t start_index = 3; constexpr uint8_t end_index = 99; @@ -99,6 +102,7 @@ void test_maths_percentage_perf(void) TEST_ASSERT_INT32_WITHIN(UINT32_MAX/2, comparison.timeA.result, comparison.timeB.result); TEST_ASSERT_LESS_THAN(comparison.timeA.durationMicros, comparison.timeB.durationMicros); +#endif } void testPercent()