mirror of
https://github.com/thelsing/knx.git
synced 2025-04-23 01:16:29 +02:00
Merge branch 'master' into feat_datasecure
This commit is contained in:
commit
318d350243
@ -93,6 +93,7 @@
|
|||||||
<ClInclude Include="..\..\src\knx\device_object.h" />
|
<ClInclude Include="..\..\src\knx\device_object.h" />
|
||||||
<ClInclude Include="..\..\src\knx\dpt.h" />
|
<ClInclude Include="..\..\src\knx\dpt.h" />
|
||||||
<ClInclude Include="..\..\src\knx\dptconvert.h" />
|
<ClInclude Include="..\..\src\knx\dptconvert.h" />
|
||||||
|
<ClInclude Include="..\..\src\knx\function_property.h" />
|
||||||
<ClInclude Include="..\..\src\knx\group_object.h" />
|
<ClInclude Include="..\..\src\knx\group_object.h" />
|
||||||
<ClInclude Include="..\..\src\knx\group_object_table_object.h" />
|
<ClInclude Include="..\..\src\knx\group_object_table_object.h" />
|
||||||
<ClInclude Include="..\..\src\knx\interface_object.h" />
|
<ClInclude Include="..\..\src\knx\interface_object.h" />
|
||||||
|
@ -194,6 +194,9 @@
|
|||||||
<ClInclude Include="..\..\src\knx\knx_ip_supported_service_dib.h">
|
<ClInclude Include="..\..\src\knx\knx_ip_supported_service_dib.h">
|
||||||
<Filter>Header files\knx</Filter>
|
<Filter>Header files\knx</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\src\knx\function_property.h">
|
||||||
|
<Filter>Header files\knx</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="main.cpp">
|
<ClCompile Include="main.cpp">
|
||||||
|
@ -487,7 +487,7 @@ void ApplicationLayer::systemNetworkParameterReadResponse(Priority priority, Hop
|
|||||||
|
|
||||||
//TODO: ApplicationLayer::domainAddressSerialNumberWriteRequest()
|
//TODO: ApplicationLayer::domainAddressSerialNumberWriteRequest()
|
||||||
//TODO: ApplicationLayer::domainAddressSerialNumberReadRequest()
|
//TODO: ApplicationLayer::domainAddressSerialNumberReadRequest()
|
||||||
void ApplicationLayer::domainAddressSerialNumberReadResponse(Priority priority, HopCountType hopType, uint8_t* rfDoA,
|
void ApplicationLayer::domainAddressSerialNumberReadResponse(Priority priority, HopCountType hopType, const uint8_t* rfDoA,
|
||||||
const uint8_t* knxSerialNumber)
|
const uint8_t* knxSerialNumber)
|
||||||
{
|
{
|
||||||
CemiFrame frame(13);
|
CemiFrame frame(13);
|
||||||
@ -506,8 +506,8 @@ void ApplicationLayer::domainAddressSerialNumberReadResponse(Priority priority,
|
|||||||
|
|
||||||
//TODO: ApplicationLayer::IndividualAddressSerialNumberWriteRequest()
|
//TODO: ApplicationLayer::IndividualAddressSerialNumberWriteRequest()
|
||||||
//TODO: ApplicationLayer::IndividualAddressSerialNumberReadRequest()
|
//TODO: ApplicationLayer::IndividualAddressSerialNumberReadRequest()
|
||||||
void ApplicationLayer::IndividualAddressSerialNumberReadResponse(Priority priority, HopCountType hopType, uint8_t* rfDoA,
|
void ApplicationLayer::IndividualAddressSerialNumberReadResponse(Priority priority, HopCountType hopType, const uint8_t* rfDoA,
|
||||||
uint8_t* knxSerialNumber)
|
const uint8_t* knxSerialNumber)
|
||||||
{
|
{
|
||||||
CemiFrame frame(13);
|
CemiFrame frame(13);
|
||||||
APDU& apdu = frame.apdu();
|
APDU& apdu = frame.apdu();
|
||||||
|
@ -135,10 +135,10 @@ class ApplicationLayer
|
|||||||
void systemNetworkParameterReadResponse(Priority priority, HopCountType hopType, uint16_t objectType,
|
void systemNetworkParameterReadResponse(Priority priority, HopCountType hopType, uint16_t objectType,
|
||||||
uint16_t propertyId, uint8_t* testInfo, uint16_t testInfoLength,
|
uint16_t propertyId, uint8_t* testInfo, uint16_t testInfoLength,
|
||||||
uint8_t* testResult, uint16_t testResultLength);
|
uint8_t* testResult, uint16_t testResultLength);
|
||||||
void domainAddressSerialNumberReadResponse(Priority priority, HopCountType hopType, uint8_t* rfDoA,
|
void domainAddressSerialNumberReadResponse(Priority priority, HopCountType hopType, const uint8_t* rfDoA,
|
||||||
|
const uint8_t* knxSerialNumber);
|
||||||
|
void IndividualAddressSerialNumberReadResponse(Priority priority, HopCountType hopType, const uint8_t* rfDoA,
|
||||||
const uint8_t* knxSerialNumber);
|
const uint8_t* knxSerialNumber);
|
||||||
void IndividualAddressSerialNumberReadResponse(Priority priority, HopCountType hopType, uint8_t* rfDoA,
|
|
||||||
uint8_t* knxSerialNumber);
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -56,6 +56,9 @@ void BauSystemB::enabled(bool value)
|
|||||||
|
|
||||||
void BauSystemB::sendNextGroupTelegram()
|
void BauSystemB::sendNextGroupTelegram()
|
||||||
{
|
{
|
||||||
|
if(!configured())
|
||||||
|
return;
|
||||||
|
|
||||||
static uint16_t startIdx = 1;
|
static uint16_t startIdx = 1;
|
||||||
|
|
||||||
GroupObjectTableObject& table = _groupObjTable;
|
GroupObjectTableObject& table = _groupObjTable;
|
||||||
|
@ -34,7 +34,7 @@ uint32_t digitalRead(uint32_t dwPin);
|
|||||||
typedef void (*voidFuncPtr)(void);
|
typedef void (*voidFuncPtr)(void);
|
||||||
void attachInterrupt(uint32_t pin, voidFuncPtr callback, uint32_t mode);
|
void attachInterrupt(uint32_t pin, voidFuncPtr callback, uint32_t mode);
|
||||||
|
|
||||||
#elif ARDUINO_ARCH_SAMD
|
#elif ARDUINO_ARCH_SAMD || ARDUINO_ARCH_STM32
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
||||||
#define getbyte(x,n) (*(((uint8_t*)&(x))+n))
|
#define getbyte(x,n) (*(((uint8_t*)&(x))+n))
|
||||||
|
@ -323,9 +323,9 @@ uint8_t* CemiFrame::rfSerialOrDoA() const
|
|||||||
return _rfSerialOrDoA;
|
return _rfSerialOrDoA;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CemiFrame::rfSerialOrDoA(uint8_t* rfSerialOrDoA)
|
void CemiFrame::rfSerialOrDoA(const uint8_t* rfSerialOrDoA)
|
||||||
{
|
{
|
||||||
_rfSerialOrDoA = rfSerialOrDoA;
|
_rfSerialOrDoA = (uint8_t*)rfSerialOrDoA;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t CemiFrame::rfInfo() const
|
uint8_t CemiFrame::rfInfo() const
|
||||||
|
@ -60,7 +60,7 @@ class CemiFrame
|
|||||||
#ifdef USE_RF
|
#ifdef USE_RF
|
||||||
// only for RF medium
|
// only for RF medium
|
||||||
uint8_t* rfSerialOrDoA() const;
|
uint8_t* rfSerialOrDoA() const;
|
||||||
void rfSerialOrDoA(uint8_t* rfSerialOrDoA);
|
void rfSerialOrDoA(const uint8_t* rfSerialOrDoA);
|
||||||
uint8_t rfInfo() const;
|
uint8_t rfInfo() const;
|
||||||
void rfInfo(uint8_t rfInfo);
|
void rfInfo(uint8_t rfInfo);
|
||||||
uint8_t rfLfn() const;
|
uint8_t rfLfn() const;
|
||||||
|
@ -416,11 +416,11 @@ int busValueToUnsigned8(const uint8_t* payload, size_t payload_length, const Dpt
|
|||||||
switch (datatype.subGroup)
|
switch (datatype.subGroup)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
value = (uint8_t)(unsigned8FromPayload(payload, 0) * 100.0 / 255.0);
|
value = (uint8_t)round(unsigned8FromPayload(payload, 0) * 100.0 / 255.0);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
value = (uint8_t)unsigned8FromPayload(payload, 0) * 360.0 / 255.0;
|
value = (uint8_t)round(unsigned8FromPayload(payload, 0) * 360.0 / 255.0);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case 6:
|
case 6:
|
||||||
@ -1043,7 +1043,7 @@ int valueToBusValueSigned8(const KNXValue& value, uint8_t* payload, size_t paylo
|
|||||||
if ((int64_t)value < INT64_C(-128) || (int64_t)value > INT64_C(127))
|
if ((int64_t)value < INT64_C(-128) || (int64_t)value > INT64_C(127))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
signed8ToPayload(payload, 0, payload_length, (uint64_t)value, 0xFF);
|
signed8ToPayload(payload, payload_length, 0, (uint64_t)value, 0xFF);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1723,8 +1723,9 @@ double float16FromPayload(const uint8_t* payload, int index)
|
|||||||
}
|
}
|
||||||
float float32FromPayload(const uint8_t* payload, int index)
|
float float32FromPayload(const uint8_t* payload, int index)
|
||||||
{
|
{
|
||||||
uint32_t area = unsigned32FromPayload(payload, index);
|
union { float f; uint32_t i; } area;
|
||||||
return *((float*)&area);
|
area.i = unsigned32FromPayload(payload, index);
|
||||||
|
return area.f;
|
||||||
}
|
}
|
||||||
int64_t signed64FromPayload(const uint8_t* payload, int index)
|
int64_t signed64FromPayload(const uint8_t* payload, int index)
|
||||||
{
|
{
|
||||||
@ -1815,8 +1816,9 @@ void float16ToPayload(uint8_t* payload, size_t payload_length, int index, double
|
|||||||
}
|
}
|
||||||
void float32ToPayload(uint8_t* payload, size_t payload_length, int index, double value, uint32_t mask)
|
void float32ToPayload(uint8_t* payload, size_t payload_length, int index, double value, uint32_t mask)
|
||||||
{
|
{
|
||||||
float num = value;
|
union { float f; uint32_t i; } num;
|
||||||
unsigned32ToPayload(payload, payload_length, index, *((uint32_t*)&num), mask);
|
num.f = value;
|
||||||
|
unsigned32ToPayload(payload, payload_length, index, num.i, mask);
|
||||||
}
|
}
|
||||||
void signed64ToPayload(uint8_t* payload, size_t payload_length, int index, int64_t value, uint64_t mask)
|
void signed64ToPayload(uint8_t* payload, size_t payload_length, int index, int64_t value, uint64_t mask)
|
||||||
{
|
{
|
||||||
|
@ -7,11 +7,11 @@ class InterfaceObject;
|
|||||||
template <class T> class FunctionProperty : public Property
|
template <class T> class FunctionProperty : public Property
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FunctionProperty(T* io, PropertyID id, uint8_t access,
|
FunctionProperty(T* io, PropertyID id,
|
||||||
void (*commandCallback)(T*, uint8_t*, uint8_t, uint8_t*, uint8_t&),
|
void (*commandCallback)(T*, uint8_t*, uint8_t, uint8_t*, uint8_t&),
|
||||||
void (*stateCallback)(T*, uint8_t*, uint8_t, uint8_t*, uint8_t&))
|
void (*stateCallback)(T*, uint8_t*, uint8_t, uint8_t*, uint8_t&))
|
||||||
: Property(id, false, PDT_FUNCTION, 1, access), _interfaceObject(io), _commandCallback(commandCallback), _stateCallback(stateCallback)
|
: Property(id, false, PDT_FUNCTION, 1, ReadLv0|WriteLv0), _interfaceObject(io), _commandCallback(commandCallback), _stateCallback(stateCallback)
|
||||||
/* max_elements is set to 1, see 3.3.7 Application Layer p.68 */
|
/* max_elements is set to 1, read and write level any value so we use Lv0, see 3.3.7 Application Layer p.68 */
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual uint8_t read(uint16_t start, uint8_t count, uint8_t* data) const override
|
virtual uint8_t read(uint16_t start, uint8_t count, uint8_t* data) const override
|
||||||
|
@ -10,54 +10,6 @@ InterfaceObject::~InterfaceObject()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void InterfaceObject::readPropertyDescription(uint8_t& propertyId, uint8_t& propertyIndex, bool& writeEnable, uint8_t& type, uint16_t& numberOfElements, uint8_t& access)
|
void InterfaceObject::readPropertyDescription(uint8_t& propertyId, uint8_t& propertyIndex, bool& writeEnable, uint8_t& type, uint16_t& numberOfElements, uint8_t& access)
|
||||||
{
|
|
||||||
PropertyDescription* descriptions = propertyDescriptions();
|
|
||||||
uint8_t count = propertyDescriptionCount();
|
|
||||||
|
|
||||||
numberOfElements = 0;
|
|
||||||
if (descriptions == nullptr || count == 0)
|
|
||||||
return readPropertyDescription2(propertyId, propertyIndex, writeEnable, type, numberOfElements, access);
|
|
||||||
|
|
||||||
PropertyDescription* desc = nullptr;
|
|
||||||
|
|
||||||
// from KNX spec. 03.03.07 Application Layer (page 56) - 3.4.3.3 A_PropertyDescription_Read-service
|
|
||||||
// Summary: either propertyId OR propertyIndex, but not both at the same time
|
|
||||||
if (propertyId != 0)
|
|
||||||
{
|
|
||||||
for (uint8_t i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
PropertyDescription d = descriptions[i];
|
|
||||||
if (d.Id != propertyId)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
desc = &d;
|
|
||||||
propertyIndex = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// If propertyId is zero, propertyIndex shall be used.
|
|
||||||
// Response: propertyIndex of received A_PropertyDescription_Read
|
|
||||||
if (propertyIndex < count)
|
|
||||||
{
|
|
||||||
desc = &descriptions[propertyIndex];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (desc != nullptr)
|
|
||||||
{
|
|
||||||
propertyId = desc->Id;
|
|
||||||
writeEnable = desc->WriteEnable;
|
|
||||||
type = desc->Type;
|
|
||||||
numberOfElements = desc->MaxElements;
|
|
||||||
access = desc->Access;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return readPropertyDescription2(propertyId, propertyIndex, writeEnable, type, numberOfElements, access);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InterfaceObject::readPropertyDescription2(uint8_t& propertyId, uint8_t& propertyIndex, bool& writeEnable, uint8_t& type, uint16_t& numberOfElements, uint8_t& access)
|
|
||||||
{
|
{
|
||||||
uint8_t count = _propertyCount;
|
uint8_t count = _propertyCount;
|
||||||
|
|
||||||
@ -161,17 +113,6 @@ void InterfaceObject::state(PropertyID id, uint8_t* data, uint8_t length, uint8_
|
|||||||
prop->state(data, length, resultData, resultLength);
|
prop->state(data, length, resultData, resultLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t InterfaceObject::propertyDescriptionCount()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
PropertyDescription* InterfaceObject::propertyDescriptions()
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void InterfaceObject::initializeProperties(size_t propertiesSize, Property** properties)
|
void InterfaceObject::initializeProperties(size_t propertiesSize, Property** properties)
|
||||||
{
|
{
|
||||||
_propertyCount = propertiesSize / sizeof(Property*);
|
_propertyCount = propertiesSize / sizeof(Property*);
|
||||||
|
@ -147,9 +147,7 @@ class InterfaceObject : public SaveRestore
|
|||||||
*
|
*
|
||||||
* @param[out] access the ::AccessLevel necessary to read/write the property.
|
* @param[out] access the ::AccessLevel necessary to read/write the property.
|
||||||
*/
|
*/
|
||||||
// TODO: remove first version after complete property refactoring
|
|
||||||
void readPropertyDescription(uint8_t& propertyId, uint8_t& propertyIndex, bool& writeEnable, uint8_t& type, uint16_t& numberOfElements, uint8_t& access);
|
void readPropertyDescription(uint8_t& propertyId, uint8_t& propertyIndex, bool& writeEnable, uint8_t& type, uint16_t& numberOfElements, uint8_t& access);
|
||||||
void readPropertyDescription2(uint8_t& propertyId, uint8_t& propertyIndex, bool& writeEnable, uint8_t& type, uint16_t& numberOfElements, uint8_t& access);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets property with PropertyID id if it exists and nullptr otherwise.
|
* Gets property with PropertyID id if it exists and nullptr otherwise.
|
||||||
@ -184,15 +182,6 @@ class InterfaceObject : public SaveRestore
|
|||||||
virtual uint16_t saveSize() override;
|
virtual uint16_t saveSize() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
|
||||||
* Returns the number of properties the interface object has.
|
|
||||||
*/
|
|
||||||
virtual uint8_t propertyDescriptionCount();
|
|
||||||
/**
|
|
||||||
* Returns a pointer to the first PropertyDescription of the interface object.
|
|
||||||
* This is used by readPropertyDescription() together with propertyCount().
|
|
||||||
*/
|
|
||||||
virtual PropertyDescription* propertyDescriptions();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Intializes the Property-array the the supplied values.
|
* Intializes the Property-array the the supplied values.
|
||||||
|
@ -1,141 +1,60 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include "rf_medium_object.h"
|
#include "rf_medium_object.h"
|
||||||
#include "bits.h"
|
#include "bits.h"
|
||||||
|
#include "data_property.h"
|
||||||
|
#include "function_property.h"
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#ifdef USE_RF
|
#ifdef USE_RF
|
||||||
|
|
||||||
void RfMediumObject::readProperty(PropertyID propertyId, uint16_t start, uint8_t& count, uint8_t* data)
|
RfMediumObject::RfMediumObject()
|
||||||
{
|
{
|
||||||
switch (propertyId)
|
uint8_t rfDomainAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // see KNX RF S-Mode AN160 p.11
|
||||||
|
Property* properties[] =
|
||||||
{
|
{
|
||||||
case PID_OBJECT_TYPE:
|
new DataProperty(PID_OBJECT_TYPE, false, PDT_UNSIGNED_INT, 1, ReadLv3 | WriteLv0, (uint16_t)OT_RF_MEDIUM),
|
||||||
pushWord(OT_RF_MEDIUM, data);
|
new DataProperty(PID_RF_MULTI_TYPE, true, PDT_GENERIC_01, 1, ReadLv3 | WriteLv2, (uint8_t)0x00),
|
||||||
break;
|
new DataProperty(PID_RF_RETRANSMITTER, false, PDT_GENERIC_01, 1, ReadLv3 | WriteLv0, (uint8_t)0x00),
|
||||||
case PID_RF_MULTI_TYPE:
|
new DataProperty(PID_RF_DOMAIN_ADDRESS, true, PDT_GENERIC_06, 1, ReadLv3 | WriteLv2, rfDomainAddress),
|
||||||
data[0] = 0x00; // KNX RF ready only
|
new FunctionProperty<RfMediumObject>(this, PID_RF_BIDIR_TIMEOUT,
|
||||||
break;
|
[](RfMediumObject* io, uint8_t* data, uint8_t length, uint8_t* resultData, uint8_t& resultLength)
|
||||||
case PID_RF_DOMAIN_ADDRESS:
|
|
||||||
pushByteArray((uint8_t*)_rfDomainAddress, 6, data);
|
|
||||||
break;
|
|
||||||
case PID_RF_RETRANSMITTER:
|
|
||||||
data[0] = 0x00; // No KNX RF retransmitter
|
|
||||||
break;
|
|
||||||
case PID_RF_BIDIR_TIMEOUT: // PDT_FUNCTION
|
|
||||||
data[0] = 0x00; // success
|
|
||||||
data[1] = 0xFF; // permanent bidirectional device
|
|
||||||
data[2] = 0xFF; // permanent bidirectional device
|
|
||||||
break;
|
|
||||||
case PID_RF_DIAG_SA_FILTER_TABLE: // PDT_GENERIC_03[]
|
|
||||||
pushByteArray((uint8_t*)_rfDiagSourceAddressFilterTable, 24, data);
|
|
||||||
break;
|
|
||||||
case PID_RF_DIAG_BUDGET_TABLE:
|
|
||||||
pushByteArray((uint8_t*)_rfDiagLinkBudgetTable, 24, data);
|
|
||||||
break;
|
|
||||||
case PID_RF_DIAG_PROBE: // PDT_FUNCTION
|
|
||||||
// Not supported yet
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
count = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RfMediumObject::writeProperty(PropertyID id, uint16_t start, uint8_t* data, uint8_t& count)
|
|
||||||
{
|
|
||||||
switch (id)
|
|
||||||
{
|
{
|
||||||
case PID_RF_MULTI_TYPE:
|
resultData[0] = 0x00; // success
|
||||||
// We only support RF ready and not RF multi, ignore write request
|
resultData[1] = 0xFF; // permanent bidirectional device
|
||||||
break;
|
resultData[2] = 0xFF; // permanent bidirectional device
|
||||||
case PID_RF_DOMAIN_ADDRESS:
|
resultLength = 3;
|
||||||
for (uint8_t i = start; i < start + count; i++)
|
},
|
||||||
_rfDomainAddress[i-1] = data[i - start];
|
[](RfMediumObject* io, uint8_t* data, uint8_t length, uint8_t* resultData, uint8_t& resultLength)
|
||||||
break;
|
|
||||||
case PID_RF_BIDIR_TIMEOUT: // PDT_FUNCTION
|
|
||||||
// Not supported yet (permanent bidir device)
|
|
||||||
break;
|
|
||||||
case PID_RF_DIAG_SA_FILTER_TABLE:
|
|
||||||
for (uint8_t i = start; i < start + count; i++)
|
|
||||||
_rfDiagSourceAddressFilterTable[i-1] = data[i - start];
|
|
||||||
break;
|
|
||||||
case PID_RF_DIAG_BUDGET_TABLE:
|
|
||||||
for (uint8_t i = start; i < start + count; i++)
|
|
||||||
_rfDiagLinkBudgetTable[i-1] = data[i - start];
|
|
||||||
break;
|
|
||||||
case PID_RF_DIAG_PROBE:
|
|
||||||
// Not supported yet
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
count = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t RfMediumObject::propertySize(PropertyID id)
|
|
||||||
{
|
|
||||||
switch (id)
|
|
||||||
{
|
{
|
||||||
case PID_RF_MULTI_TYPE:
|
resultData[0] = 0x00; // success
|
||||||
case PID_RF_RETRANSMITTER:
|
resultData[1] = 0xFF; // permanent bidirectional device
|
||||||
return 1;
|
resultData[2] = 0xFF; // permanent bidirectional device
|
||||||
case PID_OBJECT_TYPE:
|
resultLength = 3;
|
||||||
return 2;
|
}),
|
||||||
case PID_RF_DOMAIN_ADDRESS:
|
/* This properties are used in NMP_LinkBudget_Measure to diagnose the Link Budget of the communication.
|
||||||
return 6;
|
This in not implemented yet.
|
||||||
case PID_RF_DIAG_SA_FILTER_TABLE:
|
new DataProperty(PID_RF_DIAG_SA_FILTER_TABLE, true, PDT_GENERIC_03, 8, ReadLv3 | WriteLv3),
|
||||||
case PID_RF_DIAG_BUDGET_TABLE:
|
new DataProperty(PID_RF_DIAG_BUDGET_TABLE, false, PDT_GENERIC_03, 8, ReadLv3 | WriteLv0),
|
||||||
return 24;
|
new FunctionProperty<RfMediumObject>(this, PID_RF_DIAG_PROBE,
|
||||||
// case PID_RF_BIDIR_TIMEOUT: ?
|
[](RfMediumObject* io, uint8_t* data, uint8_t length, uint8_t* resultData, uint8_t& resultLength)
|
||||||
// case PID_RF_DIAG_PROBE: ?
|
{
|
||||||
default:
|
},
|
||||||
break;
|
[](RfMediumObject* io, uint8_t* data, uint8_t length, uint8_t* resultData, uint8_t& resultLength)
|
||||||
}
|
{
|
||||||
return 0;
|
}), */
|
||||||
|
};
|
||||||
|
initializeProperties(sizeof(properties), properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* RfMediumObject::save(uint8_t* buffer)
|
const uint8_t* RfMediumObject::rfDomainAddress()
|
||||||
{
|
{
|
||||||
buffer = pushByteArray((uint8_t*)_rfDomainAddress, 6, buffer);
|
DataProperty* prop = (DataProperty*)property(PID_RF_DOMAIN_ADDRESS);
|
||||||
return buffer;
|
return prop->data();
|
||||||
}
|
|
||||||
|
|
||||||
const uint8_t* RfMediumObject::restore(const uint8_t* buffer)
|
|
||||||
{
|
|
||||||
buffer = popByteArray((uint8_t*)_rfDomainAddress, 6, buffer);
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t RfMediumObject::saveSize()
|
|
||||||
{
|
|
||||||
return 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t* RfMediumObject::rfDomainAddress()
|
|
||||||
{
|
|
||||||
return _rfDomainAddress;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RfMediumObject::rfDomainAddress(const uint8_t* value)
|
void RfMediumObject::rfDomainAddress(const uint8_t* value)
|
||||||
{
|
{
|
||||||
pushByteArray(value, 6, _rfDomainAddress);
|
Property* prop = property(PID_RF_DOMAIN_ADDRESS);
|
||||||
}
|
prop->write(value);
|
||||||
|
|
||||||
static PropertyDescription _propertyDescriptions[] =
|
|
||||||
{
|
|
||||||
{ PID_OBJECT_TYPE, false, PDT_UNSIGNED_INT, 1, ReadLv3 | WriteLv0 },
|
|
||||||
{ PID_RF_MULTI_TYPE, false, PDT_GENERIC_01, 1, ReadLv3 | WriteLv0 },
|
|
||||||
{ PID_RF_RETRANSMITTER, false, PDT_GENERIC_01, 1, ReadLv3 | WriteLv0 },
|
|
||||||
{ PID_RF_DOMAIN_ADDRESS, true, PDT_GENERIC_06, 1, ReadLv3 | WriteLv0 }
|
|
||||||
};
|
|
||||||
static uint8_t _propertyDescriptionCount = sizeof(_propertyDescriptions) / sizeof(PropertyDescription);
|
|
||||||
|
|
||||||
uint8_t RfMediumObject::propertyDescriptionCount()
|
|
||||||
{
|
|
||||||
return _propertyDescriptionCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
PropertyDescription* RfMediumObject::propertyDescriptions()
|
|
||||||
{
|
|
||||||
return _propertyDescriptions;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
@ -7,21 +7,11 @@
|
|||||||
class RfMediumObject: public InterfaceObject
|
class RfMediumObject: public InterfaceObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void readProperty(PropertyID id, uint16_t start, uint8_t& count, uint8_t* data) override;
|
RfMediumObject();
|
||||||
void writeProperty(PropertyID id, uint16_t start, uint8_t* data, uint8_t& count) override;
|
const uint8_t* rfDomainAddress();
|
||||||
uint8_t propertySize(PropertyID id) override;
|
|
||||||
uint8_t* save(uint8_t* buffer) override;
|
|
||||||
const uint8_t* restore(const uint8_t* buffer) override;
|
|
||||||
uint16_t saveSize() override;
|
|
||||||
|
|
||||||
uint8_t* rfDomainAddress();
|
|
||||||
void rfDomainAddress(const uint8_t* value);
|
void rfDomainAddress(const uint8_t* value);
|
||||||
|
|
||||||
protected:
|
|
||||||
uint8_t propertyDescriptionCount() override;
|
|
||||||
PropertyDescription* propertyDescriptions() override;
|
|
||||||
private:
|
private:
|
||||||
uint8_t _rfDomainAddress[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // see KNX RF S-Mode AN160 p.11
|
|
||||||
uint8_t _rfDiagSourceAddressFilterTable[24] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,};
|
uint8_t _rfDiagSourceAddressFilterTable[24] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,};
|
||||||
uint8_t _rfDiagLinkBudgetTable[24] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,};
|
uint8_t _rfDiagLinkBudgetTable[24] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,};
|
||||||
};
|
};
|
||||||
|
@ -59,7 +59,7 @@ extern void delayMicroseconds (unsigned int howLong);
|
|||||||
#define PKTLEN 0x06 // Packet length
|
#define PKTLEN 0x06 // Packet length
|
||||||
#define PKTCTRL1 0x07 // Packet automation control
|
#define PKTCTRL1 0x07 // Packet automation control
|
||||||
#define PKTCTRL0 0x08 // Packet automation control
|
#define PKTCTRL0 0x08 // Packet automation control
|
||||||
#define DADDR 0x09 // Device address
|
#define DEVADDR 0x09 // Device address
|
||||||
#define CHANNR 0x0A // Channel number
|
#define CHANNR 0x0A // Channel number
|
||||||
#define FSCTRL1 0x0B // Frequency synthesizer control
|
#define FSCTRL1 0x0B // Frequency synthesizer control
|
||||||
#define FSCTRL0 0x0C // Frequency synthesizer control
|
#define FSCTRL0 0x0C // Frequency synthesizer control
|
||||||
|
@ -92,6 +92,16 @@ void TpUartDataLinkLayer::loop()
|
|||||||
uint8_t* buffer = _receiveBuffer + 2;
|
uint8_t* buffer = _receiveBuffer + 2;
|
||||||
uint8_t rxByte;
|
uint8_t rxByte;
|
||||||
|
|
||||||
|
if (!_enabled)
|
||||||
|
{
|
||||||
|
if (millis() - _lastResetChipTime > 1000)
|
||||||
|
{
|
||||||
|
//reset chip every 1 seconds
|
||||||
|
_lastResetChipTime = millis();
|
||||||
|
_enabled = resetChip();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!_enabled)
|
if (!_enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -429,12 +439,14 @@ void TpUartDataLinkLayer::enabled(bool value)
|
|||||||
{
|
{
|
||||||
_platform.setupUart();
|
_platform.setupUart();
|
||||||
|
|
||||||
if (resetChip()){
|
if (resetChip())
|
||||||
|
{
|
||||||
_enabled = true;
|
_enabled = true;
|
||||||
print("ownaddr ");
|
print("ownaddr ");
|
||||||
println(_deviceObject.induvidualAddress(), HEX);
|
println(_deviceObject.induvidualAddress(), HEX);
|
||||||
}
|
}
|
||||||
else{
|
else
|
||||||
|
{
|
||||||
_enabled = false;
|
_enabled = false;
|
||||||
println("ERROR, TPUART not responding");
|
println("ERROR, TPUART not responding");
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ class TpUartDataLinkLayer : public DataLinkLayer
|
|||||||
uint8_t _xorSum = 0;
|
uint8_t _xorSum = 0;
|
||||||
uint32_t _lastByteRxTime;
|
uint32_t _lastByteRxTime;
|
||||||
uint32_t _waitConfirmStartTime;
|
uint32_t _waitConfirmStartTime;
|
||||||
|
uint32_t _lastResetChipTime = 0;
|
||||||
|
|
||||||
struct _tx_queue_frame_t
|
struct _tx_queue_frame_t
|
||||||
{
|
{
|
||||||
|
@ -15,24 +15,37 @@
|
|||||||
#else
|
#else
|
||||||
#error "No medium type specified for platform Arduino_SAMD! Please set MEDIUM_TYPE! (TP:0, RF:2, IP:5)"
|
#error "No medium type specified for platform Arduino_SAMD! Please set MEDIUM_TYPE! (TP:0, RF:2, IP:5)"
|
||||||
#endif
|
#endif
|
||||||
#define ICACHE_RAM_ATTR
|
|
||||||
#elif ARDUINO_ARCH_ESP8266
|
#elif ARDUINO_ARCH_ESP8266
|
||||||
// predefined global instance for IP only
|
// predefined global instance for IP only
|
||||||
KnxFacade<EspPlatform, Bau57B0> knx;
|
KnxFacade<EspPlatform, Bau57B0> knx;
|
||||||
#elif ARDUINO_ARCH_ESP32
|
#elif ARDUINO_ARCH_ESP32
|
||||||
// predefined global instance for IP only
|
// predefined global instance for TP or IP
|
||||||
|
#ifdef MEDIUM_TYPE
|
||||||
|
#if MEDIUM_TYPE == 0
|
||||||
|
KnxFacade<Esp32Platform, Bau07B0> knx;
|
||||||
|
#elif MEDIUM_TYPE == 5
|
||||||
KnxFacade<Esp32Platform, Bau57B0> knx;
|
KnxFacade<Esp32Platform, Bau57B0> knx;
|
||||||
|
#else
|
||||||
|
#error "Only TP and IP supported for Arduino ESP32 platform!"
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
// Compatibility
|
||||||
|
KnxFacade<Esp32Platform, Bau57B0> knx;
|
||||||
|
//#error "No medium type specified for platform Arduino ESP32! Please set MEDIUM_TYPE! (TP:0, RF:2, IP:5)"
|
||||||
|
#endif
|
||||||
|
#elif ARDUINO_ARCH_STM32
|
||||||
|
KnxFacade<Stm32Platform, Bau07B0> knx;
|
||||||
#elif __linux__
|
#elif __linux__
|
||||||
// no predefined global instance
|
// no predefined global instance
|
||||||
#define ICACHE_RAM_ATTR
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef __linux__
|
#ifndef ICACHE_RAM_ATTR
|
||||||
uint32_t lastpressed=0;
|
#define ICACHE_RAM_ATTR
|
||||||
#endif
|
#endif
|
||||||
ICACHE_RAM_ATTR void buttonUp()
|
ICACHE_RAM_ATTR void buttonUp()
|
||||||
{
|
{
|
||||||
#ifndef __linux__
|
#ifndef __linux__
|
||||||
|
static uint32_t lastpressed=0;
|
||||||
if (millis() - lastpressed > 200){
|
if (millis() - lastpressed > 200){
|
||||||
knx._toogleProgMode = true;
|
knx._toogleProgMode = true;
|
||||||
lastpressed = millis();
|
lastpressed = millis();
|
||||||
|
@ -17,7 +17,11 @@
|
|||||||
#elif ARDUINO_ARCH_ESP32
|
#elif ARDUINO_ARCH_ESP32
|
||||||
#define LED_BUILTIN 13
|
#define LED_BUILTIN 13
|
||||||
#include "esp32_platform.h"
|
#include "esp32_platform.h"
|
||||||
|
#include "knx/bau07B0.h"
|
||||||
#include "knx/bau57B0.h"
|
#include "knx/bau57B0.h"
|
||||||
|
#elif ARDUINO_ARCH_STM32
|
||||||
|
#include "stm32_platform.h"
|
||||||
|
#include "knx/bau07B0.h"
|
||||||
#else
|
#else
|
||||||
#define LED_BUILTIN 0
|
#define LED_BUILTIN 0
|
||||||
#include "linux_platform.h"
|
#include "linux_platform.h"
|
||||||
@ -331,8 +335,21 @@ template <class P, class B> class KnxFacade : private SaveRestore
|
|||||||
// predefined global instance for IP only
|
// predefined global instance for IP only
|
||||||
extern KnxFacade<EspPlatform, Bau57B0> knx;
|
extern KnxFacade<EspPlatform, Bau57B0> knx;
|
||||||
#elif ARDUINO_ARCH_ESP32
|
#elif ARDUINO_ARCH_ESP32
|
||||||
// predefined global instance for IP only
|
// predefined global instance for TP or IP
|
||||||
|
#ifdef MEDIUM_TYPE
|
||||||
|
#if MEDIUM_TYPE == 0
|
||||||
|
extern KnxFacade<Esp32Platform, Bau07B0> knx;
|
||||||
|
#elif MEDIUM_TYPE == 5
|
||||||
extern KnxFacade<Esp32Platform, Bau57B0> knx;
|
extern KnxFacade<Esp32Platform, Bau57B0> knx;
|
||||||
|
#else
|
||||||
|
#error "Only TP and IP supported for Arduino ESP32 platform!"
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#error "No medium type specified for Arduino ESP32 platform! Please set MEDIUM_TYPE! (TP:0, RF:2, IP:5)"
|
||||||
|
#endif
|
||||||
|
#elif ARDUINO_ARCH_STM32
|
||||||
|
// predefined global instance for TP only
|
||||||
|
extern KnxFacade<Stm32Platform, Bau07B0> knx;
|
||||||
#elif __linux__
|
#elif __linux__
|
||||||
// no predefined global instance
|
// no predefined global instance
|
||||||
#endif
|
#endif
|
42
src/stm32_platform.cpp
Normal file
42
src/stm32_platform.cpp
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#include "stm32_platform.h"
|
||||||
|
|
||||||
|
#ifdef ARDUINO_ARCH_STM32
|
||||||
|
#include <EEPROM.h>
|
||||||
|
#include "knx/bits.h"
|
||||||
|
|
||||||
|
Stm32Platform::Stm32Platform() : ArduinoPlatform(&Serial2), eepromPtr(nullptr), eepromSize(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Stm32Platform::Stm32Platform( HardwareSerial* s) : ArduinoPlatform(s), eepromPtr(nullptr), eepromSize(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Stm32Platform::~Stm32Platform()
|
||||||
|
{
|
||||||
|
delete [] eepromPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Stm32Platform::restart()
|
||||||
|
{
|
||||||
|
NVIC_SystemReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t * Stm32Platform::getEepromBuffer(uint16_t size)
|
||||||
|
{
|
||||||
|
delete [] eepromPtr;
|
||||||
|
eepromPtr = new uint8_t[size];
|
||||||
|
for (uint16_t i = 0; i < size; ++i)
|
||||||
|
eepromPtr[i] = EEPROM[i];
|
||||||
|
return eepromPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Stm32Platform::commitToEeprom()
|
||||||
|
{
|
||||||
|
if(eepromPtr == nullptr)
|
||||||
|
return;
|
||||||
|
for (uint16_t i = 0; i < eepromSize; ++i)
|
||||||
|
EEPROM.update(i, eepromPtr[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
22
src/stm32_platform.h
Normal file
22
src/stm32_platform.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#ifdef ARDUINO_ARCH_STM32
|
||||||
|
#include "arduino_platform.h"
|
||||||
|
|
||||||
|
class Stm32Platform : public ArduinoPlatform
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Stm32Platform();
|
||||||
|
Stm32Platform( HardwareSerial* s);
|
||||||
|
~Stm32Platform();
|
||||||
|
|
||||||
|
// basic stuff
|
||||||
|
void restart();
|
||||||
|
|
||||||
|
//memory
|
||||||
|
uint8_t* getEepromBuffer(uint16_t size);
|
||||||
|
void commitToEeprom();
|
||||||
|
private:
|
||||||
|
uint8_t *eepromPtr;
|
||||||
|
uint16_t eepromSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user