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

📄 exceptions.c

📁 GM5621原代码
💻 C
字号:
/*
	$Workfile:   exceptions.c  $
	$Revision:   1.14  $
	$Date:   Jul 19 2004 10:34:22  $
*/

//******************************************************************
//
//		Copyright (C) 2001.  GENESIS MICROCHIP INC.
// All rights reserved.  No part of this program may be reproduced
//
//	Genesis Microchip Inc., 165 Commerce Valley Dr. West
//		Thornhill, Ontario, Canada, L3T 7V8
//
//================================================================
//
// MODULE:  exceptions.c
//
// USAGE :  provide 80c186 exception handlers for divide by 0 interrupt
//			bus watchdog timer, software watchdog timer
//
//
//******************************************************************

//******************************************************************
//                  I N C L U D E    F I L E S
//******************************************************************
#include "inc\all.h"
#include "system\mcu186.h"
#include <mem.h>
#if ProcessExceptions != DisableExceptions 

//**************************************************************
//	         L O C A L   V A R I A B L ES
//**************************************************************
WORD exceptionFound;  // ISR will set bit corresponding to exception type
						// can be cleared by gprobe

#if ProcessExceptions == ReportExceptions
WORD savestack[Exception_STACKSIZE]; // save 20 WORD of stack if ReportExceptions if enabled
#endif
static WORD watchdog;					
//**************************************************************
//	         L O C A L   D E F I N I T I O N S
//**************************************************************

//
// Watch dog timer defines
//
#define WDT_ENA ( (WORD)1 << 15)
#define WDT_WRST ( (WORD)1 << 14)
#define WDT_RSTFLAG ( (WORD)1 << 13)
#define WDT_NMIFLAG ( (WORD)1 << 12)
#define WDT_COUNT  0xFF      
 
#define WDT_TIMEOUT (WDT_TIMEOUT_SECONDS * 3)   //watchdog timer interval is approx 1/3 second,  set timeout to WDT_TIMEOUT_SECONDS
#if WDT_TIMEOUT > 255
	#error WDT_TIMEOUT_SECONDS too long, it must have a value of 85 or less
#endif
//
// Bit fields for reporting exception type encountered
//
#define ExceptionDiv0		0x0001
#define ExceptionBounds		0x0002
#define ExceptionBusWDT 	0x0004
#define ExceptionNMI		0x0008
#define ExceptionGeneric 	0x0010

//**************************************************************
//	         L O C A L   F U N C T I O N    P R O T O T Y P E S
//**************************************************************
#if RESET_ON_WDT
static void ResetOCM(void);
#endif
#ifdef USE_ExceptionHandler
static void ExceptionHandler(WORD exceptiontype);
#endif
#if  UseWatchdogTimer == 1
static void ResetWatchDog(void);
static void EnableWatchDogTimer(void);
#endif
static void InitBUS_WDT(void);


//**************************************************************
//	         C O D E
//**************************************************************


//***************************************************************
//	DESCRIPTION	:	
//	SYNTAX     	:	
//	PARAMETERS	:	None
//  RETURN		:	none
//					none
//***************************************************************

//***************************************************************
//	DESCRIPTION	:	process divide by 0 interrupts (int 0) by either 
//					simply returning from an interrupt or switching context
//					to a debug handler allowing examination of stack and
//					other system variables
//	SYNTAX     	:  void far interrupt IrqFourManager (void)
//	PARAMETERS	:	None
//  RETURN		:	none
//					none
//***************************************************************

void far interrupt Div0IRQHanlder (void)
{
	exceptionFound |= ExceptionDiv0;
	#if TRAP_DIV0
		ExceptionHandler(ExceptionDiv0);
	#endif
	
}

//***************************************************************
//	DESCRIPTION	:	non maskable interrupt (Watch dog timer)
//	SYNTAX     	:  void far interrupt NMIHanlder (void)	
//	PARAMETERS	:	None
//  RETURN		:	none
//					none
//***************************************************************
void far interrupt NMIHanlder (void)
{
	// reset timer
#if  UseWatchdogTimer == 1
	ResetWatchDog();
	watchdog--; // decrement counter
	if(watchdog == 0)
	{
		exceptionFound |= ExceptionNMI;
		watchdog = WDT_TIMEOUT; // reset for next go around in case we don't reset
		#if TRAP_WDT
			ExceptionHandler(ExceptionNMI);
		#endif
		#if RESET_ON_WDT
			ResetOCM();
		#endif
	}
#else
// watchdog timer is disabled but we still detect any NMI that occured.
	exceptionFound |= ExceptionNMI;
#endif
	
}
	   

//***************************************************************
//	DESCRIPTION	:	process array out of bounds interrupt1 (int x) by either 
//					simply returning from an interrupt or switching context
//					to a debug handler allowing examination of stack and
//					other system variables
//	SYNTAX     	:  void far interrupt IrqFourManager (void)
//	PARAMETERS	:	None
//  RETURN		:	none
//					none
//***************************************************************

void far interrupt BoundIRQHanlder (void)
{
	exceptionFound |= ExceptionBounds;
		#if TRAP_BOUND
			ExceptionHandler(ExceptionBounds);
		#endif
}

//***************************************************************
//	DESCRIPTION	:	generic handler to provide trap for exceptions 
//	SYNTAX     	:  such as unused op codes etc. that do not need
//                 any special handling.
//	PARAMETERS	:	None
//  RETURN		:	none
//					none
//***************************************************************

void far interrupt GenericIRQHanlder (void)
{
	exceptionFound |= ExceptionGeneric;
		#if TRAP_GENERIC
			ExceptionHandler(ExceptionGeneric);
		#endif
}

//***************************************************************
//	DESCRIPTION	:	BUS_WDT_IRQHanlder handler to provide trap for exceptions 
//	SYNTAX     	:  void far interrupt BUS_WDT_IRQHanlder(void);
//	PARAMETERS	:	None
//  RETURN		:	none
//					none
//***************************************************************

void far interrupt BUS_WDT_IRQHanlder (void)
{
	gm_WriteRegByte(OCM_BUS_WDT_STATUS,TRANSACTION_ERR); 
	exceptionFound |= ExceptionBusWDT;

		#if TRAP_GENERIC
			ExceptionHandler(ExceptionBusWDT);
		#endif
	WRITE_PCB_REG(EOI, INT1_VTYPE);			// Clear interrupt
		
}

 
//***************************************************************
//	DESCRIPTION	:	set up exception interrupt handlers
//	SYNTAX     	:	void InitExceptionHandler(void)
//	PARAMETERS	:	None
//  RETURN		:	none
//					none
//***************************************************************
void InitExceptionHandler(void)
{
	SET_VECTOR(DIV0_VECTOR, Div0IRQHanlder);
	SET_VECTOR(BOUNDS_VECTOR, BoundIRQHanlder);
	SET_VECTOR(WDT_VECTOR, NMIHanlder);
	SET_VECTOR(SINGLE_STEP_VECTOR, GenericIRQHanlder);
	SET_VECTOR(SWBP_VECTOR, GenericIRQHanlder);
#if (GET_KEY_TIMER_ISR != TIMER0_VECTOR)
#if !defined(USE_ADC_CALIBRATION_ISR) || (USE_ADC_CALIBRATION_ISR == 0)
	SET_VECTOR(INTO_VECTOR, GenericIRQHanlder);
#endif
#endif
	SET_VECTOR(UNUSED_OP_VECTOR, GenericIRQHanlder);
	SET_VECTOR(ESC_VECTOR, GenericIRQHanlder);
	SET_VECTOR(BUS_WDT_VECTOR, BUS_WDT_IRQHanlder);
	InitBUS_WDT();  // enable bus watch dog timer and optionally bus WDT irq
	#if UseWatchdogTimer
		EnableWatchDogTimer();
	#endif	
//
// Following are place holders for 5221 specific interrupts
//  they are commented as interrupts are masked by default
//  customer code that enables interrupts should provide a handler
// 
	#if 0
		SET_VECTOR(IRQIN, GenericIRQHanlder);
		SET_VECTOR(IFM_VECTOR, GenericIRQHanlder);
		SET_VECTOR(INPUT_VECTOR, GenericIRQHanlder);
		SET_VECTOR(MISC_VECTOR, GenericIRQHanlder);
	#endif

}

#if  UseWatchdogTimer == 1
//***************************************************************
//	DESCRIPTION	:	enable watch dog timer to use NMI
//	SYNTAX     	:	void EnableWatchDogTimer(void)
//	PARAMETERS	:	None
//  RETURN		:	none
//					none
//***************************************************************

