From d65983d0f4230f0e4bd406ee19381c071a789225 Mon Sep 17 00:00:00 2001 From: Enzo Monchanin Date: Fri, 28 Feb 2025 19:10:03 +0100 Subject: [PATCH] Compatibility with Espressif32 v3 (UNTESTED BUT BUILD SUCCESSFUL) --- src/VanBusRx.cpp | 44 ++++++++++++++++++++++++++++++-------------- src/VanBusTx.cpp | 31 ++++++++++++++++++++++--------- src/VanBusTx.h | 14 ++++++++++++-- 3 files changed, 64 insertions(+), 25 deletions(-) diff --git a/src/VanBusRx.cpp b/src/VanBusRx.cpp index ff02c3f..6f3c03b 100644 --- a/src/VanBusRx.cpp +++ b/src/VanBusRx.cpp @@ -542,10 +542,16 @@ inline __attribute__((always_inline)) unsigned int nBitsTakingIntoAccountJitter( return _nBits; } // nBitsTakingIntoAccountJitter +void IRAM_ATTR txTimerISRWrapper(void *arg) { + // Converts the void* argument to a pointer to the real ISR + auto callback = reinterpret_cast(arg); + callback(); // Call the old ISR function +} + void IRAM_ATTR SetTxBitTimer() { #ifdef ARDUINO_ARCH_ESP32 - timerAlarmDisable(timer); + timerStop(timer); #else // ! ARDUINO_ARCH_ESP32 timer1_disable(); #endif // ARDUINO_ARCH_ESP32 @@ -556,9 +562,8 @@ void IRAM_ATTR SetTxBitTimer() #ifdef ARDUINO_ARCH_ESP32 - timerAttachInterrupt(timer, VanBusRx.txTimerIsr, true); - timerAlarmWrite(timer, VanBusRx.txTimerTicks, true); - timerAlarmEnable(timer); + timerAttachInterruptArg(timer, txTimerISRWrapper, reinterpret_cast(VanBusRx.txTimerIsr)); + timerAlarm(timer, VanBusRx.txTimerTicks, true, 0); #else // ! ARDUINO_ARCH_ESP32 @@ -593,6 +598,11 @@ portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED; #define EXIT_CRITICAL_ISR #endif // ARDUINO_ARCH_ESP32 +void IRAM_ATTR waitAckIsrWrapper(void *arg) { + (void)arg; // Ignore arg + WaitAckIsr(); +} + // Pin level change interrupt handler void IRAM_ATTR RxPinChangeIsr() { @@ -846,7 +856,7 @@ void IRAM_ATTR RxPinChangeIsr() ) { #ifdef ARDUINO_ARCH_ESP32 - timerAlarmDisable(timer); + timerStop(timer); #else // ! ARDUINO_ARCH_ESP32 timer1_disable(); #endif // ARDUINO_ARCH_ESP32 @@ -1165,10 +1175,9 @@ void IRAM_ATTR RxPinChangeIsr() #ifdef ARDUINO_ARCH_ESP32 - timerAlarmDisable(timer); - timerAttachInterrupt(timer, &WaitAckIsr, true); - timerAlarmWrite(timer, 40 * 5, false); // 5 time slots = 5 * 8 us = 40 us - timerAlarmEnable(timer); + timerStop(timer); + timerAttachInterruptArg(timer, waitAckIsrWrapper, nullptr); + timerAlarm(timer, 40 * 5, false, 0); // 5 time slots = 5 * 8 us = 40 us #else // ! ARDUINO_ARCH_ESP32 @@ -1219,8 +1228,10 @@ bool TVanPacketRxQueue::Setup(uint8_t rxPin, int queueSize) #ifdef ARDUINO_ARCH_ESP32 // Clock to timer (prescaler) is always 80MHz, even F_CPU is 160 MHz. We want 0.2 microsecond resolution. - timer = timerBegin(0, 80 / 5, true); - timerAlarmDisable(timer); + // Prescaler : 80 MHz / 5 = 16 | Frequency : 80 MHz / 16 = 5 MHz + timer = timerBegin(5'000'000); + + timerEnd(timer); #else // ! ARDUINO_ARCH_ESP32 timer1_isr_init(); timer1_disable(); @@ -1263,7 +1274,7 @@ void TVanPacketRxQueue::Disable() if (pin == VAN_NO_PIN_ASSIGNED) return; // Call Setup first! #ifdef ARDUINO_ARCH_ESP32 - timerAlarmDisable(timer); + timerEnd(timer); #else // ! ARDUINO_ARCH_ESP32 timer1_disable(); #endif // ARDUINO_ARCH_ESP32 @@ -1312,10 +1323,15 @@ void IRAM_ATTR TVanPacketRxQueue::_AdvanceHead() if (nQueued <= startDroppingPacketsAt || (isEssentialPacket != 0 && (*isEssentialPacket)(*_head))) { // Move to next slot in queue - if (++_head == end) _head = pool; // Roll over if needed + TVanPacketRxDesc *newHead = _head + 1; + if (newHead == end) { + newHead = pool; // Roll over if needed + } + _head = newHead; // Keep track of queue fill level - if (++nQueued > maxQueued) maxQueued = nQueued; + int newNQueud = nQueued + 1; + if (newNQueud > maxQueued) maxQueued = newNQueud; } else { diff --git a/src/VanBusTx.cpp b/src/VanBusTx.cpp index 2a262a5..d539d76 100644 --- a/src/VanBusTx.cpp +++ b/src/VanBusTx.cpp @@ -35,18 +35,18 @@ void IRAM_ATTR FinishPacketTransmission(TVanPacketTxDesc* txDesc) VanBusRx.RegisterTxIsr(NULL); #ifdef ARDUINO_ARCH_ESP32 - timerAlarmDisable(timer); + timerEnd(timer); #else // ! ARDUINO_ARCH_ESP32 timer1_disable(); #endif // ARDUINO_ARCH_ESP32 - + TVanPacketTxQueue::alarmEnabled = false; } // if VanBusRx.SetLastMediaAccessAt(ESP.getCycleCount()); // It was me! :-) // Start listening again at other devices on the bus attachInterrupt(digitalPinToInterrupt(VanBusRx.pin), RxPinChangeIsr, CHANGE); -} // +} // // Send one bit on the VAN bus void IRAM_ATTR SendBitIsr() @@ -144,6 +144,11 @@ void IRAM_ATTR SendBitIsr() } // if } // SendBitIsr +void IRAM_ATTR sendBitIsrWrapper(void *arg) { + (void)arg; // Ignore arg + SendBitIsr(); +} + // Initializes the VAN packet transmitter void TVanPacketTxQueue::Setup(uint8_t theRxPin, uint8_t theTxPin) { @@ -236,13 +241,13 @@ void TVanPacketTxQueue::StartBitSendTimer() #ifdef ARDUINO_ARCH_ESP32 - if (! timerAlarmEnabled(timer)) + if (!alarmEnabled) { // Set a repetitive timer - timerAlarmDisable(timer); - timerAttachInterrupt(timer, &SendBitIsr, true); - timerAlarmWrite(timer, VAN_BIT_TIMER_TICKS, true); - timerAlarmEnable(timer); + timerEnd(timer); + timerAttachInterruptArg(timer, sendBitIsrWrapper, nullptr); + timerAlarm(timer, VAN_BIT_TIMER_TICKS, true, 0); + alarmEnabled = true; } // if #else // ! ARDUINO_ARCH_ESP32 @@ -270,7 +275,15 @@ bool TVanPacketTxQueue::WaitForHeadAvailable(unsigned int timeOutMs) unsigned int waitPoll = timeOutMs; // Relying on short-circuit boolean evaluation - while (! SlotAvailable() && (timeOutMs == 0 || --waitPoll > 0)) delay(1); + while (!SlotAvailable()) { + if (timeOutMs != 0) { + if (waitPoll == 0) + break; + waitPoll--; + } + delay(1); + } + return SlotAvailable(); } // TVanPacketTxQueue::WaitForHeadAvailable diff --git a/src/VanBusTx.h b/src/VanBusTx.h index d9838c6..9f50e30 100644 --- a/src/VanBusTx.h +++ b/src/VanBusTx.h @@ -120,16 +120,26 @@ class TVanPacketTxQueue static void StartBitSendTimer(); bool WaitForHeadAvailable(unsigned int timeOutMs = 10); + static bool alarmEnabled; + // Only to be called from ISR, unsafe otherwise void IRAM_ATTR _AdvanceTail() { _tail->state = VAN_TX_DONE; - if (++_tail == end) _tail = pool; // roll over if needed + TVanPacketTxDesc *newTail = _tail + 1; + if (newTail == end) { + newTail = pool; // Roll over if needed + } + _tail = newTail; } // _AdvanceTail void AdvanceHead() { - if (++_head == end) _head = pool; // roll over if needed + TVanPacketTxDesc *newHead = _head + 1; + if (newHead == end) { + newHead = pool; // Roll over if needed + } + _head = newHead; count++; } // AdvanceHead