Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use a custom chrono-like type for time #415

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
6 changes: 3 additions & 3 deletions firmware/config/boards/hellen/hellen_board_id.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,10 +229,10 @@ bool HellenBoardIdFinder<NumPins>::measureChargingTimes(int i, float & Tc1_us, f
}

// 4. calculate the first charging time
efitick_t Tc1_nt = t2 - t1;
efidur_t Tc1_nt = t2 - t1;
Tc1_us = NT2USF(Tc1_nt);
// We use the same 'charging time' to discharge the capacitor to some random voltage below the threshold voltage.
efitick_t Td_nt = Tc1_nt;
efidur_t Td_nt = Tc1_nt;

// 5. And now just wait for the rest of the discharge process...
// Spin wait since chThdSleepMicroseconds() lacks the resolution we need
Expand All @@ -243,7 +243,7 @@ bool HellenBoardIdFinder<NumPins>::measureChargingTimes(int i, float & Tc1_us, f
pinState = palReadPad(state.rInputPinPort, state.rInputPinIdx);

// 6. And immediately begin charging again until the threshold voltage is reached!
state.timeChargeNt = 0;
state.timeChargeNt = {};
palSetPad(state.rOutputPinPort, state.rOutputPinIdx);

// Wait for the charging completion
Expand Down
4 changes: 2 additions & 2 deletions firmware/console/binary/tooth_logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const std::vector<CompositeEvent>& getCompositeEvents() {
void SetNextCompositeEntry(efitick_t timestamp) {
CompositeEvent event;

event.timestamp = timestamp;
event.timestamp = timestamp.count();
event.primaryTrigger = currentTrigger1;
event.secondaryTrigger = currentTrigger2;
event.isTDC = currentTdc;
Expand Down Expand Up @@ -290,7 +290,7 @@ void LogTriggerTopDeadCenter(efitick_t timestamp) {
currentTdc = true;
SetNextCompositeEntry(timestamp);
currentTdc = false;
SetNextCompositeEntry(timestamp + 10);
SetNextCompositeEntry(timestamp + efidur_t{10});
}

void LogTriggerCoilState(efitick_t timestamp, bool state) {
Expand Down
2 changes: 1 addition & 1 deletion firmware/console/status_loop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@ void updateTunerStudioState() {
#endif /* EFI_CAN_SUPPORT */

#if EFI_CLOCK_LOCKS
tsOutputChannels->maxLockedDuration = NT2US(maxLockedDuration);
tsOutputChannels->maxLockedDuration = maxLockedDuration / US_TO_NT_MULTIPLIER;
#endif /* EFI_CLOCK_LOCKS */

#if EFI_SHAFT_POSITION_INPUT
Expand Down
94 changes: 83 additions & 11 deletions firmware/controllers/algo/rusefi_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,16 @@ using time_t = uint32_t;
*/

struct efidur_t {
using rep = int64_t;

constexpr efidur_t() = default;
constexpr efidur_t(int64_t c) : m_count(c) { }
/*todo: explicit*/ constexpr efidur_t(rep c) : m_count(c) { }

constexpr operator int64_t() const {
return m_count;
constexpr operator rep() const {
return count();
}

constexpr int64_t count() const {
constexpr rep count() const {
return m_count;
}

Expand All @@ -70,25 +72,95 @@ struct efidur_t {
}

private:
int64_t m_count = 0;
rep m_count = 0;
};

constexpr bool operator==(const efidur_t& l, const efidur_t& r) {
return l.count() == r.count();
}

constexpr bool operator<(const efidur_t& l, const efidur_t& r) {
return l.count() < r.count();
}

constexpr bool operator<=(const efidur_t& l, const efidur_t& r) {
return l.count() <= r.count();
}

constexpr bool operator>(const efidur_t& l, const efidur_t& r) {
return l.count() > r.count();
}

constexpr bool operator>=(const efidur_t& l, const efidur_t& r) {
return l.count() >= r.count();
}

constexpr efidur_t operator*(const efidur_t& l, const int r) {
return efidur_t{l.count() * r};
}

constexpr efidur_t operator*(const int l, const efidur_t& r) {
return r * l;
}

struct efitick_t {
using rep = efidur_t::rep;

constexpr efitick_t() = default;
constexpr efitick_t(int64_t c) : count(c) { }
/*todo: explicit*/ constexpr efitick_t(rep c) : m_count(c) { }

constexpr operator int64_t() const {
return count;
constexpr rep count() const {
return m_count;
}

constexpr efitick_t& operator+=(const efidur_t &s) {
m_count += s.count();
return *this;
}

efitick_t& operator+=(const efidur_t &s) {
count += s.count();
constexpr efitick_t& operator-=(const efidur_t &s) {
m_count -= s.count();
return *this;
}

int64_t count = 0;
constexpr efitick_t operator+(const efidur_t& rhs) const {
return efitick_t{m_count + rhs.count()};
}

constexpr efitick_t operator-(const efidur_t& rhs) const {
return efitick_t{m_count - rhs.count()};
}

constexpr efidur_t operator-(const efitick_t& rhs) const {
return efidur_t{m_count - rhs.count()};
}

private:
rep m_count = 0;
};



constexpr bool operator==(const efitick_t& l, const efitick_t& r) {
return l.count() == r.count();
}

constexpr bool operator<(const efitick_t& l, const efitick_t& r) {
return l.count() < r.count();
}

constexpr bool operator<=(const efitick_t& l, const efitick_t& r) {
return l.count() <= r.count();
}

constexpr bool operator>(const efitick_t& l, const efitick_t& r) {
return l.count() > r.count();
}

constexpr bool operator>=(const efitick_t& l, const efitick_t& r) {
return l.count() >= r.count();
}

/**
* 64 bit time in microseconds (1/1_000_000 of a second), since boot
*/
Expand Down
6 changes: 3 additions & 3 deletions firmware/controllers/engine_controller_misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ void slowStartStopButtonCallback() {
}
engine->engineState.startStopState = startStopState;

if (engine->startStopStateLastPushTime == 0) {
// nothing is going on with startStop button
return;
if (engine->startStopStateLastPushTime == efitick_t{}) {
// nothing is going on with startStop button
return;
}

// TODO: split starter (/disable relay) control in to its own controller
Expand Down
2 changes: 1 addition & 1 deletion firmware/controllers/engine_cycle/spark_logic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ static void scheduleSparkEvent(bool limitedSpark, IgnitionEvent *event,

if (!limitedSpark && engine->enableOverdwellProtection) {
// auto fire spark at 1.5x nominal dwell
efitick_t fireTime = chargeTime + (uint32_t)MSF2NT(1.5f * dwellMs);
efitick_t fireTime = chargeTime + efidur_t{(uint32_t)MSF2NT(1.5f * dwellMs)};
engine->executor.scheduleByTimestampNt("overdwell", &event->sparkEvent.scheduling, fireTime, { overFireSparkAndPrepareNextSchedule, event });
}
}
Expand Down
4 changes: 2 additions & 2 deletions firmware/controllers/system/timer/event_queue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ bool EventQueue::insertTask(scheduling_s *scheduling, efitick_t timeX, action_s
if (scheduling->action) {
#if EFI_UNIT_TEST
if (verboseMode) {
printf("Already scheduled was %d\r\n", (int)scheduling->momentX);
printf("Already scheduled now %d\r\n", (int)timeX);
printf("Already scheduled was %d\r\n", (int)scheduling->momentX.count());
printf("Already scheduled now %d\r\n", (int)timeX.count());
}
#endif /* EFI_UNIT_TEST */
return false;
Expand Down
8 changes: 4 additions & 4 deletions firmware/controllers/system/timer/pwm_generator_logic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ void SimplePwm::setSimplePwmDutyCycle(float dutyCycle) {
* returns absolute timestamp of state change
*/
static efitick_t getNextSwitchTimeNt(PwmConfig *state) {
efiAssert(ObdCode::CUSTOM_ERR_ASSERT, state->safe.phaseIndex < PWM_PHASE_MAX_COUNT, "phaseIndex range", 0);
efiAssert(ObdCode::CUSTOM_ERR_ASSERT, state->safe.phaseIndex < PWM_PHASE_MAX_COUNT, "phaseIndex range", {});
int iteration = state->safe.iteration;
// we handle PM_ZERO and PM_FULL separately
float switchTime = state->mode == PM_NORMAL ? state->multiChannelStateSequence->getSwitchTime(state->safe.phaseIndex) : 1;
Expand All @@ -106,7 +106,7 @@ static efitick_t getNextSwitchTimeNt(PwmConfig *state) {
* Once 'iteration' gets relatively high, we might lose calculation precision here.
* This is addressed by iterationLimit below, using any many cycles as possible without overflowing timeToSwitchNt
*/
uint32_t timeToSwitchNt = (uint32_t)((iteration + switchTime) * periodNt);
efidur_t timeToSwitchNt = efidur_t{(uint32_t)((iteration + switchTime) * periodNt)};

#if DEBUG_PWM
efiPrintf("start=%d timeToSwitch=%d", state->safe.start, timeToSwitch);
Expand Down Expand Up @@ -174,7 +174,7 @@ void PwmConfig::handleCycleStart() {
*/
efitick_t PwmConfig::togglePwmState() {
if (isStopRequested) {
return 0;
return {};
}

#if DEBUG_PWM
Expand Down Expand Up @@ -257,7 +257,7 @@ static void timerCallback(PwmConfig *state) {
efiAssertVoid(ObdCode::CUSTOM_ERR_6581, state->dbgNestingLevel < 25, "PWM nesting issue");

efitick_t switchTimeNt = state->togglePwmState();
if (switchTimeNt == 0) {
if (switchTimeNt == efitick_t{}) {
// we are here when PWM gets stopped
return;
}
Expand Down
4 changes: 2 additions & 2 deletions firmware/controllers/trigger/instant_rpm_calculator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ float InstantRpmCalculator::calculateInstantRpm(
// It's OK to truncate from 64b to 32b, ARM with single precision FPU uses an expensive
// software function to convert 64b int -> float, while 32b int -> float is very cheap hardware conversion
// The difference is guaranteed to be short (it's 90 degrees of engine rotation!), so it won't overflow.
uint32_t nowNt32 = nowNt;
uint32_t nowNt32 = nowNt.count();

assertIsInBoundsWithResult(current_index, timeOfLastEvent, "calc timeOfLastEvent", 0);

Expand Down Expand Up @@ -111,7 +111,7 @@ void InstantRpmCalculator::setLastEventTimeForInstantRpm(efitick_t nowNt) {
return;
}

uint32_t nowNt32 = nowNt;
uint32_t nowNt32 = nowNt.count();
spinningEvents[spinningEventIndex] = nowNt32;

// If we are using only rising edges, we never write in to the odd-index slots that
Expand Down
6 changes: 3 additions & 3 deletions firmware/controllers/trigger/trigger_decoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ expected<TriggerDecodeResult> TriggerDecoderBase::decodeTriggerEvent(
firmwareError(ObdCode::CUSTOM_OBD_93, "[%s] toothed_previous_time after nowNt prev=%d now=%d", msg, toothed_previous_time, nowNt);
}

efidur_t currentDurationLong = isFirstEvent ? 0 : (nowNt - toothed_previous_time);
efidur_t currentDurationLong = isFirstEvent ? efidur_t::zero() : (nowNt - toothed_previous_time);

/**
* For performance reasons, we want to work with 32 bit values. If there has been more then
Expand All @@ -423,7 +423,7 @@ expected<TriggerDecodeResult> TriggerDecoderBase::decodeTriggerEvent(
printf("%s isLessImportant %s now=%d index=%d\r\n",
getTrigger_type_e(triggerConfiguration.TriggerType.type),
getTrigger_event_e(signal),
(int)nowNt,
(int)nowNt.count(),
currentCycle.current_index);
}
#endif /* EFI_UNIT_TEST */
Expand All @@ -436,7 +436,7 @@ expected<TriggerDecodeResult> TriggerDecoderBase::decodeTriggerEvent(
printf("%s event %s %lld\r\n",
getTrigger_type_e(triggerConfiguration.TriggerType.type),
getTrigger_event_e(signal),
nowNt.count);
nowNt.count());
printf("decodeTriggerEvent ratio %.2f: current=%d previous=%d\r\n", 1.0 * toothDurations[0] / toothDurations[1],
toothDurations[0], toothDurations[1]);
}
Expand Down
4 changes: 3 additions & 1 deletion firmware/controllers/trigger/trigger_simulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ void TriggerStimulatorHelper::feedSimulatedEvent(
efiAssertVoid(ObdCode::CUSTOM_ERR_6593, shape.getSize() > 0, "size not zero");
int stateIndex = i % shape.getSize();

int time = getSimulatedEventTime(shape, i);
// TODO: why is this an int?
int timeint = getSimulatedEventTime(shape, i);
efitick_t time(timeint);

const auto & multiChannelStateSequence = shape.wave;

Expand Down
6 changes: 3 additions & 3 deletions firmware/development/engine_sniffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ bool WaveChart::isStartedTooLongAgo() const {
*
*/
efidur_t chartDurationNt = getTimeNowNt() - startTimeNt;
return startTimeNt != 0 && NT2US(chartDurationNt) > engineConfiguration->engineChartSize * 1000000 / 20;
return startTimeNt.count() != 0 && NT2US(chartDurationNt) > engineConfiguration->engineChartSize * 1000000 / 20;
}

bool WaveChart::isFull() const {
Expand Down Expand Up @@ -205,8 +205,8 @@ void WaveChart::addEvent3(const char *name, const char * msg) {
*
* at least that's 32 bit division now
*/
uint32_t diffNt = nowNt - startTimeNt;
uint32_t time100 = NT2US(diffNt / ENGINE_SNIFFER_UNIT_US);
uint32_t diffUs = NT2US(nowNt - startTimeNt);
uint32_t time100 = diffUs / ENGINE_SNIFFER_UNIT_US;

if (logging.remainingSize() > 35) {
/**
Expand Down
2 changes: 1 addition & 1 deletion firmware/hw_layer/digital_input/digital_input_exti.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ CH_IRQ_HANDLER(STM32_I2C1_EVENT_HANDLER) {
auto& entry = result.Value;
auto& timestamp = entry.Timestamp;

if (timestamp != 0) {
if (timestamp != efitick_t{}) {
auto& channel = channels[entry.Channel];

if (channel.Callback) {
Expand Down
6 changes: 3 additions & 3 deletions firmware/hw_layer/microsecond_timer/microsecond_timer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ void setHardwareSchedulerTimer(efitick_t nowNt, efitick_t setTimeNt) {
* #259 BUG error: not positive deltaTimeNt
* Once in a while we night get an interrupt where we do not expect it
*/
if (timeDeltaNt <= 0) {
if (timeDeltaNt <= efidur_t::zero()) {
timerFreezeCounter++;
warning(ObdCode::CUSTOM_OBD_LOCAL_FREEZE, "local freeze cnt=%d", timerFreezeCounter);
}
Expand Down Expand Up @@ -105,14 +105,14 @@ void portMicrosecondTimerCallback() {
class MicrosecondTimerWatchdogController : public PeriodicTimerController {
void PeriodicTask() override {
efitick_t nowNt = getTimeNowNt();
if (nowNt >= lastSetTimerTimeNt + 2 * CORE_CLOCK) {
if (nowNt.count() >= lastSetTimerTimeNt.count() + 2 * CORE_CLOCK) {
firmwareError(ObdCode::CUSTOM_ERR_SCHEDULING_ERROR, "watchdog: no events since %d", lastSetTimerTimeNt);
return;
}

const char* msg = isTimerPending ? "No_cb too long" : "Timer not awhile";
// 2 seconds of inactivity would not look right
efiAssertVoid(ObdCode::CUSTOM_TIMER_WATCHDOG, nowNt < lastSetTimerTimeNt + 2 * CORE_CLOCK, msg);
efiAssertVoid(ObdCode::CUSTOM_TIMER_WATCHDOG, nowNt.count() < lastSetTimerTimeNt.count() + 2 * CORE_CLOCK, msg);
}

int getPeriodMs() override {
Expand Down
2 changes: 1 addition & 1 deletion firmware/hw_layer/ports/stm32/microsecond_timer_stm32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ void portSetHardwareSchedulerTimer(efitick_t nowNt, efitick_t setTimeNt) {
// This implementation doesn't need the current time, only the target time
UNUSED(nowNt);

pwm_lld_enable_channel(&SCHEDULER_PWM_DEVICE, 0, setTimeNt);
pwm_lld_enable_channel(&SCHEDULER_PWM_DEVICE, 0, setTimeNt.count());
pwmEnableChannelNotificationI(&SCHEDULER_PWM_DEVICE, 0);
}

Expand Down
2 changes: 1 addition & 1 deletion firmware/util/efitime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ static WrapAround62 timeNt;
* 64-bit counter CPU/timer cycles since MCU reset
*/
efitick_t getTimeNowNt() {
return timeNt.update(getTimeNowLowerNt());
return efitick_t{(int64_t)timeNt.update(getTimeNowLowerNt())};
}

#endif /* !EFI_UNIT_TEST */
Expand Down
6 changes: 3 additions & 3 deletions firmware/util/efitime.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
// microseconds to ticks
// since only about 20 seconds of ticks fit in 32 bits this macro is casting parameter into 64 bits 'efitick_t' type
// please note that int64 <-> float is a heavy operation thus we have 'USF2NT' below
#define US2NT(us) (efidur_t{(((int64_t)(us)) * US_TO_NT_MULTIPLIER)})
#define US2NT(us) (efidur_t{(((efidur_t::rep)(us)) * US_TO_NT_MULTIPLIER)})

// microseconds to ticks, but floating point
// If converting a floating point time period, use this macro to avoid
Expand All @@ -39,7 +39,7 @@
#define USF2MS(us_float) (0.001f * (us_float))

// And back
#define NT2US(x) ((x) / US_TO_NT_MULTIPLIER)
#define NT2US(x) ((x).count() / US_TO_NT_MULTIPLIER)
#define NT2USF(x) (((float)(x)) / US_TO_NT_MULTIPLIER)

// milliseconds to ticks
Expand Down Expand Up @@ -71,7 +71,7 @@ struct WrapAround62 {
// the 64-bit result. Doing it this way means we only operate on one half at a
// time. Source will supply those bits anyways, so we don't need them from
// upper...
return (efitick_t(upper >> (32 - shift)) << 32) | source;
return (int64_t(upper >> (32 - shift)) << 32) | source;
}

private:
Expand Down
Loading
Loading