diff --git a/GITHUB_SHA.h b/GITHUB_SHA.h index 0a5110a..42646fe 100644 --- a/GITHUB_SHA.h +++ b/GITHUB_SHA.h @@ -1 +1 @@ -#define GITHUB_SHA "devel-202312131041Z" +#define GITHUB_SHA "devel-202312251647Z" diff --git a/IO_EXIOExpander.h b/IO_EXIOExpander.h index 675d66c..c8bcba0 100644 --- a/IO_EXIOExpander.h +++ b/IO_EXIOExpander.h @@ -22,13 +22,10 @@ * This device driver will configure the device on startup, along with * interacting with the device for all input/output duties. * -* To create EX-IOExpander devices, these are defined in myHal.cpp: +* To create EX-IOExpander devices, these are defined in myAutomation.h: * (Note the device driver is included by default) * -* void halSetup() { -* // EXIOExpander::create(vpin, num_vpins, i2c_address); -* EXIOExpander::create(800, 18, 0x65); -* } +* HAL(EXIOExpander,800,18,0x65) * * All pins on an EX-IOExpander device are allocated according to the pin map for the specific * device in use. There is no way for the device driver to sanity check pins are used for the @@ -98,25 +95,30 @@ private: _numAnaloguePins = receiveBuffer[2]; // See if we already have suitable buffers assigned - size_t digitalBytesNeeded = (_numDigitalPins + 7) / 8; - if (_digitalPinBytes < digitalBytesNeeded) { - // Not enough space, free any existing buffer and allocate a new one - if (_digitalPinBytes > 0) free(_digitalInputStates); - _digitalInputStates = (byte*) calloc(_digitalPinBytes, 1); - _digitalPinBytes = digitalBytesNeeded; - } - size_t analogueBytesNeeded = _numAnaloguePins * 2; - if (_analoguePinBytes < analogueBytesNeeded) { - // Free any existing buffers and allocate new ones. - if (_analoguePinBytes > 0) { - free(_analogueInputBuffer); - free(_analogueInputStates); - free(_analoguePinMap); + if (_numDigitalPins>0) { + size_t digitalBytesNeeded = (_numDigitalPins + 7) / 8; + if (_digitalPinBytes < digitalBytesNeeded) { + // Not enough space, free any existing buffer and allocate a new one + if (_digitalPinBytes > 0) free(_digitalInputStates); + _digitalInputStates = (byte*) calloc(_digitalPinBytes, 1); + _digitalPinBytes = digitalBytesNeeded; + } + } + + if (_numAnaloguePins>0) { + size_t analogueBytesNeeded = _numAnaloguePins * 2; + if (_analoguePinBytes < analogueBytesNeeded) { + // Free any existing buffers and allocate new ones. + if (_analoguePinBytes > 0) { + free(_analogueInputBuffer); + free(_analogueInputStates); + free(_analoguePinMap); + } + _analogueInputStates = (uint8_t*) calloc(analogueBytesNeeded, 1); + _analogueInputBuffer = (uint8_t*) calloc(analogueBytesNeeded, 1); + _analoguePinMap = (uint8_t*) calloc(_numAnaloguePins, 1); + _analoguePinBytes = analogueBytesNeeded; } - _analogueInputStates = (uint8_t*) calloc(analogueBytesNeeded, 1); - _analogueInputBuffer = (uint8_t*) calloc(analogueBytesNeeded, 1); - _analoguePinMap = (uint8_t*) calloc(_numAnaloguePins, 1); - _analoguePinBytes = analogueBytesNeeded; } } else { DIAG(F("EX-IOExpander I2C:%s ERROR configuring device"), _I2CAddress.toString()); @@ -124,8 +126,8 @@ private: return; } } - // We now need to retrieve the analogue pin map - if (status == I2C_STATUS_OK) { + // We now need to retrieve the analogue pin map if there are analogue pins + if (status == I2C_STATUS_OK && _numAnaloguePins>0) { commandBuffer[0] = EXIOINITA; status = I2CManager.read(_I2CAddress, _analoguePinMap, _numAnaloguePins, commandBuffer, 1); } @@ -239,7 +241,7 @@ private: // If we're not doing anything now, check to see if a new input transfer is due. if (_readState == RDS_IDLE) { - if (currentMicros - _lastDigitalRead > _digitalRefresh) { // Delay for digital read refresh + if (currentMicros - _lastDigitalRead > _digitalRefresh && _numDigitalPins>0) { // Delay for digital read refresh // Issue new read request for digital states. As the request is non-blocking, the buffer has to // be allocated from heap (object state). _readCommandBuffer[0] = EXIORDD; @@ -247,7 +249,7 @@ private: // non-blocking read _lastDigitalRead = currentMicros; _readState = RDS_DIGITAL; - } else if (currentMicros - _lastAnalogueRead > _analogueRefresh) { // Delay for analogue read refresh + } else if (currentMicros - _lastAnalogueRead > _analogueRefresh && _numAnaloguePins>0) { // Delay for analogue read refresh // Issue new read for analogue input states _readCommandBuffer[0] = EXIORDAN; I2CManager.read(_I2CAddress, _analogueInputBuffer, diff --git a/WifiESP32.cpp b/WifiESP32.cpp index f0a857f..c990495 100644 --- a/WifiESP32.cpp +++ b/WifiESP32.cpp @@ -74,25 +74,39 @@ class NetworkClient { public: NetworkClient(WiFiClient c) { wifi = c; - }; - bool ok() { - return (inUse && wifi.connected()); - }; - bool recycle(WiFiClient c) { - - if (inUse == true) return false; - - // return false here until we have - // implemented a LRU timer - // if (LRU too recent) return false; - return false; - - wifi = c; inUse = true; + }; + bool active(byte clientId) { + if (!inUse) + return false; + if(!wifi.connected()) { + DIAG(F("Remove client %d"), clientId); + CommandDistributor::forget(clientId); + wifi.stop(); + inUse = false; + return false; + } return true; + } + bool recycle(WiFiClient c) { + if (wifi == c) { + if (inUse == true) + DIAG(F("WARNING: Duplicate")); + else + DIAG(F("Returning")); + inUse = true; + return true; + } + if (inUse == false) { + wifi = c; + inUse = true; + return true; + } + return false; }; WiFiClient wifi; - bool inUse = true; +private: + bool inUse; }; static std::vector clients; // a list to hold all clients @@ -282,37 +296,26 @@ void WifiESP::loop() { // really no good way to check for LISTEN especially in AP mode? wl_status_t wlStatus; if (APmode || (wlStatus = WiFi.status()) == WL_CONNECTED) { - // loop over all clients and remove inactive - for (clientId=0; clientIdhasClient()) { WiFiClient client; while (client = server->available()) { for (clientId=0; clientId=clients.size()) { NetworkClient nc(client); clients.push_back(nc); - DIAG(F("New client %d, %s"), clientId, client.remoteIP().toString().c_str()); + DIAG(F("New client %d, %s:%d"), clientId, client.remoteIP().toString().c_str(),client.remotePort()); } } } // loop over all connected clients + // this removes as a side effect inactive clients when checking ::active() for (clientId=0; clientId 0) { // read data from client @@ -350,7 +353,7 @@ void WifiESP::loop() { } // buffer filled, end with '\0' so we can use it as C string buffer[count]='\0'; - if((unsigned int)clientId <= clients.size() && clients[clientId].ok()) { + if((unsigned int)clientId <= clients.size() && clients[clientId].active(clientId)) { if (Diag::CMD || Diag::WITHROTTLE) DIAG(F("SEND %d:%s"), clientId, buffer); clients[clientId].wifi.write(buffer,count); @@ -383,8 +386,9 @@ void WifiESP::loop() { // prio task. On core1 this is not a problem // as there the wdt is disabled by the // arduio IDE startup routines. - if (xPortGetCoreID() == 0) + if (xPortGetCoreID() == 0) { feedTheDog0(); - yield(); + yield(); + } } #endif //ESP32 diff --git a/WifiInterface.cpp b/WifiInterface.cpp index d08ce29..9a4b37f 100644 --- a/WifiInterface.cpp +++ b/WifiInterface.cpp @@ -68,7 +68,9 @@ Stream * WifiInterface::wifiStream; #define NUM_SERIAL 3 #define SERIAL1 Serial3 #define SERIAL3 Serial5 -#elif defined(ARDUINO_NUCLEO_F413ZH) || defined(ARDUINO_NUCLEO_F429ZI) || defined(ARDUINO_NUCLEO_F439ZI) || defined(ARDUINO_NUCLEO_F446ZE) || defined(ARDUINO_NUCLEO_F412ZG) +#elif defined(ARDUINO_NUCLEO_F413ZH) || defined(ARDUINO_NUCLEO_F429ZI) \ + || defined(ARDUINO_NUCLEO_F446ZE) || defined(ARDUINO_NUCLEO_F412ZG) \ + || defined(ARDUINO_NUCLEO_F439ZI) #define NUM_SERIAL 3 #define SERIAL1 Serial6 #define SERIAL3 Serial2 diff --git a/version.h b/version.h index 8895dc2..bccbac1 100644 --- a/version.h +++ b/version.h @@ -3,11 +3,14 @@ #include "StringFormatter.h" -#define VERSION "5.2.15ethC" +#define VERSION "5.2.17ethCdf" +// 5.2.17 - ESP32 simplify network logic +// 5.2.16 - Bugfix to allow for devices using the EX-IOExpander protocol to have no analogue or no digital pins +// df - I2C DFPlayper capability // 5.2.15 - move call to CommandDistributor::broadcastPower() into the TrackManager::setTrackPower(*) functions // - add repeats to function packets that are not reminded in accordance with accessory packets // 5.2.14eth - Initial ethernet code for STM32F429ZI and F439ZI boards -// - CMRI RS485 connection +// C - CMRI RS485 connection // 5.2.14 - Reminder window DCC packet optimization // - Optional #define DISABLE_FUNCTION_REMINDERS // 5.2.13 - EXRAIL STEALTH