Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:09

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_hal_wwdg.c
0004   * @author  MCD Application Team
0005   * @brief   WWDG HAL module driver.
0006   *          This file provides firmware functions to manage the following
0007   *          functionalities of the Window Watchdog (WWDG) peripheral:
0008   *           + Initialization and Configuration functions
0009   *           + IO operation functions
0010   ******************************************************************************
0011   * @attention
0012   *
0013   * Copyright (c) 2017 STMicroelectronics.
0014   * All rights reserved.
0015   *
0016   * This software is licensed under terms that can be found in the LICENSE file
0017   * in the root directory of this software component.
0018   * If no LICENSE file comes with this software, it is provided AS-IS.
0019   *
0020   ******************************************************************************
0021   @verbatim
0022   ==============================================================================
0023                       ##### WWDG Specific features #####
0024   ==============================================================================
0025   [..]
0026     Once enabled the WWDG generates a system reset on expiry of a programmed
0027     time period, unless the program refreshes the counter (T[6;0] downcounter)
0028     before reaching 0x3F value (i.e. a reset is generated when the counter
0029     value rolls down from 0x40 to 0x3F).
0030 
0031     (+) An MCU reset is also generated if the counter value is refreshed
0032         before the counter has reached the refresh window value. This
0033         implies that the counter must be refreshed in a limited window.
0034     (+) Once enabled the WWDG cannot be disabled except by a system reset.
0035     (+) If required by application, an Early Wakeup Interrupt can be triggered
0036         in order to be warned before WWDG expiration. The Early Wakeup Interrupt
0037         (EWI) can be used if specific safety operations or data logging must
0038         be performed before the actual reset is generated. When the downcounter
0039         reaches 0x40, interrupt occurs. This mechanism requires WWDG interrupt
0040         line to be enabled in NVIC. Once enabled, EWI interrupt cannot be
0041         disabled except by a system reset.
0042     (+) WWDGRST flag in RCC CSR register can be used to inform when a WWDG
0043         reset occurs.
0044     (+) The WWDG counter input clock is derived from the APB clock divided
0045         by a programmable prescaler.
0046     (+) WWDG clock (Hz) = PCLK1 / (4096 * Prescaler)
0047     (+) WWDG timeout (mS) = 1000 * (T[5;0] + 1) / WWDG clock (Hz)
0048         where T[5;0] are the lowest 6 bits of Counter.
0049     (+) WWDG Counter refresh is allowed between the following limits :
0050         (++) min time (mS) = 1000 * (Counter - Window) / WWDG clock
0051         (++) max time (mS) = 1000 * (Counter - 0x40) / WWDG clock
0052     (+) Typical values (case of STM32H74x/5x devices):
0053         (++) Counter min (T[5;0] = 0x00) @100MHz (PCLK1) with zero prescaler:
0054              max timeout before reset: approximately 40.96us
0055         (++) Counter max (T[5;0] = 0x3F) @100MHz (PCLK1) with prescaler dividing by 128:
0056              max timeout before reset: approximately 335.54ms
0057     (+) Typical values (case of STM32H7Ax/Bx devices):
0058         (++) Counter min (T[5;0] = 0x00) @140MHz (PCLK1) with zero prescaler:
0059              max timeout before reset: approximately 29.25us
0060         (++) Counter max (T[5;0] = 0x3F) @140MHz (PCLK1) with prescaler dividing by 128:
0061              max timeout before reset: approximately 239.67ms
0062     (+) Typical values (case of STM32H72x/3x devices):
0063         (++) Counter min (T[5;0] = 0x00) @125MHz (PCLK1) with zero prescaler:
0064              max timeout before reset: approximately 32.76us
0065         (++) Counter max (T[5;0] = 0x3F) @125MHz (PCLK1) with prescaler dividing by 128:
0066              max timeout before reset: approximately 268.43ms
0067 
0068                      ##### How to use this driver #####
0069   ==============================================================================
0070 
0071     *** Common driver usage ***
0072     ===========================
0073 
0074   [..]
0075     (+) Enable WWDG APB1 clock using __HAL_RCC_WWDG_CLK_ENABLE().
0076     (+) Configure the WWDG prescaler, refresh window value, counter value and early
0077         interrupt status using HAL_WWDG_Init() function. This will automatically
0078         enable WWDG and start its downcounter. Time reference can be taken from
0079         function exit. Care must be taken to provide a counter value
0080         greater than 0x40 to prevent generation of immediate reset.
0081     (+) If the Early Wakeup Interrupt (EWI) feature is enabled, an interrupt is
0082         generated when the counter reaches 0x40. When HAL_WWDG_IRQHandler is
0083         triggered by the interrupt service routine, flag will be automatically
0084         cleared and HAL_WWDG_WakeupCallback user callback will be executed. User
0085         can add his own code by customization of callback HAL_WWDG_WakeupCallback.
0086     (+) Then the application program must refresh the WWDG counter at regular
0087         intervals during normal operation to prevent an MCU reset, using
0088         HAL_WWDG_Refresh() function. This operation must occur only when
0089         the counter is lower than the refresh window value already programmed.
0090 
0091     *** Callback registration ***
0092     =============================
0093 
0094   [..]
0095     The compilation define USE_HAL_WWDG_REGISTER_CALLBACKS when set to 1 allows
0096     the user to configure dynamically the driver callbacks. Use Functions
0097     HAL_WWDG_RegisterCallback() to register a user callback.
0098 
0099     (+) Function HAL_WWDG_RegisterCallback() allows to register following
0100         callbacks:
0101         (++) EwiCallback : callback for Early WakeUp Interrupt.
0102         (++) MspInitCallback : WWDG MspInit.
0103     This function takes as parameters the HAL peripheral handle, the Callback ID
0104     and a pointer to the user callback function.
0105 
0106     (+) Use function HAL_WWDG_UnRegisterCallback() to reset a callback to
0107     the default weak (surcharged) function. HAL_WWDG_UnRegisterCallback()
0108     takes as parameters the HAL peripheral handle and the Callback ID.
0109     This function allows to reset following callbacks:
0110         (++) EwiCallback : callback for  Early WakeUp Interrupt.
0111         (++) MspInitCallback : WWDG MspInit.
0112 
0113     [..]
0114     When calling HAL_WWDG_Init function, callbacks are reset to the
0115     corresponding legacy weak (surcharged) functions:
0116     HAL_WWDG_EarlyWakeupCallback() and HAL_WWDG_MspInit() only if they have
0117     not been registered before.
0118 
0119     [..]
0120     When compilation define USE_HAL_WWDG_REGISTER_CALLBACKS is set to 0 or
0121     not defined, the callback registering feature is not available
0122     and weak (surcharged) callbacks are used.
0123 
0124     *** WWDG HAL driver macros list ***
0125     ===================================
0126     [..]
0127       Below the list of available macros in WWDG HAL driver.
0128       (+) __HAL_WWDG_ENABLE: Enable the WWDG peripheral
0129       (+) __HAL_WWDG_GET_FLAG: Get the selected WWDG's flag status
0130       (+) __HAL_WWDG_CLEAR_FLAG: Clear the WWDG's pending flags
0131       (+) __HAL_WWDG_ENABLE_IT: Enable the WWDG early wakeup interrupt
0132 
0133   @endverbatim
0134   ******************************************************************************
0135   */
0136 
0137 /* Includes ------------------------------------------------------------------*/
0138 #include "stm32h7xx_hal.h"
0139 
0140 /** @addtogroup STM32H7xx_HAL_Driver
0141   * @{
0142   */
0143 
0144 #ifdef HAL_WWDG_MODULE_ENABLED
0145 /** @defgroup WWDG WWDG
0146   * @ingroup RTEMSBSPsARMSTM32H7
0147   * @brief WWDG HAL module driver.
0148   * @{
0149   */
0150 
0151 /* Private typedef -----------------------------------------------------------*/
0152 /* Private define ------------------------------------------------------------*/
0153 /* Private macro -------------------------------------------------------------*/
0154 /* Private variables ---------------------------------------------------------*/
0155 /* Private function prototypes -----------------------------------------------*/
0156 /* Exported functions --------------------------------------------------------*/
0157 
0158 /** @defgroup WWDG_Exported_Functions WWDG Exported Functions
0159   * @ingroup RTEMSBSPsARMSTM32H7
0160   * @{
0161   */
0162 
0163 /** @defgroup WWDG_Exported_Functions_Group1 Initialization and Configuration functions
0164   * @ingroup RTEMSBSPsARMSTM32H7
0165   *  @brief    Initialization and Configuration functions.
0166   *
0167 @verbatim
0168   ==============================================================================
0169           ##### Initialization and Configuration functions #####
0170   ==============================================================================
0171   [..]
0172     This section provides functions allowing to:
0173       (+) Initialize and start the WWDG according to the specified parameters
0174           in the WWDG_InitTypeDef of associated handle.
0175       (+) Initialize the WWDG MSP.
0176 
0177 @endverbatim
0178   * @{
0179   */
0180 
0181 /**
0182   * @brief  Initialize the WWDG according to the specified.
0183   *         parameters in the WWDG_InitTypeDef of  associated handle.
0184   * @param  hwwdg  pointer to a WWDG_HandleTypeDef structure that contains
0185   *                the configuration information for the specified WWDG module.
0186   * @retval HAL status
0187   */
0188 HAL_StatusTypeDef HAL_WWDG_Init(WWDG_HandleTypeDef *hwwdg)
0189 {
0190   /* Check the WWDG handle allocation */
0191   if (hwwdg == NULL)
0192   {
0193     return HAL_ERROR;
0194   }
0195 
0196   /* Check the parameters */
0197   assert_param(IS_WWDG_ALL_INSTANCE(hwwdg->Instance));
0198   assert_param(IS_WWDG_PRESCALER(hwwdg->Init.Prescaler));
0199   assert_param(IS_WWDG_WINDOW(hwwdg->Init.Window));
0200   assert_param(IS_WWDG_COUNTER(hwwdg->Init.Counter));
0201   assert_param(IS_WWDG_EWI_MODE(hwwdg->Init.EWIMode));
0202 
0203 #if (USE_HAL_WWDG_REGISTER_CALLBACKS == 1)
0204   /* Reset Callback pointers */
0205   if (hwwdg->EwiCallback == NULL)
0206   {
0207     hwwdg->EwiCallback = HAL_WWDG_EarlyWakeupCallback;
0208   }
0209 
0210   if (hwwdg->MspInitCallback == NULL)
0211   {
0212     hwwdg->MspInitCallback = HAL_WWDG_MspInit;
0213   }
0214 
0215   /* Init the low level hardware */
0216   hwwdg->MspInitCallback(hwwdg);
0217 #else
0218   /* Init the low level hardware */
0219   HAL_WWDG_MspInit(hwwdg);
0220 #endif /* USE_HAL_WWDG_REGISTER_CALLBACKS */
0221 
0222   /* Set WWDG Counter */
0223   WRITE_REG(hwwdg->Instance->CR, (WWDG_CR_WDGA | hwwdg->Init.Counter));
0224 
0225   /* Set WWDG Prescaler and Window */
0226   WRITE_REG(hwwdg->Instance->CFR, (hwwdg->Init.EWIMode | hwwdg->Init.Prescaler | hwwdg->Init.Window));
0227 
0228   /* Return function status */
0229   return HAL_OK;
0230 }
0231 
0232 
0233 /**
0234   * @brief  Initialize the WWDG MSP.
0235   * @param  hwwdg  pointer to a WWDG_HandleTypeDef structure that contains
0236   *                the configuration information for the specified WWDG module.
0237   * @note   When rewriting this function in user file, mechanism may be added
0238   *         to avoid multiple initialize when HAL_WWDG_Init function is called
0239   *         again to change parameters.
0240   * @retval None
0241   */
0242 __weak void HAL_WWDG_MspInit(WWDG_HandleTypeDef *hwwdg)
0243 {
0244   /* Prevent unused argument(s) compilation warning */
0245   UNUSED(hwwdg);
0246 
0247   /* NOTE: This function should not be modified, when the callback is needed,
0248            the HAL_WWDG_MspInit could be implemented in the user file
0249    */
0250 }
0251 
0252 
0253 #if (USE_HAL_WWDG_REGISTER_CALLBACKS == 1)
0254 /**
0255   * @brief  Register a User WWDG Callback
0256   *         To be used instead of the weak (surcharged) predefined callback
0257   * @param  hwwdg WWDG handle
0258   * @param  CallbackID ID of the callback to be registered
0259   *         This parameter can be one of the following values:
0260   *           @arg @ref HAL_WWDG_EWI_CB_ID Early WakeUp Interrupt Callback ID
0261   *           @arg @ref HAL_WWDG_MSPINIT_CB_ID MspInit callback ID
0262   * @param  pCallback pointer to the Callback function
0263   * @retval status
0264   */
0265 HAL_StatusTypeDef HAL_WWDG_RegisterCallback(WWDG_HandleTypeDef *hwwdg, HAL_WWDG_CallbackIDTypeDef CallbackID,
0266                                             pWWDG_CallbackTypeDef pCallback)
0267 {
0268   HAL_StatusTypeDef status = HAL_OK;
0269 
0270   if (pCallback == NULL)
0271   {
0272     status = HAL_ERROR;
0273   }
0274   else
0275   {
0276     switch (CallbackID)
0277     {
0278       case HAL_WWDG_EWI_CB_ID:
0279         hwwdg->EwiCallback = pCallback;
0280         break;
0281 
0282       case HAL_WWDG_MSPINIT_CB_ID:
0283         hwwdg->MspInitCallback = pCallback;
0284         break;
0285 
0286       default:
0287         status = HAL_ERROR;
0288         break;
0289     }
0290   }
0291 
0292   return status;
0293 }
0294 
0295 
0296 /**
0297   * @brief  Unregister a WWDG Callback
0298   *         WWDG Callback is redirected to the weak (surcharged) predefined callback
0299   * @param  hwwdg WWDG handle
0300   * @param  CallbackID ID of the callback to be registered
0301   *         This parameter can be one of the following values:
0302   *           @arg @ref HAL_WWDG_EWI_CB_ID Early WakeUp Interrupt Callback ID
0303   *           @arg @ref HAL_WWDG_MSPINIT_CB_ID MspInit callback ID
0304   * @retval status
0305   */
0306 HAL_StatusTypeDef HAL_WWDG_UnRegisterCallback(WWDG_HandleTypeDef *hwwdg, HAL_WWDG_CallbackIDTypeDef CallbackID)
0307 {
0308   HAL_StatusTypeDef status = HAL_OK;
0309 
0310   switch (CallbackID)
0311   {
0312     case HAL_WWDG_EWI_CB_ID:
0313       hwwdg->EwiCallback = HAL_WWDG_EarlyWakeupCallback;
0314       break;
0315 
0316     case HAL_WWDG_MSPINIT_CB_ID:
0317       hwwdg->MspInitCallback = HAL_WWDG_MspInit;
0318       break;
0319 
0320     default:
0321       status = HAL_ERROR;
0322       break;
0323   }
0324 
0325   return status;
0326 }
0327 #endif /* USE_HAL_WWDG_REGISTER_CALLBACKS */
0328 
0329 /**
0330   * @}
0331   */
0332 
0333 /** @defgroup WWDG_Exported_Functions_Group2 IO operation functions
0334   * @ingroup RTEMSBSPsARMSTM32H7
0335   *  @brief    IO operation functions
0336   *
0337 @verbatim
0338   ==============================================================================
0339                       ##### IO operation functions #####
0340   ==============================================================================
0341   [..]
0342     This section provides functions allowing to:
0343     (+) Refresh the WWDG.
0344     (+) Handle WWDG interrupt request and associated function callback.
0345 
0346 @endverbatim
0347   * @{
0348   */
0349 
0350 /**
0351   * @brief  Refresh the WWDG.
0352   * @param  hwwdg  pointer to a WWDG_HandleTypeDef structure that contains
0353   *                the configuration information for the specified WWDG module.
0354   * @retval HAL status
0355   */
0356 HAL_StatusTypeDef HAL_WWDG_Refresh(WWDG_HandleTypeDef *hwwdg)
0357 {
0358   /* Write to WWDG CR the WWDG Counter value to refresh with */
0359   WRITE_REG(hwwdg->Instance->CR, (hwwdg->Init.Counter));
0360 
0361   /* Return function status */
0362   return HAL_OK;
0363 }
0364 
0365 /**
0366   * @brief  Handle WWDG interrupt request.
0367   * @note   The Early Wakeup Interrupt (EWI) can be used if specific safety operations
0368   *         or data logging must be performed before the actual reset is generated.
0369   *         The EWI interrupt is enabled by calling HAL_WWDG_Init function with
0370   *         EWIMode set to WWDG_EWI_ENABLE.
0371   *         When the downcounter reaches the value 0x40, and EWI interrupt is
0372   *         generated and the corresponding Interrupt Service Routine (ISR) can
0373   *         be used to trigger specific actions (such as communications or data
0374   *         logging), before resetting the device.
0375   * @param  hwwdg  pointer to a WWDG_HandleTypeDef structure that contains
0376   *                the configuration information for the specified WWDG module.
0377   * @retval None
0378   */
0379 void HAL_WWDG_IRQHandler(WWDG_HandleTypeDef *hwwdg)
0380 {
0381   /* Check if Early Wakeup Interrupt is enable */
0382   if (__HAL_WWDG_GET_IT_SOURCE(hwwdg, WWDG_IT_EWI) != RESET)
0383   {
0384     /* Check if WWDG Early Wakeup Interrupt occurred */
0385     if (__HAL_WWDG_GET_FLAG(hwwdg, WWDG_FLAG_EWIF) != RESET)
0386     {
0387       /* Clear the WWDG Early Wakeup flag */
0388       __HAL_WWDG_CLEAR_FLAG(hwwdg, WWDG_FLAG_EWIF);
0389 
0390 #if (USE_HAL_WWDG_REGISTER_CALLBACKS == 1)
0391       /* Early Wakeup registered callback */
0392       hwwdg->EwiCallback(hwwdg);
0393 #else
0394       /* Early Wakeup callback */
0395       HAL_WWDG_EarlyWakeupCallback(hwwdg);
0396 #endif /* USE_HAL_WWDG_REGISTER_CALLBACKS */
0397     }
0398   }
0399 }
0400 
0401 
0402 /**
0403   * @brief  WWDG Early Wakeup callback.
0404   * @param  hwwdg  pointer to a WWDG_HandleTypeDef structure that contains
0405   *                the configuration information for the specified WWDG module.
0406   * @retval None
0407   */
0408 __weak void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg)
0409 {
0410   /* Prevent unused argument(s) compilation warning */
0411   UNUSED(hwwdg);
0412 
0413   /* NOTE: This function should not be modified, when the callback is needed,
0414            the HAL_WWDG_EarlyWakeupCallback could be implemented in the user file
0415    */
0416 }
0417 
0418 /**
0419   * @}
0420   */
0421 
0422 /**
0423   * @}
0424   */
0425 
0426 #endif /* HAL_WWDG_MODULE_ENABLED */
0427 /**
0428   * @}
0429   */
0430 
0431 /**
0432   * @}
0433   */