libopencm3
A free/libre/open-source firmware library for various ARM Cortex-M3 microcontrollers.
iwdg_common_all.c
Go to the documentation of this file.
1/** @addtogroup iwdg_file IWDG peripheral API
2@ingroup peripheral_apis
3
4@author @htmlonly © @endhtmlonly 2012 Ken Sarkies ksarkies@internode.on.net
5
6This library supports the Independent Watchdog Timer System in the STM32F1xx
7series of ARM Cortex Microcontrollers by ST Microelectronics.
8
9The watchdog timer uses the LSI (low speed internal) clock which is low power
10and continues to operate during stop and standby modes. Its frequency is
11nominally 32kHz (40kHz for the STM32F1xx series) but can vary from as low
12as 17kHz up to 60kHz (refer to datasheet electrical characteristics).
13
14Note that the User Configuration option byte provides a means of automatically
15enabling the IWDG timer at power on (with counter value 0xFFF). If the
16relevant bit is not set, the IWDG timer must be enabled by software.
17
18@note: Tested: CPU STM32F103RET6, Board ET-ARM Stamp STM32
19
20*/
21/*
22 * This file is part of the libopencm3 project.
23 *
24 * This library is free software: you can redistribute it and/or modify
25 * it under the terms of the GNU Lesser General Public License as published by
26 * the Free Software Foundation, either version 3 of the License, or
27 * (at your option) any later version.
28 *
29 * This library is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU Lesser General Public License for more details.
33 *
34 * You should have received a copy of the GNU Lesser General Public License
35 * along with this library. If not, see <http://www.gnu.org/licenses/>.
36 */
37
38/**@{*/
39
41
42#define LSI_FREQUENCY 32000
43#define COUNT_LENGTH 12
44#define COUNT_MASK ((1 << COUNT_LENGTH)-1)
45
46/*---------------------------------------------------------------------------*/
47/** @brief IWDG Enable Watchdog Timer
48
49The watchdog timer is started. The timeout period defaults to 512 milliseconds
50unless it has been previously defined.
51
52*/
53
54void iwdg_start(void)
55{
57}
58
59/*---------------------------------------------------------------------------*/
60/** @brief IWDG Set Period in Milliseconds
61
62The countdown period is converted into count and prescale values. The maximum
63period is 32.76 seconds; values above this are truncated. Periods less than 1ms
64are not supported by this library.
65
66A delay of up to 5 clock cycles of the LSI clock (about 156 microseconds)
67can occasionally occur if the prescale or preload registers are currently busy
68loading a previous value.
69
70@param[in] period uint32_t Period in milliseconds (< 32760) from a watchdog
71reset until a system reset is issued.
72*/
73void iwdg_set_period_ms(uint32_t period)
74{
75 const int PRESCALER_MAX = 6;
76 uint8_t prescale = 0;
77
78 /* Set the count to represent ticks of 8kHz clock (the 32kHz LSI clock
79 * divided by 4 = lowest prescaler setting)
80 */
81 uint32_t count = period << 3;
82
83 /* Prevent underflow */
84 if (count == 0) {
85 count = 1;
86 }
87
88 /* Shift count while increasing prescaler as many times as needed to
89 * fit into IWDG_RLR
90 */
91 while ((count - 1) >> COUNT_LENGTH) {
92 count >>= 1;
93 prescale++;
94 }
95
96 /* IWDG_RLR actually holds count - 1 */
97 count--;
98
99 /* Clamp to max possible period */
100 if (prescale > PRESCALER_MAX) {
101 count = COUNT_MASK;
102 prescale = PRESCALER_MAX;
103 }
104
105 while (iwdg_prescaler_busy());
107 IWDG_PR = prescale;
108 while (iwdg_reload_busy());
110 IWDG_RLR = count & COUNT_MASK;
111
112 /* Refresh counter after configuration is complete */
113 iwdg_reset();
114}
115
116/*---------------------------------------------------------------------------*/
117/** @brief IWDG Get Reload Register Status
118
119@returns boolean: TRUE if the reload register is busy and unavailable for
120loading a new count value.
121*/
122
124{
125 return IWDG_SR & IWDG_SR_RVU;
126}
127
128/*---------------------------------------------------------------------------*/
129/** @brief IWDG Get Prescaler Register Status
130
131@returns boolean: TRUE if the prescaler register is busy and unavailable for
132loading a new period value.
133*/
134
136{
137 return IWDG_SR & IWDG_SR_PVU;
138}
139
140/*---------------------------------------------------------------------------*/
141/** @brief IWDG reset Watchdog Timer
142
143The watchdog timer is reset. The counter restarts from the value in the reload
144register.
145*/
146
147void iwdg_reset(void)
148{
150}
151/**@}*/
152
#define IWDG_RLR
Reload register (IWDG_RLR)
#define IWDG_SR
Status register (IWDG_SR)
#define IWDG_KR
Key Register (IWDG_KR)
#define IWDG_PR
Prescaler register (IWDG_PR)
#define COUNT_MASK
void iwdg_start(void)
IWDG Enable Watchdog Timer.
void iwdg_set_period_ms(uint32_t period)
IWDG Set Period in Milliseconds.
bool iwdg_reload_busy(void)
IWDG Get Reload Register Status.
#define COUNT_LENGTH
bool iwdg_prescaler_busy(void)
IWDG Get Prescaler Register Status.
void iwdg_reset(void)
IWDG reset Watchdog Timer.
#define IWDG_KR_UNLOCK
#define IWDG_KR_RESET
#define IWDG_KR_START
#define IWDG_SR_PVU
PVU: Watchdog prescaler value update.
#define IWDG_SR_RVU
RVU: Watchdog counter reload value update.