#include <stdio.h>
#include <ti/csl/csl_tmr.h>
#include <ti/csl/csl_tmrAux.h>
#include <ti/csl/src/intc/csl_intc.h>
#include <ti/csl/src/intc/csl_intcAux.h>
#include <ti/csl/src/intc/csl_intc.h>
#include <ti/csl/src/intc/_csl_intc.h>
/**********************************************************************
 ************************** Local Definitions *************************
 **********************************************************************/

/* Maximum delay to wait for to detect spurious interrupts. */
#define  MAX_DELAY                  0xFFFF

#pragma DATA_SECTION (_CSL_intcAllocMask, ".bss:csl_section:intc");
CSL_BitMask32*   _CSL_intcAllocMask = NULL;

#pragma CODE_SECTION (_CSL_intcDispatcher, ".text:csl_section:intc");
interrupt void _CSL_intcDispatcher (void)
{
    Uint32  evtId;
    Uint32  intrId = (_CSL_intcCpuIntrTable.currentVectId - \
                    (Uint32)(&_CSL_intcCpuIntrTable) - 4)/4;
        
    /* Get the Event Source of the Interrupt */
    if (intrId < 8) 
        evtId = CSL_FEXTR(((CSL_IntcRegsOvly)CSL_CGEM0_5_REG_BASE_ADDRESS_REGS)->INTMUX1, \
                            (intrId-4)*8+6,(intrId-4)*8);
    else {
        if (intrId < 12) 
            evtId = CSL_FEXTR(((CSL_IntcRegsOvly)CSL_CGEM0_5_REG_BASE_ADDRESS_REGS)->INTMUX2, \
                                (intrId-8)*8+6,(intrId-8)*8);
        else 
            evtId = CSL_FEXTR(((CSL_IntcRegsOvly)CSL_CGEM0_5_REG_BASE_ADDRESS_REGS)->INTMUX3, \
                                (intrId-12)*8+6,(intrId-12)*8);
    }
    
    if (_CSL_intcEventOffsetMap[evtId] != CSL_INTC_MAPPED_NONE) 
        _CSL_intcEventHandlerRecord[_CSL_intcEventOffsetMap[evtId]].handler (
            _CSL_intcEventHandlerRecord[_CSL_intcEventOffsetMap[evtId]].arg 
            );    
}

#pragma CODE_SECTION (_CSL_intcEvent0Dispatcher, ".text:csl_section:intc");
interrupt void _CSL_intcEvent0Dispatcher (void)
{
    volatile CSL_BitMask32  evtRcv;
    Uint32                  evtId;
    Uint32                  evtMask ;
    
    evtRcv = ((CSL_IntcRegsOvly)CSL_CGEM0_5_REG_BASE_ADDRESS_REGS)->MEVTFLAG[0];
    
    while (evtRcv) {
        /* Clear the events */
        ((CSL_IntcRegsOvly)CSL_CGEM0_5_REG_BASE_ADDRESS_REGS)->EVTCLR[0] = evtRcv ;
        evtMask = 1 << 4;
        evtId = 4;
        evtRcv &= ~(0xF);
        do {
            if (evtRcv & evtMask) {
                if (_CSL_intcEventOffsetMap[evtId] != CSL_INTC_MAPPED_NONE) 
                    _CSL_intcEventHandlerRecord
                    [_CSL_intcEventOffsetMap[evtId]].handler (
                        _CSL_intcEventHandlerRecord 
                        [_CSL_intcEventOffsetMap[evtId]].arg
                   );
                evtRcv &= ~evtMask;
            }
                
            evtMask = evtMask << 1;         
            evtId++;
        } while (evtRcv);   
        
        /* Read the MEVTFLAG[0] register */
        evtRcv = ((CSL_IntcRegsOvly)CSL_CGEM0_5_REG_BASE_ADDRESS_REGS)->MEVTFLAG[0];
    }
}

#pragma CODE_SECTION (_CSL_intcEvent1Dispatcher, ".text:csl_section:intc");
interrupt void _CSL_intcEvent1Dispatcher (void)
{
    volatile CSL_BitMask32  evtRcv;
    Uint32                  evtId;
    Uint32                  evtMask ;
    
    /* Read the MEVTFLAG[1] register */
    evtRcv = ((CSL_IntcRegsOvly)CSL_CGEM0_5_REG_BASE_ADDRESS_REGS)->MEVTFLAG[1];
    while (evtRcv) {
        /* Clear the events */
        ((CSL_IntcRegsOvly)CSL_CGEM0_5_REG_BASE_ADDRESS_REGS)->EVTCLR[1] = evtRcv ;
        evtId = 32;
        evtMask = 1;
        do {
            if (evtRcv & evtMask) {
                if (_CSL_intcEventOffsetMap[evtId] != CSL_INTC_MAPPED_NONE) 
                    _CSL_intcEventHandlerRecord 
                        [_CSL_intcEventOffsetMap[evtId]].handler (
                        _CSL_intcEventHandlerRecord 
                            [_CSL_intcEventOffsetMap[evtId]].arg
                    );
                evtRcv &= ~evtMask;
            }    
            evtMask = evtMask << 1;         
            evtId++;
        } while (evtRcv);   
        
        /* Read the MEVTFLAG[1] register */
        evtRcv = ((CSL_IntcRegsOvly)CSL_CGEM0_5_REG_BASE_ADDRESS_REGS)->MEVTFLAG[1];
    }
}

