Acheiving Low Power

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderators: RoccoMarco, barthess

Tabulous
Posts: 509
Joined: Fri May 03, 2013 12:02 pm
Has thanked: 7 times
Been thanked: 17 times

Acheiving Low Power

Postby Tabulous » Thu Mar 16, 2017 11:12 am

Just looking for suggestions has to if i've missed anything when entering sleep mode with evt wakeup.
Current consumption of MCU is still around 2-3mA which cannot be right......Datasheet suggests around 500uA when HSI is 16Mhz with PLL off and Peripherals disabled.


Heres the console code that puts it to sleep.

Code: Select all

static void cmd_sleep(BaseSequentialStream *chp, int argc, char *argv[]) {
int i;
char cmd[20];
msg_t result;
char *response;


  (void)argv;
  if (argc > 0)
  {
      if (strstr(argv[0], "zzz") != NULL)
      {
          /* Switch off the gsm modem */
          result = modemTakeAccess(MS2ST( 20000 ));

          if( result != MSG_OK )
          {
              chprintf(chp, "gsm access err\r\n");
              return;
          }
          else
          {
              chsnprintf(cmd, sizeof(cmd),
                         "%s\r", "at+qpowd=0;");

              response = modemExecCommand(cmd, 3 );

              if( strstr( response, "OK" ) != NULL )
              {
                  chprintf(chp, "gsm powered off\r\n");

                  /* Disable the power to the gnss */
                  palSetPad( GPIOE, GPIOE_GNSS_PWR );
                  chprintf(chp, "gnss powered off\r\n");

                  /* Configure exti to events mode */
                  extiConfigLowPowerMode();
                  chprintf( chp, "setup exti event\r\n" );

                  /* Set alarm to wakup in 60 seconds */
                  clkAlarmSet( ALMMUL_SEC, 60 );
                  chprintf( chp, "alarm wakeup 60s\r\n" );

                  chThdSleepMilliseconds(1000);
                  chprintf(chp, "Entering sleep zzz \r\n");
                  chThdSleepMilliseconds(1000);

                  /* Set all I/O pins to Analog inputs */
                  for( i = 0; i < 16; i++ )
                   {
                       palSetPadMode( GPIOA, i,
                                      PAL_MODE_INPUT_ANALOG );

                       palSetPadMode( GPIOB, i,
                                      PAL_MODE_INPUT_ANALOG );

                       palSetPadMode( GPIOC, i,
                                      PAL_MODE_INPUT_ANALOG );

                       palSetPadMode( GPIOD, i,
                                      PAL_MODE_INPUT_ANALOG );

                       palSetPadMode( GPIOE, i,
                                      PAL_MODE_INPUT_ANALOG );

                       palSetPadMode( GPIOH, ( i % 2 ),
                                      PAL_MODE_INPUT_ANALOG );
                   }

                  /* disable clock sources on the buses */
                  RCC->AHB2ENR &= ~( RCC_AHB2ENR_OTGFSEN );

                  RCC->APB1ENR &= ~( RCC_APB1ENR_TIM2EN | \
                                     RCC_APB1ENR_TIM3EN | \
                                     RCC_APB1ENR_TIM4EN | \
                                     RCC_APB1ENR_TIM5EN | \
                                     RCC_APB1ENR_WWDGEN | \
                                     RCC_APB1ENR_SPI2EN | \
                                     RCC_APB1ENR_SPI3EN | \
                                     RCC_APB1ENR_I2C1EN | \
                                     RCC_APB1ENR_I2C2EN | \
                                     RCC_APB1ENR_I2C3EN | \
                                     RCC_APB1ENR_USART2EN );

                  RCC->AHB1ENR &= ~( RCC_AHB1ENR_DMA1EN | \
                                     RCC_AHB1ENR_DMA2EN | \
                                     RCC_AHB1ENR_GPIOAEN | \
                                     RCC_AHB1ENR_GPIOBEN | \
                                     RCC_AHB1ENR_GPIOCEN | \
                                     RCC_AHB1ENR_GPIODEN | \
                                     RCC_AHB1ENR_GPIOEEN | \
                                     RCC_AHB1ENR_GPIOHEN );

                  RCC->APB2ENR &= ~( RCC_APB2ENR_TIM1EN | \
                                     RCC_APB2ENR_ADC1EN | \
                                     RCC_APB2ENR_SDIOEN | \
                                     RCC_APB2ENR_SPI1EN | \
                                     RCC_APB2ENR_SPI4EN | \
                                     RCC_APB2ENR_SPI5EN | \
                                     RCC_APB2ENR_TIM9EN | \
                                     RCC_APB2ENR_TIM10EN | \
                                     RCC_APB2ENR_TIM11EN | \
                                     RCC_APB2ENR_SYSCFGEN | \
                                     RCC_APB2ENR_USART1EN | \
                                     RCC_APB2ENR_USART6EN );

                  /* swtich clock source to HSI as we need
                   * to disable the phase locked loop  */

                  /* Enable HSI clock */
                  RCC->CR |= RCC_CR_HSION;

                  /* Wait for HSI is ready */
                  while (!(RCC->CR & RCC_CR_HSIRDY));

                  /* Select HSI clock as main clock */
                  RCC->CFGR &= ~( RCC_CFGR_SW );
                  RCC->CFGR |= RCC_CFGR_SW_HSI;

                  /* Disable PLL clock */
                  RCC->CR &= ~RCC_CR_PLLON;

                  /* start teh process of entering sleep
                   * mode. On exit we do system reset  */

                  /* clear PDDS bit safety */
                  PWR->CR &= ~( PWR_CR_PDDS );

                  /* set LPDS, clear flags */
                  PWR->CR |= ( PWR_CR_LPDS | \
                               PWR_CR_CSBF | \
                               PWR_CR_CWUF | \
                               PWR_CR_FPDS );

                  /* set the deep sleep mask */
                  SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;

                  chSysLock();
                  __SEV();
                  __WFE();
                  __WFE();
                  chSysUnlock();

                  /* clear the deep sleep mask */
                  SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;

                  /* reset the system to restart */
                  __ASM volatile ("dsb");

                  /* Keep priority group unchanged */
                  SCB->AIRCR  = ((0x5FA << SCB_AIRCR_VECTKEY_Pos)      |        \
                                 (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |        \
                                  SCB_AIRCR_SYSRESETREQ_Msk);

                  __ASM volatile ("dsb");
                  return;
              }
              else
              {
                  chprintf(chp, "modem command err\r\n");
              }

              modemGiveAccess();
          }

          return;
      }
  }
}

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: Acheiving Low Power

Postby Giovanni » Thu Mar 16, 2017 8:04 pm

Is the consumption measured at board level or just the MCU?

Giovanni

Tabulous
Posts: 509
Joined: Fri May 03, 2013 12:02 pm
Has thanked: 7 times
Been thanked: 17 times

Re: Acheiving Low Power

Postby Tabulous » Fri Mar 17, 2017 10:55 am

Giovanni wrote:Is the consumption measured at board level or just the MCU?

Giovanni


Its at board level but i can isolate parts of the board. Am down at around 3.9mA now for the total board, this is more than ok for what we need :-)


Return to “STM32 Support”

Who is online

Users browsing this forum: No registered users and 16 guests