コード例 #1
0
ファイル: InterruptArm.c プロジェクト: mobiaqua/ti-ipc1
/*!
 *  ======== InterruptArm_intClear ========
 *  Clear interrupt 
 */
UInt InterruptArm_intClear(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo)
{
    UInt16 statBitPos;
    volatile UInt32 *chipSigReg = (volatile UInt32 *)CHIPSIGREG;

    switch(intInfo->localIntId) {
        case DSP2ARM_CHIPINT0:
            statBitPos = 0;
            break;
        case DSP2ARM_CHIPINT1:
            statBitPos = 1;
            break;
    }

    chipSigReg[1] = (1 << statBitPos);

    switch(intInfo->localIntId) {
        case DSP2ARM_CHIPINT0:
            Hwi_clearInterrupt(DSP2ARM_CHIPINT0);
            break;
        case DSP2ARM_CHIPINT1:
            Hwi_clearInterrupt(DSP2ARM_CHIPINT1);
            break;
    }

    return (0);
}
コード例 #2
0
ファイル: Timer.c プロジェクト: andreimironenko/bios
/*
 *  ======== Timer_trigger ========
 *  1. stop timer
 *  2. write the period with insts
 *  3. start the timer.
 */
Void Timer_trigger(Timer_Object *obj, UInt insts)
{
    UInt key;

    /* follow proper procedure for dynamic period change */
    key = Hwi_disable();
    if (obj->id == 0) {                 /* SysTick Timer */
        Hwi_nvic.STCSR = 0;             /* stop the timer */
        Hwi_clearInterrupt(obj->intNum);
        Hwi_enableInterrupt(obj->intNum);
        Hwi_nvic.STRVR = insts;         /* set the period */
        if (obj->extFreq.lo) {
            Hwi_nvic.STCSR = 0x3;       /* start timer, select ext clock */
        }
        else {
            Hwi_nvic.STCSR = 0x7;       /* start timer, select int clock */
        }
    }
    else {                              /* CTM Timer */
        /* RESET=1, ENBL=0 */
        CTM_ctm.CTCR[obj->ctmid] = 2;
        Hwi_clearInterrupt(obj->intNum);
        Hwi_enableInterrupt(obj->intNum);
        /* set interval to insts */
        CTM_ctm.TINTVLR[obj->ctmid] = insts;
        /* RESTART=0, INT=1, ENBL=1 */
        CTM_ctm.CTCR[obj->ctmid] = 0x00000101;
    }
    Hwi_restore(key);
}
コード例 #3
0
ファイル: Timer.c プロジェクト: andreimironenko/bios
/*
 *  ======== Timer_start ========
 *  1. Hwi_disable();
 *  2. Clear the counters
 *  3. Clear IFR
 *  4. Enable timer interrupt
 *  5. Start timer
 *  6. Hwi_restore()
 */
Void Timer_start(Timer_Object *obj)
{
    UInt key;

    key = Hwi_disable();

    if (obj->hwi) {
        Hwi_clearInterrupt(obj->intNum);
        Hwi_enableInterrupt(obj->intNum);
    }

    if (obj->id == 0) { /* Systick */
        if (obj->extFreq.lo) {
            Hwi_nvic.STCSR |= 0x1;      /* start timer, select ext clock */
        }
        else {
            Hwi_nvic.STCSR |= 0x5;      /* start timer, select int clock */
        }
    }
    else {              /* CTM Timer */
        if (obj->runMode == Timer_RunMode_CONTINUOUS) {
            /* RESTART=1, INT=1, ENBL=1 */
            CTM_ctm.CTCR[obj->ctmid] = 0x00000501;
        }
        else {
            /* RESTART=0, INT=1, ENBL=1 */
            CTM_ctm.CTCR[obj->ctmid] = 0x00000101;
        }
    }

    Hwi_restore(key);
}
コード例 #4
0
ファイル: Timer.c プロジェクト: mobiaqua/ti-sysbios-c64t
/*
 *  ======== Timer_initDevice ========
 */
