HWA
Bare metal programming with style
wdb_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__wdb , _hwa_cfwdb
44
45
/* Optionnal argument `timeout`
46
*/
47
#define _hw_wdb_timeout_16ms , 0
48
#define _hw_wdb_timeout_32ms , 1
49
#define _hw_wdb_timeout_64ms , 2
50
#define _hw_wdb_timeout_125ms , 3
51
#define _hw_wdb_timeout_250ms , 4
52
#define _hw_wdb_timeout_500ms , 5
53
#define _hw_wdb_timeout_1s , 6
54
#define _hw_wdb_timeout_2s , 7
55
#define _hw_wdb_timeout_4s , 8
56
#define _hw_wdb_timeout_8s , 9
57
58
#define _hwa_cfwdb(o,a,k,...) \
59
do { HW_B(_hwa_cfwdb_ktimeout_,_hw_is_timeout_##k)(o,k,__VA_ARGS__,,) }while(0)
60
61
#define _hwa_cfwdb_ktimeout_1(o,k,v,...) \
62
HW_B(_hwa_cfwdb_vtimeout_,_hw_wdb_timeout_##v)(o,v,__VA_ARGS__)
63
64
#define _hwa_cfwdb_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_cfwdb_vtimeout_1(o,v,k,...) \
68
hwa->o.config.timeout = HW_A1(_hw_wdb_timeout_##v); \
69
HW_B(_hwa_cfwdb_kaction_,_hw_is_action_##k)(o,k,__VA_ARGS__)
70
71
#define _hwa_cfwdb_ktimeout_0(...) \
72
HW_B(_hwa_cfwdb_kaction_,_hw_is_action_##k)(o,k,__VA_ARGS__)
73
74
/* Mandatory argument `action`
75
*/
76
#define _hw_wdb_action_none , 0
77
#define _hw_wdb_action_irq , 1
78
#define _hw_wdb_action_reset , 2
79
#define _hw_wdb_action_irq_or_reset , 3
80
81
#define _hwa_cfwdb_kaction_0(o,k,...) HW_E(HW_EM_VL(k,(action)))
82
#define _hwa_cfwdb_kaction_1(o,k,v,...) HW_B(_hwa_cfwdb_vaction_,_hw_wdb_action_##v)(o,v,__VA_ARGS__)
83
#define _hwa_cfwdb_vaction_0(o,v,...) HW_E(HW_EM_VAL(v,action,(none,irq,reset,irq_or_reset)))
84
#define _hwa_cfwdb_vaction_1(o,v,...) \
85
hwa->o.config.action = HW_A1(_hw_wdb_action_##v); \
86
HW_EOL(__VA_ARGS__)
87
88
112
#define hw_enable__wdb , _hw_enwdb
113
#define _hw_enwdb(o,a) _hw_write(o,wde,1)
114
115
#define hwa_enable__wdb , _hwa_enwdb
116
#define _hwa_enwdb(o,a) _hwa_write(o,wde,1)
117
118
#define hw_disable__wdb , _hw_dswdb
119
#define hwa_disable__wdb , _hwa_dswdb
120
121
/* Disable the watchdog by clearing WDE. That special sequence must be
122
* respected.
123
*
124
* FIXME: that also clears WDRF (required) and other reset flags, as well
125
* as WDIE but this should not be a problem. WDP and WDIF are left intact.
126
* May be should only clear WDRF
127
*
128
* FIXME: 0x27 is the mask for WDP bits in WDTCR
129
*/
130
#define _hw_dswdb(o,...) \
131
do { \
132
uint8_t reg ; \
133
_hw_write( core0, mcusr, 0 ); \
134
__asm__ __volatile__(" in %[r], %[wdtcr]" "\n\t" \
135
" ori %[r], %[wdce]|%[wde]" "\n\t" \
136
" out %[wdtcr], %[r]" "\n\t" \
137
" andi %[r], %[wdp]" "\n\t" \
138
" out %[wdtcr], %[r]" "\n\t" \
139
: [r] "=&d" (reg) \
140
: [wdtcr] "I" (HW_ADDRESS((o, csr))-0x20), \
141
[wdce] "I" (1<<HW_POSITION((o, wdce))), \
142
[wde] "I" (1<<HW_POSITION((o, wde))), \
143
[wdp] "I" (0x27)); \
144
} while(0)
145
146
147
/* Action completed when committing
148
*/
149
#define _hwa_dswdb(o,...) hwa->o.config.action = HW_A1(_hw_wdb_action_none)
150
151
161
#define hw_reset__wdb , _hw_rstwdb
162
163
#define _hw_rstwdb(o,a,...) hw_asm("wdr"::) HW_EOL(__VA_ARGS__)
164
165
166
/*******************************************************************************
167
* *
168
* Context management *
169
* *
170
*******************************************************************************/
171
172
#define _hwa_setup__wdb(o,a) \
173
_hwa_setup_r( o, csr ); \
174
hwa->o.config.action = 0xFF ; \
175
hwa->o.config.timeout = 0xFF
176
177
#define _hwa_init__wdb(o,a) _hwa_init_r( o, csr, 0x00 )
178
179
/* Commit the configuration of a _wdb class watchdog
180
*
181
* Turning the watchdog off requires to:
182
* 1. Clear WDRF
183
* 2. Clear WDIF
184
* 3. Set WDCE and WDE to 1 in the same operation
185
* 4. Set WDE to 0 within 4 cycles after step 3.
186
*/
187
#define _hwa_commit__wdb(o,a) \
188
do { \
189
if ( hwa->o.config.action != 0xFF ) { \
190
if ( hwa->o.config.action == HW_A1(_hw_wdb_action_none) ) { \
191
/* Turn it off */
\
192
if ( HW_DEVICE_FUSE_WDTON == 0 ) \
193
HWA_E(HW_EM_4); \
194
_hwa_write( o, wdrf, 0 ); \
195
_hwa_commit_r( o, wdrf ); \
196
_hwa_write( o, if, 1 );
/* was not in _wodga */
\
197
_hwa_write( o, wdce, 1 ); \
198
_hwa_write( o, wde, 1 ); \
199
_hwa_commit_r( o, csr ); \
200
_hwa_write( o, ie, 0 ); \
201
_hwa_write( o, wdce, 0 ); \
202
_hwa_write( o, wde, 0 ); \
203
_hwa_write( o, wdp, 0 ); \
204
} \
205
else { \
206
/* Configure it */
\
207
_hwa_write( o, wdce, 1 );
/* was not in _wodga */
\
208
_hwa_write( o, wde, 1 );
/* was not in _wodga */
\
209
_hwa_commit_r( o, csr );
/* was not in _wodga */
\
210
_hwa_write( o, wdce, 0 );
/* was not in _wodga */
\
211
_hwa_write( o, eie, hwa->o.config.action ); \
212
if ( hwa->o.config.timeout != 0xFF ) \
213
_hwa_write( o, wdp, hwa->o.config.timeout ); \
214
} \
215
/* hwa->o.config.action = 0xFF ; */
\
216
/* hwa->o.config.timeout = 0xFF ; */
\
217
} \
218
_hwa_commit_r( o, csr ); \
219
} while(0)
Generated for HWA by
1.8.6