mbed library sources. Supersedes mbed-src.
Dependents: Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more
Diff: targets/TARGET_STM/TARGET_STM32F0/device/stm32f0xx_hal_iwdg.c
- Revision:
- 156:95d6b41a828b
- Parent:
- 149:156823d33999
- Child:
- 180:96ed750bd169
--- a/targets/TARGET_STM/TARGET_STM32F0/device/stm32f0xx_hal_iwdg.c Thu Jan 05 10:51:54 2017 +0000 +++ b/targets/TARGET_STM/TARGET_STM32F0/device/stm32f0xx_hal_iwdg.c Mon Jan 16 15:03:32 2017 +0000 @@ -2,76 +2,80 @@ ****************************************************************************** * @file stm32f0xx_hal_iwdg.c * @author MCD Application Team - * @version V1.4.0 - * @date 27-May-2016 + * @version V1.5.0 + * @date 04-November-2016 * @brief IWDG HAL module driver. * This file provides firmware functions to manage the following * functionalities of the Independent Watchdog (IWDG) peripheral: - * + Initialization and Configuration functions + * + Initialization and Start functions * + IO operation functions - * + Peripheral State functions - * + * @verbatim - =============================================================================== - ##### IWDG Specific features ##### - =============================================================================== - [..] - (+) The IWDG can be started by either software or hardware (configurable - through option byte). - (+) The IWDG is clocked by its own dedicated Low-Speed clock (LSI) and - thus stays active even if the main clock fails. - (+) Once the IWDG is started, the LSI is forced ON and cannot be disabled - (LSI cannot be disabled too), and the counter starts counting down from - the reset value of 0xFFF. When it reaches the end of count value (0x000) - a system reset is generated. - (+) The IWDG counter should be refreshed at regular intervals, otherwise the - watchdog generates an MCU reset when the counter reaches 0. - (+) The IWDG is implemented in the VDD voltage domain that is still functional - in STOP and STANDBY mode (IWDG reset can wake-up from STANDBY). - (+) IWDGRST flag in RCC_CSR register can be used to inform when an IWDG - reset occurs. - (+) Min-max timeout value @41KHz (LSI): ~0.1ms / ~25.5s - The IWDG timeout may vary due to LSI frequency dispersion. STM32F0x - devices provide the capability to measure the LSI frequency (LSI clock - connected internally to TIM16 CH1 input capture). The measured value - can be used to have an IWDG timeout with an acceptable accuracy. - For more information, please refer to the STM32F0x Reference manual. + ============================================================================== + ##### IWDG Generic features ##### + ============================================================================== + [..] + (+) The IWDG can be started by either software or hardware (configurable + through option byte). + + (+) The IWDG is clocked by Low-Speed clock (LSI) and thus stays active even + if the main clock fails. + + (+) Once the IWDG is started, the LSI is forced ON and both can not be + disabled. The counter starts counting down from the reset value (0xFFF). + When it reaches the end of count value (0x000) a reset signal is + generated (IWDG reset). + + (+) Whenever the key value 0x0000 AAAA is written in the IWDG_KR register, + the IWDG_RLR value is reloaded in the counter and the watchdog reset is + prevented. + + (+) The IWDG is implemented in the VDD voltage domain that is still functional + in STOP and STANDBY mode (IWDG reset can wake-up from STANDBY). + IWDGRST flag in RCC_CSR register can be used to inform when an IWDG + reset occurs. + + (+) Debug mode : When the microcontroller enters debug mode (core halted), + the IWDG counter either continues to work normally or stops, depending + on DBG_IWDG_STOP configuration bit in DBG module, accessible through + __HAL_DBGMCU_FREEZE_IWDG() and __HAL_DBGMCU_UNFREEZE_IWDG() macros - ##### How to use this driver ##### - =============================================================================== - [..] - (#) if Window option is disabled - (++) Use IWDG using HAL_IWDG_Init() function to : - (+++) Enable write access to IWDG_PR, IWDG_RLR. - (+++) Configure the IWDG prescaler, counter reload value. - This reload value will be loaded in the IWDG counter each time the counter - is reloaded, then the IWDG will start counting down from this value. - (++) Use IWDG using HAL_IWDG_Start() function to : - (+++) Reload IWDG counter with value defined in the IWDG_RLR register. - (+++) Start the IWDG, when the IWDG is used in software mode (no need - to enable the LSI, it will be enabled by hardware). - (++) Then the application program must refresh the IWDG counter at regular - intervals during normal operation to prevent an MCU reset, using - HAL_IWDG_Refresh() function. - (#) if Window option is enabled: - (++) Use IWDG using HAL_IWDG_Start() function to enable IWDG downcounter - (++) Use IWDG using HAL_IWDG_Init() function to : - (+++) Enable write access to IWDG_PR, IWDG_RLR and IWDG_WINR registers. - (+++) Configure the IWDG prescaler, reload value and window value. - (++) Then the application program must refresh the IWDG counter at regular - intervals during normal operation to prevent an MCU reset, using - HAL_IWDG_Refresh() function. + [..] Min-max timeout value @40KHz (LSI): ~0.1ms / ~26.2s + The IWDG timeout may vary due to LSI frequency dispersion. STM32F0xx + devices provide the capability to measure the LSI frequency (LSI clock + connected internally to TIM16 CH1 input capture). The measured value + can be used to have an IWDG timeout with an acceptable accuracy. + + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Use IWDG using HAL_IWDG_Init() function to : + (++) Enable instance by writing Start keyword in IWDG_KEY register. LSI + clock is forced ON and IWDG counter starts downcounting. + (++) Enable write access to configuration register: IWDG_PR, IWDG_RLR & + IWDG_WINR. + (++) Configure the IWDG prescaler and counter reload value. This reload + value will be loaded in the IWDG counter each time the watchdog is + reloaded, then the IWDG will start counting down from this value. + (++) wait for status flags to be reset" + (++) Depending on window parameter: + (+++) If Window Init parameter is same as Window register value, + nothing more is done but reload counter value in order to exit + function withy exact time base. + (+++) Else modify Window register. This will automatically reload + watchdog counter. + + (#) Then the application program must refresh the IWDG counter at regular + intervals during normal operation to prevent an MCU reset, using + HAL_IWDG_Refresh() function. *** IWDG HAL driver macros list *** ==================================== [..] - Below the list of most used macros in IWDG HAL driver. - + Below the list of most used macros in IWDG HAL driver: (+) __HAL_IWDG_START: Enable the IWDG peripheral - (+) __HAL_IWDG_RELOAD_COUNTER: Reloads IWDG counter with value defined in the reload register - (+) IWDG_ENABLE_WRITE_ACCESS : Enable write access to IWDG_PR and IWDG_RLR registers - (+) IWDG_DISABLE_WRITE_ACCESS : Disable write access to IWDG_PR and IWDG_RLR registers - (+) __HAL_IWDG_GET_FLAG: Get the selected IWDG's flag status + (+) __HAL_IWDG_RELOAD_COUNTER: Reloads IWDG counter with value defined in + the reload register @endverbatim ****************************************************************************** @@ -111,61 +115,63 @@ * @{ */ -/** @defgroup IWDG IWDG +#ifdef HAL_IWDG_MODULE_ENABLED +/** @addtogroup IWDG * @brief IWDG HAL module driver. * @{ */ -#ifdef HAL_IWDG_MODULE_ENABLED - /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /** @defgroup IWDG_Private_Defines IWDG Private Defines * @{ */ - -#define HAL_IWDG_DEFAULT_TIMEOUT (uint32_t)1000 - +/* Status register need 5 RC LSI divided by prescaler clock to be updated. With + higher prescaler (256), and according to LSI variation, we need to wait at + least 6 cycles so 39 ms. */ +#define HAL_IWDG_DEFAULT_TIMEOUT 39U /** * @} */ + /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ /* Exported functions --------------------------------------------------------*/ -/** @defgroup IWDG_Exported_Functions IWDG Exported Functions +/** @addtogroup IWDG_Exported_Functions * @{ */ -/** @defgroup IWDG_Exported_Functions_Group1 Initialization and de-initialization functions - * @brief Initialization and Configuration functions. +/** @addtogroup IWDG_Exported_Functions_Group1 + * @brief Initialization and Start functions. * @verbatim =============================================================================== - ##### Initialization and de-initialization functions ##### + ##### Initialization and Start functions ##### =============================================================================== - [..] This section provides functions allowing to: - (+) Initialize the IWDG according to the specified parameters - in the IWDG_InitTypeDef and create the associated handle - (+) Manage Window option - (+) Initialize the IWDG MSP - (+) DeInitialize the IWDG MSP + [..] This section provides functions allowing to: + (+) Initialize the IWDG according to the specified parameters in the + IWDG_InitTypeDef of associated handle. + (+) Manage Window option. + (+) Once initialization is performed in HAL_IWDG_Init function, Watchdog + is reloaded in order to exit function with correct time base. @endverbatim * @{ */ /** - * @brief Initialize the IWDG according to the specified - * parameters in the IWDG_InitTypeDef and initialize the associated handle. - * @param hiwdg: pointer to a IWDG_HandleTypeDef structure that contains + * @brief Initialize the IWDG according to the specified parameters in the + * IWDG_InitTypeDef and start watchdog. Before exiting function, + * watchdog is refreshed in order to have correct time base. + * @param hiwdg pointer to a IWDG_HandleTypeDef structure that contains * the configuration information for the specified IWDG module. * @retval HAL status */ HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg) { - uint32_t tickstart = 0; + uint32_t tickstart; /* Check the IWDG handle allocation */ if(hiwdg == NULL) @@ -179,192 +185,43 @@ assert_param(IS_IWDG_RELOAD(hiwdg->Init.Reload)); assert_param(IS_IWDG_WINDOW(hiwdg->Init.Window)); - /* Check pending flag, if previous update not done, return error */ - if((__HAL_IWDG_GET_FLAG(hiwdg, IWDG_FLAG_PVU) != RESET) - &&(__HAL_IWDG_GET_FLAG(hiwdg, IWDG_FLAG_RVU) != RESET) - &&(__HAL_IWDG_GET_FLAG(hiwdg, IWDG_FLAG_WVU) != RESET)) - { - return HAL_ERROR; - } + /* Enable IWDG. LSI is turned on automaticaly */ + __HAL_IWDG_START(hiwdg); - if(hiwdg->State == HAL_IWDG_STATE_RESET) - { - /* Allocate lock resource and initialize it */ - hiwdg->Lock = HAL_UNLOCKED; - - /* Init the low level hardware */ - HAL_IWDG_MspInit(hiwdg); - } - - /* Change IWDG peripheral state */ - hiwdg->State = HAL_IWDG_STATE_BUSY; - - /* Enable write access to IWDG_PR, IWDG_RLR and IWDG_WINR registers */ - /* by writing 0x5555 in KR */ + /* Enable write access to IWDG_PR, IWDG_RLR and IWDG_WINR registers by writing + 0x5555 in KR */ IWDG_ENABLE_WRITE_ACCESS(hiwdg); - /* Write to IWDG registers the IWDG_Prescaler & IWDG_Reload values to work with */ - MODIFY_REG(hiwdg->Instance->PR, IWDG_PR_PR, hiwdg->Init.Prescaler); - MODIFY_REG(hiwdg->Instance->RLR, IWDG_RLR_RL, hiwdg->Init.Reload); - - /* check if window option is enabled */ - if (((hiwdg->Init.Window) != IWDG_WINDOW_DISABLE) || ((hiwdg->Instance->WINR) != IWDG_WINDOW_DISABLE)) - { - tickstart = HAL_GetTick(); - - /* Wait for register to be updated */ - while((uint32_t)(hiwdg->Instance->SR) != RESET) - { - if((HAL_GetTick() - tickstart ) > HAL_IWDG_DEFAULT_TIMEOUT) - { - /* Set IWDG state */ - hiwdg->State = HAL_IWDG_STATE_TIMEOUT; - return HAL_TIMEOUT; - } - } - - /* Write to IWDG WINR the IWDG_Window value to compare with */ - MODIFY_REG(hiwdg->Instance->WINR, IWDG_WINR_WIN, hiwdg->Init.Window); - } - - /* Change IWDG peripheral state */ - hiwdg->State = HAL_IWDG_STATE_READY; - - /* Return function status */ - return HAL_OK; -} - -/** - * @brief Initialize the IWDG MSP. - * @param hiwdg: pointer to a IWDG_HandleTypeDef structure that contains - * the configuration information for the specified IWDG module. - * @retval None - */ -__weak void HAL_IWDG_MspInit(IWDG_HandleTypeDef *hiwdg) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hiwdg); + /* Write to IWDG registers the Prescaler & Reload values to work with */ + hiwdg->Instance->PR = hiwdg->Init.Prescaler; + hiwdg->Instance->RLR = hiwdg->Init.Reload; - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_IWDG_MspInit could be implemented in the user file - */ -} - -/** - * @} - */ - -/** @defgroup IWDG_Exported_Functions_Group2 IO operation functions - * @brief IO operation functions - * -@verbatim - =============================================================================== - ##### IO operation functions ##### - =============================================================================== - [..] This section provides functions allowing to: - (+) Start the IWDG. - (+) Refresh the IWDG. - -@endverbatim - * @{ - */ - -/** - * @brief Start the IWDG. - * @param hiwdg: pointer to a IWDG_HandleTypeDef structure that contains - * the configuration information for the specified IWDG module. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_IWDG_Start(IWDG_HandleTypeDef *hiwdg) -{ - uint32_t tickstart = 0; - - /* Process locked */ - __HAL_LOCK(hiwdg); - - /* Change IWDG peripheral state */ - hiwdg->State = HAL_IWDG_STATE_BUSY; - - /* Reload IWDG counter with value defined in the RLR register */ - if ((hiwdg->Init.Window) == IWDG_WINDOW_DISABLE) - { - __HAL_IWDG_RELOAD_COUNTER(hiwdg); - } - - /* Start the IWDG peripheral */ - __HAL_IWDG_START(hiwdg); - + /* Check pending flag, if previous update not done, return timeout */ tickstart = HAL_GetTick(); - /* Wait until PVU, RVU, WVU flag are RESET */ - while( (__HAL_IWDG_GET_FLAG(hiwdg, IWDG_FLAG_PVU) != RESET) - &&(__HAL_IWDG_GET_FLAG(hiwdg, IWDG_FLAG_RVU) != RESET) - &&(__HAL_IWDG_GET_FLAG(hiwdg, IWDG_FLAG_WVU) != RESET) ) + /* Wait for register to be updated */ + while(hiwdg->Instance->SR != RESET) { - if((HAL_GetTick() - tickstart ) > HAL_IWDG_DEFAULT_TIMEOUT) { - /* Set IWDG state */ - hiwdg->State = HAL_IWDG_STATE_TIMEOUT; - - /* Process unlocked */ - __HAL_UNLOCK(hiwdg); - return HAL_TIMEOUT; } } - /* Change IWDG peripheral state */ - hiwdg->State = HAL_IWDG_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hiwdg); - - /* Return function status */ - return HAL_OK; -} - -/** - * @brief Refresh the IWDG. - * @param hiwdg: pointer to a IWDG_HandleTypeDef structure that contains - * the configuration information for the specified IWDG module. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg) -{ - uint32_t tickstart = 0; - - /* Process Locked */ - __HAL_LOCK(hiwdg); - - /* Change IWDG peripheral state */ - hiwdg->State = HAL_IWDG_STATE_BUSY; - - tickstart = HAL_GetTick(); - - /* Wait until RVU flag is RESET */ - while(__HAL_IWDG_GET_FLAG(hiwdg, IWDG_FLAG_RVU) != RESET) + /* If window parameter is different than current value, modify window + register */ + if(hiwdg->Instance->WINR != hiwdg->Init.Window) { - if((HAL_GetTick() - tickstart ) > HAL_IWDG_DEFAULT_TIMEOUT) - { - /* Set IWDG state */ - hiwdg->State = HAL_IWDG_STATE_TIMEOUT; - - /* Process unlocked */ - __HAL_UNLOCK(hiwdg); - - return HAL_TIMEOUT; - } + /* Write to IWDG WINR the IWDG_Window value to compare with. In any case, + even if window feature is disabled, Watchdog will be reloaded by writing + windows register */ + hiwdg->Instance->WINR = hiwdg->Init.Window; } - - /* Reload IWDG counter with value defined in the reload register */ - __HAL_IWDG_RELOAD_COUNTER(hiwdg); - - /* Change IWDG peripheral state */ - hiwdg->State = HAL_IWDG_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hiwdg); + else + { + /* Reload IWDG counter with value defined in the reload register */ + __HAL_IWDG_RELOAD_COUNTER(hiwdg); + } /* Return function status */ return HAL_OK; @@ -374,30 +231,35 @@ * @} */ -/** @defgroup IWDG_Exported_Functions_Group3 Peripheral State functions - * @brief Peripheral State functions. + +/** @addtogroup IWDG_Exported_Functions_Group2 + * @brief IO operation functions * @verbatim =============================================================================== - ##### Peripheral State functions ##### + ##### IO operation functions ##### =============================================================================== - [..] - This subsection permits to get in run-time the status of the peripheral. + [..] This section provides functions allowing to: + (+) Refresh the IWDG. @endverbatim * @{ */ + /** - * @brief Return the IWDG handle state. - * @param hiwdg: pointer to a IWDG_HandleTypeDef structure that contains + * @brief Refresh the IWDG. + * @param hiwdg pointer to a IWDG_HandleTypeDef structure that contains * the configuration information for the specified IWDG module. - * @retval HAL state + * @retval HAL status */ -HAL_IWDG_StateTypeDef HAL_IWDG_GetState(IWDG_HandleTypeDef *hiwdg) +HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg) { - /* Return IWDG handle state */ - return hiwdg->State; + /* Reload IWDG counter with value defined in the reload register */ + __HAL_IWDG_RELOAD_COUNTER(hiwdg); + + /* Return function status */ + return HAL_OK; } /**