From a510042e782d9207a2bcf4f34fc7bdb845a06451 Mon Sep 17 00:00:00 2001 From: Thomas Kunze Date: Fri, 13 Sep 2024 17:53:32 +0200 Subject: [PATCH] Squashed commit of the following: commit 043ba081ffae5799a36d420650670298746afc3f Merge: eb0d626 277a5d5 Author: OnlineCaveman <115506475+OnlineCaveman@users.noreply.github.com> Date: Fri Oct 28 22:09:18 2022 +0200 Merge branch 'w5500' commit 277a5d57fa60f5cbe18931a646a46c61e13d9801 Merge: cf44c4e 187ab2e Author: OnlineCaveman <115506475+OnlineCaveman@users.noreply.github.com> Date: Fri Oct 28 19:35:32 2022 +0200 Merge branch 'w5500' of https://github.com/OnlineCaveman/knx-samd51 into w5500 commit cf44c4efe944f36c5e359ad4f6cd835e8302a0c8 Author: OnlineCaveman <115506475+OnlineCaveman@users.noreply.github.com> Date: Fri Oct 28 19:35:02 2022 +0200 Added functionality for W5500 Initialisation works. Compiling fails on "htonl" expansion. If commented out it compiles fine. commit 187ab2e9f1fa4b0de9fc06f46d9344500faf4585 Merge: b0238cf eef3a85 Author: OnlineCaveman <115506475+OnlineCaveman@users.noreply.github.com> Date: Thu Oct 27 14:30:17 2022 +0200 Merge branch 'thelsing:master' into w5500 commit eb0d62666d18787b775e4aa24f224e84685cbce3 Merge: b0238cf eef3a85 Author: OnlineCaveman <115506475+OnlineCaveman@users.noreply.github.com> Date: Thu Oct 27 14:29:49 2022 +0200 Merge branch 'thelsing:master' into master commit b0238cfe7e16c687794a2f67ae9ca298a704dfdf Author: OnlineCaveman <115506475+OnlineCaveman@users.noreply.github.com> Date: Tue Oct 25 17:28:00 2022 +0200 Changed comment lines Changed the comment lines to reflect the current possibilities TP and RF commit d24f6de36fca4dedf3a42a60e19fb65393bb67b2 Author: OnlineCaveman <115506475+OnlineCaveman@users.noreply.github.com> Date: Tue Oct 25 17:24:55 2022 +0200 Added the RF (0x27B0) Added checks for RF 0x27B0 as that should work ootb I suppose. Builds and uploads successfully. Gives the debug output "ERROR, RF transceiver not responding" since I have no RF hw to test. Same goes for the TP 0x07B0. Build and uploads successfully. Gives the debug output "ERROR, TPUART not responding" since no I have no TP uart hw to test. commit 7373ab0a875b42e5eab242adc56707430f7756e1 Author: OnlineCaveman <115506475+OnlineCaveman@users.noreply.github.com> Date: Tue Oct 25 16:19:53 2022 +0200 No IP version yet commit 76762571ea6a8852705ad491b0ef53235e29c044 Author: OnlineCaveman <115506475+OnlineCaveman@users.noreply.github.com> Date: Tue Oct 25 15:56:34 2022 +0200 Ifdef include requested change commit 02565a0ba3d573314797991255c092589a825f6e Author: OnlineCaveman <115506475+OnlineCaveman@users.noreply.github.com> Date: Mon Oct 17 21:10:23 2022 +0200 Cleanup Removed unnecesary Qspi stuff for now. Compiles fine for samd51 and samd21. Have no samd21 platform or tpuart to do thorough testing but nothing fundamental was changed in samd_platform other than the ifdef checks. commit 598f6bddfd6efe579b24b8de4870e773f9f16bb7 Merge: 37e056a b403480 Author: OnlineCaveman <115506475+OnlineCaveman@users.noreply.github.com> Date: Mon Oct 17 20:38:08 2022 +0200 Merge branch 'master' of https://github.com/OnlineCaveman/knx-samd51 commit 37e056a91cbc2a77326c8d9c587f3709047616a1 Author: OnlineCaveman <115506475+OnlineCaveman@users.noreply.github.com> Date: Mon Oct 17 20:37:44 2022 +0200 ARCH_SAMD Now checking for __SAMD21__ and __SAMD51__ in knx_facade, samd_platform (samd21) and samd51_platform (samd51) Preparation for external flash functionality in platform.h commit b403480f0c67b8f74e315c32c1400e8aa768f4ef Merge: c0e5621 a0134e6 Author: OnlineCaveman <115506475+OnlineCaveman@users.noreply.github.com> Date: Mon Oct 17 19:59:28 2022 +0200 Merge branch 'thelsing:master' into master commit c0e5621a5f4420c086fa1fb0ec92912b56b29833 Author: OnlineCaveman <115506475+OnlineCaveman@users.noreply.github.com> Date: Mon Oct 17 19:52:10 2022 +0200 Rename back to original commit 6c4a10e189e81b553d854b92862be24e0177501e Author: OnlineCaveman <115506475+OnlineCaveman@users.noreply.github.com> Date: Mon Oct 17 19:51:31 2022 +0200 Fault in change tracking Renaming subdir knx to force changes commit b8107fd62d44c8d6ced25a9d363c0d156dda6647 Author: OnlineCaveman <115506475+OnlineCaveman@users.noreply.github.com> Date: Mon Oct 17 19:48:09 2022 +0200 SAMD51/SAMD21 files Separate files for SAMD51 and SAMD21 platforms. commit 4248a1f073b86e3e2bffb26a7741f16377dbb17e Author: OnlineCaveman <115506475+OnlineCaveman@users.noreply.github.com> Date: Sat Oct 15 16:15:32 2022 +0200 Updated for samd51 flash storage compatibility --- examples/knx-demo/.gitignore | 5 + examples/knx-demo/platformio-ci.ini | 20 +- examples/knx-demo/platformio.ini | 21 +- src/knx.h | 12 +- src/knx/knx_facade.cpp | 113 +++--- src/knx/knx_facade.h | 145 +++---- ...{samd_platform.cpp => samd21_platform.cpp} | 51 +-- .../{samd_platform.h => samd21_platform.h} | 9 +- src/knx/platform/samd51_platform.cpp | 363 ++++++++++++++++++ src/knx/platform/samd51_platform.h | 79 ++++ 10 files changed, 646 insertions(+), 172 deletions(-) create mode 100644 examples/knx-demo/.gitignore rename src/knx/platform/{samd_platform.cpp => samd21_platform.cpp} (76%) rename src/knx/platform/{samd_platform.h => samd21_platform.h} (91%) create mode 100644 src/knx/platform/samd51_platform.cpp create mode 100644 src/knx/platform/samd51_platform.h diff --git a/examples/knx-demo/.gitignore b/examples/knx-demo/.gitignore new file mode 100644 index 0000000..89cc49c --- /dev/null +++ b/examples/knx-demo/.gitignore @@ -0,0 +1,5 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/examples/knx-demo/platformio-ci.ini b/examples/knx-demo/platformio-ci.ini index b426eb0..c114346 100644 --- a/examples/knx-demo/platformio-ci.ini +++ b/examples/knx-demo/platformio-ci.ini @@ -8,7 +8,7 @@ ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html -;--- SAMD -------------------------------------------------- +;--- SAMD21 -------------------------------------------------- [env:adafruit_feather_m0_rf] platform = atmelsam board = adafruit_feather_m0 @@ -21,8 +21,24 @@ build_flags = -DMASK_VERSION=0x27B0 -Wno-unknown-pragmas -DUSE_DATASECURE -;----------------------------------------------------------- +;--- SAMD51 -------------------------------------------------- + +[env:feather_m4_w5500] +platform = atmelsam +board = adafruit_feather_m4 +framework = arduino + +lib_deps = + WifiManager + knx + Ethernet + +build_flags = + -DMASK_VERSION=0x57B0 + -DUSE_W5X00=1 + -DKNX_NO_SPI=1 + -Wno-unknown-pragmas ;--- ESP8266 ----------------------------------------------- [env:nodemcuv2_ip] diff --git a/examples/knx-demo/platformio.ini b/examples/knx-demo/platformio.ini index 0de299b..8bbf656 100644 --- a/examples/knx-demo/platformio.ini +++ b/examples/knx-demo/platformio.ini @@ -20,11 +20,10 @@ board = adafruit_feather_m0 framework = arduino ; We consider that the this projects is opened within its project directory ; while working with VS Code. -lib_extra_dirs = ../../../ lib_deps = SPI - knx + knx=file://../../../knx build_flags = -DMASK_VERSION=0x27B0 @@ -39,11 +38,10 @@ build_flags = #framework = arduino ; We consider that the this projects is opened within its project directory ; while working with VS Code. -#lib_extra_dirs = ../../../ #lib_deps = # WifiManager -# knx +# knx=file://../../../knx #build_flags = # -DMASK_VERSION=0x57B0 @@ -55,11 +53,10 @@ board = nodemcuv2 framework = arduino ; We consider that the this projects is opened within its project directory ; while working with VS Code. -lib_extra_dirs = ../../../ lib_deps = WifiManager@0.15.0 - knx + knx=file://../../../knx build_flags = -DMASK_VERSION=0x07B0 @@ -75,11 +72,10 @@ board = esp32dev framework = arduino ; We consider that the this projects is opened within its project directory ; while working with VS Code. -lib_extra_dirs = ../../../ lib_deps = https://github.com/tzapu/WiFiManager.git - knx + knx=file://../../../knx build_flags = -DMASK_VERSION=0x57B0 @@ -91,10 +87,9 @@ board = esp32dev framework = arduino ; We consider that the this projects is opened within its project directory ; while working with VS Code. -lib_extra_dirs = ../../../ lib_deps = - knx + knx=file://../../../knx build_flags = -DMASK_VERSION=0x07B0 @@ -107,10 +102,9 @@ board = genericSTM32F103CB framework = arduino ; We consider that the this projects is opened within its project directory ; while working with VS Code. -lib_extra_dirs = ../../../ lib_deps = - knx + knx=file://../../../knx build_flags = -DENABLE_HWSERIAL1 @@ -130,10 +124,9 @@ board = genericSTM32F103CB framework = arduino ; We consider that the this projects is opened within its project directory ; while working with VS Code. -lib_extra_dirs = ../../../ lib_deps = - knx + knx=file://../../../knx build_flags = -DENABLE_HWSERIAL1 diff --git a/src/knx.h b/src/knx.h index 1a7b63b..49a9106 100644 --- a/src/knx.h +++ b/src/knx.h @@ -117,9 +117,11 @@ package platform { class Platform [[class_platform.html]] class ArduinoPlatform [[class_arduino_platform.html]] -class SamdPlatform [[class_samd_platform.html]] +class Samd21Platform [[class_samd21_platform.html]] +class Samd51Platform [[class_samd51_platform.html]] Platform<|--ArduinoPlatform -ArduinoPlatform<|--SamdPlatform +ArduinoPlatform<|--Samd21Platform +ArduinoPlatform<|--Samd51Platform class EspPlatform [[class_esp_platform.html]] ArduinoPlatform<|--EspPlatform class Esp32Platform [[class_esp32_platform.html]] @@ -219,9 +221,11 @@ package platform { class Platform [[class_platform.html]] class ArduinoPlatform [[class_arduino_platform.html]] -class SamdPlatform [[class_samd_platform.html]] +class Samd21Platform [[class_samd21_platform.html]] +class Samd51Platform [[class_samd51_platform.html]] Platform<|--ArduinoPlatform -ArduinoPlatform<|--SamdPlatform +ArduinoPlatform<|--Samd21Platform +ArduinoPlatform<|--Samd51Platform class EspPlatform [[class_esp_platform.html]] ArduinoPlatform<|--EspPlatform class Esp32Platform [[class_esp32_platform.html]] diff --git a/src/knx/knx_facade.cpp b/src/knx/knx_facade.cpp index b1cb9af..9f2eb4e 100644 --- a/src/knx/knx_facade.cpp +++ b/src/knx/knx_facade.cpp @@ -44,65 +44,76 @@ ICACHE_RAM_ATTR void buttonEvent() } #endif -#ifdef ARDUINO_ARCH_SAMD - // predefined global instance for TP or RF or TP/RF coupler - #if MASK_VERSION == 0x07B0 - Knx::KnxFacade knx(buttonEvent); - #elif MASK_VERSION == 0x27B0 - Knx::KnxFacade knx(buttonEvent); - #elif MASK_VERSION == 0x2920 - Knx::KnxFacade knx(buttonEvent); - #else - #error "Mask version not supported on ARDUINO_ARCH_SAMD" - #endif +#ifdef __SAMD51__ +// predefined global instance for TP or RF +#if MASK_VERSION == 0x07B0 + Knx::KnxFacade knx(buttonEvent); +#elif MASK_VERSION == 0x27B0 + Knx::KnxFacade knx(buttonEvent); +#elif MASK_VERSION == 0x57B0 + Knx::KnxFacade knx(buttonEvent); +#else + #error "Mask version not supported on SAMD51" +#endif +#elif defined(_SAMD21_) +// predefined global instance for TP or RF or TP/RF coupler +#if MASK_VERSION == 0x07B0 + Knx::KnxFacade knx(buttonEvent); +#elif MASK_VERSION == 0x27B0 + Knx::KnxFacade knx(buttonEvent); +#elif MASK_VERSION == 0x2920 + Knx::KnxFacade knx(buttonEvent); +#else + #error "Mask version not supported on SAMD21" +#endif #elif defined(ARDUINO_ARCH_RP2040) - // predefined global instance for TP or RF or IP or TP/RF coupler or TP/IP coupler - #if MASK_VERSION == 0x07B0 - Knx::KnxFacade knx(buttonEvent); - #elif MASK_VERSION == 0x27B0 - Knx::KnxFacade knx(buttonEvent); - #elif MASK_VERSION == 0x57B0 - Knx::KnxFacade knx(buttonEvent); - #elif MASK_VERSION == 0x2920 - Knx::KnxFacade knx(buttonEvent); - #elif MASK_VERSION == 0x091A - Knx::KnxFacade knx(buttonEvent); - #else - #error "Mask version not supported on ARDUINO_ARCH_RP2040" - #endif +// predefined global instance for TP or RF or IP or TP/RF coupler or TP/IP coupler +#if MASK_VERSION == 0x07B0 + Knx::KnxFacade knx(buttonEvent); +#elif MASK_VERSION == 0x27B0 + Knx::KnxFacade knx(buttonEvent); +#elif MASK_VERSION == 0x57B0 + Knx::KnxFacade knx(buttonEvent); +#elif MASK_VERSION == 0x2920 + Knx::KnxFacade knx(buttonEvent); +#elif MASK_VERSION == 0x091A + Knx::KnxFacade knx(buttonEvent); +#else + #error "Mask version not supported on ARDUINO_ARCH_RP2040" +#endif #elif defined(ARDUINO_ARCH_ESP8266) - // predefined global instance for TP or IP or TP/IP coupler - #if MASK_VERSION == 0x07B0 - Knx::KnxFacade knx(buttonEvent); - #elif MASK_VERSION == 0x57B0 - Knx::KnxFacade knx(buttonEvent); - #elif MASK_VERSION == 0x091A - Knx::KnxFacade knx(buttonEvent); - #else - #error "Mask version not supported on ARDUINO_ARCH_ESP8266" - #endif +// predefined global instance for TP or IP or TP/IP coupler +#if MASK_VERSION == 0x07B0 + Knx::KnxFacade knx(buttonEvent); +#elif MASK_VERSION == 0x57B0 + Knx::KnxFacade knx(buttonEvent); +#elif MASK_VERSION == 0x091A + Knx::KnxFacade knx(buttonEvent); +#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 - Knx::KnxFacade knx(buttonEvent); - #elif MASK_VERSION == 0x57B0 - Knx::KnxFacade knx(buttonEvent); - #elif MASK_VERSION == 0x091A - Knx::KnxFacade knx(buttonEvent); - #else - #error "Mask version not supported on ARDUINO_ARCH_ESP32" - #endif +// predefined global instance for TP or IP or TP/IP coupler +#if MASK_VERSION == 0x07B0 + Knx::KnxFacade knx(buttonEvent); +#elif MASK_VERSION == 0x57B0 + Knx::KnxFacade knx(buttonEvent); +#elif MASK_VERSION == 0x091A + Knx::KnxFacade knx(buttonEvent); +#else + #error "Mask version not supported on ARDUINO_ARCH_ESP32" +#endif #elif defined(ARDUINO_ARCH_STM32) - #if MASK_VERSION == 0x07B0 - Knx::KnxFacade knx(buttonEvent); - #else - #error "Mask version not supported on ARDUINO_ARCH_STM32" - #endif +#if MASK_VERSION == 0x07B0 + Knx::KnxFacade knx(buttonEvent); +#else + #error "Mask version not supported on ARDUINO_ARCH_STM32" +#endif #else // Non-Arduino platforms and Linux platform - // no predefined global instance +// no predefined global instance #endif #endif // KNX_NO_AUTOMATIC_GLOBAL_INSTANCE diff --git a/src/knx/knx_facade.h b/src/knx/knx_facade.h index ab23bea..509939b 100644 --- a/src/knx/knx_facade.h +++ b/src/knx/knx_facade.h @@ -14,20 +14,22 @@ #define USERDATA_SAVE_SIZE 0 #endif -#ifdef ARDUINO_ARCH_SAMD - #include "platform/samd_platform.h" +#ifdef __SAMD51__ +#include "platform/samd51_platform.h" +#elif defined(_SAMD21_) +#include "platform/samd21_platform.h" #elif defined(ARDUINO_ARCH_RP2040) - #include "platform/rp2040_arduino_platform.h" +#include "platform/rp2040_arduino_platform.h" #elif defined(ARDUINO_ARCH_ESP8266) - #include "platform/esp_platform.h" +#include "platform/esp_platform.h" #elif defined(ARDUINO_ARCH_ESP32) - #include "platform/esp32_platform.h" +#include "platform/esp32_platform.h" #elif defined(ARDUINO_ARCH_STM32) - #include "platform/stm32_platform.h" +#include "platform/stm32_platform.h" #elif __linux__ - #include "platform/linux_platform.h" +#include "platform/linux_platform.h" #else - #include "platform/cc1310_platform.h" +#include "platform/cc1310_platform.h" #endif #ifndef KNX_LED @@ -462,62 +464,73 @@ namespace Knx }; } #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 Knx::KnxFacade knx; - #elif MASK_VERSION == 0x27B0 - extern Knx::KnxFacade knx; - #elif MASK_VERSION == 0x2920 - extern Knx::KnxFacade knx; - #else - #error "Mask version not supported on ARDUINO_ARCH_SAMD" - #endif - #elif defined(ARDUINO_ARCH_RP2040) - // predefined global instance for TP or RF or TP/RF or TP/IP coupler - #if MASK_VERSION == 0x07B0 - extern Knx::KnxFacade knx; - #elif MASK_VERSION == 0x27B0 - extern Knx::KnxFacade knx; - #elif MASK_VERSION == 0x57B0 - extern Knx::KnxFacade knx; - #elif MASK_VERSION == 0x2920 - extern Knx::KnxFacade knx; - #elif MASK_VERSION == 0x091A - extern Knx::KnxFacade knx; - #else - #error "Mask version not supported on ARDUINO_ARCH_RP2040" - #endif - #elif defined(ARDUINO_ARCH_ESP8266) - // predefined global instance for TP or IP or TP/IP coupler - #if MASK_VERSION == 0x07B0 - extern Knx::KnxFacade knx; - #elif MASK_VERSION == 0x57B0 - extern Knx::KnxFacade knx; - #elif MASK_VERSION == 0x091A - extern Knx::KnxFacade 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 Knx::KnxFacade knx; - #elif MASK_VERSION == 0x57B0 - extern Knx::KnxFacade knx; - #elif MASK_VERSION == 0x091A - extern Knx::KnxFacade 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 Knx::KnxFacade knx; - #else - #error "Mask version not supported on ARDUINO_ARCH_STM32" - #endif - #else // Non-Arduino platforms and Linux platform - // no predefined global instance - #endif +#ifdef __SAMD51__ +// predefined global instance for TP or RF +#if MASK_VERSION == 0x07B0 + extern Knx::KnxFacade knx; +#elif MASK_VERSION == 0x27B0 + extern Knx::KnxFacade knx; +#elif MASK_VERSION == 0x57B0 + extern Knx::KnxFacade knx; +#else + #error "Mask version not supported on SAMD51" +#endif +#elif defined(_SAMD21_) +// predefined global instance for TP or RF or TP/RF coupler +#if MASK_VERSION == 0x07B0 + extern Knx::KnxFacade knx; +#elif MASK_VERSION == 0x27B0 + extern Knx::KnxFacade knx; +#elif MASK_VERSION == 0x2920 + extern Knx::KnxFacade knx; +#else + #error "Mask version not supported on ARDUINO_ARCH_SAMD" +#endif +#elif defined(ARDUINO_ARCH_RP2040) +// predefined global instance for TP or RF or TP/RF or TP/IP coupler +#if MASK_VERSION == 0x07B0 + extern Knx::KnxFacade knx; +#elif MASK_VERSION == 0x27B0 + extern Knx::KnxFacade knx; +#elif MASK_VERSION == 0x57B0 + extern Knx::KnxFacade knx; +#elif MASK_VERSION == 0x2920 + extern Knx::KnxFacade knx; +#elif MASK_VERSION == 0x091A + extern Knx::KnxFacade knx; +#else + #error "Mask version not supported on ARDUINO_ARCH_RP2040" +#endif +#elif defined(ARDUINO_ARCH_ESP8266) +// predefined global instance for TP or IP or TP/IP coupler +#if MASK_VERSION == 0x07B0 + extern Knx::KnxFacade knx; +#elif MASK_VERSION == 0x57B0 + extern Knx::KnxFacade knx; +#elif MASK_VERSION == 0x091A + extern Knx::KnxFacade 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 Knx::KnxFacade knx; +#elif MASK_VERSION == 0x57B0 + extern Knx::KnxFacade knx; +#elif MASK_VERSION == 0x091A + extern Knx::KnxFacade 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 Knx::KnxFacade 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 diff --git a/src/knx/platform/samd_platform.cpp b/src/knx/platform/samd21_platform.cpp similarity index 76% rename from src/knx/platform/samd_platform.cpp rename to src/knx/platform/samd21_platform.cpp index 28819c8..6d61f3e 100644 --- a/src/knx/platform/samd_platform.cpp +++ b/src/knx/platform/samd21_platform.cpp @@ -1,6 +1,5 @@ -#ifdef ARDUINO_ARCH_SAMD -#include "samd_platform.h" - +#include "samd21_platform.h" +#if defined(_SAMD21_) #include #include @@ -22,7 +21,8 @@ extern uint32_t __data_end__; namespace Knx { - SamdPlatform::SamdPlatform() + + Samd21Platform::Samd21Platform() #ifndef KNX_NO_DEFAULT_UART : ArduinoPlatform(&KNX_SERIAL) #endif @@ -32,34 +32,25 @@ namespace Knx #endif } - SamdPlatform::SamdPlatform( HardwareSerial* s) : ArduinoPlatform(s) + Samd21Platform::Samd21Platform( HardwareSerial* s) : ArduinoPlatform(s) { #ifndef USE_SAMD_EEPROM_EMULATION init(); #endif } - uint32_t SamdPlatform::uniqueSerialNumber() + uint32_t Samd21Platform::uniqueSerialNumber() { -#if defined (__SAMD51__) - // SAMD51 from section 9.6 of the datasheet -#define SERIAL_NUMBER_WORD_0 *(volatile uint32_t*)(0x008061FC) -#define SERIAL_NUMBER_WORD_1 *(volatile uint32_t*)(0x00806010) -#define SERIAL_NUMBER_WORD_2 *(volatile uint32_t*)(0x00806014) -#define SERIAL_NUMBER_WORD_3 *(volatile uint32_t*)(0x00806018) -#else - //#elif defined (__SAMD21E17A__) || defined(__SAMD21G18A__) || defined(__SAMD21E18A__) || defined(__SAMD21J18A__) // SAMD21 from section 9.3.3 of the datasheet #define SERIAL_NUMBER_WORD_0 *(volatile uint32_t*)(0x0080A00C) #define SERIAL_NUMBER_WORD_1 *(volatile uint32_t*)(0x0080A040) #define SERIAL_NUMBER_WORD_2 *(volatile uint32_t*)(0x0080A044) #define SERIAL_NUMBER_WORD_3 *(volatile uint32_t*)(0x0080A048) -#endif return SERIAL_NUMBER_WORD_0 ^ SERIAL_NUMBER_WORD_1 ^ SERIAL_NUMBER_WORD_2 ^ SERIAL_NUMBER_WORD_3; } - void SamdPlatform::restart() + void Samd21Platform::restart() { println("restart"); NVIC_SystemReset(); @@ -67,7 +58,7 @@ namespace Knx #ifdef USE_SAMD_EEPROM_EMULATION #pragma warning "Using EEPROM Simulation" - uint8_t* SamdPlatform::getEepromBuffer(uint32_t size) + uint8_t* Samd21Platform::getEepromBuffer(uint32_t size) { //EEPROM.begin(size); if (size > EEPROM_EMULATION_SIZE) @@ -76,7 +67,7 @@ namespace Knx return EEPROM.getDataPtr(); } - void SamdPlatform::commitToEeprom() + void Samd21Platform::commitToEeprom() { EEPROM.commit(); } @@ -84,7 +75,7 @@ namespace Knx static const uint32_t pageSizes[] = {8, 16, 32, 64, 128, 256, 512, 1024}; - void SamdPlatform::init() + void Samd21Platform::init() { _memoryType = Flash; _pageSize = pageSizes[NVMCTRL->PARAM.bit.PSZ]; @@ -109,22 +100,22 @@ namespace Knx } } - size_t SamdPlatform::flashEraseBlockSize() + size_t Samd21Platform::flashEraseBlockSize() { return PAGES_PER_ROW; } - size_t SamdPlatform::flashPageSize() + size_t Samd21Platform::flashPageSize() { return _pageSize; } - uint8_t* SamdPlatform::userFlashStart() + uint8_t* Samd21Platform::userFlashStart() { return (uint8_t*)_MemoryStart; } - size_t SamdPlatform::userFlashSizeEraseBlocks() + size_t Samd21Platform::userFlashSizeEraseBlocks() { if (KNX_FLASH_SIZE <= 0) return 0; @@ -132,7 +123,7 @@ namespace Knx return ((KNX_FLASH_SIZE - 1) / (flashPageSize() * flashEraseBlockSize())) + 1; } - void SamdPlatform::flashErase(uint16_t eraseBlockNum) + void Samd21Platform::flashErase(uint16_t eraseBlockNum) { noInterrupts(); @@ -142,7 +133,7 @@ namespace Knx interrupts(); } - void SamdPlatform::flashWritePage(uint16_t pageNumber, uint8_t* data) + void Samd21Platform::flashWritePage(uint16_t pageNumber, uint8_t* data) { noInterrupts(); @@ -152,7 +143,7 @@ namespace Knx interrupts(); } - void SamdPlatform::writeBufferedEraseBlock() + void Samd21Platform::writeBufferedEraseBlock() { if (_bufferedEraseblockNumber > -1 && _bufferedEraseblockDirty) { @@ -169,12 +160,12 @@ namespace Knx } } - uint32_t SamdPlatform::getRowAddr(uint32_t flasAddr) + uint32_t Samd21Platform::getRowAddr(uint32_t flasAddr) { return flasAddr & ~(_rowSize - 1); } - void SamdPlatform::write(const volatile void* flash_ptr, const void* data, uint32_t size) + void Samd21Platform::write(const volatile void* flash_ptr, const void* data, uint32_t size) { // Calculate data boundaries size = (size + 3) / 4; @@ -216,7 +207,7 @@ namespace Knx } } - void SamdPlatform::erase(const volatile void* flash_ptr, uint32_t size) + void Samd21Platform::erase(const volatile void* flash_ptr, uint32_t size) { const uint8_t* ptr = (const uint8_t*)flash_ptr; @@ -230,7 +221,7 @@ namespace Knx eraseRow(ptr); } - void SamdPlatform::eraseRow(const volatile void* flash_ptr) + void Samd21Platform::eraseRow(const volatile void* flash_ptr) { NVMCTRL->ADDR.reg = ((uint32_t)flash_ptr) / 2; NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_ER; diff --git a/src/knx/platform/samd_platform.h b/src/knx/platform/samd21_platform.h similarity index 91% rename from src/knx/platform/samd_platform.h rename to src/knx/platform/samd21_platform.h index 7b32f51..c27d258 100644 --- a/src/knx/platform/samd_platform.h +++ b/src/knx/platform/samd21_platform.h @@ -2,17 +2,16 @@ #include "Arduino.h" -#ifdef ARDUINO_ARCH_SAMD - +#if defined(_SAMD21_) #define PAGES_PER_ROW 4 namespace Knx { - class SamdPlatform : public ArduinoPlatform + class Samd21Platform : public ArduinoPlatform { public: - SamdPlatform(); - SamdPlatform( HardwareSerial* s); + Samd21Platform(); + Samd21Platform( HardwareSerial* s); // unique serial number uint32_t uniqueSerialNumber() override; diff --git a/src/knx/platform/samd51_platform.cpp b/src/knx/platform/samd51_platform.cpp new file mode 100644 index 0000000..81e3e17 --- /dev/null +++ b/src/knx/platform/samd51_platform.cpp @@ -0,0 +1,363 @@ +#include "samd51_platform.h" + +#ifdef __SAMD51__ + +#include +#include + +#if KNX_FLASH_SIZE % 1024 + #error "KNX_FLASH_SIZE must be multiple of 1024" +#endif + +#ifndef KNX_SERIAL + #define KNX_SERIAL Serial1 +#endif + +extern uint32_t __etext; +extern uint32_t __data_start__; +extern uint32_t __data_end__; + +namespace Knx +{ + Samd51Platform::Samd51Platform() +#ifndef KNX_NO_DEFAULT_UART + : ArduinoPlatform(&KNX_SERIAL) +#endif + { + init(); + } + + Samd51Platform::Samd51Platform( HardwareSerial* s) : ArduinoPlatform(s) + { + init(); + } + + uint32_t Samd51Platform::uniqueSerialNumber() + { + // SAMD51 from section 9.6 of the datasheet +#define SERIAL_NUMBER_WORD_0 *(volatile uint32_t*)(0x008061FC) +#define SERIAL_NUMBER_WORD_1 *(volatile uint32_t*)(0x00806010) +#define SERIAL_NUMBER_WORD_2 *(volatile uint32_t*)(0x00806014) +#define SERIAL_NUMBER_WORD_3 *(volatile uint32_t*)(0x00806018) + + return SERIAL_NUMBER_WORD_0 ^ SERIAL_NUMBER_WORD_1 ^ SERIAL_NUMBER_WORD_2 ^ SERIAL_NUMBER_WORD_3; + } + + void Samd51Platform::restart() + { + println("restart"); + NVIC_SystemReset(); + } + +#if USE_W5X00 == 1 + + uint32_t Samd51Platform::currentIpAddress() + { + // IPAddress _ip = Ethernet.localIP(); + // _ipAddress = htonl(_ip); + // return _ipAddress; + + return Ethernet.localIP(); + + // _ipAddress = 0x0A063232; + // return _ipAddress; + + // return 0x0A063232; + } + + uint32_t Samd51Platform::currentSubnetMask() + { + // IPAddress _nm = Ethernet.subnetMask(); + // _netmask = htonl(_nm); + // return _netmask; + + return Ethernet.subnetMask(); + + // _netmask = 0xFFFFFF00; + // return _netmask; + + // return 0xFFFFFF00; + } + + uint32_t Samd51Platform::currentDefaultGateway() + { + // IPAddress _gw = Ethernet.gatewayIP(); + // _defaultGateway = htonl(_gw); + // return _defaultGateway; + + return Ethernet.gatewayIP(); + + // _defaultGateway = 0x0A063201; + // return _defaultGateway; + + // return 0x0A063201; + } + + void Samd51Platform::macAddress(uint8_t* mac_address) + { + //Ethernet.macAddress(mac_address); //try this first, not sure if this will work, is for ethernet3 lib + memcpy(mac_address, _macAddress, sizeof(_macAddress) / sizeof(_macAddress[0])); //sizeof should resolve to be just 6 + } + + void Samd51Platform::setupMultiCast(uint32_t addr, uint16_t port) + { + IPAddress _mcastaddr(htonl(addr)); + + KNX_DEBUG_SERIAL.printf("setup multicast on %d.%d.%d.%d:%d\n", _mcastaddr[0], _mcastaddr[1], _mcastaddr[2], _mcastaddr[3], port); + uint8_t result = _udp.beginMulticast(_multicastAddr, _multicastPort); + KNX_DEBUG_SERIAL.printf("result %d\n", result); + } + + void Samd51Platform::closeMultiCast() + { + _udp.stop(); + } + + bool Samd51Platform::sendBytesMultiCast(uint8_t* buffer, uint16_t len) + { + //printHex("<- ",buffer, len); + _udp.beginPacket(_multicastAddr, _multicastPort); + _udp.write(buffer, len); + _udp.endPacket(); + return true; + } + + int Samd51Platform::readBytesMultiCast(uint8_t* buffer, uint16_t maxLen) + { + int len = _udp.parsePacket(); + + if (len == 0) + return 0; + + if (len > maxLen) + { + KNX_DEBUG_SERIAL.printf("udp buffer to small. was %d, needed %d\n", maxLen, len); + fatalError(); + } + + _udp.read(buffer, len); + printHex("-> ", buffer, len); + return len; + } + + bool Samd51Platform::sendBytesUniCast(uint32_t addr, uint16_t port, uint8_t* buffer, uint16_t len) + { + IPAddress ucastaddr(htonl(addr)); + println("sendBytesUniCast endPacket fail"); + + if (_udp.beginPacket(ucastaddr, port) == 1) + { + _udp.write(buffer, len); + + if (_udp.endPacket() == 0) + println("sendBytesUniCast endPacket fail"); + } + else + println("sendBytesUniCast beginPacket fail"); + + return true; + } + +#endif + + static const uint32_t pageSizes[] = {8, 16, 32, 64, 128, 256, 512, 1024}; + + void Samd51Platform::init() + { + // println("Entered Init .h variables active, rest and .cpp commented"); + + // #if USE_W5X00 == 1 + // IPAddress _ip = Ethernet.localIP(); + // _ipAddress = htonl(_ip); + // _ip = Ethernet.subnetMask(); + // _netmask = htonl(_ip); + // _ip = Ethernet.gatewayIP(); + // _defaultGateway = htonl(_ip); + // #endif + + _memoryType = Flash; + _pageSize = pageSizes[NVMCTRL->PARAM.bit.PSZ]; + _pageCnt = NVMCTRL->PARAM.bit.NVMP; + _rowSize = (_pageSize * _pageCnt / 64); + + //find end of program flash and set limit to next row + uint32_t endEddr = (uint32_t)(&__etext + (&__data_end__ - &__data_start__)); // text + data MemoryBlock + _MemoryStart = getRowAddr(_pageSize * _pageCnt - KNX_FLASH_SIZE - 1); // 23295 + _MemoryEnd = getRowAddr(_pageSize * _pageCnt - 1); + + //chosen flash size is not available anymore + if (_MemoryStart < endEddr) + { + println("KNX_FLASH_SIZE is not available (possible too much flash use by firmware)"); + fatalError(); + } + } + + // Invalidate all CMCC cache entries if CMCC cache is enabled. + static void invalidate_CMCC_cache() + { + if (CMCC->SR.bit.CSTS) + { + CMCC->CTRL.bit.CEN = 0; + + while (CMCC->SR.bit.CSTS) {} + + CMCC->MAINT0.bit.INVALL = 1; + CMCC->CTRL.bit.CEN = 1; + } + } + + static inline uint32_t read_unaligned_uint32(volatile void* data) + { + union + { + uint32_t u32; + uint8_t u8[4]; + } res; + const uint8_t* d = (const uint8_t*)data; + res.u8[0] = d[0]; + res.u8[1] = d[1]; + res.u8[2] = d[2]; + res.u8[3] = d[3]; + return res.u32; + } + + size_t Samd51Platform::flashEraseBlockSize() + { + return (_pageSize / 64); //PAGES_PER_ROW; + } + + size_t Samd51Platform::flashPageSize() + { + return _pageSize; + } + + uint8_t* Samd51Platform::userFlashStart() + { + return (uint8_t*)_MemoryStart; + } + + size_t Samd51Platform::userFlashSizeEraseBlocks() + { + if (KNX_FLASH_SIZE <= 0) + return 0; + else + return ((KNX_FLASH_SIZE - 1) / (flashPageSize() * flashEraseBlockSize())) + 1; + } + + void Samd51Platform::flashErase(uint16_t eraseBlockNum) + { + noInterrupts(); + + eraseRow((void*)(_MemoryStart + eraseBlockNum * _rowSize)); + // flash_range_erase(KNX_FLASH_OFFSET + eraseBlockNum * flashPageSize() * flashEraseBlockSize(), flashPageSize() * flashEraseBlockSize()); + + interrupts(); + } + + void Samd51Platform::flashWritePage(uint16_t pageNumber, uint8_t* data) + { + noInterrupts(); + + write((void*)(_MemoryStart + pageNumber * _pageSize), data, _pageSize); + // flash_range_program(KNX_FLASH_OFFSET + pageNumber * flashPageSize(), data, flashPageSize()); + + interrupts(); + } + + void Samd51Platform::writeBufferedEraseBlock() + { + if (_bufferedEraseblockNumber > -1 && _bufferedEraseblockDirty) + { + noInterrupts(); + + eraseRow((void*)(_MemoryStart + _bufferedEraseblockNumber * _rowSize)); + write((void*)(_MemoryStart + _bufferedEraseblockNumber * _rowSize), _eraseblockBuffer, _rowSize); + // flash_range_erase(KNX_FLASH_OFFSET + _bufferedEraseblockNumber * flashPageSize() * flashEraseBlockSize(), flashPageSize() * flashEraseBlockSize()); + // flash_range_program(KNX_FLASH_OFFSET + _bufferedEraseblockNumber * flashPageSize() * flashEraseBlockSize(), _eraseblockBuffer, flashPageSize() * flashEraseBlockSize()); + + interrupts(); + + _bufferedEraseblockDirty = false; + } + } + + uint32_t Samd51Platform::getRowAddr(uint32_t flasAddr) + { + return flasAddr & ~(_rowSize - 1); + } + + void Samd51Platform::write(const volatile void* flash_ptr, const void* data, uint32_t size) + { + // Calculate data boundaries + size = (size + 3) / 4; + volatile uint32_t* src_addr = (volatile uint32_t*)data; + volatile uint32_t* dst_addr = (volatile uint32_t*)flash_ptr; + + // Disable automatic page write + NVMCTRL->CTRLA.bit.WMODE = 0; + + while (NVMCTRL->STATUS.bit.READY == 0) { } + + // Disable NVMCTRL cache while writing, per SAMD51 errata. + bool original_CACHEDIS0 = NVMCTRL->CTRLA.bit.CACHEDIS0; + bool original_CACHEDIS1 = NVMCTRL->CTRLA.bit.CACHEDIS1; + NVMCTRL->CTRLA.bit.CACHEDIS0 = true; + NVMCTRL->CTRLA.bit.CACHEDIS1 = true; + + // Do writes in pages + while (size) + { + // Execute "PBC" Page Buffer Clear + NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMDEX_KEY | NVMCTRL_CTRLB_CMD_PBC; + + while (NVMCTRL->INTFLAG.bit.DONE == 0) { } + + // Fill page buffer + uint32_t i; + + for (i = 0; i < (_pageSize / 4) && size; i++) + { + *dst_addr = read_unaligned_uint32(src_addr); + src_addr += 4; + dst_addr++; + size--; + } + + // Execute "WP" Write Page + NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMDEX_KEY | NVMCTRL_CTRLB_CMD_WP; + + while (NVMCTRL->INTFLAG.bit.DONE == 0) { } + + invalidate_CMCC_cache(); + // Restore original NVMCTRL cache settings. + NVMCTRL->CTRLA.bit.CACHEDIS0 = original_CACHEDIS0; + NVMCTRL->CTRLA.bit.CACHEDIS1 = original_CACHEDIS1; + } + } + + void Samd51Platform::erase(const volatile void* flash_ptr, uint32_t size) + { + const uint8_t* ptr = (const uint8_t*)flash_ptr; + + while (size > _rowSize) + { + eraseRow(ptr); + ptr += _rowSize; + size -= _rowSize; + } + + eraseRow(ptr); + } + + void Samd51Platform::eraseRow(const volatile void* flash_ptr) + { + NVMCTRL->ADDR.reg = ((uint32_t)flash_ptr); + NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMDEX_KEY | NVMCTRL_CTRLB_CMD_EB; + + while (!NVMCTRL->INTFLAG.bit.DONE) { } + + invalidate_CMCC_cache(); + } +} +#endif diff --git a/src/knx/platform/samd51_platform.h b/src/knx/platform/samd51_platform.h new file mode 100644 index 0000000..b72ff67 --- /dev/null +++ b/src/knx/platform/samd51_platform.h @@ -0,0 +1,79 @@ +#include +#include "arduino_platform.h" + +#ifdef __SAMD51__ +#include +#include +#include + +namespace Knx +{ + class Samd51Platform : public ArduinoPlatform + { + public: + Samd51Platform(); + Samd51Platform( HardwareSerial* s); + + // unique serial number + uint32_t uniqueSerialNumber() override; + + void restart(); + +#if USE_W5X00 == 1 + // ip config + uint32_t currentIpAddress() override; + uint32_t currentSubnetMask() override; + uint32_t currentDefaultGateway() override; + void macAddress(uint8_t* data) override; + + //multicast + void setupMultiCast(uint32_t addr, uint16_t port) override; + void closeMultiCast() override; + bool sendBytesMultiCast(uint8_t* buffer, uint16_t len) override; + int readBytesMultiCast(uint8_t* buffer, uint16_t maxLen) override; + + bool sendBytesUniCast(uint32_t addr, uint16_t port, uint8_t* buffer, uint16_t len) override; +#endif + + // size of one EraseBlock in pages + virtual size_t flashEraseBlockSize(); + // size of one flash page in bytes + virtual size_t flashPageSize(); + // start of user flash aligned to start of an erase block + virtual uint8_t* userFlashStart(); + // size of the user flash in EraseBlocks + virtual size_t userFlashSizeEraseBlocks(); + // relativ to userFlashStart + virtual void flashErase(uint16_t eraseBlockNum); + // write a single page to flash (pageNumber relative to userFashStart + virtual void flashWritePage(uint16_t pageNumber, uint8_t* data); + + // writes _eraseblockBuffer to flash - overrides Plattform::writeBufferedEraseBlock() for performance optimization only + void writeBufferedEraseBlock(); + + private: + void init(); + uint32_t _MemoryEnd = 0; + uint32_t _MemoryStart = 0; + uint32_t _pageSize; + uint32_t _rowSize; + uint32_t _pageCnt; + + uint32_t getRowAddr(uint32_t flasAddr); + void write(const volatile void* flash_ptr, const void* data, uint32_t size); + void erase(const volatile void* flash_ptr, uint32_t size); + void eraseRow(const volatile void* flash_ptr); + +#if USE_W5X00 == 1 + uint8_t _macAddress[6] = {0xC0, 0xFF, 0xEE, 0xC0, 0xDE, 0x00}; + uint32_t _ipAddress = 0; + uint32_t _netmask = 0; + uint32_t _defaultGateway = 0; + + uint32_t _multicastAddr = -1; + uint16_t _multicastPort = -1; + EthernetUDP _udp; +#endif + }; +} +#endif