diff --git a/src/Afterburner.cpp b/src/Afterburner.cpp index 2541280..0917303 100644 --- a/src/Afterburner.cpp +++ b/src/Afterburner.cpp @@ -116,6 +116,7 @@ #include #include #include "Utility/MQTTsetup.h" +#include // SSID & password now stored in NV storage - these are still the default values. //#define AP_SSID "Afterburner" @@ -221,9 +222,6 @@ bool bHaveWebClient = false; bool bBTconnected = false; long BootTime; -hw_timer_t *watchdogTimer = NULL; -hw_timer_t *JSONwatchdog = NULL; - //////////////////////////////////////////////////////////////////////////////////////////////////////// // Bluetooth instantiation // @@ -286,13 +284,39 @@ void parentKeyHandler(uint8_t event) ScreenManager.keyHandler(event); // call into the Screen Manager } - void interruptReboot() { ets_printf("Software watchdog reboot......\r\n"); esp_restart(); } +unsigned long WatchdogTick = -1; +unsigned long JSONWatchdogTick = -1; + +void WatchdogTask(void * param) +{ + for(;;) { + if(WatchdogTick >= 0) { + if(WatchdogTick == 0) { + interruptReboot(); + } + else { + WatchdogTick--; + } + } + if(JSONWatchdogTick >= 0) { + if(JSONWatchdogTick == 0) { + interruptReboot(); + } + else { + JSONWatchdogTick--; + } + } + vTaskDelay(10); + } +} + + //************************************************************************************************** //** ** //** WORKAROUND for crap ESP32 millis() standard function ** @@ -455,17 +479,17 @@ void setup() { setupGPIO(); #if USE_SW_WATCHDOG == 1 && USE_JTAG == 0 - // create a watchdog timer - watchdogTimer = timerBegin(0, 80, true); //timer 0, divisor 80 - timerAlarmWrite(watchdogTimer, 15000000, false); //set time in uS must be fed within this time or reboot - timerAttachInterrupt(watchdogTimer, &interruptReboot, true); - timerAlarmEnable(watchdogTimer); //enable interrupt + // create a high priority FreeRTOS task as a watchdog monitor + TaskHandle_t wdTask; + xTaskCreate(WatchdogTask, + "watchdogTask", + 2000, + NULL, + configMAX_PRIORITIES-1, + &wdTask); #endif - - JSONwatchdog = timerBegin(1, 80, true); - timerAlarmWrite(JSONwatchdog, 60000000, false); //set time in uS must be fed within this time or reboot - timerAttachInterrupt(JSONwatchdog, &interruptReboot, true); - timerAlarmDisable(JSONwatchdog); //disable interrupt for now + JSONWatchdogTick = -1; + WatchdogTick = -1; FilteredSamples.ipVolts.setRounding(0.1); FilteredSamples.GlowAmps.setRounding(0.01); @@ -607,9 +631,7 @@ void loop() case CommStates::Idle: -#if USE_SW_WATCHDOG == 1 && USE_JTAG == 0 - feedWatchdog(); //reset timer (feed watchdog) -#endif + feedWatchdog(); // feed watchdog doStreaming(); // do wifi, BT tx etc when NOT in midst of handling blue wire // this especially avoids E-07 faults due to larger data transfers @@ -1752,28 +1774,22 @@ void ShowOTAScreen(int percent, eOTAmodes updateType) void feedWatchdog() { -#if USE_JTAG == 0 +#if USE_SW_WATCHDOG == 1 && USE_JTAG == 0 // BEST NOT USE WATCHDOG WITH JTAG DEBUG :-) - uint64_t timeRem = timerRead(watchdogTimer); - if(timeRem > 500000) // 500ms - DebugPort.printf("WD time = %lld\r\n", timeRem); // print longer WD intervals - - timerWrite(watchdogTimer, 0); //reset timer (feed watchdog) - timerAlarmWrite(watchdogTimer, 15000000, false); //set time in uS must be fed within this time or reboot + WatchdogTick = 1500; +#else + WatchdogTick = -1; #endif } void doJSONwatchdog(int topup) { - if(topup) { - timerWrite(JSONwatchdog, 0); //reset timer (feed watchdog) - uint64_t deathtime = topup * 1000000; - timerAlarmWrite(JSONwatchdog, deathtime, false); //set time in uS must be fed within this time or reboot - timerAlarmEnable(JSONwatchdog); //enable interrupt - } - else { - timerAlarmDisable(JSONwatchdog); //disable interrupt - } + if(topup) { + JSONWatchdogTick = topup * 100; + } + else { + JSONWatchdogTick = -1; + } } diff --git a/src/Protocol/TxManage.cpp b/src/Protocol/TxManage.cpp index 547ad4f..6c7dd89 100644 --- a/src/Protocol/TxManage.cpp +++ b/src/Protocol/TxManage.cpp @@ -48,6 +48,9 @@ extern void DebugReportFrame(const char* hdr, const CProtocol&, const char* ftr) // _____________________________________________________________________ // Tx Data ||||||||||||||| +unsigned long CTxManage::m_nStartTime = 0; +int CTxManage::m_nTxGatePin = 0; + CTxManage::CTxManage(int TxGatePin, HardwareSerial& serial) : m_BlueWireSerial(serial), m_TxFrame(CProtocol::CtrlMode) @@ -58,12 +61,30 @@ CTxManage::CTxManage(int TxGatePin, HardwareSerial& serial) : m_nStartTime = 0; m_nTxGatePin = TxGatePin; _rawCommand = 0; + m_HWTimer = NULL; } +// static function used for the tx gate termination +void CTxManage::GateTerminate() +{ + digitalWrite(m_nTxGatePin, LOW); // default to receive mode + m_nStartTime = 0; // cancel, we are DONE +} + + void CTxManage::begin() { pinMode(m_nTxGatePin, OUTPUT); digitalWrite(m_nTxGatePin, LOW); // default to receive mode + + // use a hardware timer to terminate the Tx gate shortly after the completion of the 24 byte transmit packet + m_HWTimer = timerBegin(2, 80, true); + //set time in uS of Tx gate from when actual tx data bytes are loaded + // 240 bits @ 25000bps is 9.6ms, we'll use 9.7ms for a bit of tolerance + timerAlarmWrite(m_HWTimer, 10000-300, false); + timerAttachInterrupt(m_HWTimer, &GateTerminate, true); + timerAlarmDisable(m_HWTimer); //disable interrupt for now + timerSetAutoReload(m_HWTimer, false); } void @@ -231,37 +252,33 @@ CTxManage::PrepareFrame(const CProtocol& basisFrame, bool isBTCmaster) void CTxManage::Start(unsigned long timenow) { - if(timenow == 0) // avoid a black hole if millis() has wrapped to zero - timenow++; - - m_nStartTime = timenow; + m_nStartTime = timenow + m_nStartTime; // create a dwell period if an OEM controller is present after it's data exchange + m_nStartTime |= 1; // avoid a black hole if millis() has wrapped to zero m_bTxPending = true; } // generate a Tx Gate, then send the TxFrame to the Blue wire -// Note the serial data is ISR driven, we need to hold off -// for a while to let teh buffewred dat clear before closing the Tx Gate. +// Note the serial data is ISR driven, we supply all 24 bytes to the Tx buffer which is then drained automatically +// the Tx Gate is closed shortly after the last byte is completed. bool CTxManage::CheckTx(unsigned long timenow) { - if(m_nStartTime) { + if(m_nStartTime && m_bTxPending) { long diff = timenow - m_nStartTime; - if(diff > m_nStartDelay) { + if(diff >= 0) { // dwell since OEM exchange has expired ? // begin front porch of Tx gating pulse digitalWrite(m_nTxGatePin, HIGH); } - if(m_bTxPending && (diff > (m_nStartDelay + m_nFrontPorch))) { - // front porch expired, perform serial transmission + if(diff >= m_nFrontPorch) { + // front porch expired, start actual serial transmission // Tx gate remains held high + // it is then brought low by the timer alarm callback, which also cancels m_nStartTime m_bTxPending = false; m_BlueWireSerial.write(m_TxFrame.Data, 24); // write native binary values - } - if(diff > (m_nStartDelay + m_nFrameTime)) { - // conclude Tx gating after (emperical) delay - digitalWrite(m_nTxGatePin, LOW); - m_nStartTime = 0; // cancel, we are DONE + timerWrite(m_HWTimer, 0); //reset tx gate timeout + timerAlarmEnable(m_HWTimer); // timeout will cause cessation of the Tx gate } } return m_nStartTime == 0; // returns true when done diff --git a/src/Protocol/TxManage.h b/src/Protocol/TxManage.h index 60a139f..5070841 100644 --- a/src/Protocol/TxManage.h +++ b/src/Protocol/TxManage.h @@ -25,7 +25,7 @@ class CTxManage { const int m_nStartDelay = 20; const int m_nFrameTime = 14; - const int m_nFrontPorch = 2; + const int m_nFrontPorch = 0; public: CTxManage(int TxGatePin, HardwareSerial& serial); @@ -37,6 +37,7 @@ public: bool CheckTx(unsigned long timenow); void begin(); const CProtocol& getFrame() const { return m_TxFrame; }; + static void GateTerminate(); private: HardwareSerial& m_BlueWireSerial; @@ -44,9 +45,11 @@ private: bool m_bOnReq; bool m_bOffReq; bool m_bTxPending; - int m_nTxGatePin; + static int m_nTxGatePin; uint8_t _rawCommand; - unsigned long m_nStartTime; + static unsigned long m_nStartTime; + hw_timer_t *m_HWTimer; + }; diff --git a/src/WiFi/BTCWebServer.cpp b/src/WiFi/BTCWebServer.cpp index 6e94ef6..69ec06d 100644 --- a/src/WiFi/BTCWebServer.cpp +++ b/src/WiFi/BTCWebServer.cpp @@ -766,9 +766,7 @@ void onUploadProgression() // handle file fragments of form upload else if (upload.status == UPLOAD_FILE_WRITE) { -#if USE_SW_WATCHDOG == 1 feedWatchdog(); // we get stuck here for a while, don't let the watchdog bite! -#endif int sts = BrowserUpload.fragment(upload); if(sts < 0) { sprintf(JSON, "{\"progress\":%d}", sts); diff --git a/src/WiFi/BTCota.cpp b/src/WiFi/BTCota.cpp index 411af3f..459d19f 100644 --- a/src/WiFi/BTCota.cpp +++ b/src/WiFi/BTCota.cpp @@ -67,9 +67,7 @@ void initOTA(){ DebugPort.println("Start updating " + type); DebugPort.handle(); // keep telnet spy alive ShowOTAScreen(); -#if USE_SW_WATCHDOG == 1 feedWatchdog(); // we get stuck here for a while, don't let the watchdog bite! -#endif }) .onEnd([]() { DebugPort.println("\nEnd");