Go Down

Topic: how to enter/exit stop mode on STM32F405RG (Read 579 times) previous topic - next topic

jun76

Hi.

I'm developing on Wio LTE Cat.1 (processor: STM32F405RG) + Arduino IDE ver.1.8.8.

To reduce power consumption, I want to use stop mode. (STM32F40x Reference manual P.100 stop mode)

Here is my code.

Code: [Select]

#include <WioLTEforArduino.h>
#include <RTClock.h>
#include <libmaple/pwr.h>
#include <libmaple/scb.h>

#define PWR_CR_CWUF_Msk  (1UL << PWR_CR_CWUF)
#define PWR_CR_PDDS_Msk  (1UL << PWR_CR_PDDS)
#define PWR_CR_LPDS_Msk  (1UL << PWR_CR_LPDS)
#define PWR_CSR_WUF_Msk  (1UL << PWR_CSR_WUF)
#define RTC_CR_WUTIE_Msk (1UL << RTC_CR_WUTIE_BIT)
#define RTC_ISR_WUTF_Msk (1UL << RTC_ISR_WUTF_BIT)

WioLTE wio;
RTClock rt(RTCSEL_LSE);

void setup(void)
{
  wio.Init();
  SerialUSB.begin(115200);

  wio.LedSetRGB(0, 8, 0);
  delay(1000);
  wio.LedSetRGB(0, 0, 0);
  SerialUSB.println("setup done");
}

void enter_stop_mode(uint8_t sec)
{
  rt.setPeriodicWakeup(sec);

  /* WFI (Wait for Interrupt) or WFE (Wait for Event) while:
   *  - Set SLEEPDEEP bit in Cortex™-M4F System Control register
   *  - Clear PDDS bit in Power Control register (PWR_CR)
   *  - Select the voltage regulator mode by configuring LPDS bit in PWR_CR.
   */
  SCB_BASE->SCR |= SCB_SCR_SLEEPDEEP_Msk;
  PWR_BASE->CR &= ~PWR_CR_PDDS_Msk;
  PWR_BASE->CR |= PWR_CR_LPDS_Msk;

  /* Safe RTC alternate function wakeup flag clearing sequence
   *  When using RTC wakeup to wake up the device from the low-power modes:
   *   - Disable the RTC Wakeup interrupt (WUTIE bit in the RTC_CR register)
   *   - Clear the RTC Wakeup (WUTF) flag
   *   - Clear the PWR Wakeup (WUF) flag
   *   - Enable the RTC Wakeup interrupt
   *   - Re-enter the low power mode
   */
  RTC_BASE->CR &= ~RTC_CR_WUTIE_Msk;
  RTC_BASE->ISR &= ~RTC_ISR_WUTF_Msk;
  PWR_BASE->CR |= PWR_CR_CWUF_Msk;

  /* Clear the WUF Wakeup Flag after 2 System clock cycles */
  for (;;) {
    if (!(PWR_BASE->CSR & PWR_CSR_WUF_Msk)) {
      break;
    }
  }

  RTC_BASE->CR |= RTC_CR_WUTIE_Msk;

  asm("wfi");
}

void loop(void)
{
  SerialUSB.println("loop");
  wio.LedSetRGB(0, 0, 8);
  delay(1000);
  wio.LedSetRGB(0, 0, 0);

  enter_stop_mode(5);
}


The expected behavior is as follows:

1. green LED ON (1000ms) + serial usb output "setup done"
2. serial usb output "loop" + blue LED ON (1000ms)
3. enter stop mode (5000ms)
4. exit stop mode
5. goto 2.

but the actual behavior is as follows:

1. green LED ON (1000ms) + serial usb output "setup done"
2. serial usb output "loop" + blue LED ON (1000ms)
3. enter stop mode ?? (5000ms)
4. exit stop mode ??
5. white LED ON continuously (unexpected. very strong brightness)

LED is something wrong, and serial usb also may have disabled (never again output "loop").

Why is this behavior? Please teach me how to enter/exit stop mode correctly.

Thanks.

jun76

Calling setupClocks() and setupUSB(), LED is now OK. (but I don't know why setupUSB() is necessary...)

Code: [Select]

// Arduino15\packages\SeeedJP\hardware\Seeed_STM32F4\1.1.0\cores\arduino\boards.cpp
void setupClocks(void)
{
  rcc_clk_init(RCC_CLKSRC_PLL, RCC_PLLSRC_HSE, RCC_PLLMUL_9);
  rcc_set_prescaler(RCC_PRESCALER_AHB, RCC_AHB_SYSCLK_DIV_1);
  rcc_set_prescaler(RCC_PRESCALER_APB1, RCC_APB1_HCLK_DIV_2);
  rcc_set_prescaler(RCC_PRESCALER_APB2, RCC_APB2_HCLK_DIV_1);
}

// Arduino15\packages\SeeedJP\hardware\Seeed_STM32F4\1.1.0\cores\arduino\libmaple\usbF4\usb.c
void setupUSB (void) {
    #define USB_DISC_DEV         GPIOD
    #define USB_DISC_PIN         11

gpio_set_mode(USB_DISC_DEV, USB_DISC_PIN, GPIO_OUTPUT_OD); // ala42
#ifdef USB_DISC_OD
  //gpio_set_mode(USB_DISC_DEV, USB_DISC_PIN, GPIO_OUTPUT_OD); // ala42
#else
  //gpio_set_mode(USB_DISC_DEV, USB_DISC_PIN, GPIO_OUTPUT_PP); // ala42 for active pull-up on disconnect pin
#endif

  gpio_write_bit(USB_DISC_DEV, USB_DISC_PIN,0); // ala42
  delay_us(200000);

  /* setup the apb1 clock for USB */
  //rcc_reg_map *pRCC = RCC_BASE;
  //pRCC->APB1ENR |= RCC_APB1ENR_USBEN;

  /* initialize the usb application */
  gpio_write_bit(USB_DISC_DEV, USB_DISC_PIN, 1); // ala42 // presents us to the host
  USBD_Init(&USB_OTG_dev,
            USB_OTG_FS_CORE_ID,
            &USR_desc,
            &USBD_CDC_cb,
            &USR_cb);
}


USB serial is still dead. What should I do after wake up from stop mode?

Thanks.


DrAzzy

#2
Apr 16, 2019, 04:28 am Last Edit: Apr 16, 2019, 04:28 am by DrAzzy
Have you tried disconnecting and reconnecting to the serial port?

I don't have any specific knowledge relevant to STM32 - just thinking about how computers interact with serial ports.

You might do better on the forum dedicated to the board you're working with - all the non-AVR/SAM arduino cores have their own forums on different websites, full of people intimately familiar with those parts. I think I see a couple of posts here a month about STM32 - so clearly the STM32-with-arduino-ide people are hanging out somewhere else.
ATTinyCore for x4/x5/x61/x7/x8/x41/1634/828/x313 megaTinyCore for the megaavr ATtinies - Board Manager:
http://drazzy.com/package_drazzy.com_index.json
ATtiny breakouts, mosfets, awesome prototyping board in my store http://tindie.com/stores/DrAzzy

jun76

> Have you tried disconnecting and reconnecting to the serial port?

I can't try this because my evaluation board is power supplied by USB serial...
but I noticed such viewpoint, thank you.


Thank you for your advice. I'll try to find other STM32-specific forum.


Go Up