Skip to content

Commit

Permalink
this adds IP (WiFi and wired Ethernet) support to the rp2040 platform.
Browse files Browse the repository at this point in the history
It includes also some optimizations for KNX-IP in general.

Squashed commit of the following:

commit 14bf9be
Author: Ing-Dom <[email protected]>
Date:   Sun Dec 24 10:17:05 2023 +0100

    clean up, remove KNX_LOG_IP

commit 57223e4
Merge: 2911448 a870dd8
Author: Ing-Dom <[email protected]>
Date:   Sun Dec 24 10:10:19 2023 +0100

    Merge remote-tracking branch 'remotes/origin/master' into rp2040_ip

commit 2911448
Merge: 8ac6aec 3c29d16
Author: Dom <[email protected]>
Date:   Wed Dec 20 10:04:32 2023 +0100

    Merge pull request #13 from OpenKNX/fix_serialnumber

    Fix serialnumber

commit 8ac6aec
Author: Ing-Dom <[email protected]>
Date:   Thu Dec 14 12:28:02 2023 +0100

    fix macAddress reading for Wifi

commit 9db2cd5
Author: Ing-Dom <[email protected]>
Date:   Tue Dec 12 13:08:53 2023 +0100

    remove LARGE_BUFFERS and clean up header files of ETHERNET_GENERIC

commit 2f229ae
Author: Ing-Dom <[email protected]>
Date:   Tue Dec 12 00:56:32 2023 +0100

    temporary fix, solution needed for tunneling

commit f6e7e61
Author: Ing-Dom <[email protected]>
Date:   Mon Dec 11 13:54:26 2023 +0100

    unified approach for different ip stacks with rp2040 plattform

commit 4723eda
Author: Marco Scholl <[email protected]>
Date:   Mon Dec 11 08:34:25 2023 +0100

    wip

commit 5bf3e61
Author: Ing-Dom <[email protected]>
Date:   Thu Dec 7 14:53:42 2023 +0100

    ip and not ip in one rp2040 plattform

commit aaca34a
Merge: fd97f59 d44606d
Author: Dom <[email protected]>
Date:   Wed Dec 6 15:30:17 2023 +0100

    Merge branch 'thelsing:master' into rp2040_lwip

commit fd97f59
Author: Marco Scholl <[email protected]>
Date:   Thu Nov 30 23:19:13 2023 +0100

    dd sime ifdef to allow build without ip interface

commit c665a79
Author: Ing-Dom <[email protected]>
Date:   Tue Nov 14 10:03:48 2023 +0100

    stub for handling SearchRequestExt to prevent console messages

commit 50745be
Author: Ing-Dom <[email protected]>
Date:   Tue Nov 14 00:02:49 2023 +0100

    adding ip support for rp2040 plattform
  • Loading branch information
Ing-Dom committed Dec 24, 2023
1 parent a870dd8 commit 470ec8b
Show file tree
Hide file tree
Showing 7 changed files with 218 additions and 8 deletions.
11 changes: 9 additions & 2 deletions src/knx/ip_data_link_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/knx/ip_parameter_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down
2 changes: 2 additions & 0 deletions src/knx/knx_ip_frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ enum KnxIpServiceType
ConnectionStateResponse = 0x208,
DisconnectRequest = 0x209,
DisconnectResponse = 0x20A,
SearchRequestExt = 0x20B,
SearchResponseExt = 0x20C,
DeviceConfigurationRequest = 0x310,
DeviceConfigurationAck = 0x311,
TunnelingRequest = 0x420,
Expand Down
6 changes: 5 additions & 1 deletion src/knx_facade.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 5 additions & 1 deletion src/knx_facade.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
126 changes: 123 additions & 3 deletions src/rp2040_arduino_platform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Plattform for Raspberry Pi Pico and other RP2040 boards
by SirSydom <[email protected]> 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
Expand All @@ -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)
----------------------------------------------------*/

Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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


72 changes: 72 additions & 0 deletions src/rp2040_arduino_platform.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#pragma once

#include "arduino_platform.h"

#include "Arduino.h"
Expand All @@ -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
{
Expand Down Expand Up @@ -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

0 comments on commit 470ec8b

Please sign in to comment.