📄 timer.c
字号:
/*
* File: timer.c
*
* Purpose: timer routines
*/
#if !defined(__ISR_H__)
#include "isr.h"
#endif
#if !defined(__TIMER_H__)
#include "timer.h"
#endif
/*--------------------- Static Definitions ------------------------*/
#define MAX_TIMERTICK_PROC 32
//--------------------------------------
// Timer 0, 1
//--------------------------------------
#define ASIC_TMR_TMOD (*VPUINT32 (0x03FF0000UL + 0x6000))
#define ASIC_TMR_TDATA0 (*VPUINT32 (0x03FF0000UL + 0x6004))
#define ASIC_TMR_TDATA1 (*VPUINT32 (0x03FF0000UL + 0x6008))
#define ASIC_TMR_TCNT0 (*VPUINT32 (0x03FF0000UL + 0x600C))
#define ASIC_TMR_TCNT1 (*VPUINT32 (0x03FF0000UL + 0x6010))
#define fMCLK_MHz 50000000 // crystal is 50 MHz
// Timer0 functions
#define TMR_vTimer0Start() do { ASIC_TMR_TMOD |= (0x01); } while (0)
#define TMR_vTimer0Stop() do { ASIC_TMR_TMOD &= ~(0x01); } while (0)
/*--------------------- Static Types ------------------------------*/
struct tagSTimer {
UINT idTimer;
// TRUE == periodic timer, FALSE == one-shot timer
BOOL bPeriodic;
UINT uTimeOutPeriod;
UINT uTimeOutPeriodBackup;
PFN_CALLBACK_TIMER pfnTimerCallbackFunc;
PVOID pvTimerCallbackContext;
struct tagSTimer* ptmrNext;
};
typedef struct tagSTimer STimer;
/*--------------------- Static Macros -----------------------------*/
/*--------------------- Static Classes ----------------------------*/
/*--------------------- Static Variables --------------------------*/
// system time ticks, when each time the timer interrupted,
// this value will increse by one
static volatile UINT32 sg_u32TimeTick = 0;
static PFN_HOOK sg_pfnHookTimer;
static STimer sg_aTimerEntryTable[MAX_TIMERTICK_PROC];
/*--------------------- Static Functions --------------------------*/
/*--------------------- Export Variables --------------------------*/
//
// Interrupt Service Routines: Timer 0
//
void TMR_vIsrTimer0 (void)
{
static BOOL s_bSemaphoreInTimerIsr = FALSE;
UINT uu;
sg_u32TimeTick++;
// prevent reentry
if (!s_bSemaphoreInTimerIsr) {
s_bSemaphoreInTimerIsr = TRUE;
for (uu = 0; uu < MAX_TIMERTICK_PROC; uu++) {
if (sg_aTimerEntryTable[uu].pfnTimerCallbackFunc != NULL) {
sg_aTimerEntryTable[uu].uTimeOutPeriod--;
if (sg_aTimerEntryTable[uu].uTimeOutPeriod == 0) {
// call callback function
sg_aTimerEntryTable[uu].pfnTimerCallbackFunc(sg_aTimerEntryTable[uu].pvTimerCallbackContext);
if (sg_aTimerEntryTable[uu].bPeriodic) {
// restore timeout value
sg_aTimerEntryTable[uu].uTimeOutPeriod = sg_aTimerEntryTable[uu].uTimeOutPeriodBackup;
}
else {
sg_aTimerEntryTable[uu].pfnTimerCallbackFunc = NULL;
}
}
}
}
s_bSemaphoreInTimerIsr = FALSE;
}
// if got any ticks, calling the callback function
if (sg_pfnHookTimer != NULL)
sg_pfnHookTimer();
}
void TMR_vInit (void)
{
UINT uu;
for (uu = 0; uu < MAX_TIMERTICK_PROC; uu++)
sg_aTimerEntryTable[uu].pfnTimerCallbackFunc = NULL;
sg_pfnHookTimer = NULL;
//Timer0 init
ASIC_TMR_TDATA0 = (0.01 * fMCLK_MHz) - 1;
ASIC_TMR_TCNT0 = 0;
ASIC_TMR_TMOD = 0x02;
//Timer0 start
TMR_vTimer0Start();
INTR_vSetHandler(VEC_TIMER0_INT, TMR_vIsrTimer0);
ASIC_INT_MASK &= ~MASK_TIMER0_INT;
}
void TMR_vSetHookFunc (PFN_HOOK pfnHook)
{
INTR_vCriticalSectionEnter();
sg_pfnHookTimer = pfnHook;
INTR_vCriticalSectionLeave();
}
UINT32 TMR_u32GetSysTick (void)
{
return sg_u32TimeTick;
}
/*
* return timer id == -1, means failed
*/
INT TMR_iSetTimer (
UINT uTimeToDelay,
PFN_CALLBACK_TIMER pfnTimerCallbackFunc,
PVOID pvTimerCallbackContext
)
{
UINT idTimer;
for (idTimer = 0; idTimer < MAX_TIMERTICK_PROC; idTimer++) {
if (sg_aTimerEntryTable[idTimer].pfnTimerCallbackFunc == NULL)
break;
}
if (idTimer == MAX_TIMERTICK_PROC)
return FAILED;
// protect data structure from being accessed before it's properly set
INTR_vCriticalSectionEnter();
sg_aTimerEntryTable[idTimer].idTimer = idTimer;
sg_aTimerEntryTable[idTimer].bPeriodic = FALSE;
sg_aTimerEntryTable[idTimer].uTimeOutPeriod = uTimeToDelay;
sg_aTimerEntryTable[idTimer].uTimeOutPeriodBackup = uTimeToDelay;
sg_aTimerEntryTable[idTimer].pfnTimerCallbackFunc = pfnTimerCallbackFunc;
sg_aTimerEntryTable[idTimer].pvTimerCallbackContext = pvTimerCallbackContext;
INTR_vCriticalSectionLeave();
return idTimer;
}
/*
* return timer id == -1, means failed
*/
INT TMR_iSetPeriodicTimer (
UINT uTimeOutPeriod,
PFN_CALLBACK_TIMER pfnTimerCallbackFunc,
PVOID pvTimerCallbackContext
)
{
UINT idTimer;
for (idTimer = 0; idTimer < MAX_TIMERTICK_PROC; idTimer++) {
if (sg_aTimerEntryTable[idTimer].pfnTimerCallbackFunc == NULL)
break;
}
if (idTimer == MAX_TIMERTICK_PROC)
return FAILED;
// protect data structure from being accessed before it's properly set
INTR_vCriticalSectionEnter();
sg_aTimerEntryTable[idTimer].idTimer = idTimer;
sg_aTimerEntryTable[idTimer].bPeriodic = TRUE;
sg_aTimerEntryTable[idTimer].uTimeOutPeriod = uTimeOutPeriod;
sg_aTimerEntryTable[idTimer].uTimeOutPeriodBackup = uTimeOutPeriod;
sg_aTimerEntryTable[idTimer].pfnTimerCallbackFunc = pfnTimerCallbackFunc;
sg_aTimerEntryTable[idTimer].pvTimerCallbackContext = pvTimerCallbackContext;
INTR_vCriticalSectionLeave();
return idTimer;
}
BOOL TMR_bCancelTimer (UINT idTimer)
{
INTR_vCriticalSectionEnter();
sg_aTimerEntryTable[idTimer].pfnTimerCallbackFunc = NULL;
INTR_vCriticalSectionLeave();
return TRUE;
}
BOOL TMR_bCancelAllTimer (void)
{
UINT idTimer;
INTR_vCriticalSectionEnter();
for (idTimer = 0; idTimer < MAX_TIMERTICK_PROC; idTimer++)
sg_aTimerEntryTable[idTimer].pfnTimerCallbackFunc = NULL;
INTR_vCriticalSectionLeave();
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -