This is an automated email from the ASF dual-hosted git repository.

wes3 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git


The following commit(s) were added to refs/heads/master by this push:
     new ee51a8c  Implement low-power support in the LoRa stack (#1670)
ee51a8c is described below

commit ee51a8cf8d099a2641e971a17776af90c78e6287
Author: amrbekhit <amrbek...@gmail.com>
AuthorDate: Tue May 14 07:03:36 2019 +0300

    Implement low-power support in the LoRa stack (#1670)
    
    * Implement low-power support in the LoRa stack and modify the nRF timer 
code to use the HFXO manager.
    
    Use of timers in the LoRa stack has been split into critical and 
non-critial timers. Non-critical timers (such as retry delays) are now 
implemented using the os_cputime functions. The
    os_cputime needs to be configured to use a lower power time in the BSP 
(such as is done by the BLE stack via the BLE_LP_CLOCK syscfg). Critical timers 
are only used to time the opening of
    the RX windows. These continue to use the hal_timer functions, but require 
that the user implements two callback functions (lora_low_power_enter and 
lora_low_power_exit) to turn the
    LORA_MAC_TIMER off and on. This is necessary as turning a timer on is a 
hardware-specific operation that may require that the caller pass in a custom 
configuration struct.
    
    This patch also modifies the nRF timer code to use the HFXO manager found 
in hw/mcu/nordic/nrf52xxx/src/nrf5x_clock.c. This allows multiple different 
timers to be turned on and off
    independently and manager will automatically turn the nRF HFXO on and off 
as required. This is necessary in order for the LoRa and BLE stacks to be able 
to run side by side.
    
    * Correct HFXO manager header files.
    
    * Correct calls to to HFXO manager.
    
    * Correct HFXO manager header.
    
    * Make SX1272 DIO3 IRQ optional.
    
    The SX1272 DIO3 IRQ is used during Carrier Detect (CAD). This is neither 
necessary for LoRa operation, nor used in the current driver. Therefore, by 
making this pin optional, an extra GPIO/IRQ can be freed for other tasks.
    
    * -Fixed a bug when calculating the delays for the TX retry timer 
(https://github.com/apache/mynewt-core/pull/1670#discussion_r266275964).
    -Resolved minor formatting issues.
    
    * -Reverted the HFXO changes in the hal_system and hal_timer files. These 
will be added to a separate pull request.
    
    * -Modified the low power callbacks so that there is only one rather than 
two: lora_bsp_enable_mac_timer. This is because the hal_timer functions already 
allow application code to disable timers in a hardware-agnostic fashion using
    the hal_timer_deinit function. The LoRa code now turns the timer off 
itself, but requires the BSP to implement lora_bsp_enable_mac_timer in order to 
turn the timer on.
    
    * -Modified the b-l072z-lrwan1 and telee02 BSPs to implement the 
lora_bsp_enable_mac_timer function in order to allow CI to pass.
---
 hw/bsp/b-l072z-lrwan1/src/hal_bsp.c      | 19 ++++++++
 hw/bsp/telee02/src/hal_bsp.c             |  9 ++++
 hw/drivers/lora/include/lora/utilities.h |  8 ---
 hw/drivers/lora/src/utilities.c          | 16 ++----
 hw/drivers/lora/sx1272/src/sx1272.c      | 84 ++++++++++++++++----------------
 hw/drivers/lora/sx1276/src/sx1276.c      | 74 +++++++++++++---------------
 net/lora/node/include/node/lora.h        |  1 -
 net/lora/node/include/node/lora_priv.h   |  8 +++
 net/lora/node/include/node/utilities.h   |  8 ---
 net/lora/node/src/lora_cli.c             | 12 +++++
 net/lora/node/src/lora_node.c            | 28 ++++++++++-
 net/lora/node/src/mac/LoRaMac.c          | 56 +++++++++++++--------
 net/lora/node/src/utilities.c            |  6 ---
 net/lora/node/syscfg.yml                 |  5 ++
 14 files changed, 196 insertions(+), 138 deletions(-)

diff --git a/hw/bsp/b-l072z-lrwan1/src/hal_bsp.c 
b/hw/bsp/b-l072z-lrwan1/src/hal_bsp.c
index a352ae3..46a5281 100644
--- a/hw/bsp/b-l072z-lrwan1/src/hal_bsp.c
+++ b/hw/bsp/b-l072z-lrwan1/src/hal_bsp.c
@@ -175,3 +175,22 @@ hal_bsp_get_nvic_priority(int irq_num, uint32_t pri)
     /* Add any interrupt priorities configured by the bsp here */
     return pri;
 }
+
+#if MYNEWT_VAL(LORA_NODE)
+void lora_bsp_enable_mac_timer(void)
+{
+    /* Turn on the LoRa MAC timer. This function is automatically
+     * called by the LoRa stack when exiting low power mode.*/
+    #if MYNEWT_VAL(LORA_MAC_TIMER_NUM) == 0
+        #define TIMER_INIT  TIM2
+    #elif MYNEWT_VAL(LORA_MAC_TIMER_NUM) == 1
+        #define TIMER_INIT  TIM3
+    #elif MYNEWT_VAL(LORA_MAC_TIMER_NUM) == 2
+        #define TIMER_INIT  TIM21
+    #else
+        #error "Invalid LORA_MAC_TIMER_NUM"
+    #endif
+
+    hal_timer_init(MYNEWT_VAL(LORA_MAC_TIMER_NUM), TIMER_INIT);
+}
+#endif
diff --git a/hw/bsp/telee02/src/hal_bsp.c b/hw/bsp/telee02/src/hal_bsp.c
index 464d2a4..abaf113 100644
--- a/hw/bsp/telee02/src/hal_bsp.c
+++ b/hw/bsp/telee02/src/hal_bsp.c
@@ -157,3 +157,12 @@ hal_bsp_init(void)
     rc = hal_gpio_init_out(SX1276_ANT_HF_CTRL, 1);
     assert(rc == 0);
 }
+
+#if MYNEWT_VAL(LORA_NODE)
+void lora_bsp_enable_mac_timer(void)
+{
+    /* Turn on the LoRa MAC timer. This function is automatically
+     * called by the LoRa stack when exiting low power mode.*/
+    hal_timer_init(MYNEWT_VAL(LORA_MAC_TIMER_NUM), NULL);
+}
+#endif
diff --git a/hw/drivers/lora/include/lora/utilities.h 
b/hw/drivers/lora/include/lora/utilities.h
index fa0b81f..181dcbe 100644
--- a/hw/drivers/lora/include/lora/utilities.h
+++ b/hw/drivers/lora/include/lora/utilities.h
@@ -40,12 +40,4 @@ uint32_t timer_get_current_time(void);
  */
 uint32_t timer_get_elapsed_time(uint32_t saved_time);
 
-/*!
- * \brief Return the Time elapsed since a fix moment in Time
- *
- * \param [IN] event_in_future  fix moment in the future
- * \retval time                 returns difference between now and future event
- */
-uint32_t timer_get_future_time(uint32_t event_in_future);
-
 #endif // __LORA_UTILITIES_H__
diff --git a/hw/drivers/lora/src/utilities.c b/hw/drivers/lora/src/utilities.c
index e800e6a..810f2e8 100644
--- a/hw/drivers/lora/src/utilities.c
+++ b/hw/drivers/lora/src/utilities.c
@@ -17,25 +17,19 @@
  * under the License.
  */
 
-#include <stdlib.h>
+#include <stdint.h>
 
-#include "os/mynewt.h"
-#include "lora/utilities.h"
+#include "os/os.h"
 
 uint32_t
 timer_get_current_time(void)
 {
-    return hal_timer_read(MYNEWT_VAL(LORA_MAC_TIMER_NUM));
+    /* Convert the OS time ticks to seconds, and then to us*/
+    return os_cputime_ticks_to_usecs(os_cputime_get32());
 }
 
 uint32_t
 timer_get_elapsed_time(uint32_t saved_time)
 {
-    return hal_timer_read(MYNEWT_VAL(LORA_MAC_TIMER_NUM)) - saved_time;
-}
-
-uint32_t
-timer_get_future_time(uint32_t event_in_future)
-{
-    return hal_timer_read(MYNEWT_VAL(LORA_MAC_TIMER_NUM)) + event_in_future;
+    return timer_get_current_time() - saved_time;
 }
diff --git a/hw/drivers/lora/sx1272/src/sx1272.c 
b/hw/drivers/lora/sx1272/src/sx1272.c
index 64b349a..df7c988 100644
--- a/hw/drivers/lora/sx1272/src/sx1272.c
+++ b/hw/drivers/lora/sx1272/src/sx1272.c
@@ -16,21 +16,15 @@ Maintainer: Miguel Luis and Gregory Cristian
 #include <string.h>
 #include <stdlib.h>
 #include "os/mynewt.h"
+#include "os/os.h"
 #include "hal/hal_gpio.h"
 #include "hal/hal_spi.h"
-#include "hal/hal_timer.h"
 #include "bsp/bsp.h"
 #include "radio/radio.h"
 #include "sx1272.h"
 #include "sx1272-board.h"
 #include "lora/utilities.h"
 
-#if MYNEWT_VAL(LORA_MAC_TIMER_NUM) == -1
-#error "Must define a Lora MAC timer number"
-#else
-#define SX1272_TIMER_NUM    MYNEWT_VAL(LORA_MAC_TIMER_NUM)
-#endif
-
 /* XXX: dummy for now to read sx1272 */
 #if MYNEWT_VAL(BSP_USE_HAL_SPI)
 void bsp_spi_read_buf(uint8_t addr, uint8_t *buf, uint8_t size);
@@ -214,7 +208,11 @@ DioIrqHandler *DioIrq[] = {
     SX1272OnDio0Irq,
     SX1272OnDio1Irq,
     SX1272OnDio2Irq,
+#if (SX1272_DIO3 >= 0)
     SX1272OnDio3Irq,
+#else
+    NULL,
+#endif
 #if (SX1272_DIO4 >= 0)
     SX1272OnDio4Irq,
 #else
@@ -265,9 +263,9 @@ SX1272Init(RadioEvents_t *events)
     RadioEvents = events;
 
     // Initialize driver timeout timers
-    hal_timer_set_cb(SX1272_TIMER_NUM, &TxTimeoutTimer, SX1272OnTimeoutIrq, 
NULL);
-    hal_timer_set_cb(SX1272_TIMER_NUM, &RxTimeoutTimer, SX1272OnTimeoutIrq, 
NULL);
-    hal_timer_set_cb(SX1272_TIMER_NUM, &RxTimeoutSyncWord, SX1272OnTimeoutIrq, 
NULL);
+    os_cputime_timer_init(&TxTimeoutTimer, SX1272OnTimeoutIrq, NULL);
+    os_cputime_timer_init(&RxTimeoutTimer, SX1272OnTimeoutIrq, NULL);
+    os_cputime_timer_init(&RxTimeoutSyncWord, SX1272OnTimeoutIrq, NULL);
 
     SX1272IoInit();
     SX1272IoIrqInit(DioIrq);
@@ -315,7 +313,7 @@ SX1272IsChannelFree(RadioModems_t modem, uint32_t freq, 
int16_t rssiThresh,
     SX1272SetOpMode(RF_OPMODE_RECEIVER);
 
     /* Delay for 1 msec */
-    hal_timer_delay(SX1272_TIMER_NUM, 1000);
+    os_cputime_delay_usecs(1000);
 
     carrierSenseTime = timer_get_current_time( );
 
@@ -357,7 +355,7 @@ SX1272Random(void)
     SX1272SetOpMode(RF_OPMODE_RECEIVER);
 
     for (i = 0; i < 32; i++) {
-        hal_timer_delay(SX1272_TIMER_NUM, 1000);
+        os_cputime_delay_usecs(1000);
         // Unfiltered RSSI value reading. Only takes the LSB value
         rnd |= ((uint32_t)SX1272Read(REG_LR_RSSIWIDEBAND) & 0x01) << i;
     }
@@ -729,7 +727,7 @@ SX1272Send(uint8_t *buffer, uint8_t size)
         // FIFO operations can not take place in Sleep mode
         if ((SX1272Read(REG_OPMODE) & ~RF_OPMODE_MASK) == RF_OPMODE_SLEEP) {
             SX1272SetStby();
-            hal_timer_delay(SX1272_TIMER_NUM, 1000);
+            os_cputime_delay_usecs(1000);
         }
 
         // Write payload buffer
@@ -747,8 +745,8 @@ SX1272Send(uint8_t *buffer, uint8_t size)
 void
 SX1272SetSleep(void)
 {
-    hal_timer_stop(&RxTimeoutTimer);
-    hal_timer_stop(&TxTimeoutTimer);
+    os_cputime_timer_stop(&RxTimeoutTimer);
+    os_cputime_timer_stop(&TxTimeoutTimer);
 
     SX1272SetOpMode(RF_OPMODE_SLEEP);
     SX1272.Settings.State = RF_IDLE;
@@ -757,8 +755,8 @@ SX1272SetSleep(void)
 void
 SX1272SetStby(void)
 {
-    hal_timer_stop(&RxTimeoutTimer);
-    hal_timer_stop(&TxTimeoutTimer);
+    os_cputime_timer_stop(&RxTimeoutTimer);
+    os_cputime_timer_stop(&TxTimeoutTimer);
 
     SX1272SetOpMode(RF_OPMODE_STANDBY);
     SX1272.Settings.State = RF_IDLE;
@@ -845,16 +843,16 @@ SX1272SetRx(uint32_t timeout)
 
     SX1272.Settings.State = RF_RX_RUNNING;
     if (timeout != 0) {
-        hal_timer_stop(&RxTimeoutTimer);
-        hal_timer_start(&RxTimeoutTimer, timeout * 1000);
+        os_cputime_timer_stop(&RxTimeoutTimer);
+        os_cputime_timer_relative(&RxTimeoutTimer, timeout * 1000);
     }
 
     if (SX1272.Settings.Modem == MODEM_FSK) {
         SX1272SetOpMode(RF_OPMODE_RECEIVER);
 
         if (rxcontinuous == false) {
-            hal_timer_stop(&RxTimeoutSyncWord);
-            hal_timer_start(&RxTimeoutSyncWord,
+            os_cputime_timer_stop(&RxTimeoutSyncWord);
+            os_cputime_timer_relative(&RxTimeoutSyncWord,
                             SX1272.Settings.Fsk.RxSingleTimeout * 1000);
 
         }
@@ -917,8 +915,8 @@ SX1272SetTx(uint32_t timeout)
     }
 
     SX1272.Settings.State = RF_TX_RUNNING;
-    hal_timer_stop(&TxTimeoutTimer);
-    hal_timer_start(&TxTimeoutTimer, timeout * 1000);
+    os_cputime_timer_stop(&TxTimeoutTimer);
+    os_cputime_timer_relative(&TxTimeoutTimer, timeout * 1000);
     SX1272SetOpMode(RF_OPMODE_TRANSMITTER);
 }
 
@@ -964,10 +962,10 @@ SX1272SetTxContinuousWave(uint32_t freq, int8_t power, 
uint16_t time)
     SX1272Write(REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_11 | 
RF_DIOMAPPING1_DIO1_11);
     SX1272Write(REG_DIOMAPPING2, RF_DIOMAPPING2_DIO4_10 | 
RF_DIOMAPPING2_DIO5_10);
 
-    hal_timer_stop(&TxTimeoutTimer);
+    os_cputime_timer_stop(&TxTimeoutTimer);
 
     SX1272.Settings.State = RF_TX_RUNNING;
-    hal_timer_start(&TxTimeoutTimer, timeout * 1000);
+    os_cputime_timer_relative(&TxTimeoutTimer, timeout * 1000);
     SX1272SetOpMode(RF_OPMODE_TRANSMITTER);
 }
 
@@ -1005,9 +1003,9 @@ SX1272Reset(void)
 {
 
     hal_gpio_init_out(SX1272_NRESET, 1);
-    hal_timer_delay(SX1272_TIMER_NUM, 1000);
+    os_cputime_delay_usecs(1000);
     hal_gpio_init_in(SX1272_NRESET, HAL_GPIO_PULL_NONE);
-    hal_timer_delay(SX1272_TIMER_NUM, 6000);
+    os_cputime_delay_usecs(6000);
 }
 
 void
@@ -1176,12 +1174,12 @@ SX1272OnTimeoutIrq(void *unused)
             {
                 // Continuous mode restart Rx chain
                 SX1272Write(REG_RXCONFIG, SX1272Read(REG_RXCONFIG) | 
RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK);
-                hal_timer_stop(&RxTimeoutSyncWord);
-                hal_timer_start(&RxTimeoutSyncWord,
+                os_cputime_timer_stop(&RxTimeoutSyncWord);
+                os_cputime_timer_relative(&RxTimeoutSyncWord,
                                 SX1272.Settings.Fsk.RxSingleTimeout * 1000);
             } else {
                 SX1272.Settings.State = RF_IDLE;
-                hal_timer_stop(&RxTimeoutSyncWord);
+                os_cputime_timer_stop(&RxTimeoutSyncWord);
             }
         }
 
@@ -1246,16 +1244,16 @@ SX1272OnDio0Irq(void *unused)
                                                     
RF_IRQFLAGS1_SYNCADDRESSMATCH);
                         SX1272Write(REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN);
 
-                        hal_timer_stop(&RxTimeoutTimer);
+                        os_cputime_timer_stop(&RxTimeoutTimer);
 
                         if (SX1272.Settings.Fsk.RxContinuous == false) {
-                            hal_timer_stop(&RxTimeoutSyncWord);
+                            os_cputime_timer_stop(&RxTimeoutSyncWord);
                             SX1272.Settings.State = RF_IDLE;
                         } else {
                             // Continuous mode restart Rx chain
                             SX1272Write(REG_RXCONFIG, SX1272Read(REG_RXCONFIG) 
| RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK);
-                            hal_timer_stop(&RxTimeoutSyncWord);
-                            hal_timer_start(&RxTimeoutSyncWord,
+                            os_cputime_timer_stop(&RxTimeoutSyncWord);
+                            os_cputime_timer_relative(&RxTimeoutSyncWord,
                                             
SX1272.Settings.Fsk.RxSingleTimeout * 1000);
                         }
 
@@ -1284,16 +1282,16 @@ SX1272OnDio0Irq(void *unused)
                     SX1272.Settings.FskPacketHandler.NbBytes += 
(SX1272.Settings.FskPacketHandler.Size - 
SX1272.Settings.FskPacketHandler.NbBytes);
                 }
 
-                hal_timer_stop(&RxTimeoutTimer);
+                os_cputime_timer_stop(&RxTimeoutTimer);
 
                 if (SX1272.Settings.Fsk.RxContinuous == false) {
                     SX1272.Settings.State = RF_IDLE;
-                    hal_timer_stop(&RxTimeoutSyncWord);
+                    os_cputime_timer_stop(&RxTimeoutSyncWord);
                 } else {
                     // Continuous mode restart Rx chain
                     SX1272Write(REG_RXCONFIG, SX1272Read(REG_RXCONFIG) | 
RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK);
-                    hal_timer_stop(&RxTimeoutSyncWord);
-                    hal_timer_start(&RxTimeoutSyncWord,
+                    os_cputime_timer_stop(&RxTimeoutSyncWord);
+                    os_cputime_timer_relative(&RxTimeoutSyncWord,
                                     SX1272.Settings.Fsk.RxSingleTimeout * 
1000);
                 }
 
@@ -1317,7 +1315,7 @@ SX1272OnDio0Irq(void *unused)
                     if (SX1272.Settings.LoRa.RxContinuous == false) {
                         SX1272.Settings.State = RF_IDLE;
                     }
-                    hal_timer_stop(&RxTimeoutTimer);
+                    os_cputime_timer_stop(&RxTimeoutTimer);
 
                     if ((RadioEvents != NULL) && (RadioEvents->RxError != 
NULL)) {
                         RadioEvents->RxError();
@@ -1351,7 +1349,7 @@ SX1272OnDio0Irq(void *unused)
                 if (SX1272.Settings.LoRa.RxContinuous == false) {
                     SX1272.Settings.State = RF_IDLE;
                 }
-                hal_timer_stop(&RxTimeoutTimer);
+                os_cputime_timer_stop(&RxTimeoutTimer);
 
                 if ((RadioEvents != NULL) && (RadioEvents->RxDone != NULL)) {
                     RadioEvents->RxDone(g_rxtx_buffer,
@@ -1365,7 +1363,7 @@ SX1272OnDio0Irq(void *unused)
             }
             break;
         case RF_TX_RUNNING:
-            hal_timer_stop(&TxTimeoutTimer);
+            os_cputime_timer_stop(&TxTimeoutTimer);
             // TxDone interrupt
             switch (SX1272.Settings.Modem) {
             case MODEM_LORA:
@@ -1414,7 +1412,7 @@ SX1272OnDio1Irq(void *unused)
                 break;
             case MODEM_LORA:
                 // Sync time out
-                hal_timer_stop(&RxTimeoutTimer);
+                os_cputime_timer_stop(&RxTimeoutTimer);
 
                 // Clear Irq
                 SX1272Write(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXTIMEOUT);
@@ -1461,7 +1459,7 @@ SX1272OnDio2Irq(void *unused)
             case MODEM_FSK:
                 if ((SX1272.Settings.FskPacketHandler.PreambleDetected == 
true) &&
                     (SX1272.Settings.FskPacketHandler.SyncWordDetected == 
false)) {
-                    hal_timer_stop(&RxTimeoutSyncWord);
+                    os_cputime_timer_stop(&RxTimeoutSyncWord);
 
                     SX1272.Settings.FskPacketHandler.SyncWordDetected = true;
 
diff --git a/hw/drivers/lora/sx1276/src/sx1276.c 
b/hw/drivers/lora/sx1276/src/sx1276.c
index 107edb9..de59b03 100644
--- a/hw/drivers/lora/sx1276/src/sx1276.c
+++ b/hw/drivers/lora/sx1276/src/sx1276.c
@@ -16,21 +16,15 @@ Maintainer: Miguel Luis, Gregory Cristian and Wael Guibene
 #include <math.h>
 #include <string.h>
 #include "os/mynewt.h"
+#include "os/os.h"
 #include "hal/hal_gpio.h"
 #include "hal/hal_spi.h"
-#include "hal/hal_timer.h"
 #include "bsp/bsp.h"
 #include "radio/radio.h"
 #include "sx1276.h"
 #include "sx1276-board.h"
 #include "lora/utilities.h"
 
-#if MYNEWT_VAL(LORA_MAC_TIMER_NUM) == -1
-#error "Must define a Lora MAC timer number"
-#else
-#define SX1276_TIMER_NUM    MYNEWT_VAL(LORA_MAC_TIMER_NUM)
-#endif
-
 /*
  * Local types definition
  */
@@ -299,9 +293,9 @@ SX1276Init(RadioEvents_t *events)
     RadioEvents = events;
 
     // Initialize driver timeout timers. NOTE: assumes timer configured.
-    hal_timer_set_cb(SX1276_TIMER_NUM, &TxTimeoutTimer, SX1276OnTimeoutIrq, 
NULL);
-    hal_timer_set_cb(SX1276_TIMER_NUM, &RxTimeoutTimer, SX1276OnTimeoutIrq, 
NULL);
-    hal_timer_set_cb(SX1276_TIMER_NUM, &RxTimeoutSyncWord, SX1276OnTimeoutIrq, 
NULL);
+    os_cputime_timer_init(&TxTimeoutTimer, SX1276OnTimeoutIrq, NULL);
+    os_cputime_timer_init(&RxTimeoutTimer, SX1276OnTimeoutIrq, NULL);
+    os_cputime_timer_init(&RxTimeoutSyncWord, SX1276OnTimeoutIrq, NULL);
 
     SX1276IoInit();
     SX1276IoIrqInit(DioIrq);
@@ -353,7 +347,7 @@ SX1276IsChannelFree(RadioModems_t modem, uint32_t freq, 
int16_t rssiThresh,
     SX1276SetOpMode(RF_OPMODE_RECEIVER);
 
     /* Delay for 1 msec */
-    hal_timer_delay(SX1276_TIMER_NUM, 1000);
+    os_cputime_delay_usecs(1000);
 
     carrierSenseTime = timer_get_current_time();
 
@@ -395,7 +389,7 @@ SX1276Random(void)
     SX1276SetOpMode(RF_OPMODE_RECEIVER);
 
     for (i = 0; i < 32; i++) {
-        hal_timer_delay(SX1276_TIMER_NUM, 1000);
+        os_cputime_delay_usecs(1000);
         // Unfiltered RSSI value reading. Only takes the LSB value
         rnd |= ((uint32_t)SX1276Read(REG_LR_RSSIWIDEBAND) & 0x01) << i;
     }
@@ -899,7 +893,7 @@ SX1276Send(uint8_t *buffer, uint8_t size)
         // FIFO operations can not take place in Sleep mode
         if ((SX1276Read(REG_OPMODE) & ~RF_OPMODE_MASK) == RF_OPMODE_SLEEP) {
             SX1276SetStby();
-            hal_timer_delay(SX1276_TIMER_NUM, 1000);
+            os_cputime_delay_usecs(1000);
         }
         // Write payload buffer
         SX1276WriteFifo(buffer, size);
@@ -913,8 +907,8 @@ SX1276Send(uint8_t *buffer, uint8_t size)
 void
 SX1276SetSleep(void)
 {
-    hal_timer_stop(&RxTimeoutTimer);
-    hal_timer_stop(&TxTimeoutTimer);
+    os_cputime_timer_stop(&RxTimeoutTimer);
+    os_cputime_timer_stop(&TxTimeoutTimer);
 
     SX1276SetOpMode(RF_OPMODE_SLEEP);
     SX1276.Settings.State = RF_IDLE;
@@ -923,8 +917,8 @@ SX1276SetSleep(void)
 void
 SX1276SetStby(void)
 {
-    hal_timer_stop(&RxTimeoutTimer);
-    hal_timer_stop(&TxTimeoutTimer);
+    os_cputime_timer_stop(&RxTimeoutTimer);
+    os_cputime_timer_stop(&TxTimeoutTimer);
 
     SX1276SetOpMode(RF_OPMODE_STANDBY);
     SX1276.Settings.State = RF_IDLE;
@@ -1054,8 +1048,8 @@ SX1276SetRx(uint32_t timeout)
 
     SX1276.Settings.State = RF_RX_RUNNING;
     if (timeout != 0) {
-        hal_timer_stop(&RxTimeoutTimer);
-        hal_timer_start(&RxTimeoutTimer, timeout * 1000);
+        os_cputime_timer_stop(&RxTimeoutTimer);
+        os_cputime_timer_relative(&RxTimeoutTimer, timeout * 1000);
     }
 
     if (SX1276.Settings.Modem == MODEM_FSK) {
@@ -1067,8 +1061,8 @@ SX1276SetRx(uint32_t timeout)
                              ((SX1276Read(REG_SYNCCONFIG) &
                                 ~RF_SYNCCONFIG_SYNCSIZE_MASK) + 1.0) + 10.0) /
                       (double)SX1276.Settings.Fsk.Datarate) * 1e3) + 4;
-            hal_timer_stop(&RxTimeoutSyncWord);
-            hal_timer_start(&RxTimeoutSyncWord, rx_timeout_sync_delay * 1000);
+            os_cputime_timer_stop(&RxTimeoutSyncWord);
+            os_cputime_timer_relative(&RxTimeoutSyncWord, 
rx_timeout_sync_delay * 1000);
         }
     } else {
         if (rxcontinuous == true) {
@@ -1130,8 +1124,8 @@ SX1276SetTx(uint32_t timeout)
     }
 
     SX1276.Settings.State = RF_TX_RUNNING;
-    hal_timer_stop(&TxTimeoutTimer);
-    hal_timer_start(&TxTimeoutTimer, timeout * 1000);
+    os_cputime_timer_stop(&TxTimeoutTimer);
+    os_cputime_timer_relative(&TxTimeoutTimer, timeout * 1000);
     SX1276SetOpMode(RF_OPMODE_TRANSMITTER);
 }
 
@@ -1193,13 +1187,13 @@ SX1276Reset(void)
     hal_gpio_init_out(SX1276_NRESET, 0);
 
     // Wait 1 ms
-    hal_timer_delay(SX1276_TIMER_NUM, 1000);
+    os_cputime_delay_usecs(1000);
 
     // Configure RESET as input
     hal_gpio_init_in(SX1276_NRESET, HAL_GPIO_PULL_NONE);
 
     // Wait 6 ms
-    hal_timer_delay(SX1276_TIMER_NUM, 6000);
+    os_cputime_delay_usecs(6000);
 }
 
 void
@@ -1362,11 +1356,11 @@ SX1276OnTimeoutIrq(void *unused)
                 // Continuous mode restart Rx chain
                 SX1276Write(REG_RXCONFIG, SX1276Read(REG_RXCONFIG) | 
RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK);
                 assert(rx_timeout_sync_delay != (uint32_t)-1);
-                hal_timer_stop(&RxTimeoutSyncWord);
-                hal_timer_start(&RxTimeoutSyncWord, 
rx_timeout_sync_delay*1000);
+                os_cputime_timer_stop(&RxTimeoutSyncWord);
+                os_cputime_timer_relative(&RxTimeoutSyncWord, 
rx_timeout_sync_delay*1000);
             } else {
                 SX1276.Settings.State = RF_IDLE;
-                hal_timer_stop(&RxTimeoutSyncWord);
+                os_cputime_timer_stop(&RxTimeoutSyncWord);
             }
         }
         SX1276RxTimeout();
@@ -1402,17 +1396,17 @@ SX1276OnDio0Irq(void *unused)
                                                RF_IRQFLAGS1_SYNCADDRESSMATCH);
                     SX1276Write(REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN);
 
-                    hal_timer_stop(&RxTimeoutTimer);
+                    os_cputime_timer_stop(&RxTimeoutTimer);
 
                     if (SX1276.Settings.Fsk.RxContinuous == false) {
-                        hal_timer_stop(&RxTimeoutSyncWord);
+                        os_cputime_timer_stop(&RxTimeoutSyncWord);
                         SX1276.Settings.State = RF_IDLE;
                     } else {
                         // Continuous mode restart Rx chain
                         SX1276Write(REG_RXCONFIG, SX1276Read(REG_RXCONFIG) | 
RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK);
                         assert(rx_timeout_sync_delay != (uint32_t)-1);
-                        hal_timer_stop(&RxTimeoutSyncWord);
-                        hal_timer_start(&RxTimeoutSyncWord, 
rx_timeout_sync_delay*1000);
+                        os_cputime_timer_stop(&RxTimeoutSyncWord);
+                        os_cputime_timer_relative(&RxTimeoutSyncWord, 
rx_timeout_sync_delay*1000);
                     }
 
                     SX1276RxError();
@@ -1441,15 +1435,15 @@ SX1276OnDio0Irq(void *unused)
             if (SX1276.Settings.Fsk.RxContinuous == false) {
                 SX1276.Settings.State = RF_IDLE;
                 assert(rx_timeout_sync_delay != (uint32_t)-1);
-                hal_timer_stop(&RxTimeoutSyncWord);
-                hal_timer_start(&RxTimeoutSyncWord, 
rx_timeout_sync_delay*1000);
+                os_cputime_timer_stop(&RxTimeoutSyncWord);
+                os_cputime_timer_relative(&RxTimeoutSyncWord, 
rx_timeout_sync_delay*1000);
 
             } else {
                 // Continuous mode restart Rx chain
                 SX1276Write(REG_RXCONFIG, SX1276Read(REG_RXCONFIG) | 
RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK);
             }
 
-            hal_timer_stop(&RxTimeoutTimer);
+            os_cputime_timer_stop(&RxTimeoutTimer);
 
             SX1276RxDone(RxTxBuffer, SX1276.Settings.FskPacketHandler.Size, 
SX1276.Settings.FskPacketHandler.RssiValue, 0);
             SX1276.Settings.FskPacketHandler.PreambleDetected = false;
@@ -1469,7 +1463,7 @@ SX1276OnDio0Irq(void *unused)
                 if (SX1276.Settings.LoRa.RxContinuous == false) {
                     SX1276.Settings.State = RF_IDLE;
                 }
-                hal_timer_stop(&RxTimeoutTimer);
+                os_cputime_timer_stop(&RxTimeoutTimer);
 
                 SX1276RxError();
                 break;
@@ -1512,7 +1506,7 @@ SX1276OnDio0Irq(void *unused)
             if (SX1276.Settings.LoRa.RxContinuous == false) {
                 SX1276.Settings.State = RF_IDLE;
             }
-            hal_timer_stop(&RxTimeoutTimer);
+            os_cputime_timer_stop(&RxTimeoutTimer);
 
             SX1276RxDone(RxTxBuffer, SX1276.Settings.LoRaPacketHandler.Size, 
SX1276.Settings.LoRaPacketHandler.RssiValue, 
SX1276.Settings.LoRaPacketHandler.SnrValue);
             break;
@@ -1521,7 +1515,7 @@ SX1276OnDio0Irq(void *unused)
         }
         break;
     case RF_TX_RUNNING:
-        hal_timer_stop(&TxTimeoutTimer);
+        os_cputime_timer_stop(&TxTimeoutTimer);
         // TxDone interrupt
         switch (SX1276.Settings.Modem) {
         case MODEM_LORA:
@@ -1567,7 +1561,7 @@ SX1276OnDio1Irq(void *unused)
             break;
         case MODEM_LORA:
             // Sync time out
-            hal_timer_stop(&RxTimeoutTimer);
+            os_cputime_timer_stop(&RxTimeoutTimer);
             SX1276Write(REG_LR_IRQFLAGS, RFLR_IRQFLAGS_RXTIMEOUT);
             SX1276.Settings.State = RF_IDLE;
             SX1276RxTimeout();
@@ -1609,7 +1603,7 @@ SX1276OnDio2Irq(void *unused)
         case MODEM_FSK:
             if ((SX1276.Settings.FskPacketHandler.PreambleDetected == true) &&
                 (SX1276.Settings.FskPacketHandler.SyncWordDetected == false)) {
-                hal_timer_stop(&RxTimeoutSyncWord);
+                os_cputime_timer_stop(&RxTimeoutSyncWord);
 
                 SX1276.Settings.FskPacketHandler.SyncWordDetected = true;
 
diff --git a/net/lora/node/include/node/lora.h 
b/net/lora/node/include/node/lora.h
index f12f8c3..8c0a5b8 100644
--- a/net/lora/node/include/node/lora.h
+++ b/net/lora/node/include/node/lora.h
@@ -301,7 +301,6 @@ int lora_app_link_check(void);
  */
 int lora_node_link_qual(int16_t *rssi, int16_t *snr);
 
-
 /*
  * Maximum payload that can be sent in the next frame.
  */
diff --git a/net/lora/node/include/node/lora_priv.h 
b/net/lora/node/include/node/lora_priv.h
index d817123..f755923 100644
--- a/net/lora/node/include/node/lora_priv.h
+++ b/net/lora/node/include/node/lora_priv.h
@@ -263,9 +263,17 @@ extern uint16_t g_lnd_log_index;
 #define LORA_NODE_LOG_RX_ADR_REQ        (80)
 #define LORA_NODE_LOG_PROC_MAC_CMD      (85)
 #define LORA_NODE_LOG_LINK_CHK          (90)
+#define LORA_NODE_LOG_LP_ENTER          (95)
+#define LORA_NODE_LOG_LP_EXIT           (96)
+#define LORA_NODE_LOG_RX_WIN2_TIMEOUT   (97)
+#define LORA_NODE_LOG_RX_WIN2_CANCEL    (98)
 
 #else
 #define lora_node_log(a,b,c,d)
 #endif
 
+void lora_enter_low_power(void);
+void lora_exit_low_power(void);
+void lora_config_peripherals(void);
+
 #endif
diff --git a/net/lora/node/include/node/utilities.h 
b/net/lora/node/include/node/utilities.h
index 66bb2a8..cb26797 100644
--- a/net/lora/node/include/node/utilities.h
+++ b/net/lora/node/include/node/utilities.h
@@ -137,12 +137,4 @@ TimerTime_t TimerGetCurrentTime( void );
  */
 TimerTime_t TimerGetElapsedTime( TimerTime_t savedTime );
 
-/*!
- * \brief Return the Time elapsed since a fix moment in Time
- *
- * \param [IN] eventInFuture    fix moment in the future
- * \retval time             returns difference between now and future event
- */
-TimerTime_t TimerGetFutureTime( TimerTime_t eventInFuture );
-
 #endif // __UTILITIES_H__
diff --git a/net/lora/node/src/lora_cli.c b/net/lora/node/src/lora_cli.c
index 75d2a31..27d6fcb 100644
--- a/net/lora/node/src/lora_cli.c
+++ b/net/lora/node/src/lora_cli.c
@@ -676,6 +676,18 @@ lora_cli_log_cmd(int argc, char **argv)
         case LORA_NODE_LOG_LINK_CHK:
             console_printf("LINK_CHK status=%lu", g_lnd_log[i].lnd_p32);
             break;
+        case LORA_NODE_LOG_LP_ENTER:
+            console_printf("LOW POWER ENTER");
+            break;
+        case LORA_NODE_LOG_LP_EXIT:
+            console_printf("LOW POWER EXIT");
+            break;
+        case LORA_NODE_LOG_RX_WIN2_TIMEOUT:
+            console_printf("RX_WIN2 TIMEOUT");
+            break;
+        case LORA_NODE_LOG_RX_WIN2_CANCEL:
+            console_printf("RX_WIN2 CANCEL");
+            break;
         default:
             console_printf("id=%u p8=%u p16=%u p32=%lu",
                            g_lnd_log[i].lnd_id, g_lnd_log[i].lnd_p8,
diff --git a/net/lora/node/src/lora_node.c b/net/lora/node/src/lora_node.c
index d8a964b..5796356 100644
--- a/net/lora/node/src/lora_node.c
+++ b/net/lora/node/src/lora_node.c
@@ -19,6 +19,7 @@
 
 #include <string.h>
 #include "os/mynewt.h"
+#include "node/lora.h"
 #include "node/lora_priv.h"
 #include "node/lora_band.h"
 
@@ -88,6 +89,9 @@ struct lm_join_ev_arg_obj g_lm_join_ev_arg;
 struct lora_node_debug_log_entry g_lnd_log[LORA_NODE_DEBUG_LOG_ENTRIES];
 uint16_t g_lnd_log_index;
 
+/* Low power callback functions */
+extern void lora_bsp_enable_mac_timer(void);
+
 void
 lora_node_log(uint8_t logid, uint8_t p8, uint16_t p16, uint32_t p32)
 {
@@ -98,8 +102,7 @@ lora_node_log(uint8_t logid, uint8_t p8, uint16_t p16, 
uint32_t p32)
     g_lnd_log[g_lnd_log_index].lnd_p8 = p8;
     g_lnd_log[g_lnd_log_index].lnd_p16 = p16;
     g_lnd_log[g_lnd_log_index].lnd_p32 = p32;
-    g_lnd_log[g_lnd_log_index].lnd_cputime =
-        hal_timer_read(MYNEWT_VAL(LORA_MAC_TIMER_NUM));
+    g_lnd_log[g_lnd_log_index].lnd_cputime = TimerGetCurrentTime();
 
     ++g_lnd_log_index;
     if (g_lnd_log_index == LORA_NODE_DEBUG_LOG_ENTRIES) {
@@ -679,3 +682,24 @@ lora_node_init(void)
     assert(lms == LORAMAC_STATUS_OK);
 #endif
 }
+
+static bool low_power_active = true;
+
+void lora_enter_low_power(void)
+{
+    if (!low_power_active) {
+        low_power_active = true;
+        hal_timer_deinit(MYNEWT_VAL(LORA_MAC_TIMER_NUM));
+        lora_node_log(LORA_NODE_LOG_LP_ENTER, 0, 0, 0);
+    }
+}
+
+void lora_exit_low_power(void)
+{
+    if (low_power_active) {
+        low_power_active = false;
+        lora_bsp_enable_mac_timer();
+        lora_node_log(LORA_NODE_LOG_LP_EXIT, 0, 0, 0);
+        lora_config_peripherals();
+    }
+}
diff --git a/net/lora/node/src/mac/LoRaMac.c b/net/lora/node/src/mac/LoRaMac.c
index b254eb0..41e5abf 100644
--- a/net/lora/node/src/mac/LoRaMac.c
+++ b/net/lora/node/src/mac/LoRaMac.c
@@ -32,6 +32,7 @@
 #include <string.h>
 #include <assert.h>
 #include "os/mynewt.h"
+#include "os/os.h"
 #include "node/lora.h"
 #include "node/utilities.h"
 #include "node/mac/LoRaMacCrypto.h"
@@ -39,6 +40,7 @@
 #include "node/mac/LoRaMacTest.h"
 #include "hal/hal_timer.h"
 #include "node/lora_priv.h"
+#include "lora/utilities.h"
 
 #if MYNEWT_VAL(LORA_MAC_TIMER_NUM) == -1
 #error "Must define a Lora MAC timer number"
@@ -253,7 +255,7 @@ lora_mac_rx_disable(void)
 static void
 lora_mac_rtx_timer_stop(void)
 {
-    hal_timer_stop(&g_lora_mac_data.rtx_timer);
+    os_cputime_timer_stop(&g_lora_mac_data.rtx_timer);
     os_eventq_remove(lora_node_mac_evq_get(), &g_lora_mac_rtx_timeout_event);
 }
 
@@ -268,7 +270,9 @@ lora_mac_rx_win2_stop(void)
 {
     if (LoRaMacDeviceClass == CLASS_A) {
         hal_timer_stop(&RxWindowTimer2);
+        lora_enter_low_power();
         os_eventq_remove(lora_node_mac_evq_get(), &g_lora_mac_rx_win2_event);
+        lora_node_log(LORA_NODE_LOG_RX_WIN2_CANCEL, 0, 0, 0);
     }
 }
 
@@ -721,9 +725,9 @@ lora_mac_join_req_tx_fail(void)
            this but probably should be modified */
         /* Add some transmit delay between join request transmissions */
         LoRaMacState |= LORAMAC_TX_DELAYED;
-        hal_timer_stop(&TxDelayedTimer);
-        hal_timer_start(&TxDelayedTimer,
-            randr(0, MYNEWT_VAL(LORA_JOIN_REQ_RAND_DELAY) * 1000));
+        os_cputime_timer_stop(&TxDelayedTimer);
+        os_cputime_timer_relative(&TxDelayedTimer,
+            randr(0, MYNEWT_VAL(LORA_JOIN_REQ_RAND_DELAY * 1000)));
     }
 }
 
@@ -803,15 +807,16 @@ lora_mac_process_radio_tx(struct os_event *ev)
     PhyParam_t phyParam;
     SetBandTxDoneParams_t txDone;
 
-    /* XXX: We need to time this more accurately */
-    uint32_t curTime = hal_timer_read(LORA_MAC_TIMER_NUM);
-
+    lora_exit_low_power();
     if (LoRaMacDeviceClass != CLASS_C) {
         Radio.Sleep( );
     } else {
         lora_mac_rx_on_window2();
     }
 
+    /* XXX: We need to time this more accurately */
+    uint32_t curTime = hal_timer_read(LORA_MAC_TIMER_NUM);
+
     /* Always start receive window 1 */
     hal_timer_start_at(&RxWindowTimer1,
                        curTime + (g_lora_mac_data.rx_win1_delay * 1000));
@@ -833,7 +838,8 @@ lora_mac_process_radio_tx(struct os_event *ev)
     if (LM_F_NODE_ACK_REQ()) {
         getPhy.Attribute = PHY_ACK_TIMEOUT;
         phyParam = RegionGetPhyParam(LoRaMacRegion, &getPhy);
-        hal_timer_start_at(&g_lora_mac_data.rtx_timer, curTime +
+        os_cputime_timer_stop(&g_lora_mac_data.rtx_timer);
+        os_cputime_timer_relative(&g_lora_mac_data.rtx_timer,
                            ((g_lora_mac_data.rx_win2_delay + phyParam.Value) * 
1000));
     } else {
         /*
@@ -853,7 +859,8 @@ lora_mac_process_radio_tx(struct os_event *ev)
                 timeout += (uint32_t)((RxWindow2Config.tsymbol * 1000) *
                     RxWindow2Config.WindowTimeout);
             }
-            hal_timer_start_at(&g_lora_mac_data.rtx_timer, curTime + timeout);
+            os_cputime_timer_stop(&g_lora_mac_data.rtx_timer);
+            os_cputime_timer_relative(&g_lora_mac_data.rtx_timer, timeout);
         }
     }
 
@@ -863,11 +870,11 @@ lora_mac_process_radio_tx(struct os_event *ev)
     // Update last tx done time for the current channel
     txDone.Channel = g_lora_mac_data.cur_chan;
     txDone.Joined = LM_F_IS_JOINED();
-    txDone.LastTxDoneTime = curTime;
+    txDone.LastTxDoneTime = timer_get_current_time();
     RegionSetBandTxDone(LoRaMacRegion, &txDone);
 
     // Update Aggregated last tx done time
-    g_lora_mac_data.aggr_last_tx_done_time = curTime;
+    g_lora_mac_data.aggr_last_tx_done_time = txDone.LastTxDoneTime;
 
     if (!LM_F_NODE_ACK_REQ()) {
         g_lora_mac_data.nb_rep_cntr++;
@@ -1501,6 +1508,9 @@ lora_mac_rx_on_window2(void)
 static void
 lora_mac_process_rx_win2_timeout(struct os_event *ev)
 {
+    /* Turn off the high resolution timer */
+    lora_enter_low_power();
+    lora_node_log(LORA_NODE_LOG_RX_WIN2_TIMEOUT, 0, 0, 0);
     /*
      * There are two cases here. Either the radio is still receiving in which
      * case the radio status is not idle, or the radio finished receiving
@@ -1973,8 +1983,8 @@ ScheduleTx(void)
 
             // Send later - prepare timer
             LoRaMacState |= LORAMAC_TX_DELAYED;
-            hal_timer_stop(&TxDelayedTimer);
-            hal_timer_start(&TxDelayedTimer, duty_cycle_time_off);
+            os_cputime_timer_stop(&TxDelayedTimer);
+            os_cputime_timer_relative(&TxDelayedTimer, duty_cycle_time_off);
 
             lora_node_log(LORA_NODE_LOG_TX_DELAY, g_lora_mac_data.max_dc, 0,
                           duty_cycle_time_off);
@@ -2494,16 +2504,17 @@ LoRaMacInitialization(LoRaMacCallback_t *callbacks, 
LoRaMacRegion_t region)
 
     ResetMacParameters( );
 
-    /* XXX: determine which of these should be os callouts */
-    hal_timer_config(LORA_MAC_TIMER_NUM, LORA_MAC_TIMER_FREQ);
-    hal_timer_set_cb(LORA_MAC_TIMER_NUM, &TxDelayedTimer, 
OnTxDelayedTimerEvent,
-                     NULL);
+    /* TxDelayedTimer and RTX timers are configured to use the CPU timer, 
which should be configured
+    as a low power timer. The accuracy of these timers is not critical. */
+    os_cputime_timer_init(&TxDelayedTimer, OnTxDelayedTimerEvent, NULL);
+    os_cputime_timer_init(&g_lora_mac_data.rtx_timer, lora_mac_rtx_timer_cb, 
NULL);
+
+    /* The RX Window timers are configured to use the high resolution 
LORA_MAC_TIMER,
+    as their accuracy is critical. */
     hal_timer_set_cb(LORA_MAC_TIMER_NUM, &RxWindowTimer1, 
OnRxWindow1TimerEvent,
                      NULL);
     hal_timer_set_cb(LORA_MAC_TIMER_NUM, &RxWindowTimer2, 
OnRxWindow2TimerEvent,
                      NULL);
-    hal_timer_set_cb(LORA_MAC_TIMER_NUM, &g_lora_mac_data.rtx_timer,
-                     lora_mac_rtx_timer_cb, NULL);
 
     /* Init MAC radio events */
     g_lora_mac_radio_tx_timeout_event.ev_cb = 
lora_mac_process_radio_tx_timeout;
@@ -3289,3 +3300,10 @@ lora_mac_extract_mac_cmds(uint8_t max_cmd_bytes, uint8_t 
*buf)
 
     return bytes_added;
 }
+
+/* Reconfigure peripherals after exiting low power mode */
+void
+lora_config_peripherals(void)
+{
+    hal_timer_config(LORA_MAC_TIMER_NUM, LORA_MAC_TIMER_FREQ);
+}
diff --git a/net/lora/node/src/utilities.c b/net/lora/node/src/utilities.c
index 793d260..335cb06 100644
--- a/net/lora/node/src/utilities.c
+++ b/net/lora/node/src/utilities.c
@@ -40,9 +40,3 @@ TimerGetElapsedTime(TimerTime_t savedTime)
 {
     return timer_get_elapsed_time(savedTime);
 }
-
-TimerTime_t
-TimerGetFutureTime(TimerTime_t eventInFuture)
-{
-    return timer_get_future_time(eventInFuture);
-}
diff --git a/net/lora/node/syscfg.yml b/net/lora/node/syscfg.yml
index 28305b9..0841b51 100644
--- a/net/lora/node/syscfg.yml
+++ b/net/lora/node/syscfg.yml
@@ -93,6 +93,11 @@ syscfg.defs:
                 the network is public; private otherwise
         value: 0
 
+    LORA_LP_CLOCK:
+        description: >
+            Used by BSP packages to configure LP clock for the LoRa system.
+        value: 1
+
     LORA_NODE_SYSINIT_STAGE:
         description: >
             Sysinit stage for the LoRa endpoint.

Reply via email to