Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Openknx merge #289

Merged
merged 59 commits into from
Aug 9, 2024
Merged
Changes from 14 commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
efe2c46
New implementation of Uninitialized state for group object
Jan 15, 2024
c6368db
Finalize uninitialized handling
Jan 18, 2024
f5f45e2
Allow Setting Value of GroupObject (KO) with Checking Change after Co…
cornelius-koepp Aug 13, 2023
1f426e9
Update for New Uninitialized-Handling
cornelius-koepp Jan 22, 2024
defffbd
fix build pipeline errors
Ing-Dom Jan 30, 2024
5521e4b
Merge branch 'thelsing:master' into devel
Ing-Dom Jan 30, 2024
9ab6b6c
Merge pull request #20 from OpenKNX/openknx/fix/pipeline_knxusb
traxanos Jan 31, 2024
a12ff2d
Merge remote-tracking branch 'origin/master' into devel
cornelius-koepp Feb 12, 2024
9d7c8ac
update library.properties to V2.0.0
Ing-Dom Feb 13, 2024
cacbd9f
add rp2040 build environment to knx-demo example for both example pro…
Ing-Dom Feb 26, 2024
03f55f5
Makes the data link layer accessible from outside
traxanos Feb 26, 2024
f5724c6
Extends the platforms with additional uart methods.
traxanos Feb 27, 2024
6b2ac7e
Adds dma support for rp2040 uart
traxanos Mar 28, 2024
1ee78a4
Reimplementation of the tpuart data link layer
traxanos Mar 28, 2024
8388c79
adds gcc optimize for tp frame
traxanos Mar 29, 2024
cf1b6bc
some bugfixes
traxanos Mar 29, 2024
6884734
fixes the missing processRx() in loop()
traxanos Mar 30, 2024
9d7e29d
auto format
traxanos Mar 30, 2024
7b910eb
small optimizes
traxanos Apr 4, 2024
e65afeb
reenable sendframe handling
traxanos Apr 4, 2024
1754e53
fixes some problems with txqueue
traxanos Apr 8, 2024
97e15c7
remove some debug output.
traxanos Apr 10, 2024
1ef4856
Update platformio-ci.ini
Ing-Dom Apr 22, 2024
7cbc0d8
Merge pull request #21 from OpenKNX/features/add_rp2040_to_demo
Ing-Dom Apr 23, 2024
f94bd0b
allow to change MAX_TX_QUEUE
traxanos May 19, 2024
a330699
Add function to group object to send a value only if it was changed.
Apr 17, 2024
9de8591
Merge pull request #23 from mgeramb/addValueCompareFunction
Ing-Dom May 21, 2024
06e0365
Merge branch 'v1dev-tp2' into v1dev
traxanos May 21, 2024
2adac5e
fix: resets stats
traxanos May 23, 2024
a645575
support detect acks with busy + nack and show in monitoring
traxanos May 23, 2024
6eb7af7
flag also repeated telegrams as echoed / own telegrams
Ing-Dom Jun 2, 2024
4f0e47f
drop unexpected udp data packet length
traxanos Jun 3, 2024
acf4a0b
remove annoying file
thewhobox Jun 3, 2024
e69f636
Release V2.1.0
Ing-Dom Jul 3, 2024
12fb67c
fix: only set pinMode of Prog button pin when pin is >= 0 and isr fun…
Ing-Dom Jul 17, 2024
093ae42
String \0 terminated in group objects (#25)
mgeramb Jul 20, 2024
d0b5e84
remove generic ethernet support on rp2040. uses now KNX_IP_LAN or KNX…
traxanos Jul 20, 2024
194de33
update rp2040 plattform version in examples and ci
Ing-Dom Jul 22, 2024
7f11927
Better Routing and new Tunneling Support (#26)
Ing-Dom Jul 29, 2024
84a0ce3
fixes modulo in rx queue
traxanos Aug 3, 2024
845aa38
Merge branch 'v1' into v1dev
traxanos Aug 3, 2024
f0cd44c
add DPT 27.001
mgeramb Aug 7, 2024
b2bcba7
Merge pull request #27 from mgeramb/add_DPT17.001
traxanos Aug 7, 2024
27ef9ee
cmake changes
thelsing Aug 9, 2024
85ac27a
add rp2040 build environment to knx-demo example for both example pro…
Ing-Dom Feb 26, 2024
f676cd2
Merge commit '06e0365' into openknx-merge
thelsing Aug 9, 2024
9a88b48
merge
thelsing Aug 9, 2024
934d9ca
translate german comments with deepL
thelsing Aug 9, 2024
2b11ecc
Merge branch 'master' into openknx-merge
thelsing Aug 9, 2024
5ddbff2
Merge commit '093ae42' into openknx-merge
thelsing Aug 9, 2024
dd5367e
lib props
thelsing Aug 9, 2024
ee4d4ba
Merge commit '7f11927' into openknx-merge
thelsing Aug 9, 2024
2043141
Merge commit 'b2bcba7' into openknx-merge
thelsing Aug 9, 2024
5ac8581
Merge branch 'master' of https://github.com/thelsing/knx
thelsing Aug 9, 2024
82f0774
Merge branch 'master' into openknx-merge
thelsing Aug 9, 2024
8480891
del files
thelsing Aug 9, 2024
7c85635
fix build
thelsing Aug 9, 2024
5293dd8
no more warnings
thelsing Aug 9, 2024
af96a76
empty lines
thelsing Aug 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/arduino_platform.cpp
Original file line number Diff line number Diff line change
@@ -103,6 +103,11 @@ size_t ArduinoPlatform::readBytesUart(uint8_t *buffer, size_t length)
return length;
}

void ArduinoPlatform::flushUart()
{
return _knxSerial->flush();
}

#ifndef KNX_NO_SPI
void ArduinoPlatform::setupSpi()
{
1 change: 1 addition & 0 deletions src/arduino_platform.h
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@ class ArduinoPlatform : public Platform
virtual size_t writeUart(const uint8_t* buffer, size_t size);
virtual int readUart();
virtual size_t readBytesUart(uint8_t* buffer, size_t length);
virtual void flushUart();

//spi
#ifndef KNX_NO_SPI
3 changes: 3 additions & 0 deletions src/knx/bau07B0.cpp
Original file line number Diff line number Diff line change
@@ -151,4 +151,7 @@ bool Bau07B0::isAckRequired(uint16_t address, bool isGrpAddr)
return false;
}

TpUartDataLinkLayer* Bau07B0::getDataLinkLayer() {
return (TpUartDataLinkLayer*)&_dlLayer;
}
#endif
3 changes: 2 additions & 1 deletion src/knx/bau07B0.h
Original file line number Diff line number Diff line change
@@ -15,7 +15,8 @@ class Bau07B0 : public BauSystemBDevice, public ITpUartCallBacks, public DataLin
void loop() override;
bool enabled() override;
void enabled(bool value) override;


TpUartDataLinkLayer* getDataLinkLayer();
protected:
InterfaceObject* getInterfaceObject(uint8_t idx);
InterfaceObject* getInterfaceObject(ObjectType objectType, uint8_t objectInstance);
7 changes: 7 additions & 0 deletions src/knx/bau091A.cpp
Original file line number Diff line number Diff line change
@@ -167,4 +167,11 @@ bool Bau091A::isAckRequired(uint16_t address, bool isGrpAddr)
return false;
}

