Skip to content

Fix LoRa sx1276 Low Power sleep, now 3uA #15181

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 8, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 27 additions & 10 deletions connectivity/drivers/lora/COMPONENT_SX1276/SX1276_LoRaRadio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ SPDX-License-Identifier: BSD-3-Clause
#include "sx1276Regs-LoRa.h"

#include <math.h> //rint

#include <chrono>
using namespace std::chrono_literals;
using namespace rtos;
using namespace mbed;

Expand Down Expand Up @@ -210,6 +211,8 @@ SX1276_LoRaRadio::SX1276_LoRaRadio(PinName spi_mosi,

if (tcxo != NC) {
_tcxo = 1;
// TCXO startup time
ThisThread::sleep_for(5ms);
}

#ifdef MBED_CONF_RTOS_PRESENT
Expand Down Expand Up @@ -288,9 +291,9 @@ void SX1276_LoRaRadio::radio_reset()
{
_reset_ctl.output();
_reset_ctl = 0;
ThisThread::sleep_for(2);
ThisThread::sleep_for(2ms);
_reset_ctl.input();
ThisThread::sleep_for(6);
ThisThread::sleep_for(6ms);
}

/**
Expand Down Expand Up @@ -357,7 +360,7 @@ uint32_t SX1276_LoRaRadio::random(void)
set_operation_mode(RF_OPMODE_RECEIVER);

for (i = 0; i < 32; i++) {
ThisThread::sleep_for(1);
ThisThread::sleep_for(1ms);
// Unfiltered RSSI value reading. Only takes the LSB value
rnd |= ((uint32_t) read_register(REG_LR_RSSIWIDEBAND) & 0x01) << i;
}
Expand Down Expand Up @@ -805,7 +808,7 @@ void SX1276_LoRaRadio::send(uint8_t *buffer, uint8_t size)
// FIFO operations can not take place in Sleep mode
if ((read_register(REG_OPMODE) & ~RF_OPMODE_MASK) == RF_OPMODE_SLEEP) {
standby();
ThisThread::sleep_for(1);
ThisThread::sleep_for(1ms);
}
// write_to_register payload buffer
write_fifo(buffer, size);
Expand Down Expand Up @@ -1025,7 +1028,7 @@ bool SX1276_LoRaRadio::perform_carrier_sense(radio_modems_t modem,
set_operation_mode(RF_OPMODE_RECEIVER);

// hold on a bit, radio turn-around time
ThisThread::sleep_for(1);
ThisThread::sleep_for(1ms);

Timer elapsed_time;
elapsed_time.start();
Expand Down Expand Up @@ -1263,13 +1266,27 @@ void SX1276_LoRaRadio::read_fifo(uint8_t *buffer, uint8_t size)
void SX1276_LoRaRadio::set_operation_mode(uint8_t mode)
{
if (mode == RF_OPMODE_SLEEP) {
write_to_register(REG_OPMODE, (read_register(REG_OPMODE) & RF_OPMODE_MASK) | mode);
set_low_power_mode();
/* FIXME taken from set_modem, it reduces the power consumption
*from 300µA to 1.5µA */
write_to_register(REG_DIOMAPPING1, 0x00); // sets DIO0-DI03 in default mode
write_to_register(REG_DIOMAPPING2, 0x30); // bits 4-5 are turned on i.e.,
if (_rf_ctrls.tcxo != NC) {
ThisThread::sleep_for(1ms);
_tcxo = 0;
}
} else {
if (_rf_ctrls.tcxo != NC) {
_tcxo = 1;
// TCXO startup time
ThisThread::sleep_for(5ms);
Copy link

@mickael868 mickael868 Nov 29, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the tests I did on a custom Murata-based board, if the sleep period is greater or equal to 9ms, the device is unable to receive a join accept.

Copy link
Contributor Author

@hallard hallard Nov 29, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @mickael868, this mean that 5ms looks like correct value (no magic, I took this 5ms from code of other stack).
Pay attention to SPI, SPI communication with sx1272 won't work if TCXO is not enabled. Worth mentioning this one
@jeromecoutant could you please confirm it now works with your DISCO_L072CZ_LRWAN1 ?

}
set_low_power_mode();
write_to_register(REG_OPMODE, (read_register(REG_OPMODE) & RF_OPMODE_MASK) | mode);
set_antenna_switch(mode);
}

write_to_register(REG_OPMODE, (read_register(REG_OPMODE) & RF_OPMODE_MASK) | mode);
}

/**
Expand Down Expand Up @@ -1327,14 +1344,14 @@ void SX1276_LoRaRadio::set_sx1276_variant_type()
{
if (_rf_ctrls.ant_switch != NC) {
_ant_switch.input();
ThisThread::sleep_for(1);
ThisThread::sleep_for(1ms);
if (_ant_switch == 1) {
radio_variant = SX1276MB1LAS;
} else {
radio_variant = SX1276MB1MAS;
}
_ant_switch.output();
ThisThread::sleep_for(1);
ThisThread::sleep_for(1ms);
} else {
radio_variant = MBED_CONF_SX1276_LORA_DRIVER_RADIO_VARIANT;
}
Expand Down Expand Up @@ -2274,4 +2291,4 @@ void SX1276_LoRaRadio::handle_timeout_irq()

#endif // DEVICE_SPI

// EOF
// EOF