GOing mad trying to sort out sleep mode on STM32F103 Bluepill board

Post here first, or if you can't find a relevant section!
asmallri
Posts: 16
Joined: Fri Oct 06, 2017 12:37 am

GOing mad trying to sort out sleep mode on STM32F103 Bluepill board

Post by asmallri » Sun Dec 10, 2017 8:03 pm

Hi,

I have a requirement to use both Sleep and Standby modes on a BluePill. I am using the STM32Sleep.h library for the Standby and it works as expected however the goToSleep() function in the library does not work correctly - it instead puts the processor in standby. I want to put the processor into deep sleep for x minutes and when out of deepsleep, put it into sleep when it is waiting external tasks. The processor exits deep sleep either as a result of an external wakeup on the WKUP pin or as a result of an RTC alarm. For sleep mode, I am using the RTC's one second interrupt to wake the processor from sleep every second. My code does not use any other interrupt functions.

I have looked at lots of code on this forum for the sleep and found that they don't work on my hardware and in all cases simply continue to execute immediately after the wfi statement. In all cases where the software appears to be correctly coded, the processor wakes immediately after executing the wfi command. I have observed this behavioour using a logic analyser and setting test pins before the wfi instruction and clearing it afterwards.

My Bluepill has the USB bootloader installed however the USB is only used for this function, it is not used for the application. I suspect the processor is being woken up from a core interrupt or from the bootloader. But I cannot find anything in other posted examples that try to address interrupts outside of the application itself. Am I missing something?

Code: Select all

#include <RTClock.h> 
#include <STM32Sleep.h>

RTClock rt (RTCSEL_LSE);  // Initialise RTC with LSE

// Defined for power and sleep functions pwr.h and scb.h
#include <libmaple/pwr.h>
#include <libmaple/scb.h>
#include <libmaple/iwdg.h>

#define TestPin1  PB6   // SCL1
#define TestPin2  PB7   // SDA1

volatile uint32_t globSecCnt = 0;
uint32_t lastGlobSecCnt = 0;


// RTC Seconds Interrupt Handler
void rtc_sec_intr(){ 
  if(rtc_is_second()){
    globSecCnt++;

    // clear the sesonds interrupt flag
    RTC_BASE->CRL &= ~(1<<RTC_CRL_SECF_BIT);    
    }
}


setup(){
  // .. other typical setup - no interrupt logic
  rt.attachSecondsInterrupt(rtc_sec_intr); 
}


void Snooze(void){  
  Clear the RTC Seconds Interrupt Flag
  if (RTC_BASE->CRL & (1<<RTC_CRL_SECF_BIT))
    RTC_BASE->CRL &= ~(1<<RTC_CRL_SECF_BIT);

  digitalWrite(TestPin2, HIGH);  
  
  // Clear PDDS and LPDS bits
  PWR_BASE->CR &= ~(PWR_CR_PDDS | PWR_CR_LPDS);
    
  // clear sleepdeep in the system control register
  SCB_BASE->SCR &= ~SCB_SCR_SLEEPDEEP;

  // Clear previous wakeup register by setting the CWUF bit
  PWR_BASE->CR |= PWR_CR_CWUF;
          
      
  // set Low-power sleep.
  PWR_BASE->CR |= PWR_CR_LPDS;
   
  // Now go into stop mode, wake up on interrupt
  asm("    wfi"); 
          
  // Clear SLEEPDEEP bit so we can use SLEEP mode
  SCB_BASE->SCR &= ~SCB_SCR_SLEEPDEEP;   

  digitalWrite(TestPin2, LOW);   
}  
Below if an extract of my operational standby code

Code: Select all

  breakTime(rt.getTime(), dateTime); 
  uint16_t SleepSeconds = (Config.ScanInterval - ((dateTime.Minute + 1) % Config.ScanInterval)) * 60 + 60 - dateTime.Second - 6;

  // enable wakeup pin
  PWR_BASE->CSR |= PWR_CSR_EWUP;
  sleepAndWakeUp(STANDBY, &rt, SleepSeconds); 
 

stevestrong
Posts: 1977
Joined: Mon Oct 19, 2015 12:06 am
Location: Munich, Germany
Contact:

Re: GOing mad trying to sort out sleep mode on STM32F103 Bluepill board

Post by stevestrong » Mon Dec 11, 2017 12:25 pm

Do you power the board from the USB? If so, then no wonder, because the serial USB is started and working in the background.
If you don't need USB serial, then you should remove the compiler directive "-DSERIAL_USB" from the boards.txt line corresponding to the plue pill.

asmallri
Posts: 16
Joined: Fri Oct 06, 2017 12:37 am

Re: GOing mad trying to sort out sleep mode on STM32F103 Bluepill board

Post by asmallri » Mon Dec 11, 2017 4:15 pm

