@@ -49,9 +49,21 @@ STATIC nrfx_timer_t *timer = NULL;
49
49
STATIC nrfx_wdt_t wdt = NRFX_WDT_INSTANCE (0 );
50
50
STATIC nrfx_wdt_channel_id wdt_channel_id ;
51
51
52
- NORETURN void mp_raise_WatchDogTimeout (void ) {
53
- nlr_raise (MP_OBJ_FROM_PTR (& MP_STATE_VM (mp_watchdog_exception )));
54
- }
52
+ const mp_obj_type_t mp_type_WatchDogTimeout = {
53
+ { & mp_type_type },
54
+ .name = MP_QSTR_WatchDogTimeout ,
55
+ .make_new = mp_obj_exception_make_new ,
56
+ .attr = mp_obj_exception_attr ,
57
+ .parent = & mp_type_Exception ,
58
+ };
59
+
60
+ static mp_obj_exception_t mp_watchdog_timeout_exception = {
61
+ .base .type = & mp_type_WatchDogTimeout ,
62
+ .traceback_alloc = 0 ,
63
+ .traceback_len = 0 ,
64
+ .traceback_data = NULL ,
65
+ .args = (mp_obj_tuple_t * )& mp_const_empty_tuple_obj ,
66
+ };
55
67
56
68
STATIC void watchdogtimer_timer_event_handler (nrf_timer_event_t event_type , void * p_context ) {
57
69
(void )p_context ;
@@ -62,7 +74,8 @@ STATIC void watchdogtimer_timer_event_handler(nrf_timer_event_t event_type, void
62
74
63
75
// If the timer hits without being cleared, pause the timer and raise an exception.
64
76
nrfx_timer_pause (timer );
65
- MP_STATE_VM (mp_pending_exception ) = MP_OBJ_FROM_PTR (& MP_STATE_VM (mp_watchdog_exception ));
77
+ mp_obj_exception_clear_traceback (MP_OBJ_FROM_PTR (& mp_watchdog_timeout_exception ));
78
+ MP_STATE_VM (mp_pending_exception ) = & mp_watchdog_timeout_exception ;
66
79
#if MICROPY_ENABLE_SCHEDULER
67
80
if (MP_STATE_VM (sched_state ) == MP_SCHED_IDLE ) {
68
81
MP_STATE_VM (sched_state ) = MP_SCHED_PENDING ;
@@ -84,6 +97,97 @@ void watchdog_watchdogtimer_reset(void) {
84
97
timer_refcount = 0 ;
85
98
}
86
99
100
+ <<<<<<< HEAD
101
+ == = == ==
102
+ //| class WDT:
103
+ //| """Watchdog Timer"""
104
+ //|
105
+ //| def __init__(self, ):
106
+ //| """This class represents the system's Watchdog Timer. It is a
107
+ //| singleton and will always return the same instance.
108
+ //|
109
+ //| """
110
+ //| ...
111
+ //|
112
+ STATIC mp_obj_t watchdog_watchdogtimer_make_new (const mp_obj_type_t * type , size_t n_args ,
113
+ const mp_obj_t * pos_args ,
114
+ mp_map_t * kw_args ) {
115
+ enum { ARG_timeout , ARG_sleep , ARG_hardware };
116
+ static const mp_arg_t allowed_args [] = {
117
+ {MP_QSTR_timeout , MP_ARG_OBJ | MP_ARG_REQUIRED },
118
+ {MP_QSTR_sleep , MP_ARG_BOOL , {.u_bool = false}},
119
+ {MP_QSTR_hardware , MP_ARG_BOOL , {.u_bool = false}},
120
+ };
121
+ mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
122
+
123
+ mp_arg_parse_all (n_args , pos_args , kw_args , MP_ARRAY_SIZE (allowed_args ),
124
+ allowed_args , args );
125
+ mp_float_t timeout = mp_obj_get_float (args [ARG_timeout ].u_obj );
126
+ bool hardware = args [ARG_hardware ].u_bool ;
127
+ bool sleep = args [ARG_sleep ].u_bool ;
128
+
129
+ // If the hardware timer is already running, return that timer.
130
+ // If the parameters have changed, then ignore them, but print
131
+ // an error.
132
+ if (wdt_singleton && hardware ) {
133
+ if ((sleep != wdt_singleton -> sleep )
134
+ || (hardware != wdt_singleton -> hardware )
135
+ || fabsf (timeout - wdt_singleton -> timeout ) > 0.01f ) {
136
+ // Print a warning indicating things aren't quite right
137
+ // mp_printf(&mp_stderr_print, translate("warning: hardware timer was already running"));
138
+ }
139
+ watchdogtimer_hardware_feed ();
140
+ return wdt_singleton ;
141
+ }
142
+
143
+ if (timeout <= 0 ) {
144
+ mp_raise_ValueError (translate ("watchdog timeout must be greater than 0" ));
145
+ }
146
+
147
+ watchdog_watchdogtimer_obj_t * self = m_new_obj (watchdog_watchdogtimer_obj_t );
148
+ self -> base .type = & watchdog_watchdogtimer_type ;
149
+ self -> timeout = timeout ;
150
+ self -> sleep = sleep ;
151
+ self -> hardware = hardware ;
152
+
153
+ if (hardware ) {
154
+ watchdogtimer_hardware_init (self -> timeout , self -> sleep );
155
+ wdt_singleton = self ;
156
+ } else {
157
+ uint64_t ticks = timeout * 31250ULL ;
158
+ if (ticks > UINT32_MAX ) {
159
+ mp_raise_ValueError (translate ("timeout duration exceeded the maximum supported value" ));
160
+ }
161
+
162
+ if (timer_refcount == 0 ) {
163
+ timer = nrf_peripherals_allocate_timer_or_throw ();
164
+ }
165
+ timer_refcount ++ ;
166
+
167
+ nrfx_timer_config_t timer_config = {
168
+ .frequency = NRF_TIMER_FREQ_31250Hz ,
169
+ .mode = NRF_TIMER_MODE_TIMER ,
170
+ .bit_width = NRF_TIMER_BIT_WIDTH_32 ,
171
+ .interrupt_priority = NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY ,
172
+ .p_context = self ,
173
+ };
174
+
175
+ nrfx_timer_init (timer , & timer_config , & watchdogtimer_event_handler );
176
+
177
+ // true enables interrupt.
178
+ nrfx_timer_clear (timer );
179
+ nrfx_timer_compare (timer , NRF_TIMER_CC_CHANNEL0 , ticks , true);
180
+ nrfx_timer_resume (timer );
181
+ }
182
+
183
+ // Feed the watchdog, in case there's a timer that's already running
184
+ // and it's only partially finished.
185
+ mp_obj_t * self_obj = MP_OBJ_FROM_PTR (self );
186
+ watchdog_watchdogtimer_feed (self_obj );
187
+ return self_obj ;
188
+ }
189
+
190
+ >>>>>>> parent of 561e7e619 ... add WatchDogTimeout exception
87
191
//| def feed(self):
88
192
//| """Feed the watchdog timer. This must be called regularly, otherwise
89
193
//| the timer will expire."""
0 commit comments