Merge commit '093ae42' into openknx-merge

This commit is contained in:
Thomas Kunze 2024-08-09 20:14:40 +02:00
commit 5ddbff2d16
10 changed files with 75 additions and 65 deletions

View File

@ -1,10 +0,0 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
],
"unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
}

View File

@ -517,15 +517,13 @@ int busValueToAccess(const uint8_t* payload, size_t payload_length, const Dpt& d
int busValueToString(const uint8_t* payload, size_t payload_length, const Dpt& datatype, KNXValue& value)
{
ASSERT_PAYLOAD(14);
char strValue[15];
strValue[14] = '\0';
for (int n = 0; n < 14; ++n)
{
strValue[n] = signed8FromPayload(payload, n);
if (!datatype.subGroup && (strValue[n] & 0x80))
auto value = signed8FromPayload(payload, n);
if (!datatype.subGroup && (value & 0x80))
return false;
}
value = strValue;
value = (const char*) payload;
return true;
}

View File

@ -20,18 +20,6 @@ GroupObject::GroupObject()
#endif
}
GroupObject::GroupObject(const GroupObject& other)
{
_data = new uint8_t[other._dataLength];
_commFlagEx = other._commFlagEx;
_dataLength = other._dataLength;
_asap = other._asap;
#ifndef SMALL_GROUPOBJECT
_updateHandler = other._updateHandler;
#endif
memcpy(_data, other._data, _dataLength);
}
GroupObject::~GroupObject()
{
if (_data)
@ -114,12 +102,12 @@ size_t GroupObject::goSize()
size_t size = sizeInTelegram();
if (size == 0)
return 1;
return size;
}
// see knxspec 3.5.1 p. 178
size_t GroupObject::asapValueSize(uint8_t code)
size_t GroupObject::asapValueSize(uint8_t code) const
{
if (code < 7)
return 0;
@ -194,6 +182,17 @@ size_t GroupObject::sizeInTelegram()
return asapValueSize(code);
}
size_t GroupObject::sizeInMemory() const
{
uint8_t code = lowByte(ntohs(_table->_tableData[_asap]));
size_t result = asapValueSize(code);
if (code == 0)
return 1;
if (code == 14)
return 14 + 1;
return result;
}
#ifdef SMALL_GROUPOBJECT
GroupObjectUpdatedHandler GroupObject::classCallback()
{

View File

@ -57,10 +57,6 @@ class GroupObject
* The constructor.
*/
GroupObject();
/**
* The copy constructor.
*/
GroupObject(const GroupObject& other);
/**
* The destructor.
*/
@ -139,6 +135,11 @@ class GroupObject
* will return 0.
*/
size_t sizeInTelegram();
/**
* returns the size of the group object in the heap memory of the group object. The function returns the same value as goSize(),
* exept fot the 14 byte string type to reserve one byte of a \0 terminator character.
*/
size_t sizeInMemory() const;
/**
* returns the pointer to the value of the group object. This can be used if a datapoint type is not supported or if you want do
* your own conversion.
@ -274,7 +275,7 @@ class GroupObject
static GroupObjectUpdatedHandler _updateHandlerStatic;
#endif
size_t asapValueSize(uint8_t code);
size_t asapValueSize(uint8_t code) const;
size_t goSize();
uint16_t _asap = 0;
ComFlagEx _commFlagEx;

View File

@ -107,10 +107,11 @@ bool GroupObjectTableObject::initGroupObjects()
GroupObject& go = _groupObjects[asap - 1];
go._asap = asap;
go._table = this;
go._dataLength = go.goSize();
go._data = new uint8_t[go._dataLength];
memset(go._data, 0, go._dataLength);
size_t sizeInMemory = go.sizeInMemory();
go._data = new uint8_t[sizeInMemory];
memset(go._data, 0, sizeInMemory);
if (go.valueReadOnInit())
go.requestObjectRead();

View File

@ -19,13 +19,16 @@
#define TP_FRAME_FLAG_ECHO 0b00010000
// Means that the frame is processed by this device
#define TP_FRAME_FLAG_ADDRESSED 0b00000100
#define TP_FRAME_FLAG_ADDRESSED 0b00001000
// Means that the frame has been acked by this device.
#define TP_FRAME_FLAG_ACKING 0b00000010
// Means that the frame has been acked with BUSY
#define TP_FRAME_FLAG_ACK_BUSY 0b00000100
// Means that the frame has been acked by other (Busmontior)
#define TP_FRAME_FLAG_ACKED 0b00000001
// Means that the frame has been acked with NACK
#define TP_FRAME_FLAG_ACK_NACK 0b00000010
// Means that the frame has been acked
#define TP_FRAME_FLAG_ACK 0b00000001
class TpFrame
{

View File

@ -60,6 +60,8 @@
// acknowledge services (device is transparent in bus monitor mode)
#define L_ACKN_IND 0x00
#define L_ACKN_MASK 0x33
#define L_ACKN_BUSY_MASK 0x0C
#define L_ACKN_NACK_MASK 0xC0
#define L_DATA_CON 0x0B
#define L_DATA_CON_MASK 0x7F
#define SUCCESS 0x80
@ -138,11 +140,11 @@ void printFrame(TpFrame *tpframe)
print((tpframe->flags() & TP_FRAME_FLAG_INVALID) ? 'I' : '_'); // Invalid
print((tpframe->flags() & TP_FRAME_FLAG_EXTENDED) ? 'E' : '_'); // Extended
print((tpframe->flags() & TP_FRAME_FLAG_REPEATED) ? 'R' : '_'); // Repeat
print((tpframe->flags() & TP_FRAME_FLAG_ECHO) ? 'O' : '_'); // My own
print((tpframe->flags() & 0b00001000) ? 'x' : '_'); // Reserve
print((tpframe->flags() & TP_FRAME_FLAG_ADDRESSED) ? 'D' : '_'); // For me
print((tpframe->flags() & TP_FRAME_FLAG_ACKING) ? 'A' : '_'); // ACK recevied
print((tpframe->flags() & TP_FRAME_FLAG_ACKED) ? 'A' : '_'); // ACK sent
print((tpframe->flags() & TP_FRAME_FLAG_ECHO) ? 'T' : '_'); // Send by me
print((tpframe->flags() & TP_FRAME_FLAG_ADDRESSED) ? 'D' : '_'); // Recv for me
print((tpframe->flags() & TP_FRAME_FLAG_ACK_NACK) ? 'N' : '_'); // ACK + NACK
print((tpframe->flags() & TP_FRAME_FLAG_ACK_BUSY) ? 'B' : '_'); // ACK + BUSY
print((tpframe->flags() & TP_FRAME_FLAG_ACK) ? 'A' : '_'); // ACK
print("] ");
printHex("( ", tpframe->data(), tpframe->size(), false);
print(")");
@ -294,7 +296,13 @@ void TpUartDataLinkLayer::processRxByte()
*/
if (_rxFrame->size() > 0)
{
_rxFrame->addFlags(TP_FRAME_FLAG_ACKED);
if (!(byte & L_ACKN_BUSY_MASK))
_rxFrame->addFlags(TP_FRAME_FLAG_ACK_BUSY);
if (!(byte & L_ACKN_NACK_MASK))
_rxFrame->addFlags(TP_FRAME_FLAG_ACK_NACK);
_rxFrame->addFlags(TP_FRAME_FLAG_ACK);
processRxFrameComplete();
}
// println("L_ACKN_IND");
@ -412,8 +420,8 @@ void TpUartDataLinkLayer::processRxFrameByte(uint8_t byte)
// Of course, this is only allowed if I am not sending myself, as you cannot ACK your own frames
if (_txState == TX_IDLE)
{
// Save that tracking should take place
_rxFrame->addFlags(TP_FRAME_FLAG_ACKING);
// Save that Acking should take place
_rxFrame->addFlags(TP_FRAME_FLAG_ACK);
// and in the TPUart so that it can send the ACK
_platform.writeUart(U_ACK_REQ | U_ACK_REQ_ADRESSED);
@ -468,8 +476,8 @@ void TpUartDataLinkLayer::processRxFrameComplete()
// When a frame has been sent
if (_txState == TX_FRAME)
{
// check whether the reception corresponds to this
if (!memcmp(_rxFrame->data(), _txFrame->data(), _txFrame->size()))
// check whether the receive corresponds to this: comparison of the source address and destination address and start byte without taking the retry bit into account
if(!((_rxFrame->data(0) ^ _txFrame->data(0)) & ~0x20) && _rxFrame->destination() == _txFrame->destination() && _rxFrame->source() == _txFrame->source())
{
// and mark this accordingly
// println("MATCH");
@ -563,7 +571,6 @@ void TpUartDataLinkLayer::pushTxFrameQueue(TpFrame *tpFrame)
}
_txQueueCount++;
_txFrameCounter++;
}
void TpUartDataLinkLayer::setRepetitions(uint8_t nack, uint8_t busy)
@ -579,12 +586,15 @@ void TpUartDataLinkLayer::setFrameRepetition(uint8_t nack, uint8_t busy)
bool TpUartDataLinkLayer::sendFrame(CemiFrame &cemiFrame)
{
_txFrameCounter++;
if (!_connected || _monitoring || _txQueueCount > MAX_TX_QUEUE)
{
if (_txQueueCount > MAX_TX_QUEUE)
{
println("Ignore frame because transmit queue is full!");
}
dataConReceived(cemiFrame, false);
return false;
}
@ -691,6 +701,17 @@ void TpUartDataLinkLayer::connected(bool state /* = true */)
_connected = state;
}
void TpUartDataLinkLayer::resetStats()
{
_rxProcessdFrameCounter = 0;
_rxIgnoredFrameCounter = 0;
_rxInvalidFrameCounter = 0;
_rxInvalidFrameCounter = 0;
_rxUnkownControlCounter = 0;
_txFrameCounter = 0;
_txProcessdFrameCounter = 0;
}
bool TpUartDataLinkLayer::reset()
{
// println("Reset TP");
@ -704,11 +725,7 @@ bool TpUartDataLinkLayer::reset()
isrLock(true);
// Reset
_rxIgnoredFrameCounter = 0;
_rxInvalidFrameCounter = 0;
_rxInvalidFrameCounter = 0;
_rxUnkownControlCounter = 0;
resetStats();
clearTxFrame();
clearTxFrameQueue();
@ -791,6 +808,7 @@ void TpUartDataLinkLayer::monitor()
// println("busmonitor");
_monitoring = true;
_platform.writeUart(U_BUSMON_REQ);
resetStats();
}
void TpUartDataLinkLayer::enabled(bool value)

View File

@ -57,6 +57,7 @@ class TpUartDataLinkLayer : public DataLinkLayer
bool isMonitoring();
bool isStopped();
bool isBusy();
void resetStats();
#ifdef USE_TP_RX_QUEUE
void processRxISR();

View File

@ -286,10 +286,10 @@ template <class P, class B> class KnxFacade : private SaveRestore
pinMode(ledPin(), OUTPUT);
progLedOff();
pinMode(buttonPin(), INPUT_PULLUP);
if (_progButtonISRFuncPtr && _buttonPin >= 0)
{
pinMode(buttonPin(), INPUT_PULLUP);
// Workaround for https://github.com/arduino/ArduinoCore-samd/issues/587
#if (ARDUINO_API_VERSION >= 10200)
attachInterrupt(_buttonPin, _progButtonISRFuncPtr, (PinStatus)CHANGE);

View File

@ -517,11 +517,10 @@ int RP2040ArduinoPlatform::readBytesMultiCast(uint8_t* buffer, uint16_t maxLen)
if (len > maxLen)
{
print("udp buffer to small. was ");
print(maxLen);
print(", needed ");
println(len);
fatalError();
println("Unexpected UDP data packet length - drop packet");
for (size_t i = 0; i < len; i++)
_udp.read();
return 0;
}
_udp.read(buffer, len);