Rev 56 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 56 | Rev 61 | ||
|---|---|---|---|
| Line 36... | Line 36... | ||
| 36 | (+) Debug mode: When the microcontroller enters debug mode (core halted), |
36 | (+) Debug mode: When the microcontroller enters debug mode (core halted), |
| 37 | the IWDG counter either continues to work normally or stops, depending |
37 | the IWDG counter either continues to work normally or stops, depending |
| 38 | on DBG_IWDG_STOP configuration bit in DBG module, accessible through |
38 | on DBG_IWDG_STOP configuration bit in DBG module, accessible through |
| 39 | __HAL_DBGMCU_FREEZE_IWDG() and __HAL_DBGMCU_UNFREEZE_IWDG() macros. |
39 | __HAL_DBGMCU_FREEZE_IWDG() and __HAL_DBGMCU_UNFREEZE_IWDG() macros. |
| 40 | 40 | ||
| 41 | [..] Min-max timeout value @32KHz (LSI): ~125us / ~32.7s |
41 | [..] Min-max timeout value @37KHz (LSI): ~108.1us / ~28.28s |
| 42 | The IWDG timeout may vary due to LSI clock frequency dispersion. |
42 | The IWDG timeout may vary due to LSI clock frequency dispersion. |
| 43 | STM32L1xx devices provide the capability to measure the LSI clock |
43 | STM32L1xx devices provide the capability to measure the LSI clock |
| 44 | frequency (LSI clock is internally connected to TIM16 CH1 input capture). |
44 | frequency (LSI clock is internally connected to TIM10 CH1 input capture). |
| 45 | The measured value can be used to have an IWDG timeout with an |
45 | The measured value can be used to have an IWDG timeout with an |
| 46 | acceptable accuracy. |
46 | acceptable accuracy. |
| 47 | 47 | ||
| 48 | [..] Default timeout value (necessary for IWDG_SR status register update): |
48 | [..] Default timeout value (necessary for IWDG_SR status register update): |
| 49 | Constant LSI_VALUE is defined based on the nominal LSI clock frequency. |
49 | Constant LSI_VALUE is defined based on the nominal LSI clock frequency. |
| 50 | This frequency being subject to variations as mentioned above, the |
50 | This frequency being subject to variations as mentioned above, the |
| 51 | default timeout value (defined through constant HAL_IWDG_DEFAULT_TIMEOUT |
51 | default timeout value (defined through constant HAL_IWDG_DEFAULT_TIMEOUT |
| 52 | below) may become too short or too long. |
52 | below) may become too short or too long. |
| 53 | In such cases, this default timeout value can be tuned by redefining |
53 | In such cases, this default timeout value can be tuned by redefining |
| 54 | the constant LSI_VALUE at user-application level (based, for instance, |
54 | the constant LSI_VALUE at user-application level (based, for instance, |
| 55 | on the measured LSI clock frequency as explained above). |
55 | on the measured LSI clock frequency as explained above). |
| Line 59... | Line 59... | ||
| 59 | [..] |
59 | [..] |
| 60 | (#) Use IWDG using HAL_IWDG_Init() function to : |
60 | (#) Use IWDG using HAL_IWDG_Init() function to : |
| 61 | (++) Enable instance by writing Start keyword in IWDG_KEY register. LSI |
61 | (++) Enable instance by writing Start keyword in IWDG_KEY register. LSI |
| 62 | clock is forced ON and IWDG counter starts counting down. |
62 | clock is forced ON and IWDG counter starts counting down. |
| 63 | (++) Enable write access to configuration registers: |
63 | (++) Enable write access to configuration registers: |
| 64 | IWDG_PR, IWDG_RLR and IWDG_WINR. |
64 | IWDG_PR and IWDG_RLR. |
| 65 | (++) Configure the IWDG prescaler and counter reload value. This reload |
65 | (++) Configure the IWDG prescaler and counter reload value. This reload |
| 66 | value will be loaded in the IWDG counter each time the watchdog is |
66 | value will be loaded in the IWDG counter each time the watchdog is |
| 67 | reloaded, then the IWDG will start counting down from this value. |
67 | reloaded, then the IWDG will start counting down from this value. |
| 68 | (++) Wait for status flags to be reset. |
68 | (++) Wait for status flags to be reset. |
| 69 | 69 | ||
| Line 113... | Line 113... | ||
| 113 | * @{ |
113 | * @{ |
| 114 | */ |
114 | */ |
| 115 | /* 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 |
| 116 | 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 |
| 117 | 6 for the timeout value calculation. |
117 | 6 for the timeout value calculation. |
| 118 | The timeout value is also calculated using the highest prescaler (256) and |
118 | The timeout value is calculated using the highest prescaler (256) and |
| 119 | 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 |
| 120 | to take into account possible LSI clock period variations. |
120 | to take into account possible LSI clock period variations. |
| 121 | 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. |
| - | 122 | LSI startup time is also considered here by adding LSI_STARTUP_TIMEOUT |
|
| - | 123 | converted in milliseconds. */ |
|
| 122 | #define HAL_IWDG_DEFAULT_TIMEOUT ((6UL * 256UL * 1000UL) / LSI_VALUE) |
124 | #define HAL_IWDG_DEFAULT_TIMEOUT (((6UL * 256UL * 1000UL) / LSI_VALUE) + ((LSI_STARTUP_TIME / 1000UL) + 1UL)) |
| - | 125 | #define IWDG_KERNEL_UPDATE_FLAGS (IWDG_SR_RVU | IWDG_SR_PVU) |
|
| 123 | /** |
126 | /** |
| 124 | * @} |
127 | * @} |
| 125 | */ |
128 | */ |
| 126 | 129 | ||
| 127 | /* Private macro -------------------------------------------------------------*/ |
130 | /* Private macro -------------------------------------------------------------*/ |
| Line 174... | Line 177... | ||
| 174 | assert_param(IS_IWDG_RELOAD(hiwdg->Init.Reload)); |
177 | assert_param(IS_IWDG_RELOAD(hiwdg->Init.Reload)); |
| 175 | 178 | ||
| 176 | /* Enable IWDG. LSI is turned on automatically */ |
179 | /* Enable IWDG. LSI is turned on automatically */ |
| 177 | __HAL_IWDG_START(hiwdg); |
180 | __HAL_IWDG_START(hiwdg); |
| 178 | 181 | ||
| 179 | /* Enable write access to IWDG_PR, IWDG_RLR and IWDG_WINR registers by writing |
182 | /* Enable write access to IWDG_PR and IWDG_RLR registers by writing |
| 180 | 0x5555 in KR */ |
183 | 0x5555 in KR */ |
| 181 | IWDG_ENABLE_WRITE_ACCESS(hiwdg); |
184 | IWDG_ENABLE_WRITE_ACCESS(hiwdg); |
| 182 | 185 | ||
| 183 | /* Write to IWDG registers the Prescaler & Reload values to work with */ |
186 | /* Write to IWDG registers the Prescaler & Reload values to work with */ |
| 184 | hiwdg->Instance->PR = hiwdg->Init.Prescaler; |
187 | hiwdg->Instance->PR = hiwdg->Init.Prescaler; |
| Line 186... | Line 189... | ||
| 186 | 189 | ||
| 187 | /* Check pending flag, if previous update not done, return timeout */ |
190 | /* Check pending flag, if previous update not done, return timeout */ |
| 188 | tickstart = HAL_GetTick(); |
191 | tickstart = HAL_GetTick(); |
| 189 | 192 | ||
| 190 | /* Wait for register to be updated */ |
193 | /* Wait for register to be updated */ |
| 191 | while (hiwdg->Instance->SR != 0x00u) |
194 | while ((hiwdg->Instance->SR & IWDG_KERNEL_UPDATE_FLAGS) != 0x00u) |
| 192 | { |
195 | { |
| 193 | if ((HAL_GetTick() - tickstart) > HAL_IWDG_DEFAULT_TIMEOUT) |
196 | if ((HAL_GetTick() - tickstart) > HAL_IWDG_DEFAULT_TIMEOUT) |
| 194 | { |
197 | { |
| - | 198 | if ((hiwdg->Instance->SR & IWDG_KERNEL_UPDATE_FLAGS) != 0x00u) |
|
| - | 199 | { |
|
| 195 | return HAL_TIMEOUT; |
200 | return HAL_TIMEOUT; |
| - | 201 | } |
|
| 196 | } |
202 | } |
| 197 | } |
203 | } |
| 198 | 204 | ||
| 199 | /* Reload IWDG counter with value defined in the reload register */ |
205 | /* Reload IWDG counter with value defined in the reload register */ |
| 200 | __HAL_IWDG_RELOAD_COUNTER(hiwdg); |
206 | __HAL_IWDG_RELOAD_COUNTER(hiwdg); |
| 201 | 207 | ||
| 202 | /* Return function status */ |
208 | /* Return function status */ |
| 203 | return HAL_OK; |
209 | return HAL_OK; |
| 204 | } |
210 | } |
| 205 | 211 | ||
| - | 212 | ||
| 206 | /** |
213 | /** |
| 207 | * @} |
214 | * @} |
| 208 | */ |
215 | */ |
| 209 | 216 | ||
| 210 | 217 | ||
| Line 220... | Line 227... | ||
| 220 | 227 | ||
| 221 | @endverbatim |
228 | @endverbatim |
| 222 | * @{ |
229 | * @{ |
| 223 | */ |
230 | */ |
| 224 | 231 | ||
| 225 | - | ||
| 226 | /** |
232 | /** |
| 227 | * @brief Refresh the IWDG. |
233 | * @brief Refresh the IWDG. |
| 228 | * @param hiwdg pointer to a IWDG_HandleTypeDef structure that contains |
234 | * @param hiwdg pointer to a IWDG_HandleTypeDef structure that contains |
| 229 | * the configuration information for the specified IWDG module. |
235 | * the configuration information for the specified IWDG module. |
| 230 | * @retval HAL status |
236 | * @retval HAL status |
| Line 236... | Line 242... | ||
| 236 | 242 | ||
| 237 | /* Return function status */ |
243 | /* Return function status */ |
| 238 | return HAL_OK; |
244 | return HAL_OK; |
| 239 | } |
245 | } |
| 240 | 246 | ||
| - | 247 | ||
| 241 | /** |
248 | /** |
| 242 | * @} |
249 | * @} |
| 243 | */ |
250 | */ |
| 244 | 251 | ||
| 245 | /** |
252 | /** |