⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 watchdog.c

📁 AVR平台下的CanOpen协议桟源码包括应用
💻 C
字号:
/* ------------------------------------------------------------------------
File   : watchdog.c

Descr  : ELMB Master<->Slave watchdog/monitor mechanism;
         this is the Master (ATmega103) part.

History: 20JUL.00; Henk B&B; Version for ELMB Master processor.
--------------------------------------------------------------------------- */

#include "general.h"
#ifdef __2313_SLAVE_PRESENT__
#include "can.h"
#include "objects.h"
#endif /* __2313_SLAVE_PRESENT__ */

/* ------------------------------------------------------------------------ */
/* Globals */

BOOL        KickWatchdog;
#ifdef __2313_SLAVE_PRESENT__
static BOOL SlaveHasProblem;
#endif /* __2313_SLAVE_PRESENT__ */

/* ------------------------------------------------------------------------ */

void watchdog_init( void )
{
  BOOL global_int_enabled;

  KickWatchdog = TRUE;

  /* Disable interrupts during this operation */
  global_int_enabled = FALSE;
  if( SREG & 0x80 ) global_int_enabled = TRUE;
  CLI();

  /* Watchdog timer part: set prescale to maximum (ca. 1.9 s) and enable */
  WDR();                        /* Recommended before enabling */
#ifdef __ELMB103__
  WDTCR = BIT(WDE) | BIT(WDP0) | BIT(WDP1) | BIT(WDP2); /* For ATmega103 */
#else
  WDTCR = BIT(WDCE) | BIT(WDE); /* To change prescale need timed sequence
				   on ATmega128 */
  WDTCR = BIT(WDE) | BIT(WDP0) | BIT(WDP1) | BIT(WDP2);
  WDTCR = BIT(WDE);             /* Enable watchdog */
#endif /* __ELMB103__ */

  /* Re-enable interrupts if required */
  if( global_int_enabled ) SEI();
 
#ifdef __2313_SLAVE_PRESENT__
  /* Slave processor part, if any present... */
  SlaveHasProblem = FALSE;
#endif /* __2313_SLAVE_PRESENT__ */
}

/* ------------------------------------------------------------------------ */

void watchdog_disable( void )
{
  BOOL global_int_enabled;

  /* Disable interrupts during this operation */
  global_int_enabled = FALSE;
  if( SREG & 0x80 ) global_int_enabled = TRUE;
  CLI();

  /* Watchdog timer disable */
  WDTCR = BIT(WDCE) | BIT(WDE);
  WDTCR = BIT(WDP0) | BIT(WDP1) | BIT(WDP2); /* Keep prescale bits */

  /* Re-enable interrupts if required */
  if( global_int_enabled ) SEI();
}

/* ------------------------------------------------------------------------ */

void watchdog( void )
{
  /* Watchdog timer reset */
  WDR();

  if( (KickWatchdog & TRUE) == FALSE ) return;

#ifdef __2313_SLAVE_PRESENT__
  /* Slave processor watchdog 'reset'
    (once a problem with the Slave has been detected,
     don't bother with the Slave anymore...) */
  if( (SlaveHasProblem & TRUE) == FALSE )
    {
      BYTE cnt;

      /* Disable all interrupts during this operation */
      CLI();

      /* Start aliveness sequence with Slave;
	 generate interrupt signal on Slave */
      SET_MASTER_TO_SLAVE_LOW();
      NOP(); /* Make sure the interrupt is seen by the Slave */
      NOP();
      NOP();

      /* Switch to input */
      SET_MASTER_TO_SLAVE_INPUT();

      /* Enable pull-up resistor */
      SET_MASTER_TO_SLAVE_HIGH();

      /* Slave should now see HIGH signal, and switch to output */

      /* Now await Slave taking signal LOW and then HIGH (with time-out!) */
      cnt = 0;
      do
	{
	  ++cnt;
	}
      while( MASTER_TO_SLAVE_HIGH() && cnt != 0 );

      if( cnt != 0 )
	{
	  /* Await Slave taking signal HIGH (with time-out!) */
	  cnt = 0;
	  do
	    {
	      ++cnt;
	    }
	  while( MASTER_TO_SLAVE_LOW() && cnt != 0 );

	  if( cnt != 0 )
	    {
	      /* Switch to output (will be HIGH, as set above) */
	      SET_MASTER_TO_SLAVE_OUTPUT();
	    }
	  else
	    {
	      /* There is a problem with the Slave:
		 leave Master-to-Slave signal configured as input */

	      /* Slave did not respond */
	      SlaveHasProblem = TRUE;
	    }
	}
      else
	{
	  /* Slave did not respond */
	  SlaveHasProblem = TRUE;
	}

      /* Re-enable interrupts */
      SEI();

      if( (SlaveHasProblem & TRUE) == TRUE )
	{
	  /* Report it (once) */

	  /* CANopen Error Code 0x5000: device hardware */
	  can_write_emergency( 0x00, 0x50, EMG_SLAVE_PROCESSOR,
			       0, 0, 0, ERRREG_MANUFACTURER );

	  /* Enable/start Watchdog Timer (if not enabled already),
	     now that there is no Slave to 'guard' me... */
	  /* ###........ */
	}
      else
	{
	  /* Just to make sure, set it (protection against SEU) */
	  SlaveHasProblem = FALSE;
	}
    }
  else
    {
      /* Reset the Watchdog Timer */
      //WDR();
    }
#endif /* __2313_SLAVE_PRESENT__ */

  KickWatchdog = FALSE;
}

/* ------------------------------------------------------------------------ */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -