Subversion Repositories canSerial

Rev

Rev 2 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2 Rev 3
Line 1... Line 1...
1
/**
1
/**
2
  ******************************************************************************
2
  ******************************************************************************
3
  * @file    stm32f1xx_hal_iwdg.c
3
  * @file    stm32f1xx_hal_iwdg.c
4
  * @author  MCD Application Team
4
  * @author  MCD Application Team
5
  * @brief   IWDG HAL module driver.
5
  * @brief   IWDG HAL module driver.
6
  *          This file provides firmware functions to manage the following
6
  *          This file provides firmware functions to manage the following
7
  *          functionalities of the Independent Watchdog (IWDG) peripheral:
7
  *          functionalities of the Independent Watchdog (IWDG) peripheral:
8
  *           + Initialization and Start functions
8
  *           + Initialization and Start functions
9
  *           + IO operation functions
9
  *           + IO operation functions
10
  *
10
  *
11
  @verbatim
11
  ******************************************************************************
12
  ==============================================================================
12
  * @attention
13
                    ##### IWDG Generic features #####
13
  *
14
  ==============================================================================
14
  * Copyright (c) 2016 STMicroelectronics.
15
  [..]
15
  * All rights reserved.
16
    (+) The IWDG can be started by either software or hardware (configurable
16
  *
17
        through option byte).
17
  * This software is licensed under terms that can be found in the LICENSE file
18
 
18
  * in the root directory of this software component.
19
    (+) The IWDG is clocked by the Low-Speed Internal clock (LSI) and thus stays
19
  * If no LICENSE file comes with this software, it is provided AS-IS.
20
        active even if the main clock fails.
20
  *
21
 
21
  ******************************************************************************
22
    (+) Once the IWDG is started, the LSI is forced ON and both cannot be
22
  @verbatim
23
        disabled. The counter starts counting down from the reset value (0xFFF).
23
  ==============================================================================
24
        When it reaches the end of count value (0x000) a reset signal is
24
                    ##### IWDG Generic features #####
25
        generated (IWDG reset).
25
  ==============================================================================
26
 
26
  [..]
27
    (+) Whenever the key value 0x0000 AAAA is written in the IWDG_KR register,
27
    (+) The IWDG can be started by either software or hardware (configurable
28
        the IWDG_RLR value is reloaded into the counter and the watchdog reset
28
        through option byte).
29
        is prevented.
29
 
30
 
30
    (+) The IWDG is clocked by the Low-Speed Internal clock (LSI) and thus stays
31
    (+) The IWDG is implemented in the VDD voltage domain that is still functional
31
        active even if the main clock fails.
32
        in STOP and STANDBY mode (IWDG reset can wake up the CPU from STANDBY).
32
 
33
        IWDGRST flag in RCC_CSR register can be used to inform when an IWDG
33
    (+) Once the IWDG is started, the LSI is forced ON and both cannot be
34
        reset occurs.
34
        disabled. The counter starts counting down from the reset value (0xFFF).
35
 
35
        When it reaches the end of count value (0x000) a reset signal is
36
    (+) Debug mode: When the microcontroller enters debug mode (core halted),
36
        generated (IWDG reset).
37
        the IWDG counter either continues to work normally or stops, depending
37
 
38
        on DBG_IWDG_STOP configuration bit in DBG module, accessible through
38
    (+) Whenever the key value 0x0000 AAAA is written in the IWDG_KR register,
39
        __HAL_DBGMCU_FREEZE_IWDG() and __HAL_DBGMCU_UNFREEZE_IWDG() macros.
39
        the IWDG_RLR value is reloaded into the counter and the watchdog reset
40
 
40
        is prevented.
41
    [..] Min-max timeout value @32KHz (LSI): ~125us / ~32.7s
41
 
42
         The IWDG timeout may vary due to LSI clock frequency dispersion.
42
    (+) The IWDG is implemented in the VDD voltage domain that is still functional
43
         STM32F1xx devices provide the capability to measure the LSI clock
43
        in STOP and STANDBY mode (IWDG reset can wake up the CPU from STANDBY).
44
         frequency (LSI clock is internally connected to TIM5 CH4 input capture).
44
        IWDGRST flag in RCC_CSR register can be used to inform when an IWDG
45
         The measured value can be used to have an IWDG timeout with an
45
        reset occurs.
46
         acceptable accuracy.
46
 
47
 
47
    (+) Debug mode: When the microcontroller enters debug mode (core halted),
48
    [..] Default timeout value (necessary for IWDG_SR status register update):
48
        the IWDG counter either continues to work normally or stops, depending
49
         Constant LSI_VALUE is defined based on the nominal LSI clock frequency.
49
        on DBG_IWDG_STOP configuration bit in DBG module, accessible through
50
         This frequency being subject to variations as mentioned above, the
50
        __HAL_DBGMCU_FREEZE_IWDG() and __HAL_DBGMCU_UNFREEZE_IWDG() macros.
51
         default timeout value (defined through constant HAL_IWDG_DEFAULT_TIMEOUT
51
 
52
         below) may become too short or too long.
52
    [..] Min-max timeout value @32KHz (LSI): ~125us / ~32.7s
53
         In such cases, this default timeout value can be tuned by redefining
53
         The IWDG timeout may vary due to LSI clock frequency dispersion.
54
         the constant LSI_VALUE at user-application level (based, for instance,
54
         STM32F1xx devices provide the capability to measure the LSI clock
55
         on the measured LSI clock frequency as explained above).
55
         frequency (LSI clock is internally connected to TIM5 CH4 input capture).
56
 
56
         The measured value can be used to have an IWDG timeout with an
57
                     ##### How to use this driver #####
57
         acceptable accuracy.
58
  ==============================================================================
58
 
59
  [..]
59
    [..] Default timeout value (necessary for IWDG_SR status register update):
60
    (#) Use IWDG using HAL_IWDG_Init() function to :
60
         Constant LSI_VALUE is defined based on the nominal LSI clock frequency.
61
      (++) Enable instance by writing Start keyword in IWDG_KEY register. LSI
61
         This frequency being subject to variations as mentioned above, the
62
           clock is forced ON and IWDG counter starts counting down.
62
         default timeout value (defined through constant HAL_IWDG_DEFAULT_TIMEOUT
63
      (++) Enable write access to configuration registers:
63
         below) may become too short or too long.
64
          IWDG_PR and IWDG_RLR.
64
         In such cases, this default timeout value can be tuned by redefining
65
      (++) Configure the IWDG prescaler and counter reload value. This reload
65
         the constant LSI_VALUE at user-application level (based, for instance,
66
           value will be loaded in the IWDG counter each time the watchdog is
66
         on the measured LSI clock frequency as explained above).
67
           reloaded, then the IWDG will start counting down from this value.
67
 
68
      (++) Wait for status flags to be reset.
68
                     ##### How to use this driver #####
69
 
69
  ==============================================================================
70
    (#) Then the application program must refresh the IWDG counter at regular
70
  [..]
71
        intervals during normal operation to prevent an MCU reset, using
71
    (#) Use IWDG using HAL_IWDG_Init() function to :
72
        HAL_IWDG_Refresh() function.
72
      (++) Enable instance by writing Start keyword in IWDG_KEY register. LSI
73
 
73
           clock is forced ON and IWDG counter starts counting down.
74
     *** IWDG HAL driver macros list ***
74
      (++) Enable write access to configuration registers:
75
     ====================================
75
          IWDG_PR and IWDG_RLR.
76
     [..]
76
      (++) Configure the IWDG prescaler and counter reload value. This reload
77
       Below the list of most used macros in IWDG HAL driver:
77
           value will be loaded in the IWDG counter each time the watchdog is
78
      (+) __HAL_IWDG_START: Enable the IWDG peripheral
78
           reloaded, then the IWDG will start counting down from this value.
79
      (+) __HAL_IWDG_RELOAD_COUNTER: Reloads IWDG counter with value defined in
79
      (++) Wait for status flags to be reset.
80
          the reload register
80
 
81
 
81
    (#) Then the application program must refresh the IWDG counter at regular
82
  @endverbatim
82
        intervals during normal operation to prevent an MCU reset, using
83
  ******************************************************************************
83
        HAL_IWDG_Refresh() function.
84
  * @attention
84
 
85
  *
85
     *** IWDG HAL driver macros list ***
86
  * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
86
     ====================================
87
  * All rights reserved.</center></h2>
87
     [..]
88
  *
88
       Below the list of most used macros in IWDG HAL driver:
89
  * This software component is licensed by ST under BSD 3-Clause license,
89
      (+) __HAL_IWDG_START: Enable the IWDG peripheral
90
  * the "License"; You may not use this file except in compliance with the
90
      (+) __HAL_IWDG_RELOAD_COUNTER: Reloads IWDG counter with value defined in
91
  * License. You may obtain a copy of the License at:
91
          the reload register
92
  *                        opensource.org/licenses/BSD-3-Clause
92
 
93
  *
93
  @endverbatim
94
  ******************************************************************************
94
  */
95
  */
95
 
96
 
96
/* Includes ------------------------------------------------------------------*/
97
/* Includes ------------------------------------------------------------------*/
97
#include "stm32f1xx_hal.h"
98
#include "stm32f1xx_hal.h"
98
 
99
 
99
/** @addtogroup STM32F1xx_HAL_Driver
100
/** @addtogroup STM32F1xx_HAL_Driver
100
  * @{
101
  * @{
101
  */
102
  */
102
 
103
 
103
#ifdef HAL_IWDG_MODULE_ENABLED
104
#ifdef HAL_IWDG_MODULE_ENABLED
104
/** @addtogroup IWDG
105
/** @addtogroup IWDG
105
  * @brief IWDG HAL module driver.
106
  * @brief IWDG HAL module driver.
106
  * @{
107
  * @{
107
  */
108
  */
108
 
109
 
109
/* Private typedef -----------------------------------------------------------*/
110
/* Private typedef -----------------------------------------------------------*/
110
/* Private define ------------------------------------------------------------*/
111
/* Private define ------------------------------------------------------------*/
111
/** @defgroup IWDG_Private_Defines IWDG Private Defines
112
/** @defgroup IWDG_Private_Defines IWDG Private Defines
112
  * @{
113
  * @{
113
  */
114
  */
114
/* Status register needs up to 5 LSI clock periods divided by the clock
115
/* Status register needs up to 5 LSI clock periods divided by the clock
115
   prescaler to be updated. The number of LSI clock periods is upper-rounded to
116
   prescaler to be updated. The number of LSI clock periods is upper-rounded to
116
   6 for the timeout value calculation.
117
   6 for the timeout value calculation.
117
   The timeout value is calculated using the highest prescaler (256) and
118
   The timeout value is calculated using the highest prescaler (256) and
118
   the LSI_VALUE constant. The value of this constant can be changed by the user
119
   the LSI_VALUE constant. The value of this constant can be changed by the user
119
   to take into account possible LSI clock period variations.
120
   to take into account possible LSI clock period variations.
120
   The timeout value is multiplied by 1000 to be converted in milliseconds.
121
   The timeout value is multiplied by 1000 to be converted in milliseconds.
121
   LSI startup time is also considered here by adding LSI_STARTUP_TIME
122
   LSI startup time is also considered here by adding LSI_STARTUP_TIMEOUT
122
   converted in milliseconds. */
123
   converted in milliseconds. */
123
#define HAL_IWDG_DEFAULT_TIMEOUT        (((6UL * 256UL * 1000UL) / LSI_VALUE) + ((LSI_STARTUP_TIME / 1000UL) + 1UL))
124
#define HAL_IWDG_DEFAULT_TIMEOUT        (((6UL * 256UL * 1000UL) / LSI_VALUE) + ((LSI_STARTUP_TIME / 1000UL) + 1UL))
124
#define IWDG_KERNEL_UPDATE_FLAGS        (IWDG_SR_RVU | IWDG_SR_PVU)
125
#define IWDG_KERNEL_UPDATE_FLAGS        (IWDG_SR_RVU | IWDG_SR_PVU)
125
/**
126
/**
126
  * @}
127
  * @}
127
  */
128
  */
128
 
129
 
129
/* Private macro -------------------------------------------------------------*/
130
/* Private macro -------------------------------------------------------------*/
130
/* Private variables ---------------------------------------------------------*/
131
/* Private variables ---------------------------------------------------------*/
131
/* Private function prototypes -----------------------------------------------*/
132
/* Private function prototypes -----------------------------------------------*/
132
/* Exported functions --------------------------------------------------------*/
133
/* Exported functions --------------------------------------------------------*/
133
 
134
 
134
/** @addtogroup IWDG_Exported_Functions
135
/** @addtogroup IWDG_Exported_Functions
135
  * @{
136
  * @{
136
  */
137
  */
137
 
138
 
138
/** @addtogroup IWDG_Exported_Functions_Group1
139
/** @addtogroup IWDG_Exported_Functions_Group1
139
  *  @brief    Initialization and Start functions.
140
  *  @brief    Initialization and Start functions.
140
  *
141
  *
141
@verbatim
142
@verbatim
142
 ===============================================================================
143
 ===============================================================================
143
          ##### Initialization and Start functions #####
144
          ##### Initialization and Start functions #####
144
 ===============================================================================
145
 ===============================================================================
145
 [..]  This section provides functions allowing to:
146
 [..]  This section provides functions allowing to:
146
      (+) Initialize the IWDG according to the specified parameters in the
147
      (+) Initialize the IWDG according to the specified parameters in the
147
          IWDG_InitTypeDef of associated handle.
148
          IWDG_InitTypeDef of associated handle.
148
      (+) Once initialization is performed in HAL_IWDG_Init function, Watchdog
149
      (+) Once initialization is performed in HAL_IWDG_Init function, Watchdog
149
          is reloaded in order to exit function with correct time base.
150
          is reloaded in order to exit function with correct time base.
150
 
151
 
151
@endverbatim
152
@endverbatim
152
  * @{
153
  * @{
153
  */
154
  */
154
 
155
 
155
/**
156
/**
156
  * @brief  Initialize the IWDG according to the specified parameters in the
157
  * @brief  Initialize the IWDG according to the specified parameters in the
157
  *         IWDG_InitTypeDef and start watchdog. Before exiting function,
158
  *         IWDG_InitTypeDef and start watchdog. Before exiting function,
158
  *         watchdog is refreshed in order to have correct time base.
159
  *         watchdog is refreshed in order to have correct time base.
159
  * @param  hiwdg  pointer to a IWDG_HandleTypeDef structure that contains
160
  * @param  hiwdg  pointer to a IWDG_HandleTypeDef structure that contains
160
  *                the configuration information for the specified IWDG module.
161
  *                the configuration information for the specified IWDG module.
161
  * @retval HAL status
162
  * @retval HAL status
162
  */
163
  */
163
HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg)
164
HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg)
164
{
165
{
165
  uint32_t tickstart;
166
  uint32_t tickstart;
166
 
167
 
167
  /* Check the IWDG handle allocation */
168
  /* Check the IWDG handle allocation */
168
  if (hiwdg == NULL)
169
  if (hiwdg == NULL)
169
  {
170
  {
170
    return HAL_ERROR;
171
    return HAL_ERROR;
171
  }
172
  }
172
 
173
 
173
  /* Check the parameters */
174
  /* Check the parameters */
174
  assert_param(IS_IWDG_ALL_INSTANCE(hiwdg->Instance));
175
  assert_param(IS_IWDG_ALL_INSTANCE(hiwdg->Instance));
175
  assert_param(IS_IWDG_PRESCALER(hiwdg->Init.Prescaler));
176
  assert_param(IS_IWDG_PRESCALER(hiwdg->Init.Prescaler));
176
  assert_param(IS_IWDG_RELOAD(hiwdg->Init.Reload));
177
  assert_param(IS_IWDG_RELOAD(hiwdg->Init.Reload));
177
 
178
 
178
  /* Enable IWDG. LSI is turned on automatically */
179
  /* Enable IWDG. LSI is turned on automatically */
179
  __HAL_IWDG_START(hiwdg);
180
  __HAL_IWDG_START(hiwdg);
180
 
181
 
181
  /* Enable write access to IWDG_PR and IWDG_RLR registers by writing
182
  /* Enable write access to IWDG_PR and IWDG_RLR registers by writing
182
  0x5555 in KR */
183
  0x5555 in KR */
183
  IWDG_ENABLE_WRITE_ACCESS(hiwdg);
184
  IWDG_ENABLE_WRITE_ACCESS(hiwdg);
184
 
185
 
185
  /* Write to IWDG registers the Prescaler & Reload values to work with */
186
  /* Write to IWDG registers the Prescaler & Reload values to work with */
186
  hiwdg->Instance->PR = hiwdg->Init.Prescaler;
187
  hiwdg->Instance->PR = hiwdg->Init.Prescaler;
187
  hiwdg->Instance->RLR = hiwdg->Init.Reload;
188
  hiwdg->Instance->RLR = hiwdg->Init.Reload;
188
 
189
 
189
  /* Check pending flag, if previous update not done, return timeout */
190
  /* Check pending flag, if previous update not done, return timeout */
190
  tickstart = HAL_GetTick();
191
  tickstart = HAL_GetTick();
191
 
192
 
192
  /* Wait for register to be updated */
193
  /* Wait for register to be updated */
193
  while ((hiwdg->Instance->SR & IWDG_KERNEL_UPDATE_FLAGS) != 0x00u)
194
  while ((hiwdg->Instance->SR & IWDG_KERNEL_UPDATE_FLAGS) != 0x00u)
194
  {
195
  {
195
    if ((HAL_GetTick() - tickstart) > HAL_IWDG_DEFAULT_TIMEOUT)
196
    if ((HAL_GetTick() - tickstart) > HAL_IWDG_DEFAULT_TIMEOUT)
196
    {
197
    {
197
      if ((hiwdg->Instance->SR & IWDG_KERNEL_UPDATE_FLAGS) != 0x00u)
198
      if ((hiwdg->Instance->SR & IWDG_KERNEL_UPDATE_FLAGS) != 0x00u)
198
      {
199
      {
199
        return HAL_TIMEOUT;
200
        return HAL_TIMEOUT;
200
      }
201
      }
201
    }
202
    }
202
  }
203
  }
203
 
204
 
204
  /* Reload IWDG counter with value defined in the reload register */
205
  /* Reload IWDG counter with value defined in the reload register */
205
  __HAL_IWDG_RELOAD_COUNTER(hiwdg);
206
  __HAL_IWDG_RELOAD_COUNTER(hiwdg);
206
 
207
 
207
  /* Return function status */
208
  /* Return function status */
208
  return HAL_OK;
209
  return HAL_OK;
209
}
210
}
210
 
211
 
211
 
212
 
212
/**
213
/**
213
  * @}
214
  * @}
214
  */
215
  */
215
 
216
 
216
 
217
 
217
/** @addtogroup IWDG_Exported_Functions_Group2
218
/** @addtogroup IWDG_Exported_Functions_Group2
218
  *  @brief   IO operation functions
219
  *  @brief   IO operation functions
219
  *
220
  *
220
@verbatim
221
@verbatim
221
 ===============================================================================
222
 ===============================================================================
222
                      ##### IO operation functions #####
223
                      ##### IO operation functions #####
223
 ===============================================================================
224
 ===============================================================================
224
 [..]  This section provides functions allowing to:
225
 [..]  This section provides functions allowing to:
225
      (+) Refresh the IWDG.
226
      (+) Refresh the IWDG.
226
 
227
 
227
@endverbatim
228
@endverbatim
228
  * @{
229
  * @{
229
  */
230
  */
230
 
231
 
231
/**
232
/**
232
  * @brief  Refresh the IWDG.
233
  * @brief  Refresh the IWDG.
233
  * @param  hiwdg  pointer to a IWDG_HandleTypeDef structure that contains
234
  * @param  hiwdg  pointer to a IWDG_HandleTypeDef structure that contains
234
  *                the configuration information for the specified IWDG module.
235
  *                the configuration information for the specified IWDG module.
235
  * @retval HAL status
236
  * @retval HAL status
236
  */
237
  */
237
HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg)
238
HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg)
238
{
239
{
239
  /* Reload IWDG counter with value defined in the reload register */
240
  /* Reload IWDG counter with value defined in the reload register */
240
  __HAL_IWDG_RELOAD_COUNTER(hiwdg);
241
  __HAL_IWDG_RELOAD_COUNTER(hiwdg);
241
 
242
 
242
  /* Return function status */
243
  /* Return function status */
243
  return HAL_OK;
244
  return HAL_OK;
244
}
245
}
245
 
246
 
246
 
247
 
247
/**
248
/**
248
  * @}
249
  * @}
249
  */
250
  */
250
 
251
 
251
/**
252
/**
252
  * @}
253
  * @}
253
  */
254
  */
254
 
255
 
255
#endif /* HAL_IWDG_MODULE_ENABLED */
256
#endif /* HAL_IWDG_MODULE_ENABLED */
256
/**
257
/**
257
  * @}
258
  * @}
258
  */
259
  */
259
 
260
 
260
/**
261
/**
261
  * @}
262
  * @}
262
  */
263
  */
-
 
264
 
-
 
265
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
-