diff --git a/boards/lobaro-lorabox/include/board.h b/boards/lobaro-lorabox/include/board.h index 803bc9535f..162ce33eab 100644 --- a/boards/lobaro-lorabox/include/board.h +++ b/boards/lobaro-lorabox/include/board.h @@ -24,6 +24,15 @@ extern "C" { #endif +/** + * @name xtimer configuration + * @{ + */ +#define XTIMER_WIDTH (16) +#define XTIMER_BACKOFF (50) +#define XTIMER_ISR_BACKOFF (40) +/** @} */ + /** * @name LED pin definitions and handlers * @{ diff --git a/boards/lobaro-lorabox/include/periph_conf.h b/boards/lobaro-lorabox/include/periph_conf.h index e60891dd6b..1e6f3ec3ba 100644 --- a/boards/lobaro-lorabox/include/periph_conf.h +++ b/boards/lobaro-lorabox/include/periph_conf.h @@ -31,16 +31,6 @@ extern "C" { #endif - -/** - * @name xtimer configuration - * @{ - */ -#define XTIMER_WIDTH (16) -#define XTIMER_BACKOFF (50) -#define XTIMER_ISR_BACKOFF (40) -/** @} */ - /** * @name Clock system configuration * @{ diff --git a/drivers/include/sx127x.h b/drivers/include/sx127x.h index 717f448fdb..02d59382fb 100644 --- a/drivers/include/sx127x.h +++ b/drivers/include/sx127x.h @@ -60,7 +60,8 @@ #ifndef SX127X_H #define SX127X_H -#include "xtimer.h" +#include "timex.h" +#include "ztimer.h" #include "net/netdev.h" #include "periph/gpio.h" #include "periph/spi.h" @@ -78,9 +79,9 @@ extern "C" { #define SX127X_HF_CHANNEL_DEFAULT (868000000UL) /**< Use to calibrate RX chain for LF and HF bands */ #define SX127X_RF_MID_BAND_THRESH (525000000UL) /**< Mid-band threshold */ #define SX127X_XTAL_FREQ (32000000UL) /**< Internal oscillator frequency, 32MHz */ -#define SX127X_RADIO_WAKEUP_TIME (1000U) /**< In microseconds [us] */ +#define SX127X_RADIO_WAKEUP_TIME (1U) /**< In milliseconds [ms] */ -#define SX127X_TX_TIMEOUT_DEFAULT (1000U * 1000U * 30UL) /**< TX timeout, 30s */ +#define SX127X_TX_TIMEOUT_DEFAULT (30 * MS_PER_SEC) /**< TX timeout, 30s */ #define SX127X_RX_SINGLE (false) /**< Single byte receive mode => continuous by default */ #define SX127X_RX_BUFFER_SIZE (256) /**< RX buffer size */ #define SX127X_RADIO_TX_POWER (14U) /**< Radio power in dBm */ @@ -183,8 +184,8 @@ typedef struct { uint8_t coderate; /**< Error coding rate */ uint8_t freq_hop_period; /**< Frequency hop period */ uint8_t flags; /**< Boolean flags */ - uint32_t rx_timeout; /**< RX timeout in microseconds */ - uint32_t tx_timeout; /**< TX timeout in microseconds */ + uint32_t rx_timeout; /**< RX timeout in milliseconds */ + uint32_t tx_timeout; /**< TX timeout in milliseconds */ } sx127x_lora_settings_t; /** @@ -202,8 +203,8 @@ typedef struct { */ typedef struct { /* Data that will be passed to events handler in application */ - xtimer_t tx_timeout_timer; /**< TX operation timeout timer */ - xtimer_t rx_timeout_timer; /**< RX operation timeout timer */ + ztimer_t tx_timeout_timer; /**< TX operation timeout timer */ + ztimer_t rx_timeout_timer; /**< RX operation timeout timer */ uint32_t last_channel; /**< Last channel in frequency hopping sequence */ bool is_last_cad_success; /**< Sign of success of last CAD operation (activity detected) */ } sx127x_internal_t; diff --git a/drivers/sx127x/Makefile.dep b/drivers/sx127x/Makefile.dep index c7a106427e..cc1b688571 100644 --- a/drivers/sx127x/Makefile.dep +++ b/drivers/sx127x/Makefile.dep @@ -3,7 +3,15 @@ FEATURES_REQUIRED += periph_gpio_irq FEATURES_REQUIRED += periph_spi FEATURES_OPTIONAL += periph_spi_gpio_mode USEMODULE += iolist -USEMODULE += xtimer +USEMODULE += ztimer_usec +USEMODULE += ztimer_msec + +# If RTT feature is available use the RTT backend of ztimer +FEATURES_OPTIONAL += periph_rtt +ifneq (,$(filter periph_rtt,$(FEATURES_USED))) + USEMODULE += ztimer_periph_rtt +endif + USEMODULE += netif USEMODULE += lora diff --git a/drivers/sx127x/sx127x.c b/drivers/sx127x/sx127x.c index 962c3a16bc..f472672d57 100644 --- a/drivers/sx127x/sx127x.c +++ b/drivers/sx127x/sx127x.c @@ -24,7 +24,8 @@ #include #include -#include "xtimer.h" +#include "timex.h" +#include "ztimer.h" #include "thread.h" #include "periph/gpio.h" @@ -110,12 +111,12 @@ int sx127x_reset(const sx127x_t *dev) /* set reset pin to the state that triggers manual reset */ gpio_write(dev->params.reset_pin, SX127X_POR_ACTIVE_LOGIC_LEVEL); - xtimer_usleep(SX127X_MANUAL_RESET_SIGNAL_LEN_US); + ztimer_sleep(ZTIMER_USEC, SX127X_MANUAL_RESET_SIGNAL_LEN_US); /* Put reset pin in High-Z */ gpio_init(dev->params.reset_pin, GPIO_IN); - xtimer_usleep(SX127X_MANUAL_RESET_WAIT_FOR_READY_US); + ztimer_sleep(ZTIMER_USEC, SX127X_MANUAL_RESET_WAIT_FOR_READY_US); } return 0; @@ -147,7 +148,7 @@ int sx127x_init(sx127x_t *dev) } /* wait for the device to become ready */ - xtimer_usleep(SX127X_POR_WAIT_FOR_READY_US); + ztimer_sleep(ZTIMER_USEC, SX127X_POR_WAIT_FOR_READY_US); sx127x_reset(dev); @@ -205,7 +206,7 @@ uint32_t sx127x_random(sx127x_t *dev) sx127x_set_op_mode(dev, SX127X_RF_OPMODE_RECEIVER); for (unsigned i = 0; i < 32; i++) { - xtimer_usleep(1000); /* wait for the chaos */ + ztimer_sleep(ZTIMER_MSEC, 1); /* wait one millisecond */ /* Non-filtered RSSI value reading. Only takes the LSB value */ rnd |= ((uint32_t) sx127x_reg_read(dev, SX127X_REG_LR_RSSIWIDEBAND) & 0x01) << i; diff --git a/drivers/sx127x/sx127x_getset.c b/drivers/sx127x/sx127x_getset.c index fec8ea1103..7c96281d4b 100644 --- a/drivers/sx127x/sx127x_getset.c +++ b/drivers/sx127x/sx127x_getset.c @@ -26,6 +26,8 @@ #include #include +#include "ztimer.h" + #include "net/lora.h" #include "sx127x.h" @@ -200,8 +202,8 @@ void sx127x_set_sleep(sx127x_t *dev) DEBUG("[sx127x] Set sleep\n"); /* Disable running timers */ - xtimer_remove(&dev->_internal.tx_timeout_timer); - xtimer_remove(&dev->_internal.rx_timeout_timer); + ztimer_remove(ZTIMER_MSEC, &dev->_internal.tx_timeout_timer); + ztimer_remove(ZTIMER_MSEC, &dev->_internal.rx_timeout_timer); /* Put chip into sleep */ sx127x_set_op_mode(dev, SX127X_RF_OPMODE_SLEEP); @@ -213,8 +215,8 @@ void sx127x_set_standby(sx127x_t *dev) DEBUG("[sx127x] Set standby\n"); /* Disable running timers */ - xtimer_remove(&dev->_internal.tx_timeout_timer); - xtimer_remove(&dev->_internal.rx_timeout_timer); + ztimer_remove(ZTIMER_MSEC, &dev->_internal.tx_timeout_timer); + ztimer_remove(ZTIMER_MSEC, &dev->_internal.rx_timeout_timer); sx127x_set_op_mode(dev, SX127X_RF_OPMODE_STANDBY); sx127x_set_state(dev, SX127X_RF_IDLE); @@ -322,7 +324,7 @@ void sx127x_set_rx(sx127x_t *dev) sx127x_set_state(dev, SX127X_RF_RX_RUNNING); if (dev->settings.lora.rx_timeout != 0) { - xtimer_set(&(dev->_internal.rx_timeout_timer), dev->settings.lora.rx_timeout); + ztimer_set(ZTIMER_MSEC, &(dev->_internal.rx_timeout_timer), dev->settings.lora.rx_timeout); } @@ -395,7 +397,7 @@ void sx127x_set_tx(sx127x_t *dev) /* Start TX timeout timer */ if (dev->settings.lora.tx_timeout != 0) { - xtimer_set(&(dev->_internal.tx_timeout_timer), dev->settings.lora.tx_timeout); + ztimer_set(ZTIMER_MSEC, &(dev->_internal.tx_timeout_timer), dev->settings.lora.tx_timeout); } /* Put chip into transfer mode */ diff --git a/drivers/sx127x/sx127x_internal.c b/drivers/sx127x/sx127x_internal.c index 2a3cc9512e..c14628e669 100644 --- a/drivers/sx127x/sx127x_internal.c +++ b/drivers/sx127x/sx127x_internal.c @@ -25,6 +25,8 @@ #include #include +#include "ztimer.h" + #include "net/lora.h" #include "sx127x.h" @@ -231,7 +233,7 @@ bool sx127x_is_channel_free(sx127x_t *dev, uint32_t freq, int16_t rssi_threshold sx127x_set_channel(dev, freq); sx127x_set_op_mode(dev, SX127X_RF_OPMODE_RECEIVER); - xtimer_usleep(1000); /* wait 1 millisecond */ + ztimer_sleep(ZTIMER_MSEC, 1); /* wait 1 millisecond */ rssi = sx127x_read_rssi(dev); sx127x_set_sleep(dev); diff --git a/drivers/sx127x/sx127x_netdev.c b/drivers/sx127x/sx127x_netdev.c index 1b428fcd59..0dbc0d6a8b 100644 --- a/drivers/sx127x/sx127x_netdev.c +++ b/drivers/sx127x/sx127x_netdev.c @@ -21,6 +21,8 @@ #include #include +#include "ztimer.h" + #include "net/netopt.h" #include "net/netdev.h" #include "net/netdev/lora.h" @@ -77,7 +79,7 @@ static int _send(netdev_t *netdev, const iolist_t *iolist) * So wake up the chip */ if (sx127x_get_op_mode(dev) == SX127X_RF_OPMODE_SLEEP) { sx127x_set_standby(dev); - xtimer_usleep(SX127X_RADIO_WAKEUP_TIME); /* wait for chip wake up */ + ztimer_sleep(ZTIMER_MSEC, SX127X_RADIO_WAKEUP_TIME); /* wait for chip wake up */ } /* Write payload buffer */ @@ -122,7 +124,7 @@ static int _recv(netdev_t *netdev, void *buf, size_t len, void *info) sx127x_set_state(dev, SX127X_RF_IDLE); } - xtimer_remove(&dev->_internal.rx_timeout_timer); + ztimer_remove(ZTIMER_MSEC, &dev->_internal.rx_timeout_timer); netdev->event_callback(netdev, NETDEV_EVENT_CRC_ERROR); return -EBADMSG; } @@ -180,7 +182,7 @@ static int _recv(netdev_t *netdev, void *buf, size_t len, void *info) sx127x_set_state(dev, SX127X_RF_IDLE); } - xtimer_remove(&dev->_internal.rx_timeout_timer); + ztimer_remove(ZTIMER_MSEC, &dev->_internal.rx_timeout_timer); /* Read the last packet from FIFO */ uint8_t last_rx_addr = sx127x_reg_read(dev, SX127X_REG_LR_FIFORXCURRENTADDR); sx127x_reg_write(dev, SX127X_REG_LR_FIFOADDRPTR, last_rx_addr); @@ -565,7 +567,7 @@ void _on_dio0_irq(void *arg) netdev->event_callback(netdev, NETDEV_EVENT_RX_COMPLETE); break; case SX127X_RF_TX_RUNNING: - xtimer_remove(&dev->_internal.tx_timeout_timer); + ztimer_remove(ZTIMER_MSEC, &dev->_internal.tx_timeout_timer); switch (dev->settings.modem) { case SX127X_MODEM_LORA: /* Clear IRQ */ @@ -602,7 +604,7 @@ void _on_dio1_irq(void *arg) /* todo */ break; case SX127X_MODEM_LORA: - xtimer_remove(&dev->_internal.rx_timeout_timer); + ztimer_remove(ZTIMER_MSEC, &dev->_internal.rx_timeout_timer); /* Clear Irq */ sx127x_reg_write(dev, SX127X_REG_LR_IRQFLAGS, SX127X_RF_LORA_IRQFLAGS_RXTIMEOUT); sx127x_set_state(dev, SX127X_RF_IDLE); diff --git a/pkg/semtech-loramac/Makefile.dep b/pkg/semtech-loramac/Makefile.dep index 84d9dbab21..1bd02cfb96 100644 --- a/pkg/semtech-loramac/Makefile.dep +++ b/pkg/semtech-loramac/Makefile.dep @@ -6,6 +6,9 @@ USEMODULE += semtech_loramac_mac_region USEMODULE += semtech_loramac_crypto USEMODULE += semtech_loramac_arch +USEMODULE += ztimer_msec +USEMODULE += ztimer_periph_rtt + # The build fails on MSP430 because the toolchain doesn't provide # EXIT_SUCCESS/EXIT_FAILURE macros FEATURES_BLACKLIST += arch_msp430 diff --git a/pkg/semtech-loramac/contrib/semtech_loramac_radio.c b/pkg/semtech-loramac/contrib/semtech_loramac_radio.c index a0cf9be655..e37bb6f9ee 100644 --- a/pkg/semtech-loramac/contrib/semtech_loramac_radio.c +++ b/pkg/semtech-loramac/contrib/semtech_loramac_radio.c @@ -122,7 +122,7 @@ void SX127XSetTxConfig(RadioModems_t modem, int8_t power, uint32_t fdev, sx127x_set_tx_power(&sx127x, power); sx127x_set_preamble_length(&sx127x, preambleLen); sx127x_set_rx_single(&sx127x, false); - sx127x_set_tx_timeout(&sx127x, timeout * US_PER_MS); /* base unit us, LoRaMAC ms */ + sx127x_set_tx_timeout(&sx127x, timeout); /* base unit ms, LoRaMAC ms */ } uint32_t SX127XTimeOnAir(RadioModems_t modem, uint8_t pktLen) @@ -153,7 +153,7 @@ void SX127XStandby(void) void SX127XRx(uint32_t timeout) { - sx127x_set_rx_timeout(&sx127x, timeout * US_PER_MS); + sx127x_set_rx_timeout(&sx127x, timeout); sx127x_set_rx(&sx127x); } diff --git a/pkg/semtech-loramac/contrib/semtech_loramac_timer.c b/pkg/semtech-loramac/contrib/semtech_loramac_timer.c index d1ed507407..3a04e5a737 100644 --- a/pkg/semtech-loramac/contrib/semtech_loramac_timer.c +++ b/pkg/semtech-loramac/contrib/semtech_loramac_timer.c @@ -19,7 +19,7 @@ * @} */ -#include "xtimer.h" +#include "ztimer.h" #include "thread.h" #include "semtech-loramac/timer.h" @@ -27,7 +27,14 @@ extern kernel_pid_t semtech_loramac_pid; void TimerInit(TimerEvent_t *obj, void (*cb)(void)) { - obj->dev = (xtimer_t) { 0 }; + obj->dev = (ztimer_t) { + .base = { + .next = NULL, + .offset = 0, + }, + .callback = NULL, + .arg = NULL, + }; obj->running = 0; obj->cb = cb; } @@ -41,43 +48,43 @@ void TimerReset(TimerEvent_t *obj) void TimerStart(TimerEvent_t *obj) { obj->running = 1; - xtimer_t *timer = &(obj->dev); + ztimer_t *timer = &(obj->dev); msg_t *msg = &(obj->msg); msg->type = MSG_TYPE_MAC_TIMEOUT; msg->content.value = (uintptr_t)obj->cb; - xtimer_set_msg(timer, obj->timeout, msg, semtech_loramac_pid); + ztimer_set_msg(ZTIMER_MSEC, timer, obj->timeout, msg, semtech_loramac_pid); } void TimerStop(TimerEvent_t *obj) { obj->running = 0; - xtimer_remove(&(obj->dev)); + ztimer_remove(ZTIMER_MSEC, &(obj->dev)); } void TimerSetValue(TimerEvent_t *obj, uint32_t value) { if (obj->running) { - xtimer_remove(&(obj->dev)); + ztimer_remove(ZTIMER_MSEC, &(obj->dev)); } - obj->timeout = value * US_PER_MS; + obj->timeout = value; } TimerTime_t TimerGetCurrentTime(void) { - uint64_t CurrentTime = xtimer_now_usec64() / US_PER_MS; + uint64_t CurrentTime = ztimer_now(ZTIMER_MSEC); return (TimerTime_t)CurrentTime; } TimerTime_t TimerGetElapsedTime(TimerTime_t savedTime) { - uint64_t CurrentTime = xtimer_now_usec64() / US_PER_MS; + uint64_t CurrentTime = ztimer_now(ZTIMER_MSEC); return (TimerTime_t)(CurrentTime - savedTime); } TimerTime_t TimerGetFutureTime(TimerTime_t eventInFuture) { - uint64_t CurrentTime = xtimer_now_usec64() / US_PER_MS; + uint64_t CurrentTime = ztimer_now(ZTIMER_MSEC); return (TimerTime_t)(CurrentTime + eventInFuture); } diff --git a/pkg/semtech-loramac/doc.txt b/pkg/semtech-loramac/doc.txt index e2f0601b8c..0e13bb784b 100644 --- a/pkg/semtech-loramac/doc.txt +++ b/pkg/semtech-loramac/doc.txt @@ -152,6 +152,23 @@ * This mechanism is especially useful when using deep sleep power modes that * don't preserve RAM. * + * # Low power considerations + * + * The internal implementation of the required LoRaWAN timings (delay before + * opening RX windows, duty-cycle delays) automatically achieves the lowest + * possible power consumption while remaining usable when RIOT's low power modes + * are not blocked. All timings are managed by the @ref sys_ztimer + * running on the low-level @ref drivers_periph_rtt peripheral which + * allows for: + * - going to a deep-sleep mode with RAM retention (no reboot) between TX and + * RX1 and between RX1 and RX2 windows, and as a result reduces the power + * consumption + * - using deep-sleep mode with RAM retention and have the duty-cycle + * restriction still usable between each active cycle (wake-up, measure, send, + * receive, sleep). + * As a result, this package can only be used on boards that provide the + * `periph_rtt` feature. + * * @warning It is not possible to directly call the original LoRaMAC-node API * using this package. This package should only be considered as a * wrapper around the original LoRaMAC-node API and only the API diff --git a/pkg/semtech-loramac/include/semtech-loramac/timer.h b/pkg/semtech-loramac/include/semtech-loramac/timer.h index cce20f2083..54e01a4380 100644 --- a/pkg/semtech-loramac/include/semtech-loramac/timer.h +++ b/pkg/semtech-loramac/include/semtech-loramac/timer.h @@ -26,7 +26,7 @@ extern "C" { #endif -#include "xtimer.h" +#include "ztimer.h" #include "msg.h" #include "semtech_loramac.h" @@ -37,7 +37,7 @@ extern "C" { typedef struct TimerEvent_s { uint32_t timeout; /**< Timer timeout in us */ uint8_t running; /**< Check if timer is running */ - xtimer_t dev; /**< xtimer instance attached to this LoRaMAC timer */ + ztimer_t dev; /**< ztimer instance attached to this LoRaMAC timer */ msg_t msg; /**< message attacher to this LoRaMAC timer */ void (*cb)(void); /**< callback to call when timer timeout */ } TimerEvent_t; diff --git a/sys/ztimer/auto_init.c b/sys/ztimer/auto_init.c index a3953cd7ac..489b86ac93 100644 --- a/sys/ztimer/auto_init.c +++ b/sys/ztimer/auto_init.c @@ -68,7 +68,6 @@ ztimer_clock_t *const ZTIMER_USEC = &_ztimer_convert_shift_usec.super.super; # else static ztimer_convert_frac_t _ztimer_convert_frac_usec; ztimer_clock_t *const ZTIMER_USEC = &_ztimer_convert_frac_usec.super.super; -# define ZTIMER_USEC_CONVERT_LOWER (&_ztimer_periph_timer_usec.super) # endif # else # error ztimer_usec selected, but no configuration available! @@ -92,13 +91,8 @@ ztimer_clock_t *const ZTIMER_MSEC = &_ztimer_periph_timer_rtt_msec; static ztimer_convert_frac_t _ztimer_convert_frac_msec; ztimer_clock_t *const ZTIMER_MSEC = &_ztimer_convert_frac_msec.super.super; ztimer_clock_t *const ZTIMER_MSEC_BASE = &_ztimer_periph_timer_usec.super; -# if CONFIG_ZTIMER_USEC_BASE_FREQ < FREQ_1MHZ -# define ZTIMER_MSEC_CONVERT_LOWER ZTIMER_USEC_CONVERT_LOWER -# define ZTIMER_MSEC_CONVERT_LOWER_FREQ CONFIG_ZTIMER_USEC_BASE_FREQ -# else -# define ZTIMER_MSEC_CONVERT_LOWER (ZTIMER_USEC) -# define ZTIMER_MSEC_CONVERT_LOWER_FREQ FREQ_1MHZ -# endif +# define ZTIMER_MSEC_CONVERT_LOWER ZTIMER_USEC_BASE +# define ZTIMER_MSEC_CONVERT_LOWER_FREQ CONFIG_ZTIMER_USEC_BASE_FREQ # else # error No suitable ZTIMER_MSEC config. Maybe add USEMODULE += ztimer_usec? # endif