예제 #1
0
/*
 *  ======== Timer_getExpiredCounts ========
 */
UInt32 Timer_getExpiredCounts(Timer_Object *obj)
{
    UInt key;
    UInt32 count1, count2;
    Bool countFlag;

    key = Hwi_disable();
    count1 = Timer_getCount(obj);
    if (obj->id == 0) { /* SysTick Timer */
        countFlag = Hwi_nvic.STCSR & 0x00010000;
    }
    else {              /* CTM Timer */
        /* Test corresponding Int pending flag */
        countFlag = Hwi_nvic.ISPR[0] & (1 << (obj->intNum - 16));
    }
    count2 = Timer_getCount(obj);
    Hwi_restore(key);

    if (obj->id == 0) { /* SysTick Timer */
        if ((count1 > count2) && countFlag) {
            return (obj->period - count1 + Timer_getPeriod(obj));
        }
        else {
            return (obj->period - count1);
        }
    }
    else {              /* CTM Timer */
        if (count2 < count1 && countFlag) {
            return (count1 + Timer_getPeriod(obj));
        }
        else {
            return (count1) ;
        }
    }
}
예제 #2
0
/*
 *  ======== Timer_getExpiredCounts ========
 */
UInt32 Timer_getExpiredCounts(Timer_Object *obj)
{
    /* if timer running with RunMode_DYNAMIC ... */
    if (obj->runMode == Timer_RunMode_DYNAMIC) {
        TimerRegs *timer;
        UInt32 result;
        UInt32 count;
        UInt32 thresh;
        UInt32 period;
        UInt32 prev;
        Bool intrFlag1;
        Bool intrFlag2;

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

        intrFlag1 = timer->tisr & TIMER_IRQSTATUS_MAT_IT_FLAG;
        count = Timer_getCount(obj);
        intrFlag2 = timer->tisr & TIMER_IRQSTATUS_MAT_IT_FLAG;
        prev = obj->prevThreshold;

        /* was interrupt pending before read the count? */
        if (intrFlag1) {
            thresh = timer->tmar;               /* threshold for interrupt */
            period = Timer_getPeriod(obj);      /* period count */

            /* threshold reached; no wrap thru zero yet */
            if (count >= thresh) {
                result = (count - thresh) + period;
            }
            /* threshold reached; count has wrapped thru zero */
            else {
                result = (0xffffffff - thresh + 1) + count + period;
            }
        }

        /* new interrupt now pending, when wasn't before read the count */
        else if (intrFlag2) {
            result = Timer_getPeriod(obj);      /* return period count */
        }

        /* interrupt threshold not reached; check if wrapped thru zero */
        else if (count >= prev) {
            result = count - prev;
        }

        /* interrupt threshold not reached; count *has* wrapped thru zero */
        else {
            result = (0xffffffff - prev + 1) + count;
        }

        return (result);
    }

    /* else ... */
    else {
        return (Timer_getCount(obj));
    }
}
예제 #3
0
/*
 *  ======== Timer_getExpiredCounts ========
 *
 *  This API is used by the TimestampProvider as part of retrieving a timestamp
 *  using a timer and a tick counter. It returns the expired counts since the
 *  last serviced timer interrupt.
 *
 *  This API must be called with interrupts disabled; the TimestampProvider
 *  must disable interrupts while retrieving the tick count and calling this
 *  API.
 *
 *  The TimestampProvider uses a 32-bit timer and 32-bit tick count to track
 *  the timestamp. The tick count either comes from the Clock module or is
 *  stored in the TimestampProvider's module state and incremented by an ISR
 *  when the timer expires.
 * 
 *  For MSP430 we have 16-bit timers, and use a timer compare feature to 
 *  trigger an interrupt upon a specific threshold count being reached.  The 
 *  timer counts can rollover (going thru zero), on the way to reaching the 
 *  next threshold.  We need to  accommodate this rollover as part of 
 *  determining expired counts.
 *
 *  We also need to handle the case where there is a large period value used
 *  for the timer, and the timer is ticking at a fast rate (e.g., the CPU
 *  rate, via an SMCLK selection).  For this case, it is possible that
 *  interrupts are disabled before the timer reaches threshold, and then the
 *  timer reaches the threshold count and asserts an interrupt, and then 
 *  continues to count upwards before it is read in this routine.  If the 
 *  timer rolled past zero, then we need to know that there is an interrupt 
 *  pending, otherwise we'd report a low count, versus the period plus
 *  that low count.
 *
 *  To be sure to catch the interrupt, we sample the interrupt flag, read
 *  the count, and then sample the interrupt flag again:
 *
 *      intrFlag1
 *      count
 *      intrFlag2
 *
 *  If intrFlag1 is set, then we know we've reached the period count, and
 *  need to add it to the reported counts.  If intrFlag2 is set, but 
 *  intrFlag1 wasn't, we know the timer just reached threshold, and simply
 *  report the period count.  
 *
 *  If neither interrupt flag is set, we can then compute the expired counts by
 *  comparing the count to the previous interrupt threshold (saved in the
 *  timer object).  If the current count is greater than or equal to the 
 *  previous threshold value, then we know there has been no counter rollover, 
 *  and the expired counts is simply:
 *
 *      result = count - prevThresh
 *
 *  If the current count is less than the previous threshold, then we know a
 *  counter rollover has occurred since the last ISR.  In this case, the 
 *  expired counts has to include those between the previous threshold and
 *  zero, plus any counts after rolling past zero:
 *
 *      result = (0 - prevTresh) + count
 *
 *  Similar logic to compare the current count to previous threshold can
 *  be used for the case where we know intrFlag1 has been set, and we
 *  need to figure the counts to be added to the period counts.
 *
 */
