mirror of
https://github.com/thelsing/knx.git
synced 2024-12-18 19:08:18 +01:00
Merge commit '093ae42' into openknx-merge
This commit is contained in:
commit
5ddbff2d16
10
.vscode/extensions.json
vendored
10
.vscode/extensions.json
vendored
@ -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"
|
||||
]
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
@ -119,7 +107,7 @@ size_t GroupObject::goSize()
|
||||
}
|
||||
|
||||
// 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()
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -109,8 +109,9 @@ bool GroupObjectTableObject::initGroupObjects()
|
||||
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();
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -57,6 +57,7 @@ class TpUartDataLinkLayer : public DataLinkLayer
|
||||
bool isMonitoring();
|
||||
bool isStopped();
|
||||
bool isBusy();
|
||||
void resetStats();
|
||||
|
||||
#ifdef USE_TP_RX_QUEUE
|
||||
void processRxISR();
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user