knx
ETS configurable knx-stack
knx_facade.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "knx/bits.h"
4 #include "knx/config.h"
5 #include "knx/bau07B0.h"
6 #include "knx/bau091A.h"
7 #include "knx/bau27B0.h"
8 #include "knx/bau2920.h"
9 #include "knx/bau57B0.h"
10 
11 #ifndef USERDATA_SAVE_SIZE
12  #define USERDATA_SAVE_SIZE 0
13 #endif
14 
15 #ifdef ARDUINO_ARCH_SAMD
16  #include "samd_platform.h"
17  #ifndef KNX_NO_AUTOMATIC_GLOBAL_INSTANCE
18  void buttonUp();
19  #endif
20 #elif defined(ARDUINO_ARCH_RP2040)
21  #include "rp2040_arduino_platform.h"
22  #ifndef KNX_NO_AUTOMATIC_GLOBAL_INSTANCE
23  void buttonUp();
24  #endif
25 #elif defined(ARDUINO_ARCH_ESP8266)
26  #include "esp_platform.h"
27  #ifndef KNX_NO_AUTOMATIC_GLOBAL_INSTANCE
28  void buttonUp();
29  #endif
30 #elif defined(ARDUINO_ARCH_ESP32)
31  #include "esp32_platform.h"
32  #ifndef KNX_NO_AUTOMATIC_GLOBAL_INSTANCE
33  void buttonUp();
34  #endif
35 #elif defined(LIBRETINY)
36  #include "libretiny_platform.h"
37 #elif defined(ESP_PLATFORM)
38  #include "esp32_idf_platform.h"
39  #ifndef KNX_NO_AUTOMATIC_GLOBAL_INSTANCE
40  void buttonUp();
41  #endif
42 #elif defined(ARDUINO_ARCH_STM32)
43  #include "stm32_platform.h"
44  #ifndef KNX_NO_AUTOMATIC_GLOBAL_INSTANCE
45  void buttonUp();
46  #endif
47 #elif __linux__
48  #include "linux_platform.h"
49 #else
50  #include "cc1310_platform.h"
51  #ifndef KNX_NO_AUTOMATIC_GLOBAL_INSTANCE
52  extern void buttonUp();
53  #endif
54 #endif
55 
56 #ifndef KNX_LED
57  #define KNX_LED -1
58 #endif
59 #ifndef KNX_LED_ACTIVE_ON
60  #define KNX_LED_ACTIVE_ON 0
61 #endif
62 #ifndef KNX_BUTTON
63  #define KNX_BUTTON -1
64 #endif
65 
66 typedef const uint8_t* (*RestoreCallback)(const uint8_t* buffer);
67 typedef uint8_t* (*SaveCallback)(uint8_t* buffer);
68 typedef void (*IsrFunctionPtr)();
69 typedef void (*ProgLedOnCallback)();
70 typedef void (*ProgLedOffCallback)();
71 #ifdef KNX_ACTIVITYCALLBACK
72  typedef void (*ActivityCallback)(uint8_t info);
73 #endif
74 
75 template <class P, class B> class KnxFacade : private SaveRestore
76 {
77  public:
78  KnxFacade() : _platformPtr(new P()), _bauPtr(new B(*_platformPtr)), _bau(*_bauPtr)
79  {
80  manufacturerId(0xfa);
81  bauNumber(platform().uniqueSerialNumber());
82  _bau.addSaveRestore(this);
83  }
84 
85  KnxFacade(B& bau) : _bau(bau)
86  {
87  _platformPtr = static_cast<P*>(&bau.platform());
88  manufacturerId(0xfa);
89  bauNumber(platform().uniqueSerialNumber());
90  _bau.addSaveRestore(this);
91  }
92 
93  KnxFacade(IsrFunctionPtr buttonISRFunction) : _platformPtr(new P()), _bauPtr(new B(*_platformPtr)), _bau(*_bauPtr)
94  {
95  manufacturerId(0xfa);
96  bauNumber(platform().uniqueSerialNumber());
97  _bau.addSaveRestore(this);
98  setButtonISRFunction(buttonISRFunction);
99  }
100 
101  virtual ~KnxFacade()
102  {
103  if (_bauPtr)
104  delete _bauPtr;
105 
106  if (_platformPtr)
107  delete _platformPtr;
108  }
109 
110  P& platform()
111  {
112  return *_platformPtr;
113  }
114 
115  B& bau()
116  {
117  return _bau;
118  }
119 
120  bool enabled()
121  {
122  return _bau.enabled();
123  }
124 
125  void enabled(bool value)
126  {
127  _bau.enabled(value);
128  }
129 
130  bool progMode()
131  {
132  return _bau.deviceObject().progMode();
133  }
134 
135  void progMode(bool value)
136  {
137  _bau.deviceObject().progMode(value);
138  }
139 
144  {
145  _toggleProgMode = true;
146  }
147 
148  bool configured()
149  {
150  return _bau.configured();
151  }
152 
156  uint32_t ledPinActiveOn()
157  {
158  return _ledPinActiveOn;
159  }
160 
166  void ledPinActiveOn(uint32_t value)
167  {
168  _ledPinActiveOn = value;
169  }
170 
171  int32_t ledPin()
172  {
173  return _ledPin;
174  }
175 
176  void ledPin(int32_t value)
177  {
178  _ledPin = value;
179  }
180 
181  void setProgLedOffCallback(ProgLedOffCallback progLedOffCallback)
182  {
183  _progLedOffCallback = progLedOffCallback;
184  }
185 
186  void setProgLedOnCallback(ProgLedOnCallback progLedOnCallback)
187  {
188  _progLedOnCallback = progLedOnCallback;
189  }
190 
191  int32_t buttonPin()
192  {
193  return _buttonPin;
194  }
195 
196  void buttonPin(int32_t value)
197  {
198  _buttonPin = value;
199  }
200 
201  void readMemory()
202  {
203  _bau.readMemory();
204  }
205 
206  void writeMemory()
207  {
208  _bau.writeMemory();
209  }
210 
211  uint16_t individualAddress()
212  {
213  return _bau.deviceObject().individualAddress();
214  }
215 
216  void loop()
217  {
218  if (progMode() != _progLedState)
219  {
220  _progLedState = progMode();
221 
222  if (_progLedState)
223  {
224  println("progmode on");
225  progLedOn();
226  }
227  else
228  {
229  println("progmode off");
230  progLedOff();
231  }
232  }
233 
234  if (_toggleProgMode)
235  {
236  progMode(!progMode());
237  _toggleProgMode = false;
238  }
239 
240  _bau.loop();
241  }
242 
243  void manufacturerId(uint16_t value)
244  {
245  _bau.deviceObject().manufacturerId(value);
246  }
247 
248  void bauNumber(uint32_t value)
249  {
250  _bau.deviceObject().bauNumber(value);
251  }
252 
253  void orderNumber(const uint8_t* value)
254  {
255  _bau.deviceObject().orderNumber(value);
256  }
257 
258  void hardwareType(const uint8_t* value)
259  {
260  _bau.deviceObject().hardwareType(value);
261  }
262 
263  void version(uint16_t value)
264  {
265  _bau.deviceObject().version(value);
266  }
267 
268  void start()
269  {
270  if (_ledPin >= 0)
271  {
272 #if defined(ESP_PLATFORM)
273  gpio_reset_pin((gpio_num_t)ledPin());
274  gpio_set_direction((gpio_num_t)ledPin(), GPIO_MODE_OUTPUT);
275 #else
276  pinMode(_ledPin, OUTPUT);
277 #endif // ESP_PLATFORM
278  }
279 
280  progLedOff();
281 
282  if(_buttonPin >= 0)
283  {
284 #if defined(ESP_PLATFORM)
285  if (_progButtonISRFuncPtr)
286  {
287  attachInterrupt(_buttonPin, _progButtonISRFuncPtr, CHANGE);
288  }
289 #else
290  pinMode(_buttonPin, INPUT_PULLUP);
291 
292  if (_progButtonISRFuncPtr)
293  {
294  // Workaround for https://github.com/arduino/ArduinoCore-samd/issues/587
295 #if (ARDUINO_API_VERSION >= 10200)
296  attachInterrupt(_buttonPin, _progButtonISRFuncPtr, (PinStatus)CHANGE);
297 #else
298  attachInterrupt(_buttonPin, _progButtonISRFuncPtr, CHANGE);
299 #endif // ARDUINO_API_VERSION
300  }
301 #endif // ESP_PLATFORM
302  }
303 
304  enabled(true);
305  }
306 
307  void setButtonISRFunction(IsrFunctionPtr progButtonISRFuncPtr)
308  {
309  _progButtonISRFuncPtr = progButtonISRFuncPtr;
310  }
311 
313  {
314  _saveCallback = func;
315  }
316 
318  {
319  _restoreCallback = func;
320  }
321 
322  uint8_t* paramData(uint32_t addr)
323  {
324  if (!_bau.configured())
325  return nullptr;
326 
327  return _bau.parameters().data(addr);
328  }
329 
330  // paramBit(address, shift)
331  // get state of a parameter as a boolean like "enable/disable", ...
332  // Declaration in XML file:
333  // ...
334  // <ParameterType Id="M-00FA_A-0066-EA-0001_PT-toggle" Name="toggle">
335  // <TypeRestriction Base="Value" SizeInBit="1">
336  // <Enumeration Text="Désactivé" Value="0" Id="M-00FA_A-0066-EA-0001_PT-toggle_EN-0"/>
337  // <Enumeration Text="Activé" Value="1" Id="M-00FA_A-0066-EA-0001_PT-toggle_EN-1"/>
338  // </TypeRestriction>
339  // </ParameterType>
340  // ...
341  // <Parameter Id="M-00FA_A-0066-EA-0001_P-2" Name="Input 1" ParameterType="M-00FA_A-0066-EA-0001_PT-toggle" Text="Input 1" Value="1">
342  // <Memory CodeSegment="M-00FA_A-0066-EA-0001_RS-04-00000" Offset="1" BitOffset="0"/>
343  // </Parameter>
344  // <Parameter Id="M-00FA_A-0066-EA-0001_P-3" Name="Input 2" ParameterType="M-00FA_A-0066-EA-0001_PT-toggle" Text="Input 2" Value="1">
345  // <Memory CodeSegment="M-00FA_A-0066-EA-0001_RS-04-00000" Offset="1" BitOffset="1"/>
346  // </Parameter>
347  // <Parameter Id="M-00FA_A-0066-EA-0001_P-4" Name="Inout 3" ParameterType="M-00FA_A-0066-EA-0001_PT-toggle" Text="Input 3" Value="1">
348  // <Memory CodeSegment="M-00FA_A-0066-EA-0001_RS-04-00000" Offset="1" BitOffset="2"/>
349  // </Parameter>
350  // ...
351  // Usage in code :
352  // if ( knx.paramBit(1,1))
353  // {
354  // //do somthings ....
355  // }
356  bool paramBit(uint32_t addr, uint8_t shift)
357  {
358  if (!_bau.configured())
359  return 0;
360 
361  return (bool) ((_bau.parameters().getByte(addr) >> (7 - shift)) & 0x01);
362  }
363 
364  uint8_t paramByte(uint32_t addr)
365  {
366  if (!_bau.configured())
367  return 0;
368 
369  return _bau.parameters().getByte(addr);
370  }
371 
372  // Same usage than paramByte(addresse) for signed parameters
373  // Declaration in XML file
374  // <ParameterType Id="M-00FA_A-0066-EA-0001_PT-delta" Name="delta">
375  // <TypeNumber SizeInBit="8" Type="signedInt" minInclusive="-10" maxInclusive="10"/>
376  // </ParameterType>
377  int8_t paramSignedByte(uint32_t addr)
378  {
379  if (!_bau.configured())
380  return 0;
381 
382  return (int8_t) _bau.parameters().getByte(addr);
383  }
384 
385  uint16_t paramWord(uint32_t addr)
386  {
387  if (!_bau.configured())
388  return 0;
389 
390  return _bau.parameters().getWord(addr);
391  }
392 
393  uint32_t paramInt(uint32_t addr)
394  {
395  if (!_bau.configured())
396  return 0;
397 
398  return _bau.parameters().getInt(addr);
399  }
400 
401  double paramFloat(uint32_t addr, ParameterFloatEncodings enc)
402  {
403  if (!_bau.configured())
404  return 0;
405 
406  return _bau.parameters().getFloat(addr, enc);
407  }
408 
409 #if (MASK_VERSION == 0x07B0) || (MASK_VERSION == 0x27B0) || (MASK_VERSION == 0x57B0)
410  GroupObject& getGroupObject(uint16_t goNr)
411  {
412  return _bau.groupObjectTable().get(goNr);
413  }
414 #endif
415 
416  void restart(uint16_t individualAddress)
417  {
418  SecurityControl sc = {false, None};
419  _bau.restartRequest(individualAddress, sc);
420  }
421 
423  {
424  _bau.beforeRestartCallback(func);
425  }
426 
428  {
429  return _bau.beforeRestartCallback();
430  }
431 
432  private:
433  P* _platformPtr = 0;
434  B* _bauPtr = 0;
435  B& _bau;
436  ProgLedOnCallback _progLedOnCallback = 0;
437  ProgLedOffCallback _progLedOffCallback = 0;
438 #ifdef KNX_ACTIVITYCALLBACK
439  ActivityCallback _activityCallback = 0;
440 #endif
441  uint32_t _ledPinActiveOn = KNX_LED_ACTIVE_ON;
442  int32_t _ledPin = KNX_LED;
443  int32_t _buttonPin = KNX_BUTTON;
444  SaveCallback _saveCallback = 0;
445  RestoreCallback _restoreCallback = 0;
446  volatile bool _toggleProgMode = false;
447  bool _progLedState = false;
448  uint16_t _saveSize = USERDATA_SAVE_SIZE;
449  IsrFunctionPtr _progButtonISRFuncPtr = 0;
450 
451  uint8_t* save(uint8_t* buffer)
452  {
453  if (_saveCallback != 0)
454  return _saveCallback(buffer);
455 
456  return buffer;
457  }
458 
459  const uint8_t* restore(const uint8_t* buffer)
460  {
461  if (_restoreCallback != 0)
462  return _restoreCallback(buffer);
463 
464  return buffer;
465  }
466 
467  uint16_t saveSize()
468  {
469  return _saveSize;
470  }
471 
472  void saveSize(uint16_t size)
473  {
474  _saveSize = size;
475  }
476 
477  void progLedOn()
478  {
479  if (_ledPin >= 0)
480  {
481 #if defined(ESP_PLATFORM)
482  gpio_set_level((gpio_num_t)ledPin(), _ledPinActiveOn);
483 #else
484  digitalWrite(_ledPin, _ledPinActiveOn);
485 #endif // ESP_PLATFORM
486  }
487 
488  if (_progLedOffCallback != 0)
489  _progLedOnCallback();
490  }
491 
492  void progLedOff()
493  {
494  if (_ledPin >= 0)
495  {
496 #if defined(ESP_PLATFORM)
497  gpio_set_level((gpio_num_t)ledPin(), 1 - _ledPinActiveOn);
498 #else
499  digitalWrite(_ledPin, HIGH - _ledPinActiveOn);
500 #endif // ESP_PLATFORM
501  }
502 
503  if (_progLedOffCallback != 0)
504  _progLedOffCallback();
505  }
506 };
507 
508 #ifndef KNX_NO_AUTOMATIC_GLOBAL_INSTANCE
509  #ifdef ARDUINO_ARCH_SAMD
510  // predefined global instance for TP or RF or TP/RF coupler
511  #if MASK_VERSION == 0x07B0
513  #elif MASK_VERSION == 0x27B0
515  #elif MASK_VERSION == 0x2920
517  #else
518  #error "Mask version not supported on ARDUINO_ARCH_SAMD"
519  #endif
520  #elif defined(ARDUINO_ARCH_RP2040)
521  // predefined global instance for TP or RF or TP/RF or TP/IP coupler
522  #if MASK_VERSION == 0x07B0
524  #elif MASK_VERSION == 0x27B0
526  #elif MASK_VERSION == 0x57B0
528  #elif MASK_VERSION == 0x2920
530  #elif MASK_VERSION == 0x091A
532  #else
533  #error "Mask version not supported on ARDUINO_ARCH_RP2040"
534  #endif
535  #elif defined(ARDUINO_ARCH_ESP8266)
536  // predefined global instance for TP or IP or TP/IP coupler
537  #if MASK_VERSION == 0x07B0
539  #elif MASK_VERSION == 0x57B0
541  #elif MASK_VERSION == 0x091A
543  #else
544  #error "Mask version not supported on ARDUINO_ARCH_ESP8266"
545  #endif
546  #elif defined(ARDUINO_ARCH_ESP32)
547  // predefined global instance for TP or IP or TP/IP coupler
548  #if MASK_VERSION == 0x07B0
550  #elif MASK_VERSION == 0x57B0
552  #elif MASK_VERSION == 0x091A
554  #else
555  #error "Mask version not supported on ARDUINO_ARCH_ESP32"
556  #endif
557  #elif defined(LIBRETINY)
558  // predefined global instance for TP or IP or TP/IP coupler
559  #if MASK_VERSION == 0x07B0
561  #elif MASK_VERSION == 0x57B0
563  #elif MASK_VERSION == 0x091A
565  #else
566  #error "Mask version not supported on LIBRETINY"
567  #endif
568  #elif defined(ESP_PLATFORM)
569  // predefined global instance for TP or IP or TP/IP coupler
570  #if MASK_VERSION == 0x07B0
572  #elif MASK_VERSION == 0x57B0
574  #elif MASK_VERSION == 0x091A
576  #else
577  #error "Mask version not supported on ESP_PLATFORM"
578  #endif
579  #elif defined(ARDUINO_ARCH_STM32)
580  // predefined global instance for TP only
581  #if MASK_VERSION == 0x07B0
583  #else
584  #error "Mask version not supported on ARDUINO_ARCH_STM32"
585  #endif
586  #else // Non-Arduino platforms and Linux platform
587  // no predefined global instance
588  #endif
589 #endif // KNX_NO_AUTOMATIC_GLOBAL_INSTANCE
void println(const char *s)
void(* BeforeRestartCallback)(void)
Definition: bau.h:6
ParameterFloatEncodings
Definition: bits.h:149
void pinMode(unsigned long pin, unsigned long mode)
void attachInterrupt(uint32_t pin, IsrFuncPtr callback, uint32_t mode)
void digitalWrite(unsigned long pin, unsigned long value)
This class represents a single group object.
Definition: group_object.h:42
void setProgLedOnCallback(ProgLedOnCallback progLedOnCallback)
Definition: knx_facade.h:186
GroupObject & getGroupObject(uint16_t goNr)
Definition: knx_facade.h:410
bool configured()
Definition: knx_facade.h:148
void manufacturerId(uint16_t value)
Definition: knx_facade.h:243
uint32_t ledPinActiveOn()
returns HIGH if led is active on HIGH, LOW otherwise
Definition: knx_facade.h:156
void start()
Definition: knx_facade.h:268
bool paramBit(uint32_t addr, uint8_t shift)
Definition: knx_facade.h:356
bool progMode()
Definition: knx_facade.h:130
void setProgLedOffCallback(ProgLedOffCallback progLedOffCallback)
Definition: knx_facade.h:181
int32_t buttonPin()
Definition: knx_facade.h:191
uint16_t paramWord(uint32_t addr)
Definition: knx_facade.h:385
double paramFloat(uint32_t addr, ParameterFloatEncodings enc)
Definition: knx_facade.h:401
KnxFacade(IsrFunctionPtr buttonISRFunction)
Definition: knx_facade.h:93
void ledPin(int32_t value)
Definition: knx_facade.h:176
virtual ~KnxFacade()
Definition: knx_facade.h:101
KnxFacade(B &bau)
Definition: knx_facade.h:85
void restart(uint16_t individualAddress)
Definition: knx_facade.h:416
bool enabled()
Definition: knx_facade.h:120
P & platform()
Definition: knx_facade.h:110
void progMode(bool value)
Definition: knx_facade.h:135
uint8_t paramByte(uint32_t addr)
Definition: knx_facade.h:364
void writeMemory()
Definition: knx_facade.h:206
void enabled(bool value)
Definition: knx_facade.h:125
uint16_t individualAddress()
Definition: knx_facade.h:211
void setSaveCallback(SaveCallback func)
Definition: knx_facade.h:312
int8_t paramSignedByte(uint32_t addr)
Definition: knx_facade.h:377
void setButtonISRFunction(IsrFunctionPtr progButtonISRFuncPtr)
Definition: knx_facade.h:307
void buttonPin(int32_t value)
Definition: knx_facade.h:196
void loop()
Definition: knx_facade.h:216
uint32_t paramInt(uint32_t addr)
Definition: knx_facade.h:393
void setRestoreCallback(RestoreCallback func)
Definition: knx_facade.h:317
void beforeRestartCallback(BeforeRestartCallback func)
Definition: knx_facade.h:422
BeforeRestartCallback beforeRestartCallback()
Definition: knx_facade.h:427
int32_t ledPin()
Definition: knx_facade.h:171
void toggleProgMode()
To be called by ISR handling on button press.
Definition: knx_facade.h:143
void orderNumber(const uint8_t *value)
Definition: knx_facade.h:253
void version(uint16_t value)
Definition: knx_facade.h:263
void hardwareType(const uint8_t *value)
Definition: knx_facade.h:258
void bauNumber(uint32_t value)
Definition: knx_facade.h:248
uint8_t * paramData(uint32_t addr)
Definition: knx_facade.h:322
B & bau()
Definition: knx_facade.h:115
void ledPinActiveOn(uint32_t value)
Sets if the programming led is active on HIGH or LOW.
Definition: knx_facade.h:166
void readMemory()
Definition: knx_facade.h:201
Interface for classes that can save and restore data from a buffer.
Definition: save_restore.h:8
void(* ProgLedOnCallback)()
Definition: knx_facade.h:69
const uint8_t *(* RestoreCallback)(const uint8_t *buffer)
Definition: knx_facade.h:66
KnxFacade< SamdPlatform, Bau07B0 > knx
Definition: knx_facade.h:514
void buttonUp()
uint8_t *(* SaveCallback)(uint8_t *buffer)
Definition: knx_facade.h:67
void(* ActivityCallback)(uint8_t info)
Definition: knx_facade.h:72
void(* IsrFunctionPtr)()
Definition: knx_facade.h:68
void(* ProgLedOffCallback)()
Definition: knx_facade.h:70
@ None
Definition: knx_types.h:224