#pragma CODE_SECTION (_CSL_intcEvent2Dispatcher, ".text:csl_section:intc");
interrupt void _CSL_intcEvent2Dispatcher (void)
{
    volatile CSL_BitMask32  evtRcv;
    Uint32                  evtId;
    Uint32                  evtMask ;
    
    /* Read the MEVTFLAG[2] register */
    evtRcv = ((CSL_IntcRegsOvly)CSL_CGEM0_5_REG_BASE_ADDRESS_REGS)->MEVTFLAG[2];
    while (evtRcv) {
        /* Clear the events */
        ((CSL_IntcRegsOvly)CSL_CGEM0_5_REG_BASE_ADDRESS_REGS)->EVTCLR[2] = evtRcv ;
        evtId = 64;
        evtMask = 1;
        do {
            if (evtRcv & evtMask) {
                if (_CSL_intcEventOffsetMap[evtId] != CSL_INTC_MAPPED_NONE) 
                    _CSL_intcEventHandlerRecord 
                        [_CSL_intcEventOffsetMap[evtId]].handler (
                        _CSL_intcEventHandlerRecord 
                            [_CSL_intcEventOffsetMap[evtId]].arg
                    );
                evtRcv &= ~evtMask;
            }    
            evtMask = evtMask << 1;         
            evtId++;
        } while (evtRcv);   
        
        /* Read the MEVTFLAG[2] register */
        evtRcv = ((CSL_IntcRegsOvly)CSL_CGEM0_5_REG_BASE_ADDRESS_REGS)->MEVTFLAG[2];
    }
}

#pragma CODE_SECTION (_CSL_intcEvent3Dispatcher, ".text:csl_section:intc");
interrupt void _CSL_intcEvent3Dispatcher (void)
{
    volatile CSL_BitMask32  evtRcv;
    Uint32                  evtId;
    Uint32                  evtMask ;
    
    /* Read the MEVTFLAG[3] register */
    evtRcv = ((CSL_IntcRegsOvly)CSL_CGEM0_5_REG_BASE_ADDRESS_REGS)->MEVTFLAG[3];
    while (evtRcv) {
        /* Clear the events */
        ((CSL_IntcRegsOvly)CSL_CGEM0_5_REG_BASE_ADDRESS_REGS)->EVTCLR[3] = evtRcv ;
        evtId = 96;
        evtMask = 1;
        do {
            if (evtRcv & evtMask) {
                if (_CSL_intcEventOffsetMap[evtId] != CSL_INTC_MAPPED_NONE) 
                    _CSL_intcEventHandlerRecord 
                        [_CSL_intcEventOffsetMap[evtId]].handler (
                        _CSL_intcEventHandlerRecord 
                            [_CSL_intcEventOffsetMap[evtId]].arg
                    );
                evtRcv &= ~evtMask;
            }    
            evtMask = evtMask << 1;   
            evtId++;    
        } while (evtRcv);   
        
       /* Read the MEVTFLAG[3] register */
        evtRcv = ((CSL_IntcRegsOvly)CSL_CGEM0_5_REG_BASE_ADDRESS_REGS)->MEVTFLAG[3];
    }
}

#pragma DATA_SECTION (_CSL_intcNumEvents, ".bss:csl_section:intc");
Uint16 _CSL_intcNumEvents;

#pragma CODE_SECTION (CSL_intcHookIsr, ".text:csl_section:intc");
CSL_Status  CSL_intcHookIsr (
    CSL_IntcVectId        evtId,
    void                  *isrAddr
)
{
    Uint32      *dispPtr;
    
    dispPtr = (Uint32*)(&_CSL_intcCpuIntrTable);
    dispPtr[evtId + 1] = (Uint32)(isrAddr);
    
    return(CSL_SOK);
}

#pragma CODE_SECTION(CSL_tmrInit, ".text:csl_section:tmr");
CSL_Status CSL_tmrInit (CSL_TmrContext *pContext)
{
    return CSL_SOK;
}


#pragma DATA_SECTION (_CSL_intcCpuIntrTable, ".bss:csl_section:intc");
CSL_IntcVect _CSL_intcCpuIntrTable;

#pragma DATA_SECTION (_CSL_intcEventHandlerRecord, ".bss:csl_section:intc");
CSL_IntcEventHandlerRecord* _CSL_intcEventHandlerRecord;

#pragma DATA_SECTION (_CSL_intcEventOffsetMap, ".bss:csl_section:intc");
Int8 *_CSL_intcEventOffsetMap = NULL;

#pragma CODE_SECTION (CSL_tmrHwControl, ".text:csl_section:tmr");
CSL_Status  CSL_tmrHwControl 
(
    CSL_TmrHandle       hTmr,
    CSL_TmrHwControlCmd cmd,
    void*               arg
)
{
    CSL_Status status = CSL_SOK;

    /* Validate the arguments. */
    if (hTmr == NULL) {
        status = CSL_ESYS_BADHANDLE;
    }
    else if (\
         (cmd <= CSL_TMR_CMD_LOAD_WDKEY) && (cmd != CSL_TMR_CMD_STOP_TIMLO) &&\
         (cmd != CSL_TMR_CMD_STOP_TIMHI) && (cmd != CSL_TMR_CMD_RESET_TIMLO)&&\
         (cmd != CSL_TMR_CMD_RESET_TIMHI)&& (cmd != CSL_TMR_CMD_STOP64) &&\
         (cmd != CSL_TMR_CMD_RESET64)    && (arg == NULL)\
         ) {
        status = CSL_ESYS_INVPARAMS;
    }
    else 
    {
        /* Arguments look good; process the command. */
        switch (cmd) 
        {
            /* Load PRDLO */
            case CSL_TMR_CMD_LOAD_PRDLO:
                CSL_TmrLoadPrdLo(hTmr, (Uint32 *)arg);
                break;

            /* Load PRDHI */
            case CSL_TMR_CMD_LOAD_PRDHI:
                CSL_TmrLoadPrdHi(hTmr, (Uint32 *)arg);
                break;

            /* Load PSCHI */
            case CSL_TMR_CMD_LOAD_PSCHI:
                CSL_TmrLoadPrescalarHi(hTmr, (Uint8 *)arg);
                break;

            /* start the timer Low */
            case CSL_TMR_CMD_START_TIMLO:
                CSL_TmrStartLo(hTmr, *((CSL_TmrEnamode *)arg));
                break;

            /* start the timer Low */
            case CSL_TMR_CMD_START_TIMHI:
                CSL_TmrStartHi(hTmr, *((CSL_TmrEnamode *)arg));
                break;

            /* Stop the Timer Low */
            case CSL_TMR_CMD_STOP_TIMLO:
                CSL_TmrStopLo(hTmr);
                break;

            /* Stop the TimerHi */
            case CSL_TMR_CMD_STOP_TIMHI:
                CSL_TmrStopHi(hTmr);
                break;

            /* Reset the Timer Low */
            case CSL_TMR_CMD_RESET_TIMLO:
                CSL_TmrResetLo(hTmr);
                break;

            /* Reset the TimerHi */
            case CSL_TMR_CMD_RESET_TIMHI:
                CSL_TmrResetHi(hTmr);
                break;

            /* Start the timer in GPtimer64 OR Chained mode */
            case CSL_TMR_CMD_START64:
                CSL_TmrStart64(hTmr, *((CSL_TmrEnamode *)arg));
                break;

            /*Stop the timer of GPtimer64 OR Chained */
            case CSL_TMR_CMD_STOP64:
                CSL_TmrStop64(hTmr);
                break;

            /*Reset the timer of GPtimer64 OR Chained */
            case CSL_TMR_CMD_RESET64:
                CSL_TmrReset64(hTmr);
                break;

            /*Starts the timer in watchdog mode */
            case CSL_TMR_CMD_START_WDT:
                CSL_TmrStartWdt(hTmr, *(CSL_TmrEnamode *)arg);
                break;

            /*loads the watchdog key */
            case CSL_TMR_CMD_LOAD_WDKEY:
                CSL_TmrLoadWdkey(hTmr, *((Uint16 *)arg));
                break;

            default:
                status = CSL_ESYS_INVCMD;
                break;
        }         
    }             
    return status;
}

#pragma CODE_SECTION(CSL_tmrOpen, ".text:csl_section:tmr");
CSL_TmrHandle CSL_tmrOpen 
(
    CSL_TmrObj   *pTmrObj,
    CSL_InstNum  tmrNum,
    CSL_TmrParam *pTmrParam,
    CSL_Status   *pStatus
)
{
    CSL_Status          st;
    CSL_TmrHandle       hTmr = NULL;
    CSL_TmrBaseAddress  baseAddress;

    /* Validate the arguments... */
    if (pStatus == NULL) {
        /* do nothing */
    }
    else if (pTmrObj == NULL) {
        *pStatus = CSL_ESYS_INVPARAMS;
    }
    else 
    {
        /* Arguments look good; get the base address information for the device. */    
        st = CSL_tmrGetBaseAddress(tmrNum, pTmrParam, &baseAddress);
        if (st == CSL_SOK) 
        {
            pTmrObj->regs = baseAddress.regs;
            pTmrObj->tmrNum = (CSL_InstNum)tmrNum;
            hTmr = (CSL_TmrHandle)pTmrObj;
        }
        else 
        {
            pTmrObj->regs = (CSL_TmrRegsOvly)NULL;
            pTmrObj->tmrNum = (CSL_InstNum)-1;
            hTmr = (CSL_TmrHandle)NULL;
        }
        *pStatus = st;
    }
    return hTmr;
}

#pragma CODE_SECTION(CSL_tmrHwSetup, ".text:csl_section:tmr");
CSL_Status  CSL_tmrHwSetup 
(
    CSL_TmrHandle   hTmr,
    CSL_TmrHwSetup* hwSetup
)
{
    Uint32 tmpReg;

    /* Validate the arguments. */
    if (hTmr == NULL)
        return CSL_ESYS_BADHANDLE;

    if (hwSetup == NULL)
        return CSL_ESYS_INVPARAMS;

	/* Load the Period register's */
	hTmr->regs->PRDLO = hwSetup->tmrTimerPeriodLo;
	hTmr->regs->PRDHI = hwSetup->tmrTimerPeriodHi;

	/* Load the counter register's */
	hTmr->regs->CNTLO = hwSetup->tmrTimerCounterLo;
	hTmr->regs->CNTHI = hwSetup->tmrTimerCounterHi;

	tmpReg = hTmr->regs->TCR;

    /* Setup the TCR register  configurations */
	CSL_FINS(tmpReg, TMR_TCR_TIEN_HI, hwSetup->tmrIpGateHi);
	CSL_FINS(tmpReg, TMR_TCR_CLKSRC_HI, hwSetup->tmrClksrcHi);
	CSL_FINS(tmpReg, TMR_TCR_PWID_HI, hwSetup->tmrPulseWidthHi);
	CSL_FINS(tmpReg, TMR_TCR_CP_HI, hwSetup->tmrClockPulseHi);
	CSL_FINS(tmpReg, TMR_TCR_INVINP_HI, hwSetup->tmrInvInpHi);
	CSL_FINS(tmpReg, TMR_TCR_INVOUTP_HI, hwSetup->tmrInvOutpHi);

	/* Setup the TCR register  configurations */
	CSL_FINS(tmpReg, TMR_TCR_TIEN_LO, hwSetup->tmrIpGateLo);
	CSL_FINS(tmpReg, TMR_TCR_CLKSRC_LO, hwSetup->tmrClksrcLo);
	CSL_FINS(tmpReg, TMR_TCR_PWID_LO, hwSetup->tmrPulseWidthLo);
	CSL_FINS(tmpReg, TMR_TCR_CP_LO, hwSetup->tmrClockPulseLo);
	CSL_FINS(tmpReg, TMR_TCR_INVINP_LO, hwSetup->tmrInvInpLo);
	CSL_FINS(tmpReg, TMR_TCR_INVOUTP_LO, hwSetup->tmrInvOutpLo);

    hTmr->regs->TCR = tmpReg;
	
    /* Setup the TGCR register  configurations and the operation mode */
	tmpReg = hTmr->regs->TGCR;

    CSL_FINS(tmpReg, TMR_TGCR_PSCHI, hwSetup->tmrPreScalarCounterHi);
	/* set the operation mode */
    CSL_FINS(tmpReg, TMR_TGCR_TIMMODE, hwSetup->tmrTimerMode);

    hTmr->regs->TGCR = tmpReg;

    return CSL_SOK;
}



#pragma CODE_SECTION (CSL_intcHwControl, ".text:csl_section:intc");
CSL_Status  CSL_intcHwControl(
    CSL_IntcHandle            hIntc,
    CSL_IntcHwControlCmd      controlCommand,
    void*                     commandArg
)