IpDataLinkLayer* Bau091A::getPrimaryDataLinkLayer() {
return (IpDataLinkLayer*)&_dlLayerPrimary;
}

TpUartDataLinkLayer* Bau091A::getSecondaryDataLinkLayer() {
return (TpUartDataLinkLayer*)&_dlLayerSecondary;
}
#endif
2 changes: 2 additions & 0 deletions src/knx/bau091A.h
Original file line number Diff line number Diff line change
@@ -18,6 +18,8 @@ class Bau091A : public BauSystemBCoupler, public ITpUartCallBacks, public DataLi
bool enabled() override;
void enabled(bool value) override;

IpDataLinkLayer* getPrimaryDataLinkLayer();
TpUartDataLinkLayer* getSecondaryDataLinkLayer();
protected:
InterfaceObject* getInterfaceObject(uint8_t idx);
InterfaceObject* getInterfaceObject(ObjectType objectType, uint8_t objectInstance);
4 changes: 3 additions & 1 deletion src/knx/bau27B0.cpp
Original file line number Diff line number Diff line change
@@ -181,5 +181,7 @@ void Bau27B0::domainAddressSerialNumberReadLocalConfirm(Priority priority, HopCo
{
}


RfDataLinkLayer* Bau27B0::getDataLinkLayer() {
return (RfDataLinkLayer*)&_dlLayer;
}
#endif // #ifdef USE_RF
1 change: 1 addition & 0 deletions src/knx/bau27B0.h
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@ class Bau27B0 : public BauSystemBDevice
bool enabled() override;
void enabled(bool value) override;

RfDataLinkLayer* getDataLinkLayer();
protected:
InterfaceObject* getInterfaceObject(uint8_t idx);
InterfaceObject* getInterfaceObject(ObjectType objectType, uint8_t objectInstance);
7 changes: 7 additions & 0 deletions src/knx/bau2920.cpp
Original file line number Diff line number Diff line change
@@ -154,4 +154,11 @@ void Bau2920::loop()
BauSystemBCoupler::loop();
}

TpUartDataLinkLayer* Bau2920::getPrimaryDataLinkLayer() {
return (TpUartDataLinkLayer*)&_dlLayerPrimary;
}

RfDataLinkLayer* Bau2920::getSecondaryDataLinkLayer() {
return (RfDataLinkLayer*)&_dlLayerSecondary;
}
#endif
2 changes: 2 additions & 0 deletions src/knx/bau2920.h
Original file line number Diff line number Diff line change
@@ -22,6 +22,8 @@ class Bau2920 : public BauSystemBCoupler
bool enabled() override;
void enabled(bool value) override;

TpUartDataLinkLayer* getPrimaryDataLinkLayer();
RfDataLinkLayer* getSecondaryDataLinkLayer();
protected:
InterfaceObject* getInterfaceObject(uint8_t idx);
InterfaceObject* getInterfaceObject(ObjectType objectType, uint8_t objectInstance);
3 changes: 3 additions & 0 deletions src/knx/bau57B0.cpp
Original file line number Diff line number Diff line change
@@ -145,4 +145,7 @@ void Bau57B0::loop()
#endif
}

IpDataLinkLayer* Bau57B0::getDataLinkLayer() {
return (IpDataLinkLayer*)&_dlLayer;
}
#endif
3 changes: 2 additions & 1 deletion src/knx/bau57B0.h
Original file line number Diff line number Diff line change
@@ -15,7 +15,8 @@ class Bau57B0 : public BauSystemBDevice, public DataLinkLayerCallbacks
void loop() override;
bool enabled() override;
void enabled(bool value) override;


IpDataLinkLayer* getDataLinkLayer();
protected:
InterfaceObject* getInterfaceObject(uint8_t idx);
InterfaceObject* getInterfaceObject(ObjectType objectType, uint8_t objectInstance);
8 changes: 8 additions & 0 deletions src/knx/platform.cpp
Original file line number Diff line number Diff line change
@@ -57,6 +57,14 @@ void Platform::closeUart()
void Platform::setupUart()
{}

bool Platform::overflowUart()
{
return false;
}

void Platform::flushUart()
{}