Thanks. I do not power the Bluepill via USB, I have a modified cable that has the USB power wire disconnected. There is a flaw with the Bluepill that connects the USB directly to the +5volt rail so if you power it externally and use USB large currents can flow from the power supply to the attached USB device.

I will try the directive for the board.txt file.

Thanks, Andrew

edogaldo
Posts: 291
Joined: Fri Jun 03, 2016 8:19 am

Re: GOing mad trying to sort out sleep mode on STM32F103 Bluepill board

Post by edogaldo » Tue Dec 12, 2017 7:47 am

Hello Andrew, the problem is likely due to the systick interrupt which triggers every ms.

Best, E.

ag123
Posts: 836
Joined: Thu Jul 21, 2016 4:24 pm

Re: GOing mad trying to sort out sleep mode on STM32F103 Bluepill board

Post by ag123 » Tue Dec 12, 2017 1:40 pm

i'm not too sure if it is possible to mask certain interrupts, arm interrupts , faults & isr is rather elaborate / complicated
incidentally found an app note about the low power modes as well
http://www.st.com/content/ccc/resource/ ... 171691.pdf

i didn't need sleep, so i just keep rtc running on vbat from a coin cell, disconnecting power if it isn't needed ;)

asmallri
Posts: 16
Joined: Fri Oct 06, 2017 12:37 am

Re: GOing mad trying to sort out sleep mode on STM32F103 Bluepill board

Post by asmallri » Wed Dec 13, 2017 5:40 am

Thanks everyone. Here is what I found,

There were two primary sources of interrupts that were waking the processor up outside of my application. The first was the USB from the bootloader. I did not want to create a custom boards file. I have seen this approach is just too hard to manage over time. Instead the very first instruction in my setup was:

Code: Select all

  // disable USB interrupts
  Serial.end();
Once I did this the external interrupts reduced to once per millisecond. I could view this on the logic analyser

Code: Select all

  digitalWrite(TestPin2, HIGH); 
   
  // Now go into stop mode, wake up on interrupt
  asm("    wfi"); 

  digitalWrite(TestPin2, LOW);  
Looking at the waveform on a logic analyser, I could see the processor was sleeping for approximately 970us and was awake for 30us. What was surprising was that there was no measurable decrease in current consumption. I remember reading on this forum somewhere that sleep mode did not make much difference but that was an understatement.

My next attempt was to stop the systick interrupt but not really expecting any improvement because of the insignificant time the processor was awake. To do this I implemented the following:

Code: Select all

  digitalWrite(TestPin2, HIGH); 
  
   systick_disable();
  // Now go into stop mode, wake up on interrupt
  asm("    wfi"); 
  systick_enable();

  digitalWrite(TestPin2, LOW);  
This code removed the 1ms system interrupt and I could see the processor staying in the sleep mode for several seconds (as it should for my application) but when it woke up it continues to operate as expected, based on monitoring the current consumption as it stepped through the various stages of my application, but it killed all serial comms.

I am not going to bother debugging the comms issue because the saving in current consumption would be trivial for the 30us every 1000us the processor is awake.

User avatar
RogerClark
Posts: 7555
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: GOing mad trying to sort out sleep mode on STM32F103 Bluepill board

Post by RogerClark » Wed Dec 13, 2017 8:37 am

FYI

At the moment Serial.end () does not power down the USB Serial . This is a known "feature" and there is a PR pending to fix this.

User avatar
mrburnette
Posts: 2065
Joined: Mon Apr 27, 2015 12:50 pm
Location: Greater Atlanta
Contact:

Re: GOing mad trying to sort out sleep mode on STM32F103 Bluepill board

Post by mrburnette » Wed Dec 13, 2017 2:57 pm

RogerClark wrote:
Wed Dec 13, 2017 8:37 am
FYI

At the moment Serial.end () does not power down the USB Serial . This is a known "feature" and there is a PR pending to fix this.
... of course, such a "fix" will kill serial enumeration over USB ... might as well unplug the USB cable. the fun part of this is that re-enumeration may not take on the same port number. Oh, joy ...

Ray

edogaldo
Posts: 291
Joined: Fri Jun 03, 2016 8:19 am

Re: GOing mad trying to sort out sleep mode on STM32F103 Bluepill board

Post by edogaldo » Wed Dec 13, 2017 4:48 pm

Wouldn't it be enough to re-execute a Serial.begin() at wakeup?!

User avatar
RogerClark
Posts: 7555
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: GOing mad trying to sort out sleep mode on STM32F103 Bluepill board

Post by RogerClark » Wed Dec 13, 2017 7:09 pm

As the IDE sends the command to reboot ( into the bootloader) via serial USB, if you call Serial.end() It will most likely remove the ability for the core to receive the reboot command.

The core secretly calls Serial.begin() as part of the core init, to enable this feature.

I have not tested the PR to turn off USB power, when Serial.end() is called, but it seems a logical extension of what Serial.end() already does.

Post Reply