{
    CSL_Status status = CSL_SOK;
    
    if (hIntc == NULL)
        return CSL_ESYS_BADHANDLE;
        
    switch(controlCommand) {
        case CSL_INTC_CMD_EVTENABLE: 
            if (hIntc->vectId < CSL_INTC_VECTID_EXCEP) {
                if (hIntc->vectId < CSL_INTC_VECTID_COMBINE) {
                    if (hIntc->eventId < 4) {
                        if (commandArg)
                            CSL_intcCombinedEventEnable(hIntc->eventId,\
                                                  *(CSL_BitMask32*)commandArg);
                    }
                    CSL_intcInterruptEnable(hIntc->vectId);             
                    CSL_intcEventDisable(hIntc->eventId);                   
                }       
                else 
                    CSL_intcEventEnable(hIntc->eventId);                    
            } 
            else          
                CSL_intcExcepEnable(hIntc->eventId);
            break;
        
        case CSL_INTC_CMD_EVTDISABLE:
            if (hIntc->vectId < CSL_INTC_VECTID_EXCEP) {
                if (hIntc->vectId < CSL_INTC_VECTID_COMBINE) {
                    if (hIntc->eventId < 4) {
                        if (commandArg)
                            CSL_intcCombinedEventDisable(hIntc->eventId, \
                                                  *(CSL_BitMask32*)commandArg);
                    }
                    CSL_intcInterruptDisable(hIntc->vectId);                
                }       
                else 
                    CSL_intcEventDisable(hIntc->eventId);
            }
            else          
                CSL_intcExcepDisable(hIntc->eventId);
            break;
            
        case CSL_INTC_CMD_EVTSET:
            CSL_intcEventSet(hIntc->eventId);               
            break;
                
        case CSL_INTC_CMD_EVTCLEAR:  
            if (hIntc->vectId < CSL_INTC_VECTID_EXCEP) {
                if (hIntc->eventId < 4) {
                    if (commandArg)
                        CSL_intcCombinedEventClear(hIntc->eventId, \
                                                  *(CSL_BitMask32*)commandArg);
                } 
                else                    
                    CSL_intcEventClear(hIntc->eventId);
            } 
            else          
                CSL_intcExcepClear(hIntc->eventId);

            break;
        
        case CSL_INTC_CMD_EVTDROPENABLE:  
            if (hIntc->vectId < CSL_INTC_VECTID_COMBINE)
                CSL_intcInterruptDropEnable(1 << hIntc->vectId); 
            else 
                status = CSL_ESYS_INVCMD;
            break;
        
        case CSL_INTC_CMD_EVTDROPDISABLE:   
            if (hIntc->vectId < CSL_INTC_VECTID_COMBINE)
                CSL_intcInterruptDropDisable(1 << hIntc->vectId); 
            else 
                status = CSL_ESYS_INVCMD;   
            break;
        case CSL_INTC_CMD_EVTINVOKEFUNCTION:    
            CSL_intcInvokeEventHandle (hIntc->eventId);
            break;
        default:
            status = CSL_ESYS_INVCMD;
            break;

    }
    return status;
}

#pragma CODE_SECTION (CSL_tmrGetBaseAddress, ".text:csl_section:tmr");
CSL_Status CSL_tmrGetBaseAddress 
(
    CSL_InstNum 	       tmrNum,
    CSL_TmrParam*          pTmrParam,
    CSL_TmrBaseAddress*    pBaseAddress
)
{
    CSL_Status st = CSL_SOK;

    pTmrParam = pTmrParam;

    if (pBaseAddress == NULL)
        return CSL_ESYS_INVPARAMS;

    switch (tmrNum) {
    case CSL_TMR_0:
        pBaseAddress->regs = (CSL_TmrRegsOvly)CSL_TIMER_0_REGS;
        break;
    case CSL_TMR_1:
        pBaseAddress->regs = (CSL_TmrRegsOvly)CSL_TIMER_1_REGS;
        break;
    case CSL_TMR_2:
        pBaseAddress->regs = (CSL_TmrRegsOvly)CSL_TIMER_2_REGS;
        break;
    case CSL_TMR_3:
        pBaseAddress->regs = (CSL_TmrRegsOvly)CSL_TIMER_3_REGS;
        break;
    case CSL_TMR_4:
        pBaseAddress->regs = (CSL_TmrRegsOvly)CSL_TIMER_4_REGS;
        break;
    case CSL_TMR_5:
        pBaseAddress->regs = (CSL_TmrRegsOvly)CSL_TIMER_5_REGS;
        break;
    case CSL_TMR_6:
        pBaseAddress->regs = (CSL_TmrRegsOvly)CSL_TIMER_6_REGS;
        break;
    case CSL_TMR_7:
        pBaseAddress->regs = (CSL_TmrRegsOvly)CSL_TIMER_7_REGS;
        break;                                
    default:
        pBaseAddress->regs = (CSL_TmrRegsOvly)NULL;
        st = CSL_ESYS_FAIL;
        break;
    }

    return st;
}

