From fffb25bbb007332a2e254b709476ebee2f0286a8 Mon Sep 17 00:00:00 2001 From: Andrea Salvatori - IU6FZL Date: Mon, 4 Mar 2019 11:03:20 +0100 Subject: [PATCH] Advanced configurations to enter in DeepSleep Co-authored-by: an4cr0n --- .../StandardRTLSTag_TWR.ino | 13 +++++ keywords.txt | 7 +-- src/DW1000Ng.cpp | 49 ++++++++++++------- src/DW1000Ng.hpp | 12 ++++- src/DW1000NgConfiguration.hpp | 13 ++++- src/DW1000NgRegisters.hpp | 9 ++-- 6 files changed, 76 insertions(+), 27 deletions(-) diff --git a/examples/StandardRTLSTag_TWR/StandardRTLSTag_TWR.ino b/examples/StandardRTLSTag_TWR/StandardRTLSTag_TWR.ino index f183f1a4..26fed779 100644 --- a/examples/StandardRTLSTag_TWR/StandardRTLSTag_TWR.ino +++ b/examples/StandardRTLSTag_TWR/StandardRTLSTag_TWR.ino @@ -54,6 +54,17 @@ frame_filtering_configuration_t TAG_FRAME_FILTER_CONFIG = { false }; +sleep_configuration_t SLEEP_CONFIG = { + false, // onWakeUpRunADC reg 0x2C:00 + false, // onWakeUpReceive + false, // onWakeUpLoadEUI + true, // onWakeUpLoadL64Param + true, // preserveSleep + true, // enableSLP reg 0x2C:06 + false, // enableWakePIN + true // enableWakeSPI +}; + void setup() { // DEBUG monitoring Serial.begin(115200); @@ -75,6 +86,8 @@ void setup() { DW1000Ng::setAntennaDelay(16436); + DW1000Ng::applySleepConfiguration(SLEEP_CONFIG); + DW1000Ng::setPreambleDetectionTimeout(15); DW1000Ng::setSfdDetectionTimeout(273); DW1000Ng::setReceiveFrameWaitTimeoutPeriod(2000); diff --git a/keywords.txt b/keywords.txt index 7455e95a..a275b934 100644 --- a/keywords.txt +++ b/keywords.txt @@ -20,9 +20,10 @@ select KEYWORD2 end KEYWORD2 enableDebounceClock KEYWORD2 enableLedBlinking KEYWORD2 -setGPIOMode KEYWORD2 -deepSleep KEYWORD2 -spiWakeup KEYWORD2 +setGPIOMode KEYWORD2 +applySleepConfiguration KEYWORD2 +deepSleep KEYWORD2 +spiWakeup KEYWORD2 reset KEYWORD2 softwareReset KEYWORD2 setNetworkId KEYWORD2 diff --git a/src/DW1000Ng.cpp b/src/DW1000Ng.cpp index 3e727c73..8523ca94 100644 --- a/src/DW1000Ng.cpp +++ b/src/DW1000Ng.cpp @@ -1194,6 +1194,13 @@ namespace DW1000Ng { DW1000NgUtils::writeValueToBytes(enable_mask, 0x005FFF00, LEN_RX_CONF_SUB); _writeBytesToRegister(RF_CONF, RF_CONF_SUB, enable_mask, LEN_RX_CONF_SUB); } + + void _uploadConfigToAON() { + /* Write 1 in UPL_CFG_BIT */ + _writeToRegister(AON, AON_CTRL_SUB, 0x04, LEN_AON_CTRL); + /* Clear the register */ + _writeToRegister(AON, AON_CTRL_SUB, 0x00, LEN_AON_CTRL); + } } /* ####################### PUBLIC ###################### */ @@ -1388,31 +1395,35 @@ namespace DW1000Ng { _writeBytesToRegister(GPIO_CTRL, GPIO_MODE_SUB, gpiomode, LEN_GPIO_MODE); } - void deepSleep() { + void applySleepConfiguration(sleep_configuration_t sleep_config) { byte aon_wcfg[LEN_AON_WCFG]; - memset(aon_wcfg, 0, LEN_AON_WCFG); _readBytes(AON, AON_WCFG_SUB, aon_wcfg, LEN_AON_WCFG); + byte aon_cfg0[1]; + memset(aon_cfg0, 0, 1); + + DW1000NgUtils::setBit(aon_wcfg, LEN_AON_WCFG, ONW_RADC_BIT, sleep_config.onWakeUpRunADC); + DW1000NgUtils::setBit(aon_wcfg, LEN_AON_WCFG, ONW_RX_BIT, sleep_config.onWakeUpReceive); + DW1000NgUtils::setBit(aon_wcfg, LEN_AON_WCFG, ONW_LEUI_BIT, sleep_config.onWakeUpLoadEUI); DW1000NgUtils::setBit(aon_wcfg, LEN_AON_WCFG, ONW_LDC_BIT, true); - DW1000NgUtils::setBit(aon_wcfg, LEN_AON_WCFG, ONW_PRES_SLEEP_BIT, false); + DW1000NgUtils::setBit(aon_wcfg, LEN_AON_WCFG, ONW_L64P_BIT, sleep_config.onWakeUpLoadL64Param); + DW1000NgUtils::setBit(aon_wcfg, LEN_AON_WCFG, ONW_PRES_SLEEP_BIT, sleep_config.preserveSleep); DW1000NgUtils::setBit(aon_wcfg, LEN_AON_WCFG, ONW_LLDE_BIT, true); - DW1000NgUtils::setBit(aon_wcfg, LEN_AON_WCFG, ONW_LDD0_BIT, true); + DW1000NgUtils::setBit(aon_wcfg, LEN_AON_WCFG, ONW_LLDO_BIT, true); _writeBytesToRegister(AON, AON_WCFG_SUB, aon_wcfg, LEN_AON_WCFG); - byte aon_cfg0[LEN_AON_CFG0]; - memset(aon_cfg0, 0, LEN_AON_CFG0); - _readBytes(AON, AON_CFG0_SUB, aon_cfg0, LEN_AON_CFG0); - DW1000NgUtils::setBit(aon_cfg0, LEN_AON_CFG0, WAKE_PIN_BIT, true); - DW1000NgUtils::setBit(aon_cfg0, LEN_AON_CFG0, WAKE_SPI_BIT, true); - DW1000NgUtils::setBit(aon_cfg0, LEN_AON_CFG0, WAKE_CNT_BIT, false); - DW1000NgUtils::setBit(aon_cfg0, LEN_AON_CFG0, SLEEP_EN_BIT, true); - _writeBytesToRegister(AON, AON_CFG0_SUB, aon_cfg0, LEN_AON_CFG0); - - byte aon_ctrl[LEN_AON_CTRL]; - memset(aon_ctrl, 0, LEN_AON_CTRL); - _readBytes(AON, AON_CTRL_SUB, aon_ctrl, LEN_AON_CTRL); - //DW1000NgUtils::setBit(aon_ctrl, LEN_AON_CTRL, UPL_CFG_BIT, true); - DW1000NgUtils::setBit(aon_ctrl, LEN_AON_CTRL, SAVE_BIT, true); - _writeBytesToRegister(AON, AON_CTRL_SUB, aon_ctrl, LEN_AON_CTRL); + DW1000NgUtils::setBit(aon_cfg0, 1, WAKE_PIN_BIT, sleep_config.enableWakePIN); + DW1000NgUtils::setBit(aon_cfg0, 1, WAKE_SPI_BIT, sleep_config.enableWakeSPI); + DW1000NgUtils::setBit(aon_cfg0, 1, WAKE_CNT_BIT, false); + DW1000NgUtils::setBit(aon_cfg0, 1, SLEEP_EN_BIT, sleep_config.enableSLP); + _writeBytesToRegister(AON, AON_CFG0_SUB, aon_cfg0, 1); //Deletes 3 bits of the unused LPCLKDIVA + } + + /*Puts the device into sleep/deepSleep mode. This function also upload sleep config to AON. */ + void deepSleep() { + /* Clear the register */ + _writeToRegister(AON, AON_CTRL_SUB, 0x00, LEN_AON_CTRL); + /* Write 1 in SAVE_BIT */ + _writeToRegister(AON, AON_CTRL_SUB, 0x02, LEN_AON_CTRL); } void spiWakeup(){ diff --git a/src/DW1000Ng.hpp b/src/DW1000Ng.hpp index cbe41092..2b441ca8 100644 --- a/src/DW1000Ng.hpp +++ b/src/DW1000Ng.hpp @@ -87,7 +87,17 @@ namespace DW1000Ng { void setGPIOMode(uint8_t msgp, uint8_t mode); /** - Enable deep sleep mode + Applies the common sleep configuration and on-wake mode to the DW1000 for both DEEP_SLEEP and SLEEP modes. + ONW_LLDO_BIT and ONW_LLDE_BIT are 1 to default. + + @param [in] config struct The sleep/deepsleep configuration to apply to the DW1000 + */ + void applySleepConfiguration(sleep_configuration_t sleep_config); + + /** + Enter in DeepSleep. applySleepConfiguration must be called first. + Either spi wakeup or pin wakeup must be enabled. + -- In case of future implementation of Sleep mode, you must reset proper antenna delay with setTxAntennaDelay() after wakeUp event. -- */ void deepSleep(); diff --git a/src/DW1000NgConfiguration.hpp b/src/DW1000NgConfiguration.hpp index 9a8a7b93..53622384 100644 --- a/src/DW1000NgConfiguration.hpp +++ b/src/DW1000NgConfiguration.hpp @@ -59,4 +59,15 @@ typedef struct frame_filtering_configuration_t { boolean allowAllReserved; boolean allowReservedFour; boolean allowReservedFive; -} frame_filtering_configuration_t; \ No newline at end of file +} frame_filtering_configuration_t; + +typedef struct sleep_configuration_t { + boolean onWakeUpRunADC; + boolean onWakeUpReceive; + boolean onWakeUpLoadEUI; + boolean onWakeUpLoadL64Param; + boolean preserveSleep; + boolean enableSLP; + boolean enableWakePIN; + boolean enableWakeSPI; +} sleep_configuration_t; \ No newline at end of file diff --git a/src/DW1000NgRegisters.hpp b/src/DW1000NgRegisters.hpp index 52d4e146..87b7f407 100644 --- a/src/DW1000NgRegisters.hpp +++ b/src/DW1000NgRegisters.hpp @@ -299,11 +299,14 @@ constexpr uint16_t LEN_FS_XTALT = 1; // AON constexpr uint16_t AON = 0x2C; constexpr uint16_t AON_WCFG_SUB = 0x00; -constexpr uint16_t ONW_RX = 1; +constexpr uint16_t ONW_RADC_BIT = 0; +constexpr uint16_t ONW_RX_BIT = 1; +constexpr uint16_t ONW_LEUI_BIT = 3; constexpr uint16_t ONW_LDC_BIT = 6; +constexpr uint16_t ONW_L64P_BIT = 7; constexpr uint16_t ONW_PRES_SLEEP_BIT = 8; constexpr uint16_t ONW_LLDE_BIT = 11; -constexpr uint16_t ONW_LDD0_BIT = 12; +constexpr uint16_t ONW_LLDO_BIT = 12; constexpr uint16_t LEN_AON_WCFG = 2; constexpr uint16_t AON_CTRL_SUB = 0x02; @@ -321,7 +324,7 @@ constexpr uint16_t LPDIV_EN_BIT = 4; constexpr uint16_t LEN_AON_CFG0 = 4; constexpr uint16_t AON_CFG1_SUB = 0x0A; -constexpr uint16_t SLEEP_CE_BIT = 0; +constexpr uint16_t SLEEP_CEN_BIT = 0; constexpr uint16_t SMXX_BIT = 1; constexpr uint16_t LPOSC_CAL_BIT = 2; constexpr uint16_t LEN_AON_CFG1 = 2;