/** * @brief This function initializes in Ultra Low Power mode, * disable the LCD, LSE and configures the unused IOs * in output push-pull * @caller main and ADC_Icc_Test * @param None * @retval None */ void Halt_Init(void) { /* Set STM8 in low power */ PWR->CSR2 = 0x2; LCD_Cmd(DISABLE); /* To wait LCD disable */ while ((LCD->CR3 & 0x40) != 0x00); /* Set GPIO in low power*/ GPIO_LowPower_Config(); /* Stop RTC Source clock */ CLK_RTCClockConfig(CLK_RTCCLKSource_Off, CLK_RTCCLKDiv_1); #ifdef USE_LSE CLK_LSEConfig(CLK_LSE_OFF); while ((CLK->ECKCR & 0x04) != 0x00); #else CLK_LSICmd(DISABLE); while ((CLK->ICKCR & 0x04) != 0x00); #endif /* Stop clock RTC and LCD */ CLK_PeripheralClockConfig(CLK_Peripheral_RTC, DISABLE); CLK_PeripheralClockConfig(CLK_Peripheral_LCD, DISABLE); }
/** * @brief Current measurement in different MCU modes: * RUN/SLEEP/LowPower/STANDBY with/without RTC * @caller main and ADC_Icc_Test * @param MCU state * @retval ADC value. */ uint16_t ADC_Icc_Test(uint8_t Mcu_State) { GPIO_InitTypeDef GPIO_InitStructure; uint16_t adc_measure; uint32_t i; RCC_TypeDef SavRCC; /* Reset UserButton State */ UserButton = FALSE; /* Start counter */ GPIO_HIGH(CTN_GPIO_PORT,CTN_CNTEN_GPIO_PIN); /* Disable the RTC Wakeup Interrupt */ RTC_ITConfig(RTC_IT_WUT, DISABLE); /* Disable LCD */ LCD_Cmd(DISABLE); /* wait until LCD disable */ while (LCD_GetFlagStatus(LCD_FLAG_ENS) == SET); /*Reset Idd-WakeUP flag*/ Idd_WakeUP = FALSE; /* Set IO in lowpower configuration*/ GPIO_LowPower_Config(); /*Disable fast wakeUp*/ PWR_FastWakeUpCmd(DISABLE); /* Test MCU state for configuration */ switch (Mcu_State) { /* Run mode : Measurement Measurement performed with MSI 4 MHz without RTC*/ case MCU_RUN: /* switch on MSI clock */ SetHSICLKToMSI(RCC_MSIRange_6,NoDIV2,NoRTC) ; /* shitch on MSI clock */ Config_RCC(&SavRCC); SysTick->CTRL = 0; RCC->APB1ENR = 0; /* To run nops during measurement: it's the best case for low current */ for (i=0;i<0xffff;i++) { __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); } break; /* SLEEP mode : Measurement performed with MSI 4 MHz without RTC in WFI mode*/ case MCU_SLEEP: SetHSICLKToMSI(RCC_MSIRange_6,NoDIV2,NoRTC) ; Config_RCC(&SavRCC); Config_Systick_50ms(); Delay(1); /* Request Wait For Interrupt */ PWR_EnterSleepMode(PWR_Regulator_ON,PWR_SLEEPEntry_WFI); break; /* RUN LOW POWER mode : Measurement performed with MSI 32 Khz without RTC */ case MCU_LP_RUN: /* Disable PVD */ PWR_PVDCmd(DISABLE); /* Enable The ultra Low Power Mode */ PWR_UltraLowPowerCmd(ENABLE); /* Save the RCC configuration registers */ Config_RCC(&SavRCC); /* Stop the sys tick in order to avoid IT */ SysTick->CTRL = 0; #ifdef TESTINRAM SetHSICLKToMSI(RCC_MSIRange_0,DIV2,NoRTC) ; PWR_EnterLowPowerRunMode(ENABLE); while(PWR_GetFlagStatus(PWR_FLAG_REGLP) == RESET) ; DisableInterrupts(); EnterLPRUNModeRAM(); EnableInterrupts(); #else /* Swith in MSI 32KHz */ SetHSICLKToMSI(RCC_MSIRange_64KHz,DIV2,NoRTC) ; PWR_EnterLowPowerRunMode(ENABLE); while(PWR_GetFlagStatus(PWR_FLAG_REGLP) == RESET) ; /* Launch the counter */ GPIO_LOW(CTN_GPIO_PORT,CTN_CNTEN_GPIO_PIN); /* To run the nop during measurement: it's the best case for low current until counter reach detected by IT --> Idd_WakeUP */ do{ __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); } while (Idd_WakeUP == FALSE ); #endif PWR_EnterLowPowerRunMode(DISABLE); while(PWR_GetFlagStatus(PWR_FLAG_REGLP) != RESET) ; break; /* SLEEP LOW POWER mode Measurement done to MSI 32 Khz without RTC */ case MCU_LP_SLEEP: /* Disable PVD */ PWR_PVDCmd(DISABLE); /* Enable Ultra low power mode */ PWR_UltraLowPowerCmd(ENABLE); /* To save the RCC configuration registers */ Config_RCC(&SavRCC); /* To stop the sys tick for avoid IT */ SysTick->CTRL = 0; /* Swith in MSI 32KHz */ SetHSICLKToMSI(RCC_MSIRange_0,DIV2,NoRTC) ; #ifdef TESTINRAM DisableInterrupts(); EnterLPSLEEPModeRAM(); EnableInterrupts(); #else /* Falling edge for start counter */ GPIO_LOW(CTN_GPIO_PORT,CTN_CNTEN_GPIO_PIN); /* Request Wait For Interrupt */ PWR_EnterSleepMode(PWR_Regulator_LowPower,PWR_SLEEPEntry_WFI); #endif break; /* STOP modes Measurement done to MSI 32 Khz without or with RTC */ case MCU_STOP_NoRTC: case MCU_STOP_RTC: /* Disable PVD */ PWR_PVDCmd(DISABLE); /* Enable Ultra low power mode */ PWR_UltraLowPowerCmd(ENABLE); /* To save the RCC configuration registers */ Config_RCC(&SavRCC); /* To stop the sys tick for avoid IT */ SysTick->CTRL = 0; /* Swith in MSI 32KHz */ if( Mcu_State == MCU_STOP_NoRTC ) SetHSICLKToMSI(RCC_MSIRange_0,DIV2,NoRTC) ; else SetHSICLKToMSI(RCC_MSIRange_0,DIV2,WITHRTC) ; /* Falling edge for start counter */ GPIO_LOW(CTN_GPIO_PORT,CTN_CNTEN_GPIO_PIN); /* Request Wait For Interrupt */ PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFI); break; /* Standby mode without RTC Measurement done to MSI 32 Khz without RTC */ case MCU_STBY: /* Disable PVD */ PWR_PVDCmd(DISABLE); /* Enable Ultra low power mode */ PWR_UltraLowPowerCmd(ENABLE); RTC_OutputTypeConfig(RTC_OutputType_PushPull); RTC_OutputConfig(RTC_Output_WakeUp,RTC_OutputPolarity_High); /* To configure PC13 WakeUP output */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 ; //GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 ; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_400KHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_Init( GPIOC, &GPIO_InitStructure); // GPIO_Init( GPIOA, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOC, GPIO_PinSource13,GPIO_AF_RTC_AF1) ; //GPIO_PinAFConfig(GPIOA, GPIO_PinSource0,GPIO_AF_RTC_AF1) ; Config_RCC(&SavRCC); SysTick->CTRL = 0; /* Swith in MSI 32KHz */ SetHSICLKToMSI(RCC_MSIRange_0,DIV2,NoRTC) ; PWR_WakeUpPinCmd(PWR_WakeUpPin_1,ENABLE); PWR_UltraLowPowerCmd(ENABLE); PWR_EnterSTANDBYMode(); /* Stop here WakeUp EXIT on RESET */ break; } SetHSICLK(); Config_Systick(); RCC->AHBENR = SavRCC.AHBENR; PWR_VoltageScalingConfig(PWR_VoltageScaling_Range1); /* Wait Until the Voltage Regulator is ready */ while (PWR_GetFlagStatus(PWR_FLAG_VOS) != RESET) ; /* Read ADC for current measurmeent */ adc_measure = Current_Measurement(); /* ICC_CNT_EN Hi */ GPIO_HIGH(CTN_GPIO_PORT,CTN_CNTEN_GPIO_PIN); UserButton = TRUE; /* To restore RCC registers */ RCC->APB1ENR = SavRCC.APB1ENR; RCC->APB2ENR = SavRCC.APB2ENR; RCC->AHBLPENR = SavRCC.AHBLPENR; RCC->APB1LPENR = SavRCC.APB1LPENR; RCC->APB2LPENR = SavRCC.APB2LPENR; /* Need to reinit RCC for LCD*/ RCC_Configuration(); PWR_EnterLowPowerRunMode(DISABLE); /* Disable Ultra low power mode */ PWR_UltraLowPowerCmd(DISABLE); /* Disable FLASH during SLeep LP */ FLASH_SLEEPPowerDownCmd(DISABLE); Restore_GPIO_Config(); /* Clear Wake Up flag */ PWR_ClearFlag(PWR_FLAG_WU); /* Enable PVD */ PWR_PVDCmd(ENABLE); LCD_GLASS_Init(); return (adc_measure); }
/** * @brief Current measurement in different MCU modes: RUN/HALT/LowPower withouto LCD/LowPower with LCD * @caller main and ADC_Icc_Test * @param MCU state * @retval ADC value. */ u16 ADC_Icc_Test(u8 Mcu_State) { uint16_t res; uint8_t i; /* Test MCU state for configuration */ switch (Mcu_State) { /* test Run mode nothing to do */ case MCU_RUN: break; /* Low power mode */ case MCU_LPR: Halt_Init(); sim(); /* To prepare to start counter */ GPIO_HIGH(CTN_GPIO_PORT,CTN_CNTEN_GPIO_PIN); /* To configure Low Power */ LPR_init(); break; /* Halt mode */ case MCU_HALT: /* Init for Halt mode */ Halt_Init(); sim(); /* To prepare to start counter */ GPIO_HIGH(CTN_GPIO_PORT,CTN_CNTEN_GPIO_PIN); /* Falling edge for start counter */ GPIO_LOW(CTN_GPIO_PORT,CTN_CNTEN_GPIO_PIN); delay_10us(1); /* MCU in halt during measurement */ /* Wake up by Interrupt done counter Input Port E pin 6 */ halt(); break; case MCU_LPR_LCD: PWR->CSR2 = 0x2; sim(); /* To configure GPIO for reduce current. */ GPIO_LowPower_Config(); /* To prepare to start counter */ GPIO_HIGH(CTN_GPIO_PORT,CTN_CNTEN_GPIO_PIN); /* To configure Low Power */ LPR_init(); break; } sim(); /* re-start ADC chanel 24 for Current measurement */ ADC_Icc_Init(); /* Read ADC for current measurmeent */ /* initialize result */ res = 0; for(i=8; i>0; i--) { /* start ADC convertion by software */ ADC_SoftwareStartConv(ADC1); /* wait until end-of-covertion */ while( ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == 0 ); /* read ADC convertion result */ res += ADC_GetConversionValue(ADC1); } /* ICC_CNT_EN invalid */ GPIO_HIGH(CTN_GPIO_PORT,CTN_CNTEN_GPIO_PIN); GPIO_Init(BUTTON_GPIO_PORT, USER_GPIO_PIN,GPIO_Mode_In_FL_IT); rim(); /* Disable ADC 1 for reduce current */ ADC_Cmd(ADC1, DISABLE); CLK_PeripheralClockConfig(CLK_Peripheral_ADC1, DISABLE); if (Mcu_State !=MCU_LPR_LCD) { CLK_PeripheralClockConfig(CLK_Peripheral_RTC, ENABLE); LCD_GLASS_Init(); } return (res>>3); }