forked from franckmarini/KnxDevice
-
Notifications
You must be signed in to change notification settings - Fork 0
/
KnxDevice.h
210 lines (163 loc) · 8.35 KB
/
KnxDevice.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
// This file is part of Arduino Knx Bus Device library.
// The Arduino Knx Bus Device library allows to turn Arduino into "self-made" KNX bus device.
// Copyright (C) 2014 2015 2016 Franck MARINI ([email protected])
// The Arduino Knx Bus Device library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// File : KnxDevice.h
// Author : Franck Marini
// Description : KnxDevice Abstraction Layer
// Module dependencies : HardwareSerial, KnxTelegram, KnxComObject, KnxTpUart, ActionRingBuffer
#ifndef KNXDEVICE_H
#define KNXDEVICE_H
#include "Arduino.h"
#include "KnxTelegram.h"
#include "KnxComObject.h"
#include "ActionRingBuffer.h"
#include "KnxTpUart.h"
// !!!!!!!!!!!!!!! FLAG OPTIONS !!!!!!!!!!!!!!!!!
// DEBUG :
// #define KNXDEVICE_DEBUG_INFO // Uncomment to activate info traces
// Values returned by the KnxDevice member functions :
enum e_KnxDeviceStatus {
KNX_DEVICE_OK = 0,
KNX_DEVICE_NOT_IMPLEMENTED = 254,
KNX_DEVICE_ERROR = 255
};
// Macro functions for conversion of physical and 2/3 level group addresses
inline word P_ADDR(byte area, byte line, byte busdevice)
{ return (word) ( ((area&0xF)<<12) + ((line&0xF)<<8) + busdevice ); }
inline word G_ADDR(byte maingrp, byte midgrp, byte subgrp)
{ return (word) ( ((maingrp&0x1F)<<11) + ((midgrp&0x7)<<8) + subgrp ); }
inline word G_ADDR(byte maingrp, byte subgrp)
{ return (word) ( ((maingrp&0x1F)<<11) + subgrp ); }
#define ACTIONS_QUEUE_SIZE 16
// KnxDevice internal state
enum e_KnxDeviceState {
INIT,
IDLE,
TX_ONGOING,
};
// Action types
enum e_KnxDeviceTxActionType {
EIB_READ_REQUEST,
EIB_WRITE_REQUEST,
EIB_RESPONSE_REQUEST
};
struct struct_tx_action{
e_KnxDeviceTxActionType command; // Action type to be performed
byte index; // Index of the involved ComObject
union { // Value
// Field used in case of short value (value width <= 1 byte)
struct {
byte byteValue;
byte notUsed;
};
byte *valuePtr; // Field used in case of long value (width > 1 byte), space is allocated dynamically
};
};// type_tx_action;
typedef struct struct_tx_action type_tx_action;
// Callback function to catch and treat KNX events
// The definition shall be provided by the end-user
extern void knxEvents(byte);
// --------------- Definition of the functions for DPT translation --------------------
// Functions to convert a DPT format to a standard C type
// NB : only the usual DPT formats are supported (U16, V16, U32, V32, F16 and F32)
template <typename T> e_KnxDeviceStatus ConvertFromDpt(const byte dpt[], T& result, byte dptFormat);
// Functions to convert a standard C type to a DPT format
// NB : only the usual DPT formats are supported (U16, V16, U32, V32, F16 and F32)
template <typename T> e_KnxDeviceStatus ConvertToDpt(T value, byte dpt[], byte dptFormat);
class KnxDevice {
static KnxComObject _comObjectsList[]; // List of Com Objects attached to the KNX Device
// The definition shall be provided by the end-user
static const byte _comObjectsNb; // Nb of attached Com Objects
// The value shall be provided by the end-user
e_KnxDeviceState _state; // Current KnxDevice state
KnxTpUart *_tpuart; // TPUART associated to the KNX Device
ActionRingBuffer<type_tx_action, ACTIONS_QUEUE_SIZE> _txActionList; // Queue of transmit actions to be performed
boolean _initCompleted; // True when all the Com Object with Init attr have been initialized
byte _initIndex; // Index to the last initiated object
word _lastInitTimeMillis; // Time (in msec) of the last init (read) request on the bus
word _lastRXTimeMicros; // Time (in msec) of the last Tpuart Rx activity;
word _lastTXTimeMicros; // Time (in msec) of the last Tpuart Tx activity;
KnxTelegram _txTelegram; // Telegram object used for telegrams sending
KnxTelegram *_rxTelegram; // Reference to the telegram received by the TPUART
#if defined(KNXDEVICE_DEBUG_INFO)
byte _nbOfInits; // Nb of Initialized Com Objects
String *_debugStrPtr;
static const char _debugInfoText[];
#endif
// Constructor, Destructor
//qwq KnxDevice(); // private constructor (singleton design pattern)
//~KnxDevice() {} // private destructor (singleton design pattern)
//KnxDevice (const KnxDevice&); // private copy constructor (singleton design pattern)
public:
static KnxDevice Knx; // unique KnxDevice instance (singleton design pattern)
KnxDevice(); //qwq Constructor in class defined
// Start the KNX Device
// return KNX_DEVICE_ERROR (255) if begin() failed
// else return KNX_DEVICE_OK
e_KnxDeviceStatus begin(HardwareSerial& serial, word physicalAddr);
// Stop the KNX Device
void end();
// KNX device execution task
// This function shall be called in the "loop()" Arduino function
void task(void);
// Quick method to read a short (<=1 byte) com object
// NB : The returned value will be hazardous in case of use with long objects
byte read(byte objectIndex);
word read_dest(byte objectIndex);
// Read an usual format com object
// Supported DPT formats are short com object, U16, V16, U32, V32, F16 and F32
template <typename T> e_KnxDeviceStatus read(byte objectIndex, T& returnedValue);
// Read any type of com object (DPT value provided as is)
e_KnxDeviceStatus read(byte objectIndex, byte returnedValue[]);
// Update com object functions :
// For all the update functions, the com object value is updated locally
// and a telegram is sent on the EIB bus if the object has both COMMUNICATION & TRANSMIT attributes set
// Update an usual format com object
// Supported DPT types are short com object, U16, V16, U32, V32, F16 and F32
template <typename T> e_KnxDeviceStatus write(byte objectIndex, T value);
// Update any type of com object (rough DPT value shall be provided)
e_KnxDeviceStatus write(byte objectIndex, byte valuePtr[]);
// Com Object EIB Bus Update request
// Request the local object to be updated with the value from the bus
// NB : the function is asynchroneous, the update completion is notified by the knxEvents() callback
void update(byte objectIndex);
// The function returns true if there is rx/tx activity ongoing, else false
boolean isActive(void) const;
// Inline Debug function (definition later in this file)
// Set the string used for debug traces
#if defined(KNXDEVICE_DEBUG_INFO)
void SetDebugString(String *strPtr);
#endif
private:
// Static GetTpUartEvents() function called by the KnxTpUart layer (callback)
static void GetTpUartEvents(e_KnxTpUartEvent event);
// Static TxTelegramAck() function called by the KnxTpUart layer (callback)
static void TxTelegramAck(e_TpUartTxAck);
#if defined(KNXDEVICE_DEBUG_INFO)
// Inline Debug function (definition later in this file)
void DebugInfo(const char[]) const;
#endif
};
#if defined(KNXDEVICE_DEBUG_INFO)
// Set the string used for debug traces
inline void KnxDevice::SetDebugString(String *strPtr) {_debugStrPtr = strPtr;}
#endif
#if defined(KNXDEVICE_DEBUG_INFO)
inline void KnxDevice::DebugInfo(const char comment[]) const
{
if (_debugStrPtr != NULL) *_debugStrPtr += String(_debugInfoText) + String(comment);
}
#endif
// Reference to the KnxDevice unique instance
extern KnxDevice& Knx;
#endif // KNXDEVICE_H