📄 ptimer.c
字号:
#include "tc.h"
#define PTIMER_GLOBALS
#include "ptimer.h"
#include "eb40a.h"
#define TC0_DEFAULT_MODE (AT91C_TC_WAVESEL_UP_AUTO | AT91C_TC_ASWTRG_CLEAR | AT91C_TC_BSWTRG_CLEAR | AT91C_TC_TCCLKS_MCK32 | AT91C_TC_WAVE)
#define CRITICAL_MILLISECONDS (25)
#define PTP_TIMER_TICKS (62500) // Determines ticks to gernorate a interrupt
#define PTP_CRITICAL_NANOSECONDS (975000000) // When CurTime.nasecs > this value, CurTime.secs should add 1 in interrupt
#define PTP_INTERVAL_NANOSECONDS (25000000) // Nanoseconds between two interrupts
#define PTP_TICK_NANOSECONDS (400) // Nano-Seconds during one crystal ticks
static Time CurTime;
void TC0IntHandler(void);
void PTimerStart(void) {
CurTime.secs = 0;
CurTime.nasecs = 0;
TimerInit(AT91C_BASE_TC0,
AT91C_TC_CPCTRG|TC_CLKS_MCK32,
AT91C_AIC_PRIOR_HIGHEST - 4,
AT91C_ID_TC0,
AT91C_ID_TC0,
AT91C_TC_CPCS,
TC0IntHandler);
TCStart(AT91C_BASE_TC0, PTP_TIMER_TICKS);
}
void Getime(PTime ptime) {
CpuSr sr;
uint32 cv, bpend;
SpinLock(sr);
cv = TCGetCV(AT91C_BASE_TC0);
bpend = AT91C_BASE_AIC->AIC_IPR & (0x01 << AT91C_ID_TC0);
ptime->secs = CurTime.secs;
ptime->nasecs = CurTime.nasecs;
SpinUnLock(sr);
if((bpend != 0) && (cv < 0xFF)) {
ptime->nasecs += PTP_INTERVAL_NANOSECONDS;
}
ptime->nasecs += (cv * PTP_TICK_NANOSECONDS);
if(ptime->nasecs >= 1000000000) {
ptime->nasecs -= 1000000000;
ptime->secs += 1;
}
}
void Setime(PTime ptime) {
TCReload(AT91C_BASE_TC0, PTP_TIMER_TICKS);
CurTime.secs = ptime->secs;
CurTime.nasecs = ptime->nasecs;
}
void TC0Int(void) {
uint32 status;
CpuSr sr;
status = AT91C_BASE_TC0->TC_SR;
if(CurTime.nasecs >= PTP_CRITICAL_NANOSECONDS) {
SpinLock(sr);
CurTime.secs += 1;
CurTime.nasecs -= PTP_CRITICAL_NANOSECONDS;
SpinUnLock(sr);
}
else {
CurTime.nasecs += PTP_INTERVAL_NANOSECONDS;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -