/*
 *  ======== Timer_Instance_finalize ========
 */
Void Timer_Instance_finalize(Timer_Object *obj, Int status)
{
    UInt key;

    /* fall through in switch below is intentional */
    switch (status) {
        /* Timer_delete() */
        case 0:

        /* Hwi create failed */
        case 4:

        /* device config (setPeriodMicroSecs) failed */
        case 3:
            Timer_initDevice(obj, NULL);
            if (obj->hwi) {
                Hwi_delete(&obj->hwi);
            }
            break;      

        /* timer not available */
        case 2:

        /* invalid timer id */
        case 1:

        default:
            break;      
    }

    key = Hwi_disable();
    Timer_module->availMask |= (0x1 << obj->id);
    Timer_module->handles[obj->id] = NULL;
    Hwi_restore(key);
}
Esempio n. 2
0
/*
 *  ======== Timer_postInit ========
 */
Int Timer_postInit(Timer_Object *obj, Error_Block *eb)
{
    UInt hwiKey;

    hwiKey = Hwi_disable();

    Timer_initDevice(obj);

    Timer_setPeriod(obj, obj->period);

    Hwi_restore(hwiKey);

    return (0);
}
Esempio n. 3
0
/*
 *  ======== Timer_enableTimers ========
 */
Void Timer_enableTimers()
{
    Int i;
    Timer_Object *obj;

    for (i = 0; i < Timer_numTimerDevices; i++) {
        obj = Timer_module->handles[i];

        /* enable and reset the timer */
        if (obj != NULL) {
            Timer_enableFunc(obj->id);
            Timer_initDevice(obj);
        }
    }
}
/*
 *  ======== Timer_deviceConfig ========
 *  Configure the timer.
 */
Int Timer_deviceConfig(Timer_Object *obj, Error_Block *eb)
{
    TimerRegs *timer;
    UInt hwiKey;

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

    /* reset the timer */
    timer->tiocpCfg = obj->tiocpCfg | 0x2;

    /* wait for reset to finish */
    while(timer->tistat != 0x01) 
        ;

    /* initialize the timer */
    Timer_initDevice(obj, eb);

    hwiKey = Hwi_disable();

    /* set the period */
    if (obj->periodType == Timer_PeriodType_MICROSECS) {
        if (!Timer_setPeriodMicroSecs(obj, obj->period)) {
            Hwi_restore(hwiKey);
            Error_raise(eb, Timer_E_cannotSupport, obj->period, 0);
            return (3);
        }
    }
    else {
        timer->tcrr = Timer_MAX_PERIOD - obj->period;
        while (timer->twps & TIMER_TWPS_W_PEND_TCRR)
            ;
        timer->tldr = Timer_MAX_PERIOD - obj->period;
        while (timer->twps & TIMER_TWPS_W_PEND_TLDR)
            ;
    }

    timer->tmar = obj->tmar;
    while (timer->twps & TIMER_TWPS_W_PEND_TMAR)
        ;

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

    Hwi_restore(hwiKey);
    return (0);
}
Esempio n. 5
0
/*
 *  ======== Timer_deviceConfig ========
 *  Configure the timer.
 */
Int Timer_deviceConfig(Timer_Object *obj, Error_Block *eb)
{
    TimerRegs *timer;
    UInt hwiKey;
    UInt32 tsicr;

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

    /* initialize the timer */
    Timer_initDevice(obj, eb);

    hwiKey = Hwi_disable();

    /* if doing SOFTRESET: do it first before setting other flags */
    if (obj->tiocpCfg & TIMER_TIOCP_CFG_SOFTRESET_FLAG) {
        timer->tiocpCfg = TIMER_TIOCP_CFG_SOFTRESET_FLAG;
        while (timer->tiocpCfg & TIMER_TIOCP_CFG_SOFTRESET_FLAG)
                ;
    }
    timer->tiocpCfg = obj->tiocpCfg & ~TIMER_TIOCP_CFG_SOFTRESET_FLAG;

    /* xfer 'posted' setting if not current */
    tsicr = timer->tsicr;

    if (obj->tsicr & TIMER_TSICR_POSTED) {
        if ((tsicr & TIMER_TSICR_POSTED) == 0) {
            timer->tsicr = (tsicr | TIMER_TSICR_POSTED);
        }
    }
    else {
        if ((tsicr & TIMER_TSICR_POSTED) != 0) {
            timer->tsicr = (tsicr & ~TIMER_TSICR_POSTED);
        }
    }

    /* set the period */
    if (obj->periodType == Timer_PeriodType_MICROSECS) {
        if (!Timer_setPeriodMicroSecs(obj, obj->period)) {
            Hwi_restore(hwiKey);
            Error_raise(eb, Timer_E_cannotSupport, obj->period, 0);
            return (3);
        }
    }
    else {
        if (obj->runMode != Timer_RunMode_DYNAMIC) {
            timer->tcrr = Timer_MAX_PERIOD - obj->period;
            while (timer->twps & TIMER_TWPS_W_PEND_TCRR)
                ;
            timer->tldr = Timer_MAX_PERIOD - obj->period;
            while (timer->twps & TIMER_TWPS_W_PEND_TLDR)
                ;
        }
        else { 
            timer->tcrr = 0;
            while (timer->twps & TIMER_TWPS_W_PEND_TCRR)
                ;
            timer->tmar = obj->period;
            while (timer->twps & TIMER_TWPS_W_PEND_TMAR)
                ;
        }
    }

    if (obj->runMode != Timer_RunMode_DYNAMIC) {
        timer->tmar = obj->tmar;
        while (timer->twps & TIMER_TWPS_W_PEND_TMAR)
            ;
    }

    timer->twer = obj->twer;
    timer->tier = obj->tier;
    timer->tclr = obj->tclr;
    while (timer->twps & TIMER_TWPS_W_PEND_TCLR)
        ;

    Hwi_restore(hwiKey);
    return (0);
}
Esempio n. 6
0
/*
 *  ======== Timer_Instance_init ========
 * 1. Select timer based on id
 * 2. Mark timer as in use
 * 3. Save timer handle if necessary
 * 4. Init obj using params
 * 5. Create Hwi if tickFxn !=NULL
 * 6. Timer_init()
 * 7. Timer configuration (wrt emulation, external frequency etc)
 * 8. Timer_setPeriod()
 * 9. Timer_start()
 */
