AnsweredAssumed Answered

STM32L100 Discovery - low power mode

Question asked by knezevic.marko on Jul 26, 2014
Latest reply on Oct 12, 2014 by abraham.yuval
Hi all,

I have been trying to measure current consumption for low power sleep mode with STM32l100 Discovery board. I'm using most of the code gathered from STM32 standard peripherial library without any component attached to the board. I start by configuring maximum frequency using HSEBYP (using STlink clock) and PLL, and then using MSI with HCLK=32khz and entering sleep. 

Problem is that I cannot get less than ~1000uA and the measured current is not steady, but changing as much as 300uA (while measuring). I'm measuring by attaching amp meter on JP2 jumper. The only idea that I'm having is that R27 and R26 can interfere with measurements since that line by my calculations would spend about 285uA, which still is not explaining high current consumption. Please help, startup code that I'm using for clocks is:

__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
 
/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/
 
/* Set external clock (generated by ST-LINK chip) */
RCC->CR |= ((uint32_t)RCC_CR_HSEBYP);
 
/* Enable HSE */
RCC->CR |= ((uint32_t)RCC_CR_HSEON);
 
/* Wait till HSE is ready and if Time out is reached exit */
do
{
  HSEStatus = RCC->CR & RCC_CR_HSERDY;
  StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
 
if ((RCC->CR & RCC_CR_HSERDY) != RESET)
{
  HSEStatus = (uint32_t)0x01;
}
else
{
  HSEStatus = (uint32_t)0x00;
}
 
if (HSEStatus == (uint32_t)0x01)
{
  /* Enable 64-bit access */
  FLASH->ACR |= FLASH_ACR_ACC64;
 
  /* Enable Prefetch Buffer */
  FLASH->ACR |= FLASH_ACR_PRFTEN;
 
  /* Flash 1 wait state */
  FLASH->ACR |= FLASH_ACR_LATENCY;
 
  /* Power enable */
  RCC->APB1ENR |= RCC_APB1ENR_PWREN;
 
  /* Select the Voltage Range 1 (1.8 V) */
  PWR->CR = PWR_CR_VOS_0;
 
  /* Wait Until the Voltage Regulator is ready */
  while((PWR->CSR & PWR_CSR_VOSF) != RESET)
  {
  }
 
  /* HCLK = SYSCLK /1*/
  RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
 
  /* PCLK2 = HCLK /1*/
  RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
 
  /* PCLK1 = HCLK /1*/
  RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;
 
  /*  PLL configuration */
  RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL |
                                      RCC_CFGR_PLLDIV));
  RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMUL12 | RCC_CFGR_PLLDIV3);
 
  /* Enable PLL */
  RCC->CR |= RCC_CR_PLLON;
 
  /* Wait till PLL is ready */
  while((RCC->CR & RCC_CR_PLLRDY) == 0)
  {
  }
 
  /* Select PLL as system clock source */
  RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
  RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
 
  /* Wait till PLL is used as system clock source */
  while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL)
  {
  }
}
else
{
  /* If HSE fails to start-up, the application will have wrong clock
     configuration. User can add here some code to deal with this error */
}

sleep function:
/* HCLK = SYSCLK/2 = ~32KHz */
RCC_HCLKConfig(RCC_SYSCLK_Div2);
 
/* PCLK2 = HCLK */
RCC_PCLK2Config(RCC_HCLK_Div1);
 
/* PCLK1 = HCLK */
RCC_PCLK1Config(RCC_HCLK_Div1);
 
/* Set MSI clock range to 65.536KHz */
RCC_MSIRangeConfig(RCC_MSIRange_0);
 
/* Select MSI as system clock source */
RCC_SYSCLKConfig(RCC_SYSCLKSource_MSI);
 
/* Wait till MSI is used as system clock source */
while (RCC_GetSYSCLKSource() != 0x00)
{
}
 
/* Flash 0 wait state */
FLASH_SetLatency(FLASH_Latency_0);
 
/* Disable Prefetch Buffer */
FLASH_PrefetchBufferCmd(DISABLE);
 
/* Disable 64-bit access */
FLASH_ReadAccess64Cmd(DISABLE);
 
/* Select the Voltage Range 2 (1.5V) */
PWR_VoltageScalingConfig(PWR_VoltageScaling_Range2);
 
/* Wait Until the Voltage Regulator is ready */
while (PWR_GetFlagStatus(PWR_FLAG_VOS) != RESET)
{
}
 
/* Configure all GPIO as analog to reduce current consumption on non used IOs */
/* Enable GPIOs clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC |
RCC_AHBPeriph_GPIOD | RCC_AHBPeriph_GPIOE | RCC_AHBPeriph_GPIOH |
RCC_AHBPeriph_GPIOF | RCC_AHBPeriph_GPIOG, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_Init(GPIOH, &GPIO_InitStructure);
GPIO_Init(GPIOF, &GPIO_InitStructure);
GPIO_Init(GPIOG, &GPIO_InitStructure);
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_Init(GPIOB, &GPIO_InitStructure);
 
/* Disable GPIOs clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC |
RCC_AHBPeriph_GPIOD | RCC_AHBPeriph_GPIOE | RCC_AHBPeriph_GPIOH |
RCC_AHBPeriph_GPIOF | RCC_AHBPeriph_GPIOG, DISABLE);
 
RCC_DeInit();
 
/* Enter RUN LP Mode */
PWR_EnterLowPowerRunMode(ENABLE);
 
/* Wait until the system enters RUN LP and the Regulator is in LP mode */
while (PWR_GetFlagStatus(PWR_FLAG_REGLP) == RESET)
{
}
 
PWR_UltraLowPowerCmd(ENABLE);
 
PWR_EnterSleepMode(PWR_Regulator_LowPower, PWR_SLEEPEntry_WFE);
 
/* Exit the RUN LP Mode */
PWR_EnterLowPowerRunMode(DISABLE);

and main funcion:
//enable GPIOC for input button, enable GPIOC AHBEN clock
InitializeApplication();
 
//disable all low power clocks (sync with normal clocks)
RCC->AHBLPENR = RCC->AHBENR;
RCC->APB1LPENR = RCC->APB1ENR;
RCC->APB2LPENR = RCC->APB2ENR;
while (1) {
    //led ON
    GPIO_SetBits(GPIOC, GPIO_Pin_9);
    //wait for user click
    while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==0){}
    //led OFF and goto low power
    GPIO_ResetBits(GPIOC, GPIO_Pin_9);
    STM32_PowerDown();
    while(1){
    //test if got out of low power / blink LED
    delay_ms(1);
    GPIO_ToggleBits(GPIOC, GPIO_Pin_9);
    }
}

Is there some misunderstanding about code or? This is not exactly a copy of STDPeriph library examples as I saw that sequence of some code is maybe not correct, but even with copy of demo I could not get low power numbers from MCU data sheets.

Best regards, Marko

Outcomes