#pragma CODE_SECTION (CSL_intcOpen, ".text:csl_section:intc");
CSL_IntcHandle  CSL_intcOpen (
    CSL_IntcObj          *intcObj,
    CSL_IntcEventId      eventId,
    CSL_IntcParam        *param,
    CSL_Status           *status
)
{
    CSL_IntcHandle  hIntc = (CSL_IntcHandle)CSL_INTC_BADHANDLE;
    CSL_Status      openStatus;
    Uint32          evtId;      
    Uint32          _yCo;
    Uint32          _xCo;
    
    evtId = (Uint32)(eventId);
    _yCo = evtId >> 5;          /* _yCo co-ordinate */
    _xCo = 1 << (evtId & 0x1f); /* _xCo co-ordinate */
    
    asm(" dint");
    if (!(_CSL_intcAllocMask[_yCo] & _xCo)) {
        _CSL_intcAllocMask[_yCo] |= _xCo; /* set bit -> used */
        hIntc = intcObj;
    }
    asm(" rint");
    
    if (hIntc != (CSL_IntcHandle)CSL_INTC_BADHANDLE) {
        intcObj->eventId    = eventId;
        intcObj->vectId     = *((CSL_IntcVectId*)param);
        openStatus          = CSL_SOK;
        
        /* Do the Mapping for the Event -> CPU Interrupt */
        if (*((CSL_IntcVectId*)param) < ((Uint32)(CSL_INTC_VECTID_COMBINE))) {
            CSL_intcMapEventVector(eventId,*param); 
            if (eventId < 4) {
                switch (eventId) {
                    case 0:
                        CSL_intcHookIsr(*((CSL_IntcVectId*)param), \
                                        _CSL_intcEvent0Dispatcher);
                        break;
                    case 1:
                        CSL_intcHookIsr(*((CSL_IntcVectId*)param), \
                                       _CSL_intcEvent1Dispatcher);
                        break;
                    case 2:
                        CSL_intcHookIsr(*((CSL_IntcVectId*)param), \
                                       _CSL_intcEvent2Dispatcher);
                        break;
                    case 3:
                        CSL_intcHookIsr(*((CSL_IntcVectId*)param), \
                                       _CSL_intcEvent3Dispatcher);
                        break;                  
                }           
            }
            
        }        
    } 
    else 
        openStatus = CSL_ESYS_FAIL;

    if (status) {
        *status = openStatus;
    }
    
    return hIntc;
}

#pragma CODE_SECTION (CSL_intcInit, ".text:csl_section:intc");
CSL_Status CSL_intcInit (
    CSL_IntcContext   *pContext
)
{
    Uint16       i;
    
    asm(" dint");
    
    if (pContext != NULL) {
        _CSL_intcEventOffsetMap =  pContext->offsetResv;
        _CSL_intcAllocMask = pContext->eventAllocMask;
        _CSL_intcNumEvents =  pContext->numEvtEntries;
        
        for (i = 0; i < ((CSL_INTC_EVENTID_CNT + 31) / 32); i++)
            _CSL_intcAllocMask[i] = 0;
                 
        for (i = 0; i < CSL_INTC_EVENTID_CNT ; i++)
            _CSL_intcEventOffsetMap[i] = CSL_INTC_MAPPED_NONE;
        if (pContext->eventhandlerRecord != NULL) {
            _CSL_intcEventHandlerRecord  = pContext->eventhandlerRecord;            
            for (i = 0; i < _CSL_intcNumEvents; i++) 
                _CSL_intcEventHandlerRecord[i].handler = CSL_INTC_EVTHANDLER_NONE;
        }       
    } 
    _CSL_intcIvpSet();
    _CSL_intcCpuIntrTable.nmiIsr  = _CSL_intcNmiDummy;
    _CSL_intcCpuIntrTable.isr4  = _CSL_intcDispatcher;
    _CSL_intcCpuIntrTable.isr5  = _CSL_intcDispatcher;
    _CSL_intcCpuIntrTable.isr6  = _CSL_intcDispatcher;
    _CSL_intcCpuIntrTable.isr7  = _CSL_intcDispatcher;
    _CSL_intcCpuIntrTable.isr8  = _CSL_intcDispatcher;
    _CSL_intcCpuIntrTable.isr9  = _CSL_intcDispatcher;
    _CSL_intcCpuIntrTable.isr10 = _CSL_intcDispatcher;
    _CSL_intcCpuIntrTable.isr11 = _CSL_intcDispatcher;
    _CSL_intcCpuIntrTable.isr12 = _CSL_intcDispatcher;
    _CSL_intcCpuIntrTable.isr13 = _CSL_intcDispatcher;
    _CSL_intcCpuIntrTable.isr14 = _CSL_intcDispatcher;
    _CSL_intcCpuIntrTable.isr15 = _CSL_intcDispatcher;
    
    asm(" rint");
    
    return CSL_SOK;
}

#pragma CODE_SECTION (CSL_intcPlugEventHandler, ".text:csl_section:intc");
CSL_Status CSL_intcPlugEventHandler (
    CSL_IntcHandle                 hIntc,
    CSL_IntcEventHandlerRecord     *eventHandlerRecord
)
{
    volatile Uint16  i;
    CSL_Status status = CSL_ESYS_FAIL;

    asm(" dint");

    /* Search for free entry and plug in handler */
    
    for (i = 0; i < _CSL_intcNumEvents; i++) {
        if (_CSL_intcEventHandlerRecord[i].handler == CSL_INTC_EVTHANDLER_NONE){
            /* Plug in Handler */
            _CSL_intcEventHandlerRecord[i].handler =
                eventHandlerRecord->handler;
            _CSL_intcEventHandlerRecord[i].arg =
                eventHandlerRecord->arg;    
            /* Establish mapping */
            _CSL_intcEventOffsetMap[hIntc->eventId] = i;
            status = CSL_SOK;
            break;          
        }
    
    }
    asm(" rint");
    
    return status;
}




/**********************************************************************
 ************************** Global Variables **************************
 **********************************************************************/

/* Global Handle which keeps track of the WATCH-DOG Timer. */
//CSL_TmrHandle   wdTmr;

/* INTC Objects */ 
CSL_IntcObj                  tmrIntcObj;
CSL_IntcContext              context;
CSL_IntcEventHandlerRecord   EventHandler[30];

/* Global Variable for the INTC Module; useful for debugging. */
//CSL_IntcRegsOvly    gIntcRegisters    = (CSL_IntcRegsOvly)CSL_CGEM0_5_REG_BASE_ADDRESS_REGS;

/* Counter for Timer ISR */
volatile Int32 timerISRCounter = 0;

/**********************************************************************
 ************************ TIMER 2 INTERRUPT FUNCTIONS ************************
 **********************************************************************/

/**
 *  @b Description
 *  @n  
 *      This is the Timer ISR handler which is invoked when the timer expires
 *
 *  @param[in]  arg
 *      Event ID which caused the ISR to be invoked.
 *
 *  @retval
 *      Not Applicable.
 */
static void TimerInterruptHandler (void *arg)
{
    /* Increment the number of interrupts detected. */
    timerISRCounter++;

    /* Clear the event ID. */
    CSL_intcEventClear((CSL_IntcEventId)arg);
}

/**
 *  @b Description
 *  @n  
 *      The functions initializes the INTC module.
 *
 *  @retval
 *      Success -   0
 *  @retval
 *      Error   -   <0
 */
static Int32 intc_init (void)
{
    CSL_IntcGlobalEnableState   state;

    /* INTC module initialization */
    context.eventhandlerRecord = EventHandler;
    context.numEvtEntries      = 10;
    if (CSL_intcInit(&context) != CSL_SOK) 
        return -1;

    /* Enable NMIs */
    if (CSL_intcGlobalNmiEnable() != CSL_SOK) 
        return -1;
 
    /* Enable global interrupts */
    if (CSL_intcGlobalEnable(&state) != CSL_SOK) 
        return -1;

    /* INTC has been initialized successfully. */
    return 0;
}

/**********************************************************************
 ************************ TIMER_INTERRUPT *****************************
 **********************************************************************/