Void Timer_initDevice(Timer_Object *obj, Error_Block *eb)
{
    TimerRegs *timer;
    UInt hwiKey;

    Timer_TimerSupportProxy_enable(obj->id, eb);

    timer = (TimerRegs *)Timer_module->device[obj->id].baseAddr;

    hwiKey = Hwi_disable();

    timer->tclr = 0;
    while (timer->twps & TIMER_TWPS_W_PEND_TCLR)
        ;
    timer->tcrr = 0;
    while (timer->twps & TIMER_TWPS_W_PEND_TCRR)
        ;
    timer->tldr = 0;
    while (timer->twps & TIMER_TWPS_W_PEND_TLDR)
        ;

    if (obj->hwi) {
        /* clear any previously latched timer interrupts */
        Hwi_clearInterrupt(obj->intNum);
        Hwi_disableInterrupt(obj->intNum);
    }

    Hwi_restore(hwiKey);
}
コード例 #5
0
BOOL Intr_EnableEvent(Intr *pThis)
{
	//CSL_Status          intStat;

	//If CIC Event is provided in Interrupt Table
	if(pThis->oIntrTableParam.bCicRequired == TRUE)
	{
		//intStat = CSL_cicHwControl(pThis->CicHandle, CSL_CIC_CMD_EVTENABLE, NULL); // modified for new Chip



				/* Enable the Host Interrupt. */
				CpIntc_enableHostInt(0,pThis->oIntrTableParam.HostInt );

				/* Enable the System Interrupt */
				CpIntc_enableSysInt(0, pThis->oIntrTableParam.SysInt);




		//if(intStat != CSL_SOK)
		//{
		//	#ifdef _STE_APP
    	//	LOG_TRACE0( "INTR : CIC HwControl to enable event ... Failed.\n");
		//	#endif
		//	return FALSE;
		//}
	}
	//else

	#ifdef _STE_APP

	//Clear the Interrupt Flag Register before Enabling
	//C64_clearIFR(1 << pThis->oIntrTableParam.eIntcVectorId );// DSPBIOS API
	Hwi_clearInterrupt( pThis->oIntrTableParam.eIntcVectorId);// not sure this is the equivalent or not :(
	//Enable the Vector interrupt
	//C64_enableIER(1 << pThis->oIntrTableParam.eIntcVectorId );// DSP BIOS API
	Hwi_enableInterrupt( pThis->oIntrTableParam.eIntcVectorId);// SYS BIOS API
	#endif
	#ifdef _STE_BOOT
	intStat = CSL_intcHwControl(pThis->oIntcHandle, CSL_INTC_CMD_EVTENABLE, NULL);
    if(intStat != CSL_SOK)
	{
		#ifdef DEBUG
    	printf("INTR: HwControl to enable event ... Failed.\n");
		#endif
	}
	#endif

	return TRUE;
}
コード例 #6
0
ファイル: Hwi.c プロジェクト: andreimironenko/bios
/*
 *  ======== Hwi_dispatchFIQC ========
 *  FIQ interrupt dispatcher
 */
Void interrupt Hwi_dispatchFIQC()
{
    Hwi_Object *entry;
    UInt intNum;

    intNum = Hwi_vim.FIQINDEX - 1;

    /* ack this interrupt */
    Hwi_clearInterrupt(intNum);

    entry = Hwi_module->dispatchTable[intNum];

    (entry->fxn)(entry->arg);
}
コード例 #7
0
ファイル: Timer.c プロジェクト: alexeicolin/sysbios
/*
 *  ======== Timer_start ========
 *  1. Hwi_disable();
 *  2. Clear the counters
 *  3. Clear IFR
 *  4. Enable timer interrupt
 *  5. Start timer
 *  6. Hwi_restore()
 */
Void Timer_start(Timer_Object *obj)
{
    UInt key;

    key = Hwi_disable();

    if (obj->hwi) {
        Hwi_clearInterrupt(obj->intNum);
        Hwi_enableInterrupt(obj->intNum);
    }

    timerDevices[obj->id].cntl |= TIMER_CNTL_START;

    Hwi_restore(key);
}
コード例 #8
0
ファイル: Timer.c プロジェクト: alexeicolin/sysbios
/* ======== Timer_initDevice ========
 * 1. stop timer
 * 2. disable timer interrupt. (IER and any timer specific interrupt enable)
 * 3. clear pending interrupt. (IFR and any timer specific interrupt flags)
 * 4. Set control registers back to reset value.
 * 5. clear counters
 * 6. clear period register.
 */
Void Timer_initDevice(Timer_Object *obj)
{
    UInt key;

    key = Hwi_disable();

    CTM_ctm.CTCR[obj->ctmid] = 2;       /* reset, stop, disable */

    if (obj->hwi) {
        Hwi_disableInterrupt(obj->intNum);
        Hwi_clearInterrupt(obj->intNum);
    }

    Hwi_restore(key);
}
コード例 #9
0
ファイル: Timer.c プロジェクト: mobiaqua/ti-sysbios-c64t
/*
 *  ======== Timer_start ========
 *  1. Hwi_disable();
 *  2. Clear the counters
 *  3. Clear IFR
 *  4. Enable timer interrupt
 *  5. Start timer
 *  6. Hwi_restore()
 */
Void Timer_start(Timer_Object *obj)
{
    UInt key;
    UInt runMode;
    TimerRegs *timer;

    timer = (TimerRegs *)Timer_module->device[obj->id].baseAddr;

    key = Hwi_disable();

    Timer_stop(obj);

    if (obj->runMode == Timer_RunMode_DYNAMIC) {
        timer->tcrr = 0;           /* set timer count back to initial value */
        obj->prevThreshold = 0;    /* init previous threshold */
        timer->tmar = obj->period; /* set threshold for first interrupt */
        obj->rollovers = 0;        /* init total rollover count */
        obj->savedCurrCount = 0;
    }
    else {
        /* set timer count register back to period value */
        timer->tcrr = Timer_MAX_PERIOD - obj->period;
    }
    while (timer->twps & TIMER_TWPS_W_PEND_TCRR)
        ;

    if (obj->hwi) {
        Hwi_clearInterrupt(obj->intNum);
        Hwi_enableInterrupt(obj->intNum);
    }

    if (obj->runMode == Timer_RunMode_CONTINUOUS) {
        runMode = TIMER_TCLR_START_CONTINUOUS;
    }
    else if (obj->runMode == Timer_RunMode_ONESHOT) {
        runMode = TIMER_TCLR_START_ONESHOT;
    }
    else {
        runMode = TIMER_TCLR_START_DYNAMIC;
    }

    timer->tclr = runMode | obj->tclr;
    while (timer->twps & TIMER_TWPS_W_PEND_TCLR)
        ;

    Hwi_restore(key);
}
コード例 #10
0
ファイル: Timer.c プロジェクト: CheredHerry/ti-bios
/*
 *  ======== Timer_trigger ========
 *  1. stop timer
 *  2. write the period with insts
 *  3. start the timer.
 */
Void Timer_trigger(Timer_Object *obj, UInt32 insts)
{
    UInt key;

    /* follow proper procedure for dynamic period change */
    key = Hwi_disable();
    Hwi_nvic.STCSR = 0;                 /* stop the timer */
    Hwi_clearInterrupt(obj->intNum);    /* clear any pending interrupts */
    Hwi_nvic.STRVR = insts;             /* set the period */
    if (obj->extFreq.lo) {
        Hwi_nvic.STCSR = 0x3;   /* start timer, select ext clock */
    }
    else {
        Hwi_nvic.STCSR = 0x7;   /* start timer, select int clock */
    }
    Hwi_restore(key);
}
コード例 #11
0
ファイル: Timer.c プロジェクト: alexeicolin/sysbios
/* ======== initDevice ========
 * 1. stop timer
 * 2. disable timer interrupt. (IER and any timer specific interrupt enable)
 * 3. clear pending interrupt. (IFR and any timer specific interrupt flags)
 * 4. Set control registers back to reset value.
 * 5. clear counters
 * 6. clear period register.
 */
static Void initDevice(Timer_Object *obj) 
{
    UInt key;

    key = Hwi_disable();
    
    timerDevices[obj->id].cntl = obj->controlRegInit;

    if (obj->hwi) {
        Hwi_disableInterrupt(obj->intNum);
        Hwi_clearInterrupt(obj->intNum);
    }
    timerDevices[obj->id].load = 0;
    timerDevices[obj->id].read = 0;

    Hwi_restore(key);
}
コード例 #12
0
ファイル: Timer.c プロジェクト: CheredHerry/ti-bios
/* ======== initDevice ========
 * 1. stop timer
 * 2. disable timer interrupt. (IER and any timer specific interrupt enable)
 * 3. clear pending interrupt. (IFR and any timer specific interrupt flags)
 * 4. Set control registers back to reset value.
 * 5. clear counters
 * 6. clear period register.
 */
static Void initDevice(Timer_Object *obj) 
{
    UInt key;

    key = Hwi_disable();
    
    Hwi_nvic.STCSR = 0; /* stop the timer */
    Hwi_nvic.STRVR = 0; /* reset reload value */
    Hwi_nvic.STCVR = 0; /* reset current value */

    if (obj->hwi) {
        Hwi_disableInterrupt(obj->intNum);
        Hwi_clearInterrupt(obj->intNum);
    }

    Hwi_restore(key);
}
コード例 #13
0
ファイル: Timer.c プロジェクト: alexeicolin/sysbios
/*
 *  ======== Timer_trigger ========
 *  1. stop timer
 *  2. write the period with insts
 *  3. start the timer.
 */
Void Timer_trigger(Timer_Object *obj, UInt insts)
{
    UInt key;

    /* follow proper procedure for dynamic period change */
    key = Hwi_disable();

    /* RESET=1, ENBL=0 */
    CTM_ctm.CTCR[obj->ctmid] = 2;
    Hwi_clearInterrupt(obj->intNum);
    Hwi_enableInterrupt(obj->intNum);
    /* set interval to insts */
    CTM_ctm.TINTVLR[obj->ctmid] = insts;
    /* RESTART=0, INT=1, ENBL=1 */
    CTM_ctm.CTCR[obj->ctmid] = 0x00000101;

    Hwi_restore(key);
}
コード例 #14
0
ファイル: Timer.c プロジェクト: CheredHerry/ti-bios
/*
 *  ======== Timer_start ========
 *  1. Hwi_disable();
 *  2. Clear the counters
 *  3. Clear IFR
 *  4. Enable timer interrupt
 *  5. Start timer
 *  6. Hwi_restore()
 */
Void Timer_start(Timer_Object *obj)
{
    UInt key;

    key = Hwi_disable();

    if (obj->hwi) {
        Hwi_clearInterrupt(obj->intNum);
        Hwi_enableInterrupt(obj->intNum);
    }

    if (obj->extFreq.lo) {
        Hwi_nvic.STCSR |= 0x1;  /* start timer, select ext clock */
    }
    else {
        Hwi_nvic.STCSR |= 0x5;  /* start timer, select int clock */
    }

    Hwi_restore(key);
}
コード例 #15
0
ファイル: Timer.c プロジェクト: mobiaqua/ti-sysbios
/* ======== Timer_initDevice ========
 * 1. stop timer
 * 2. disable timer interrupt. (IER and any timer specific interrupt enable)
 * 3. clear pending interrupt. (IFR and any timer specific interrupt flags)
 * 4. Set control registers back to reset value.
 * 5. clear counters
 * 6. clear period register.
 */
Void Timer_initDevice(Timer_Object *obj)
{
    UInt key;
    ti_catalog_arm_peripherals_timers_TimerRegsM4 *timer;

    timer = (ti_catalog_arm_peripherals_timers_TimerRegsM4 *)
        Timer_module->device[obj->id].baseAddr;

    key = Hwi_disable();

    if (obj->hwi) {
        Hwi_disableInterrupt(obj->intNum);
        Hwi_clearInterrupt(obj->intNum);
    }

    /* mode setting purposely delayed a while after finishing reset */
    Timer_write(obj->altclk, &timer->GPTMCFG, 0); /* force 32 bit timer mode */

    Hwi_restore(key);
}
コード例 #16
0
ファイル: Timer.c プロジェクト: alexeicolin/sysbios
/*
 *  ======== Timer_start ========
 *  1. Hwi_disable();
 *  2. Clear the counters
 *  3. Clear IFR
 *  4. Enable timer interrupt
 *  5. Start timer
 *  6. Hwi_restore()
 */
