EVE 1.0
watchdog.c
1 #include <stdint.h>
2 #include <dev/watchdog.h>
3 #include <sys/clock.h>
4 #include <core/pm.h>
5 #include <core/mwork.h>
6 #include <core/irq-prio.h>
7 #include <nrf52.h>
8 #include <hal/nrf_wdt.h>
9 
10 #define WATCHDOG_TIMEOUT_S 4
11 
12 struct watchdog_state_t
13 {
14  unsigned dt;
15  struct mwork_t work;
16 };
17 
18 static void watchdog_work_cb(struct mwork_t *work);
19 
20 static struct watchdog_state_t watchdog_state;
21 
22 void watchdog_init(void)
23 {
24  nrf_wdt_behaviour_set(NRF_WDT_BEHAVIOUR_PAUSE_SLEEP_HALT);
25  nrf_wdt_reload_value_set(32768UL * WATCHDOG_TIMEOUT_S - 1);
26  nrf_wdt_reload_request_enable(0);
27  nrf_wdt_int_enable(NRF_WDT_INT_TIMEOUT_MASK);
28  watchdog_state.work = MWORK_INIT_TYPED(watchdog_state.work, watchdog_work_cb);
29 
30  sd_nvic_ClearPendingIRQ(WDT_IRQn);
31  sd_nvic_SetPriority(WDT_IRQn, EVE_IRQ_PRIORITY_HIGH);
32  sd_nvic_EnableIRQ(WDT_IRQn);
33 }
34 
35 void watchdog_start(void)
36 {
37  nrf_wdt_task_trigger(NRF_WDT_TASK_START);
38 }
39 
40 void watchdog_periodic(void)
41 {
42  nrf_wdt_reload_request_set(0);
43  if (watchdog_state.dt)
44  {
46  watchdog_state.work.at = mwork_now() + watchdog_state.dt;
47  mwork_schedule(&watchdog_state.work);
48  }
49 }
50 
51 extern void watchdog_stop_should_never_be_called(void);
52 void watchdog_stop(void)
53 {
54  watchdog_stop_should_never_be_called();
55 }
56 
57 void watchdog_reboot(void)
58 {
59  /* Loop until reboot by wdog */
60  watchdog_init();
61  watchdog_start();
62  __disable_irq();
63  while(1);
64 }
65 
66 void watchdog_keepalive(uint32_t duty)
67 {
68  watchdog_state.dt = MS_TO_TICKS(1000 * WATCHDOG_TIMEOUT_S * 3 / 4) * duty;
69  if (duty)
70  {
72  watchdog_state.work.at = mwork_now() + watchdog_state.dt;
73  mwork_schedule(&watchdog_state.work);
74  }
75  else
76  {
77  mwork_cancel(&watchdog_state.work);
78  }
79 }
80 
81 static void watchdog_work_cb(struct mwork_t *work)
82 {
83  pm_wakeup();
84 }
85 
86 void WDT_IRQHandler(void) __attribute__((section(".text"),interrupt));
87 void WDT_IRQHandler(void)
88 {
89  __BKPT(0);
90 }
91 
Header file for the EVE millisecond-scale work scheduling.
struct work_t work
Definition: mwork.h:183
Definition: mwork.h:182
IRQ priorities.
Header file for the EVE power management framework.
static mwork_time_t mwork_now()
Definition: mwork.h:200
#define SWINT_AUTO_LOCK()
Definition: work.h:113
__attribute__((always_inline)) static inline void swint_enable_indirect_adapter(swint_state_t *state)
Definition: work.h:245
#define MWORK_INIT_TYPED(x, callback)
Definition: mwork.h:126
void mwork_schedule(struct mwork_t *work)
void pm_wakeup(void)
void mwork_cancel(struct mwork_t *work)