SWL2001 icon indicating copy to clipboard operation
SWL2001 copied to clipboard

sx1262 energy consumption issue and peridiocally waking up after 31

Open Jackiii1989 opened this issue 7 months ago • 5 comments

Hi,

Thanks again for your previous help with the ticket.

I'm currently working on optimizing the energy consumption of the SX1262 and ensuring stability when used with the SWL2001. However, I’m running into some issues that I don’t fully understand.

  1. High power consumption

After sending data to the LoRa gateway, the device issues the SetSleep command with the bytes 0x84 0x04, indicating that it's entering sleep mode with configuration retention. I then set the next alarm for 30 minutes later. Below is the final SPI command sent before going to sleep:

Image

Despite this, the power profiler shows that the device draws 1.5 mA during sleep, which seems too high:

Image

~~I traced the current leakage and discovered that it appears to come through the SPI’s CS line and the VDD of the SX1262. When I disconnected those lines, the sleep current dropped to about 260 µA, which aligns with the expected values from the datasheet.~~

I suspect the increased energy consumption is due to the use of the TCXO (temperature-compensated crystal oscillator). I'm using the SX1262 LoRa module with a Raspberry Pi Pico, which requires activating the TCXO via the SetDIO3AsTCXOCtrl command

SX1262 LoRa module with a Raspberry Pi Pico

To enable the TCXO, I modified the code as follows:

void ral_sx126x_bsp_get_xosc_cfg( const void* context, ral_xosc_cfg_t* xosc_cfg, ...)
{
    *xosc_cfg = RAL_XOSC_CFG_TCXO_RADIO_CTRL;
    *supply_voltage = 0x01; // voltage 1.7V
    *startup_time_in_tick = 0x0140;
}

According to the datasheet from sx1262, the nominal current consumption should be around 1.5 mA, which is why I believe the TCXO is responsible for the higher power draw. The current consumption in sleep is 1.55 mA. I also attempted to reset the device in an effort to switch to the internal oscillator since it's the only way to change oscillators, but the energy consumption remained unchanged.

Is there something I can do? Can I deactivate the TCXO when it has been activated?

  1. Waking-up sporadically

The second issue is that the device wakes up every 31.99 seconds, despite being configured to wake up after 30 minutes. Here’s a snippet from the log:

Here is the log:

Image

Here is the logic analyzer output:

Image

I've been trying to identify the source of the wake-up event, but it doesn't appear to be triggered by the RTC or any of the LoRa device's pins, as there's no detectable pin state change when the device wakes up.

EDIT 1: The MCU wakes up due to the LPTIM (Low-Power Timer). I added a log message ("LPTIM") to confirm when the timer callback is triggered, and I can see it in the log:

Image

Do I need to manually disable the LPTIM, or is this something the library is supposed to handle automatically?

Let me know if you need anything else.

Jackiii1989 avatar May 21 '25 10:05 Jackiii1989

Hi,

Regarding the power issue, if I remember correctly the radio itself is supposed to turn of the TCXO after it's done (depeding on the configuration and the radio you are using). But if you need to do this manually there are some hooks for turning on/off the TCXCO in the stmc_modem_hal.c

Regarding waking up every 32 seconds due to the low power timer. This is probably because the LPTIM overflows after 32 seconds. When the radio planner want's to sleep for lets say 60 seconds it will try to configure the timer for 60 seconds however if the low power timer is only 16 bit and configured with a low value prescaler it will only be capable of setting the timer for 32 seconds. This causes the MCU to wakup early, the radio planner detects there is nothing to do yet and reconfigures the timer for the remaining 28 seconds.

You could configure the timer with using a higher prescaler (lowering the clock of the timer) which allows the low power timer to count to 64 seconds or more without waking up the MCU. However this comes at the cost of accuracy which can increase power consumption or cause timing issues.

XKottelaarAlflex avatar May 22 '25 13:05 XKottelaarAlflex

Hi,

thanks for the reply.

Regarding the power issue, if I remember correctly the radio itself is supposed to turn of the TCXO after it's done (depeding on the configuration and the radio you are using). But if you need to do this manually there are some hooks for turning on/off the TCXCO in the stmc_modem_hal.c

