static void avr_watchdog_write (avr_t * avr, avr_io_addr_t addr, uint8_t v, void *param) { avr_watchdog_t *p = (avr_watchdog_t *) param; uint8_t old_wde = avr_regbit_get (avr, p->wde); uint8_t old_wdie = avr_regbit_get (avr, p->watchdog.enable); uint8_t old_wdce = avr_regbit_get (avr, p->wdce); uint8_t was_enabled = (old_wde || old_wdie); uint8_t old_v = avr->data[addr]; // allow gdb to see write... avr_core_watch_write (avr, addr, v); if (old_wdce) { uint8_t old_wdp = avr_regbit_get_array (avr, p->wdp, 4); // wdrf (watchdog reset flag) must be cleared before wde can be cleared. if (avr_regbit_get (avr, p->wdrf)) avr_regbit_set (avr, p->wde); avr_watchdog_set_cycle_count_and_timer (avr, p, was_enabled, old_wdp); } else { /* easier to change only what we need rather than check and reset * locked/read-only bits. */ avr->data[addr] = old_v; uint8_t wdce_v = avr_regbit_from_value (avr, p->wdce, v); uint8_t wde_v = avr_regbit_from_value (avr, p->wde, v); if (wdce_v && wde_v) { avr_regbit_set (avr, p->wdce); avr_cycle_timer_register (avr, 4, avr_wdce_clear, p); } else { if (wde_v) // wde can be set but not cleared avr_regbit_set (avr, p->wde); avr_regbit_setto_raw (avr, p->watchdog.enable, v); avr_watchdog_set_cycle_count_and_timer (avr, p, was_enabled, -1); } } }
static void avr_watchdog_reset(avr_io_t * port) { avr_watchdog_t * p = (avr_watchdog_t *)port; avr_t * avr = p->io.avr; if (p->reset_context.wdrf) { p->reset_context.wdrf = 0; /* * if watchdog reset kicked, then watchdog gets restarted at * fastest interval */ avr->run = p->reset_context.avr_run; avr_regbit_set(avr, p->wde); avr_regbit_set(avr, p->wdrf); avr_regbit_set_array_from_value(avr, p->wdp, 4, 0); avr_watchdog_set_cycle_count_and_timer(avr, p, 0, 0); } /* TODO could now use the two pending/running IRQs to do the same * as before */ avr_irq_register_notify(p->watchdog.irq, avr_watchdog_irq_notify, p); }
static void avr_watchdog_reset (avr_io_t * port) { avr_watchdog_t *p = (avr_watchdog_t *) port; avr_t *avr = p->io.avr; if (p->reset_context.wdrf) { /* * if watchdog reset kicked, then watchdog gets restated at fastest interval */ avr->run = p->reset_context.avr_run; avr_regbit_set (avr, p->wde); avr_regbit_set (avr, p->wdrf); avr_regbit_set_array_from_value (avr, p->wdp, 4, 0); avr_watchdog_set_cycle_count_and_timer (avr, p, 0, 0); } avr_irq_register_notify (&p->watchdog.irq, avr_watchdog_irq_notify, p); }