uint32_t Platform::currentIpAddress()
{
return 0x01020304;
2 changes: 2 additions & 0 deletions src/knx/platform.h
Original file line number Diff line number Diff line change
@@ -62,6 +62,8 @@ class Platform
virtual size_t writeUart(const uint8_t* buffer, size_t size);
virtual int readUart();
virtual size_t readBytesUart(uint8_t* buffer, size_t length);
virtual bool overflowUart();
virtual void flushUart();

// SPI
virtual void setupSpi();
302 changes: 302 additions & 0 deletions src/knx/tp_frame.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,302 @@
#pragma once
#pragma GCC optimize("O3")

#include "cemi_frame.h"
#include <cstring>
#include <stdint.h>
#include <string>

// Means that the frame is invalid
#define TP_FRAME_FLAG_INVALID 0b10000000

// Means that the frame is an extended frame
#define TP_FRAME_FLAG_EXTENDED 0b01000000

// Means that the frame has been repeated
#define TP_FRAME_FLAG_REPEATED 0b00100000

// Means that the frame comes from the device itself
#define TP_FRAME_FLAG_ECHO 0b00010000

// Means that the frame is processed by this device
#define TP_FRAME_FLAG_ADDRESSED 0b00000100

// Means that the frame has been acked by this device.
#define TP_FRAME_FLAG_ACKING 0b00000010

// Means that the frame has been acked by other (Busmontior)
#define TP_FRAME_FLAG_ACKED 0b00000001

class TpFrame
{
private:
uint8_t *_data;
uint16_t _size;
uint16_t _maxSize;
uint8_t _flags = 0;

/*
* Sets a few flags based on the control byte
*/
inline void presetFlags()
{
if (isExtended())
addFlags(TP_FRAME_FLAG_EXTENDED);

if (isRepeated())
addFlags(TP_FRAME_FLAG_REPEATED);
}

public:
/*
* Convert a CemiFrame into a TpFrame
*/
TpFrame(CemiFrame &cemiFrame)
{
_size = cemiFrame.telegramLengthtTP();
_maxSize = cemiFrame.telegramLengthtTP();
_data = (uint8_t *)malloc(cemiFrame.telegramLengthtTP());
cemiFrame.fillTelegramTP(_data);
presetFlags();
}

/*
* Create a TpFrame with a reserved space.
* Used for incoming parsing.
*/
TpFrame(uint16_t maxSize = 263)
: _maxSize(maxSize)
{
_data = (uint8_t *)malloc(_maxSize);
_size = 0;
}

/*
* Free the data area
*/
~TpFrame()
{
free(_data);
}

/*
* Add a byte at end.
* Used for incoming parsing.
*/
inline void addByte(uint8_t byte)
{
if (!isFull())
{
_data[_size] = byte;
_size++;
}

// Read meta data for flags
if (_size == 1)
presetFlags();
}

/*
* Current frame size. This may differ from the actual size as long as the frame is not complete.
*/
inline uint16_t size()
{
return _size;
}

/*
* Returns the assigned flags
*/
inline uint16_t flags()
{
return _flags;
}

/*
* Adds one or more flags
*/
inline void addFlags(uint8_t flags)
{
_flags |= flags;
}

/*
* Returns a pointer to the data
*/
inline uint8_t *data()
{
return _data;
}

/*
* Returns the byte corresponding to the specified position
*/
inline uint8_t data(uint16_t pos)
{
return _data[pos];
}

/*
* Resets the internal values to refill the frame.
*/
inline void reset()
{
_size = 0;
_flags = 0;
// It is important to fill the _data with zeros so that the length is 0 as long as the value has not yet been read in.
memset(_data, 0x0, _maxSize);
}

/*
* Checks whether the frame has been imported completely
*/
inline bool isFull()
{
return _size >= (_size >= 7 ? fullSize() : _maxSize);
}

/*
* Returns is the frame exteneded or not
*/
inline bool isExtended()
{
return (_data[0] & 0xD3) == 0x10;
}

/*
* Returns the source
* Assumes that enough data has been imported.
*/
inline uint16_t source()
{
return isExtended() ? (_data[2] << 8) + _data[3] : (_data[1] << 8) + _data[2];
}

inline std::string humanSource()
{
uint16_t value = source();
char buffer[10];
sprintf(buffer, "%02i.%02i.%03i", (value >> 12 & 0b1111), (value >> 8 & 0b1111), (value & 0b11111111));
return buffer;
}

inline std::string humanDestination()
{
uint16_t value = destination();
char buffer[10];
if (isGroupAddress())
sprintf(buffer, "%02i/%02i/%03i", (value >> 11 & 0b1111), (value >> 8 & 0b111), (value & 0b11111111));
else
sprintf(buffer, "%02i.%02i.%03i", (value >> 12 & 0b1111), (value >> 8 & 0b1111), (value & 0b11111111));

return buffer;
}

/*
* Returns the destination
* Assumes that enough data has been imported.
*/
inline uint16_t destination()
{
return isExtended() ? (_data[4] << 8) + _data[5] : (_data[3] << 8) + _data[4];
}

/*
* Returns the payload size (with checksum)
* Assumes that enough data has been imported.
*/
inline uint8_t payloadSize()
{
return isExtended() ? _data[6] : _data[5] & 0b1111;
}

/*
* Returns the header size
*/
inline uint8_t headerSize()
{
return isExtended() ? 9 : 8;
}

/*
* Returns the frame size based on header and payload size.
* Assumes that enough data has been imported.
*/
inline uint16_t fullSize()
{
return headerSize() + payloadSize();
}

/*
* Returns if the destination is a group address
* Assumes that enough data has been imported.
*/
inline bool isGroupAddress()
{
return isExtended() ? (_data[1] >> 7) & 0b1 : (_data[5] >> 7) & 0b1;
}

/*
* Calculates the size of a CemiFrame. A CemiFrame has 2 additional bytes at the beginning.
* An additional byte is added to a standard frame, as this still has to be converted into an extendend.
*/
uint16_t cemiSize()
{
return fullSize() + (isExtended() ? 2 : 3);
}

/**
* Creates a buffer and converts the TpFrame into a CemiFrame.
* Important: After processing (i.e. also after using the CemiFrame), the reference must be released manually.
*/
uint8_t *cemiData()
{
uint8_t *cemiBuffer = (uint8_t *)malloc(cemiSize());

// Das CEMI erwartet die Daten im Extended format inkl. zwei zusätzlicher Bytes am Anfang.
cemiBuffer[0] = 0x29;
cemiBuffer[1] = 0x0;
cemiBuffer[2] = _data[0];
if (isExtended())
{
memcpy(cemiBuffer + 2, _data, fullSize());
}
else
{
cemiBuffer[3] = _data[5] & 0xF0;
memcpy(cemiBuffer + 4, _data + 1, 4);
cemiBuffer[8] = _data[5] & 0x0F;
memcpy(cemiBuffer + 9, _data + 6, cemiBuffer[8] + 2);
}

return cemiBuffer;
}

/*
* Checks whether the frame is complete and valid.
*/
inline bool isValid()
{
if (!isComplete())
return false;

uint8_t sum = 0;
const uint16_t s = fullSize() - 1;
for (uint16_t i = 0; i < s; i++)
sum ^= _data[i];
return _data[s] == (uint8_t)~sum;
}

/*
* Checks whether the frame is long enough to match the length specified in the frame
*/
inline bool isComplete()
{
return _size == fullSize();
}

inline bool isRepeated()
{
return !(_data[0] & 0b100000);
}
};
1,614 changes: 1,052 additions & 562 deletions src/knx/tpuart_data_link_layer.cpp

Large diffs are not rendered by default.

178 changes: 138 additions & 40 deletions src/knx/tpuart_data_link_layer.h
Original file line number Diff line number Diff line change
@@ -3,14 +3,31 @@
#include "config.h"
#ifdef USE_TP

#include <stdint.h>
#include "data_link_layer.h"
#include "tp_frame.h"
#include <stdint.h>

#define MAX_KNX_TELEGRAM_SIZE 263

#ifndef MAX_RX_QUEUE_BYTES
#define MAX_RX_QUEUE_BYTES MAX_KNX_TELEGRAM_SIZE + 50
#endif

#ifndef MAX_TX_QUEUE
#define MAX_TX_QUEUE 50
#endif

// __time_critical_func fallback
#ifndef ARDUINO_ARCH_RP2040
#define __time_critical_func(X) X
#define __isr
#endif

void printFrame(TpFrame* tpframe);

class ITpUartCallBacks
{
public:
public:
virtual ~ITpUartCallBacks() = default;
virtual bool isAckRequired(uint16_t address, bool isGrpAddr) = 0;
};
@@ -24,56 +41,137 @@ class TpUartDataLinkLayer : public DataLinkLayer
TpUartDataLinkLayer(DeviceObject& devObj, NetworkLayerEntity& netLayerEntity,
Platform& platform, ITpUartCallBacks& cb, DataLinkLayerCallbacks* dllcb = nullptr);



void loop();
void enabled(bool value);
bool enabled() const;
DptMedium mediumType() const override;
bool reset();
void monitor();
void stop(bool state);
void requestBusy(bool state);
void forceAck(bool state);
void setRepetitions(uint8_t nack, uint8_t busy);
// Alias
void setFrameRepetition(uint8_t nack, uint8_t busy);
bool isConnected();
bool isMonitoring();
bool isStopped();
bool isBusy();

#ifdef USE_TP_RX_QUEUE
void processRxISR();
#endif
#ifdef NCN5120
void powerControl(bool state);
#endif

uint32_t getRxInvalidFrameCounter();
uint32_t getRxProcessdFrameCounter();
uint32_t getRxIgnoredFrameCounter();
uint32_t getRxUnknownControlCounter();
uint32_t getTxFrameCounter();
uint32_t getTxProcessedFrameCounter();
uint8_t getMode();

private:
bool _enabled = false;
uint8_t* _sendBuffer = 0;
uint16_t _sendBufferLength = 0;
uint8_t _receiveBuffer[MAX_KNX_TELEGRAM_SIZE];
uint8_t _txState = 0;
uint8_t _rxState = 0;
uint16_t _RxByteCnt = 0;
uint16_t _TxByteCnt = 0;
uint8_t _oldIdx = 0;
bool _isEcho = false;
bool _convert = false;
uint8_t _xorSum = 0;
uint32_t _lastByteRxTime;
uint32_t _lastByteTxTime;
uint32_t _lastLoopTime;
uint32_t _waitConfirmStartTime = 0;
uint32_t _lastResetChipTime = 0;

struct _tx_queue_frame_t
// Frame
struct knx_tx_queue_entry_t
{
uint8_t* data;
uint16_t length;
_tx_queue_frame_t* next;
TpFrame* frame;
knx_tx_queue_entry_t* next = nullptr;

knx_tx_queue_entry_t(TpFrame* tpFrame)
: frame(tpFrame)
{
}
};

struct _tx_queue_t
// TX Queue
struct knx_tx_queue_t
{
_tx_queue_frame_t* front = NULL;
_tx_queue_frame_t* back = NULL;
} _tx_queue;

void addFrameTxQueue(CemiFrame& frame);
bool isTxQueueEmpty();
void loadNextTxFrame();
bool sendSingleFrameByte();
knx_tx_queue_entry_t* front = nullptr;
knx_tx_queue_entry_t* back = nullptr;
} _txFrameQueue;

