diff --git a/src/knx/group_object.cpp b/src/knx/group_object.cpp index b7c74d80..0abbfc0f 100644 --- a/src/knx/group_object.cpp +++ b/src/knx/group_object.cpp @@ -12,7 +12,8 @@ GroupObjectTableObject* GroupObject::_table = 0; GroupObject::GroupObject() { _data = 0; - _commFlag = Uninitialized; + _commFlagEx.uninitialized = true; + _commFlagEx.commFlag = Uninitialized; _dataLength = 0; #ifndef SMALL_GROUPOBJECT _updateHandler = 0; @@ -22,7 +23,7 @@ GroupObject::GroupObject() GroupObject::GroupObject(const GroupObject& other) { _data = new uint8_t[other._dataLength]; - _commFlag = other._commFlag; + _commFlagEx = other._commFlagEx; _dataLength = other._dataLength; _asap = other._asap; #ifndef SMALL_GROUPOBJECT @@ -75,7 +76,7 @@ bool GroupObject::readEnable() return false; // we forbid reading of new (uninitialized) go - if (_commFlag == Uninitialized) + if (_commFlagEx.uninitialized) return false; return bitRead(ntohs(_table->_tableData[_asap]), 11) > 0; @@ -157,22 +158,29 @@ size_t GroupObject::asapValueSize(uint8_t code) ComFlag GroupObject::commFlag() { - return _commFlag; + return _commFlagEx.commFlag; } void GroupObject::commFlag(ComFlag value) { - _commFlag = value; + _commFlagEx.commFlag = value; + if (value == WriteRequest || value == Updated || value == Ok) + _commFlagEx.uninitialized = false; +} + +bool GroupObject::initialized() +{ + return !_commFlagEx.uninitialized; } void GroupObject::requestObjectRead() { - _commFlag = ReadRequest; + commFlag(ReadRequest); } void GroupObject::objectWritten() { - _commFlag = WriteRequest; + commFlag(WriteRequest); } size_t GroupObject::valueSize() @@ -274,15 +282,15 @@ void GroupObject::valueNoSend(const KNXValue& value) void GroupObject::valueNoSend(const KNXValue& value, const Dpt& type) { - if (_commFlag == Uninitialized) - _commFlag = Ok; + if (_commFlagEx.uninitialized) + commFlag(Ok); KNX_Encode_Value(value, _data, _dataLength, type); } bool GroupObject::valueNoSendCompare(const KNXValue& value, const Dpt& type) { - if (_commFlag == Uninitialized) + if (_commFlagEx.uninitialized) { // always set first value this->valueNoSend(value, type); diff --git a/src/knx/group_object.h b/src/knx/group_object.h index 7c9191b1..85975bea 100644 --- a/src/knx/group_object.h +++ b/src/knx/group_object.h @@ -7,7 +7,13 @@ class GroupObjectTableObject; -enum ComFlag +/** + * LIMITATION: The differentiation between uninitialized and initialized state can NOT be represented correctly in ComFlag alone: + * It might be in state Transmitting during a ReadRequest on startup while value is still not valid. + * + * See ComFlagEx for a clear uninitialized handling. + */ +enum ComFlag : uint8_t { Updated = 0, //!< Group object was updated ReadRequest = 1, //!< Read was requested but was not processed @@ -15,7 +21,21 @@ enum ComFlag Transmitting = 3, //!< Group Object is processed a the moment (read or write) Ok = 4, //!< read or write request were send successfully Error = 5, //!< there was an error on processing a request - Uninitialized = 6 //!< uninitialized Group Object, its value is not valid + Uninitialized = 6 //!< uninitialized Group Object, its value is not valid; WARNING: Other Values do NOT guarantee an actual valid value! +}; + +/** + * Extended ComFlag + * Add a separate uninitialized flag to overcome the limitations of ComFlag. + * + * Implementation Note: + * We use MSB to store uninitialized state and keep the size of GroupObject the same saving memory resources. + * The old uninitialized handling is not changed for compatibility reasons. + */ +struct ComFlagEx +{ + bool uninitialized : 1; + ComFlag commFlag : 7; }; class GroupObject; @@ -96,6 +116,11 @@ class GroupObject */ void commFlag(ComFlag value); + /** + * Check if the group object contains a valid value assigned from bus or from application program + */ + bool initialized(); + /** * Request the read of a communication object. Calling this function triggers the * sending of a read-group-value telegram, to read the value of the communication @@ -249,7 +274,7 @@ class GroupObject size_t asapValueSize(uint8_t code); size_t goSize(); uint16_t _asap = 0; - ComFlag _commFlag = Uninitialized; + ComFlagEx _commFlagEx; uint8_t* _data = 0; uint8_t _dataLength = 0; #ifndef SMALL_GROUPOBJECT