From de303ed99494df890841d03ebee4576a4fa69587 Mon Sep 17 00:00:00 2001 From: Andrey B Date: Sat, 26 Apr 2014 09:09:26 -0500 Subject: [PATCH] sync --- firmware/config/boards/arro_board.h | 4 +- firmware/console/tunerstudio/tunerstudio.c | 10 +- firmware/controllers/algo/event_queue.cpp | 37 +- firmware/controllers/algo/event_queue.h | 9 +- firmware/controllers/algo/signal_executor.c | 16 +- firmware/controllers/algo/signal_executor.h | 8 +- .../algo/signal_executor_single_timer_algo.c | 2 +- firmware/controllers/algo/trigger_decoder.cpp | 203 ---------- firmware/controllers/algo/trigger_decoder.h | 35 -- firmware/controllers/algo/trigger_mazda.c | 58 --- firmware/controllers/algo/trigger_mazda.h | 24 -- firmware/controllers/algo/trigger_structure.c | 60 --- firmware/controllers/algo/trigger_structure.h | 106 ------ firmware/controllers/algo/wave_chart.c | 5 +- firmware/controllers/engine_controller.c | 221 ----------- firmware/controllers/math/efitime.h | 24 ++ firmware/controllers/math/engine_math.cpp | 15 +- firmware/controllers/math/engine_math.h | 3 +- firmware/controllers/settings.c | 359 ------------------ .../system/SingleTimerExecutor.cpp | 62 ++- .../controllers/system/SingleTimerExecutor.h | 13 +- .../controllers/system/pwm_generator_logic.c | 63 +-- .../controllers/system/pwm_generator_logic.h | 7 +- .../system/signal_executor_sleep.c | 8 +- firmware/controllers/system/signal_temp.c | 74 ---- firmware/controllers/system/signal_temp.h | 23 -- firmware/controllers/system/system.mk | 1 - .../system/trigger_emulator_algo.cpp | 8 +- .../trigger/main_trigger_callback.cpp | 11 +- firmware/controllers/trigger/rpm_calculator.c | 42 +- firmware/controllers/trigger/rpm_calculator.h | 6 +- .../controllers/trigger/trigger_central.c | 10 +- .../controllers/trigger/trigger_decoder.cpp | 6 +- .../controllers/trigger/trigger_decoder.h | 2 +- .../controllers/trigger/trigger_structure.h | 5 +- firmware/emulation/rfi_perftest.c | 181 --------- firmware/main.cpp | 3 + firmware/main.h | 10 - firmware/rusefi.cpp | 2 +- firmware/util/efilib.c | 75 ---- 40 files changed, 217 insertions(+), 1594 deletions(-) delete mode 100644 firmware/controllers/algo/trigger_decoder.cpp delete mode 100644 firmware/controllers/algo/trigger_decoder.h delete mode 100644 firmware/controllers/algo/trigger_mazda.c delete mode 100644 firmware/controllers/algo/trigger_mazda.h delete mode 100644 firmware/controllers/algo/trigger_structure.c delete mode 100644 firmware/controllers/algo/trigger_structure.h delete mode 100644 firmware/controllers/engine_controller.c delete mode 100644 firmware/controllers/settings.c delete mode 100644 firmware/controllers/system/signal_temp.c delete mode 100644 firmware/controllers/system/signal_temp.h delete mode 100644 firmware/emulation/rfi_perftest.c delete mode 100644 firmware/util/efilib.c diff --git a/firmware/config/boards/arro_board.h b/firmware/config/boards/arro_board.h index e8c6394f10..0e572ef8d1 100644 --- a/firmware/config/boards/arro_board.h +++ b/firmware/config/boards/arro_board.h @@ -263,9 +263,9 @@ #define LED_COMMUNICATION_PORT GPIOD #define LED_COMMUNICATION_PIN GPIOD_LED6 -#define EFI_SIGNAL_EXECUTOR_SLEEP TRUE +#define EFI_SIGNAL_EXECUTOR_SLEEP FALSE #define EFI_SIGNAL_EXECUTOR_SINGLE_TIMER FALSE -#define EFI_SIGNAL_EXECUTOR_ONE_TIMER FALSE +#define EFI_SIGNAL_EXECUTOR_ONE_TIMER TRUE #define EFI_SIGNAL_EXECUTOR_HW_TIMER FALSE //#define EFI_SIGNAL_EXECUTOR_SLEEP FALSE diff --git a/firmware/console/tunerstudio/tunerstudio.c b/firmware/console/tunerstudio/tunerstudio.c index 4856653e47..23ad3852f0 100644 --- a/firmware/console/tunerstudio/tunerstudio.c +++ b/firmware/console/tunerstudio/tunerstudio.c @@ -50,7 +50,7 @@ extern FlashState flashState; extern SerialUSBDriver SDU1; #define CONSOLE_DEVICE &SDU1 -int previousWriteReport = 0; +static efitimems_t previousWriteReportMs = 0; #if EFI_TUNER_STUDIO_OVER_USB #define ts_serail_ready() is_usb_serial_ready() @@ -150,9 +150,9 @@ void handleValueWriteCommand(void) { // unsigned char value = writeBuffer[1]; // - int now = chTimeNow(); - if (overflowDiff(now, previousWriteReport) > 5 * TICKS_IN_MS) { - previousWriteReport = now; + efitimems_t nowMs = currentTimeMillis(); + if (nowMs - previousWriteReportMs > 5) { + previousWriteReportMs = nowMs; // scheduleMsg(&logger, "page %d offset %d: value=%d", pageId, writeRequest.offset, writeRequest.value); } @@ -218,7 +218,7 @@ static msg_t tsThreadEntryPoint(void *arg) { } if (!wasReady) { wasReady = TRUE; -// scheduleSimpleMsg(&logger, "ts channel is now ready ", chTimeNow()); +// scheduleSimpleMsg(&logger, "ts channel is now ready ", hTimeNow()); } short command = (short) chSequentialStreamGet(TS_SERIAL_DEVICE); diff --git a/firmware/controllers/algo/event_queue.cpp b/firmware/controllers/algo/event_queue.cpp index c8dd8d6356..9896fea3bf 100644 --- a/firmware/controllers/algo/event_queue.cpp +++ b/firmware/controllers/algo/event_queue.cpp @@ -1,5 +1,11 @@ /** * @file event_queue.cpp + * This is a data structure which keeps track of all pending events + * Implemented as a linked list, which is fine since the number of + * pending events is pretty low + * todo: MAYBE migrate to a better data structure, but that's low priority + * + * this data structure is NOT thread safe * * @date Apr 17, 2014 * @author Andrey Belomutskiy, (c) 2012-2014 @@ -13,8 +19,7 @@ EventQueue::EventQueue() { head = NULL; } -void EventQueue::schedule(scheduling_s *scheduling, uint64_t nowUs, int delayUs, - schfunc_t callback, void *param) { +void EventQueue::insertTask(scheduling_s *scheduling, uint64_t nowUs, int delayUs, schfunc_t callback, void *param) { if (callback == NULL) firmwareError("NULL callback"); uint64_t time = nowUs + delayUs; @@ -37,34 +42,40 @@ void EventQueue::schedule(scheduling_s *scheduling, uint64_t nowUs, int delayUs, LL_PREPEND(head, scheduling); } -void EventQueue::schedule(scheduling_s *scheduling, int delayUs, - schfunc_t callback, void *param) { - schedule(scheduling, getTimeNowUs(), delayUs, callback, param); +void EventQueue::insertTask(scheduling_s *scheduling, int delayUs, schfunc_t callback, void *param) { + insertTask(scheduling, getTimeNowUs(), delayUs, callback, param); } -uint64_t EventQueue::getNextEventTime(void) { +/** + * Get the timestamp of the soonest pending action + */ +uint64_t EventQueue::getNextEventTime(uint64_t nowUs) { scheduling_s * elt; // this is a large value which is expected to be larger than any real time uint64_t result = EMPTY_QUEUE; LL_FOREACH(head, elt) { + if (elt->momentUs <= nowUs) { + // todo: I am not so sure about this branch + continue; + } if (elt->momentUs < result) result = elt->momentUs; - } return result; } -void EventQueue::execute(uint64_t now) { +/** + * Invoke all pending actions prior to specified timestamp + */ +void EventQueue::executeAll(uint64_t now) { scheduling_s * elt, *tmp; -// DL_FOREACH_SAFE() - // here we need safe iteration because we are removing elements LL_FOREACH_SAFE(head, elt, tmp) { - if (elt->momentUs < now) { + if (elt->momentUs <= now) { LL_DELETE(head, elt); #if EFI_SIGNAL_EXECUTOR_ONE_TIMER elt->callback(elt->param); @@ -72,3 +83,7 @@ void EventQueue::execute(uint64_t now) { } } } + +void EventQueue::clear(void) { + head = NULL; +} diff --git a/firmware/controllers/algo/event_queue.h b/firmware/controllers/algo/event_queue.h index 05674ea7d4..bfa68228be 100644 --- a/firmware/controllers/algo/event_queue.h +++ b/firmware/controllers/algo/event_queue.h @@ -16,12 +16,13 @@ class EventQueue { public: EventQueue(); - void schedule(scheduling_s *scheduling, int delayUs, schfunc_t callback, void *param); - void schedule(scheduling_s *scheduling, uint64_t nowUs, int delayUs, schfunc_t callback, void *param); + void insertTask(scheduling_s *scheduling, int delayUs, schfunc_t callback, void *param); + void insertTask(scheduling_s *scheduling, uint64_t nowUs, int delayUs, schfunc_t callback, void *param); - void execute(uint64_t now); + void executeAll(uint64_t now); - uint64_t getNextEventTime(void); + uint64_t getNextEventTime(uint64_t nowUs); + void clear(void); private: scheduling_s *head; }; diff --git a/firmware/controllers/algo/signal_executor.c b/firmware/controllers/algo/signal_executor.c index 050b639cb3..8c915bbf48 100644 --- a/firmware/controllers/algo/signal_executor.c +++ b/firmware/controllers/algo/signal_executor.c @@ -51,13 +51,13 @@ void initSignalExecutor(void) { void initOutputSignalBase(OutputSignal *signal) { signal->status = IDLE; - signal->last_scheduling_time = 0; +// signal->last_scheduling_time = 0; signal->initialized = TRUE; } static void turnHigh(OutputSignal *signal) { #if EFI_DEFAILED_LOGGING - signal->hi_time = chTimeNow(); +// signal->hi_time = hTimeNow(); #endif /* EFI_DEFAILED_LOGGING */ io_pin_e pin = signal->io_pin; // turn the output level ACTIVE @@ -69,7 +69,7 @@ static void turnHigh(OutputSignal *signal) { if( pin == SPARKOUT_1_OUTPUT || pin == SPARKOUT_3_OUTPUT) { -// time_t now = chTimeNow(); +// time_t now = hTimeNow(); // float an = getCrankshaftAngle(now); // scheduleMsg(&logger, "spark up%d %d", pin, now); // scheduleMsg(&logger, "spark angle %d %f", (int)an, an); @@ -87,7 +87,7 @@ static void turnLow(OutputSignal *signal) { setOutputPinValue(signal->io_pin, FALSE); #if EFI_DEFAILED_LOGGING - systime_t after = chTimeNow(); + systime_t after = hTimeNow(); debugInt(&signal->logging, "a_time", after - signal->hi_time); scheduleLogging(&signal->logging); #endif /* EFI_DEFAILED_LOGGING */ @@ -107,7 +107,7 @@ static void turnLow(OutputSignal *signal) { int getRevolutionCounter(void); -void scheduleOutput(OutputSignal *signal, float delayMs, float durationMs, time_t now) { +void scheduleOutput(OutputSignal *signal, float delayMs, float durationMs) { if (durationMs < 0) { firmwareError("duration cannot be negative: %d", durationMs); return; @@ -119,10 +119,10 @@ void scheduleOutput(OutputSignal *signal, float delayMs, float durationMs, time_ scheduling_s * sUp = &signal->signalTimerUp[index]; scheduling_s * sDown = &signal->signalTimerDown[index]; - scheduleTask(sUp, TICKS_IN_MS * delayMs, (schfunc_t) &turnHigh, (void *) signal); - scheduleTask(sDown, TICKS_IN_MS * (delayMs + durationMs), (schfunc_t) &turnLow, (void*)signal); + scheduleTask(sUp, MS2US(delayMs), (schfunc_t) &turnHigh, (void *) signal); + scheduleTask(sDown, MS2US(delayMs + durationMs), (schfunc_t) &turnLow, (void*)signal); - signal->last_scheduling_time = now; +// signal->last_scheduling_time = now; } void scheduleOutputBase(OutputSignal *signal, float delayMs, float durationMs) { diff --git a/firmware/controllers/algo/signal_executor.h b/firmware/controllers/algo/signal_executor.h index ac51861398..ee03775993 100644 --- a/firmware/controllers/algo/signal_executor.h +++ b/firmware/controllers/algo/signal_executor.h @@ -69,8 +69,8 @@ struct OutputSignal_struct { #endif int initialized; - time_t last_scheduling_time; - time_t hi_time; +// time_t last_scheduling_time; +// time_t hi_time; /** * We are alternating instances so that events which extend into next revolution are not overriden while @@ -95,13 +95,13 @@ extern "C" #endif /* __cplusplus */ void initOutputSignal(OutputSignal *signal, io_pin_e ioPin); -void scheduleOutput(OutputSignal *signal, float delayMs, float durationMs, time_t now); +void scheduleOutput(OutputSignal *signal, float delayMs, float durationMs); void initOutputSignalBase(OutputSignal *signal); void scheduleOutputBase(OutputSignal *signal, float delayMs, float durationMs); void initSignalExecutor(void); void initSignalExecutorImpl(void); -void scheduleTask(scheduling_s *scheduling, float delay, schfunc_t callback, void *param); +void scheduleTask(scheduling_s *scheduling, int delayUs, schfunc_t callback, void *param); void scheduleByAngle(scheduling_s *timer, float angle, schfunc_t callback, void *param); #ifdef __cplusplus diff --git a/firmware/controllers/algo/signal_executor_single_timer_algo.c b/firmware/controllers/algo/signal_executor_single_timer_algo.c index e073f1e4ec..f18747c00c 100644 --- a/firmware/controllers/algo/signal_executor_single_timer_algo.c +++ b/firmware/controllers/algo/signal_executor_single_timer_algo.c @@ -66,7 +66,7 @@ inline time_t toggleSignalIfNeeded(OutputSignal *out, time_t now) { // addWaveChartEvent(out->name, out->status ? "up" : "down", ""); #endif /* EFI_WAVE_ANALYZER */ - out->last_scheduling_time = now; /* store last update */ +// out->last_scheduling_time = now; /* store last update */ estimated = now + GET_DURATION(out); /* update estimation */ } return estimated - now; diff --git a/firmware/controllers/algo/trigger_decoder.cpp b/firmware/controllers/algo/trigger_decoder.cpp deleted file mode 100644 index 047b69485e..0000000000 --- a/firmware/controllers/algo/trigger_decoder.cpp +++ /dev/null @@ -1,203 +0,0 @@ -/** - * @file trigger_decoder.c - * - * @date Dec 24, 2013 - * @author Andrey Belomutskiy, (c) 2012-2014 - * - * This file is part of rusEfi - see http://rusefi.com - * - * rusEfi is free software; you can redistribute it and/or modify it under the terms of - * the GNU General Public License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with this program. - * If not, see . - */ - -#include "main.h" -#include "trigger_decoder.h" -#include "cyclic_buffer.h" -extern "C" -{ -#include "trigger_mazda.h" -} - -#if EFI_PROD_CODE || EFI_SIMULATOR -static Logging logger; -#endif - -static cyclic_buffer errorDetection; - -/** - * @return TRUE is something is wrong with trigger decoding - */ -int isTriggerDecoderError(void) { - return errorDetection.sum(6) > 4; -} - -static inline int isSynchronizationGap(trigger_state_s *shaftPositionState, trigger_shape_s *triggerShape, - trigger_config_s *triggerConfig, int currentDuration) { - if (!triggerConfig->isSynchronizationNeeded) - return FALSE; - - return currentDuration > shaftPositionState->toothed_previous_duration * triggerConfig->syncRatioFrom - && currentDuration < shaftPositionState->toothed_previous_duration * triggerConfig->syncRatioTo; -} - -static inline int noSynchronizationResetNeeded(trigger_state_s *shaftPositionState, trigger_shape_s *triggerShape, - trigger_config_s *triggerConfig) { - if (triggerConfig->isSynchronizationNeeded) - return FALSE; - if (!shaftPositionState->shaft_is_synchronized) - return TRUE; - /** - * in case of noise the counter could be above the expected number of events - */ - return shaftPositionState->current_index >= triggerShape->shaftPositionEventCount - 1; -} - -/** - * @brief This method changes the state of trigger_state_s data structure according to the trigger event - */ -void processTriggerEvent(trigger_state_s *shaftPositionState, trigger_shape_s *triggerShape, - trigger_config_s *triggerConfig, ShaftEvents signal, time_t now) { - - int isLessImportant = (triggerConfig->useRiseEdge && signal != SHAFT_PRIMARY_UP) - || (!triggerConfig->useRiseEdge && signal != SHAFT_PRIMARY_DOWN); - - if (isLessImportant) { - /** - * For less important events we simply increment the index. - */ - shaftPositionState->current_index++; - return; - } - - int currentDuration = now - shaftPositionState->toothed_previous_time; - -// todo: skip a number of signal from the beginning - -#if EFI_PROD_CODE -// scheduleMsg(&logger, "from %f to %f %d %d", triggerConfig->syncRatioFrom, triggerConfig->syncRatioTo, currentDuration, shaftPositionState->toothed_previous_duration); -// scheduleMsg(&logger, "ratio %f", 1.0 * currentDuration/ shaftPositionState->toothed_previous_duration); -#else - if (shaftPositionState->toothed_previous_duration != 0) { -// printf("ratio %f: cur=%d pref=%d\r\n", 1.0 * currentDuration / shaftPositionState->toothed_previous_duration, -// currentDuration, shaftPositionState->toothed_previous_duration); - } -#endif - - if (noSynchronizationResetNeeded(shaftPositionState, triggerShape, triggerConfig) - || isSynchronizationGap(shaftPositionState, triggerShape, triggerConfig, currentDuration)) { - /** - * We can check if things are fine by comparing the number of events in a cycle with the expected number of event. - */ - int isDecodingError = shaftPositionState->current_index != triggerShape->shaftPositionEventCount - 1; - errorDetection.add(isDecodingError); - - shaftPositionState->shaft_is_synchronized = TRUE; - shaftPositionState->current_index = 0; - } else { - shaftPositionState->current_index++; - } - - shaftPositionState->toothed_previous_duration = currentDuration; - shaftPositionState->toothed_previous_time = now; - -} - -static void initializeSkippedToothTriggerShape(trigger_shape_s *s, int totalTeethCount, int skippedCount) { - triggerShapeInit(s); - - float toothWidth = 0.5; - - for (int i = 0; i < totalTeethCount - skippedCount - 1; i++) { - float angleDown = 720.0 / totalTeethCount * (i + toothWidth); - float angleUp = 720.0 / totalTeethCount * (i + 1); - triggerAddEvent(s, angleDown, T_PRIMARY, TV_HIGH); - triggerAddEvent(s, angleUp, T_PRIMARY, TV_LOW); - } - - float angleDown = 720.0 / totalTeethCount * (totalTeethCount - skippedCount - 1 + toothWidth); - triggerAddEvent(s, angleDown, T_PRIMARY, TV_HIGH); - triggerAddEvent(s, 720, T_PRIMARY, TV_LOW); -} - -void initializeSkippedToothTriggerShapeExt(engine_configuration2_s *engineConfiguration2, int totalTeethCount, - int skippedCount) { - trigger_shape_s *s = &engineConfiguration2->triggerShape; - initializeSkippedToothTriggerShape(s, totalTeethCount, skippedCount); - - engineConfiguration2->triggerShape.shaftPositionEventCount = ((totalTeethCount - skippedCount) * 2); - checkSwitchTimes(s->size, s->wave.switchTimes); -} - -static void configureNeonTriggerShape(trigger_shape_s *s) { - triggerShapeInit(s); - - triggerAddEvent(s, 60, T_PRIMARY, TV_HIGH); - triggerAddEvent(s, 210, T_PRIMARY, TV_LOW); - triggerAddEvent(s, 420, T_PRIMARY, TV_HIGH); - triggerAddEvent(s, 630, T_PRIMARY, TV_LOW); - // voodoo magic - we always need 720 at the end - triggerAddEvent(s, 720, T_PRIMARY, TV_LOW); - - s->shaftPositionEventCount = 4; -} - -static void confgiureFordAspireTriggerShape(trigger_shape_s * s) { - triggerShapeInit(s); - - s->shaftPositionEventCount = 10; - - - triggerAddEvent(s, 53.747, T_SECONDARY, TV_HIGH); - triggerAddEvent(s, 121.90, T_SECONDARY, TV_LOW); - triggerAddEvent(s, 232.76, T_SECONDARY, TV_HIGH); - triggerAddEvent(s, 300.54, T_SECONDARY, TV_LOW); - triggerAddEvent(s, 360, T_PRIMARY, TV_HIGH); - - triggerAddEvent(s, 409.8412, T_SECONDARY, TV_HIGH); - triggerAddEvent(s, 478.6505, T_SECONDARY, TV_LOW); - triggerAddEvent(s, 588.045, T_SECONDARY, TV_HIGH); - triggerAddEvent(s, 657.03, T_SECONDARY, TV_LOW); - triggerAddEvent(s, 720, T_PRIMARY, TV_LOW); -} - - -void initializeTriggerShape(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2) { - trigger_config_s *tt = &engineConfiguration->triggerConfig; - switch (tt->triggerType) { - - case TT_TOOTHED_WHEEL: - initializeSkippedToothTriggerShapeExt(engineConfiguration2, tt->totalToothCount, tt->skippedToothCount); - return; - - case TT_MAZDA_MIATA_NB: - initializeMazdaMiataNbShape(&engineConfiguration2->triggerShape); - return; - - case TT_DODGE_NEON: - configureNeonTriggerShape(&engineConfiguration2->triggerShape); - return; - - case TT_FORD_ASPIRE: - confgiureFordAspireTriggerShape(&engineConfiguration2->triggerShape); - return; - - default: - fatal("not implemented") - ; - } -} - -void initTriggerDecoder(void) { -#if EFI_PROD_CODE || EFI_SIMULATOR - initLogging(&logger, "trigger decoder"); -#endif -} - diff --git a/firmware/controllers/algo/trigger_decoder.h b/firmware/controllers/algo/trigger_decoder.h deleted file mode 100644 index c34774efe7..0000000000 --- a/firmware/controllers/algo/trigger_decoder.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * @file trigger_decoder.h - * - * @date Dec 24, 2013 - * @author Andrey Belomutskiy, (c) 2012-2013 - */ - -#ifndef TRIGGER_DECODER_H_ -#define TRIGGER_DECODER_H_ - -#include -#ifdef __cplusplus -extern "C" -{ - -#include "trigger_structure.h" -#include "engine_configuration.h" - -#else - -#include "trigger_structure.h" -#include "engine_configuration.h" - -#endif - - -int isTriggerDecoderError(void); -void processTriggerEvent(trigger_state_s *shaftPositionState, trigger_shape_s *triggerShape, trigger_config_s *triggerConfig, ShaftEvents signal, time_t now); -void initializeSkippedToothTriggerShapeExt(engine_configuration2_s *engineConfiguration2, int totalTeethCount, int skippedCount); -void initializeTriggerShape(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2); -void initTriggerDecoder(void); -#ifdef __cplusplus -} -#endif -#endif /* TRIGGER_DECODER_H_ */ diff --git a/firmware/controllers/algo/trigger_mazda.c b/firmware/controllers/algo/trigger_mazda.c deleted file mode 100644 index 3faf372232..0000000000 --- a/firmware/controllers/algo/trigger_mazda.c +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @file trigger_mazda.c - * - * @date Feb 18, 2014 - * @author Andrey Belomutskiy, (c) 2012-2014 - * - * This file is part of rusEfi - see http://rusefi.com - * - * rusEfi is free software; you can redistribute it and/or modify it under the terms of - * the GNU General Public License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with this program. - * If not, see . - */ - -#include "trigger_mazda.h" - -void initializeMazdaMiataNbShape(trigger_shape_s *s) { - triggerShapeInit(s); - - /** - * cam sensor is primary, crank sensor is secondary - */ - triggerAddEvent(s, 20, T_PRIMARY, TV_LOW); - - triggerAddEvent(s, 66, T_SECONDARY, TV_HIGH); - triggerAddEvent(s, 70, T_SECONDARY, TV_LOW); - triggerAddEvent(s, 136, T_SECONDARY, TV_HIGH); - triggerAddEvent(s, 140, T_SECONDARY, TV_LOW); - triggerAddEvent(s, 246, T_SECONDARY, TV_HIGH); - triggerAddEvent(s, 250, T_SECONDARY, TV_LOW); - triggerAddEvent(s, 316, T_SECONDARY, TV_HIGH); - triggerAddEvent(s, 320, T_SECONDARY, TV_LOW); - - triggerAddEvent(s, 340, T_PRIMARY, TV_HIGH); - triggerAddEvent(s, 360, T_PRIMARY, TV_LOW); - - triggerAddEvent(s, 380, T_PRIMARY, TV_HIGH); - triggerAddEvent(s, 400, T_PRIMARY, TV_LOW); - - triggerAddEvent(s, 426, T_SECONDARY, TV_HIGH); - triggerAddEvent(s, 430, T_SECONDARY, TV_LOW); - triggerAddEvent(s, 496, T_SECONDARY, TV_HIGH); - triggerAddEvent(s, 500, T_SECONDARY, TV_LOW); - triggerAddEvent(s, 606, T_SECONDARY, TV_HIGH); - triggerAddEvent(s, 610, T_SECONDARY, TV_LOW); - triggerAddEvent(s, 676, T_SECONDARY, TV_HIGH); - triggerAddEvent(s, 680, T_SECONDARY, TV_LOW); - - triggerAddEvent(s, 720, T_PRIMARY, TV_HIGH); - - s->shaftPositionEventCount = 6 + 16; -} diff --git a/firmware/controllers/algo/trigger_mazda.h b/firmware/controllers/algo/trigger_mazda.h deleted file mode 100644 index 7221247e7e..0000000000 --- a/firmware/controllers/algo/trigger_mazda.h +++ /dev/null @@ -1,24 +0,0 @@ -/** - * @file trigger_mazda.h - * - * @date Feb 18, 2014 - * @author Andrey Belomutskiy, (c) 2012-2013 - */ - -#ifndef TRIGGER_MAZDA_H_ -#define TRIGGER_MAZDA_H_ - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -#include "trigger_structure.h" - -void initializeMazdaMiataNbShape(trigger_shape_s *s); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* TRIGGER_MAZDA_H_ */ diff --git a/firmware/controllers/algo/trigger_structure.c b/firmware/controllers/algo/trigger_structure.c deleted file mode 100644 index f316541a01..0000000000 --- a/firmware/controllers/algo/trigger_structure.c +++ /dev/null @@ -1,60 +0,0 @@ -/** - * @file trigger_structure.c - * - * @date Jan 20, 2014 - * @author Andrey Belomutskiy, (c) 2012-2014 - * - * This file is part of rusEfi - see http://rusefi.com - * - * rusEfi is free software; you can redistribute it and/or modify it under the terms of - * the GNU General Public License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with this program. - * If not, see . - */ - -#include "main.h" -#include "trigger_structure.h" - -void clearTriggerState(trigger_state_s *state) { - state->shaft_is_synchronized = FALSE; - state->toothed_previous_time = 0; - state->toothed_previous_duration = 0; - state->current_index = 0; -} - -void triggerShapeInit(trigger_shape_s *trigger) { - memset(trigger, 0, sizeof(trigger_shape_s)); -} - -void triggerAddEvent(trigger_shape_s *trigger, float angle, trigger_wheel_e waveIndex, trigger_value_e state) { - angle /= 720; - if (trigger->size == 0) { - trigger->size = 1; - for (int i = 0; i < PWM_PHASE_MAX_WAVE_PER_PWM; i++) - trigger->wave.waves[i].pinStates[0] = 0; - - trigger->wave.switchTimes[0] = angle; - trigger->wave.waves[waveIndex].pinStates[0] = state; - return; - } - -// if(angle!=trigger->wave.switchTimes[trigger->currentIndex]) - - int index = trigger->size++; - - for (int i = 0; i < PWM_PHASE_MAX_WAVE_PER_PWM; i++) - trigger->wave.waves[i].pinStates[index] = trigger->wave.waves[i].pinStates[index - 1]; - trigger->wave.switchTimes[index] = angle; - trigger->wave.waves[waveIndex].pinStates[index] = state; -} - -void checkSwitchTimes(int size, float *switchTimes) { - for (int i = 0; i < size - 1; i++) - chDbgCheck(switchTimes[i] < switchTimes[i + 1], "invalid switchTimes"); -} diff --git a/firmware/controllers/algo/trigger_structure.h b/firmware/controllers/algo/trigger_structure.h deleted file mode 100644 index 6a76ed6150..0000000000 --- a/firmware/controllers/algo/trigger_structure.h +++ /dev/null @@ -1,106 +0,0 @@ -/** - * @file trigger_structure.h - * - * @date Dec 22, 2013 - * @author Andrey Belomutskiy, (c) 2012-2013 - */ - -#ifndef TRIGGER_STRUCTURE_H_ -#define TRIGGER_STRUCTURE_H_ - -#include "rusefi_enums.h" - -#define PWM_PHASE_MAX_COUNT 150 -#define PWM_PHASE_MAX_WAVE_PER_PWM 2 - -typedef enum { - SHAFT_PRIMARY_UP = 0, - SHAFT_PRIMARY_DOWN = 1, - SHAFT_SECONDARY_UP = 2, - SHAFT_SECONDARY_DOWN = 3, -} ShaftEvents; - -typedef struct { - /** - * TRUE if we know where we are - */ - unsigned char shaft_is_synchronized; - - int current_index; - - int toothed_previous_duration; - int toothed_previous_time; - -} trigger_state_s; - -/** - * @brief PWM configuration for the specific output pin - */ -typedef struct { - int pinStates[PWM_PHASE_MAX_COUNT]; -} single_wave_s; - -typedef struct { - /** - * Number of events in the cycle - */ - int phaseCount; - /** - * Number of signal wires - */ - int waveCount; - single_wave_s waves[PWM_PHASE_MAX_WAVE_PER_PWM]; - /** - * values in the (0..1] range which refer to points within the period at at which pin state should be changed - * So, in the simplest case we turn pin off at 0.3 and turn it on at 1 - that would give us a 70% duty cycle PWM - */ - float switchTimes[PWM_PHASE_MAX_COUNT]; -} multi_wave_s; - -typedef enum { - TV_LOW = 0, - TV_HIGH = 1 -} trigger_value_e; - -typedef enum { - T_PRIMARY = 0, - T_SECONDARY = 1 -} trigger_wheel_e; - -/** - * @brief Trigger wheel(s) configuration - */ -typedef struct { - trigger_type_e triggerType; - - int isSynchronizationNeeded; - - int totalToothCount; - int skippedToothCount; - - float syncRatioFrom; - float syncRatioTo; - - int useRiseEdge; - -} trigger_config_s; - -typedef struct { - multi_wave_s wave; - int size; - - /** - * Total count of shaft events per CAM or CRANK shaft revolution. - * TODO this should be migrated to CRANKshaft revolution, this would go together - * TODO with eliminating RPM_MULT magic constant - */ - int shaftPositionEventCount; -} trigger_shape_s; - -void clearTriggerState(trigger_state_s *state); -void triggerShapeInit(trigger_shape_s *trigger); -void triggerAddEvent(trigger_shape_s *trigger, float angle, trigger_wheel_e waveIndex, trigger_value_e state); - -void checkSwitchTimes(int size, float *switchTimes); - -#endif /* TRIGGER_STRUCTURE_H_ */ diff --git a/firmware/controllers/algo/wave_chart.c b/firmware/controllers/algo/wave_chart.c index c42ee09b1a..c2fb005268 100644 --- a/firmware/controllers/algo/wave_chart.c +++ b/firmware/controllers/algo/wave_chart.c @@ -110,7 +110,7 @@ void publishChart(WaveChart *chart) { * @brief Register a change in sniffed signal */ void addWaveChartEvent3(WaveChart *chart, char *name, char * msg, char * msg2) { - chDbgCheck(chart->isInitialized, "chart not initizlied"); + chDbgCheck(chart->isInitialized, "chart not initialized"); #if DEBUG_WAVE scheduleSimpleMsg(&debugLogging, "current", chart->counter); #endif @@ -118,7 +118,8 @@ void addWaveChartEvent3(WaveChart *chart, char *name, char * msg, char * msg2) { return; lockOutputBuffer(); // we have multiple threads writing to the same output buffer appendPrintf(&chart->logging, "%s%s%s%s", name, CHART_DELIMETER, msg, CHART_DELIMETER); - appendPrintf(&chart->logging, "%d%s%s", chTimeNow(), msg2, CHART_DELIMETER); + int time100 = getTimeNowUs() / 10; + appendPrintf(&chart->logging, "%d%s%s", time100, msg2, CHART_DELIMETER); chart->counter++; unlockOutputBuffer(); } diff --git a/firmware/controllers/engine_controller.c b/firmware/controllers/engine_controller.c deleted file mode 100644 index ad4aa3b6a0..0000000000 --- a/firmware/controllers/engine_controller.c +++ /dev/null @@ -1,221 +0,0 @@ -/** - * @file engine_controller.c - * @brief Controllers package entry point code - * - * - * - * @date Feb 7, 2013 - * @author Andrey Belomutskiy, (c) 2012-2014 - * - * This file is part of rusEfi - see http://rusefi.com - * - * rusEfi is free software; you can redistribute it and/or modify it under the terms of - * the GNU General Public License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with this program. - * If not, see . - */ - -#include "main.h" -#include "trigger_central.h" -#include "engine_controller.h" -#include "idle_thread.h" -#include "rpm_calculator.h" -#include "signal_executor.h" -#include "main_trigger_callback.h" -#include "map_multiplier_thread.h" -#include "io_pins.h" -#include "tunerstudio.h" -#include "injector_central.h" -#include "ignition_central.h" -#include "rfiutil.h" -#include "engine_configuration.h" -#include "engine_math.h" -#include "wave_analyzer.h" -#include "allsensors.h" -#include "analog_chart.h" -#include "electronic_throttle.h" -#include "malfunction_indicator.h" -#include "map_averaging.h" -#include "malfunction_central.h" -#include "pin_repository.h" -#include "pwm_generator.h" -#include "adc_inputs.h" -#include "algo.h" - -#define _10_MILLISECONDS (10 * TICKS_IN_MS) - -extern engine_configuration_s *engineConfiguration; - -/** - * CH_FREQUENCY is the number of system ticks in a second - */ -#define FUEL_PUMP_DELAY (4 * CH_FREQUENCY) - -static VirtualTimer everyMsTimer; -static VirtualTimer fuelPumpTimer; - -static Logging logger; - -static engine_configuration2_s ec2; -engine_configuration2_s * engineConfiguration2 = &ec2; - -static void updateStatusLeds(void) { - int is_cranking = isCranking(); - setOutputPinValue(LED_RUNNING, getRpm() > 0 && !is_cranking); - setOutputPinValue(LED_CRANKING, is_cranking); -} - -static void updateErrorCodes(void) { - /** - * technically we can set error codes right inside the getMethods, but I a bit on a fence about it - */ - setError(isValidIntakeAirTemperature(getIntakeAirTemperature()), OBD_Intake_Air_Temperature_Circuit_Malfunction); - setError(isValidCoolantTemperature(getCoolantTemperature()), OBD_Engine_Coolant_Temperature_Circuit_Malfunction); -} - -static void fanRelayControl(void) { - - int isCurrentlyOn = getOutputPinValue(FAN_RELAY); - int newValue; - if (isCurrentlyOn) { - // if the fan is already on, we keep it on till the 'fanOff' temperature - newValue = getCoolantTemperature() > engineConfiguration->fanOffTemperature; - } else { - newValue = getCoolantTemperature() > engineConfiguration->fanOnTemperature; - } - - if (isCurrentlyOn != newValue) { - scheduleMsg(&logger, "FAN relay: %s", newValue ? "ON" : "OFF"); - setOutputPinValue(FAN_RELAY, newValue); - } -} - -static void onEveny10Milliseconds(void *arg) { - updateStatusLeds(); - - updateErrorCodes(); - - fanRelayControl(); - - // schedule next invocation - chVTSetAny(&everyMsTimer, _10_MILLISECONDS, &onEveny10Milliseconds, 0); -} - -static void initPeriodicEvents(void) { - // schedule first invocation - chVTSetAny(&everyMsTimer, _10_MILLISECONDS, &onEveny10Milliseconds, 0); -} - -static void fuelPumpOff(void *arg) { - if (getOutputPinValue(FUEL_PUMP_RELAY)) - scheduleMsg(&logger, "fuelPump OFF at %s%d", portname(FUEL_PUMP_PORT ), FUEL_PUMP_PIN); - turnOutputPinOff(FUEL_PUMP_RELAY); -} - -static void fuelPumpOn(ShaftEvents signal, int index) { - if (index != 0) - return; // let's not abuse the timer - one time per revolution would be enough - if (!getOutputPinValue(FUEL_PUMP_RELAY)) - scheduleMsg(&logger, "fuelPump ON at %s%d", portname(FUEL_PUMP_PORT ), FUEL_PUMP_PIN); - turnOutputPinOn(FUEL_PUMP_RELAY); - /** - * the idea of this implementation is that we turn the pump when the ECU turns on or - * if the shafts are spinning and then we are constantly postponing the time when we - * will turn it off. Only if the shafts stop the turn off would actually happen. - */ - chVTSetAny(&fuelPumpTimer, FUEL_PUMP_DELAY, &fuelPumpOff, 0); -} - -static void initFuelPump(void) { - registerShaftPositionListener(&fuelPumpOn, "fuel pump"); - fuelPumpOn(SHAFT_PRIMARY_UP, 0); -} - - -char * getPinNameByAdcChannel(int hwChannel, uint8_t *buffer) { - strcpy(buffer, portname(getAdcChannelPort(hwChannel))); - itoa10(&buffer[2], getAdcChannelPin(hwChannel)); - return buffer; -} - -static uint8_t pinNameBuffer[16]; - -static void printAnalogChannelInfoExt(char *name, int hwChannel, float voltage) { - scheduleMsg(&logger, "%s ADC%d %s value=%fv", name, hwChannel, getPinNameByAdcChannel(hwChannel, pinNameBuffer), - voltage); -} - -static void printAnalogChannelInfo(char *name, int hwChannel) { - printAnalogChannelInfoExt(name, hwChannel, getVoltageDivided(hwChannel)); -} - -static void printAnalogInfo(void) { - printAnalogChannelInfo("TPS", engineConfiguration->tpsAdcChannel); - printAnalogChannelInfo("CLT", engineConfiguration->cltAdcChannel); - printAnalogChannelInfo("IAT", engineConfiguration->iatAdcChannel); - printAnalogChannelInfo("MAF", engineConfiguration->mafAdcChannel); - printAnalogChannelInfo("AFR", engineConfiguration->afrSensor.afrAdcChannel); - printAnalogChannelInfoExt("Vbatt", engineConfiguration->vBattAdcChannel, getVBatt()); -} - -void initEngineContoller(void) { - initLogging(&logger, "Engine Controller"); - - initSensors(); - - initPwmGenerator(); - - initAnalogChart(); - - initAlgo(); - -#ifdef EFI_WAVE_ANALYZER - initWaveAnalyzer(); -#endif - - /** - * there is an implicit dependency on the fact that 'tachometer' listener is the 1st listener - this case - * other listeners can access current RPM value - */ - initRpmCalculator(); - - -#if EFI_TUNER_STUDIO - startTunerStudioConnectivity(); -#endif - -// multiple issues with this initMapAdjusterThread(); - initPeriodicEvents(); - -#if EFI_SIGNAL_EXECUTOR_SINGLE_TIMER - initOutputScheduler(); -#endif - initInjectorCentral(); - initIgnitionCentral(); - initMalfunctionCentral(); - -#if EFI_ELECTRONIC_THROTTLE_BODY - initElectronicThrottle(); -#endif /* EFI_ELECTRONIC_THROTTLE_BODY */ - initMalfunctionIndicator(); - initMapAveraging(); - - /** - * This method initialized the main listener which actually runs injectors & ignition - */ - initMainEventListener(); - -#if EFI_IDLE_CONTROL - startIdleThread(); -#endif - - initFuelPump(); - - addConsoleAction("analoginfo", printAnalogInfo); -} diff --git a/firmware/controllers/math/efitime.h b/firmware/controllers/math/efitime.h index 0066546b25..fb978a2502 100644 --- a/firmware/controllers/math/efitime.h +++ b/firmware/controllers/math/efitime.h @@ -13,12 +13,24 @@ #include #include "efifeatures.h" +/** + * integer time in milliseconds + * 32 bit 4B / 1000 = 4M seconds = 1111.11 hours = 46 days. + * Please restart your ECU every 46 days? :) + */ +typedef uint32_t efitimems_t; #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ +#define US_PER_SECOND 1000000 + +#define MS2US(MS_TIME) ((MS_TIME) * 1000) + +#define US_TO_TI_TEMP 10 + // todo: implement a function to work with times considering counter overflow #define overflowDiff(now, time) ((now) - (time)) @@ -30,6 +42,18 @@ extern "C" */ uint64_t getTimeNowUs(void); +uint64_t getHalTimer(void); + +/** + * @brief Returns the number of milliseconds since the board initialization. + */ +efitimems_t currentTimeMillis(void); + +/** + * @brief Current system time in seconds. + */ +int getTimeNowSeconds(void); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/firmware/controllers/math/engine_math.cpp b/firmware/controllers/math/engine_math.cpp index bbecf7d4b1..551ebcdd7b 100644 --- a/firmware/controllers/math/engine_math.cpp +++ b/firmware/controllers/math/engine_math.cpp @@ -73,19 +73,10 @@ float getOneDegreeTimeMs(int rpm) { } /** - * @return time needed to rotate crankshaft by one degree, in systicks - * @deprecated use getOneDegreeTimeMs + * @return number of milliseconds in one crankshaft revolution */ -float getOneDegreeTime(int rpm) { - return getOneDegreeTimeMs(rpm) * TICKS_IN_MS; -} - -/** - * @return number of system it needed for one crankshaft revolution, in systicks - * @todo migrate getOneDegreeTimeMs - */ -float getCrankshaftRevolutionTime(int rpm) { - return 360 * getOneDegreeTime(rpm); +float getCrankshaftRevolutionTimeMs(int rpm) { + return 360 * getOneDegreeTimeMs(rpm); } /** diff --git a/firmware/controllers/math/engine_math.h b/firmware/controllers/math/engine_math.h index a78d717b62..08a2bcd819 100644 --- a/firmware/controllers/math/engine_math.h +++ b/firmware/controllers/math/engine_math.h @@ -24,8 +24,7 @@ float getDefaultFuel(int rpm, float map); //float getTCharge(int rpm, int tps, float coolantTemp, float airTemp); float getOneDegreeTimeMs(int rpm); -float getOneDegreeTime(int rpm); -float getCrankshaftRevolutionTime(int rpm); +float getCrankshaftRevolutionTimeMs(int rpm); int isCrankingRT(engine_configuration_s *engineConfiguration, int rpm); #define isCrankingR(rpm) isCrankingRT(engineConfiguration, rpm) diff --git a/firmware/controllers/settings.c b/firmware/controllers/settings.c deleted file mode 100644 index 69ef7db0e3..0000000000 --- a/firmware/controllers/settings.c +++ /dev/null @@ -1,359 +0,0 @@ -/** - * @file settings.c - * @brief This file is about configuring engine via the human-readable protocol - * - * @date Dec 30, 2012 - * @author Andrey Belomutskiy, (c) 2012-2014 - */ - -#include "main.h" -#include "settings.h" - -#include "eficonsole.h" -#include "engine_configuration.h" -#include "flash_main.h" -#include "engine_controller.h" -#include "rusefi.h" -#include "thermistors.h" -#include "adc_inputs.h" -#include "interpolation.h" - -#if EFI_PROD_CODE -#include "pin_repository.h" -#endif /* EFI_PROD_CODE */ - -static Logging logger; - -static char LOGGING_BUFFER[1000]; - -extern engine_configuration_s *engineConfiguration; -extern engine_configuration2_s *engineConfiguration2; - -static void doPrintConfiguration(void) { - printConfiguration(engineConfiguration, engineConfiguration2); -} - -static void printIntArray(int array[], int size) { - for (int j = 0; j < size; j++) - print("%d ", array[j]); - print("\r\n"); -} - -void printFloatArray(char *prefix, float array[], int size) { - appendMsgPrefix(&logger); - appendPrintf(&logger, prefix); - for (int j = 0; j < size; j++) - appendPrintf(&logger, "%f ", array[j]); - appendMsgPostfix(&logger); - scheduleLogging(&logger); -} - -char* getConfigurationName(engine_configuration_s *engineConfiguration) { - switch (engineConfiguration->engineType) { -#if EFI_SUPPORT_DODGE_NEON - case DODGE_NEON_1995: - return "Dodge Neon"; -#endif /* EFI_SUPPORT_DODGE_NEON */ -#if EFI_SUPPORT_FORD_ASPIRE - case FORD_ASPIRE_1996: - return "Ford Aspire"; -#endif /* EFI_SUPPORT_FORD_ASPIRE */ -#if EFI_SUPPORT_FORD_FIESTA - case FORD_FIESTA: - return "Ford Fiesta"; -#endif /* EFI_SUPPORT_FORD_FIESTA */ -#if EFI_SUPPORT_NISSAN_PRIMERA - case NISSAN_PRIMERA: - return "Nissan Primera"; -#endif /* EFI_SUPPORT_NISSAN_PRIMERA */ - case HONDA_ACCORD: - return "Honda Accord"; - case FORD_INLINE_6_1995: - return "Ford 1995 inline 6"; - case GY6_139QMB: - return "Gy6 139qmb"; - case MAZDA_MIATA_NB: - return "Mazda Miata NB"; - case MAZDA_323: - return "Mazda 323"; - default: - return NULL; - } -} - -/** - * @brief Prints current engine configuration to human-readable console. - */ -void printConfiguration(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2) { - - scheduleMsg(&logger, getConfigurationName(engineConfiguration)); - - scheduleMsg(&logger, "configurationVersion=%d", getGlobalConfigurationVersion()); - - for (int k = 0; k < FUEL_LOAD_COUNT; k++) { -// print("line %d (%f): ", k, engineConfiguration->fuelKeyBins[k]); -// for (int r = 0; r < FUEL_RPM_COUNT; r++) { -// print("%f ", engineConfiguration->fuelTable[k][r]); -// } -// print("\r\n"); - } - - printFloatArray("RPM bin: ", engineConfiguration->fuelRpmBins, FUEL_RPM_COUNT); - - printFloatArray("Y bin: ", engineConfiguration->fuelLoadBins, FUEL_LOAD_COUNT); - - printFloatArray("CLT: ", engineConfiguration->cltFuelCorr, CLT_CURVE_SIZE); - printFloatArray("CLT bins: ", engineConfiguration->cltFuelCorrBins, CLT_CURVE_SIZE); - - printFloatArray("IAT: ", engineConfiguration->iatFuelCorr, IAT_CURVE_SIZE); - printFloatArray("IAT bins: ", engineConfiguration->iatFuelCorrBins, IAT_CURVE_SIZE); - - printFloatArray("vBatt: ", engineConfiguration->battInjectorLagCorr, VBAT_INJECTOR_CURVE_SIZE); - printFloatArray("vBatt bins: ", engineConfiguration->battInjectorLagCorrBins, VBAT_INJECTOR_CURVE_SIZE); - -// appendMsgPrefix(&logger); - - scheduleMsg(&logger, "rpmHardLimit: %d", engineConfiguration->rpmHardLimit); - scheduleMsg(&logger, "rpmMultiplier=%f", engineConfiguration->rpmMultiplier); - - scheduleMsg(&logger, "tpsMin: %d", engineConfiguration->tpsMin); - scheduleMsg(&logger, "tpsMax: %d", engineConfiguration->tpsMax); - - scheduleMsg(&logger, "timingMode: %d", engineConfiguration->timingMode); - scheduleMsg(&logger, "fixedModeTiming: %d", (int) engineConfiguration->fixedModeTiming); - scheduleMsg(&logger, "crankingChargeAngle=%f", engineConfiguration->crankingChargeAngle); - scheduleMsg(&logger, "globalTriggerAngleOffset=%f", engineConfiguration->globalTriggerAngleOffset); - - scheduleMsg(&logger, "analogChartMode: %d", engineConfiguration->analogChartMode); - - scheduleMsg(&logger, "crankingRpm: %d", engineConfiguration->crankingSettings.crankingRpm); - - scheduleMsg(&logger, "injectionPinMode: %d", engineConfiguration->injectionPinMode); - scheduleMsg(&logger, "ignitionPinMode: %d", engineConfiguration->ignitionPinMode); - scheduleMsg(&logger, "idlePinMode: %d", engineConfiguration->idlePinMode); - scheduleMsg(&logger, "fuelPumpPinMode: %d", engineConfiguration->fuelPumpPinMode); - scheduleMsg(&logger, "malfunctionIndicatorPinMode: %d", engineConfiguration->malfunctionIndicatorPinMode); - scheduleMsg(&logger, "analogInputDividerCoefficient: %f", engineConfiguration->analogInputDividerCoefficient); - -#if EFI_PROD_CODE - // todo: calculate coils count based on ignition mode - for (int i = 0; i < 4; i++) { - brain_pin_e brainPin = engineConfiguration->ignitionPins[i]; - GPIO_TypeDef *hwPort = getHwPort(brainPin); - int hwPin = getHwPin(brainPin); - scheduleMsg(&logger, "ignition %d @ %s%d", i, portname(hwPort), hwPin); - } -#endif /* EFI_PROD_CODE */ - - // appendPrintf(&logger, DELIMETER); -// scheduleLogging(&logger); -} - -static void setFixedModeTiming(int value) { - engineConfiguration->fixedModeTiming = value; - doPrintConfiguration(); -} - -static void setTimingMode(int value) { - engineConfiguration->timingMode = (timing_mode_e) value; - doPrintConfiguration(); -} - -static void setEngineType(int value) { - engineConfiguration->engineType = (engine_type_e) value; - resetConfigurationExt((engine_type_e) value, engineConfiguration, engineConfiguration2); -#if EFI_PROD_CODE - writeToFlash(); - scheduleReset(); -#endif /* EFI_PROD_CODE */ - incrementGlobalConfigurationVersion(); - doPrintConfiguration(); -} - -static void setInjectionPinMode(int value) { - engineConfiguration->injectionPinMode = (pin_output_mode_e) value; - doPrintConfiguration(); -} - -static void setIgnitionPinMode(int value) { - engineConfiguration->ignitionPinMode = (pin_output_mode_e) value; - doPrintConfiguration(); -} - -static void setIdlePinMode(int value) { - engineConfiguration->idlePinMode = (pin_output_mode_e) value; - doPrintConfiguration(); -} - -static void setIgnitionOffset(int value) { - engineConfiguration->ignitionOffset = value; - doPrintConfiguration(); -} - -static void setFuelPumpPinMode(int value) { - engineConfiguration->fuelPumpPinMode = (pin_output_mode_e) value; - doPrintConfiguration(); -} - -static void setMalfunctionIndicatorPinMode(int value) { - engineConfiguration->malfunctionIndicatorPinMode = (pin_output_mode_e) value; - doPrintConfiguration(); -} - -static void setAnalogChartMode(int value) { - engineConfiguration->analogChartMode = value; - doPrintConfiguration(); -} - -static void setRpmMultiplier(int value) { - engineConfiguration->rpmMultiplier = value; - doPrintConfiguration(); -} - -static uint8_t pinNameBuffer[16]; - -static void printThermistor(char *msg, Thermistor *thermistor) { - int adcChannel = thermistor->channel; - float voltage = getVoltageDivided(adcChannel); - float r = getResistance(thermistor); - - float t = getTemperatureC(thermistor); - - scheduleMsg(&logger, "%s v=%f C=%f R=%f on channel %d", msg, voltage, t, r, adcChannel); - scheduleMsg(&logger, "bias=%f A=%f B=%f C=%f", thermistor->config->bias_resistor, thermistor->config->s_h_a, - thermistor->config->s_h_b, thermistor->config->s_h_c); -#if EFI_PROD_CODE - scheduleMsg(&logger, "@%s", getPinNameByAdcChannel(adcChannel, pinNameBuffer)); -#endif -} - -static void printTemperatureInfo(void) { - printThermistor("CLT", &engineConfiguration2->clt); - printThermistor("IAT", &engineConfiguration2->iat); - - float rClt = getResistance(&engineConfiguration2->clt); - float rIat = getResistance(&engineConfiguration2->iat); - -#if EFI_PROD_CODE - int cltChannel = engineConfiguration2->clt.channel; - scheduleMsg(&logger, "CLT R=%f on channel %d@%s", rClt, cltChannel, - getPinNameByAdcChannel(cltChannel, pinNameBuffer)); - int iatChannel = engineConfiguration2->iat.channel; - scheduleMsg(&logger, "IAT R=%f on channel %d@%s", rIat, iatChannel, - getPinNameByAdcChannel(iatChannel, pinNameBuffer)); - - scheduleMsg(&logger, "cranking fuel %fms @ %fC", engineConfiguration->crankingSettings.fuelAtMinTempMs, - engineConfiguration->crankingSettings.coolantTempMinC); - scheduleMsg(&logger, "cranking fuel %fms @ %fC", engineConfiguration->crankingSettings.fuelAtMaxTempMs, - engineConfiguration->crankingSettings.coolantTempMaxC); -#endif -} - -/** - * For example - * set_cranking_fuel_min 15 0 - * would be 15ms @ 0C - */ -static void setCrankingFuleMin(int timeMs, int tempC) { - engineConfiguration->crankingSettings.coolantTempMinC = tempC; - engineConfiguration->crankingSettings.fuelAtMinTempMs = timeMs; - printTemperatureInfo(); -} - -static void setCrankingFuleMax(int timeMs, int tempC) { - engineConfiguration->crankingSettings.coolantTempMaxC = tempC; - engineConfiguration->crankingSettings.fuelAtMaxTempMs = timeMs; - printTemperatureInfo(); -} - -static void setGlobalTriggerAngleOffset(int value) { - engineConfiguration->globalTriggerAngleOffset = value; - doPrintConfiguration(); -} - -static void setGlobalFuelCorrection(float value) { - if (value < 0.01 || value > 50) - return; - scheduleMsg(&logger, "setting fuel mult=%f", value); - engineConfiguration->globalFuelCorrection = value; -} - -static void setWholeTimingMap(float value) { - scheduleMsg(&logger, "Setting whole timing map to %f", value); - for (int l = 0; l < IGN_LOAD_COUNT; l++) { - for (int r = 0; r < IGN_RPM_COUNT; r++) { - engineConfiguration->ignitionTable[l][r] = value; - } - } -} - -static void setWholeFuelMap(float value) { - scheduleMsg(&logger, "Setting whole fuel map to %f", value); - for (int l = 0; l < FUEL_LOAD_COUNT; l++) { - for (int r = 0; r < FUEL_RPM_COUNT; r++) { - engineConfiguration->fuelTable[l][r] = value; - } - } -} - -static void setTimingMap(char * rpmStr, char *loadStr, char *valueStr) { - float rpm = atoff(rpmStr); - float engineLoad = atoff(loadStr); - float value = atoi(valueStr); - - int rpmIndex = findIndex(engineConfiguration->ignitionRpmBins, IGN_RPM_COUNT, rpm); - rpmIndex = rpmIndex < 0 ? 0 : rpmIndex; - int loadIndex = findIndex(engineConfiguration->ignitionLoadBins, IGN_LOAD_COUNT, engineLoad); - loadIndex = loadIndex < 0 ? 0 : loadIndex; - - engineConfiguration->ignitionTable[loadIndex][rpmIndex] = value; - scheduleMsg(&logger, "Setting timing map entry %d:%d to %f", rpmIndex, loadIndex, value); -} - -static void setFuelMap(char * rpmStr, char *loadStr, char *valueStr) { - float rpm = atoff(rpmStr); - float engineLoad = atoff(loadStr); - float value = atoi(valueStr); - - int rpmIndex = findIndex(engineConfiguration->fuelRpmBins, FUEL_RPM_COUNT, rpm); - rpmIndex = rpmIndex < 0 ? 0 : rpmIndex; - int loadIndex = findIndex(engineConfiguration->fuelLoadBins, FUEL_LOAD_COUNT, engineLoad); - loadIndex = loadIndex < 0 ? 0 : loadIndex; - - engineConfiguration->fuelTable[loadIndex][rpmIndex] = value; - scheduleMsg(&logger, "Setting fuel map entry %d:%d to %f", rpmIndex, loadIndex, value); -} - -void initSettings(void) { - initLoggingExt(&logger, "settings control", LOGGING_BUFFER, sizeof(LOGGING_BUFFER)); - - addConsoleAction("showconfig", doPrintConfiguration); - addConsoleAction("tempinfo", printTemperatureInfo); - - addConsoleActionI("set_ignition_offset", setIgnitionOffset); - addConsoleActionI("set_global_trigger_offset_angle", setGlobalTriggerAngleOffset); - addConsoleActionI("set_analog_chart_mode", setAnalogChartMode); - addConsoleActionI("set_fixed_mode_timing", setFixedModeTiming); - addConsoleActionI("set_timing_mode", setTimingMode); - addConsoleActionI("set_engine_type", setEngineType); - - addConsoleActionI("set_injection_pin_mode", setInjectionPinMode); - addConsoleActionI("set_ignition_pin_mode", setIgnitionPinMode); - addConsoleActionI("set_idle_pin_mode", setIdlePinMode); - addConsoleActionI("set_fuel_pump_pin_mode", setFuelPumpPinMode); - addConsoleActionI("set_malfunction_indicator_pin_mode", setMalfunctionIndicatorPinMode); - addConsoleActionI("set_rpm_multiplier", setRpmMultiplier); - // todo: start saving values into flash right away? - - addConsoleActionF("set_global_fuel_correction", setGlobalFuelCorrection); - - addConsoleActionII("set_cranking_fuel_min", setCrankingFuleMin); - addConsoleActionII("set_cranking_fuel_max", setCrankingFuleMax); - - addConsoleActionF("set_whole_fuel_map", setWholeFuelMap); - addConsoleActionSSS("set_fuel_map", setFuelMap); - - addConsoleActionF("set_whole_timing_map", setWholeTimingMap); - addConsoleActionSSS("set_timing_map", setTimingMap); -} - diff --git a/firmware/controllers/system/SingleTimerExecutor.cpp b/firmware/controllers/system/SingleTimerExecutor.cpp index a438aa81a9..adc54d0bfd 100644 --- a/firmware/controllers/system/SingleTimerExecutor.cpp +++ b/firmware/controllers/system/SingleTimerExecutor.cpp @@ -1,13 +1,20 @@ -/* - * SingleTimerExecutor.cpp +/** + * @file SingleTimerExecutor.cpp * - * Created on: Apr 18, 2014 - * Author: Andrey + * This class combines the powers of a 1MHz hardware timer from microsecond_timer.c + * and pending events queue event_queue.cpp + * + * todo: add thread safety + * + * @date: Apr 18, 2014 + * @author Andrey Belomutskiy, (c) 2012-2014 */ #include "SingleTimerExecutor.h" #include "efitime.h" -#include "signal_temp.h" +#if EFI_PROD_CODE +#include "microsecond_timer.h" +#endif #if EFI_SIGNAL_EXECUTOR_ONE_TIMER || defined(__DOXYGEN__) @@ -16,33 +23,62 @@ static Executor instance; extern schfunc_t globalTimerCallback; static void executorCallback(void *arg) { - instance.eq.execute(getTimeNowUs()); + instance.execute(getTimeNowUs()); +} + +void Executor::setTimer(uint64_t nowUs) { + uint64_t nextEventTime = queue.getNextEventTime(nowUs); + setHardwareUsTimer(nextEventTime - nowUs); } Executor::Executor() { } void Executor::schedule(scheduling_s *scheduling, uint64_t nowUs, int delayUs, schfunc_t callback, void *param) { - eq.schedule(scheduling, nowUs, delayUs, callback, param); - uint64_t nextEventTime = eq.getNextEventTime(); - setTimer(nextEventTime - getTimeNowUs()); + queue.insertTask(scheduling, nowUs, delayUs, callback, param); + setTimer(nowUs); } -void scheduleTask(scheduling_s *scheduling, float delayMs, schfunc_t callback, void *param) { +void Executor::execute(uint64_t now) { + /** + * Let's execute actions we should execute at this point + */ + queue.executeAll(now); + /** + * Let's set up the timer for the next execution + */ + setTimer(now); +} + +/** + * @brief Schedule an event + * + * Invokes event callback after the specified amount of time. + * + * @param [in, out] scheduling Data structure to keep this event in the collection. + * @param [in] delayUs the number of microseconds before the output signal immediate output if delay is zero. + * @param [in] dwell the number of ticks of output duration. + */ +void scheduleTask(scheduling_s *scheduling, int delayUs, schfunc_t callback, void *param) { + if (delayUs == 0) { + callback(param); + return; + } // todo: eliminate this /100. Times still come as systick times here - instance.schedule(scheduling, getTimeNowUs(), delayMs * 1000000 / 100000, callback, param); + instance.schedule(scheduling, getTimeNowUs(), delayUs, callback, param); } void initOutputSignal(OutputSignal *signal, io_pin_e ioPin) { signal->io_pin = ioPin; signal->name = getPinName(ioPin); -// signal->duration = 0; initOutputSignalBase(signal); } void initSignalExecutorImpl(void) { globalTimerCallback = executorCallback; - TIM_Init(); +#if EFI_PROD_CODE + initMicrosecondTimer(); +#endif /* EFI_PROD_CODE */ } #endif diff --git a/firmware/controllers/system/SingleTimerExecutor.h b/firmware/controllers/system/SingleTimerExecutor.h index 3d7ce98d3d..b3438640e3 100644 --- a/firmware/controllers/system/SingleTimerExecutor.h +++ b/firmware/controllers/system/SingleTimerExecutor.h @@ -1,8 +1,8 @@ -/* - * SingleTimerExecutor.h +/** + * @file SingleTimerExecutor.h * - * Created on: Apr 18, 2014 - * Author: Andrey + * @date: Apr 18, 2014 + * @author Andrey Belomutskiy, (c) 2012-2014 */ #ifndef SINGLETIMEREXECUTOR_H_ @@ -15,7 +15,10 @@ class Executor { public: Executor(); void schedule(scheduling_s *scheduling, uint64_t nowUs, int delayUs, schfunc_t callback, void *param); - EventQueue eq; + void execute(uint64_t now); +private: + EventQueue queue; + void setTimer(uint64_t now); }; #endif /* SINGLETIMEREXECUTOR_H_ */ diff --git a/firmware/controllers/system/pwm_generator_logic.c b/firmware/controllers/system/pwm_generator_logic.c index 6d4c54e2d5..72836aa403 100644 --- a/firmware/controllers/system/pwm_generator_logic.c +++ b/firmware/controllers/system/pwm_generator_logic.c @@ -8,46 +8,46 @@ #include "pwm_generator_logic.h" #include "engine_math.h" -static time_t getNextSwitchTime(PwmConfig *state) { +static uint64_t getNextSwitchTimeUs(PwmConfig *state) { chDbgAssert(state->safe.phaseIndex < PWM_PHASE_MAX_COUNT, "phaseIndex range", NULL); int iteration = state->safe.iteration; float switchTime = state->multiWave.switchTimes[state->safe.phaseIndex]; - float period = state->safe.period; + float periodMs = state->safe.periodMs; #if DEBUG_PWM scheduleMsg(&logger, "iteration=%d switchTime=%f period=%f", iteration, switchTime, period); #endif - systime_t timeToSwitch = (systime_t) ((iteration + switchTime) * period); + uint64_t timeToSwitchUs = (iteration + switchTime) * periodMs * 1000; #if DEBUG_PWM scheduleMsg(&logger, "start=%d timeToSwitch=%d", state->safe.start, timeToSwitch); #endif - return state->safe.start + timeToSwitch; + return state->safe.startUs + timeToSwitchUs; } -static time_t togglePwmState(PwmConfig *state) { +static uint64_t togglePwmState(PwmConfig *state) { #if DEBUG_PWM scheduleMsg(&logger, "togglePwmState phaseIndex=%d iteration=%d", state->safe.phaseIndex, state->safe.iteration); scheduleMsg(&logger, "state->period=%f state->safe.period=%f", state->period, state->safe.period); #endif if (state->safe.phaseIndex == 0) { - if (cisnan(state->period)) { + if (cisnan(state->periodMs)) { /** * zero period means PWM is paused */ - return TICKS_IN_MS; + return 1; } if (state->cycleCallback != NULL) state->cycleCallback(state); - chDbgAssert(state->period != 0, "period not initialized", NULL); - if (state->safe.period != state->period) { + chDbgAssert(state->periodMs != 0, "period not initialized", NULL); + if (state->safe.periodMs != state->periodMs) { /** * period length has changed - we need to reset internal state */ - state->safe.start = chTimeNow(); + state->safe.startUs = getTimeNowUs(); state->safe.iteration = 0; - state->safe.period = state->period; + state->safe.periodMs = state->periodMs; #if DEBUG_PWM scheduleMsg(&logger, "state reset start=%d iteration=%d", state->safe.start, state->safe.iteration); #endif @@ -57,14 +57,14 @@ static time_t togglePwmState(PwmConfig *state) { state->stateChangeCallback(state, state->safe.phaseIndex == 0 ? state->multiWave.phaseCount - 1 : state->safe.phaseIndex - 1); - time_t nextSwitchTime = getNextSwitchTime(state); + uint64_t nextSwitchTimeUs = getNextSwitchTimeUs(state); #if DEBUG_PWM scheduleMsg(&logger, "%s: nextSwitchTime %d", state->name, nextSwitchTime); #endif - time_t timeToSwitch = nextSwitchTime - chTimeNow(); + uint64_t timeToSwitch = nextSwitchTimeUs - getTimeNowUs(); if (timeToSwitch < 1) { //todo: introduce error and test this error handling warning(OBD_PCM_Processor_Fault, "PWM: negative switch time"); - timeToSwitch = 1; + timeToSwitch = 10; } state->safe.phaseIndex++; @@ -76,34 +76,11 @@ static time_t togglePwmState(PwmConfig *state) { } static void timerCallback(PwmConfig *state) { - // todo: use this implementation! but something is wrong with it :( - time_t timeToSleep = togglePwmState(state); - scheduleTask(&state->scheduling, timeToSleep, (schfunc_t) timerCallback, state); + time_t timeToSleepUs = togglePwmState(state); + // parameter here is still in systicks + scheduleTask(&state->scheduling, timeToSleepUs, (schfunc_t) timerCallback, state); } -//static msg_t deThread(PwmConfig *state) { -// chRegSetThreadName("Wave"); -// -//#if DEBUG_PWM -// scheduleMsg(&logger, "Thread started for %s", state->name); -//#endif -// -//// setPadValue(state, state->idleState); todo: currently pin is always zero at first iteration. -//// we can live with that for now -// // todo: figure out overflow -// -// while (TRUE) { -// time_t timeToSwitch = togglePwmState(state); -//#if DEBUG_PWM -// scheduleMsg(&logger, "%s: sleep %d", state->name, timeToSwitch); -//#endif -// chThdSleep(timeToSwitch); -// } -//#if defined __GNUC__ -// return -1; -//#endif -//} - /** * Incoming parameters are potentially just values on current stack, so we have to copy * into our own permanent storage, right? @@ -125,7 +102,7 @@ void copyPwmParameters(PwmConfig *state, int phaseCount, float *switchTimes, int void weComplexInit(char *msg, PwmConfig *state, int phaseCount, float *switchTimes, int waveCount, int **pinStates, pwm_cycle_callback *cycleCallback, pwm_gen_callback *stateChangeCallback) { - chDbgCheck(state->period != 0, "period is not initialized"); + chDbgCheck(state->periodMs != 0, "period is not initialized"); chDbgCheck(phaseCount > 1, "count is too small"); if (phaseCount > PWM_PHASE_MAX_COUNT) { firmwareError("too many phases in PWM"); @@ -146,11 +123,9 @@ void weComplexInit(char *msg, PwmConfig *state, int phaseCount, float *switchTim state->stateChangeCallback = stateChangeCallback; state->safe.phaseIndex = 0; - state->safe.period = -1; + state->safe.periodMs = -1; state->safe.iteration = -1; state->name = msg; -// chThdCreateStatic(state->deThreadStack, sizeof(state->deThreadStack), NORMALPRIO, (tfunc_t) deThread, state); timerCallback(state); - } diff --git a/firmware/controllers/system/pwm_generator_logic.h b/firmware/controllers/system/pwm_generator_logic.h index 3a4f96a9c4..f7cdfab195 100644 --- a/firmware/controllers/system/pwm_generator_logic.h +++ b/firmware/controllers/system/pwm_generator_logic.h @@ -18,7 +18,7 @@ typedef struct { * a copy so that all phases are executed on the same period, even if another thread * would be adjusting PWM parameters */ - float period; + float periodMs; /** * Iteration counter */ @@ -26,7 +26,7 @@ typedef struct { /** * Start time of current iteration */ - systime_t start; + uint64_t startUs; int phaseIndex; } pwm_config_safe_state_s; @@ -46,9 +46,8 @@ struct PwmConfig_struct { * float value of PWM period * PWM generation is not happening while this value is zero */ - float period; + float periodMs; - WORKING_AREA(deThreadStack, UTILITY_THREAD_STACK_SIZE); scheduling_s scheduling; pwm_config_safe_state_s safe; diff --git a/firmware/controllers/system/signal_executor_sleep.c b/firmware/controllers/system/signal_executor_sleep.c index d37ec2fe0f..39ebeaab24 100644 --- a/firmware/controllers/system/signal_executor_sleep.c +++ b/firmware/controllers/system/signal_executor_sleep.c @@ -30,9 +30,9 @@ #if EFI_SIGNAL_EXECUTOR_SLEEP || defined(__DOXYGEN__) -void scheduleTask(scheduling_s *scheduling, float delayF, schfunc_t callback, void *param) { - int delay = delayF; - if (delay == 0) { +void scheduleTask(scheduling_s *scheduling, int delayUs, schfunc_t callback, void *param) { + int delaySt = delayUs * CH_FREQUENCY / 1000000; + if (delaySt == 0) { /** * in case of zero delay, we should invoke the callback */ @@ -45,7 +45,7 @@ void scheduleTask(scheduling_s *scheduling, float delayF, schfunc_t callback, vo if (isArmed) chVTResetI(&scheduling->timer); - chVTSetI(&scheduling->timer, delay, (vtfunc_t)callback, param); + chVTSetI(&scheduling->timer, delaySt, (vtfunc_t)callback, param); unlockAnyContext(); } diff --git a/firmware/controllers/system/signal_temp.c b/firmware/controllers/system/signal_temp.c deleted file mode 100644 index f29782b259..0000000000 --- a/firmware/controllers/system/signal_temp.c +++ /dev/null @@ -1,74 +0,0 @@ -/** - * @file signal_temp.c - * - * Work in progress. https://sourceforge.net/p/rusefi/tickets/24/ - * - * Here we have a 1MHz timer dedicated to event scheduling. We are using one of the 32-bit timers here, - * so this timer can schedule events up to 4B/100M = 4000 seconds from now. - * - * @date Apr 14, 2014 - * @author Andrey Belomutskiy, (c) 2012-2013 - */ - -#include "main.h" -#include "signal_executor.h" -#include "signal_temp.h" - -// https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=https%3a%2f%2fmy.st.com%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fcortex_mx_stm32%2fInterrupt%20on%20CEN%20bit%20setting%20in%20TIM7&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B¤tviews=474 - -#if EFI_PROD_CODE - -int globalCounter = 0; - -static TIM_TypeDef *TIM = TIM5; - -schfunc_t globalTimerCallback; - -void setTimer(int timeUs) { - TIM->ARR = timeUs - 1; - TIM->EGR |= TIM_EGR_UG; // generate an update event to reload timer's counter value - TIM->CR1 |= TIM_CR1_CEN; // restart timer -} - -static void callback(void) { - GPIOD ->ODR ^= (1 << 13); // Toggle D13 - - globalCounter++; - - if (globalTimerCallback == NULL) { - firmwareError("NULL globalTimerCallback"); - return; - } - globalTimerCallback(NULL); -// if (globalCounter < 6) { -// setTimer(100000); -// } -} - -// if you decide to move this to .cpp do not forget to make that a C method -CH_IRQ_HANDLER(STM32_TIM5_HANDLER) { - CH_IRQ_PROLOGUE(); - if (((TIM->SR & 0x0001) != 0) && ((TIM->DIER & 0x0001) != 0)) { - callback(); - } - TIM->SR = (int) ~STM32_TIM_SR_UIF; // Interrupt has been handled - CH_IRQ_EPILOGUE(); -} - -void TIM_Init(void) { -// if (1==1) -// return; // something is not right with this code :( - - RCC ->APB1ENR |= RCC_APB1ENR_TIM5EN; // Enable TIM5 clock -// NVIC_EnableIRQ(TIM5_IRQn); // Enable TIM5 IRQ - nvicEnableVector(TIM5_IRQn, CORTEX_PRIORITY_MASK(12)); - TIM->DIER |= TIM_DIER_UIE; // Enable interrupt on update event - TIM->CR1 |= TIM_CR1_OPM; // one pulse mode: count down ARR and stop - TIM->CR1 &= ~TIM_CR1_ARPE; /* ARR register is NOT buffered, allows to update timer's period on-fly. */ - - TIM->PSC = 84 - 1; // 168MHz / 2 / 84 = 1MHz, each tick is a microsecond - -// setTimer(100000); -} - -#endif /* EFI_PROD_CODE */ diff --git a/firmware/controllers/system/signal_temp.h b/firmware/controllers/system/signal_temp.h deleted file mode 100644 index 56207ef92b..0000000000 --- a/firmware/controllers/system/signal_temp.h +++ /dev/null @@ -1,23 +0,0 @@ -/** - * @file signal_temp.h - * - * @date Apr 14, 2014 - * @author Andrey Belomutskiy, (c) 2012-2013 - */ - -#ifndef SIGNAL_TEMP_H_ -#define SIGNAL_TEMP_H_ - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -void TIM_Init(void); -void setTimer(int timeUs); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* SIGNAL_TEMP_H_ */ diff --git a/firmware/controllers/system/system.mk b/firmware/controllers/system/system.mk index c133b50b66..0547075a85 100644 --- a/firmware/controllers/system/system.mk +++ b/firmware/controllers/system/system.mk @@ -3,7 +3,6 @@ SYSTEMSRC = \ $(PROJECT_DIR)/controllers/system/pwm_generator_logic.c \ $(PROJECT_DIR)/controllers/system/signal_executor_sleep.c \ $(PROJECT_DIR)/controllers/system/signal_executor_single_timer.c \ - $(PROJECT_DIR)/controllers/system/signal_temp.c \ $(PROJECT_DIR)/controllers/system/signal_executor_hw_timer.c SYSTEMSRC_CPP = $(PROJECT_DIR)/controllers/system/trigger_emulator_algo.cpp \ diff --git a/firmware/controllers/system/trigger_emulator_algo.cpp b/firmware/controllers/system/trigger_emulator_algo.cpp index 57cb7e606a..2b885a6976 100644 --- a/firmware/controllers/system/trigger_emulator_algo.cpp +++ b/firmware/controllers/system/trigger_emulator_algo.cpp @@ -24,22 +24,22 @@ static LocalVersionHolder localVersion; void setTriggerEmulatorRPM(int rpm) { if (rpm == 0) { - configuration.period = NAN; + configuration.periodMs = NAN; } else { float gRpm = rpm * engineConfiguration->rpmMultiplier / 60.0; // per minute converted to per second - configuration.period = frequency2period(gRpm); + configuration.periodMs = frequency2period(gRpm); } scheduleMsg(&logger, "Emulating position sensor(s). RPM=%d", rpm); } static void updateTriggerShapeIfNeeded(PwmConfig *state) { if(localVersion.isOld()) { - scheduleMsg(&logger, "Stimulator: updating trigger shape: %d/%d %d", localVersion.getVersion(), getGlobalConfigurationVersion(), chTimeNow()); + scheduleMsg(&logger, "Stimulator: updating trigger shape: %d/%d %d", localVersion.getVersion(), getGlobalConfigurationVersion(), currentTimeMillis()); trigger_shape_s *s = &engineConfiguration2->triggerShape; int *pinStates[2] = {s->wave.waves[0].pinStates, s->wave.waves[1].pinStates}; copyPwmParameters(state, s->size, s->wave.switchTimes, 2, pinStates); - state->safe.period = -1; // this would cause loop re-initialization + state->safe.periodMs = -1; // this would cause loop re-initialization } } diff --git a/firmware/controllers/trigger/main_trigger_callback.cpp b/firmware/controllers/trigger/main_trigger_callback.cpp index 2ef987a490..8e208fbd05 100644 --- a/firmware/controllers/trigger/main_trigger_callback.cpp +++ b/firmware/controllers/trigger/main_trigger_callback.cpp @@ -87,7 +87,7 @@ static void handleFuelInjectionEvent(ActuatorEvent *event, int rpm) { // if (isCranking()) // scheduleMsg(&logger, "crankingFuel=%f for CLT=%fC", fuelMs, getCoolantTemperature()); - scheduleOutput(event->actuator, delay, fuelMs, chTimeNow()); + scheduleOutput(event->actuator, delay, fuelMs); } static void handleFuel(int eventIndex) { @@ -141,7 +141,7 @@ static void handleSparkEvent(ActuatorEvent *event, int rpm) { //return; } - scheduleOutput(event->actuator, sparkDelay, dwellMs, chTimeNow()); + scheduleOutput(event->actuator, sparkDelay, dwellMs); } static void handleSpark(int eventIndex) { @@ -200,6 +200,11 @@ static void onShaftSignal(ShaftEvents ckpSignalType, int eventIndex) { initializeIgnitionActions(advance - dwellAngle, engineConfiguration, engineConfiguration2); } + if(rpm==0) { + // this happens while we just start cranking + // todo: check for 'trigger->is_synchnonized?' + return; + } handleFuel(eventIndex); handleSpark(eventIndex); @@ -225,7 +230,7 @@ void initMainEventListener() { addConsoleAction("maininfo", showMainInfo); initLogging(&logger, "main event handler"); - printMsg(&logger, "initMainLoop: %d", chTimeNow()); + printMsg(&logger, "initMainLoop: %d", currentTimeMillis()); initHistogram(&mainLoopHisto, "main callback"); if (!isInjectionEnabled()) diff --git a/firmware/controllers/trigger/rpm_calculator.c b/firmware/controllers/trigger/rpm_calculator.c index 95144b1c6e..64b866b9e3 100644 --- a/firmware/controllers/trigger/rpm_calculator.c +++ b/firmware/controllers/trigger/rpm_calculator.c @@ -38,12 +38,12 @@ static Logging logger; * @return true if there was a full shaft revolution within the last second */ int isRunning() { - time_t now = chTimeNow(); - return overflowDiff(now, rpmState.lastRpmEventTime) < CH_FREQUENCY; + uint64_t nowUs = getTimeNowUs(); + return nowUs - rpmState.lastRpmEventTimeUs < US_PER_SECOND; } -int getLastRpmEventTime(void) { - return rpmState.lastRpmEventTime; +uint64_t getLastRpmEventTime(void) { + return rpmState.lastRpmEventTimeUs; } int isCranking(void) { @@ -63,12 +63,12 @@ int getRpm() { /** * @return Current crankshaft angle, 0 to 720 for four-stroke */ -float getCrankshaftAngle(time_t time) { - int timeSinceZeroAngle = overflowDiff(time, rpmState.lastRpmEventTime); +float getCrankshaftAngle(uint64_t timeUs) { + uint64_t timeSinceZeroAngle = timeUs - rpmState.lastRpmEventTimeUs; - float cRevolutionTime = getCrankshaftRevolutionTime(rpmState.rpm); + float cRevolutionTimeMs = getCrankshaftRevolutionTimeMs(rpmState.rpm); - return 360 * timeSinceZeroAngle / cRevolutionTime; + return 360.0 * timeSinceZeroAngle / cRevolutionTimeMs / 1000; } int getRevolutionCounter(void) { @@ -81,9 +81,9 @@ int getRevolutionCounter(void) { * * @return TRUE if noise is detected */ -static int isNoisySignal(rpm_s * rpmState, int now) { - int diff = overflowDiff(now, rpmState->lastRpmEventTime); - return diff == 0; +static int isNoisySignal(rpm_s * rpmState, uint64_t nowUs) { + uint64_t diff = nowUs - rpmState->lastRpmEventTimeUs; + return diff < 1000; // that's 1ms } static char shaft_signal_msg_index[15]; @@ -114,35 +114,35 @@ static void shaftPositionCallback(ShaftEvents ckpSignalType, int index) { if (index != 0) { #if EFI_PROD_CODE || EFI_SIMULATOR if (engineConfiguration->analogChartMode == AC_TRIGGER) - acAddData(getCrankshaftAngle(chTimeNow()), 1000 * ckpSignalType + index); + acAddData(getCrankshaftAngle(getTimeNowUs()), 1000 * ckpSignalType + index); #endif return; } rpmState.revolutionCounter++; - time_t now = chTimeNow(); + uint64_t nowUs = getTimeNowUs(); int hadRpmRecently = isRunning(); if (hadRpmRecently) { - if (isNoisySignal(&rpmState, now)) { + if (isNoisySignal(&rpmState, nowUs)) { // unexpected state. Noise? rpmState.rpm = NOISY_RPM; } else { - int diff = now - rpmState.lastRpmEventTime; + uint64_t diff = nowUs - rpmState.lastRpmEventTimeUs; // 60000 because per minute // * 2 because each revolution of crankshaft consists of two camshaft revolutions // / 4 because each cylinder sends a signal // need to measure time from the previous non-skipped event - int rpm = (int)(60000 * TICKS_IN_MS / engineConfiguration->rpmMultiplier / diff); + int rpm = (int)(60 * US_PER_SECOND / engineConfiguration->rpmMultiplier / diff); rpmState.rpm = rpm > UNREALISTIC_RPM ? NOISY_RPM : rpm; } } - rpmState.lastRpmEventTime = now; + rpmState.lastRpmEventTimeUs = nowUs; #if EFI_PROD_CODE || EFI_SIMULATOR if (engineConfiguration->analogChartMode == AC_TRIGGER) - acAddData(getCrankshaftAngle(now), index); + acAddData(getCrankshaftAngle(nowUs), index); #endif } @@ -169,13 +169,13 @@ void initRpmCalculator(void) { rpmState.rpm = 0; // we need this initial to have not_running at first invocation - rpmState.lastRpmEventTime = (time_t)-10 * CH_FREQUENCY; + rpmState.lastRpmEventTimeUs = (uint64_t)-10 * US_PER_SECOND; registerShaftPositionListener(&shaftPositionCallback, "rpm reporter"); registerShaftPositionListener(&tdcMarkCallback, "chart TDC mark"); } void scheduleByAngle(scheduling_s *timer, float angle, schfunc_t callback, void *param) { - int delay = (int)(getOneDegreeTime(getRpm()) * angle); - scheduleTask(timer, delay, callback, param); + float delayMs = getOneDegreeTimeMs(getRpm()) * angle; + scheduleTask(timer, MS2US(delayMs), callback, param); } diff --git a/firmware/controllers/trigger/rpm_calculator.h b/firmware/controllers/trigger/rpm_calculator.h index ddd981e419..073eed95ae 100644 --- a/firmware/controllers/trigger/rpm_calculator.h +++ b/firmware/controllers/trigger/rpm_calculator.h @@ -15,7 +15,7 @@ typedef struct { volatile int rpm; - volatile time_t lastRpmEventTime; + volatile uint64_t lastRpmEventTimeUs; /** * This counter is incremented with each revolution of one of the shafts. Could be * crankshaft could be camshaft. @@ -37,10 +37,10 @@ void initRpmCalculator(void); */ int getRpm(void); int isCranking(void); -int getLastRpmEventTime(void); +uint64_t getLastRpmEventTime(void); int getRevolutionCounter(void); -float getCrankshaftAngle(time_t time); +float getCrankshaftAngle(uint64_t timeUs); int isRunning(void); void addWaveChartEvent(char *name, char *msg, char *msg2); diff --git a/firmware/controllers/trigger/trigger_central.c b/firmware/controllers/trigger/trigger_central.c index 5e8339f892..2a53e21c35 100644 --- a/firmware/controllers/trigger/trigger_central.c +++ b/firmware/controllers/trigger/trigger_central.c @@ -26,7 +26,7 @@ extern engine_configuration_s *engineConfiguration; extern engine_configuration2_s *engineConfiguration2; // we need this initial to have not_running at first invocation -static volatile time_t previousShaftEventTime = (time_t) -10 * CH_FREQUENCY; +static volatile uint64_t previousShaftEventTime = (efitimems_t) -10 * US_PER_SECOND; static IntListenerArray triggerListeneres; @@ -58,16 +58,16 @@ void hwHandleShaftSignal(ShaftEvents signal) { chDbgCheck(eventIndex >= 0 && eventIndex < HW_EVENT_TYPES, "signal type"); hwEventCounters[eventIndex]++; - time_t now = chTimeNow(); + uint64_t nowUs = getTimeNowUs(); - if (overflowDiff(now, previousShaftEventTime) > CH_FREQUENCY) { + if (nowUs - previousShaftEventTime > US_PER_SECOND) { /** * We are here if there is a time gap between now and previous shaft event - that means the engine is not runnig. * That means we have lost synchronization since the engine is not running :) */ triggerState.shaft_is_synchronized = FALSE; } - previousShaftEventTime = now; + previousShaftEventTime = nowUs; // this is not atomic, but it's fine here shaftEventCounter++; @@ -75,7 +75,7 @@ void hwHandleShaftSignal(ShaftEvents signal) { * This invocation changes the state of */ processTriggerEvent(&triggerState, &engineConfiguration2->triggerShape, &engineConfiguration->triggerConfig, signal, - now); + nowUs); if (!triggerState.shaft_is_synchronized) return; // we should not propagate event if we do not know where we are diff --git a/firmware/controllers/trigger/trigger_decoder.cpp b/firmware/controllers/trigger/trigger_decoder.cpp index 83375ed87e..2792d5dca3 100644 --- a/firmware/controllers/trigger/trigger_decoder.cpp +++ b/firmware/controllers/trigger/trigger_decoder.cpp @@ -68,7 +68,7 @@ static inline int noSynchronizationResetNeeded(trigger_state_s const *shaftPosit * @brief This method changes the state of trigger_state_s data structure according to the trigger event */ void processTriggerEvent(trigger_state_s *shaftPositionState, trigger_shape_s const *triggerShape, - trigger_config_s const *triggerConfig, ShaftEvents signal, time_t now) { + trigger_config_s const *triggerConfig, ShaftEvents signal, uint64_t nowUs) { int isLessImportant = (triggerConfig->useRiseEdge && signal != SHAFT_PRIMARY_UP) || (!triggerConfig->useRiseEdge && signal != SHAFT_PRIMARY_DOWN); @@ -81,7 +81,7 @@ void processTriggerEvent(trigger_state_s *shaftPositionState, trigger_shape_s co return; } - int currentDuration = overflowDiff(now, shaftPositionState->toothed_previous_time); + int64_t currentDuration = nowUs - shaftPositionState->toothed_previous_time; chDbgCheck(currentDuration >= 0, "negative duration?"); // todo: skip a number of signal from the beginning @@ -114,7 +114,7 @@ void processTriggerEvent(trigger_state_s *shaftPositionState, trigger_shape_s co } shaftPositionState->toothed_previous_duration = currentDuration; - shaftPositionState->toothed_previous_time = now; + shaftPositionState->toothed_previous_time = nowUs; } diff --git a/firmware/controllers/trigger/trigger_decoder.h b/firmware/controllers/trigger/trigger_decoder.h index 2d9e4d3261..ddeb5c264e 100644 --- a/firmware/controllers/trigger/trigger_decoder.h +++ b/firmware/controllers/trigger/trigger_decoder.h @@ -19,7 +19,7 @@ extern "C" #include "engine_configuration.h" int isTriggerDecoderError(void); -void processTriggerEvent(trigger_state_s *shaftPositionState, trigger_shape_s const*triggerShape, trigger_config_s const*triggerConfig, ShaftEvents signal, time_t now); +void processTriggerEvent(trigger_state_s *shaftPositionState, trigger_shape_s const*triggerShape, trigger_config_s const*triggerConfig, ShaftEvents signal, uint64_t nowUs); void initializeSkippedToothTriggerShapeExt(engine_configuration2_s *engineConfiguration2, int totalTeethCount, int skippedCount); void initializeTriggerShape(engine_configuration_s *engineConfiguration, engine_configuration2_s *engineConfiguration2); int findTriggerZeroEventIndex(trigger_shape_s const * shape, trigger_config_s const*triggerConfig); diff --git a/firmware/controllers/trigger/trigger_structure.h b/firmware/controllers/trigger/trigger_structure.h index a12265c7a4..81759b69d0 100644 --- a/firmware/controllers/trigger/trigger_structure.h +++ b/firmware/controllers/trigger/trigger_structure.h @@ -9,6 +9,7 @@ #define TRIGGER_STRUCTURE_H_ #include "rusefi_enums.h" +#include "stdint.h" #define PWM_PHASE_MAX_COUNT 150 #define PWM_PHASE_MAX_WAVE_PER_PWM 2 @@ -28,8 +29,8 @@ typedef struct { int current_index; - int toothed_previous_duration; - int toothed_previous_time; + uint64_t toothed_previous_duration; + uint64_t toothed_previous_time; } trigger_state_s; diff --git a/firmware/emulation/rfi_perftest.c b/firmware/emulation/rfi_perftest.c deleted file mode 100644 index bb5b1bc9c5..0000000000 --- a/firmware/emulation/rfi_perftest.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * rdi_perftest.c - * - * Created on: Nov 30, 2012 - * Author: Andrey Belomutskiy, (c) 2012-2013 - */ - -#include "main.h" -#include "rfi_perftest.h" -#include "fuel_math.h" - -//#include "rfirtc.h" -#include "eficonsole.h" -#include "time.h" -#include "engine_math.h" -#include "gpio_helper.h" - -//#define TEST_PORT GPIOB -//#define TEST_PIN 6 - -static OutputPin testOutput; - -static void testSystemCalls(int count) { - time_t start, time; - long result = 0; - - start = currentTimeMillis(); - for (int i = 0; i < count / 2; i++) { -// setPinValue(&testOutput, 0); -// setPinValue(&testOutput, 1); - } - - time = currentTimeMillis() - start; - // Finished 100000 iterations of 'setPinValue()' in 120ms -// print("Finished %d iterations of 'setPinValue()' in %dms\r\n", count, time); - - start = currentTimeMillis(); - for (int i = 0; i < count; i++) - result += chTimeNow(); - time = currentTimeMillis() - start; - if (result != 0) { - // Finished 100000 iterations of 'chTimeNow()' in 33ms - print("Finished %d iterations of 'chTimeNow()' in %dms\r\n", count, time); - } - - start = currentTimeMillis(); - for (int i = 0; i < count; i++) { - chSysLock() - ; - result += chTimeNow(); - chSysUnlock() - ; - } - time = currentTimeMillis() - start; - if (result != 0) { - // Finished 100000 iterations of 'chTimeNow()' with chSysLock in 144ms - print("Finished %d iterations of 'chTimeNow()' with chSysLock in %dms\r\n", count, time); - } - - count /= 10; - - start = currentTimeMillis(); - for (int i = 0; i < count; i++) - result += currentTimeMillis(); - time = currentTimeMillis() - start; - if (result != 0) - print("Finished %d iterations of 'currentTimeMillis' in %dms\r\n", count, time); - -} - - -static void testRusefiMethods(int count) { - time_t start, time; - int tempi = 1; - - start = currentTimeMillis(); - - for (int i = 0; i < count; i++) - tempi += getBaseFuel(4020, 2.21111); - time = currentTimeMillis() - start; - if (tempi != 0) - print("Finished %d iterations of getBaseFuel in %dms\r\n", count, time); - - start = currentTimeMillis(); - -// for (int i = 0; i < count; i++) -// tempi += getDefaultFuel(4020, 2.21111); -// time = currentTimeMillis() - start; -// if (tempi == 0) -// print("Finished %d iterations of getDefaultFuel in %dms\r\n", count, time); -} - -static void testMath(int count) { - time_t start, time; - int tempi = 1; - - start = currentTimeMillis(); - for (int i = 0; i < count; i++) - ; - time = currentTimeMillis() - start; - print("Finished %d iterations of empty loop in %dms\r\n", count, time); - - start = currentTimeMillis(); - for (int i = 0; i < count; i++) - tempi += tempi; - time = currentTimeMillis() - start; - if (tempi == 0) - print("Finished %d iterations of int summation in %dms\r\n", count, time); - - start = currentTimeMillis(); - tempi = 1; - for (int i = 0; i < count; i++) - tempi += (tempi + 100) / 130; - time = currentTimeMillis() - start; - if (tempi != 0) - print("Finished %d iterations of int division in %dms\r\n", count, time); - - start = currentTimeMillis(); - long templ = 1; - for (int i = 0; i < count; i++) - templ += templ; - time = currentTimeMillis() - start; - if (templ == 0) - print("Finished %d iterations of long summation in %dms\r\n", count, time); - - start = currentTimeMillis(); - templ = 1; - for (int i = 0; i < count; i++) - templ += (templ + 100) / 130; - time = currentTimeMillis() - start; - if (templ != 0) { - // Finished 100000 iterations of long division in 45ms - print("Finished %d iterations of long division in %dms\r\n", count, time); - } - - start = currentTimeMillis(); - float tempf = 1; - for (int i = 0; i < count; i++) - tempf += tempf; - time = currentTimeMillis() - start; - if (tempf != 0) - print("Finished %d iterations of float summation in %dms\r\n", count, time); - - start = currentTimeMillis(); - tempf = 1; - for (int i = 0; i < count; i++) - tempf += (tempf + 100) / 130.0; - time = currentTimeMillis() - start; - if (tempf != 0) { - // Finished 100000 iterations of float division in 65ms - print("Finished %d iterations of float division in %dms\r\n", count, time); - } - - start = currentTimeMillis(); - double tempd = 1; - for (int i = 0; i < count; i++) - tempd += tempd / 2; - time = currentTimeMillis() - start; - if (tempd != 0) - print("Finished %d iterations of double summation in %dms\r\n", count, time); - - start = currentTimeMillis(); - tempd = 1; - for (int i = 0; i < count; i++) - tempd += (tempd + 100) / 130.0; - time = currentTimeMillis() - start; - if (tempd != 0) - print("Finished %d iterations of double division in %dms\r\n", count, time); - -} - -static void runTests(int count) { - testRusefiMethods(count); - testSystemCalls(count); - testMath(count); -} - -void initTimePerfActions() { -// initOutputPin("test pad", &testOutput, TEST_PORT, TEST_PIN); - addConsoleActionI("testmath", runTests); -} diff --git a/firmware/main.cpp b/firmware/main.cpp index b94f5a429d..5bbf57b9b7 100644 --- a/firmware/main.cpp +++ b/firmware/main.cpp @@ -24,6 +24,9 @@ int main(void) { halInit(); chSysInit(); + // looks like this holds a random value on start? Let's set a nice clean zero + DWT_CYCCNT = 0; + runRusEfi(); return 0; } diff --git a/firmware/main.h b/firmware/main.h index 75dcca24ba..144c2f6d33 100644 --- a/firmware/main.h +++ b/firmware/main.h @@ -43,16 +43,6 @@ extern "C" */ #define TICKS_IN_MS (CH_FREQUENCY / 1000) -/** - * @brief Current system time in seconds. - */ -#define chTimeNowSeconds() (chTimeNow() / CH_FREQUENCY) - -/** - * @brief Returns the number of milliseconds since the board initialization. - */ -#define currentTimeMillis() (chTimeNow() / TICKS_IN_MS) - #define Delay(ms) chThdSleepMilliseconds(ms) #ifdef __cplusplus extern "C" diff --git a/firmware/rusefi.cpp b/firmware/rusefi.cpp index 370cde6338..448df9af56 100644 --- a/firmware/rusefi.cpp +++ b/firmware/rusefi.cpp @@ -274,5 +274,5 @@ void firmwareError(const char *fmt, ...) { } int getRusEfiVersion(void) { - return 20140422; + return 20140424; } diff --git a/firmware/util/efilib.c b/firmware/util/efilib.c deleted file mode 100644 index e28af0fc04..0000000000 --- a/firmware/util/efilib.c +++ /dev/null @@ -1,75 +0,0 @@ -/** - * @file efilib.c - * - * We cannot use stdlib because we do not have malloc - so, we have to implement these functions - * - * @date Feb 21, 2014 - * @author Andrey Belomutskiy, (c) 2012-2014 - */ - -#include -#include -#include "efilib.h" - -int indexOf(const char *string, char ch) { - // todo: there should be a standard function for this - int len = strlen(string); - for (int i = 0; i < len; i++) { - if (string[i] == ch) - return i; - } - return -1; -} - -// string to integer -int atoi(const char *string) { - // todo: use stdlib '#include ' - int len = strlen(string); - if (len == 0) - return -ERROR_CODE; - if (string[0] == '-') - return -atoi(string + 1); - int result = 0; - - for (int i = 0; i < len; i++) { - char ch = string[i]; - if (ch < '0' || ch > '9') { - return ERROR_CODE; - } - int c = ch - '0'; - result = result * 10 + c; - } - - return result; -} - -static char todofixthismesswithcopy[100]; - -// string to float -float atoff(const char *param) { - int totallen = strlen(param); - if (totallen > sizeof(todofixthismesswithcopy) - 1) - return (float)NAN; - strcpy(todofixthismesswithcopy, param); - char *string = todofixthismesswithcopy; - - // todo: is there a standard function? - // todo: create a unit test - int dotIndex = indexOf(string, '.'); - if (dotIndex == -1) { - // just an integer - int result = atoi(string); - return (float) result; - } - // todo: this needs to be fixed - string[dotIndex] = 0; - int integerPart = atoi(string); - string += (dotIndex + 1); - int decimalLen = strlen(string); - int decimal = atoi(string); - float divider = 1.0; - // todo: reuse 'pow10' function which we have anyway - for (int i = 0; i < decimalLen; i++) - divider = divider * 10.0; - return integerPart + decimal / divider; -}