diff --git a/firmware/hw_layer/digital_input/digital_input_exti.cpp b/firmware/hw_layer/digital_input/digital_input_exti.cpp index 72c01de267..fc00aab3b7 100644 --- a/firmware/hw_layer/digital_input/digital_input_exti.cpp +++ b/firmware/hw_layer/digital_input/digital_input_exti.cpp @@ -28,8 +28,7 @@ struct ExtiChannel ExtiCallback Callback = nullptr; void* CallbackData; - efitick_t Timestamp = 0; - + // Name is also used as an enable bit const char* Name = nullptr; }; @@ -43,6 +42,8 @@ void efiExtiEnablePin(const char *msg, brain_pin_e brainPin, uint32_t mode, Exti return; } + efiAssertVoid(OBD_PCM_Processor_Fault, msg, "efiExtiEnablePin msg must not be null"); + ioportid_t port = getHwPort(msg, brainPin); if (port == NULL) { return; @@ -68,10 +69,9 @@ void efiExtiEnablePin(const char *msg, brain_pin_e brainPin, uint32_t mode, Exti return; } - channel.Name = msg; channel.Callback = cb; channel.CallbackData = cb_data; - channel.Timestamp = 0; + channel.Name = msg; ioline_t line = PAL_LINE(port, index); palEnableLineEvent(line, mode); @@ -102,7 +102,6 @@ void efiExtiDisablePin(brain_pin_e brainPin) palDisableLineEvent(line); /* mark unused */ - channel.Timestamp = 0; channel.Name = nullptr; channel.Callback = nullptr; channel.CallbackData = nullptr; @@ -123,21 +122,79 @@ static inline void triggerInterrupt() { NVIC->STIR = I2C1_EV_IRQn; } +struct ExtiQueueEntry { + efitick_t Timestamp; + uint8_t Channel; +}; + +template +class ExtiQueue { +public: + void push(const T& val) { + if ((m_write == m_read - 1) || (m_write == TSize - 1 && m_read == 0)) { + // queue full, drop + return; + } + + arr[m_write] = val; + m_write++; + + // wrap end of list + if (m_write == TSize) { + m_write = 0; + } + } + + expected pop() { + if (m_read == m_write) { + // Queue empty + return unexpected; + } + + T value = arr[m_read]; + m_read++; + + // wrap end of list + if (m_read == TSize) { + m_read = 0; + } + + return value; + } + +private: + T arr[TSize]; + + uint8_t m_read = 0; + uint8_t m_write = 0; +}; + +static ExtiQueue queue; + CH_IRQ_HANDLER(STM32_I2C1_EVENT_HANDLER) { OSAL_IRQ_PROLOGUE(); - for (size_t i = 0; i < 16; i++) { - auto& channel = channels[i]; - + while (true) { // get the timestamp out under lock // todo: lock freeeeee! __disable_irq(); - auto timestamp = channel.Timestamp; - channel.Timestamp = 0; + auto result = queue.pop(); __enable_irq(); + // Queue empty, we're done here. + if (!result) { + break; + } + + auto& entry = result.Value; + auto& timestamp = entry.Timestamp; + if (timestamp != 0) { - channel.Callback(channel.CallbackData, timestamp); + auto& channel = channels[entry.Channel]; + + if (channel.Name) { + channel.Callback(channel.CallbackData, timestamp); + } } } @@ -151,11 +208,7 @@ void handleExtiIsr(uint8_t index) { extiGetAndClearGroup1(1U << index, pr); if (pr & (1 << index)) { - auto& timestamp = channels[index].Timestamp; - - if (timestamp == 0) { - timestamp = getTimeNowNt(); - } + queue.push({getTimeNowNt(), index}); triggerInterrupt(); } diff --git a/firmware/hw_layer/digital_input/trigger/trigger_input_exti.cpp b/firmware/hw_layer/digital_input/trigger/trigger_input_exti.cpp index 476fa52918..e7ac89a380 100644 --- a/firmware/hw_layer/digital_input/trigger/trigger_input_exti.cpp +++ b/firmware/hw_layer/digital_input/trigger/trigger_input_exti.cpp @@ -27,9 +27,7 @@ static ioline_t camLines[CAM_INPUTS_COUNT]; static void shaft_callback(void *arg, efitick_t stamp) { // do the time sensitive things as early as possible! TRIGGER_BAIL_IF_DISABLED -//#if HW_CHECK_MODE -// TRIGGER_BAIL_IF_SELF_STIM -//#endif + TRIGGER_BAIL_IF_SELF_STIM int index = (int)arg; ioline_t pal_line = shaftLines[index]; @@ -43,9 +41,7 @@ static void shaft_callback(void *arg, efitick_t stamp) { static void cam_callback(void *arg, efitick_t stamp) { TRIGGER_BAIL_IF_DISABLED -//#if HW_CHECK_MODE -// TRIGGER_BAIL_IF_SELF_STIM -//#endif + TRIGGER_BAIL_IF_SELF_STIM int index = (int)arg; ioline_t pal_line = camLines[index]; diff --git a/firmware/hw_layer/digital_input/trigger/trigger_input_icu.cpp b/firmware/hw_layer/digital_input/trigger/trigger_input_icu.cpp index 67b18620c1..b1d5ca0b76 100644 --- a/firmware/hw_layer/digital_input/trigger/trigger_input_icu.cpp +++ b/firmware/hw_layer/digital_input/trigger/trigger_input_icu.cpp @@ -26,9 +26,8 @@ int icuFallingCallbackCounter = 0; static void vvtRisingCallback(void *arg) { efitick_t now = getTimeNowNt(); TRIGGER_BAIL_IF_DISABLED -#if HW_CHECK_MODE TRIGGER_BAIL_IF_SELF_STIM -#endif + int index = (int)arg; #if EFI_TOOTH_LOGGER @@ -43,9 +42,8 @@ static void vvtRisingCallback(void *arg) { static void vvtFallingCallback(void * arg) { efitick_t now = getTimeNowNt(); TRIGGER_BAIL_IF_DISABLED -#if HW_CHECK_MODE TRIGGER_BAIL_IF_SELF_STIM -#endif + int index = (int)arg; #if EFI_TOOTH_LOGGER if (!engineConfiguration->displayLogicLevelsInEngineSniffer) { @@ -62,9 +60,8 @@ static void shaftRisingCallback(bool isPrimary) { efitick_t stamp = getTimeNowNt(); TRIGGER_BAIL_IF_DISABLED -#if HW_CHECK_MODE TRIGGER_BAIL_IF_SELF_STIM -#endif + icuRisingCallbackCounter++; // icucnt_t last_width = icuGetWidth(icup); so far we are fine with system time @@ -76,9 +73,7 @@ static void shaftFallingCallback(bool isPrimary) { efitick_t stamp = getTimeNowNt(); TRIGGER_BAIL_IF_DISABLED -#if HW_CHECK_MODE TRIGGER_BAIL_IF_SELF_STIM -#endif icuFallingCallbackCounter++;