Reputation: 1743
I am using STOP
mode to save power and also deinitialize GPIO
to achieve maximum power saving. In this case current consumption goes below 1mA. I am using UART
Rx
pin as external interrupt to wake up board from STOP
mode. The board does wake up but UART
or other peripheral like DCMI
doesn't work. Following is my code.
void MX_GPIO_Deinit()
{
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Pin = GPIO_PIN_All;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
/* Disable GPIOs clock */
__HAL_RCC_GPIOA_CLK_DISABLE();
__HAL_RCC_GPIOB_CLK_DISABLE();
__HAL_RCC_GPIOC_CLK_DISABLE();
__HAL_RCC_GPIOH_CLK_DISABLE();
}
void stopMode(void)
{
HAL_SuspendTick();
MX_GPIO_Deinit();
__HAL_RCC_PWR_CLK_ENABLE();
HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF8_UART4;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
}
void resumeStopMode(void)
{
SystemClock_Config();
HAL_ResumeTick();
MX_GPIO_Init();
HAL_UART_MspInit(&huart4);
HAL_I2C_MspInit(&hi2c2);
HAL_DCMI_MspInit(&hdma_dcmi);
HAL_TIM_MspPostInit(&htim1);
MX_DMA_Init();
MX_UART4_Init();
MX_I2C2_Init();
MX_DCMI_Init();
MX_TIM1_Init();
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
}
int getChar()
{
uint8_t InputData = 0;
TimmingDelay = 50000;
while (TimmingDelay !=0)
{
if (__HAL_UART_GET_FLAG(&huart4, UART_FLAG_ORE))
__HAL_UART_CLEAR_OREFLAG(&huart4);
if (__HAL_UART_GET_FLAG(&huart4, UART_FLAG_RXNE))
{
InputData = huart4.Instance->DR & 0x1FF;
return InputData;
}
}
return -1;
}
void main(void)
{
stopMode()
resumeStopMode() /* woken up by uart interrupt*/
int receivedByte = 0;
receivedByte = getChar() /* This line doesn't work after waking it goes into stop mode */
}
Since I deinitialize all GPIO
I am not able to to debug. How can I make UART
work properly after waking up from STOP
mode.
Upvotes: 1
Views: 3383
Reputation: 3943
I ran into almost this exact same issue and here was my solution (keep in mind I'm using UART2):
HAL_UART_MspInit(&huart2);
MX_USART2_UART_Init();
The reason that just calling the normal MX_USART2_UART_Init()
function doesn't work is because the UART peripheral has state and wont re-initialize clocks if its state doesn't think it needs to:
Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c
308 HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
309 {
.
.
.
327 if (huart->gState == HAL_UART_STATE_RESET)
328 {
.
.
.
343 /* Init the low level hardware : GPIO, CLOCK */
344 HAL_UART_MspInit(huart);
Upvotes: 0
Reputation: 11
This is my solution.
HAL_UART_MspInit(&huart4);
__HAL_UART_DISABLE(&huart4);
__HAL_UART_ENABLE(&huart4);
but following do not work.
HAL_UART_Init(&huart4);
Upvotes: 0
Reputation: 120
There is a wake-up latency associated with STOP mode to allow the HSI RC oscillator to wake up and potentially flash and the internal regulator. If the first byte is corrupt then it is most likely that it is a result of this latency.
Upvotes: 0