opt-out global KNX, ability to DIY construct knx object, minor cleanups (#121)

* Refactored the knx_facade a bit to make the auto-building of the global knx object and the buttonUp() ISR function opt-in. Also added the ability to quite easily attach another serial (in this case tested with Serial2 of an ESP32).

* Added visual studio code temp files to .gitignore

* Fix for missing build flag for WifiManager in ESP32_ip demo

* Added example in which we DIY build the KNX object and use ESP32's second UART to connect so that you can debug with the first one that's connected to USB.

* Minor platform cleanups to remove compilation warnings.

* ESP32 can't handle the defaulted 8192 byte EPROM. Next to that I needed to begin() the eprom lib in my setup() to get it to work and that requires knowing how much memory KNX will use. This fix makes the default more conservative and moves it's definition to the .h file so that other files can always use it as well.

* After comments from thelsing, inverted the logic. The default global knx object is now opt-out by defining KNX_NO_AUTOMATIC_GLOBAL_INSTANCE. See the knx-demo-diy project for an example.
Minor syntactic cleanups.

* Removed hardwareserial from facade (detail which was not needed)
Placed facade constructors together
Minor syntactic cleanup

* Fixed knx-cc1310 where own button routine was calling now private internal knx facade variable.
Renamed files in knx-demo-diy
Minor syntactic stuff

* Added gitattributes for binary knxprod files
This commit is contained in:
Dennis Fleurbaaij
2021-02-05 15:57:45 +01:00
committed by GitHub
parent 58d3721571
commit f169e20f2f
19 changed files with 529 additions and 159 deletions

View File

@@ -12,11 +12,12 @@ ArduinoPlatform::ArduinoPlatform(HardwareSerial* knxSerial) : _knxSerial(knxSeri
void ArduinoPlatform::fatalError()
{
const int period = 200;
while (true)
{
#ifdef LED_BUILTIN
if ((millis() % period) > (period / 2))
static const long LED_BLINK_PERIOD = 200;
if ((millis() % LED_BLINK_PERIOD) > (LED_BLINK_PERIOD / 2))
digitalWrite(LED_BUILTIN, HIGH);
else
digitalWrite(LED_BUILTIN, LOW);

View File

@@ -10,7 +10,7 @@ Esp32Platform::Esp32Platform() : ArduinoPlatform(&Serial1)
{
}
Esp32Platform::Esp32Platform( HardwareSerial* s) : ArduinoPlatform(s)
Esp32Platform::Esp32Platform(HardwareSerial* s) : ArduinoPlatform(s)
{
}
@@ -58,10 +58,9 @@ void Esp32Platform::closeMultiCast()
bool Esp32Platform::sendBytesMultiCast(uint8_t * buffer, uint16_t len)
{
//printHex("<- ",buffer, len);
int result = 0;
result = _udp.beginMulticastPacket();
result = _udp.write(buffer, len);
result = _udp.endPacket();
_udp.beginMulticastPacket();
_udp.write(buffer, len);
_udp.endPacket();
return true;
}

View File

@@ -8,7 +8,7 @@ class Esp32Platform : public ArduinoPlatform
{
public:
Esp32Platform();
Esp32Platform( HardwareSerial* s);
Esp32Platform(HardwareSerial* s);
// ip stuff
uint32_t currentIpAddress() override;

View File

@@ -61,10 +61,9 @@ void EspPlatform::closeMultiCast()
bool EspPlatform::sendBytesMultiCast(uint8_t * buffer, uint16_t len)
{
//printHex("<- ",buffer, len);
int result = 0;
result = _udp.beginPacketMulticast(_mulitcastAddr, _mulitcastPort, WiFi.localIP());
result = _udp.write(buffer, len);
result = _udp.endPacket();
_udp.beginPacketMulticast(_mulitcastAddr, _mulitcastPort, WiFi.localIP());
_udp.write(buffer, len);
_udp.endPacket();
return true;
}

View File

@@ -8,7 +8,7 @@ class EspPlatform : public ArduinoPlatform
{
public:
EspPlatform();
EspPlatform( HardwareSerial* s);
EspPlatform(HardwareSerial* s);
// ip stuff
uint32_t currentIpAddress() override;

View File

@@ -2,10 +2,6 @@
#include <string.h>
#include "bits.h"
#ifndef KNX_FLASH_SIZE
# define KNX_FLASH_SIZE 8192
#endif
Memory::Memory(Platform& platform, DeviceObject& deviceObject)
: _platform(platform), _deviceObject(deviceObject)
{

View File

@@ -9,6 +9,10 @@
#define MAXSAVE 5
#define MAXTABLEOBJ 4
#ifndef KNX_FLASH_SIZE
# define KNX_FLASH_SIZE 1024
#endif
class MemoryBlock
{
public:

View File

@@ -2,72 +2,72 @@
#include "knx/bits.h"
#ifdef ARDUINO_ARCH_SAMD
// predefined global instance for TP or RF or TP/RF coupler
#if MASK_VERSION == 0x07B0
KnxFacade<SamdPlatform, Bau07B0> knx;
#elif MASK_VERSION == 0x27B0
KnxFacade<SamdPlatform, Bau27B0> knx;
#elif MASK_VERSION == 0x2920
KnxFacade<SamdPlatform, Bau2920> knx;
#else
#error Mask version not supported on ARDUINO_ARCH_SAMD
#ifndef KNX_NO_AUTOMATIC_GLOBAL_INSTANCE
#if (defined(ARDUINO_ARCH_STM32) || \
defined(ARDUINO_ARCH_ESP32) || \
defined(ARDUINO_ARCH_ESP8266) || \
defined(ARDUINO_ARCH_SAMD))
// Only ESP8266 and ESP32 have this define. For all other platforms this is just empty.
#ifndef ICACHE_RAM_ATTR
#define ICACHE_RAM_ATTR
#endif
ICACHE_RAM_ATTR void buttonUp()
{
static uint32_t lastpressed=0;
if (millis() - lastpressed > 200){
knx.toggleProgMode();
lastpressed = millis();
}
}
#endif
#elif defined(ARDUINO_ARCH_ESP8266)
// predefined global instance for TP or IP or TP/IP coupler
#if MASK_VERSION == 0x07B0
KnxFacade<EspPlatform, Bau07B0> knx;
#elif MASK_VERSION == 0x57B0
KnxFacade<EspPlatform, Bau57B0> knx;
#elif MASK_VERSION == 0x091A
KnxFacade<EspPlatform, Bau091A> knx;
#else
#error Mask version not supported on ARDUINO_ARCH_ESP8266
#ifdef ARDUINO_ARCH_SAMD
// predefined global instance for TP or RF or TP/RF coupler
#if MASK_VERSION == 0x07B0
KnxFacade<SamdPlatform, Bau07B0> knx(buttonUp);
#elif MASK_VERSION == 0x27B0
KnxFacade<SamdPlatform, Bau27B0> knx(buttonUp);
#elif MASK_VERSION == 0x2920
KnxFacade<SamdPlatform, Bau2920> knx(buttonUp);
#else
#error "Mask version not supported on ARDUINO_ARCH_SAMD"
#endif
#elif defined(ARDUINO_ARCH_ESP8266)
// predefined global instance for TP or IP or TP/IP coupler
#if MASK_VERSION == 0x07B0
KnxFacade<EspPlatform, Bau07B0> knx(buttonUp);
#elif MASK_VERSION == 0x57B0
KnxFacade<EspPlatform, Bau57B0> knx(buttonUp);
#elif MASK_VERSION == 0x091A
KnxFacade<EspPlatform, Bau091A> knx(buttonUp);
#else
#error "Mask version not supported on ARDUINO_ARCH_ESP8266"
#endif
#elif defined(ARDUINO_ARCH_ESP32)
// predefined global instance for TP or IP or TP/IP coupler
#if MASK_VERSION == 0x07B0
KnxFacade<Esp32Platform, Bau07B0> knx(buttonUp);
#elif MASK_VERSION == 0x57B0
KnxFacade<Esp32Platform, Bau57B0> knx(buttonUp);
#elif MASK_VERSION == 0x091A
KnxFacade<Esp32Platform, Bau091A> knx(buttonUp);
#else
#error "Mask version not supported on ARDUINO_ARCH_ESP32"
#endif
#elif defined(ARDUINO_ARCH_STM32)
#if MASK_VERSION == 0x07B0
KnxFacade<Stm32Platform, Bau07B0> knx(buttonUp);
#else
#error "Mask version not supported on ARDUINO_ARCH_STM32"
#endif
#else // Non-Arduino platforms and Linux platform
// no predefined global instance
#endif
#elif defined(ARDUINO_ARCH_ESP32)
// predefined global instance for TP or IP or TP/IP coupler
#if MASK_VERSION == 0x07B0
KnxFacade<Esp32Platform, Bau07B0> knx;
#elif MASK_VERSION == 0x57B0
KnxFacade<Esp32Platform, Bau57B0> knx;
#elif MASK_VERSION == 0x091A
KnxFacade<Esp32Platform, Bau091A> knx;
#else
#error Mask version not supported on ARDUINO_ARCH_ESP8266
#endif
#elif defined(ARDUINO_ARCH_STM32)
#if MASK_VERSION == 0x07B0
KnxFacade<Stm32Platform, Bau07B0> knx;
#else
#error Mask version not supported on ARDUINO_ARCH_STM32
#endif
#else // Non-Arduino platforms and Linux platform
// no predefined global instance
#endif
// Only ESP8266 and ESP32 have this define. For all other platforms this is just empty.
#ifndef ICACHE_RAM_ATTR
#define ICACHE_RAM_ATTR
#endif
#if (defined(ARDUINO_ARCH_STM32) || \
defined(ARDUINO_ARCH_ESP32) || \
defined(ARDUINO_ARCH_ESP8266) || \
defined(ARDUINO_ARCH_SAMD))
ICACHE_RAM_ATTR void buttonUp()
{
static uint32_t lastpressed=0;
if (millis() - lastpressed > 200){
knx._toogleProgMode = true;
lastpressed = millis();
}
}
#elif defined(__linux__)
void buttonUp()
{
// no de-bounce on linux platform, just satisfy the compiler
}
#endif
#endif // KNX_NO_AUTOMATIC_GLOBAL_INSTANCE

View File

@@ -10,33 +10,41 @@
#ifdef ARDUINO_ARCH_SAMD
#include "samd_platform.h"
void buttonUp();
#ifndef KNX_NO_AUTOMATIC_GLOBAL_INSTANCE
void buttonUp();
#endif
#elif defined(ARDUINO_ARCH_ESP8266)
#include "esp_platform.h"
void buttonUp();
#include "esp_platform.h"
#ifndef KNX_NO_AUTOMATIC_GLOBAL_INSTANCE
void buttonUp();
#endif
#elif defined(ARDUINO_ARCH_ESP32)
#define LED_BUILTIN 13
#include "esp32_platform.h"
void buttonUp();
#define LED_BUILTIN 13
#include "esp32_platform.h"
#ifndef KNX_NO_AUTOMATIC_GLOBAL_INSTANCE
void buttonUp();
#endif
#elif defined(ARDUINO_ARCH_STM32)
#include "stm32_platform.h"
void buttonUp();
#include "stm32_platform.h"
#ifndef KNX_NO_AUTOMATIC_GLOBAL_INSTANCE
void buttonUp();
#endif
#elif __linux__
#define LED_BUILTIN 0
#include "linux_platform.h"
void buttonUp();
#define LED_BUILTIN 0
#include "linux_platform.h"
#else
#define LED_BUILTIN 5 // see GPIO_PinConfig gpioPinConfigs[]
#include "cc1310_platform.h"
extern void buttonUp();
#define LED_BUILTIN 5 // see GPIO_PinConfig gpioPinConfigs[]
#include "cc1310_platform.h"
#ifndef KNX_NO_AUTOMATIC_GLOBAL_INSTANCE
extern void buttonUp();
#endif
#endif
typedef uint8_t* (*SaveRestoreCallback)(uint8_t* buffer);
typedef void (*IsrFunctionPtr)();
template <class P, class B> class KnxFacade : private SaveRestore
{
friend void buttonUp();
public:
KnxFacade() : _platformPtr(new P()), _bauPtr(new B(*_platformPtr)), _bau(*_bauPtr)
{
@@ -44,6 +52,19 @@ template <class P, class B> class KnxFacade : private SaveRestore
_bau.addSaveRestore(this);
}
KnxFacade(B& bau) : _bau(bau)
{
manufacturerId(0xfa);
_bau.addSaveRestore(this);
}
KnxFacade(IsrFunctionPtr buttonISRFunction) : _platformPtr(new P()), _bauPtr(new B(*_platformPtr)), _bau(*_bauPtr)
{
manufacturerId(0xfa);
_bau.addSaveRestore(this);
setButtonISRFunction(buttonISRFunction);
}
virtual ~KnxFacade()
{
if (_bauPtr)
@@ -53,12 +74,6 @@ template <class P, class B> class KnxFacade : private SaveRestore
delete _platformPtr;
}
KnxFacade(B& bau) : _bau(bau)
{
manufacturerId(0xfa);
_bau.addSaveRestore(this);
}
P& platform()
{
return *_platformPtr;
@@ -89,6 +104,14 @@ template <class P, class B> class KnxFacade : private SaveRestore
_bau.deviceObject().progMode(value);
}
/**
* To be called by ISR handling on button press.
*/
void toggleProgMode()
{
_toggleProgMode = true;
}
bool configured()
{
return _bau.configured();
@@ -181,10 +204,10 @@ template <class P, class B> class KnxFacade : private SaveRestore
digitalWrite(ledPin(), HIGH - _ledPinActiveOn);
}
}
if (_toogleProgMode)
if (_toggleProgMode)
{
progMode(!progMode());
_toogleProgMode = false;
_toggleProgMode = false;
}
_bau.loop();
}
@@ -216,21 +239,30 @@ template <class P, class B> class KnxFacade : private SaveRestore
void start()
{
pinMode(_ledPin, OUTPUT);
pinMode(ledPin(), OUTPUT);
digitalWrite(_ledPin, HIGH - _ledPinActiveOn);
digitalWrite(ledPin(), HIGH - _ledPinActiveOn);
pinMode(_buttonPin, INPUT_PULLUP);
pinMode(buttonPin(), INPUT_PULLUP);
if (_progButtonISRFuncPtr)
{
// Workaround for https://github.com/arduino/ArduinoCore-samd/issues/587
#if (ARDUINO_API_VERSION >= 10200)
attachInterrupt(_buttonPin, _progButtonISRFuncPtr, (PinStatus)_buttonPinInterruptOn);
#else
attachInterrupt(_buttonPin, _progButtonISRFuncPtr, _buttonPinInterruptOn);
#endif
}
// Workaround for https://github.com/arduino/ArduinoCore-samd/issues/587
#if (ARDUINO_API_VERSION >= 10200)
attachInterrupt(_buttonPin, buttonUp, (PinStatus)_buttonPinInterruptOn);
#else
attachInterrupt(_buttonPin, buttonUp, _buttonPinInterruptOn);
#endif
enabled(true);
}
void setButtonISRFunction(IsrFunctionPtr progButtonISRFuncPtr)
{
_progButtonISRFuncPtr = progButtonISRFuncPtr;
}
void setSaveCallback(SaveRestoreCallback func)
{
_saveCallback = func;
@@ -303,9 +335,10 @@ template <class P, class B> class KnxFacade : private SaveRestore
uint32_t _buttonPin = 0;
SaveRestoreCallback _saveCallback = 0;
SaveRestoreCallback _restoreCallback = 0;
bool _toogleProgMode = false;
volatile bool _toggleProgMode = false;
bool _progLedState = false;
uint16_t _saveSize = 0;
IsrFunctionPtr _progButtonISRFuncPtr = 0;
uint8_t* save(uint8_t* buffer)
{
@@ -334,46 +367,48 @@ template <class P, class B> class KnxFacade : private SaveRestore
}
};
#ifdef ARDUINO_ARCH_SAMD
// predefined global instance for TP or RF or TP/RF coupler
#if MASK_VERSION == 0x07B0
extern KnxFacade<SamdPlatform, Bau07B0> knx;
#elif MASK_VERSION == 0x27B0
extern KnxFacade<SamdPlatform, Bau27B0> knx;
#elif MASK_VERSION == 0x2920
extern KnxFacade<SamdPlatform, Bau2920> knx;
#else
#error "Mask version not supported on ARDUINO_ARCH_SAMD"
#ifndef KNX_NO_AUTOMATIC_GLOBAL_INSTANCE
#ifdef ARDUINO_ARCH_SAMD
// predefined global instance for TP or RF or TP/RF coupler
#if MASK_VERSION == 0x07B0
extern KnxFacade<SamdPlatform, Bau07B0> knx;
#elif MASK_VERSION == 0x27B0
extern KnxFacade<SamdPlatform, Bau27B0> knx;
#elif MASK_VERSION == 0x2920
extern KnxFacade<SamdPlatform, Bau2920> knx;
#else
#error "Mask version not supported on ARDUINO_ARCH_SAMD"
#endif
#elif defined(ARDUINO_ARCH_ESP8266)
// predefined global instance for TP or IP or TP/IP coupler
#if MASK_VERSION == 0x07B0
extern KnxFacade<EspPlatform, Bau07B0> knx;
#elif MASK_VERSION == 0x57B0
extern KnxFacade<EspPlatform, Bau57B0> knx;
#elif MASK_VERSION == 0x091A
extern KnxFacade<EspPlatform, Bau091A> knx;
#else
#error "Mask version not supported on ARDUINO_ARCH_ESP8266"
#endif
#elif defined(ARDUINO_ARCH_ESP32)
// predefined global instance for TP or IP or TP/IP coupler
#if MASK_VERSION == 0x07B0
extern KnxFacade<Esp32Platform, Bau07B0> knx;
#elif MASK_VERSION == 0x57B0
extern KnxFacade<Esp32Platform, Bau57B0> knx;
#elif MASK_VERSION == 0x091A
extern KnxFacade<Esp32Platform, Bau091A> knx;
#else
#error "Mask version not supported on ARDUINO_ARCH_ESP32"
#endif
#elif defined(ARDUINO_ARCH_STM32)
// predefined global instance for TP only
#if MASK_VERSION == 0x07B0
extern KnxFacade<Stm32Platform, Bau07B0> knx;
#else
#error "Mask version not supported on ARDUINO_ARCH_STM32"
#endif
#else // Non-Arduino platforms and Linux platform
// no predefined global instance
#endif
#elif defined(ARDUINO_ARCH_ESP8266)
// predefined global instance for TP or IP or TP/IP coupler
#if MASK_VERSION == 0x07B0
extern KnxFacade<EspPlatform, Bau07B0> knx;
#elif MASK_VERSION == 0x57B0
extern KnxFacade<EspPlatform, Bau57B0> knx;
#elif MASK_VERSION == 0x091A
extern KnxFacade<EspPlatform, Bau091A> knx;
#else
#error "Mask version not supported on ARDUINO_ARCH_ESP8266"
#endif
#elif defined(ARDUINO_ARCH_ESP32)
// predefined global instance for TP or IP or TP/IP coupler
#if MASK_VERSION == 0x07B0
extern KnxFacade<Esp32Platform, Bau07B0> knx;
#elif MASK_VERSION == 0x57B0
extern KnxFacade<Esp32Platform, Bau57B0> knx;
#elif MASK_VERSION == 0x091A
extern KnxFacade<Esp32Platform, Bau091A> knx;
#else
#error "Mask version not supported on ARDUINO_ARCH_ESP32"
#endif
#elif defined(ARDUINO_ARCH_STM32)
// predefined global instance for TP only
#if MASK_VERSION == 0x07B0
extern KnxFacade<Stm32Platform, Bau07B0> knx;
#else
#error Mask version not supported on ARDUINO_ARCH_STM32
#endif
#else // Non-Arduino platforms and Linux platform
// no predefined global instance
#endif
#endif // KNX_NO_AUTOMATIC_GLOBAL_INSTANCE