What's causing this power spike in STM32 low power mode

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








7












$begingroup$


I'm using an STM32L073RZ on a bare board with just the CPU and decoupling caps. I'm powering the board straight from an Otii Arc and measuring current consumption. I'm running MbedOS 5.11.2.



When I call the sleep() function the CPU goes into a low power mode, with an occasional 5mA spike in current consumption approximately every second, see the image below:



Current consumption



What is the cause of this? I'm attempting to place the CPU into STOP mode with an RTC running - this should draw, according to the datasheet, 1µA current.



Further to this, how can I tell which low power mode the sleep() function has chosen? I'm trying to stay away from the HAL because I've had many issues configuring interrupts and the like.



For completeness, here's the code that's running on the board:



#include "mbed.h"

int main()
sleep();










share|improve this question









$endgroup$







  • 1




    $begingroup$
    I would guess your mcu is waking up once a second for some reason
    $endgroup$
    – Colin
    Mar 15 at 13:58






  • 2




    $begingroup$
    It seems quite plausible that the RTC is generating an interrupt once per second. Put a breakpoint on the RTC interrupt handler.
    $endgroup$
    – Jeremy
    Mar 15 at 14:41










  • $begingroup$
    @Jeremy thanks for the suggestion, doesn't appear to be an RTC interrupt as the handler doesn't trigger if I include it.
    $endgroup$
    – Adam Mitchell
    Mar 15 at 14:47






  • 1




    $begingroup$
    @Adam - Even if the interrupt is masked, if the RTC is active it may be bringing elements out of low-power mode anyway.
    $endgroup$
    – Jeremy
    Mar 15 at 14:49










  • $begingroup$
    @Jeremy that's a fair suggestion. I think I'll have to get to grips with the HAL so I can be absolutely sure which timers are running, which power mode the CPU is in etc.. Thanks!
    $endgroup$
    – Adam Mitchell
    Mar 15 at 14:53

















7












$begingroup$


I'm using an STM32L073RZ on a bare board with just the CPU and decoupling caps. I'm powering the board straight from an Otii Arc and measuring current consumption. I'm running MbedOS 5.11.2.



When I call the sleep() function the CPU goes into a low power mode, with an occasional 5mA spike in current consumption approximately every second, see the image below:



Current consumption



What is the cause of this? I'm attempting to place the CPU into STOP mode with an RTC running - this should draw, according to the datasheet, 1µA current.



Further to this, how can I tell which low power mode the sleep() function has chosen? I'm trying to stay away from the HAL because I've had many issues configuring interrupts and the like.



For completeness, here's the code that's running on the board:



#include "mbed.h"

int main()
sleep();










share|improve this question









$endgroup$







  • 1




    $begingroup$
    I would guess your mcu is waking up once a second for some reason
    $endgroup$
    – Colin
    Mar 15 at 13:58






  • 2




    $begingroup$
    It seems quite plausible that the RTC is generating an interrupt once per second. Put a breakpoint on the RTC interrupt handler.
    $endgroup$
    – Jeremy
    Mar 15 at 14:41










  • $begingroup$
    @Jeremy thanks for the suggestion, doesn't appear to be an RTC interrupt as the handler doesn't trigger if I include it.
    $endgroup$
    – Adam Mitchell
    Mar 15 at 14:47






  • 1




    $begingroup$
    @Adam - Even if the interrupt is masked, if the RTC is active it may be bringing elements out of low-power mode anyway.
    $endgroup$
    – Jeremy
    Mar 15 at 14:49










  • $begingroup$
    @Jeremy that's a fair suggestion. I think I'll have to get to grips with the HAL so I can be absolutely sure which timers are running, which power mode the CPU is in etc.. Thanks!
    $endgroup$
    – Adam Mitchell
    Mar 15 at 14:53













7












7








7





$begingroup$


I'm using an STM32L073RZ on a bare board with just the CPU and decoupling caps. I'm powering the board straight from an Otii Arc and measuring current consumption. I'm running MbedOS 5.11.2.



When I call the sleep() function the CPU goes into a low power mode, with an occasional 5mA spike in current consumption approximately every second, see the image below:



Current consumption



What is the cause of this? I'm attempting to place the CPU into STOP mode with an RTC running - this should draw, according to the datasheet, 1µA current.



Further to this, how can I tell which low power mode the sleep() function has chosen? I'm trying to stay away from the HAL because I've had many issues configuring interrupts and the like.



For completeness, here's the code that's running on the board:



#include "mbed.h"

int main()
sleep();










share|improve this question









$endgroup$




