📄 timerdrv.c
字号:
if(rem0 >= SW.w[0])
{
div1.rem = U32divU16s((unsigned long)rem0, (unsigned short)SW.w[0], &div1.quot);
/* prevent divider overflow */
if(div1.quot + (unsigned long)HWCounter > 0xFFFF) div1.rem = 0xFFFF;
};
if(rem1 >= SW.w[0] + 1)
{
div2.rem = U32divU16s((unsigned long)rem1, (unsigned short)SW.w[0] + 1, &div2.quot);
/* prevent small divider */
if(HWCounter < 0x7FFF + (unsigned long)div2.quot) div2.rem = 0xFFFF;
};
if(rem0 < minRem)
{
minRem = rem0;
foundDivider = HWCounter;
};
if(rem1 < minRem)
{
minRem = rem1;
foundDivider = HWCounter;
};
if(div1.rem < minRem)
{
minRem = div1.rem;
foundDivider = HWCounter + div1.quot;
};
if(div2.rem < minRem)
{
minRem = div2.rem;
foundDivider = HWCounter - div2.quot;
};
};/* for */
HWCounter = foundDivider;
rem0 = U64divU16(tickPeriod, foundDivider, &SW);
if ( rem0 > ( foundDivider - rem0 ) )
{
U64addU32(&SW, 1, &SW);
}
*SWCounter = SW.w[0];
return foundDivider;
}
/*****************************************************************************
*
* Module: timer_settime
*
* Description (POSIX): Set timer values
*
* Returns: A return value of 0 indicates that the call succeeded.
*
* Arguments: Timer device handle, assigned initial and period time.
*
* Range Issues: time precision - 10us, initial time ignored
*
* Special Issues: For executive loop only
*
*****************************************************************************/
int timer_settime( timer_t TimerID,
int Flags,
const struct itimerspec * pTimeValue,
struct itimerspec * pOvalue
)
{
extern const qt_sQuadState timerStdFastStart;
posix_tContext * ptr = POSIX_TIMER_GET_CONTEXT(TimerID);
unsigned long SWCounter;
unsigned short HWCounter, reminder;
U64 tickPeriod;
/* translate into nanoseconds */
if ( ( pTimeValue->it_interval.tv_sec == 0 ) && ( pTimeValue->it_interval.tv_nsec == 0 ))
time2Ticks(&pTimeValue->it_value, &tickPeriod);
else
time2Ticks(&pTimeValue->it_interval, &tickPeriod);
if(tickPeriod.w[1] == 0 && tickPeriod.w[0] < 0x10000UL )
{
HWCounter = (unsigned short)tickPeriod.w[0];
SWCounter = 1;
}
else
{
/* factorization */
HWCounter = factorization(&tickPeriod, &SWCounter);
};
if ( ( pTimeValue->it_interval.tv_sec == 0 ) && ( pTimeValue->it_interval.tv_nsec == 0 ))
{
ptr->reloadSoftCounter = 0;
ptr->SoftCounter = SWCounter;
}
else
{
/* save software counter */
ptr->reloadSoftCounter = SWCounter;
/* translate first interval into nanoseconds */
time2Ticks(&pTimeValue->it_value, &tickPeriod);
/* Represent time in tick as rem0=HWCounter*A + rem0 */
reminder = U64divU16(&tickPeriod, HWCounter, &tickPeriod);
ptr->SoftCounter = tickPeriod.w[0]; /* inital value, there is original SWCounter at reloadSoftCounter */
}
/* load and start low ( hardware ) counter */
timer_qt_writeCompareReg2( (arch_sTimerChannel*)TimerID, 0 );
timer_qt_writeLoadReg( (arch_sTimerChannel*)TimerID, (short)HWCounter );
timer_qt_writeCounterReg( (arch_sTimerChannel*)TimerID, reminder );
timer_CallbackOnCompare_On( (arch_sTimerChannel*)TimerID );
if (HWCounter > 0x4B0)
timer_qt_start((arch_sTimerChannel*)TimerID, timerStdFastStart.value);
}
/*****************************************************************************
*
* Module: clock_settime
*
* Description (POSIX) :
* The clock_settime() function sets the specified clock, clock_id,
* to the value specified by tp. Time values that are between two consecutive
* non-negative integer multiples of the resolution of the specified clock
* are truncated down to the smaller multiple of the resolution.
*
* Returns: A return value of 0 indicates that the call succeeded.
*
* Range Issues: None
* Special Issues: None
* Test Method: timers.mcp
*
*****************************************************************************/
int clock_settime(clockid_t ClockID, const struct timespec * tp)
{
return 0;
}
/*****************************************************************************
*
* Module: clock_gettime
*
* Description (POSIX) :
* The clock_gettime() function returns the current value tp for the
* specified clock, clock_id.
*
* Returns: A return value of 0 indicates that the call succeeded.
*
* Range Issues: None
* Special Issues: None
* Test Method: timers.mcp
*
*****************************************************************************/
int clock_gettime(clockid_t ClockID, struct timespec * tp)
{
posix_tContext* ptr = POSIX_TIMER_GET_CONTEXT(ClockID);
U64 timePeriod;
timePeriod.w[0]=(unsigned long)ptr->reloadSoftCounter - (unsigned long)ptr->SoftCounter;
timePeriod.w[1]=0;
/* get expired ticks */
U64mulU32(&timePeriod, timer_qt_readLoadReg( (arch_sTimerChannel*)ClockID ), &timePeriod);
U64addU32(&timePeriod, timer_qt_readCounterReg( (arch_sTimerChannel*)ClockID ), &timePeriod);
U64mulU32(&timePeriod, POSIX_TIMER_READ_PRESCALER_VALUE((arch_sTimerChannel*)ClockID, 0), &timePeriod);
/* translate ticks to ns */
ticks2ns(&timePeriod, &timePeriod);
/* factorization */
ns2Time(&timePeriod, tp);
return 0;
}
/*****************************************************************************
*
* Module: clock_get_system_time
*
* Description: system time for CLOCK_REALTIME timer
*
* Returns: A return value of 0 indicates that the call succeeded.
*
* Range Issues: None
* Special Issues: None
* Test Method: timers.mcp
*
*****************************************************************************/
int clock_get_system_time( struct timespec * tp)
{
U64 timePeriod;
/* translate ISR count to ns */
timePeriod.w[0] = TimerISRCount;
timePeriod.w[1] = 0;
U64mulU32(&timePeriod, REAL_TIME_TIMER_RESOLUTION, &timePeriod);
ns2Time(&timePeriod, tp);
return 0;
}
/*****************************************************************************
*
* Module: clock_getres
*
* Description (POSIX) :
* The resolution of any clock can be obtained by calling clock_getres().
* Clock resolutions are implementation-dependent and cannot be set by
* a process. If the argument res is not NULL, the resolution of the
* specified clock is stored in the location pointed to by res.
*
* Returns: A return value of 0 indicates that the call succeeded.
*
* Range Issues: None
* Special Issues: None
* Test Method: timers.mcp
*
*****************************************************************************/
int clock_getres(clockid_t ClockID, struct timespec * Resolution)
{
U64 tickPeriod;
U64 timePeriod;
/* get ticks */
tickPeriod.w[0] = POSIX_TIMER_READ_PRESCALER_VALUE(ptr->bspDevice, 0);
U64mulU32(&tickPeriod, timer_qt_readLoadReg((arch_sTimerChannel*)ClockID), &tickPeriod);
ticks2ns(&tickPeriod, &timePeriod);
ns2Time(&timePeriod, Resolution);
return 0;
}
/*****************************************************************************
*
* Module: nanosleep
*
* Description (POSIX) :
* The nanosleep() function causes the current thread (SDK executive loop )
* to be suspended from execution until either the time interval specified
* by the rqtp argument has elapsed or a signal is delivered to the calling
* thread and its action is to invoke a signal-catching function or
* to terminate the process. The suspension time may be longer than requested
* because the argument value is rounded up to an integer multiple of the sleep
* resolution or because of the scheduling of other activity by the system.
* But, except for the case of being interrupted by a signal, the suspension
* time will not be less than the time specified by rqtp, as measured by
* the system clock, CLOCK_REALTIME
*
* Returns: f the nanosleep() function returns because the requested time
* has elapsed, its return value is zero.
*
* Range Issues: None
* Special Issues: None
* Test Method: timers.mcp
*
*****************************************************************************/
int nanosleep(const struct timespec * rqtp, struct timespec * rmtp)
{
U64 tickPeriod;
time2Ticks(rqtp, &tickPeriod);
U64divU16(&tickPeriod, REAL_TIME_TIMER_STEP, &tickPeriod);
U64divU16(&tickPeriod, REAL_TIME_TIMER_PRESCALER, &tickPeriod);
if(tickPeriod.w[0] == 0)
{
tickPeriod.w[0] = 1;
}
timerSleep( tickPeriod.w[0] );
return 0;
}
/*****************************************************************************
*
* Module: timerCreate
*
* Description: Configuration of SDK POSIX real time timer block.
*
* Returns: passed value
*
* Range Issues: None
* Special Issues: None
* Test Method: timers.mcp
*
*****************************************************************************/
Result timerCreate( /* const char * pName */ )
{
timer_t realTimeTimer;
struct sigevent realTimeEvent;
register posix_tContext * ptr;
realTimeEvent.sigev_notify_function = timerRealTimeClockISR;
timer_create(CLOCK_REALTIME, &realTimeEvent, &realTimeTimer);
ptr = POSIX_TIMER_GET_CONTEXT(realTimeTimer);
/* save software counter */
ptr->reloadSoftCounter = 1;
ptr->SoftCounter = 1;
timer_qt_writeCompareReg2( (arch_sTimerChannel*)realTimeTimer, 0);
timer_qt_writeLoadReg( (arch_sTimerChannel*)realTimeTimer, REAL_TIME_TIMER_STEP );
timer_qt_writeCounterReg( (arch_sTimerChannel*)realTimeTimer, 0 );
timer_CallbackOnCompare_On((arch_sTimerChannel*)realTimeTimer );
timer_qt_start((arch_sTimerChannel*)realTimeTimer, timerStdFastStart.value /* QTB_TCFIE */ );
return PASS;
}
/****************************************************************************************
* *
* *
* *
* MEASURE BLOCK *
* *
* *
* *
*****************************************************************************************/
/**************************************************
* const defenition
***************************************************/
#define HIGH_BITS_VALUE 0xFFFF0000
#define LOW_BITS_VALUE 0x0000FFFF
static measure_t gCalibrate = 0;
volatile arch_sTimerChannel * gArchQtmerOut;
volatile arch_sTimerChannel * gArchQtmerIn;
static unsigned long InitialLoadValue = 0xFFFF;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -