mirror of
https://github.com/thelsing/knx.git
synced 2024-12-18 19:08:18 +01:00
Squashed commit of the following:
commit043ba081ff
Merge:eb0d626
277a5d5
Author: OnlineCaveman <115506475+OnlineCaveman@users.noreply.github.com> Date: Fri Oct 28 22:09:18 2022 +0200 Merge branch 'w5500' commit277a5d57fa
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 commitcf44c4efe9
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. commit187ab2e9f1
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 commiteb0d62666d
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 commitb0238cfe7e
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 commitd24f6de36f
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. commit7373ab0a87
Author: OnlineCaveman <115506475+OnlineCaveman@users.noreply.github.com> Date: Tue Oct 25 16:19:53 2022 +0200 No IP version yet commit76762571ea
Author: OnlineCaveman <115506475+OnlineCaveman@users.noreply.github.com> Date: Tue Oct 25 15:56:34 2022 +0200 Ifdef include requested change commit02565a0ba3
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. commit598f6bddfd
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 commit37e056a91c
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 commitb403480f0c
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 commitc0e5621a5f
Author: OnlineCaveman <115506475+OnlineCaveman@users.noreply.github.com> Date: Mon Oct 17 19:52:10 2022 +0200 Rename back to original commit6c4a10e189
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 commitb8107fd62d
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. commit4248a1f073
Author: OnlineCaveman <115506475+OnlineCaveman@users.noreply.github.com> Date: Sat Oct 15 16:15:32 2022 +0200 Updated for samd51 flash storage compatibility
This commit is contained in:
parent
ae60d24b68
commit
a510042e78
5
examples/knx-demo/.gitignore
vendored
Normal file
5
examples/knx-demo/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
.pio
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/ipch
|
@ -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]
|
||||
|
@ -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
|
||||
|
12
src/knx.h
12
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]]
|
||||
|
@ -44,16 +44,27 @@ ICACHE_RAM_ATTR void buttonEvent()
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ARDUINO_ARCH_SAMD
|
||||
#ifdef __SAMD51__
|
||||
// predefined global instance for TP or RF
|
||||
#if MASK_VERSION == 0x07B0
|
||||
Knx::KnxFacade<Knx::Samd51Platform, Knx::Bau07B0> knx(buttonEvent);
|
||||
#elif MASK_VERSION == 0x27B0
|
||||
Knx::KnxFacade<Knx::Samd51Platform, Knx::Bau2920> knx(buttonEvent);
|
||||
#elif MASK_VERSION == 0x57B0
|
||||
Knx::KnxFacade<Knx::Samd51Platform, Knx::Bau57B0> 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::SamdPlatform, Knx::Bau07B0> knx(buttonEvent);
|
||||
Knx::KnxFacade<Knx::Samd21Platform, Knx::Bau07B0> knx(buttonEvent);
|
||||
#elif MASK_VERSION == 0x27B0
|
||||
Knx::KnxFacade<Knx::SamdPlatform, Knx::Bau27B0> knx(buttonEvent);
|
||||
Knx::KnxFacade<Knx::Samd21Platform, Knx::Bau27B0> knx(buttonEvent);
|
||||
#elif MASK_VERSION == 0x2920
|
||||
Knx::KnxFacade<Knx::SamdPlatform, Knx::Bau2920> knx(buttonEvent);
|
||||
Knx::KnxFacade<Knx::Samd21Platform, Knx::Bau2920> knx(buttonEvent);
|
||||
#else
|
||||
#error "Mask version not supported on ARDUINO_ARCH_SAMD"
|
||||
#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
|
||||
|
@ -14,8 +14,10 @@
|
||||
#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"
|
||||
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||
@ -462,14 +464,25 @@ namespace Knx
|
||||
};
|
||||
}
|
||||
#ifndef KNX_NO_AUTOMATIC_GLOBAL_INSTANCE
|
||||
#ifdef ARDUINO_ARCH_SAMD
|
||||
#ifdef __SAMD51__
|
||||
// predefined global instance for TP or RF
|
||||
#if MASK_VERSION == 0x07B0
|
||||
extern Knx::KnxFacade<Knx::Samd51Platform, Knx::Bau07B0> knx;
|
||||
#elif MASK_VERSION == 0x27B0
|
||||
extern Knx::KnxFacade<Knx::Samd51Platform, Knx::Bau2920> knx;
|
||||
#elif MASK_VERSION == 0x57B0
|
||||
extern Knx::KnxFacade<Knx::Samd51Platform, Knx::Bau57B0> 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::SamdPlatform, Knx::Bau07B0> knx;
|
||||
extern Knx::KnxFacade<Knx::Samd21Platform, Knx::Bau07B0> knx;
|
||||
#elif MASK_VERSION == 0x27B0
|
||||
extern Knx::KnxFacade<Knx::SamdPlatform, Knx::Bau27B0> knx;
|
||||
extern Knx::KnxFacade<Knx::Samd21Platform, Knx::Bau27B0> knx;
|
||||
#elif MASK_VERSION == 0x2920
|
||||
extern Knx::KnxFacade<Knx::SamdPlatform, Knx::Bau2920> knx;
|
||||
extern Knx::KnxFacade<Knx::Samd21Platform, Knx::Bau2920> knx;
|
||||
#else
|
||||
#error "Mask version not supported on ARDUINO_ARCH_SAMD"
|
||||
#endif
|
||||
|
@ -1,6 +1,5 @@
|
||||
#ifdef ARDUINO_ARCH_SAMD
|
||||
#include "samd_platform.h"
|
||||
|
||||
#include "samd21_platform.h"
|
||||
#if defined(_SAMD21_)
|
||||
#include <knx/bits.h>
|
||||
|
||||
#include <Arduino.h>
|
||||
@ -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;
|
@ -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;
|
363
src/knx/platform/samd51_platform.cpp
Normal file
363
src/knx/platform/samd51_platform.cpp
Normal file
@ -0,0 +1,363 @@
|
||||
#include "samd51_platform.h"
|
||||
|
||||
#ifdef __SAMD51__
|
||||
|
||||
#include <knx/bits.h>
|
||||
#include <Arduino.h>
|
||||
|
||||
#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
|
79
src/knx/platform/samd51_platform.h
Normal file
79
src/knx/platform/samd51_platform.h
Normal file
@ -0,0 +1,79 @@
|
||||
#include <Arduino.h>
|
||||
#include "arduino_platform.h"
|
||||
|
||||
#ifdef __SAMD51__
|
||||
#include <SPI.h>
|
||||
#include <Ethernet.h>
|
||||
#include <EthernetUdp.h>
|
||||
|
||||
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
|
Loading…
Reference in New Issue
Block a user