Void Timer_start(Timer_Object *obj)
{
    UInt key;

    key = Hwi_disable();

    if (obj->hwi) {
        Hwi_clearInterrupt(obj->intNum);
        Hwi_enableInterrupt(obj->intNum);
    }

    if (obj->runMode == Timer_RunMode_CONTINUOUS) {
        /* RESTART=1, INT=1, ENBL=1 */
        CTM_ctm.CTCR[obj->ctmid] = 0x00000501;
    }
    else {
        /* RESTART=0, INT=1, ENBL=1 */
        CTM_ctm.CTCR[obj->ctmid] = 0x00000101;
    }

    Hwi_restore(key);
}
コード例 #17
0
ファイル: Timer.c プロジェクト: andreimironenko/bios
/* ======== initDevice ========
 * 1. stop timer
 * 2. disable timer interrupt. (IER and any timer specific interrupt enable)
 * 3. clear pending interrupt. (IFR and any timer specific interrupt flags)
 * 4. Set control registers back to reset value.
 * 5. clear counters
 * 6. clear period register.
 */
static Void initDevice(Timer_Object *obj) 
{
    UInt key;

    key = Hwi_disable();

    if (obj->id == 0) { /* SysTick */
        Hwi_nvic.STCSR = 0;     /* stop the timer */
        Hwi_nvic.STRVR = 0;     /* reset reload value */
        Hwi_nvic.STCVR = 0;     /* reset current value */
    }
    else {              /* CTM Timer */
        CTM_ctm.CTCR[obj->ctmid] = 2;   /* reset, stop, disable */
    }

    if (obj->hwi) {
        Hwi_disableInterrupt(obj->intNum);
        Hwi_clearInterrupt(obj->intNum);
    }

    Hwi_restore(key);
}
コード例 #18
0
/*
 *  ======== osi_RegisterInterruptHandler ========
 *  SimpleLink Host Driver API to register a function to handle network
 *  processor interrupts.
 */
int osi_RegisterInterruptHandler(P_EVENT_HANDLER InterruptHdl , void *pValue)
{
    WiFiCC3100_Object        *object = wifiHandle->object;
#if !defined(MSP430WARE)
    WiFiCC3100_HWAttrs const *hwAttrs = wifiHandle->hwAttrs;
#endif

    if(InterruptHdl == NULL) {
#if !defined(MSP430WARE)
        Hwi_disableInterrupt(hwAttrs->irqIntNum);
        Hwi_clearInterrupt(hwAttrs->irqIntNum);
#endif
        object->wifiIntFxn = NULL;
    }
    else {
        object->wifiIntFxn = InterruptHdl;
#if !defined(MSP430WARE)
        Hwi_enableInterrupt(hwAttrs->irqIntNum);
#endif
    }

    return (0);
}
コード例 #19
0
/*
 *  ======== Timer_start ========
 *  1. Hwi_disable();
 *  2. Clear the counters
 *  3. Clear IFR
 *  4. Enable timer interrupt
 *  5. Start timer
 *  6. Hwi_restore()
 */
Void Timer_start(Timer_Object *obj)
{
    UInt key;
    UInt runMode;
    TimerRegs *timer;

    timer = (TimerRegs *)Timer_module->device[obj->id].baseAddr;

    key = Hwi_disable();

    Timer_stop(obj);

    /* set timer count register back to period value */
    timer->tcrr = Timer_MAX_PERIOD - obj->period;
    while (timer->twps & TIMER_TWPS_W_PEND_TCRR)
        ;

    if (obj->hwi) {
        Hwi_clearInterrupt(obj->intNum);
        Hwi_enableInterrupt(obj->intNum);
        timer->tier = obj->tier; /* enable the interrupt at the timer */
    }

    if (obj->runMode == Timer_RunMode_CONTINUOUS) {
        runMode = TIMER_TCLR_START_CONTINUOUS;
    }
    else {
        runMode = TIMER_TCLR_START_ONESHOT;
    }

    timer->tclr = runMode | obj->tclr;
    while (timer->twps & TIMER_TWPS_W_PEND_TCLR)
        ;

    Hwi_restore(key);
}
コード例 #20
0
ファイル: Hwi.c プロジェクト: andreimironenko/bios
/*
 *  ======== Hwi_dispatchIRQC ========
 *  Configurable IRQ interrupt dispatcher.
 */