static Int32 make_1us_timer_interrupt (Uint8 IntcInstance)
{
    CSL_TmrHandle               hTmr;
    CSL_TmrObj                  TmrObj;
    CSL_Status                  intStat, status;
    CSL_TmrHwSetup              hwSetup; 
    CSL_IntcEventHandlerRecord  EventRecord;
    CSL_IntcParam               vectId;
    Uint32                      LoadValue = 1000;
    CSL_IntcHandle              tmrIntcHandle;
    CSL_TmrEnamode              TimeCountMode = CSL_TMR_ENAMODE_ENABLE;
    Uint32                      count;

    /* Clear local data structures */
    memset(&TmrObj, 0, sizeof(CSL_TmrObj));
    printf("Debug: Initialzing Low Timer (Unchained) in One Shot Mode...\n");

    /**************************************************************
     ********************** INTC related code *********************
     **************************************************************/
     
    /* Open INTC */
    vectId = CSL_INTC_VECTID_12;
    tmrIntcHandle = CSL_intcOpen(&tmrIntcObj, CSL_GEM_TINTLN, &vectId, &intStat);
    if (tmrIntcHandle == NULL)
        return -1;
 
    /* Bind ISR to Interrupt */
    EventRecord.handler = (CSL_IntcEventHandler)&TimerInterruptHandler;
    EventRecord.arg     = (void *)CSL_GEM_TINTLN;
    CSL_intcPlugEventHandler(tmrIntcHandle, &EventRecord);

    /* Event Enable */
    CSL_intcHwControl(tmrIntcHandle, CSL_INTC_CMD_EVTENABLE, NULL);
 
    /**************************************************************
     ********************** Timer related code ********************
     **************************************************************/
   
    /* Open the timer. */ 
    hTmr =  CSL_tmrOpen(&TmrObj, IntcInstance, NULL, &status);
    if (hTmr == NULL)
        return -1;

    /* Config the timer */
    hwSetup.tmrTimerMode    = CSL_TMR_TIMMODE_DUAL_UNCHAINED;
    hwSetup.tmrPulseWidthLo = CSL_TMR_PWID_THREECLKS;
    hwSetup.tmrClksrcLo     = CSL_TMR_CLKSRC_INTERNAL;
    hwSetup.tmrClockPulseLo = CSL_TMR_CP_PULSE;
    hwSetup.tmrClockPulseHi = CSL_TMR_CP_PULSE; 
    hwSetup.tmrIpGateLo     = CSL_TMR_CLOCK_INP_NOGATE;
    CSL_tmrHwSetup(hTmr, &hwSetup);
    
    printf("The current CNTLO is : %d\n",hTmr->regs->CNTLO);

    /* Stop the Timer */
    /////////status = CSL_tmrHwControl(hTmr, CSL_TMR_CMD_RESET_TIMLO, NULL);
    
    /* Reset the timer ISR Counter. */
    timerISRCounter = 0;

    /* Load the period register */
    CSL_tmrHwControl(hTmr, CSL_TMR_CMD_LOAD_PRDLO, (void *)&LoadValue);

    /* Start the timer with continue mode */
    CSL_tmrHwControl(hTmr, CSL_TMR_CMD_START_TIMLO, (void *)&TimeCountMode);
    printf("The current CNTLO is : %d\n",hTmr->regs->CNTLO);

    /* INTC related code */
    while (timerISRCounter != 1);

    /* Good. The timer ISR was invoked; now we wait for some time and make
     * sure that the ISR was not invoked again since this is a ONE SHOT
     * Timer. */
    for (LoadValue = 0; LoadValue < MAX_DELAY; LoadValue++);

    /* Timer ISR Counter should still be the same */
    {printf("The current ISR Counter is : %d\n",timerISRCounter);
    if (timerISRCounter < 0)
        return -1;}

    /* Also the LOW Count Register should remain at the value 0. */
    //CSL_tmrGetTimLoCount(hTmr, &count);
    //if (count != 0)
    //    return -1;
 
    /**************************************************************/

    /* Disable the interrupts. */    
    //CSL_intcHwControl(tmrIntcHandle, CSL_INTC_CMD_EVTDISABLE, NULL);
      
    /* Stop the Timer */
    //CSL_tmrHwControl(hTmr, CSL_TMR_CMD_RESET_TIMLO, NULL);

    /* Close the Timer and Interrupt Handles. */
    //CSL_tmrClose(hTmr);
    //CSL_intcClose(tmrIntcHandle);    
 
    /* Test has been completed successfully. */
    return 0;
}


/**
 *  @b Description
 *  @n  
 *      The main code.
 *
 *  @retval
 *      Not Applicable.
 */
void main (void)
{    
    printf ("**************************************************\n");
    printf ("***************  Timer Interrupt  ****************\n");
    printf ("**************************************************\n");

    /* Initialize the INTC Module. */
    if (intc_init() < 0)
    {
        printf ("Error: Initialization of the INTC module failed\n");
        return;
    }
    printf("Debug: Initialization of the INTC module Passed\n");

    /* Initialize timer CSL module */
    CSL_tmrInit(NULL);
    
    /* Start the LOW Timer. */
    if (make_1us_timer_interrupt(CSL_TMR_0) < 0)
    {
        printf("Error: Testing 1us Low Timer (Unchained) in One Shot Mode FAILED\n");
        return;
    }
    printf("Debug: Testing Low Timer (Unchained) in One Shot Mode Passed\n");

   
    /* All the timer tests have passed. */
    printf ("**************************************************\n");
    printf ("*********** Timer Interrupt Successful ***********\n");
    printf ("**************************************************\n");

    return; 
}

