📄 exceptions.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 + -