Skip to content
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

Unexpected Deepsleep consumption of STML476RG with Lora SX1262 #14224

Closed
andreagilardoni opened this issue Feb 1, 2021 · 11 comments
Closed

Unexpected Deepsleep consumption of STML476RG with Lora SX1262 #14224

andreagilardoni opened this issue Feb 1, 2021 · 11 comments

Comments

@andreagilardoni
Copy link
Contributor

andreagilardoni commented Feb 1, 2021

Description of defect

Given the datasheet of the components mentioned in the title I expect a low power consumption of:

  • STM32L476RG of around 10/20uA in STOP mode (I think the default is STOP2)
  • sx1262 of a 1/2uA in sleep mode

I am getting an unusual behavior with higher power consumption ~800uA (On Average).

Target(s) affected by this defect ?

Custom board based on STM32L476RG, the configuration is identical to NUCLEO_L476RG.

pinmap:

PA_4 NSS
PA_5 SCK
PA_6 MISO
PA_7 MOSI
PA_8 RESET
PA_9 BUSY
PB_1 DIO1
PB_0 ANTSW (not used)

Toolchain(s) (name and version) displaying this defect ?

I am using the mbed os master branch.

What version of Mbed-os are you using (tag or sha) ?

073ae1d

What version(s) of tools are you using. List all that apply (E.g. mbed-cli)

mbed-cli version 1.10.5
arm-none-eabi-g++ (GNU Arm Embedded Toolchain 10-2020-q4-major) 10.2.1 20201103 (release)

How is this defect reproduced ?

The following is a sample code I wrote to replicate the behavior without using the complete LoraRadio object.
The code takes some snippets of code from connectivity/drivers/lora/COMPONENT_SX126X/SX126X_LoRaRadio.cpp to wake the radio up wakeup_radio() and put it to sleep sleep_radio().

The code does the following:

  1. Create spi object and Digital In/Outs simulating the LoraRadio object
  2. Turn on the reset pin for 200ms
  3. call sleep_radio function
  4. put the stm device in STOP mode
  5. call wakeup_radio function
  6. wait 1s
  7. call sleep_radio function
  8. go to step 4
#include <mbed.h>
SPI spi(PA_7, PA_6, PA_5);
DigitalOut _chip_select(PA_4, 1);
DigitalIn _busy(PA_9, PullNone); 

DigitalInOut reset_ctl(PA_8);
InterruptIn _dio1_ctl(PB_1, PullNone);

void sleep_radio(void) {
    // warm start, power consumption 600 nA
    uint8_t sleep_state = 0x04;

    _chip_select = 0;

    while (_busy) {
        // do nothing
        printf(".");
    }
    printf("\n");

    spi.write(0x84); // SLEEP command
    spi.write(sleep_state);

    _chip_select = 1;
    ThisThread::sleep_for(2);
}

void wakeup_radio() {
    // hold the NSS low, this should wakeup the chip.
    // now we should wait for the _busy line to go low
    _chip_select = 0;
    while (_busy) {
        // do nothing
        printf(".");
    }
    printf("\n");

    _chip_select = 1;
}

#define TIME 5s
int main() {
    printf("\n\nTesting SPI power consumption\n\n");
    
    printf("putting radio to sleep\n");
    reset_ctl=1;
    ThisThread::sleep_for(200ms);
    reset_ctl=0;

    sleep_radio();
    ThisThread::sleep_for(200ms);

    printf("radio sleeping\n");

    while (1) {
        ThisThread::sleep_for(1000ms);
        printf("\n\ndeep sleep time\n");
        ThisThread::sleep_for(TIME);

        printf("waking radio\n");
        wakeup_radio();
        printf("radio awake\n");

        ThisThread::sleep_for(1000ms);
        printf("putting radio to sleep\n");

        sleep_radio();
        ThisThread::sleep_for(200ms);
        printf("radio sleeping\n");
    }
}

The following is a screenshot captured with an otii of the power consumption of the device I am talking about. It contains the recording of some cycles of the code described before.
The strange thing is that on the first cycle the power consumption is as intended and after the power consumption rises to 300uA.
Screenshot from 2021-02-01 17-09-00

@ciarmcom
Copy link
Member

ciarmcom commented Feb 1, 2021

@alcheagle thank you for raising this issue.Please take a look at the following comments:

It would help if you could also specify the versions of any tools you are using?

NOTE: If there are fields which are not applicable then please just add 'n/a' or 'None'. This indicates to us that at least all the fields have been considered.
Please update the issue header with the missing information, the issue will not be mirrored to our internal defect tracking system or investigated until this has been fully resolved.

@ciarmcom
Copy link
Member

ciarmcom commented Feb 1, 2021

Thank you for raising this detailed GitHub issue. I am now notifying our internal issue triagers.
Internal Jira reference: https://jira.arm.com/browse/IOTOSM-3371

@0xc0170
Copy link
Contributor

0xc0170 commented Feb 2, 2021

