HWA
Bare metal programming with style
wda_2.h
Go to the documentation of this file.
1
2
/* This file is part of the HWA project.
3
* Copyright (c) 2012,2015 Christophe Duparquet.
4
* All rights reserved. Read LICENSE.TXT for details.
5
*/
6
43
#define hwa_configure__wda , _hwa_cfwda
44
45
/* Optionnal argument `timeout`
46
*/
47
#define _hw_wda_timeout_16ms , 0
48
#define _hw_wda_timeout_32ms , 1
49
#define _hw_wda_timeout_64ms , 2
50
#define _hw_wda_timeout_125ms , 3
51
#define _hw_wda_timeout_250ms , 4
52
#define _hw_wda_timeout_500ms , 5
53
#define _hw_wda_timeout_1s , 6
54
#define _hw_wda_timeout_2s , 7
55
#define _hw_wda_timeout_4s , 8
56
#define _hw_wda_timeout_8s , 9
57
58
#define _hwa_cfwda(o,a,k,...) \
59
do { HW_B(_hwa_cfwda_ktimeout_,_hw_is_timeout_##k)(o,k,__VA_ARGS__,,) }while(0)
60
61
#define _hwa_cfwda_ktimeout_1(o,k,v,...) \
62
HW_B(_hwa_cfwda_vtimeout_,_hw_wda_timeout_##v)(o,v,__VA_ARGS__)
63
64
#define _hwa_cfwda_vtimeout_0(o,v,...) \
65
HW_E(HW_EM_VAL(v,timeout,(16ms,32ms,64ms,125ms,250ms,500ms,1s,2s,4s,8s)))
66
67
#define _hwa_cfwda_vtimeout_1(o,v,k,...) \
68
hwa->o.config.timeout = HW_A1(_hw_wda_timeout_##v); \
69
HW_B(_hwa_cfwda_kaction_,_hw_is_action_##k)(o,k,__VA_ARGS__)
70
71
#define _hwa_cfwda_ktimeout_0(...) \
72
HW_B(_hwa_cfwda_kaction_,_hw_is_action_##k)(o,k,__VA_ARGS__)
73
74
/* Mandatory argument `action`
75
*/
76
#define _hw_wda_action_none , 0
77
#define _hw_wda_action_irq , 1
78
#define _hw_wda_action_reset , 2
79
#define _hw_wda_action_irq_or_reset , 3
80
81
#define _hwa_cfwda_kaction_0(o,k,...) \
82
HW_E(HW_EM_AN(k,action))
83
84
#define _hwa_cfwda_kaction_1(o,k,v,...) \
85
HW_B(_hwa_cfwda_vaction_,_hw_wda_action_##v)(o,v,__VA_ARGS__)
86
87
#define _hwa_cfwda_vaction_0(o,v,...) \
88
HW_E(HW_EM_VAL(v,action,(none,irq,reset,irq_or_reset)))
89
90
#define _hwa_cfwda_vaction_1(o,v,...) \
91
hwa->o.config.action = HW_A1(_hw_wda_action_##v); \
92
HW_EOL(__VA_ARGS__)
93
94
118
#define hw_enable__wda , _hw_enwda
119
#define _hw_enwda(o,a) _hw_write(o,wde,1)
120
121
#define hwa_enable__wda , _hwa_enwda
122
#define _hwa_enwda(o,a) _hwa_write(o,wde,1)
123
124
#define hw_disable__wda , _hw_dswda
125
#define hwa_disable__wda , _hwa_dswda
126
127
128
/* Disable the watchdog by clearing WDE. That special sequence must be
129
* respected.
130
*
131
* FIXME: that also clears WDRF (required) and other reset flags, as well
132
* as WDIE but this should not be a problem. WDP and WDIF are left intact.
133
* May be should only clear WDRF
134
*
135
* FIXME: 0x27 is the mask for WDP bits in WDTCR
136
*/
137
#define _hw_dswda(o,...) \
138
do { \
139
uint8_t reg ; \
140
_hw_write( core0, mcusr, 0 ); \
141
__asm__ __volatile__(" in %[r], %[wdtcr]" "\n\t" \
142
" ori %[r], %[wdce]|%[wde]" "\n\t" \
143
" out %[wdtcr], %[r]" "\n\t" \
144
" andi %[r], %[wdp]" "\n\t" \
145
" out %[wdtcr], %[r]" "\n\t" \
146
: [r] "=&d" (reg) \
147
: [wdtcr] "I" (HW_ADDRESS((o, csr))-0x20), \
148
[wdce] "I" (1<<HW_POSITION((o, wdce))), \
149
[wde] "I" (1<<HW_POSITION((o, wde))), \
150
[wdp] "I" (0x27)); \
151
} while(0)
152
153
154
/* Action completed when committing
155
*/
156
#define _hwa_dswda(o,...) hwa->o.config.action = HW_A1(_hw_wda_action_none)
157
158
159
169
#define hw_reset__wda , _hw_rstwda
170
171
#define _hw_rstwda(...) hw_asm("wdr"::) HW_EOL(__VA_ARGS__)
172
173
174
/*******************************************************************************
175
* *
176
* Context management *
177
* *
178
*******************************************************************************/
179
180
#define _hwa_setup__wda(o,a) \
181
_hwa_setup_r( o, csr ); \
182
hwa->o.config.action = 0xFF ; \
183
hwa->o.config.timeout = 0xFF
184
185
186
#define _hwa_init__wda(o,a) _hwa_init_r( o, csr, 0x00 )
187
188
189
/* Commit the configuration of a _wda class watchdog
190
*
191
* Turning the watchdog off requires:
192
* 1. Clearing WDRF
193
* 2. Setting WDCE and WDE to 1 in the same operation
194
* 3. Setting WDE to 0 within 4 cycles after 2.
195
*/
196
#define _hwa_commit__wda(o,a) \
197
do { \
198
if ( hwa->o.config.action != 0xFF ) { \
199
if ( hwa->o.config.action == HW_A1(_hw_wda_action_none) ) { \
200
/* Turn it off */
\
201
if ( HW_DEVICE_WDTON == 0 ) \
202
HWA_E(HW_EM_4); \
203
_hwa_write( o, wdrf, 0 ); \
204
_hwa_commit_r( o, wdrf ); \
205
_hwa_write( o, wdce, 1 ); \
206
_hwa_write( o, wde, 1 ); \
207
_hwa_commit_r( o, csr ); \
208
_hwa_write( o, ie, 0 ); \
209
_hwa_write( o, wdce, 0 ); \
210
_hwa_write( o, wde, 0 ); \
211
_hwa_write( o, wdp, 0 ); \
212
} \
213
else { \
214
/* Configure it */
\
215
_hwa_write( o, eie, hwa->o.config.action ); \
216
if ( hwa->o.config.timeout != 0xFF ) \
217
_hwa_write( o, wdp, hwa->o.config.timeout ); \
218
} \
219
hwa->o.config.action = 0xFF ; \
220
hwa->o.config.timeout = 0xFF ; \
221
} \
222
_hwa_commit_r( o, csr ); \
223
} while(0)
Generated for HWA by
1.8.6