mirror of
				https://github.com/thelsing/knx.git
				synced 2025-10-26 10:26:25 +01:00 
			
		
		
		
	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 <dom@ing-dom.de>
Date:   Sun Dec 24 10:17:05 2023 +0100
    clean up, remove KNX_LOG_IP
commit 57223e46e414010662772989c2520cf1960ed268
Merge: 2911448 a870dd8
Author: Ing-Dom <dom@ing-dom.de>
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 <dom@ing-dom.de>
Date:   Wed Dec 20 10:04:32 2023 +0100
    Merge pull request #13 from OpenKNX/fix_serialnumber
    Fix serialnumber
commit 8ac6aeccce20a9e5e1bbf5300008a72383f7ee71
Author: Ing-Dom <dom@ing-dom.de>
Date:   Thu Dec 14 12:28:02 2023 +0100
    fix macAddress reading for Wifi
commit 9db2cd58708e9d7bbfd485ada2ff38c829447c42
Author: Ing-Dom <dom@ing-dom.de>
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 <dom@ing-dom.de>
Date:   Tue Dec 12 00:56:32 2023 +0100
    temporary fix, solution needed for tunneling
commit f6e7e619a454f43db10e644b41c58b43a1a2b453
Author: Ing-Dom <dom@ing-dom.de>
Date:   Mon Dec 11 13:54:26 2023 +0100
    unified approach for different ip stacks with rp2040 plattform
commit 4723edab84986bca6d31ea7b3083b1b7b8ef907e
Author: Marco Scholl <develop@marco-scholl.de>
Date:   Mon Dec 11 08:34:25 2023 +0100
    wip
commit 5bf3e615c8649dd9c34be7b1fe6ad4062ce96c34
Author: Ing-Dom <dom@ing-dom.de>
Date:   Thu Dec 7 14:53:42 2023 +0100
    ip and not ip in one rp2040 plattform
commit aaca34a237686c5389888b7bd040b860331bdbff
Merge: fd97f59 d44606d
Author: Dom <dom@ing-dom.de>
Date:   Wed Dec 6 15:30:17 2023 +0100
    Merge branch 'thelsing:master' into rp2040_lwip
commit fd97f5920ef486ca955f5425cbcaec062e3ef977
Author: Marco Scholl <develop@marco-scholl.de>
Date:   Thu Nov 30 23:19:13 2023 +0100
    dd sime ifdef to allow build without ip interface
commit c665a79db9cee7063dd77a155108633db81ef8e8
Author: Ing-Dom <dom@ing-dom.de>
Date:   Tue Nov 14 10:03:48 2023 +0100
    stub for handling SearchRequestExt to prevent console messages
commit 50745be66681616681f67d7bdf17008f5d19640d
Author: Ing-Dom <dom@ing-dom.de>
Date:   Tue Nov 14 00:02:49 2023 +0100
    adding ip support for rp2040 plattform
			
			
This commit is contained in:
		
							parent
							
								
									a870dd812d
								
							
						
					
					
						commit
						470ec8b521
					
				| @ -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);
 | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -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<IpParameterObject>(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  | ||||
|             {  | ||||
|  | ||||
| @ -23,6 +23,8 @@ enum KnxIpServiceType | ||||
|     ConnectionStateResponse = 0x208, | ||||
|     DisconnectRequest = 0x209, | ||||
|     DisconnectResponse = 0x20A, | ||||
|     SearchRequestExt = 0x20B, | ||||
|     SearchResponseExt = 0x20C, | ||||
|     DeviceConfigurationRequest = 0x310, | ||||
|     DeviceConfigurationAck = 0x311, | ||||
|     TunnelingRequest = 0x420, | ||||
|  | ||||
| @ -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<RP2040ArduinoPlatform, Bau07B0> knx(buttonEvent); | ||||
|         #elif MASK_VERSION == 0x27B0 | ||||
|             KnxFacade<RP2040ArduinoPlatform, Bau27B0> knx(buttonEvent); | ||||
|         #elif MASK_VERSION == 0x57B0 | ||||
|             KnxFacade<RP2040ArduinoPlatform, Bau57B0> knx(buttonEvent); | ||||
|         #elif MASK_VERSION == 0x2920 | ||||
|             KnxFacade<RP2040ArduinoPlatform, Bau2920> knx(buttonEvent); | ||||
|         #elif MASK_VERSION == 0x091A | ||||
|             KnxFacade<RP2040ArduinoPlatform, Bau091A> knx(buttonEvent); | ||||
|         #else | ||||
|             #error "Mask version not supported on ARDUINO_ARCH_RP2040" | ||||
|         #endif | ||||
|  | ||||
| @ -480,13 +480,17 @@ template <class P, class B> 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<RP2040ArduinoPlatform, Bau07B0> knx; | ||||
|         #elif MASK_VERSION == 0x27B0 | ||||
|             extern KnxFacade<RP2040ArduinoPlatform, Bau27B0> knx; | ||||
|         #elif MASK_VERSION == 0x57B0 | ||||
|             extern KnxFacade<RP2040ArduinoPlatform, Bau57B0> knx; | ||||
|         #elif MASK_VERSION == 0x2920 | ||||
|             extern KnxFacade<RP2040ArduinoPlatform, Bau2920> knx; | ||||
|         #elif MASK_VERSION == 0x091A | ||||
|             extern KnxFacade<RP2040ArduinoPlatform, Bau091A> knx; | ||||
|         #else | ||||
|             #error "Mask version not supported on ARDUINO_ARCH_RP2040" | ||||
|         #endif | ||||
|  | ||||
| @ -4,7 +4,7 @@ Plattform for Raspberry Pi Pico and other RP2040 boards | ||||
| by SirSydom <com@sirsydom.de> 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 | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -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 <W5500lwIP.h> | ||||
| 
 | ||||
| #elif defined(KNX_IP_WIFI) | ||||
| 
 | ||||
| #define KNX_NETIF WiFi | ||||
| #include <WiFi.h> | ||||
| 
 | ||||
| #elif defined(KNX_IP_GENERIC) | ||||
| 
 | ||||
| 
 | ||||
| #include <SPI.h> | ||||
| 
 | ||||
| #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 <Ethernet_Generic.hpp>             // https://github.com/khoih-prog/Ethernet_Generic | ||||
| 
 | ||||
| 
 | ||||
| #define KNX_NETIF Ethernet | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| class RP2040ArduinoPlatform : public ArduinoPlatform | ||||
| { | ||||
| @ -55,6 +98,35 @@ public: | ||||
|     // 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 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user