2020-11-04 06:56 AM
Hey there.. iam currently working with a L432KC on a custom made PCB.
My programm reads a sensor value (I2C) and sends it so another device via SPI.
This operation is performed every minute.
iam using the HAL_Delay(60000) command to wait fot the next minute.
is that a smart and powersaving solution?
what Lowpower modes should i use? my project will be powered through a CR1632 and i want it to last as long as possible. i connected a 32khz xtal as LSE.
HAL_Delay() uses SYSTick as timer right? is that meant by RTC ?
speaking : if i set the controller into the "shutdown" mode (with disables everything). will it be able to wakeup after a HAL_Delay() function?
annother question:
Iam using SPI, I2C and UART when my controller is doing someting (not in sleepmode)
wich power mode should i use then? i cant find SPI in the peripherals table ..
what should i configure in the clock config in the .ioc file?
i dont really get it ... thank you!
Solved! Go to Solution.
2020-11-05 06:47 AM
STM32L4 Familly support seven low power mode.
You should review RM0394.pdf Chapter 5.3 which describe all mode and CPU, Memory, Clock and peripharal enable/disable for each mode.
I2C1 peripheral (see table 20) can wake up the device from STOP0/STOP1 mode in case of address match with a master.
Concerning Standby and Shutdown mode, they provide the very low current consumption and generate a full device reset during wake-up.
I don't know what is your requirement for your own application, but usually, a low power application powered with a single battery works in this way:
Wake-up from LP mode to Run Mode or Low-Power Run Mode (slow clock gating)
Perform some stuff data computation ADC, Timer...
Send datas by using SPI, UART or I2C
Optionaly backup some data into SRAM retention or Backup register
Configure AutoWake-up Timer for a period.
Put all Peripheral Disabled and not clocked lie ADC, SPI....
Put all GPIO in Analog Mode (to limit current leakage and extra consumption)
Enter in Low Power mode for period
In this case, you have un short time in run mode to perform the stuff, and a long time in Low Power mode.
I suggest to you to try CubeMX PCC Tools and simulate the peripheral and CPU configuration you want, set Run and LP sequence and see the Battery Life Estimation if it suit for your need.
Please, thanks to Like or select Best Answer.
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2020-11-04 06:04 PM
> iam using the HAL_Delay(60000) command to wait fot the next minute.
> is that a smart and powersaving solution?
It's not a powersaving solution, it's just keeping the mcu busy until a minute passes. A better solution would be to go into a low power mode and wake up in a minute.
> HAL_Delay() uses SYSTick as timer right? is that meant by RTC ?
By default, yes. No, the systick timer is independent of the RTC.
> will it be able to wakeup after a HAL_Delay() function?
If it's asleep, it won't be executing HAL_Delay.
> i dont really get it ... thank you!
I would recommend looking at the reference manual and reading the section on low power modes. It goes into quite a bit of detail into the differences, how to enter, and how to exit.
2020-11-05 04:56 AM
alright, i sped some with RM0394 and i think iam better prepared now.
i managed so set my controller into standby by using
HAL_PWR_EnterSTANDBYMode();
i want to use the RTC with the WakeUpTimer so wake it up.
i activated RTC and Internal WakeUp in the .ioc-file and set the clock divider to 16 and the counter to 0x5000.
this should give me a wakeup Interrupt every 10seconcs (10s * 32.768khz/16 = 20480 = 0x5000)
this is not waking up my controller..
RM0394 Page 1039 gives instructions to change the Timer..
do i have to do this ?
2020-11-05 05:11 AM
Hi,
Before entering in Standby mode. You must activate Wakeup Timer (here below an example)
HAL_RTCEx_SetWakeUpTimer_IT(&RTCHandle, period, RTC_WAKEUPCLOCK_RTCCLK_DIV16);
Note Standby low power mode perform a Reset during wake up. So checking and clearing Reset Cause register is a good practice.
You can review the following example in Cube_L4 as starting point.
C:\Users\you\STM32Cube\Repository\STM32Cube_FW_L4_V1.16.0\Projects\NUCLEO-L432KC\Examples\PWR\PWR_STANDBY_RTC
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2020-11-05 05:56 AM
int main(void)
{
HAL_Init();
SystemClock_Config();
//SystemPower_Config();
__HAL_RCC_PWR_CLK_ENABLE();
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_RTC_Init();
char s[] ="\r\n\r\n**************\r\nSTM32L432 Reset\r\n\r\n";
tx_com((uint8_t*)s, strlen(s));
if(__HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET)
{
/* Clear Standby flag */
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);
char s[] ="resumed from standby\r\n";
tx_com((uint8_t*)s, strlen(s));
}
else {
char s1[] ="resumed not from standby\r\n";
tx_com((uint8_t*)s1, strlen(s1));
}
HAL_Delay(5000);
HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0x5000, RTC_WAKEUPCLOCK_RTCCLK_DIV16); // 10 sec
HAL_RTC_DeInit(&hrtc);
while (1)
{
char s[]="ctr 1 \r\n";
tx_com((uint8_t*)s, strlen(s));
HAL_Delay(1000);
char s1[]="ctr 2 \r\n";
tx_com((uint8_t*)s1, strlen(s1));
HAL_Delay(1000);
char s2[]="ctr 3 \r\n";
tx_com((uint8_t*)s2, strlen(s2));
HAL_Delay(1000);
HAL_PWR_EnterSTANDBYMode();
}
}
i started with the Example, but my code istn really working.. it looks like its not waking up.
Iam sending UART messages for testing.. do i need to reinitialize the UART after waking up?
my output looks like:
**************
STM32L432 Reset
resumed not from standby
ctr 1
ctr 2
ctr 3
2020-11-05 06:05 AM
If you do a deInit RTC peripheral, it is normal you will never woke !
By doing that, you will stop RTC and wakeup Timer which you have started on the previous line !
You must remove
HAL_RTC_DeInit(&hrtc);
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2020-11-05 06:21 AM
okay, thank you! its working now!
it seems like the controller is starting at the top of main() right?
that makes it configure the WakeUp every time it has woken up. is that a good solution?
What Mode should i choose for the Rest of my application? (whem iam transmitting data over SPI for example?)
The table in the datasheet says that things like I2C are working in the stop modes ? (Stop2) how is that possible when the CPU is stopped in theese modes?
2020-11-05 06:47 AM
STM32L4 Familly support seven low power mode.
You should review RM0394.pdf Chapter 5.3 which describe all mode and CPU, Memory, Clock and peripharal enable/disable for each mode.
I2C1 peripheral (see table 20) can wake up the device from STOP0/STOP1 mode in case of address match with a master.
Concerning Standby and Shutdown mode, they provide the very low current consumption and generate a full device reset during wake-up.
I don't know what is your requirement for your own application, but usually, a low power application powered with a single battery works in this way:
Wake-up from LP mode to Run Mode or Low-Power Run Mode (slow clock gating)
Perform some stuff data computation ADC, Timer...
Send datas by using SPI, UART or I2C
Optionaly backup some data into SRAM retention or Backup register
Configure AutoWake-up Timer for a period.
Put all Peripheral Disabled and not clocked lie ADC, SPI....
Put all GPIO in Analog Mode (to limit current leakage and extra consumption)
Enter in Low Power mode for period
In this case, you have un short time in run mode to perform the stuff, and a long time in Low Power mode.
I suggest to you to try CubeMX PCC Tools and simulate the peripheral and CPU configuration you want, set Run and LP sequence and see the Battery Life Estimation if it suit for your need.
Please, thanks to Like or select Best Answer.
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2020-11-05 07:55 AM
thank you! that gives me a good gameplan..
a few more questions:
i want to go into the LP-Run mode. I changed the MSI to 1Mhz and used that as HCLK..
how would i change the LPR bit in PWR_CR1 ?
PWR_CR=PWR_CR| 0000 0000 0000 0000 0100 0000 0000 0000 ? (bit14)
how would i change this SCB_SCR_SLEEPDEEP_Msk and what is its purpurse?
cant find it in the reference manual..
void HAL_PWR_EnterSTANDBYMode(void)
{
/* Set Stand-by mode */
MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_CR1_LPMS_STANDBY);
/* Set SLEEPDEEP bit of Cortex System Control Register */
SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
/* This option is used to ensure that store operations are completed */
#if defined ( __CC_ARM)
__force_stores();
#endif
/* Request Wait For Interrupt */
__WFI();
}
2020-11-05 08:21 AM
Use HAL API below to Enable/Disable Low Power Run Mode (stm32l4xx_hal_pwr_ex.c)
/**
* @brief Enter Low-power Run mode
* @note In Low-power Run mode, all I/O pins keep the same state as in Run mode.
* @note When Regulator is set to PWR_LOWPOWERREGULATOR_ON, the user can optionally configure the
* Flash in power-down monde in setting the RUN_PD bit in FLASH_ACR register.
* Additionally, the clock frequency must be reduced below 2 MHz.
* Setting RUN_PD in FLASH_ACR then appropriately reducing the clock frequency must
* be done before calling HAL_PWREx_EnableLowPowerRunMode() API.
* @retval None
*/
void HAL_PWREx_EnableLowPowerRunMode(void)
{
/* Set Regulator parameter */
SET_BIT(PWR->CR1, PWR_CR1_LPR);
}
/**
* @brief Exit Low-power Run mode.
* @note Before HAL_PWREx_DisableLowPowerRunMode() completion, the function checks that
* REGLPF has been properly reset (otherwise, HAL_PWREx_DisableLowPowerRunMode
* returns HAL_TIMEOUT status). The system clock frequency can then be
* increased above 2 MHz.
* @retval HAL Status
*/
HAL_StatusTypeDef HAL_PWREx_DisableLowPowerRunMode(void)
{
uint32_t wait_loop_index;
/* Clear LPR bit */
CLEAR_BIT(PWR->CR1, PWR_CR1_LPR);
/* Wait until REGLPF is reset */
wait_loop_index = ((PWR_FLAG_SETTING_DELAY_US * SystemCoreClock) / 1000000U) + 1U;
while ((HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_REGLPF)) && (wait_loop_index != 0U))
{
wait_loop_index--;
}
if (HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_REGLPF))
{
return HAL_TIMEOUT;
}
return HAL_OK;
}
SCB_SCR_SLEEPDEEP_Msk is a macro defined in CMSIS core_cm4.h
#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
It is used to shifting operation purpose on SCB->SCR Register which are part of Cortex M4 register (see PM0214.pdf chapter 4.4.6)
In this case it is used to set SCB->SCR Bit 2 SLEEPDEEP
If you plan to use Standby mode, you do not have to modify this register your self.
Use HAL_PWR_EnterSTANDBYMode API.
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.