UInt32 Timer_getExpiredCounts(Timer_Object *obj)
{
    ti_catalog_msp430_peripherals_timers_TimerRegs *timer;
    UInt32 result32;
    UInt32 count32;
    UInt32 thresh32;
    UInt32 period32;
    UInt32 prev32;
    Bool intrFlag1;
    Bool intrFlag2;

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

    intrFlag1 = timer->cctl_0 & TIMER_COMPARE_INTR_PENDING;
    count32 = Timer_getCount(obj) & 0xffff;
    intrFlag2 = timer->cctl_0 & TIMER_COMPARE_INTR_PENDING;
    prev32 = obj->prevThreshold & 0xffff;

    /* interrupt pending before read count? */
    if (intrFlag1) { 
        thresh32 = timer->cc_compare_0 & 0xffff;  /* threshold for interrupt */
        period32 = Timer_getPeriod(obj) & 0xffff; /* period count */

        /* threshold reached; no wrap thru zero yet */
        if (count32 >= thresh32) { 
            result32 = (count32 - thresh32) + period32;
        }
        /* threshold reached; count has wrapped thru zero */
        else { 
            result32 = (0x10000 - thresh32) + count32 + period32;
        }
    }

    /* new interrupt now pending, when wasn't before read the count */
    else if (intrFlag2) { 
        result32 = Timer_getPeriod(obj) & 0xffff; /* return period count */
    }

    /* interrupt threshold not reached; check if wrapped thru zero */
    else if (count32 >= prev32) {  
        result32 = count32 - prev32;
    }

    /* interrupt threshold not reached; count has wrapped thru zero */
    else { 
        result32 = (0x10000 - prev32) + count32;
    }

    return (result32);
}
예제 #4
0
/*
 *  ======== TimestampProvider_get32 ========
 *  The 32-bit timestamp can be retrieved more efficiently than the 64-bit one,
 *  so it has a different implementation.
 */
Bits32 TimestampProvider_get32() 
{
    /*
     * If we're sharing the Clock timer, get the timestamp by using the Clock
     * tick count.
     */
    if (TimestampProvider_useClockTimer) {
        UInt key;
        UInt32 timestamp;

        /* 
         * Disable interrupts so that the Clock tick count doesn't change if 
         * the timer expires while we are reading it.
         */
        key = Hwi_disable();

        /* 
         * timestamp = (clock ticks) x (tick period) + (current timer count)
         * The 'getExpiredCounts' API retrieves the current Timer count and
         * also accounts for timer rollover.
         */
        timestamp = Clock_getTicks() * Timer_getPeriod(MOD->timer)
                    + Timer_getExpiredCounts(MOD->timer);

        Hwi_restore(key);

        return (timestamp);
    }
    /* If we have a dedicated timer, just read the timer count. */
    else {
        return (Timer_getCount(MOD->timer));
    }
}
/*
 *  ======== TimestampProvider_get32 ========
 */
Bits32 TimestampProvider_get32()
{
    if (TimestampProvider_useClockTimer) {
        UInt key;
        UInt32 timestamp;

        key = Hwi_disable();

        timestamp = Clock_getTicks() * Timer_getPeriod(MOD->timer)
                    + Timer_getExpiredCounts(MOD->timer);

        Hwi_restore(key);

        return (timestamp);
    }
    else {
        return (Timer_getCount(MOD->timer));
    }
}
예제 #6
0
파일: Timer.c 프로젝트: alexeicolin/sysbios
/*
 *  ======== Timer_getExpiredCounts ========
 */
UInt32 Timer_getExpiredCounts(Timer_Object *obj)
{
    UInt key;
    UInt32 count1, count2;
    Bool itrFlag;

    key = Hwi_disable();
    count1 = Timer_getCount(obj);
    itrFlag = (Hwi_l1Intc.ITR & (0x1 << obj->intNum));
    count2 = Timer_getCount(obj);

    Hwi_restore(key);

    if (count2 < count1 && itrFlag) {
        return (count1 + Timer_getPeriod(obj));
    }
    else {
        return (count1) ;
    }
}
예제 #7
0
/*
 *  ======== TimestampProvider_get64 ========
 */
Void TimestampProvider_get64(Types_Timestamp64 *result)
{
    UInt key;
    UInt64 timestamp;

    key = Hwi_disable();

    if (TimestampProvider_useClockTimer) {

        timestamp = Clock_getTicks() * Timer_getPeriod(MOD->timer)
                   + Timer_getExpiredCounts(MOD->timer);
    }
    else {
        timestamp = ((UInt64)MOD->hi << 32) + Timer_getExpiredCounts(MOD->timer);
    }

    Hwi_restore(key);

    result->hi = timestamp >> 32;
    result->lo = timestamp;
}
예제 #8
0
/*
 *  ======== Timer_getExpiredCounts ========
 */
UInt32 Timer_getExpiredCounts(Timer_Object *obj)
{
    UInt key;
    UInt32 count1, count2;
    Bool countFlag;

    key = Hwi_disable();
    count1 = Timer_getCount(obj);

    /* Test corresponding Int pending flag */
    countFlag = Hwi_nvic.ISPR[0] & (1 << (obj->intNum - 16));

    count2 = Timer_getCount(obj);

    Hwi_restore(key);

    if (count2 < count1 && countFlag) {
        return (count1 + Timer_getPeriod(obj));
    }
    else {
        return (count1) ;
    }
}
예제 #9
0
파일: Timer.c 프로젝트: alexeicolin/sysbios
/*
 *  ======== Timer_getExpiredCounts ========
 */
UInt32 Timer_getExpiredCounts(Timer_Object *obj)
{
    UInt key;
    UInt32 count1, count2;
    Bool countFlag;
    extern cregister volatile unsigned int IFR;

    key = Hwi_disable();
    count1 = Timer_getCount(obj);

    /* Test corresponding Int pending flag */
    countFlag = IFR & (1 << obj->intNum);

    count2 = Timer_getCount(obj);
    Hwi_restore(key);

    /* CTM Timer */
    if (count2 < count1 && countFlag) {
        return (count1 + Timer_getPeriod(obj));
    }
    else {
        return (count1) ;
    }
}
예제 #10
0
/*
 *  ======== TimestampProvider_get64 ========
 *  This API has different implementations based on whether we're using a
 *  dedicated timer or sharing the Clock timer. 
 *  If we're sharing the Clock timer, we have to multiply the Clock tick count
 *  by the Clock tick period. If we have a dedicate timer, the timer period is
 *  2^32, so we can just use the MOD->hi tick count as the upper 32-bits of the
 *  timestamp.
 */
Void TimestampProvider_get64(Types_Timestamp64 *result) 
{
    UInt key;
    
    /*
     * If we're sharing the Clock timer, get the timestamp by using the Clock
     * tick count.
     */
    if (TimestampProvider_useClockTimer) {
        UInt64 timestamp;
        
        /* 
         * Disable interrupts so that the Clock tick count doesn't change if 
         * the timer expires while we are reading it.
         */
        key = Hwi_disable();

        /* 
         * timestamp = (clock ticks) x (tick period) + (current timer count)
         * The 'getExpiredCounts' API retrieves the current Timer count and
         * also accounts for timer rollover.
         */
        timestamp = (UInt64) Clock_getTicks() * Timer_getPeriod(MOD->timer)
                    + Timer_getExpiredCounts(MOD->timer);

        Hwi_restore(key);

        /* 
         * Copy the value into the result structure.
         *
         * The 28x is little endian, so it stores the 16-bit words
         * in reverse order. For example, the value
         * 0xFEDCBA9876543210
         * Is stored as:
         *   Address   Value
         *   0x0       0x3210
         *   0x1       0x7654
         *   0x2       0xBA98
         *   0x3       0xFEDC
         *
         * To retrieve the lower 32 bits, simply cast the value as a UInt32.
         * To retrieve the upper 32 bits, cast the address of 'timestamp' as a
         * pointer to a UInt32, increment the pointer by 1, then retrieve the
         * value at that address.
         */
        result->lo = (UInt32) timestamp;
        result->hi = *(((UInt32 *) &timestamp) + 1);
    }
    /* If we have a dedicated timer... */
    else {
        /* Disable interrupts while reading the tick count and timer value. */
        key = Hwi_disable();
        
        /* Use the tick counter as the upper 32-bits. */
        result->hi = MOD->hi;
        /* 
         * Get the timer value as the lower 32-bits. This API will also take
         * timer rollover into account and add 1 to result->hi if necessary.
         */
        Timer_getExpiredCounts64(MOD->timer, result);

        Hwi_restore(key);        
    }
}