TpFrame* _txFrame = nullptr;
TpFrame* _rxFrame = nullptr;

volatile bool _stopped = false;
volatile bool _connected = false;
volatile bool _monitoring = false;
volatile bool _busy = false;
volatile bool _initialized = false;

volatile uint8_t _rxState = 0;
volatile uint8_t _txState = 0;
volatile uint32_t _rxProcessdFrameCounter = 0;
volatile uint32_t _rxInvalidFrameCounter = 0;
volatile uint32_t _rxIgnoredFrameCounter = 0;
volatile uint32_t _rxUnkownControlCounter = 0;
volatile uint32_t _txFrameCounter = 0;
volatile uint32_t _txProcessdFrameCounter = 0;
volatile bool _rxMarker = false;
volatile bool _rxOverflow = false;
volatile uint8_t _tpState = 0x0;
volatile uint32_t _txLastTime = 0;
volatile uint32_t _rxLastTime = 0;
volatile bool _forceAck = false;
uint8_t _txQueueCount = 0;

inline bool markerMode();

/*
* bits
*
* 5-7 Busy (Default 11 = 3)
* 0-3 Nack (Default 11 = 3)
*/
volatile uint8_t _repetitions = 0b00110011;

// to prevent parallel rx processing by isr (when using)
volatile bool _rxProcessing = false;

volatile uint32_t _lastStateRequest = 0;

// void loadNextTxFrame();
inline bool processTxFrameBytes();
bool sendFrame(CemiFrame& frame);
void frameBytesReceived(uint8_t* buffer, uint16_t length);
void rxFrameReceived(TpFrame* frame);
void dataConBytesReceived(uint8_t* buffer, uint16_t length, bool success);
void enterRxWaitEOP();
bool resetChip();
bool resetChipTick();
void stopChip();

void processRx(bool isr = false);
void checkConnected();
void processRxByte();
void processTxQueue();
void clearTxFrameQueue();
void processRxFrameComplete();
inline void processRxFrame(TpFrame* tpFrame);
void pushTxFrameQueue(TpFrame* tpFrame);
void requestState(bool force = false);
void requestConfig();
inline void processRxFrameByte(uint8_t byte);

#ifdef USE_TP_RX_QUEUE
// Es muss ein Extended Frame rein passen + 1Byte je erlaubter ms Verzögerung
volatile uint8_t _rxBuffer[MAX_RX_QUEUE_BYTES] = {};
volatile uint16_t _rxBufferFront = 0;
volatile uint16_t _rxBufferRear = 0;
volatile uint8_t _rxBufferCount = 0;

void pushByteToRxQueue(uint8_t byte);
uint8_t pullByteFromRxQueue();
uint16_t availableInRxQueue();
void pushRxFrameQueue();
void processRxQueue();
#endif

inline bool isrLock(bool blocking = false);
inline void isrUnlock();
inline void clearUartBuffer();
inline void connected(bool state = true);
void clearTxFrame();
void clearOutdatedTxFrame();
void processTxFrameComplete(bool success);

ITpUartCallBacks& _cb;
DataLinkLayerCallbacks* _dllcb;
293 changes: 240 additions & 53 deletions src/rp2040_arduino_platform.cpp

Large diffs are not rendered by default.

31 changes: 30 additions & 1 deletion src/rp2040_arduino_platform.h
Original file line number Diff line number Diff line change
@@ -58,6 +58,22 @@

#endif

#if USE_KNX_DMA_UART == 1
#define KNX_DMA_UART uart1
#define KNX_DMA_UART_IRQ UART1_IRQ
#define KNX_DMA_UART_DREQ DREQ_UART1_RX
#else
#define KNX_DMA_UART uart0
#define KNX_DMA_UART_IRQ UART0_IRQ
#define KNX_DMA_UART_DREQ DREQ_UART0_RX
#endif

#if USE_KNX_DMA_IRQ == 1
#define KNX_DMA_IRQ DMA_IRQ_1
#else
#define KNX_DMA_IRQ DMA_IRQ_0
#endif


class RP2040ArduinoPlatform : public ArduinoPlatform
{
@@ -67,7 +83,20 @@ class RP2040ArduinoPlatform : public ArduinoPlatform

// uart
void knxUartPins(pin_size_t rxPin, pin_size_t txPin);
void setupUart();
void setupUart() override;
bool overflowUart() override;
#ifdef USE_KNX_DMA_UART
int uartAvailable() override;
void closeUart() override;
void knxUart( HardwareSerial* serial) override {};
HardwareSerial* knxUart() override { return nullptr; };
size_t writeUart(const uint8_t data) override;
size_t writeUart(const uint8_t* buffer, size_t size) override { return 0; };
int readUart() override;
size_t readBytesUart(uint8_t* buffer, size_t length) override { return 0; };
void flushUart() override {};
#endif


// unique serial number
uint32_t uniqueSerialNumber() override;