Void Hwi_dispatchIRQC(Hwi_Irp irp)
{
    /*
     * Enough room is reserved above the isr stack to handle
     * as many as 16 32-bit stack resident local variables.
     * If the dispatcher requires more than this, you must
     * handle this in Hwi_Module_startup().
     */

    Hwi_Object *hwi;
    BIOS_ThreadType prevThreadType;
    UInt intNum;
    Char *oldTaskSP;
    UInt32 oldREQENASET0, oldREQENASET1;
    Int tskKey;
    Int swiKey;
    Int i;

    /* save irp somewhere that survives the stack switch */
    Hwi_module->irp = irp;

    if (Hwi_dispatcherTaskSupport) {
        tskKey = TASK_DISABLE();
        /* 
         * If this is a non-nested interrupt,
         * tskkey is saved on the task stack.
         * It must not be referenced again until
         * switching back to the task stack!!!!
         * All other local variables will be
         * on the isr stack.
         */
    }

    /* 
     * Switch to Hwi stack if not already on it.
     * This step, and the corresponding switch back to the task
     * stack are performed outside the "if (Hwi_dispatcherTaskSupport)"
     * conditionals because sometimes the generated code placed a copy
     * of Hwi_dispatcherTaskSupport on the task stack for use below.
     */
    oldTaskSP = Hwi_switchToIsrStack();

    /* 
     * all references to local variables beyond this point
     * will be on the isr stack
     */

    intNum = Hwi_vim.IRQINDEX - 1;

    /* ack this interrupt */
    Hwi_clearInterrupt(intNum);

    hwi = Hwi_module->dispatchTable[intNum];

    hwi->irp = Hwi_module->irp;

    if (Hwi_dispatcherSwiSupport) {
        swiKey = SWI_DISABLE();
    }

    /* set thread type to Hwi */
    prevThreadType = BIOS_setThreadType(BIOS_ThreadType_Hwi);

#ifndef ti_sysbios_hal_Hwi_DISABLE_ALL_HOOKS
    /* call the begin hooks */
    for (i = 0; i < Hwi_hooks.length; i++) {
        if (Hwi_hooks.elem[i].beginFxn != NULL) {
            Hwi_hooks.elem[i].beginFxn((IHwi_Handle)hwi);
        }
    }
#endif

    Log_write5(Hwi_LM_begin, (IArg)hwi, (IArg)hwi->fxn, 
               (IArg)prevThreadType, (IArg)intNum, hwi->irp);

    /* call the user's isr */
    if (Hwi_dispatcherAutoNestingSupport) {
        oldREQENASET0 = Hwi_vim.REQENASET[0];
        Hwi_vim.REQENACLR[0] = hwi->disableMask0;
        oldREQENASET1 = Hwi_vim.REQENASET[1];
        Hwi_vim.REQENACLR[1] = hwi->disableMask1;
        Hwi_enable();

        (hwi->fxn)(hwi->arg);

        Hwi_disable();
        Hwi_vim.REQENASET[0] = (hwi->restoreMask0 & oldREQENASET0);
        Hwi_vim.REQENASET[1] = (hwi->restoreMask1 & oldREQENASET1);
    }
    else {
        (hwi->fxn)(hwi->arg);
    }

    Log_write1(Hwi_LD_end, (IArg)hwi);

#ifndef ti_sysbios_hal_Hwi_DISABLE_ALL_HOOKS
    /* call the end hooks */
    for (i = 0; i < Hwi_hooks.length; i++) {
        if (Hwi_hooks.elem[i].endFxn != NULL) {
            Hwi_hooks.elem[i].endFxn((IHwi_Handle)hwi);
        }
    }
#endif

    /* Run Swi scheduler */
    if (Hwi_dispatcherSwiSupport) {
        SWI_RESTORE(swiKey);
    }

    /* restore thread type */
    BIOS_setThreadType(prevThreadType);

    /* 
     * Switch back to Task stack if at bottom of Hwi stack
     * While it seems that this step should be placed in the
     * "if (Hwi_dispatcherTaskSupport)" conditional below,
     * some code generators placed a copy of the Hwi_dispatcherTaskSupport
     * constant on the task stack (see above comment), which would
     * make the test below bogus as it would be being performed on
     * on the ISR stack...
     */
    Hwi_switchToTaskStack(oldTaskSP);

    /* Run Task scheduler */
    if (Hwi_dispatcherTaskSupport) {
        /* tskKey fetched from task stack if this is a non-nested interrupt */
        TASK_RESTORE(tskKey);   /* returns with ints disabled */
    }
}
コード例 #21
0
ファイル: Timer.c プロジェクト: mobiaqua/ti-sysbios
/*
 *  ======== Timer_start ========
 *  1. Hwi_disable();
 *  2. Clear the counters
 *  3. Clear IFR
 *  4. Enable timer interrupt
 *  5. Start timer
 *  6. Hwi_restore()
 */