Int Timer_Instance_init(Timer_Object *obj, Int id, Timer_FuncPtr tickFxn, const Timer_Params *params, Error_Block *eb)
{
    UInt key;
    Int i, status;
    Hwi_Params hwiParams;
    UInt tempId = 0xffff;

    if (id >= Timer_numTimerDevices) {
        if (id != Timer_ANY) {
            Error_raise(eb, Timer_E_invalidTimer, id, 0);
            return (1);
        }
    }

    key = Hwi_disable();

    if (id == Timer_ANY) {
        for (i = 0; i < Timer_numTimerDevices; i++) {
            if ((Timer_anyMask & (1 << i))
                && (Timer_module->availMask & (1 << i))) {
                Timer_module->availMask &= ~(1 << i);
                tempId = i;
                break;
            }
        }
    }
    else if (Timer_module->availMask & (1 << id)) {
        Timer_module->availMask &= ~(1 << id);
        tempId = id;
    }

    Hwi_restore(key);

    obj->staticInst = FALSE;

    if (tempId == 0xffff) {
        Error_raise(eb, Timer_E_notAvailable, id, 0);
        return (2);
    }
    else {
        obj->id = tempId;
    }

    obj->runMode = params->runMode;
    obj->startMode = params->startMode;

    if (params->altclk && !Timer_supportsAltclk) {
        Error_raise(eb, Timer_E_noaltclk, id, 0);
        return (1);
    }
    obj->altclk = params->altclk;

    obj->period = params->period;
    obj->periodType = params->periodType;

    if (obj->altclk) {         /* if using altclk the freq is always 16MHz */
        obj->extFreq.lo = 16000000;
        obj->extFreq.hi = 0;
    }
    else {                     /* else use specified extFreq */
        obj->extFreq.lo = params->extFreq.lo;
        obj->extFreq.hi = params->extFreq.hi;
    }

    obj->arg = params->arg;
    obj->intNum = Timer_module->device[obj->id].intNum;
    obj->tickFxn = tickFxn;
    obj->prevThreshold = params->prevThreshold;
    obj->rollovers = 0;
    obj->savedCurrCount = 0;


    if (obj->tickFxn) {
        if (params->hwiParams) {
            Hwi_Params_copy(&hwiParams, (params->hwiParams));
        }
        else {
            Hwi_Params_init(&hwiParams);
        }

        hwiParams.arg = (UArg)obj;

        obj->hwi = Hwi_create (obj->intNum, Timer_isrStub,
                                &hwiParams, eb);

        if (obj->hwi == NULL) {
            return (3);
        }
    }
    else {
        obj->hwi = NULL;
    }

    Timer_module->handles[obj->id] = obj;

    /* enable and reset the timer */
    Timer_enableFunc(obj->id);
    Timer_initDevice(obj);

    if (obj->periodType == Timer_PeriodType_MICROSECS) {
        if (!Timer_setPeriodMicroSecs(obj, obj->period)) {
            Error_raise(eb, Timer_E_cannotSupport, obj->period, 0);
            Hwi_restore(key);
            return (4);
        }
    }

    status = Timer_postInit(obj, eb);

    if (status) {
        return (status);
    }

    if (obj->startMode == Timer_StartMode_AUTO) {
        Timer_start(obj);
    }

    return (0);
}