I'm using an STM32L073RZ on a bare board with just the CPU and decoupling caps. I'm powering the board straight from an Otii Arc and measuring current consumption. I'm running MbedOS 5.11.2.



When I call the sleep() function the CPU goes into a low power mode, with an occasional 5mA spike in current consumption approximately every second, see the image below:



Current consumption



What is the cause of this? I'm attempting to place the CPU into STOP mode with an RTC running - this should draw, according to the datasheet, 1µA current.



Further to this, how can I tell which low power mode the sleep() function has chosen? I'm trying to stay away from the HAL because I've had many issues configuring interrupts and the like.



For completeness, here's the code that's running on the board:



#include "mbed.h"

int main()
sleep();







stm32 low-power mbed






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Mar 15 at 13:49









Adam MitchellAdam Mitchell

1597




1597







  • 1




    $begingroup$
    I would guess your mcu is waking up once a second for some reason
    $endgroup$
    – Colin
    Mar 15 at 13:58






  • 2




    $begingroup$
    It seems quite plausible that the RTC is generating an interrupt once per second. Put a breakpoint on the RTC interrupt handler.
    $endgroup$
    – Jeremy
    Mar 15 at 14:41










  • $begingroup$
    @Jeremy thanks for the suggestion, doesn't appear to be an RTC interrupt as the handler doesn't trigger if I include it.
    $endgroup$
    – Adam Mitchell
    Mar 15 at 14:47






  • 1




    $begingroup$
    @Adam - Even if the interrupt is masked, if the RTC is active it may be bringing elements out of low-power mode anyway.
    $endgroup$
    – Jeremy
    Mar 15 at 14:49










  • $begingroup$
    @Jeremy that's a fair suggestion. I think I'll have to get to grips with the HAL so I can be absolutely sure which timers are running, which power mode the CPU is in etc.. Thanks!
    $endgroup$
    – Adam Mitchell
    Mar 15 at 14:53












  • 1




    $begingroup$
    I would guess your mcu is waking up once a second for some reason
    $endgroup$
    – Colin
    Mar 15 at 13:58






  • 2




    $begingroup$
    It seems quite plausible that the RTC is generating an interrupt once per second. Put a breakpoint on the RTC interrupt handler.
    $endgroup$
    – Jeremy
    Mar 15 at 14:41










  • $begingroup$
    @Jeremy thanks for the suggestion, doesn't appear to be an RTC interrupt as the handler doesn't trigger if I include it.
    $endgroup$
    – Adam Mitchell
    Mar 15 at 14:47






  • 1




    $begingroup$
    @Adam - Even if the interrupt is masked, if the RTC is active it may be bringing elements out of low-power mode anyway.
    $endgroup$
    – Jeremy
    Mar 15 at 14:49










  • $begingroup$
    @Jeremy that's a fair suggestion. I think I'll have to get to grips with the HAL so I can be absolutely sure which timers are running, which power mode the CPU is in etc.. Thanks!
    $endgroup$
    – Adam Mitchell
    Mar 15 at 14:53







1




1




$begingroup$
I would guess your mcu is waking up once a second for some reason
$endgroup$
– Colin
Mar 15 at 13:58




$begingroup$
I would guess your mcu is waking up once a second for some reason
$endgroup$
– Colin
Mar 15 at 13:58




2




2




$begingroup$
It seems quite plausible that the RTC is generating an interrupt once per second. Put a breakpoint on the RTC interrupt handler.
$endgroup$
– Jeremy
Mar 15 at 14:41




$begingroup$
It seems quite plausible that the RTC is generating an interrupt once per second. Put a breakpoint on the RTC interrupt handler.
$endgroup$
– Jeremy
Mar 15 at 14:41












$begingroup$
@Jeremy thanks for the suggestion, doesn't appear to be an RTC interrupt as the handler doesn't trigger if I include it.
$endgroup$
– Adam Mitchell
Mar 15 at 14:47




$begingroup$
@Jeremy thanks for the suggestion, doesn't appear to be an RTC interrupt as the handler doesn't trigger if I include it.
$endgroup$
– Adam Mitchell
Mar 15 at 14:47




1




1




$begingroup$
@Adam - Even if the interrupt is masked, if the RTC is active it may be bringing elements out of low-power mode anyway.
$endgroup$
– Jeremy
Mar 15 at 14:49




$begingroup$
@Adam - Even if the interrupt is masked, if the RTC is active it may be bringing elements out of low-power mode anyway.
$endgroup$
– Jeremy
Mar 15 at 14:49












$begingroup$
@Jeremy that's a fair suggestion. I think I'll have to get to grips with the HAL so I can be absolutely sure which timers are running, which power mode the CPU is in etc.. Thanks!
$endgroup$
– Adam Mitchell
Mar 15 at 14:53




$begingroup$
@Jeremy that's a fair suggestion. I think I'll have to get to grips with the HAL so I can be absolutely sure which timers are running, which power mode the CPU is in etc.. Thanks!
$endgroup$
– Adam Mitchell
Mar 15 at 14:53










4 Answers
4






active

oldest

votes


















10












$begingroup$

I can't speak about mbed specifically, but the general idea is that sleep() causes the execution of the current process to pause for some number of seconds, or indefinitely if no argument (equivalent to an argument of 0) is given.



In a multiprocess environment, that means that it simply yields the CPU to other processes. If there are no other processes ready to run, the OS may or may not put the CPU into a low-power state while waiting for interrupts — it depends on how the idle() task is written. This would not generally be the lowest-power state available on the CPU, however, since it wants to wake quickly when interrupts occur.



In your case, it appears to be waking up once a second to handle the system timer tick.



If you really want to get into a lower-power state, there are generally platform-specific calls for that, and that's exactly the sort of thing the HAL is for. You shouldn't avoid it, you should learn it.




After a quick search, I discovered that the documentation here: APIs - power management discusses this specifically.






share|improve this answer











$endgroup$












  • $begingroup$
    Thanks for your response, very useful. In Mbed, sleep() is supposed to place to CPU into a low-power mode, but no documentation that I can find explains this logic. I've disabled the SysTick IRQ in the NVIC to no avail, I guess I'll just keep turning off timers/counters until it disappears..
    $endgroup$
    – Adam Mitchell
    Mar 15 at 14:34






  • 1




    $begingroup$
    @AdamMitchell - more likely what you need to do is actually read through the Mbed code (it is open source, even if by default they link a binary version of it) and figure out what they are doing, then decide if that can be brought into alignment with your goals, or if their goals are just too different.
    $endgroup$
    – Chris Stratton
    Mar 15 at 15:32



















2












$begingroup$

As explained in the documentation, the following drivers can prevent deep sleep:




  • Ticker

  • Timeout

  • Timer

  • SPI

  • I2C

  • CAN

  • SerialBase



If you need to identify what is blocking deep sleep, you can build from the command line, and enable the verbose debugging - even though it seems you do not have any in your example.



You can also review the tickless documentation. I believe this mode is relatively new, so it is possible that your platform has some problems in the HAL.






share|improve this answer









$endgroup$




















    2












    $begingroup$

    If you enable tickless mode (via MBED_TICKLESS=1) and just pause the thread (via wait_ms(10000)) you won't see any spikes, and the MCU will stay in Stop mode (at least on my STM32F4 board).






    share|improve this answer









    $endgroup$




















      1












      $begingroup$

      So I've managed to figure this out; Sean, Dave's and Jan's answers were extremely helpful and pointed me in the right direction (as were the comments).



      As mentioned, I was using MbedOS 5.11.2. This contained this issue whereby the CPU was locked out of deepsleep mode and wasn't disabling any timers/tickers etc... Updating to version 5.11.4 solved this issue and allowed the device to go into what I assume was STOP mode.



      I was then able to utilise the HAL and go into STANDBY mode, the resulting end current draw of my idle loop was ~ 550 nA. Here's how I am putting the device into STANDBY mode:



      #include "mbed.h"

      int main()

      HAL_Init();

      __HAL_RCC_PWR_CLK_ENABLE();

      __HAL_RCC_GPIOA_CLK_ENABLE();
      __HAL_RCC_GPIOB_CLK_ENABLE();
      __HAL_RCC_GPIOC_CLK_ENABLE();
      __HAL_RCC_GPIOD_CLK_ENABLE();
      __HAL_RCC_GPIOH_CLK_ENABLE();
      __HAL_RCC_GPIOE_CLK_ENABLE();

      GPIO_InitTypeDef GPIO_InitStructure;
      GPIO_InitStructure.Pin = GPIO_PIN_All;
      GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
      GPIO_InitStructure.Pull = GPIO_NOPULL;

      HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
      HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
      HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
      HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
      HAL_GPIO_Init(GPIOH, &GPIO_InitStructure);
      HAL_GPIO_Init(GPIOE, &GPIO_InitStructure);

      /* Disable GPIOs clock */
      __HAL_RCC_GPIOA_CLK_DISABLE();
      __HAL_RCC_GPIOB_CLK_DISABLE();
      __HAL_RCC_GPIOC_CLK_DISABLE();
      __HAL_RCC_GPIOD_CLK_DISABLE();
      __HAL_RCC_GPIOH_CLK_DISABLE();
      __HAL_RCC_GPIOE_CLK_DISABLE();

      /* Enable Ultra low power mode */
      HAL_PWREx_EnableUltraLowPower();

      __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
      HAL_PWR_EnterSTANDBYMode();






      share|improve this answer









      $endgroup$












      • $begingroup$
        FYI, I have a library for Standby mode on STM32 with Mbed: github.com/janjongboom/stm32-standby-rtc-wakeup
        $endgroup$
        – Jan Jongboom
        Mar 18 at 17:27











      Your Answer






      StackExchange.ifUsing("editor", function ()
      return StackExchange.using("schematics", function ()
      StackExchange.schematics.init();
      );
      , "cicuitlab");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "135"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: false,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













      draft saved

      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2felectronics.stackexchange.com%2fquestions%2f427383%2fwhats-causing-this-power-spike-in-stm32-low-power-mode%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      10












      $begingroup$

      I can't speak about mbed specifically, but the general idea is that sleep() causes the execution of the current process to pause for some number of seconds, or indefinitely if no argument (equivalent to an argument of 0) is given.



      In a multiprocess environment, that means that it simply yields the CPU to other processes. If there are no other processes ready to run, the OS may or may not put the CPU into a low-power state while waiting for interrupts — it depends on how the idle() task is written. This would not generally be the lowest-power state available on the CPU, however, since it wants to wake quickly when interrupts occur.



      In your case, it appears to be waking up once a second to handle the system timer tick.



      If you really want to get into a lower-power state, there are generally platform-specific calls for that, and that's exactly the sort of thing the HAL is for. You shouldn't avoid it, you should learn it.




      After a quick search, I discovered that the documentation here: APIs - power management discusses this specifically.






      share|improve this answer











      $endgroup$












      • $begingroup$
        Thanks for your response, very useful. In Mbed, sleep() is supposed to place to CPU into a low-power mode, but no documentation that I can find explains this logic. I've disabled the SysTick IRQ in the NVIC to no avail, I guess I'll just keep turning off timers/counters until it disappears..
        $endgroup$
        – Adam Mitchell
        Mar 15 at 14:34






      • 1




        $begingroup$
        @AdamMitchell - more likely what you need to do is actually read through the Mbed code (it is open source, even if by default they link a binary version of it) and figure out what they are doing, then decide if that can be brought into alignment with your goals, or if their goals are just too different.
        $endgroup$
        – Chris Stratton
        Mar 15 at 15:32
















      10












      $begingroup$

      I can't speak about mbed specifically, but the general idea is that sleep() causes the execution of the current process to pause for some number of seconds, or indefinitely if no argument (equivalent to an argument of 0) is given.



      In a multiprocess environment, that means that it simply yields the CPU to other processes. If there are no other processes ready to run, the OS may or may not put the CPU into a low-power state while waiting for interrupts — it depends on how the idle() task is written. This would not generally be the lowest-power state available on the CPU, however, since it wants to wake quickly when interrupts occur.



      In your case, it appears to be waking up once a second to handle the system timer tick.



      If you really want to get into a lower-power state, there are generally platform-specific calls for that, and that's exactly the sort of thing the HAL is for. You shouldn't avoid it, you should learn it.




      After a quick search, I discovered that the documentation here: APIs - power management discusses this specifically.






      share|improve this answer











      $endgroup$












      • $begingroup$
        Thanks for your response, very useful. In Mbed, sleep() is supposed to place to CPU into a low-power mode, but no documentation that I can find explains this logic. I've disabled the SysTick IRQ in the NVIC to no avail, I guess I'll just keep turning off timers/counters until it disappears..
        $endgroup$
        – Adam Mitchell
        Mar 15 at 14:34






      • 1




        $begingroup$
        @AdamMitchell - more likely what you need to do is actually read through the Mbed code (it is open source, even if by default they link a binary version of it) and figure out what they are doing, then decide if that can be brought into alignment with your goals, or if their goals are just too different.
        $endgroup$
        – Chris Stratton
        Mar 15 at 15:32














      10












      10








      10





      $begingroup$

      I can't speak about mbed specifically, but the general idea is that sleep() causes the execution of the current process to pause for some number of seconds, or indefinitely if no argument (equivalent to an argument of 0) is given.



      In a multiprocess environment, that means that it simply yields the CPU to other processes. If there are no other processes ready to run, the OS may or may not put the CPU into a low-power state while waiting for interrupts — it depends on how the idle() task is written. This would not generally be the lowest-power state available on the CPU, however, since it wants to wake quickly when interrupts occur.



      In your case, it appears to be waking up once a second to handle the system timer tick.



      If you really want to get into a lower-power state, there are generally platform-specific calls for that, and that's exactly the sort of thing the HAL is for. You shouldn't avoid it, you should learn it.




      After a quick search, I discovered that the documentation here: APIs - power management discusses this specifically.






      share|improve this answer











      $endgroup$



      I can't speak about mbed specifically, but the general idea is that sleep() causes the execution of the current process to pause for some number of seconds, or indefinitely if no argument (equivalent to an argument of 0) is given.



      In a multiprocess environment, that means that it simply yields the CPU to other processes. If there are no other processes ready to run, the OS may or may not put the CPU into a low-power state while waiting for interrupts — it depends on how the idle() task is written. This would not generally be the lowest-power state available on the CPU, however, since it wants to wake quickly when interrupts occur.



      In your case, it appears to be waking up once a second to handle the system timer tick.



      If you really want to get into a lower-power state, there are generally platform-specific calls for that, and that's exactly the sort of thing the HAL is for. You shouldn't avoid it, you should learn it.




      After a quick search, I discovered that the documentation here: APIs - power management discusses this specifically.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Mar 15 at 15:18

























      answered Mar 15 at 14:07









      Dave TweedDave Tweed

      124k10154269




      124k10154269











      • $begingroup$
        Thanks for your response, very useful. In Mbed, sleep() is supposed to place to CPU into a low-power mode, but no documentation that I can find explains this logic. I've disabled the SysTick IRQ in the NVIC to no avail, I guess I'll just keep turning off timers/counters until it disappears..
        $endgroup$
        – Adam Mitchell
        Mar 15 at 14:34






      • 1




        $begingroup$
        @AdamMitchell - more likely what you need to do is actually read through the Mbed code (it is open source, even if by default they link a binary version of it) and figure out what they are doing, then decide if that can be brought into alignment with your goals, or if their goals are just too different.
        $endgroup$
        – Chris Stratton
        Mar 15 at 15:32

















      • $begingroup$
        Thanks for your response, very useful. In Mbed, sleep() is supposed to place to CPU into a low-power mode, but no documentation that I can find explains this logic. I've disabled the SysTick IRQ in the NVIC to no avail, I guess I'll just keep turning off timers/counters until it disappears..
        $endgroup$
        – Adam Mitchell
        Mar 15 at 14:34






      • 1




        $begingroup$
        @AdamMitchell - more likely what you need to do is actually read through the Mbed code (it is open source, even if by default they link a binary version of it) and figure out what they are doing, then decide if that can be brought into alignment with your goals, or if their goals are just too different.
        $endgroup$
        – Chris Stratton
        Mar 15 at 15:32
















      $begingroup$
      Thanks for your response, very useful. In Mbed, sleep() is supposed to place to CPU into a low-power mode, but no documentation that I can find explains this logic. I've disabled the SysTick IRQ in the NVIC to no avail, I guess I'll just keep turning off timers/counters until it disappears..
      $endgroup$
      – Adam Mitchell
      Mar 15 at 14:34




      $begingroup$
      Thanks for your response, very useful. In Mbed, sleep() is supposed to place to CPU into a low-power mode, but no documentation that I can find explains this logic. I've disabled the SysTick IRQ in the NVIC to no avail, I guess I'll just keep turning off timers/counters until it disappears..
      $endgroup$
      – Adam Mitchell
      Mar 15 at 14:34




      1




      1




      $begingroup$
      @AdamMitchell - more likely what you need to do is actually read through the Mbed code (it is open source, even if by default they link a binary version of it) and figure out what they are doing, then decide if that can be brought into alignment with your goals, or if their goals are just too different.
      $endgroup$
      – Chris Stratton
      Mar 15 at 15:32





      $begingroup$
      @AdamMitchell - more likely what you need to do is actually read through the Mbed code (it is open source, even if by default they link a binary version of it) and figure out what they are doing, then decide if that can be brought into alignment with your goals, or if their goals are just too different.
      $endgroup$
      – Chris Stratton
      Mar 15 at 15:32














      2












      $begingroup$

      As explained in the documentation, the following drivers can prevent deep sleep:




      • Ticker

      • Timeout

      • Timer

      • SPI

      • I2C

      • CAN

      • SerialBase



      If you need to identify what is blocking deep sleep, you can build from the command line, and enable the verbose debugging - even though it seems you do not have any in your example.



      You can also review the tickless documentation. I believe this mode is relatively new, so it is possible that your platform has some problems in the HAL.






      share|improve this answer









      $endgroup$

















        2












        $begingroup$

        As explained in the documentation, the following drivers can prevent deep sleep:




        • Ticker

        • Timeout

        • Timer

        • SPI

        • I2C

        • CAN

        • SerialBase



        If you need to identify what is blocking deep sleep, you can build from the command line, and enable the verbose debugging - even though it seems you do not have any in your example.



        You can also review the tickless documentation. I believe this mode is relatively new, so it is possible that your platform has some problems in the HAL.






        share|improve this answer









        $endgroup$















          2












          2








          2





          $begingroup$

          As explained in the documentation, the following drivers can prevent deep sleep:




          • Ticker

          • Timeout

          • Timer

          • SPI

          • I2C

          • CAN

          • SerialBase



          If you need to identify what is blocking deep sleep, you can build from the command line, and enable the verbose debugging - even though it seems you do not have any in your example.



          You can also review the tickless documentation. I believe this mode is relatively new, so it is possible that your platform has some problems in the HAL.






          share|improve this answer









          $endgroup$



          As explained in the documentation, the following drivers can prevent deep sleep:




          • Ticker

          • Timeout

          • Timer

          • SPI

          • I2C

          • CAN

          • SerialBase



          If you need to identify what is blocking deep sleep, you can build from the command line, and enable the verbose debugging - even though it seems you do not have any in your example.



          You can also review the tickless documentation. I believe this mode is relatively new, so it is possible that your platform has some problems in the HAL.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Mar 15 at 20:29









          Sean HoulihaneSean Houlihane

          3,41211223




          3,41211223





















              2












              $begingroup$

              If you enable tickless mode (via MBED_TICKLESS=1) and just pause the thread (via wait_ms(10000)) you won't see any spikes, and the MCU will stay in Stop mode (at least on my STM32F4 board).






              share|improve this answer









              $endgroup$

















                2












                $begingroup$

                If you enable tickless mode (via MBED_TICKLESS=1) and just pause the thread (via wait_ms(10000)) you won't see any spikes, and the MCU will stay in Stop mode (at least on my STM32F4 board).






                share|improve this answer









                $endgroup$















                  2












                  2








                  2





                  $begingroup$

                  If you enable tickless mode (via MBED_TICKLESS=1) and just pause the thread (via wait_ms(10000)) you won't see any spikes, and the MCU will stay in Stop mode (at least on my STM32F4 board).






                  share|improve this answer









                  $endgroup$



                  If you enable tickless mode (via MBED_TICKLESS=1) and just pause the thread (via wait_ms(10000)) you won't see any spikes, and the MCU will stay in Stop mode (at least on my STM32F4 board).







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Mar 18 at 13:48









                  Jan JongboomJan Jongboom

                  27117




                  27117





















                      1












                      $begingroup$

                      So I've managed to figure this out; Sean, Dave's and Jan's answers were extremely helpful and pointed me in the right direction (as were the comments).



                      As mentioned, I was using MbedOS 5.11.2. This contained this issue whereby the CPU was locked out of deepsleep mode and wasn't disabling any timers/tickers etc... Updating to version 5.11.4 solved this issue and allowed the device to go into what I assume was STOP mode.



                      I was then able to utilise the HAL and go into STANDBY mode, the resulting end current draw of my idle loop was ~ 550 nA. Here's how I am putting the device into STANDBY mode:



                      #include "mbed.h"

                      int main()

                      HAL_Init();

                      __HAL_RCC_PWR_CLK_ENABLE();

                      __HAL_RCC_GPIOA_CLK_ENABLE();
                      __HAL_RCC_GPIOB_CLK_ENABLE();
                      __HAL_RCC_GPIOC_CLK_ENABLE();
                      __HAL_RCC_GPIOD_CLK_ENABLE();
                      __HAL_RCC_GPIOH_CLK_ENABLE();
                      __HAL_RCC_GPIOE_CLK_ENABLE();

                      GPIO_InitTypeDef GPIO_InitStructure;
                      GPIO_InitStructure.Pin = GPIO_PIN_All;
                      GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
                      GPIO_InitStructure.Pull = GPIO_NOPULL;

                      HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
                      HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
                      HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
                      HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
                      HAL_GPIO_Init(GPIOH, &GPIO_InitStructure);
                      HAL_GPIO_Init(GPIOE, &GPIO_InitStructure);

                      /* Disable GPIOs clock */
                      __HAL_RCC_GPIOA_CLK_DISABLE();
                      __HAL_RCC_GPIOB_CLK_DISABLE();
                      __HAL_RCC_GPIOC_CLK_DISABLE();
                      __HAL_RCC_GPIOD_CLK_DISABLE();
                      __HAL_RCC_GPIOH_CLK_DISABLE();
                      __HAL_RCC_GPIOE_CLK_DISABLE();

                      /* Enable Ultra low power mode */
                      HAL_PWREx_EnableUltraLowPower();

                      __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
                      HAL_PWR_EnterSTANDBYMode();






                      share|improve this answer









                      $endgroup$












                      • $begingroup$
                        FYI, I have a library for Standby mode on STM32 with Mbed: github.com/janjongboom/stm32-standby-rtc-wakeup
                        $endgroup$
                        – Jan Jongboom
                        Mar 18 at 17:27















                      1












                      $begingroup$

                      So I've managed to figure this out; Sean, Dave's and Jan's answers were extremely helpful and pointed me in the right direction (as were the comments).



                      As mentioned, I was using MbedOS 5.11.2. This contained this issue whereby the CPU was locked out of deepsleep mode and wasn't disabling any timers/tickers etc... Updating to version 5.11.4 solved this issue and allowed the device to go into what I assume was STOP mode.



                      I was then able to utilise the HAL and go into STANDBY mode, the resulting end current draw of my idle loop was ~ 550 nA. Here's how I am putting the device into STANDBY mode:



                      #include "mbed.h"

                      int main()

                      HAL_Init();

                      __HAL_RCC_PWR_CLK_ENABLE();

                      __HAL_RCC_GPIOA_CLK_ENABLE();
                      __HAL_RCC_GPIOB_CLK_ENABLE();
                      __HAL_RCC_GPIOC_CLK_ENABLE();
                      __HAL_RCC_GPIOD_CLK_ENABLE();
                      __HAL_RCC_GPIOH_CLK_ENABLE();
                      __HAL_RCC_GPIOE_CLK_ENABLE();

                      GPIO_InitTypeDef GPIO_InitStructure;
                      GPIO_InitStructure.Pin = GPIO_PIN_All;
                      GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
                      GPIO_InitStructure.Pull = GPIO_NOPULL;

                      HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
                      HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
                      HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
                      HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
                      HAL_GPIO_Init(GPIOH, &GPIO_InitStructure);
                      HAL_GPIO_Init(GPIOE, &GPIO_InitStructure);

                      /* Disable GPIOs clock */
                      __HAL_RCC_GPIOA_CLK_DISABLE();
                      __HAL_RCC_GPIOB_CLK_DISABLE();
                      __HAL_RCC_GPIOC_CLK_DISABLE();
                      __HAL_RCC_GPIOD_CLK_DISABLE();
                      __HAL_RCC_GPIOH_CLK_DISABLE();
                      __HAL_RCC_GPIOE_CLK_DISABLE();

                      /* Enable Ultra low power mode */
                      HAL_PWREx_EnableUltraLowPower();

                      __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
                      HAL_PWR_EnterSTANDBYMode();






                      share|improve this answer









                      $endgroup$












                      • $begingroup$
                        FYI, I have a library for Standby mode on STM32 with Mbed: github.com/janjongboom/stm32-standby-rtc-wakeup
                        $endgroup$
                        – Jan Jongboom
                        Mar 18 at 17:27













                      1












                      1








                      1





                      $begingroup$

                      So I've managed to figure this out; Sean, Dave's and Jan's answers were extremely helpful and pointed me in the right direction (as were the comments).



                      As mentioned, I was using MbedOS 5.11.2. This contained this issue whereby the CPU was locked out of deepsleep mode and wasn't disabling any timers/tickers etc... Updating to version 5.11.4 solved this issue and allowed the device to go into what I assume was STOP mode.



                      I was then able to utilise the HAL and go into STANDBY mode, the resulting end current draw of my idle loop was ~ 550 nA. Here's how I am putting the device into STANDBY mode:



                      #include "mbed.h"

                      int main()

                      HAL_Init();

                      __HAL_RCC_PWR_CLK_ENABLE();

                      __HAL_RCC_GPIOA_CLK_ENABLE();
                      __HAL_RCC_GPIOB_CLK_ENABLE();
                      __HAL_RCC_GPIOC_CLK_ENABLE();
                      __HAL_RCC_GPIOD_CLK_ENABLE();
                      __HAL_RCC_GPIOH_CLK_ENABLE();
                      __HAL_RCC_GPIOE_CLK_ENABLE();

                      GPIO_InitTypeDef GPIO_InitStructure;
                      GPIO_InitStructure.Pin = GPIO_PIN_All;
                      GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
                      GPIO_InitStructure.Pull = GPIO_NOPULL;

                      HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
                      HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
                      HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
                      HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
                      HAL_GPIO_Init(GPIOH, &GPIO_InitStructure);
                      HAL_GPIO_Init(GPIOE, &GPIO_InitStructure);

                      /* Disable GPIOs clock */
                      __HAL_RCC_GPIOA_CLK_DISABLE();
                      __HAL_RCC_GPIOB_CLK_DISABLE();
                      __HAL_RCC_GPIOC_CLK_DISABLE();
                      __HAL_RCC_GPIOD_CLK_DISABLE();
                      __HAL_RCC_GPIOH_CLK_DISABLE();
                      __HAL_RCC_GPIOE_CLK_DISABLE();

                      /* Enable Ultra low power mode */
                      HAL_PWREx_EnableUltraLowPower();

                      __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
                      HAL_PWR_EnterSTANDBYMode();






                      share|improve this answer









                      $endgroup$



                      So I've managed to figure this out; Sean, Dave's and Jan's answers were extremely helpful and pointed me in the right direction (as were the comments).



                      As mentioned, I was using MbedOS 5.11.2. This contained this issue whereby the CPU was locked out of deepsleep mode and wasn't disabling any timers/tickers etc... Updating to version 5.11.4 solved this issue and allowed the device to go into what I assume was STOP mode.



                      I was then able to utilise the HAL and go into STANDBY mode, the resulting end current draw of my idle loop was ~ 550 nA. Here's how I am putting the device into STANDBY mode:



                      #include "mbed.h"

                      int main()

                      HAL_Init();

                      __HAL_RCC_PWR_CLK_ENABLE();

                      __HAL_RCC_GPIOA_CLK_ENABLE();
                      __HAL_RCC_GPIOB_CLK_ENABLE();
                      __HAL_RCC_GPIOC_CLK_ENABLE();
                      __HAL_RCC_GPIOD_CLK_ENABLE();
                      __HAL_RCC_GPIOH_CLK_ENABLE();
                      __HAL_RCC_GPIOE_CLK_ENABLE();

                      GPIO_InitTypeDef GPIO_InitStructure;
                      GPIO_InitStructure.Pin = GPIO_PIN_All;
                      GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
                      GPIO_InitStructure.Pull = GPIO_NOPULL;

                      HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
                      HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
                      HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
                      HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
                      HAL_GPIO_Init(GPIOH, &GPIO_InitStructure);
                      HAL_GPIO_Init(GPIOE, &GPIO_InitStructure);

                      /* Disable GPIOs clock */
                      __HAL_RCC_GPIOA_CLK_DISABLE();
                      __HAL_RCC_GPIOB_CLK_DISABLE();
                      __HAL_RCC_GPIOC_CLK_DISABLE();
                      __HAL_RCC_GPIOD_CLK_DISABLE();
                      __HAL_RCC_GPIOH_CLK_DISABLE();
                      __HAL_RCC_GPIOE_CLK_DISABLE();

                      /* Enable Ultra low power mode */
                      HAL_PWREx_EnableUltraLowPower();

                      __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
                      HAL_PWR_EnterSTANDBYMode();







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Mar 18 at 15:19









                      Adam MitchellAdam Mitchell

                      1597




                      1597











                      • $begingroup$
                        FYI, I have a library for Standby mode on STM32 with Mbed: github.com/janjongboom/stm32-standby-rtc-wakeup
                        $endgroup$
                        – Jan Jongboom
                        Mar 18 at 17:27
















                      • $begingroup$
                        FYI, I have a library for Standby mode on STM32 with Mbed: github.com/janjongboom/stm32-standby-rtc-wakeup
                        $endgroup$
                        – Jan Jongboom
                        Mar 18 at 17:27















                      $begingroup$
                      FYI, I have a library for Standby mode on STM32 with Mbed: github.com/janjongboom/stm32-standby-rtc-wakeup
                      $endgroup$
                      – Jan Jongboom
                      Mar 18 at 17:27




                      $begingroup$
                      FYI, I have a library for Standby mode on STM32 with Mbed: github.com/janjongboom/stm32-standby-rtc-wakeup
                      $endgroup$
                      – Jan Jongboom
                      Mar 18 at 17:27

















                      draft saved

                      draft discarded
















































                      Thanks for contributing an answer to Electrical Engineering Stack Exchange!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      Use MathJax to format equations. MathJax reference.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2felectronics.stackexchange.com%2fquestions%2f427383%2fwhats-causing-this-power-spike-in-stm32-low-power-mode%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown






                      Popular posts from this blog

                      How to check contact read email or not when send email to Individual?

                      Bahrain

                      Postfix configuration issue with fips on centos 7; mailgun relay