Tx gate now terminated via a HW timer callback. Using max priority task for SW watchdog.
This commit is contained in:
parent
c649517805
commit
c9298656fa
|
@ -116,6 +116,7 @@
|
|||
#include <SPIFFS.h>
|
||||
#include <nvs.h>
|
||||
#include "Utility/MQTTsetup.h"
|
||||
#include <FreeRTOS.h>
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in New Issue