I found the functions (smtc_modem_hal_start_radio_tcxo() and smtc_modem_hal_stop_radio_tcxo()), implemented some logic and tried to get them to work, but I made a worse mess of it. I decided to change the LoRa chip to a supported platform and bought the SX1261MB2xAS. After connecting and flashing, the high power consumption in sleep mode disappeared. It only consumed around 40 µA. So, I will leave it here.

Regarding waking up every 32 seconds due to the low power timer. This is probably because the LPTIM overflows after 32 seconds. When the radio planner want's to sleep for lets say 60 seconds it will try to configure the timer for 60 seconds however if the low power timer is only 16 bit and configured with a low value prescaler it will only be capable of setting the timer for 32 seconds. This causes the MCU to wakup early, the radio planner detects there is nothing to do yet and reconfigures the timer for the remaining 28 seconds.

Yes, you are absolutely right. I did the calculation and got exactly 31.99 seconds (16-bit ARR value ÷ timer clock (32,768) ÷ prescaler (16) = 31.99). However, I think this is a bug because there are two timers: the RTC and the lptim. In sleep mode, only the RTC should be active, and in the active state, the LPTIM should be active for fast-changing events. It should be the SWL2001 library that takes care of this, not the user. When I manually stopped the timer before going to sleep, the wake-up issue disappeared. I also found other issues with the RTC and GPIOs. It seems to me that the library has not been completely ported to the SX1261.

Jackiii1989 avatar May 27 '25 16:05 Jackiii1989

Hi, Library was fully ported on SX1261. Could you please elaborate on the reason why you are saying " It seems to me that the library has not been completely ported to the SX1261" ? Thank you very much for your feedback, Best regards,

opeyrard avatar Jun 03 '25 12:06 opeyrard

Hi,

sorry for my late response. I maybe overreacted to say that is not completely ported, but there are a couple things that is bothering me, mainly relating to the SX1261 and the STM32L0. Perhaps I’m being overly picky, but these inconsistencies are a bit frustrating.

In the smtc_hal_spi.c file, for instance, the input parameters for hal_spi_init() and hal_spi_de_init() remain unused. Instead, the pin initialisation and configuration are hardcoded. This means that if I modify the SPI pins in modem_pinout.h, the changes do not affect smtc_hal_spi.c; the only module in which the pin configuration from modem_pinout.h appears to take effect is smtc_hal_gpio.c.

The lbm_examples/README.md specifies that only the LR1XXX and SX126X radios are supported. However, the Makefile also includes support for SX127X, which is a bit confusing. I tried changing the pins, compiled it it worked. I noticed that when the device entered sleep mode, the LPTIM was not triggered. When I switched to the SX1261, LPTIM was triggered during sleep. This difference in behavior of sleep should not occur. From the READMEs of both drivers, I can see they expose different interfaces to the upper layers. For instance, the SX126X driver does not provide any timer control functions, which can explain maybe why the LPTIM is not stopped, but again this is annoying.

Image

While these details may not seem directly relevant, they can still be somewhat frustrating. For example, the SysTick timer is implemented on the Nucleo L476RG board but not on the L073RZ. The accuracy of hal_mcu_wait_us() depends on the system clock, meaning any changes to the clock speed could affect its behavior. That said, this might not be critical, as hal_mcu_wait_us() doesn't handle any timing-sensitive tasks. This functionality could be implemented more effectively using the SysTick timer, especially since sleep functions deactivates and activates the SysTick Timer.

Another point is the STACK_ID, which appears to serve no functional purpose and only adds unnecessary clutter to the code. While I understand it may have grown historical and is maybe relate to legacy hardware, it raises questions about what other remnants might be influencing the application.

I hope this feedback doesn't come across as overly critical—these are just my personal observations from reviewing the code.

Jackiii1989 avatar Jun 24 '25 11:06 Jackiii1989

Hi, Thank you very much for your feedback. Regarding STACK_ID, this is used to run multiple LoRaWAN stacks in parallel. This will be documented in a next coming release. Best regards,

lbm-team avatar Jul 16 '25 08:07 lbm-team