cc @ARMmbed/team-st-mcd Please review

@andreagilardoni
Copy link
Contributor Author

andreagilardoni commented Feb 2, 2021

I observe that:

  1. when I power the device from 0 the power consumption is high (few mA), I suppose the radio is on at that moment
  2. after turning off the radio (sleep_radio()) the consumption goes down to reasonable values (tens of uA)
  3. I turn on and off the radio again the consumption reaches ~300uA of consumption.

I am not able to measure the 2 domains separately(radio and mcu), but it seems that the MCU after issuing the second command is in a strange state (maybe the SPI object is the culprit) where either the radio is waiting for something or the mcu is in some gpio misconfiguration. For this reason if I remove the step 2 the total consumption remains in a reasonable level.

@andreagilardoni
Copy link
Contributor Author

I don't know how but this may be related to #8373 in some way. Where can I find some docs about Pinmap Configuration? I don't understand whether I have to change PeripheralPins.c file of the target I am using or if I have to change something else.

I tried the following configuration, but nothing improves.

MBED_WEAK const PinMap PinMap_SPI_MISO[] = {
-    {PA_6,       SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF5_SPI1)},
+    {PA_6,       SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)},
    {PB_4,       SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF5_SPI1)},
    {PB_4_ALT0,  SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF6_SPI3)},
    {PB_14,      SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF5_SPI2)},
    {PC_2,       SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF5_SPI2)},
    {PC_11,      SPI_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF6_SPI3)},
    {NC, NC, 0}
};

@evandavey
Copy link
Contributor

@alcheagle - did you make any progress with this issue? I am testing on a Murata 1SJ dev board link using the mbed-os SX126X driver (on mbed master as I patched it remove dependencies on freq, device and crystal select pins). I have tested putting the radio to sleep (I get 50uA) then waking then sleeping again (I get 50uA) again. However, I know this board is capable of going as low as 2uA (based on the supplied AT firmware). Interestingly if I power up the board and call radio.sleep() I get 50uA, but if I comment this line and re-upload (meaning radio is still asleep) I get 11uA so there is something about calling radio.sleep() that adds ~40uA (it toggles chip select and calls spi.write similar to your code). I have tried messing with the pinmap config like you did but this has not helped. So the question is how to stop that 40uA then secondly where is the missing 9uA vs the AT firmware.

I am using a bare-metal example, with the ev_queue responsible for deep sleep (which is how a full lorawan example would work) with my main simply:

For 50uA

int main(void)
{
    radio.sleep();
    ev_queue.dispatch_forever();
}

or for 11uA after running the above

int main(void)
{
    // radio.sleep();
    ev_queue.dispatch_forever();
}

@andreagilardoni
Copy link
Contributor Author

Hi @eavelardev, I struggled figuring out the culprit of this issue. It passed a while since I tried handling this issue, so I may not remember all the details.
As I remember the issue lies in the SPI object being created with some strange behaviour with the MISO pin in combination to the sx126x pin configuration. I discovered that by putting a GND wire in contact with the MISO pin by hand the consumption dropped down to the desired levels and went up after some send cycles.

I got no answer for this issue about how to properly configure pinmap in PeripheralPins.c and make sure I was making them right.

The temporary solution I adopted was to change radio module and come back later and try to fix it again.

@evandavey
Copy link
Contributor

evandavey commented Jul 24, 2021

See some progress we are making here: ARMmbed/mbed-os-example-lorawan#227 (comment)

In summary, I believe the pins are not being placed in a low power state during sleep, and this accounts for considerable current loss. So the SX126X driver needs to be updated to deinit pins on sleep and reinit on wakeup. However, it looks like this is not easily supported with MBED out of the box: #3106. Updates look needed to all the peripheral drivers to create deinit/reinit methods, and further updates likely needed to the sleep manager so these are called for sleep/wakeup. #3106 looks like a very old and stale issue.

@JojoS62
Copy link
Contributor

JojoS62 commented Jul 24, 2021

I had a similar issue with LPC812 and RFM69. The LPC turns off completely in deep power down, including the internal pull up resistors. That caused floating inputs at SPI an increased power consumption. Adding external Rs to all SPI outputs fixed it.

@evandavey
Copy link
Contributor

evandavey commented Jul 24, 2021

Possibly a solution to try for this original issue with external radio chip though I suspect the underlying cause is the same (GPIOs not powered down in sleep).

I am working with modules (combined STM32L0 + radio) so no possibility of added external resistors without signifcant hackery (the MCU to SPI connections are internal). Besides, 2uA is possible on the same board using an alternative framework to MBED. Our issue I think is that the GPIOs are not turned off at all, rather than GPIOS + internal pullups being off. I have demonstrated 7uA manually turning them off, but haven't yet figured out how to turn them back on again within the constraints of the framework.

@0xc0170
Copy link
Contributor

0xc0170 commented Jul 22, 2022

Should be fixed via #15181

@0xc0170 0xc0170 closed this as completed Jul 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants