2018-11-28 07:00 PM
The chip is STM32L486VGT6. I can use the usart wake up the stop1 mode,but I can not wake up with the irda(usart3) mode .Please help!!!
#define UartHandle hirda3
void Stop_IRDA(void)
{
UART_WakeUpTypeDef WakeUpSelection;
/* make sure that no UART transfer is on-going */
while(__HAL_UART_GET_FLAG(&UartHandle, USART_ISR_BUSY) == SET);
/* make sure that UART is ready to receive
* (test carried out again later in HAL_UARTEx_StopModeWakeUpSourceConfig) */
while(__HAL_UART_GET_FLAG(&UartHandle, USART_ISR_REACK) == RESET);
/* set the wake-up event:
* specify wake-up on RXNE flag */
WakeUpSelection.WakeUpEvent = UART_WAKEUP_ON_READDATA_NONEMPTY;
if (HAL_IRDAEx_StopModeWakeUpSourceConfig(&UartHandle, WakeUpSelection)!= HAL_OK)
{
LED3_ON;
}
/* Enable the UART Wake UP from STOP1 mode Interrupt */
__HAL_UART_ENABLE_IT(&UartHandle, UART_IT_WUF);
/* enable MCU wake-up by UART */
HAL_IRDAEx_EnableStopMode(&UartHandle);
printf("CR1:0x%08X\r\n",UartHandle.Instance->CR1);
printf("CR2:0x%08X\r\n",UartHandle.Instance->CR2);
printf("CR3:0x%08X\r\n",UartHandle.Instance->CR3);
printf("enter STOP1 mode");
/* enter STOP1 mode */
HAL_PWREx_EnterSTOP1Mode(PWR_STOPENTRY_WFI);
for(uint8_t i = 0; i<10;i++)
{
LED1_TOG;
HAL_Delay(50);
}
/* at that point, MCU has been awoken: the LED has been turned back on */
SystemClock_Config();
HAL_IRDAEx_DisableStopMode(&UartHandle);
}
/**
* @brief Initialize the IRDA wake-up from stop mode parameters when triggered by address detection.
* @param hirda IRDA handle.
* @param WakeUpSelection IRDA wake up from stop mode parameters.
* @retval None
*/
static void IRDAEx_Wakeup_AddressConfig(IRDA_HandleTypeDef *hirda, UART_WakeUpTypeDef WakeUpSelection)
{
assert_param(IS_UART_ADDRESSLENGTH_DETECT(WakeUpSelection.AddressLength));
/* Set the USART address length */
MODIFY_REG(hirda->Instance->CR2, USART_CR2_ADDM7, WakeUpSelection.AddressLength);
/* Set the USART address node */
MODIFY_REG(hirda->Instance->CR2, USART_CR2_ADD, ((uint32_t)WakeUpSelection.Address << UART_CR2_ADDRESS_LSB_POS));
}
/**
* @brief Handle IRDA Communication Timeout.
* @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
* the configuration information for the specified IRDA module.
* @param Flag Specifies the IRDA flag to check.
* @param Status Flag status (SET or RESET)
* @param Tickstart Tick start value
* @param Timeout Timeout duration
* @retval HAL status
*/
static HAL_StatusTypeDef __IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout)
{
/* Wait until flag is set */
while ((__HAL_IRDA_GET_FLAG(hirda, Flag) ? SET : RESET) == Status)
{
/* Check for the Timeout */
if (Timeout != HAL_MAX_DELAY)
{
if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
{
/* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
#if defined(USART_CR1_FIFOEN)
CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE));
#else
CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE));
#endif
CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
hirda->gState = HAL_IRDA_STATE_READY;
hirda->RxState = HAL_IRDA_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hirda);
return HAL_TIMEOUT;
}
}
}
return HAL_OK;
}
/**
* @brief Set Wakeup from Stop mode interrupt flag selection.
* @note It is the application responsibility to enable the interrupt used as
* usart_wkup interrupt source before entering low-power mode.
* @param hirda IRDA handle.
* @param WakeUpSelection Address match, Start Bit detection or RXNE/RXFNE bit status.
* This parameter can be one of the following values:
* @arg @ref IRDA_WAKEUP_ON_ADDRESS
* @arg @ref IRDA_WAKEUP_ON_STARTBIT
* @arg @ref IRDA_WAKEUP_ON_READDATA_NONEMPTY
* @retval HAL status
*/
HAL_StatusTypeDef HAL_IRDAEx_StopModeWakeUpSourceConfig(IRDA_HandleTypeDef *hirda, UART_WakeUpTypeDef WakeUpSelection)
{
HAL_StatusTypeDef status = HAL_OK;
uint32_t tickstart = 0U;
/* check the wake-up from stop mode IRDA instance */
assert_param(IS_UART_WAKEUP_FROMSTOP_INSTANCE(hirda->Instance));
/* check the wake-up selection parameter */
assert_param(IS_UART_WAKEUP_SELECTION(WakeUpSelection.WakeUpEvent));
/* Process Locked */
__HAL_LOCK(hirda);
hirda->gState = HAL_IRDA_STATE_BUSY;
/* Disable the Peripheral */
__HAL_IRDA_DISABLE(hirda);
/* Set the wake-up selection scheme */
MODIFY_REG(hirda->Instance->CR3, USART_CR3_WUS, WakeUpSelection.WakeUpEvent);
if (WakeUpSelection.WakeUpEvent == UART_WAKEUP_ON_ADDRESS)
{
IRDAEx_Wakeup_AddressConfig(hirda, WakeUpSelection);
}
/* Enable the Peripheral */
__HAL_IRDA_ENABLE(hirda);
/* Init tickstart for timeout managment*/
tickstart = HAL_GetTick();
/* Wait until REACK flag is set */
if (__IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_REACK, RESET, tickstart, HAL_UART_TIMEOUT_VALUE) != HAL_OK)
{
status = HAL_TIMEOUT;
}
else
{
/* Initialize the IRDA State */
hirda->gState = HAL_IRDA_STATE_READY;
}
/* Process Unlocked */
__HAL_UNLOCK(hirda);
return status;
}
/**
* @brief Enable IRDA Stop Mode.
* @note The IRDA is able to wake up the MCU from Stop 1 mode as long as IRDA clock is HSI or LSE.
* @param hirda IRDA handle.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_IRDAEx_EnableStopMode(IRDA_HandleTypeDef *hirda)
{
/* Process Locked */
__HAL_LOCK(hirda);
/* Set UESM bit */
SET_BIT(hirda->Instance->CR1, USART_CR1_UESM);
/* Process Unlocked */
__HAL_UNLOCK(hirda);
return HAL_OK;
}
/**
* @brief Disable IRDA Stop Mode.
* @param hirda IRDA handle.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_IRDAEx_DisableStopMode(IRDA_HandleTypeDef *hirda)
{
/* Process Locked */
__HAL_LOCK(hirda);
/* Clear UESM bit */
CLEAR_BIT(hirda->Instance->CR1, USART_CR1_UESM);
/* Process Unlocked */
__HAL_UNLOCK(hirda);
return HAL_OK;
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInit;
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 5;
RCC_OscInitStruct.PLL.PLLN = 32;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_USART2
|RCC_PERIPHCLK_USART3|RCC_PERIPHCLK_UART4
|RCC_PERIPHCLK_LPUART1|RCC_PERIPHCLK_I2C2
|RCC_PERIPHCLK_SDMMC1;
PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
PeriphClkInit.Usart3ClockSelection = RCC_USART3CLKSOURCE_HSI;
PeriphClkInit.Uart4ClockSelection = RCC_UART4CLKSOURCE_PCLK1;
PeriphClkInit.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK1;
PeriphClkInit.I2c2ClockSelection = RCC_I2C2CLKSOURCE_PCLK1;
PeriphClkInit.Sdmmc1ClockSelection = RCC_SDMMC1CLKSOURCE_PLLSAI1;
PeriphClkInit.PLLSAI1.PLLSAI1Source = RCC_PLLSOURCE_HSE;
PeriphClkInit.PLLSAI1.PLLSAI1M = 5;
PeriphClkInit.PLLSAI1.PLLSAI1N = 16;
PeriphClkInit.PLLSAI1.PLLSAI1P = RCC_PLLP_DIV7;
PeriphClkInit.PLLSAI1.PLLSAI1Q = RCC_PLLQ_DIV2;
PeriphClkInit.PLLSAI1.PLLSAI1R = RCC_PLLR_DIV2;
PeriphClkInit.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_48M2CLK;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure the main internal regulator output voltage
*/
if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure the Systick interrupt time
*/
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
/**Configure the Systick
*/
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}