diff --git a/firmware/console/status_loop.cpp b/firmware/console/status_loop.cpp index 110de37fe4..571fa79d52 100644 --- a/firmware/console/status_loop.cpp +++ b/firmware/console/status_loop.cpp @@ -412,8 +412,9 @@ static THD_WORKING_AREA(lcdThreadStack, UTILITY_THREAD_STACK_SIZE); /** * blinking thread to show that we are alive + * that's a trivial task - a smaller stack should work */ -static THD_WORKING_AREA(comBlinkingStack, UTILITY_THREAD_STACK_SIZE); +static THD_WORKING_AREA(blinkingStack, 128); static OutputPin communicationPin; OutputPin checkEnginePin; @@ -446,13 +447,8 @@ static void initialLedsBlink(void) { leds[i]->setValue(0); } -/** - * error thread to show error condition (blinking LED means non-fatal error) - */ -static THD_WORKING_AREA(errBlinkingStack, UTILITY_THREAD_STACK_SIZE); - #if EFI_PROD_CODE || defined(__DOXYGEN__) -static void comBlinkingThread(void *arg) { +static void blinkingThread(void *arg) { (void) arg; chRegSetThreadName("communication blinking"); @@ -468,27 +464,19 @@ static void comBlinkingThread(void *arg) { } communicationPin.setValue(0); + warningPin.setValue(0); chThdSleepMilliseconds(delay); communicationPin.setValue(1); +#if EFI_ENGINE_CONTROL || defined(__DOXYGEN__) + if (isTriggerDecoderError() || isIgnitionTimingError()) + warningPin.setValue(1); +#endif chThdSleepMilliseconds(delay); + } } -static void errBlinkingThread(void *arg) { - (void) arg; - chRegSetThreadName("err blinking"); -#if EFI_ENGINE_CONTROL || defined(__DOXYGEN__) - while (TRUE) { - int delay = 33; - if (isTriggerDecoderError() || isIgnitionTimingError()) - warningPin.setValue(1); - chThdSleepMilliseconds(delay); - warningPin.setValue(0); - chThdSleepMilliseconds(delay); - } -#endif /* EFI_ENGINE_CONTROL */ -} #endif /* EFI_PROD_CODE */ static void lcdThread(Engine *engine) { @@ -630,8 +618,7 @@ void startStatusThreads(Engine *engine) { chThdCreateStatic(lcdThreadStack, sizeof(lcdThreadStack), NORMALPRIO, (tfunc_t) lcdThread, engine); chThdCreateStatic(tsThreadStack, sizeof(tsThreadStack), NORMALPRIO, (tfunc_t) tsStatusThread, engine); #if EFI_PROD_CODE || defined(__DOXYGEN__) - chThdCreateStatic(comBlinkingStack, sizeof(comBlinkingStack), NORMALPRIO, (tfunc_t) comBlinkingThread, NULL); - chThdCreateStatic(errBlinkingStack, sizeof(errBlinkingStack), NORMALPRIO, (tfunc_t) errBlinkingThread, NULL); + chThdCreateStatic(blinkingStack, sizeof(blinkingStack), NORMALPRIO, (tfunc_t) blinkingThread, NULL); #endif /* EFI_PROD_CODE */ } diff --git a/firmware/controllers/core/EfiWave.cpp b/firmware/controllers/core/EfiWave.cpp index 1c15012acb..a4d6e3f571 100644 --- a/firmware/controllers/core/EfiWave.cpp +++ b/firmware/controllers/core/EfiWave.cpp @@ -13,11 +13,11 @@ single_wave_s::single_wave_s() { init(NULL); } -single_wave_s::single_wave_s(int *ps) { +single_wave_s::single_wave_s(pin_state_t *ps) { init(ps); } -void single_wave_s::init(int *pinStates) { +void single_wave_s::init(pin_state_t *pinStates) { this->pinStates = pinStates; } diff --git a/firmware/controllers/core/EfiWave.h b/firmware/controllers/core/EfiWave.h index 4c20d4127d..3208e776c5 100644 --- a/firmware/controllers/core/EfiWave.h +++ b/firmware/controllers/core/EfiWave.h @@ -12,15 +12,24 @@ #define PWM_PHASE_MAX_COUNT 250 #define PWM_PHASE_MAX_WAVE_PER_PWM 3 +/** + * int8_t is probably less efficient then int32_t but we need + * to reduce memory footprint + * + * todo: migrate to bit-array to same memory? but this would + * this would some CPU cycles. see std::vector + */ +typedef int8_t pin_state_t; + /** * @brief PWM configuration for the specific output pin */ class single_wave_s { public: single_wave_s(); - single_wave_s(int *pinStates); - void init(int *pinStates); - int *pinStates; + single_wave_s(pin_state_t *pinStates); + void init(pin_state_t *pinStates); + pin_state_t *pinStates; }; class TriggerShape; diff --git a/firmware/controllers/system/pwm_generator_logic.cpp b/firmware/controllers/system/pwm_generator_logic.cpp index 5ab1df7841..41e79ef11c 100644 --- a/firmware/controllers/system/pwm_generator_logic.cpp +++ b/firmware/controllers/system/pwm_generator_logic.cpp @@ -18,8 +18,8 @@ #define ITERATION_LIMIT 1000 SimplePwm::SimplePwm() { - wave.init(pinStates); - sr[0] = wave; + waveInstance.init(pinStates); + sr[0] = waveInstance; init(_switchTimes, sr); } @@ -148,7 +148,7 @@ static void timerCallback(PwmConfig *state) { * Incoming parameters are potentially just values on current stack, so we have to copy * into our own permanent storage, right? */ -void copyPwmParameters(PwmConfig *state, int phaseCount, float *switchTimes, int waveCount, int **pinStates) { +void copyPwmParameters(PwmConfig *state, int phaseCount, float *switchTimes, int waveCount, pin_state_t **pinStates) { state->phaseCount = phaseCount; for (int phaseIndex = 0; phaseIndex < phaseCount; phaseIndex++) { @@ -163,7 +163,7 @@ void copyPwmParameters(PwmConfig *state, int phaseCount, float *switchTimes, int } void PwmConfig::weComplexInit(const char *msg, int phaseCount, float *switchTimes, int waveCount, - int **pinStates, pwm_cycle_callback *cycleCallback, pwm_gen_callback *stateChangeCallback) { + pin_state_t **pinStates, pwm_cycle_callback *cycleCallback, pwm_gen_callback *stateChangeCallback) { efiAssertVoid(periodNt != 0, "period is not initialized"); if (phaseCount == 0) { diff --git a/firmware/controllers/system/pwm_generator_logic.h b/firmware/controllers/system/pwm_generator_logic.h index cd69c1198e..e4f57fe745 100644 --- a/firmware/controllers/system/pwm_generator_logic.h +++ b/firmware/controllers/system/pwm_generator_logic.h @@ -46,7 +46,7 @@ public: void init(float *switchTimes, single_wave_s *waves); void weComplexInit(const char *msg, - int phaseCount, float *swithcTimes, int waveCount, int **pinStates, + int phaseCount, float *swithcTimes, int waveCount, pin_state_t **pinStates, pwm_cycle_callback *cycleCallback, pwm_gen_callback *callback); @@ -87,13 +87,14 @@ class SimplePwm : public PwmConfig { public: SimplePwm(); void setSimplePwmDutyCycle(float dutyCycle); - int pinStates[2]; - single_wave_s wave; + pin_state_t pinStates[2]; single_wave_s sr[1]; float _switchTimes[2]; +private: + single_wave_s waveInstance; }; void copyPwmParameters(PwmConfig *state, int phaseCount, float *switchTimes, - int waveCount, int **pinStates); + int waveCount, pin_state_t **pinStates); #endif /* PWM_GENERATOR_LOGIC_H_ */ diff --git a/firmware/controllers/trigger/trigger_emulator_algo.cpp b/firmware/controllers/trigger/trigger_emulator_algo.cpp index 337b16114f..503a34189a 100644 --- a/firmware/controllers/trigger/trigger_emulator_algo.cpp +++ b/firmware/controllers/trigger/trigger_emulator_algo.cpp @@ -52,9 +52,9 @@ EXTERN_ENGINE; * todo: should we simply re-use instances used by trigger_decoder? * todo: since we are emulating same shape we are decoding */ -static int pinStates1[PWM_PHASE_MAX_COUNT]; -static int pinStates2[PWM_PHASE_MAX_COUNT]; -static int pinStates3[PWM_PHASE_MAX_COUNT]; +static pin_state_t pinStates1[PWM_PHASE_MAX_COUNT]; +static pin_state_t pinStates2[PWM_PHASE_MAX_COUNT]; +static pin_state_t pinStates3[PWM_PHASE_MAX_COUNT]; static single_wave_s waves[PWM_PHASE_MAX_WAVE_PER_PWM] = { single_wave_s(pinStates1), single_wave_s(pinStates2), single_wave_s(pinStates3) }; static single_wave_s sr[PWM_PHASE_MAX_WAVE_PER_PWM] = { waves[0], waves[1], waves[2] }; @@ -96,7 +96,7 @@ static void updateTriggerShapeIfNeeded(PwmConfig *state) { applyNonPersistentConfiguration(logger, engine); TriggerShape *s = &engine->triggerShape; - int *pinStates[PWM_PHASE_MAX_WAVE_PER_PWM] = { s->wave.waves[0].pinStates, s->wave.waves[1].pinStates, + pin_state_t *pinStates[PWM_PHASE_MAX_WAVE_PER_PWM] = { s->wave.waves[0].pinStates, s->wave.waves[1].pinStates, s->wave.waves[2].pinStates }; copyPwmParameters(state, s->getSize(), s->wave.switchTimes, PWM_PHASE_MAX_WAVE_PER_PWM, pinStates); state->safe.periodNt = -1; // this would cause loop re-initialization @@ -137,7 +137,7 @@ void initTriggerEmulatorLogic(Logging *sharedLogger, Engine *engine) { TriggerShape *s = &engine->triggerShape; setTriggerEmulatorRPM(engineConfiguration->bc.triggerSimulatorFrequency, engine); - int *pinStates[PWM_PHASE_MAX_WAVE_PER_PWM] = { s->wave.waves[0].pinStates, s->wave.waves[1].pinStates, + pin_state_t *pinStates[PWM_PHASE_MAX_WAVE_PER_PWM] = { s->wave.waves[0].pinStates, s->wave.waves[1].pinStates, s->wave.waves[2].pinStates }; triggerSignal.weComplexInit("position sensor", s->getSize(), s->wave.switchTimes, PWM_PHASE_MAX_WAVE_PER_PWM, pinStates, updateTriggerShapeIfNeeded, emulatorApplyPinState); diff --git a/firmware/controllers/trigger/trigger_structure.h b/firmware/controllers/trigger/trigger_structure.h index f3cd104491..ed0b7e2006 100644 --- a/firmware/controllers/trigger/trigger_structure.h +++ b/firmware/controllers/trigger/trigger_structure.h @@ -19,7 +19,7 @@ class TriggerShape; #define TRIGGER_CHANNEL_COUNT 3 class trigger_shape_helper { - int pinStates[TRIGGER_CHANNEL_COUNT][PWM_PHASE_MAX_COUNT]; + pin_state_t pinStates[TRIGGER_CHANNEL_COUNT][PWM_PHASE_MAX_COUNT]; public: trigger_shape_helper(); diff --git a/firmware/hw_layer/microsecond_timer.c b/firmware/hw_layer/microsecond_timer.c index ce210c3d7c..6c89d2dae4 100644 --- a/firmware/hw_layer/microsecond_timer.c +++ b/firmware/hw_layer/microsecond_timer.c @@ -31,6 +31,12 @@ static volatile int timerRestartCounter = 0; schfunc_t globalTimerCallback; +static THD_WORKING_AREA(mwThreadStack, UTILITY_THREAD_STACK_SIZE); + +static const char * msg; + +static char buff[32]; + /** * sets the alarm to the specified number of microseconds from now. * This function should be invoked under kernel lock which would disable interrupts. @@ -72,29 +78,27 @@ static void callback(GPTDriver *gptp) { globalTimerCallback(NULL); } -static THD_WORKING_AREA(mwThreadStack, UTILITY_THREAD_STACK_SIZE); +static void usTimerWatchDog(void) { + if (getTimeNowNt() >= lastSetTimerTimeNt + 2 * CORE_CLOCK) { + strcpy(buff, "no_event"); + itoa10(&buff[8], lastSetTimerValue); + firmwareError(buff); + return; + } -static const char * msg; + msg = isTimerPending ? "No_cb too long" : "Timer not awhile"; + // 2 seconds of inactivity would not look right + efiAssert(getTimeNowNt() < lastSetTimerTimeNt + 2 * CORE_CLOCK, msg, -1); -static char buff[32]; +} static msg_t mwThread(int param) { (void)param; chRegSetThreadName("timer watchdog"); - while (TRUE) { + while (true) { chThdSleepMilliseconds(1000); // once a second is enough - - if (getTimeNowNt() >= lastSetTimerTimeNt + 2 * CORE_CLOCK) { - strcpy(buff, "no_event"); - itoa10(&buff[8], lastSetTimerValue); - firmwareError(buff); - return -1; - } - - msg = isTimerPending ? "No_cb too long" : "Timer not awhile"; - // 2 seconds of inactivity would not look right - efiAssert(getTimeNowNt() < lastSetTimerTimeNt + 2 * CORE_CLOCK, msg, -1); + usTimerWatchDog(); } #if defined __GNUC__ return -1; diff --git a/firmware/hw_layer/pwm_generator.cpp b/firmware/hw_layer/pwm_generator.cpp index 02b27caaad..f9ed9d25b2 100644 --- a/firmware/hw_layer/pwm_generator.cpp +++ b/firmware/hw_layer/pwm_generator.cpp @@ -36,9 +36,9 @@ void startSimplePwm(PwmConfig *state, const char *msg, OutputPin *output, float efiAssertVoid(dutyCycle >= 0 && dutyCycle <= 1, "dutyCycle"); float switchTimes[] = { dutyCycle, 1 }; - int pinStates0[] = { 0, 1 }; + pin_state_t pinStates0[] = { 0, 1 }; - int *pinStates[1] = { pinStates0 }; + pin_state_t *pinStates[1] = { pinStates0 }; state->outputPins[0] = output; diff --git a/firmware/rusefi.cpp b/firmware/rusefi.cpp index 56ba49b9e2..860bb959de 100644 --- a/firmware/rusefi.cpp +++ b/firmware/rusefi.cpp @@ -253,7 +253,7 @@ void firmwareError(const char *fmt, ...) { } } -static char UNUSED_RAM_SIZE[7500]; +static char UNUSED_RAM_SIZE[10500]; static char UNUSED_CCM_SIZE[8000] CCM_OPTIONAL;