From 53842ad0c53710789323f73edeeaaaf23b40f80d Mon Sep 17 00:00:00 2001 From: Ing-Dom Date: Sun, 17 Dec 2023 14:42:04 +0100 Subject: [PATCH 1/9] Add the possibility to have a callback function signaling knx activity (for e.g. flashing LEDs) Can be enabled with KNX_ACTIVITYCALLBACK # Conflicts: # src/knx/ip_data_link_layer.cpp --- src/knx/bits.h | 8 ++++++++ src/knx/data_link_layer.cpp | 3 +++ src/knx/data_link_layer.h | 5 ++++- src/knx/ip_data_link_layer.cpp | 10 ++++++++++ src/knx/network_layer_entity.cpp | 5 +++++ src/knx/network_layer_entity.h | 1 + src/knx/tpuart_data_link_layer.cpp | 8 +++++++- src/knx_facade.h | 21 +++++++++++++++++++++ 8 files changed, 59 insertions(+), 2 deletions(-) diff --git a/src/knx/bits.h b/src/knx/bits.h index c5ce526f..fe58f48d 100644 --- a/src/knx/bits.h +++ b/src/knx/bits.h @@ -94,6 +94,14 @@ void printHex(const char* suffix, const uint8_t *data, size_t length, bool newli #define printHex(...) do {} while(0) #endif +#ifdef KNX_ACTIVITYCALLBACK +#define KNX_ACTIVITYCALLBACK_DIR 0x00 +#define KNX_ACTIVITYCALLBACK_DIR_RECV 0x00 +#define KNX_ACTIVITYCALLBACK_DIR_SEND 0x01 +#define KNX_ACTIVITYCALLBACK_IPUNICAST 0x02 +#define KNX_ACTIVITYCALLBACK_NET 0x04 +#endif + const uint8_t* popByte(uint8_t& b, const uint8_t* data); const uint8_t* popWord(uint16_t& w, const uint8_t* data); const uint8_t* popInt(uint32_t& i, const uint8_t* data); diff --git a/src/knx/data_link_layer.cpp b/src/knx/data_link_layer.cpp index b75c1ecc..e2f601e2 100644 --- a/src/knx/data_link_layer.cpp +++ b/src/knx/data_link_layer.cpp @@ -9,6 +9,9 @@ DataLinkLayer::DataLinkLayer(DeviceObject& devObj, NetworkLayerEntity& netLayerEntity, Platform& platform) : _deviceObject(devObj), _networkLayerEntity(netLayerEntity), _platform(platform) { +#ifdef KNX_ACTIVITYCALLBACK + _netIndex = netLayerEntity.getEntityIndex(); +#endif } #ifdef USE_CEMI_SERVER diff --git a/src/knx/data_link_layer.h b/src/knx/data_link_layer.h index 9e4d6884..0270d31f 100644 --- a/src/knx/data_link_layer.h +++ b/src/knx/data_link_layer.h @@ -42,5 +42,8 @@ class DataLinkLayer Platform& _platform; #ifdef USE_CEMI_SERVER CemiServer* _cemiServer; -#endif +#endif +#ifdef KNX_ACTIVITYCALLBACK + uint8_t _netIndex = 0; +#endif }; diff --git a/src/knx/ip_data_link_layer.cpp b/src/knx/ip_data_link_layer.cpp index 43a7a595..b18f4d2a 100644 --- a/src/knx/ip_data_link_layer.cpp +++ b/src/knx/ip_data_link_layer.cpp @@ -30,6 +30,9 @@ bool IpDataLinkLayer::sendFrame(CemiFrame& frame) if(isSendLimitReached()) return false; bool success = sendBytes(packet.data(), packet.totalLength()); +#ifdef KNX_ACTIVITYCALLBACK + knx.Activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_SEND << KNX_ACTIVITYCALLBACK_DIR)); +#endif dataConReceived(frame, success); return success; } @@ -51,6 +54,10 @@ void IpDataLinkLayer::loop() || buffer[1] != KNXIP_PROTOCOL_VERSION) return; +#ifdef KNX_ACTIVITYCALLBACK + knx.Activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_RECV << KNX_ACTIVITYCALLBACK_DIR)); +#endif + uint16_t code; popWord(code, buffer + 2); switch ((KnxIpServiceType)code) @@ -67,6 +74,9 @@ void IpDataLinkLayer::loop() KnxIpSearchResponse searchResponse(_ipParameters, _deviceObject); auto hpai = searchRequest.hpai(); +#ifdef KNX_ACTIVITYCALLBACK + knx.Activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_SEND << KNX_ACTIVITYCALLBACK_DIR) | (KNX_ACTIVITYCALLBACK_IPUNICAST)); +#endif _platform.sendBytesUniCast(hpai.ipAddress(), hpai.ipPortNumber(), searchResponse.data(), searchResponse.totalLength()); break; } diff --git a/src/knx/network_layer_entity.cpp b/src/knx/network_layer_entity.cpp index 6e51736d..6463d830 100644 --- a/src/knx/network_layer_entity.cpp +++ b/src/knx/network_layer_entity.cpp @@ -23,6 +23,11 @@ DptMedium NetworkLayerEntity::mediumType() const return _dataLinkLayer->mediumType(); } +uint8_t NetworkLayerEntity::getEntityIndex() +{ + return _entityIndex; +} + void NetworkLayerEntity::dataIndication(AckType ack, AddressType addrType, uint16_t destination, FrameFormat format, NPDU& npdu, Priority priority, uint16_t source) { _netLayer.dataIndication(ack, addrType, destination, format, npdu, priority, source, _entityIndex); diff --git a/src/knx/network_layer_entity.h b/src/knx/network_layer_entity.h index e20d6114..82db48cf 100644 --- a/src/knx/network_layer_entity.h +++ b/src/knx/network_layer_entity.h @@ -19,6 +19,7 @@ class NetworkLayerEntity DataLinkLayer& dataLinkLayer(); DptMedium mediumType() const; + uint8_t getEntityIndex(); // from data link layer void dataIndication(AckType ack, AddressType addType, uint16_t destination, FrameFormat format, NPDU& npdu, diff --git a/src/knx/tpuart_data_link_layer.cpp b/src/knx/tpuart_data_link_layer.cpp index 22bbf133..a17b2a4d 100644 --- a/src/knx/tpuart_data_link_layer.cpp +++ b/src/knx/tpuart_data_link_layer.cpp @@ -7,6 +7,7 @@ #include "device_object.h" #include "address_table_object.h" #include "cemi_frame.h" +#include "knx_facade.h" #include #include @@ -546,8 +547,10 @@ TpUartDataLinkLayer::TpUartDataLinkLayer(DeviceObject& devObj, void TpUartDataLinkLayer::frameBytesReceived(uint8_t* buffer, uint16_t length) { //printHex("=>", buffer, length); +#ifdef KNX_ACTIVITYCALLBACK + knx.Activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_RECV << KNX_ACTIVITYCALLBACK_DIR)); +#endif CemiFrame frame(buffer, length); - frameReceived(frame); } @@ -653,6 +656,9 @@ bool TpUartDataLinkLayer::sendSingleFrameByte() if (_TxByteCnt >= _sendBufferLength) { _TxByteCnt = 0; +#ifdef KNX_ACTIVITYCALLBACK + knx.Activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_SEND << KNX_ACTIVITYCALLBACK_DIR)); +#endif return false; } return true; diff --git a/src/knx_facade.h b/src/knx_facade.h index 7facf61c..c1fb0ca9 100644 --- a/src/knx_facade.h +++ b/src/knx_facade.h @@ -70,6 +70,9 @@ typedef uint8_t* (*SaveCallback)(uint8_t* buffer); typedef void (*IsrFunctionPtr)(); typedef void (*ProgLedOnCallback)(); typedef void (*ProgLedOffCallback)(); +#ifdef KNX_ACTIVITYCALLBACK +typedef void (*ActivityCallback)(uint8_t info); +#endif template class KnxFacade : private SaveRestore { @@ -187,6 +190,21 @@ template class KnxFacade : private SaveRestore _progLedOnCallback = progLedOnCallback; } +#ifdef KNX_ACTIVITYCALLBACK + /// @brief sets the Callback Function indicating sent or received telegrams + /// @param activityCallback + /// @details the info parameter + void setActivityCallback(ActivityCallback activityCallback) + { + _activityCallback = activityCallback; + } + + void Activity(uint8_t info) + { + if(_activityCallback) + _activityCallback(info); + } +#endif int32_t buttonPin() { @@ -414,6 +432,9 @@ template class KnxFacade : private SaveRestore B& _bau; ProgLedOnCallback _progLedOnCallback = 0; ProgLedOffCallback _progLedOffCallback = 0; +#ifdef KNX_ACTIVITYCALLBACK + ActivityCallback _activityCallback = 0; +#endif uint32_t _ledPinActiveOn = KNX_LED_ACTIVE_ON; uint32_t _ledPin = KNX_LED; int32_t _buttonPin = KNX_BUTTON; From 38300f7e0dd18bbfb840ae9b8ee02022bfc53188 Mon Sep 17 00:00:00 2001 From: Marco Scholl Date: Wed, 20 Dec 2023 09:24:29 +0100 Subject: [PATCH 2/9] Revert "fix serialNumberReadResponse" This reverts commit 9f28f8efd26e4942b0a5a1d52a9f731efaf3e7a5. --- src/knx/application_layer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/knx/application_layer.cpp b/src/knx/application_layer.cpp index c6aedb0c..05df9a5b 100644 --- a/src/knx/application_layer.cpp +++ b/src/knx/application_layer.cpp @@ -551,7 +551,7 @@ void ApplicationLayer::systemNetworkParameterReadResponse(Priority priority, Hop void ApplicationLayer::domainAddressSerialNumberReadResponse(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, const uint8_t* rfDoA, const uint8_t* knxSerialNumber) { - CemiFrame frame(11); + CemiFrame frame(13); APDU& apdu = frame.apdu(); apdu.type(DomainAddressSerialNumberResponse); From 3c29d164508ea37e8dab78f174e56bf54b83f5da Mon Sep 17 00:00:00 2001 From: Marco Scholl Date: Wed, 20 Dec 2023 09:35:29 +0100 Subject: [PATCH 3/9] fix IndividualAddressSerialNumberReadResponse --- src/knx/application_layer.cpp | 8 ++++---- src/knx/application_layer.h | 2 +- src/knx/bau27B0.cpp | 5 +---- src/knx/bau_systemB.cpp | 2 +- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/knx/application_layer.cpp b/src/knx/application_layer.cpp index 05df9a5b..1e8ccec6 100644 --- a/src/knx/application_layer.cpp +++ b/src/knx/application_layer.cpp @@ -567,19 +567,19 @@ void ApplicationLayer::domainAddressSerialNumberReadResponse(Priority priority, //TODO: ApplicationLayer::IndividualAddressSerialNumberWriteRequest() //TODO: ApplicationLayer::IndividualAddressSerialNumberReadRequest() -void ApplicationLayer::IndividualAddressSerialNumberReadResponse(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, const uint8_t* rfDoA, +void ApplicationLayer::IndividualAddressSerialNumberReadResponse(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, const uint8_t* domainAddress, const uint8_t* knxSerialNumber) { - CemiFrame frame(13); + CemiFrame frame(11); APDU& apdu = frame.apdu(); apdu.type(IndividualAddressSerialNumberResponse); uint8_t* data = apdu.data() + 1; memcpy(data, knxSerialNumber, 6); - memcpy(data + 6, rfDoA, 6); + memcpy(data + 6, domainAddress, 2); - //apdu.printPDU(); + //apdu.printPDU(); dataBroadcastRequest(AckDontCare, hopType, SystemPriority, apdu, secCtrl); } diff --git a/src/knx/application_layer.h b/src/knx/application_layer.h index bd14ef26..c7593c8c 100644 --- a/src/knx/application_layer.h +++ b/src/knx/application_layer.h @@ -154,7 +154,7 @@ class ApplicationLayer uint8_t* testResult, uint16_t testResultLength); void domainAddressSerialNumberReadResponse(Priority priority, HopCountType hopType, const SecurityControl& secCtrl, const uint8_t* rfDoA, const uint8_t* knxSerialNumber); - void IndividualAddressSerialNumberReadResponse(Priority priority, HopCountType hopType, const SecurityControl& secCtrl, const uint8_t* rfDoA, + void IndividualAddressSerialNumberReadResponse(Priority priority, HopCountType hopType, const SecurityControl& secCtrl, const uint8_t* domainAddress, const uint8_t* knxSerialNumber); #pragma endregion diff --git a/src/knx/bau27B0.cpp b/src/knx/bau27B0.cpp index 9b119f9b..6180539a 100644 --- a/src/knx/bau27B0.cpp +++ b/src/knx/bau27B0.cpp @@ -169,10 +169,7 @@ void Bau27B0::domainAddressSerialNumberReadIndication(Priority priority, HopCoun void Bau27B0::individualAddressSerialNumberReadIndication(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint8_t* knxSerialNumber) { - // If the received serial number matches our serial number - // then send a response with the current RF domain address stored in the RF medium object and the serial number - if (!memcmp(knxSerialNumber, _deviceObj.propertyData(PID_SERIAL_NUMBER), 6)) - _appLayer.IndividualAddressSerialNumberReadResponse(priority, hopType, secCtrl, _rfMediumObj.rfDomainAddress(), knxSerialNumber); + #pragma warning "individualAddressSerialNumberReadIndication is not available for rf" } void Bau27B0::domainAddressSerialNumberWriteLocalConfirm(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, const uint8_t* rfDoA, diff --git a/src/knx/bau_systemB.cpp b/src/knx/bau_systemB.cpp index 9b8897fe..fc1fdf81 100644 --- a/src/knx/bau_systemB.cpp +++ b/src/knx/bau_systemB.cpp @@ -494,7 +494,7 @@ void BauSystemB::individualAddressSerialNumberReadIndication(Priority priority, // An open medium BAU has to override this method and provide a proper domain address. if (!memcmp(knxSerialNumber, _deviceObj.propertyData(PID_SERIAL_NUMBER), 6)) { - uint8_t emptyDomainAddress[6] = {0x00}; + uint8_t emptyDomainAddress[2] = {0x00}; applicationLayer().IndividualAddressSerialNumberReadResponse(priority, hopType, secCtrl, emptyDomainAddress, knxSerialNumber); } } From 470ec8b52157dc57550e6d28e0f517c513180abd Mon Sep 17 00:00:00 2001 From: Ing-Dom Date: Sun, 24 Dec 2023 10:20:23 +0100 Subject: [PATCH 4/9] this adds IP (WiFi and wired Ethernet) support to the rp2040 platform. It includes also some optimizations for KNX-IP in general. Squashed commit of the following: commit 14bf9bef25ccc2c9bddefe7c8f1e0f6b1d63b3bc Author: Ing-Dom Date: Sun Dec 24 10:17:05 2023 +0100 clean up, remove KNX_LOG_IP commit 57223e46e414010662772989c2520cf1960ed268 Merge: 2911448 a870dd8 Author: Ing-Dom Date: Sun Dec 24 10:10:19 2023 +0100 Merge remote-tracking branch 'remotes/origin/master' into rp2040_ip commit 2911448d22a454aacae472762677381acce6a159 Merge: 8ac6aec 3c29d16 Author: Dom Date: Wed Dec 20 10:04:32 2023 +0100 Merge pull request #13 from OpenKNX/fix_serialnumber Fix serialnumber commit 8ac6aeccce20a9e5e1bbf5300008a72383f7ee71 Author: Ing-Dom Date: Thu Dec 14 12:28:02 2023 +0100 fix macAddress reading for Wifi commit 9db2cd58708e9d7bbfd485ada2ff38c829447c42 Author: Ing-Dom Date: Tue Dec 12 13:08:53 2023 +0100 remove LARGE_BUFFERS and clean up header files of ETHERNET_GENERIC commit 2f229ae90c6f72e01c2a9b9efe134f75fc85547c Author: Ing-Dom Date: Tue Dec 12 00:56:32 2023 +0100 temporary fix, solution needed for tunneling commit f6e7e619a454f43db10e644b41c58b43a1a2b453 Author: Ing-Dom Date: Mon Dec 11 13:54:26 2023 +0100 unified approach for different ip stacks with rp2040 plattform commit 4723edab84986bca6d31ea7b3083b1b7b8ef907e Author: Marco Scholl Date: Mon Dec 11 08:34:25 2023 +0100 wip commit 5bf3e615c8649dd9c34be7b1fe6ad4062ce96c34 Author: Ing-Dom Date: Thu Dec 7 14:53:42 2023 +0100 ip and not ip in one rp2040 plattform commit aaca34a237686c5389888b7bd040b860331bdbff Merge: fd97f59 d44606d Author: Dom Date: Wed Dec 6 15:30:17 2023 +0100 Merge branch 'thelsing:master' into rp2040_lwip commit fd97f5920ef486ca955f5425cbcaec062e3ef977 Author: Marco Scholl Date: Thu Nov 30 23:19:13 2023 +0100 dd sime ifdef to allow build without ip interface commit c665a79db9cee7063dd77a155108633db81ef8e8 Author: Ing-Dom Date: Tue Nov 14 10:03:48 2023 +0100 stub for handling SearchRequestExt to prevent console messages commit 50745be66681616681f67d7bdf17008f5d19640d Author: Ing-Dom Date: Tue Nov 14 00:02:49 2023 +0100 adding ip support for rp2040 plattform --- src/knx/ip_data_link_layer.cpp | 11 ++- src/knx/ip_parameter_object.cpp | 3 +- src/knx/knx_ip_frame.h | 2 + src/knx_facade.cpp | 6 +- src/knx_facade.h | 6 +- src/rp2040_arduino_platform.cpp | 126 +++++++++++++++++++++++++++++++- src/rp2040_arduino_platform.h | 72 ++++++++++++++++++ 7 files changed, 218 insertions(+), 8 deletions(-) diff --git a/src/knx/ip_data_link_layer.cpp b/src/knx/ip_data_link_layer.cpp index 43a7a595..75783fbb 100644 --- a/src/knx/ip_data_link_layer.cpp +++ b/src/knx/ip_data_link_layer.cpp @@ -70,9 +70,16 @@ void IpDataLinkLayer::loop() _platform.sendBytesUniCast(hpai.ipAddress(), hpai.ipPortNumber(), searchResponse.data(), searchResponse.totalLength()); break; } + case SearchRequestExt: + { + // FIXME, implement (not needed atm) + break; + } default: - print("Unhandled service identifier: "); - println(code, HEX); + { + // print("Unhandled service identifier: "); + // println(code, HEX); + } } } diff --git a/src/knx/ip_parameter_object.cpp b/src/knx/ip_parameter_object.cpp index dcbbba35..3de44d34 100644 --- a/src/knx/ip_parameter_object.cpp +++ b/src/knx/ip_parameter_object.cpp @@ -34,8 +34,9 @@ IpParameterObject::IpParameterObject(DeviceObject& deviceObject, Platform& platf io->_deviceObject.individualAddress(getWord(data)); return 1; }), + new DataProperty(PID_CURRENT_IP_ASSIGNMENT_METHOD, false, PDT_UNSIGNED_CHAR, 0, ReadLv3 | WriteLv3), new DataProperty(PID_IP_ASSIGNMENT_METHOD, true, PDT_UNSIGNED_CHAR, 1, ReadLv3 | WriteLv3), - new DataProperty(PID_IP_CAPABILITIES, true, PDT_BITSET8, 1, ReadLv3 | WriteLv1), + new DataProperty(PID_IP_CAPABILITIES, true, PDT_BITSET8, 0, ReadLv3 | WriteLv1), // must be set by application due to capabilities of the used ip stack new CallbackProperty(this, PID_CURRENT_IP_ADDRESS, false, PDT_UNSIGNED_LONG, 1, ReadLv3 | WriteLv0, [](IpParameterObject* io, uint16_t start, uint8_t count, uint8_t* data) -> uint8_t { diff --git a/src/knx/knx_ip_frame.h b/src/knx/knx_ip_frame.h index f8a421f5..c6c1c518 100644 --- a/src/knx/knx_ip_frame.h +++ b/src/knx/knx_ip_frame.h @@ -23,6 +23,8 @@ enum KnxIpServiceType ConnectionStateResponse = 0x208, DisconnectRequest = 0x209, DisconnectResponse = 0x20A, + SearchRequestExt = 0x20B, + SearchResponseExt = 0x20C, DeviceConfigurationRequest = 0x310, DeviceConfigurationAck = 0x311, TunnelingRequest = 0x420, diff --git a/src/knx_facade.cpp b/src/knx_facade.cpp index 1dee9fcc..03e4ce63 100644 --- a/src/knx_facade.cpp +++ b/src/knx_facade.cpp @@ -53,13 +53,17 @@ #error "Mask version not supported on ARDUINO_ARCH_SAMD" #endif #elif defined(ARDUINO_ARCH_RP2040) - // predefined global instance for TP or RF or TP/RF coupler + // predefined global instance for TP or RF or IP or TP/RF coupler or TP/IP coupler #if MASK_VERSION == 0x07B0 KnxFacade knx(buttonEvent); #elif MASK_VERSION == 0x27B0 KnxFacade knx(buttonEvent); + #elif MASK_VERSION == 0x57B0 + KnxFacade knx(buttonEvent); #elif MASK_VERSION == 0x2920 KnxFacade knx(buttonEvent); + #elif MASK_VERSION == 0x091A + KnxFacade knx(buttonEvent); #else #error "Mask version not supported on ARDUINO_ARCH_RP2040" #endif diff --git a/src/knx_facade.h b/src/knx_facade.h index 7facf61c..647b22be 100644 --- a/src/knx_facade.h +++ b/src/knx_facade.h @@ -480,13 +480,17 @@ template class KnxFacade : private SaveRestore #error "Mask version not supported on ARDUINO_ARCH_SAMD" #endif #elif defined(ARDUINO_ARCH_RP2040) - // predefined global instance for TP or RF or TP/RF coupler + // predefined global instance for TP or RF or TP/RF or TP/IP coupler #if MASK_VERSION == 0x07B0 extern KnxFacade knx; #elif MASK_VERSION == 0x27B0 extern KnxFacade knx; + #elif MASK_VERSION == 0x57B0 + extern KnxFacade knx; #elif MASK_VERSION == 0x2920 extern KnxFacade knx; + #elif MASK_VERSION == 0x091A + extern KnxFacade knx; #else #error "Mask version not supported on ARDUINO_ARCH_RP2040" #endif diff --git a/src/rp2040_arduino_platform.cpp b/src/rp2040_arduino_platform.cpp index 44eb8c4b..c2b64344 100644 --- a/src/rp2040_arduino_platform.cpp +++ b/src/rp2040_arduino_platform.cpp @@ -4,7 +4,7 @@ Plattform for Raspberry Pi Pico and other RP2040 boards by SirSydom 2021-2022 made to work with arduino-pico - "Raspberry Pi Pico Arduino core, for all RP2040 boards" -by Earl E. Philhower III https://github.com/earlephilhower/arduino-pico V1.11.0 +by Earl E. Philhower III https://github.com/earlephilhower/arduino-pico RTTI must be set to enabled in the board options @@ -17,6 +17,10 @@ EEPROM Emulation from arduino-pico core (max 4k) can be use by defining USE_RP20 A RAM-buffered Flash can be use by defining USE_RP2040_LARGE_EEPROM_EMULATION +For usage of KNX-IP you have to define either +- KNX_IP_W5500 (use the arduino-pico core's w5500 lwip stack) +- KNX_IP_WIFI (use the arduino-pico core's PiPicoW lwip stack) +- KNX_IP_GENERIC (use the Ethernet_Generic stack) ----------------------------------------------------*/ @@ -45,8 +49,11 @@ A RAM-buffered Flash can be use by defining USE_RP2040_LARGE_EEPROM_EMULATION #endif #endif -#ifndef KNX_SERIAL -#define KNX_SERIAL Serial1 +#ifdef KNX_IP_W5500 +extern Wiznet5500lwIP KNX_NETIF; +#elif defined(KNX_IP_WIFI) +#elif defined(KNX_IP_GENERIC) + #endif RP2040ArduinoPlatform::RP2040ArduinoPlatform() @@ -234,6 +241,119 @@ void RP2040ArduinoPlatform::writeBufferedEraseBlock() } } #endif + +#if defined(KNX_NETIF) +uint32_t RP2040ArduinoPlatform::currentIpAddress() +{ + return KNX_NETIF.localIP(); +} +uint32_t RP2040ArduinoPlatform::currentSubnetMask() +{ + return KNX_NETIF.subnetMask(); +} +uint32_t RP2040ArduinoPlatform::currentDefaultGateway() +{ + return KNX_NETIF.gatewayIP(); +} +void RP2040ArduinoPlatform::macAddress(uint8_t* addr) +{ +#if defined(KNX_IP_W5500) + addr = KNX_NETIF.getNetIf()->hwaddr; +#elif defined(KNX_IP_WIFI) + uint8_t macaddr[6] = {0,0,0,0,0,0}; + addr = KNX_NETIF.macAddress(macaddr); +#elif defined(KNX_IP_GENERIC) + KNX_NETIF.MACAddress(addr); +#endif +} + +// multicast +void RP2040ArduinoPlatform::setupMultiCast(uint32_t addr, uint16_t port) +{ + mcastaddr = IPAddress(htonl(addr)); + _port = port; + uint8_t result = _udp.beginMulticast(mcastaddr, port); + (void) result; + + #ifdef KNX_IP_GENERIC + //if(!_unicast_socket_setup) + // _unicast_socket_setup = UDP_UNICAST.begin(3671); + #endif + + // print("Setup Mcast addr: "); + // print(mcastaddr.toString().c_str()); + // print(" on port: "); + // print(port); + // print(" result "); + // println(result); +} + +void RP2040ArduinoPlatform::closeMultiCast() +{ + _udp.stop(); +} + +bool RP2040ArduinoPlatform::sendBytesMultiCast(uint8_t* buffer, uint16_t len) +{ + // printHex("<- ",buffer, len); + + //ToDo: check if Ethernet is able to receive, return false if not + _udp.beginPacket(mcastaddr, _port); + _udp.write(buffer, len); + _udp.endPacket(); + return true; +} + +int RP2040ArduinoPlatform::readBytesMultiCast(uint8_t* buffer, uint16_t maxLen) +{ + int len = _udp.parsePacket(); + if (len == 0) + return 0; + + if (len > maxLen) + { + print("udp buffer to small. was "); + print(maxLen); + print(", needed "); + println(len); + fatalError(); + } + + _udp.read(buffer, len); + + // print("Remote IP: "); + // print(_udp.remoteIP().toString().c_str()); + // printHex("-> ", buffer, len); + + return len; +} + +// unicast +bool RP2040ArduinoPlatform::sendBytesUniCast(uint32_t addr, uint16_t port, uint8_t* buffer, uint16_t len) +{ + IPAddress ucastaddr(htonl(addr)); + + // print("sendBytesUniCast to:"); + // println(ucastaddr.toString().c_str()); + +#ifdef KNX_IP_GENERIC + if(!_unicast_socket_setup) + _unicast_socket_setup = UDP_UNICAST.begin(3671); +#endif + + if (UDP_UNICAST.beginPacket(ucastaddr, port) == 1) + { + UDP_UNICAST.write(buffer, len); + if (UDP_UNICAST.endPacket() == 0) + println("sendBytesUniCast endPacket fail"); + } + else + println("sendBytesUniCast beginPacket fail"); + + return true; +} +#endif + #endif diff --git a/src/rp2040_arduino_platform.h b/src/rp2040_arduino_platform.h index 15e6dcb7..e6df5466 100644 --- a/src/rp2040_arduino_platform.h +++ b/src/rp2040_arduino_platform.h @@ -1,3 +1,5 @@ +#pragma once + #include "arduino_platform.h" #include "Arduino.h" @@ -15,6 +17,47 @@ #define USE_RP2040_EEPROM_EMULATION #endif +#ifndef KNX_SERIAL +#pragma warn "KNX_SERIAL not defined, using Serial1" +#define KNX_SERIAL Serial1 +#endif + +#ifdef KNX_IP_W5500 +#if ARDUINO_PICO_MAJOR * 10000 + ARDUINO_PICO_MINOR * 100 + ARDUINO_PICO_REVISION < 30600 +#pragma error "arduino-pico >= 3.6.0 needed" +#endif +#define KNX_NETIF Eth + +#include "SPI.h" +#include + +#elif defined(KNX_IP_WIFI) + +#define KNX_NETIF WiFi +#include + +#elif defined(KNX_IP_GENERIC) + + +#include + +#ifndef DEBUG_ETHERNET_GENERIC_PORT +#define DEBUG_ETHERNET_GENERIC_PORT Serial +#endif + +#ifndef _ETG_LOGLEVEL_ +#define _ETG_LOGLEVEL_ 1 +#endif + + +#define ETHERNET_USE_RPIPICO true +#include // https://github.com/khoih-prog/Ethernet_Generic + + +#define KNX_NETIF Ethernet + +#endif + class RP2040ArduinoPlatform : public ArduinoPlatform { @@ -55,6 +98,35 @@ class RP2040ArduinoPlatform : public ArduinoPlatform // writes _eraseblockBuffer to flash - overrides Plattform::writeBufferedEraseBlock() for performance optimization only void writeBufferedEraseBlock(); #endif + + + #if defined(KNX_NETIF) + uint32_t currentIpAddress() override; + uint32_t currentSubnetMask() override; + uint32_t currentDefaultGateway() override; + void macAddress(uint8_t* addr) override; + + // multicast + void setupMultiCast(uint32_t addr, uint16_t port) override; + void closeMultiCast() override; + bool sendBytesMultiCast(uint8_t* buffer, uint16_t len) override; + int readBytesMultiCast(uint8_t* buffer, uint16_t maxLen) override; + + // unicast + bool sendBytesUniCast(uint32_t addr, uint16_t port, uint8_t* buffer, uint16_t len) override; + + #if defined(KNX_IP_W5500) || defined(KNX_IP_WIFI) + #define UDP_UNICAST _udp + protected: WiFiUDP _udp; + #elif defined(KNX_IP_GENERIC) + #define UDP_UNICAST _udp_uni + protected: bool _unicast_socket_setup = false; + protected: EthernetUDP _udp; + protected: EthernetUDP UDP_UNICAST; + #endif + protected: IPAddress mcastaddr; + protected: uint16_t _port; + #endif }; #endif From 311abdd88f5e10ea74f289ec3e82f2b2e054b63e Mon Sep 17 00:00:00 2001 From: Ing-Dom Date: Mon, 25 Dec 2023 16:34:40 +0100 Subject: [PATCH 5/9] redesigned the activitycallback without using the facade and with a more flexible approach. For performace reasons, the calls in the actual link layer is only activated when KNX_ACTIVITYCALLBACK is defined. There is now a DataLinkLayerCallback class where a specific Bau *can* inherit from and - if the specific link layer supports it, pass itself to that linklayer(s). --- src/knx/bau07B0.cpp | 17 ++++++++++++++++- src/knx/bau07B0.h | 2 +- src/knx/bau091A.cpp | 5 +++-- src/knx/bau091A.h | 2 +- src/knx/bau57B0.cpp | 3 ++- src/knx/bau57B0.h | 2 +- src/knx/data_link_layer.cpp | 12 ++++++++++++ src/knx/data_link_layer.h | 12 ++++++++++++ src/knx/ip_data_link_layer.cpp | 11 +++++++---- src/knx/ip_data_link_layer.h | 3 ++- src/knx/tpuart_data_link_layer.cpp | 13 ++++++++----- src/knx/tpuart_data_link_layer.h | 7 ++++++- 12 files changed, 71 insertions(+), 18 deletions(-) diff --git a/src/knx/bau07B0.cpp b/src/knx/bau07B0.cpp index ccd9b62a..92fe6658 100644 --- a/src/knx/bau07B0.cpp +++ b/src/knx/bau07B0.cpp @@ -10,7 +10,8 @@ using namespace std; Bau07B0::Bau07B0(Platform& platform) : BauSystemBDevice(platform), - _dlLayer(_deviceObj, _netLayer.getInterface(), _platform, (ITpUartCallBacks&) *this) + _dlLayer(_deviceObj, _netLayer.getInterface(), _platform, (ITpUartCallBacks&) *this, (DataLinkLayerCallbacks*) this), + DataLinkLayerCallbacks() #ifdef USE_CEMI_SERVER , _cemiServer(*this) #endif @@ -150,4 +151,18 @@ bool Bau07B0::isAckRequired(uint16_t address, bool isGrpAddr) return false; } +// /// @brief sets the Callback Function indicating sent or received telegrams +// /// @param activityCallback +// /// @details the info parameter +// void Bau07B0::setActivityCallback(ActivityCallback activityCallback) +// { +// _activityCallback = activityCallback; +// } + +// void Bau07B0::Activity(uint8_t info) +// { +// if(_activityCallback) +// _activityCallback(info); +// } + #endif diff --git a/src/knx/bau07B0.h b/src/knx/bau07B0.h index 3b29d720..b9c1e6c0 100644 --- a/src/knx/bau07B0.h +++ b/src/knx/bau07B0.h @@ -8,7 +8,7 @@ #include "cemi_server.h" #include "cemi_server_object.h" -class Bau07B0 : public BauSystemBDevice, public ITpUartCallBacks +class Bau07B0 : public BauSystemBDevice, public ITpUartCallBacks, public DataLinkLayerCallbacks { public: Bau07B0(Platform& platform); diff --git a/src/knx/bau091A.cpp b/src/knx/bau091A.cpp index 9774952e..2465bc42 100644 --- a/src/knx/bau091A.cpp +++ b/src/knx/bau091A.cpp @@ -12,8 +12,9 @@ Bau091A::Bau091A(Platform& platform) : BauSystemBCoupler(platform), _routerObj(memory()), _ipParameters(_deviceObj, platform), - _dlLayerPrimary(_deviceObj, _ipParameters, _netLayer.getPrimaryInterface(), _platform), - _dlLayerSecondary(_deviceObj, _netLayer.getSecondaryInterface(), platform, (ITpUartCallBacks&) *this) + _dlLayerPrimary(_deviceObj, _ipParameters, _netLayer.getPrimaryInterface(), _platform, (DataLinkLayerCallbacks*) this), + _dlLayerSecondary(_deviceObj, _netLayer.getSecondaryInterface(), platform, (ITpUartCallBacks&) *this, (DataLinkLayerCallbacks*) this), + DataLinkLayerCallbacks() #ifdef USE_CEMI_SERVER , _cemiServer(*this) diff --git a/src/knx/bau091A.h b/src/knx/bau091A.h index 7c9b8e5f..606fbda0 100644 --- a/src/knx/bau091A.h +++ b/src/knx/bau091A.h @@ -10,7 +10,7 @@ #include "tpuart_data_link_layer.h" #include "cemi_server_object.h" -class Bau091A : public BauSystemBCoupler, public ITpUartCallBacks +class Bau091A : public BauSystemBCoupler, public ITpUartCallBacks, public DataLinkLayerCallbacks { public: Bau091A(Platform& platform); diff --git a/src/knx/bau57B0.cpp b/src/knx/bau57B0.cpp index c9b3827b..75522aa1 100644 --- a/src/knx/bau57B0.cpp +++ b/src/knx/bau57B0.cpp @@ -11,7 +11,8 @@ using namespace std; Bau57B0::Bau57B0(Platform& platform) : BauSystemBDevice(platform), _ipParameters(_deviceObj, platform), - _dlLayer(_deviceObj, _ipParameters, _netLayer.getInterface(), _platform) + _dlLayer(_deviceObj, _ipParameters, _netLayer.getInterface(), _platform, (DataLinkLayerCallbacks*) this), + DataLinkLayerCallbacks() #ifdef USE_CEMI_SERVER , _cemiServer(*this) diff --git a/src/knx/bau57B0.h b/src/knx/bau57B0.h index a381ebb4..f6309f93 100644 --- a/src/knx/bau57B0.h +++ b/src/knx/bau57B0.h @@ -8,7 +8,7 @@ #include "ip_data_link_layer.h" #include "cemi_server_object.h" -class Bau57B0 : public BauSystemBDevice +class Bau57B0 : public BauSystemBDevice, public DataLinkLayerCallbacks { public: Bau57B0(Platform& platform); diff --git a/src/knx/data_link_layer.cpp b/src/knx/data_link_layer.cpp index e2f601e2..8de99f8c 100644 --- a/src/knx/data_link_layer.cpp +++ b/src/knx/data_link_layer.cpp @@ -6,6 +6,18 @@ #include "cemi_server.h" #include "cemi_frame.h" + +void DataLinkLayerCallbacks::Activity(uint8_t info) +{ + if(_activityCallback) + _activityCallback(info); +} + +void DataLinkLayerCallbacks::setActivityCallback(ActivityCallback activityCallback) +{ + _activityCallback = activityCallback; +} + DataLinkLayer::DataLinkLayer(DeviceObject& devObj, NetworkLayerEntity& netLayerEntity, Platform& platform) : _deviceObject(devObj), _networkLayerEntity(netLayerEntity), _platform(platform) { diff --git a/src/knx/data_link_layer.h b/src/knx/data_link_layer.h index 0270d31f..fe0d4749 100644 --- a/src/knx/data_link_layer.h +++ b/src/knx/data_link_layer.h @@ -10,6 +10,18 @@ class Platform; +typedef void (*ActivityCallback)(uint8_t info); + +class DataLinkLayerCallbacks +{ +protected: + ActivityCallback _activityCallback = nullptr; +public: + virtual ~DataLinkLayerCallbacks() = default; + virtual void Activity(uint8_t info); + virtual void setActivityCallback(ActivityCallback activityCallback); +}; + class DataLinkLayer { public: diff --git a/src/knx/ip_data_link_layer.cpp b/src/knx/ip_data_link_layer.cpp index b18f4d2a..aad2c149 100644 --- a/src/knx/ip_data_link_layer.cpp +++ b/src/knx/ip_data_link_layer.cpp @@ -19,7 +19,7 @@ #define MIN_LEN_CEMI 10 IpDataLinkLayer::IpDataLinkLayer(DeviceObject& devObj, IpParameterObject& ipParam, - NetworkLayerEntity &netLayerEntity, Platform& platform) : DataLinkLayer(devObj, netLayerEntity, platform), _ipParameters(ipParam) + NetworkLayerEntity &netLayerEntity, Platform& platform, DataLinkLayerCallbacks* dllcb) : DataLinkLayer(devObj, netLayerEntity, platform), _ipParameters(ipParam), _dllcb(dllcb) { } @@ -31,7 +31,8 @@ bool IpDataLinkLayer::sendFrame(CemiFrame& frame) return false; bool success = sendBytes(packet.data(), packet.totalLength()); #ifdef KNX_ACTIVITYCALLBACK - knx.Activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_SEND << KNX_ACTIVITYCALLBACK_DIR)); + if(_dllcb) + _dllcb->Activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_SEND << KNX_ACTIVITYCALLBACK_DIR)); #endif dataConReceived(frame, success); return success; @@ -55,7 +56,8 @@ void IpDataLinkLayer::loop() return; #ifdef KNX_ACTIVITYCALLBACK - knx.Activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_RECV << KNX_ACTIVITYCALLBACK_DIR)); + if(_dllcb) + _dllcb->Activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_RECV << KNX_ACTIVITYCALLBACK_DIR)); #endif uint16_t code; @@ -75,7 +77,8 @@ void IpDataLinkLayer::loop() auto hpai = searchRequest.hpai(); #ifdef KNX_ACTIVITYCALLBACK - knx.Activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_SEND << KNX_ACTIVITYCALLBACK_DIR) | (KNX_ACTIVITYCALLBACK_IPUNICAST)); + if(_dllcb) + _dllcb->Activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_SEND << KNX_ACTIVITYCALLBACK_DIR) | (KNX_ACTIVITYCALLBACK_IPUNICAST)); #endif _platform.sendBytesUniCast(hpai.ipAddress(), hpai.ipPortNumber(), searchResponse.data(), searchResponse.totalLength()); break; diff --git a/src/knx/ip_data_link_layer.h b/src/knx/ip_data_link_layer.h index 5f2d9962..5402a936 100644 --- a/src/knx/ip_data_link_layer.h +++ b/src/knx/ip_data_link_layer.h @@ -13,7 +13,7 @@ class IpDataLinkLayer : public DataLinkLayer public: IpDataLinkLayer(DeviceObject& devObj, IpParameterObject& ipParam, NetworkLayerEntity& netLayerEntity, - Platform& platform); + Platform& platform, DataLinkLayerCallbacks* dllcb = nullptr); void loop(); void enabled(bool value); @@ -30,5 +30,6 @@ class IpDataLinkLayer : public DataLinkLayer bool isSendLimitReached(); IpParameterObject& _ipParameters; + DataLinkLayerCallbacks* _dllcb; }; #endif diff --git a/src/knx/tpuart_data_link_layer.cpp b/src/knx/tpuart_data_link_layer.cpp index a17b2a4d..2af0ddaa 100644 --- a/src/knx/tpuart_data_link_layer.cpp +++ b/src/knx/tpuart_data_link_layer.cpp @@ -7,7 +7,6 @@ #include "device_object.h" #include "address_table_object.h" #include "cemi_frame.h" -#include "knx_facade.h" #include #include @@ -538,9 +537,11 @@ void TpUartDataLinkLayer::stopChip() TpUartDataLinkLayer::TpUartDataLinkLayer(DeviceObject& devObj, NetworkLayerEntity &netLayerEntity, Platform& platform, - ITpUartCallBacks& cb) + ITpUartCallBacks& cb, + DataLinkLayerCallbacks* dllcb) : DataLinkLayer(devObj, netLayerEntity, platform), - _cb(cb) + _cb(cb), + _dllcb(dllcb) { } @@ -548,7 +549,8 @@ void TpUartDataLinkLayer::frameBytesReceived(uint8_t* buffer, uint16_t length) { //printHex("=>", buffer, length); #ifdef KNX_ACTIVITYCALLBACK - knx.Activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_RECV << KNX_ACTIVITYCALLBACK_DIR)); + if(_dllcb) + _dllcb->Activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_RECV << KNX_ACTIVITYCALLBACK_DIR)); #endif CemiFrame frame(buffer, length); frameReceived(frame); @@ -657,7 +659,8 @@ bool TpUartDataLinkLayer::sendSingleFrameByte() { _TxByteCnt = 0; #ifdef KNX_ACTIVITYCALLBACK - knx.Activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_SEND << KNX_ACTIVITYCALLBACK_DIR)); + if(_dllcb) + _dllcb->Activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_SEND << KNX_ACTIVITYCALLBACK_DIR)); #endif return false; } diff --git a/src/knx/tpuart_data_link_layer.h b/src/knx/tpuart_data_link_layer.h index 9cc658b3..4551fcfe 100644 --- a/src/knx/tpuart_data_link_layer.h +++ b/src/knx/tpuart_data_link_layer.h @@ -21,8 +21,12 @@ class TpUartDataLinkLayer : public DataLinkLayer using DataLinkLayer::_platform; public: + // TpUartDataLinkLayer(DeviceObject& devObj, NetworkLayerEntity& netLayerEntity, + // Platform& platform, ITpUartCallBacks& cb); TpUartDataLinkLayer(DeviceObject& devObj, NetworkLayerEntity& netLayerEntity, - Platform& platform, ITpUartCallBacks& cb); + Platform& platform, ITpUartCallBacks& cb, DataLinkLayerCallbacks* dllcb = nullptr); + + void loop(); void enabled(bool value); @@ -74,5 +78,6 @@ class TpUartDataLinkLayer : public DataLinkLayer void stopChip(); ITpUartCallBacks& _cb; + DataLinkLayerCallbacks* _dllcb; }; #endif From ddd82845782e020b103e4cba7998b58f723b66e9 Mon Sep 17 00:00:00 2001 From: Michael Geramb Date: Mon, 25 Dec 2023 19:39:05 +0100 Subject: [PATCH 6/9] Allow to set uart pins for RP2040 and ESP32 platform --- src/esp32_platform.cpp | 25 +++++++++++++++++++++++++ src/esp32_platform.h | 6 ++++++ src/rp2040_arduino_platform.cpp | 23 +++++++++++++++++++++++ src/rp2040_arduino_platform.h | 2 ++ 4 files changed, 56 insertions(+) diff --git a/src/esp32_platform.cpp b/src/esp32_platform.cpp index ada8fd3d..a8c985ba 100644 --- a/src/esp32_platform.cpp +++ b/src/esp32_platform.cpp @@ -10,17 +10,42 @@ #define KNX_SERIAL Serial1 #endif +#ifndef KNX_UART_RX_PIN +#define KNX_UART_RX_PIN -1 +#endif + +#ifndef KNX_UART_TX_PIN +#define KNX_UART_TX_PIN -1 +#endif + Esp32Platform::Esp32Platform() #ifndef KNX_NO_DEFAULT_UART : ArduinoPlatform(&KNX_SERIAL) #endif { +#ifndef KNX_NO_DEFAULT_UART + knxUartPins(KNX_UART_RX_PIN, KNX_UART_TX_PIN); +#endif } Esp32Platform::Esp32Platform(HardwareSerial* s) : ArduinoPlatform(s) { } +void Esp32Platform::knxUartPins(int8_t rxPin, int8_t txPin) +{ + _rxPin = rxPin; + _txPin = txPin; +} + +// ESP specific uart handling with pins +void Esp32Platform::setupUart() +{ + _knxSerial->begin(19200, SERIAL_8E1, _rxPin, _txPin); + while (!_knxSerial) + ; +} + uint32_t Esp32Platform::currentIpAddress() { return WiFi.localIP(); diff --git a/src/esp32_platform.h b/src/esp32_platform.h index 0193efe4..318291cb 100644 --- a/src/esp32_platform.h +++ b/src/esp32_platform.h @@ -10,6 +10,10 @@ class Esp32Platform : public ArduinoPlatform Esp32Platform(); Esp32Platform(HardwareSerial* s); + // uart + void knxUartPins(int8_t rxPin, int8_t txPin); + void setupUart() override; + // ip stuff uint32_t currentIpAddress() override; uint32_t currentSubnetMask() override; @@ -36,6 +40,8 @@ class Esp32Platform : public ArduinoPlatform void commitToEeprom(); private: WiFiUDP _udp; + int8_t _rxPin = -1; + int8_t _txPin = -1; }; #endif diff --git a/src/rp2040_arduino_platform.cpp b/src/rp2040_arduino_platform.cpp index 44eb8c4b..8de0c66e 100644 --- a/src/rp2040_arduino_platform.cpp +++ b/src/rp2040_arduino_platform.cpp @@ -49,11 +49,22 @@ A RAM-buffered Flash can be use by defining USE_RP2040_LARGE_EEPROM_EMULATION #define KNX_SERIAL Serial1 #endif +#ifndef KNX_UART_RX_PIN +#define KNX_UART_RX_PIN UART_PIN_NOT_DEFINED +#endif + +#ifndef KNX_UART_TX_PIN +#define KNX_UART_TX_PIN UART_PIN_NOT_DEFINED +#endif + RP2040ArduinoPlatform::RP2040ArduinoPlatform() #ifndef KNX_NO_DEFAULT_UART : ArduinoPlatform(&KNX_SERIAL) #endif { + #ifndef KNX_NO_DEFAULT_UART + knxUartPins(KNX_UART_RX_PIN, KNX_UART_TX_PIN); + #endif #ifndef USE_RP2040_EEPROM_EMULATION _memoryType = Flash; #endif @@ -66,6 +77,18 @@ RP2040ArduinoPlatform::RP2040ArduinoPlatform( HardwareSerial* s) : ArduinoPlatfo #endif } +void RP2040ArduinoPlatform::knxUartPins(pin_size_t rxPin, pin_size_t txPin) +{ + SerialUART* serial = dynamic_cast(_knxSerial); + if(serial) + { + if (rxPin != UART_PIN_NOT_DEFINED) + serial->setRX(rxPin); + if (txPin != UART_PIN_NOT_DEFINED) + serial->setTX(txPin); + } +} + void RP2040ArduinoPlatform::setupUart() { SerialUART* serial = dynamic_cast(_knxSerial); diff --git a/src/rp2040_arduino_platform.h b/src/rp2040_arduino_platform.h index 15e6dcb7..836f8644 100644 --- a/src/rp2040_arduino_platform.h +++ b/src/rp2040_arduino_platform.h @@ -22,6 +22,8 @@ class RP2040ArduinoPlatform : public ArduinoPlatform RP2040ArduinoPlatform(); RP2040ArduinoPlatform( HardwareSerial* s); + // uart + void knxUartPins(pin_size_t rxPin, pin_size_t txPin); void setupUart(); // unique serial number From 142e0a2325321c858dae86b076376e9d893f2ac6 Mon Sep 17 00:00:00 2001 From: Ing-Dom Date: Tue, 26 Dec 2023 13:48:50 +0100 Subject: [PATCH 7/9] fixing issues from PR review --- src/knx/bau07B0.cpp | 14 -------------- src/knx/data_link_layer.cpp | 2 +- src/knx/data_link_layer.h | 2 +- src/knx/ip_data_link_layer.cpp | 8 ++++---- src/knx/tpuart_data_link_layer.cpp | 6 +++--- src/knx/tpuart_data_link_layer.h | 2 -- 6 files changed, 9 insertions(+), 25 deletions(-) diff --git a/src/knx/bau07B0.cpp b/src/knx/bau07B0.cpp index 92fe6658..c68ecb23 100644 --- a/src/knx/bau07B0.cpp +++ b/src/knx/bau07B0.cpp @@ -151,18 +151,4 @@ bool Bau07B0::isAckRequired(uint16_t address, bool isGrpAddr) return false; } -// /// @brief sets the Callback Function indicating sent or received telegrams -// /// @param activityCallback -// /// @details the info parameter -// void Bau07B0::setActivityCallback(ActivityCallback activityCallback) -// { -// _activityCallback = activityCallback; -// } - -// void Bau07B0::Activity(uint8_t info) -// { -// if(_activityCallback) -// _activityCallback(info); -// } - #endif diff --git a/src/knx/data_link_layer.cpp b/src/knx/data_link_layer.cpp index 8de99f8c..be9d6fac 100644 --- a/src/knx/data_link_layer.cpp +++ b/src/knx/data_link_layer.cpp @@ -7,7 +7,7 @@ #include "cemi_frame.h" -void DataLinkLayerCallbacks::Activity(uint8_t info) +void DataLinkLayerCallbacks::activity(uint8_t info) { if(_activityCallback) _activityCallback(info); diff --git a/src/knx/data_link_layer.h b/src/knx/data_link_layer.h index fe0d4749..817078e8 100644 --- a/src/knx/data_link_layer.h +++ b/src/knx/data_link_layer.h @@ -18,7 +18,7 @@ class DataLinkLayerCallbacks ActivityCallback _activityCallback = nullptr; public: virtual ~DataLinkLayerCallbacks() = default; - virtual void Activity(uint8_t info); + virtual void activity(uint8_t info); virtual void setActivityCallback(ActivityCallback activityCallback); }; diff --git a/src/knx/ip_data_link_layer.cpp b/src/knx/ip_data_link_layer.cpp index aad2c149..aa291cca 100644 --- a/src/knx/ip_data_link_layer.cpp +++ b/src/knx/ip_data_link_layer.cpp @@ -32,7 +32,7 @@ bool IpDataLinkLayer::sendFrame(CemiFrame& frame) bool success = sendBytes(packet.data(), packet.totalLength()); #ifdef KNX_ACTIVITYCALLBACK if(_dllcb) - _dllcb->Activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_SEND << KNX_ACTIVITYCALLBACK_DIR)); + _dllcb->activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_SEND << KNX_ACTIVITYCALLBACK_DIR)); #endif dataConReceived(frame, success); return success; @@ -57,7 +57,7 @@ void IpDataLinkLayer::loop() #ifdef KNX_ACTIVITYCALLBACK if(_dllcb) - _dllcb->Activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_RECV << KNX_ACTIVITYCALLBACK_DIR)); + _dllcb->activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_RECV << KNX_ACTIVITYCALLBACK_DIR)); #endif uint16_t code; @@ -77,8 +77,8 @@ void IpDataLinkLayer::loop() auto hpai = searchRequest.hpai(); #ifdef KNX_ACTIVITYCALLBACK - if(_dllcb) - _dllcb->Activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_SEND << KNX_ACTIVITYCALLBACK_DIR) | (KNX_ACTIVITYCALLBACK_IPUNICAST)); + if(_dllcb) + _dllcb->activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_SEND << KNX_ACTIVITYCALLBACK_DIR) | (KNX_ACTIVITYCALLBACK_IPUNICAST)); #endif _platform.sendBytesUniCast(hpai.ipAddress(), hpai.ipPortNumber(), searchResponse.data(), searchResponse.totalLength()); break; diff --git a/src/knx/tpuart_data_link_layer.cpp b/src/knx/tpuart_data_link_layer.cpp index 2af0ddaa..1c9f7773 100644 --- a/src/knx/tpuart_data_link_layer.cpp +++ b/src/knx/tpuart_data_link_layer.cpp @@ -550,7 +550,7 @@ void TpUartDataLinkLayer::frameBytesReceived(uint8_t* buffer, uint16_t length) //printHex("=>", buffer, length); #ifdef KNX_ACTIVITYCALLBACK if(_dllcb) - _dllcb->Activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_RECV << KNX_ACTIVITYCALLBACK_DIR)); + _dllcb->activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_RECV << KNX_ACTIVITYCALLBACK_DIR)); #endif CemiFrame frame(buffer, length); frameReceived(frame); @@ -659,8 +659,8 @@ bool TpUartDataLinkLayer::sendSingleFrameByte() { _TxByteCnt = 0; #ifdef KNX_ACTIVITYCALLBACK - if(_dllcb) - _dllcb->Activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_SEND << KNX_ACTIVITYCALLBACK_DIR)); + if(_dllcb) + _dllcb->activity((_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_SEND << KNX_ACTIVITYCALLBACK_DIR)); #endif return false; } diff --git a/src/knx/tpuart_data_link_layer.h b/src/knx/tpuart_data_link_layer.h index 4551fcfe..c2e46f30 100644 --- a/src/knx/tpuart_data_link_layer.h +++ b/src/knx/tpuart_data_link_layer.h @@ -21,8 +21,6 @@ class TpUartDataLinkLayer : public DataLinkLayer using DataLinkLayer::_platform; public: - // TpUartDataLinkLayer(DeviceObject& devObj, NetworkLayerEntity& netLayerEntity, - // Platform& platform, ITpUartCallBacks& cb); TpUartDataLinkLayer(DeviceObject& devObj, NetworkLayerEntity& netLayerEntity, Platform& platform, ITpUartCallBacks& cb, DataLinkLayerCallbacks* dllcb = nullptr); From c1691b7e816c8ce137e23273f419720d9f08806f Mon Sep 17 00:00:00 2001 From: Michael Geramb Date: Sun, 31 Dec 2023 13:31:51 +0100 Subject: [PATCH 8/9] Fix for RP2040 UART pin handling: Setting of uart pins moved setupUart method. --- src/esp32_platform.cpp | 17 ++++++----------- src/rp2040_arduino_platform.cpp | 29 +++++++++++------------------ src/rp2040_arduino_platform.h | 2 ++ 3 files changed, 19 insertions(+), 29 deletions(-) diff --git a/src/esp32_platform.cpp b/src/esp32_platform.cpp index a8c985ba..9367f4e4 100644 --- a/src/esp32_platform.cpp +++ b/src/esp32_platform.cpp @@ -10,22 +10,17 @@ #define KNX_SERIAL Serial1 #endif -#ifndef KNX_UART_RX_PIN -#define KNX_UART_RX_PIN -1 -#endif - -#ifndef KNX_UART_TX_PIN -#define KNX_UART_TX_PIN -1 -#endif - Esp32Platform::Esp32Platform() #ifndef KNX_NO_DEFAULT_UART : ArduinoPlatform(&KNX_SERIAL) #endif { -#ifndef KNX_NO_DEFAULT_UART - knxUartPins(KNX_UART_RX_PIN, KNX_UART_TX_PIN); -#endif + #ifdef KNX_UART_RX_PIN + _rxPin = KNX_UART_RX_PIN; + #endif + #ifdef KNX_UART_TX_PIN + _txPin = KNX_UART_TX_PIN; + #endif } Esp32Platform::Esp32Platform(HardwareSerial* s) : ArduinoPlatform(s) diff --git a/src/rp2040_arduino_platform.cpp b/src/rp2040_arduino_platform.cpp index dd8dfb93..ddc89cbc 100644 --- a/src/rp2040_arduino_platform.cpp +++ b/src/rp2040_arduino_platform.cpp @@ -56,21 +56,16 @@ extern Wiznet5500lwIP KNX_NETIF; #endif -#ifndef KNX_UART_RX_PIN -#define KNX_UART_RX_PIN UART_PIN_NOT_DEFINED -#endif - -#ifndef KNX_UART_TX_PIN -#define KNX_UART_TX_PIN UART_PIN_NOT_DEFINED -#endif - RP2040ArduinoPlatform::RP2040ArduinoPlatform() #ifndef KNX_NO_DEFAULT_UART : ArduinoPlatform(&KNX_SERIAL) #endif { - #ifndef KNX_NO_DEFAULT_UART - knxUartPins(KNX_UART_RX_PIN, KNX_UART_TX_PIN); + #ifdef KNX_UART_RX_PIN + _rxPin = KNX_UART_RX_PIN; + #endif + #ifdef KNX_UART_TX_PIN + _txPin = KNX_UART_TX_PIN; #endif #ifndef USE_RP2040_EEPROM_EMULATION _memoryType = Flash; @@ -86,14 +81,8 @@ RP2040ArduinoPlatform::RP2040ArduinoPlatform( HardwareSerial* s) : ArduinoPlatfo void RP2040ArduinoPlatform::knxUartPins(pin_size_t rxPin, pin_size_t txPin) { - SerialUART* serial = dynamic_cast(_knxSerial); - if(serial) - { - if (rxPin != UART_PIN_NOT_DEFINED) - serial->setRX(rxPin); - if (txPin != UART_PIN_NOT_DEFINED) - serial->setTX(txPin); - } + _rxPin = rxPin; + _txPin = txPin; } void RP2040ArduinoPlatform::setupUart() @@ -101,6 +90,10 @@ void RP2040ArduinoPlatform::setupUart() SerialUART* serial = dynamic_cast(_knxSerial); if(serial) { + if (_rxPin != UART_PIN_NOT_DEFINED) + serial->setRX(_rxPin); + if (_txPin != UART_PIN_NOT_DEFINED) + serial->setTX(_txPin); serial->setPollingMode(); } diff --git a/src/rp2040_arduino_platform.h b/src/rp2040_arduino_platform.h index b71b3b4d..613ba27c 100644 --- a/src/rp2040_arduino_platform.h +++ b/src/rp2040_arduino_platform.h @@ -128,6 +128,8 @@ class RP2040ArduinoPlatform : public ArduinoPlatform #endif protected: IPAddress mcastaddr; protected: uint16_t _port; + protected: pin_size_t _rxPin = UART_PIN_NOT_DEFINED; + protected: pin_size_t _txPin = UART_PIN_NOT_DEFINED; #endif }; From 4cd733b86d8825cbc5b28d8043ed3705a50ff0a3 Mon Sep 17 00:00:00 2001 From: Michael Geramb Date: Tue, 2 Jan 2024 19:37:52 +0100 Subject: [PATCH 9/9] Fix build error for missing variable if KNX_NETIF is not defined --- src/rp2040_arduino_platform.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rp2040_arduino_platform.h b/src/rp2040_arduino_platform.h index 613ba27c..b4e7f8d0 100644 --- a/src/rp2040_arduino_platform.h +++ b/src/rp2040_arduino_platform.h @@ -128,9 +128,9 @@ class RP2040ArduinoPlatform : public ArduinoPlatform #endif protected: IPAddress mcastaddr; protected: uint16_t _port; + #endif protected: pin_size_t _rxPin = UART_PIN_NOT_DEFINED; protected: pin_size_t _txPin = UART_PIN_NOT_DEFINED; - #endif }; #endif