static void EnableWatchDogTimer(void)
{
	// now, enable watch dog timer
	watchdog = WDT_TIMEOUT;
	WRITE_PCB_REG(WDTCON, 0X3333);
	WRITE_PCB_REG(WDTCON,0XCCCC);
	WRITE_PCB_REG(WDTCON,WDT_ENA | 0x40) ; // enable watchdog to generate NMI after 2^25/100e6 seconds
}

//***************************************************************
//	DESCRIPTION	:	reset watch dog timer so that WDT NMI interrupt
//                  does not immediately re-occur
//	SYNTAX     	:	void ResetWatchDog(void)
//	PARAMETERS	:	None
//  RETURN		:	none
//					none
//***************************************************************

static void ResetWatchDog(void)
{
// reset watchdog counter 
	WRITE_PCB_REG(WDTCON,0XAAAA);
	WRITE_PCB_REG(WDTCON,0X5555);
}
#endif // UseWatchdogTimer == 1

//***************************************************************
//	DESCRIPTION	:	enable bus watch dog timer to prevent bus lockup
//                  if illegal memory operation occurs.  Provide option
//                  to vector to exception handler if bus_wdt fires. 
//	SYNTAX     	:	void InitBUS_WDT(void)
//	PARAMETERS	:	None
//  RETURN		:	none
//					none
//***************************************************************
static void InitBUS_WDT(void)
{
	#if ENABLE_BUS_WDT_IRQ
//		gm_WriteRegByte(OCM_BUS_CONTROL_0,ENABLE_WDT | EN_WDT_INTERRUPT );
//		WRITE_PCB_REG(I1CON,   LEVEL_FIVE); // bus WDT interrupt on ocm interrupt line 1.
	#else
//		gm_WriteRegByte(OCM_BUS_CONTROL_0,ENABLE_WDT  );
	#endif
}


//***************************************************************
//	DESCRIPTION	:	reset watch dog timer counter
//                  should be called periodically in main loop
//                  
//	SYNTAX     	:	void ResetWatchDog(void)
//	PARAMETERS	:	None
//  RETURN		:	none
//					none
//***************************************************************

void PetWatchdog(void)
{
	watchdog = WDT_TIMEOUT;
}

//***************************************************************
//	DESCRIPTION	:	Reset OCM.  First, reset host registers, next
//                  switch OCM clock domain to TCLK (resetting OCM does not do this)
//                  Next, activate OCM_RESET command in OCM_CONTROL register
//
//	SYNTAX     	:	void ResetOCM(void)
//	PARAMETERS	:	None
//  RETURN		:	none
//					none
//***************************************************************
#if RESET_ON_WDT
static void ResetOCM(void)
{
	DWORD i,val = 0;

	// Soft reset 52xx registers
	gm_WriteRegByte(HOST_CONTROL  , SOFT_RESET);

	// software delay calibrated to be 1ms at 100Mhz OCM speed running out
	// of RAM.  When running from parallel flash you can expect the delay
	// to be about 2.5 times longer (2.5ms)
	for(i=0;i<0x500;i++)
		val ^= i;

	// disable all interrupts
	gm_DisableInterrupts();
	gm_WriteRegByte(CLOCK_CONFIG,0x42); 
	gm_WriteRegByte(OCM_CONTROL,OCM_RESET); // note, OCM_RESET is self clearing
}
#endif

#ifdef USE_ExceptionHandler
//***************************************************************
//	DESCRIPTION	:	trap exceptions and call debug handler
//                  to allow examination of stack, variables, etc
//                  Also, Paradigm breakpoint can be placed on this function for debugging
//					
//	SYNTAX     	:	void ExceptionHandler(WORD exceptiontype)
//	PARAMETERS	:	word exceptiontype - indicates which type of exception occured.
//  RETURN		:	none
//					none
//***************************************************************
// surpress "parameter name is never used warning.  We can use the jtag debugger 
// to set a breakpoint on ExceptionHandler and use the parameter to determine the exception type.
#pragma argsused 
static void ExceptionHandler(WORD exceptiontype)
{
	char *stackptr = (char *)_SP + 8 ;
	memmove((char *)savestack,stackptr,sizeof(savestack));
}
#endif //USE_ExceptionHandler

#endif //#if ProcessExceptions != DisableExceptions 

⌨️ 快捷键说明

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