#include <intr.h>
#include "i_cmplx.h" /* definition of the com*/
#include <TmrDrv.h>
/*----------------------------------------------------------------------------
timer driver
-----------------------------------------------------------------------------*/
/* C6202 cpu clk = 5ns, clk/4=20ns , PRD=50000-1(1ms)
c6701 cpu clk = 6.78168402777...ns(36.864MHz), clk/4=27.126736111...ns,
, PRD=36864-1(1ms)*/
volatile static int HighVal; //1193 hours(49 days) max
interrupt void TMR_IntHandler() {
HighVal ++;
}
/*for C6202 , choose 50,000KHz; c6701 choose 36,864KHz*/
void TMR_InitDrv(int CrystalVal_KHz)
{
// init register
TIMER_RESET(0);
/*CLKSRC=1(CPU clk/4), FUNC=0, gp pin*/
TIMER_INIT(0, 0x00000200, CrystalVal_KHz - 1, 0x0);
TIMER_START(0);
HighVal = 0;
// init interrupt
intr_hook(TMR_IntHandler, CPU_INT14);
INTR_ENABLE(CPU_INT14);
}
int TMR_GetHighTime() {
return HighVal;
}
#define TMR_GetLowTime() TIMER_READ(0)
void TMR_Delay(unsigned int Ms)
{
int curval;
curval = TMR_GetHighTime();
while((TMR_GetHighTime() - curval) < Ms) {}
}
void TMR_GetTime(TIME_TMR *ptime)
{
ptime->Ms = TMR_GetHighTime();
ptime->Us = TMR_GetLowTime();
}
void TMR_Delta(TIME_TMR *ptime1, TIME_TMR *ptimeDelta )
{
TIME_TMR time2;
int period;
time2.Ms = TMR_GetHighTime();
time2.Us = TMR_GetLowTime();
period = TIMER_GET_PERIOD(0);
if((time2.Us - ptime1->Us)>=0)
{
ptimeDelta->Ms = time2.Ms - ptime1->Ms;
ptimeDelta->Us = (time2.Us - ptime1->Us) * 1000 / period;
}
else
{
ptimeDelta->Ms = time2.Ms - ptime1->Ms - 1;
ptimeDelta->Us = (time2.Us - ptime1->Us + period) * 1000 / period;
}
}
//The function must always be interruptible.
#pragma FUNC_INTERRUPT_THRESHOLD (TMR_PollFlag_TimeOut, 1)
int TMR_PollFlag_TimeOut(unsigned int* pFlag, unsigned int MsToWait, PTIME_TMR pTimeWaited)
{
TIME_TMR StartTime, WaitTime;
volatile unsigned int* p = (volatile unsigned int* )pFlag;
TMR_GetTime(&StartTime);
WaitTime.Ms = 0;
WaitTime.Us = 0;
//poll and wait
while( (!p[0]) && (WaitTime.Ms < MsToWait) )
{
WaitTime.Ms = TMR_GetHighTime() - StartTime.Ms;
}
pTimeWaited->Ms = WaitTime.Ms;
pTimeWaited->Us = 0;
//check whether timeout
if( WaitTime.Ms >= MsToWait )
return TMR_TIMEOUT;
else
return TMR_OK;
}
//The function must always be interruptible.
#pragma FUNC_INTERRUPT_THRESHOLD (TMR_PollMultiFlag_TimeOut, 1)
int TMR_PollMultiFlag_TimeOut(unsigned int* pFlagAry, unsigned int ArySize, unsigned int MsToWait, PTIME_TMR pTimeWaited)
{
TIME_TMR StartTime, WaitTime;
unsigned int sum, i;
volatile unsigned int* p = (volatile unsigned int* )pFlagAry;
TMR_GetTime(&StartTime);
WaitTime.Ms = 0;
WaitTime.Us = 0;
sum = 0; for(i = 0; i < ArySize; i++) sum += p[i];
//poll and wait
while( (sum < ArySize) && (WaitTime.Ms < MsToWait) )
{
WaitTime.Ms = TMR_GetHighTime() - StartTime.Ms;
sum = 0; for(i = 0; i < ArySize; i++) sum += p[i];
}
pTimeWaited->Ms = WaitTime.Ms;
pTimeWaited->Us = 0;
//check whether timeout
if( WaitTime.Ms >= MsToWait )
return TMR_TIMEOUT;
else
return TMR_OK;
}
//用查询定时器的方法实现延迟有可能出问题,查询过程中如果有中断发生,可能查询不到0到1的变化
//这个函数执行时间如下:
//num: 1 2 3 4 5 6 7 8 9 10 11
//delay(clks): 56 99 142 185 228 271 314 357 400 443 486
//ratio: 56 49.5 47.3 46.25 45.6 45.2 44.9 44.6 44.4 44.3 44.2
//1us:num=4.4, 10us:num=44, 143us:num=636, 143us*16:10176
void nop_delay(int num) //num => A4
{
asm(" MV A4, A1");
asm("loop:");
asm(" NOP 9");
asm(" NOP 9");
asm(" NOP 9");
asm(" NOP 9");
asm(" SUB A1, 1, A1");
asm(" [A1]B loop");
asm(" NOP 5");
}
评论0