Void Timer_start(Timer_Object *obj)
{
    UInt key;
    UInt32 amr;
    ti_catalog_arm_peripherals_timers_TimerRegsM4 *timer;

    timer = (ti_catalog_arm_peripherals_timers_TimerRegsM4 *)
        Timer_module->device[obj->id].baseAddr;

    key = Hwi_disable();

    /* stop timer */
    Timer_write(obj->altclk, &timer->GPTMCTL, timer->GPTMCTL & ~0x1);

    /* clear all of timer's interrupt status bits */
    Timer_write(obj->altclk, &timer->GPTMICR, (UInt32)0xFFFFFFFF);

    /* setup timer's Hwi */
    if (obj->hwi) {
        Hwi_clearInterrupt(obj->intNum);
        Hwi_enableInterrupt(obj->intNum);

        /* clear match and timeout enable bits */
        Timer_write(obj->altclk, &timer->GPTMIMR, timer->GPTMIMR & ~0x11);

        /* set appropriate interrupt enable based on timer mode */
        if (obj->runMode != Timer_RunMode_DYNAMIC) {
            /* unmask the timeout interrupt */
            Timer_write(obj->altclk, &timer->GPTMIMR, timer->GPTMIMR | 0x01);
        }
        else {
            /* unmask the match interrupt */
            Timer_write(obj->altclk, &timer->GPTMIMR, timer->GPTMIMR | 0x10);
        }
    }

    /* clear timer mode bits and match interrupt enable */
    amr = timer->GPTMTAMR & ~0x23;

    /* Timer_RunMode_CONTINUOUS */
    if (obj->runMode == Timer_RunMode_CONTINUOUS) {
        Timer_write(obj->altclk, &timer->GPTMTAILR, obj->period);
        Timer_write(obj->altclk, &timer->GPTMTAMR, amr | 0x2); /* periodic */
    }

    /* Timer_RunMode_DYNAMIC */
    else if (obj->runMode == Timer_RunMode_DYNAMIC) {
        obj->prevThreshold = Timer_MAX_PERIOD;
        Timer_write(obj->altclk, &timer->GPTMTAV, Timer_MAX_PERIOD);
        Timer_write(obj->altclk, &timer->GPTMTAMATCHR,
            Timer_MAX_PERIOD - obj->period);
        Timer_write(obj->altclk, &timer->GPTMTAMR, amr | 0x22);/* prd & match */
    }

    /* Timer_RunMode_ONESHOT */
    else {
        Timer_write(obj->altclk, &timer->GPTMTAILR, obj->period);
        Timer_write(obj->altclk, &timer->GPTMTAMR, amr | 0x1);  /* one-shot */
    }

    if (obj->altclk) {
        timer->GPTMCC = 1; /* note: this write not affected by erratum */
    }

    /* configure timer to halt with debugger, and start it */
    Timer_write(obj->altclk, &timer->GPTMCTL, timer->GPTMCTL | 0x3);

    Hwi_restore(key);
}