示例#1
0
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);
        }
    }
}
示例#2
0
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);
}
示例#3
0
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);
}