📄 at91timer.c
字号:
/* at91Timer.c - at91rm9200 timer driver */#include "vxWorks.h"#include "intLib.h"#include "errno.h"#include "drv/timer/timerDev.h"#include "drv/timer/timestampDev.h"#include "config.h"#include "h/drv/intrCtl/at91Intr.h"#include "h/drv/timer/at91Timer.h"#include "h/drv/sio/at91Sio.h"#define CLOCK_TICK_RATE (AT91C_SLOW_CLOCK)#define LATCH ((CLOCK_TICK_RATE + DEF_SYS_CLK_TICKS/2) / DEF_SYS_CLK_TICKS) /* For divider *//* Local forward declarations */LOCAL BOOL sysClkConnectFirstTime = TRUE;LOCAL FUNCPTR sysClkRoutine = NULL;LOCAL int sysClkArg = 0;LOCAL int sysClkRunning = FALSE;LOCAL int sysClkTicksPerSecond = DEF_SYS_CLK_TICKS;/*#ifdef INCLUDE_SYSCLK_INIT*/#define SYS_CLK_RATE_MIN 19 /* minimum system clock rate */#define SYS_CLK_RATE_MAX 1000 /* maximum system clock rate *//*#endif INCLUDE_SYSCLK_INIT */#ifdef INCLUDE_ST_RTT/* at91rm9200's RTT */LOCAL BOOL sysRTTClkConnectFirstTime = TRUE;LOCAL FUNCPTR sysRTTClkRoutine = NULL;LOCAL int sysRTTClkArg = 0;LOCAL int sysRTTClkRunning = FALSE;#endif /* INCLUDE_ST_RTT */#ifdef INCLUDE_AUX_CLKLOCAL BOOL sysAuxClkConnectFirstTime = TRUE;LOCAL FUNCPTR sysAuxClkRoutine = NULL;LOCAL int sysAuxClkArg = 0;LOCAL int sysAuxClkRunning = FALSE;LOCAL int sysAuxClkTicksPerSecond = DEF_SYS_AUX_CLK_TICKS;#endif /* INCLUDE_AUX_CLK */#if defined (INCLUDE_AUX_CLK)#define AT91C_TIMER_CLOCK1 (AT91C_MASTER_CLOCK/2)#define AT91C_TIMER_CLOCK2 (AT91C_MASTER_CLOCK/8)#define AT91C_TIMER_CLOCK3 (AT91C_MASTER_CLOCK/32)#define AT91C_TIMER_CLOCK4 (AT91C_MASTER_CLOCK/128)#define AT91C_TIMER_CLOCK5 AT91C_SLOW_CLOCK#endif /* INCLUDE_AUX_CLK */#ifdef INCLUDE_TIMESTAMPtypedef struct _AT91C_TIMESTAMP_BASE { UINT32 century; /* Current Century range : 19 - 20 */ UINT32 year; /* Current Year range : 00 - 99 */ UINT32 mounth; /* Current Month range : 01 - 12 */ UINT32 day; /* Current Day range : 1 - 7 */ UINT32 date; /* Current Date range : 01 - 31 */ UINT32 hour; /* Current Hour range : 1 - 12 */ UINT32 minute; /* Current Minute : 0 - 59 */ UINT32 second; /* Current Second : 0 - 59 */} AT91C_TIMESTAMP_BASE;LOCAL BOOL sysTimestampConnectFirstTime = TRUE;LOCAL BOOL sysTimestampBaseSetFirstTime = TRUE;LOCAL FUNCPTR sysTimestampRoutine = NULL;LOCAL int sysTimestampArg = 0;LOCAL BOOL sysTimestampRunning = TRUE;LOCAL AT91C_TIMESTAMP_BASE sysTimestampBase = {FALSE, 0, 0, 0, 0, 0, 0, 0, 0};#endif /* INCLUDE_TIMESTAMP */#ifdef INCLUDE_TIMER_COUNTERSLOCAL void TimerCounter0ISR(void);LOCAL void TimerCounter1ISR(void);LOCAL void TimerCounter2ISR(void);LOCAL void TimerCounter3ISR(void);LOCAL void TimerCounter4ISR(void);LOCAL void TimerCounter5ISR(void);#define TIMERCOUNTERS 6#define TIMER_COUNTER0 0 /* used for auxclock */#define TIMER_COUNTER1 1#define TIMER_COUNTER2 2#define TIMER_COUNTER3 3#define TIMER_COUNTER4 4#define TIMER_COUNTER5 5typedef struct _AT91C_TIMER_COUNTER { BOOL TimerCounterConnectFirstTime; AT91PS_TC TCRegBaseAddr; VOIDFUNCPTR TimerCounterISR; FUNCPTR TimerCounterRoutine; int TimerCounterArg; int TimerCounterRunning; int TimerCounterTicksPerSecond; } AT91C_TIMER_COUNTER;LOCAL AT91C_TIMER_COUNTER at91rm9200timercounter[TIMERCOUNTERS] = { {TRUE, AT91C_BASE_TC0, TimerCounter0ISR, NULL, 0, FALSE, DEF_TIMER_COUNTER_TICKS}, /*tc0*/ {TRUE, AT91C_BASE_TC1, TimerCounter1ISR, NULL, 0, FALSE, DEF_TIMER_COUNTER_TICKS}, /*tc1*/ {TRUE, AT91C_BASE_TC2, TimerCounter2ISR, NULL, 0, FALSE, DEF_TIMER_COUNTER_TICKS}, /*tc2*/ {TRUE, AT91C_BASE_TC3, TimerCounter3ISR, NULL, 0, FALSE, DEF_TIMER_COUNTER_TICKS}, /*tc3*/ {TRUE, AT91C_BASE_TC4, TimerCounter4ISR, NULL, 0, FALSE, DEF_TIMER_COUNTER_TICKS}, /*tc4*/ {TRUE, AT91C_BASE_TC5, TimerCounter5ISR, NULL, 0, FALSE, DEF_TIMER_COUNTER_TICKS} /*tc5*/};#endif /* INCLUDE_TIMER_COUNTERS *//********************************************************************************* sysClkInt - clock interrupt handler** This routine handles the clock interrupt on the at91rm9200 architecture. It is* attached to the INT_VEC_SYS vector by the routine sysClkConnect().** RETURNS : N/A*/LOCAL void sysClkInt(void){ unsigned int st_sr = AT91_SYS->ST_SR; unsigned int dbgu_sr = AT91_SYS->DBGU_CSR; /* ST interrupts */ if (st_sr & AT91C_ST_PITS) { /* Call system clock service routine. */ if (sysClkRoutine && sysClkRunning) { (*sysClkRoutine)(sysClkArg); } } if (st_sr & AT91C_ST_RTTINC) { /* Call Real Time clock service routine. */ if (sysRTTClkRoutine && sysRTTClkRunning) { (*sysRTTClkRoutine)(sysRTTClkArg); } } /* DBGU interrupts */ #ifdef AT91C_DBGU_PDC_MODE if(dbgu_sr & (AT91C_US_RXRDY | AT91C_US_ENDTX)) #else /* AT91C_DBGU_PDC_MODE */ if(dbgu_sr & (AT91C_US_RXRDY| AT91C_US_TXEMPTY )) #endif /* AT91C_DBGU_PDC_MODE */ { at91SioInt(0); }}/********************************************************************************* sysClkConnect - connect a routine to the system clock interrupt** This routine specifies the interrupt service routine to be called at each* clock interrupt. Normally, it is called from usrRoot() in usrConfig.c to* connect usrClock() to the system clock interrupt.** RETURNS: OK, or ERROR if the routine cannot be connected to the interrupt.** SEE ALSO: intConnect(), usrClock(), sysClkEnable()*/STATUS sysClkConnect( FUNCPTR routine, /* routine called at each clock interrupt */ int arg /* argument to clock interrupt routine */ ){ if (sysClkConnectFirstTime) { sysHwInit2(); /* Disable all timer interrupts */ AT91_SYS->ST_IDR = AT91C_ST_PITS | AT91C_ST_WDOVF | AT91C_ST_RTTINC | AT91C_ST_ALMS; /* Clear any pending interrupts */ (void) AT91_SYS->ST_SR; /* Set Period Interval timer */ AT91_SYS->ST_PIMR = LATCH;#if 0 /* enable the pits just in the sysClkEnable*/ /* Enable Period Interval Timer interrupt */ AT91_SYS->ST_IER = AT91C_ST_PITS;#endif /* Connect and enable interrupt. */ intConnect(INT_VEC_SYS, (VOIDFUNCPTR)sysClkInt, 0); intEnable(INT_LVL_SYS); sysClkConnectFirstTime = FALSE; } sysClkRoutine = routine; sysClkArg = arg; return OK;}/********************************************************************************* sysClkDisable - turn off system clock interrupts** This routine disables system clock interrupts.** RETURNS: N/A** SEE ALSO: sysClkEnable()*/void sysClkDisable(void){ if (sysClkRunning) { /* Disable timer. */ AT91_SYS->ST_IDR = AT91C_ST_PITS | AT91C_ST_WDOVF | AT91C_ST_RTTINC | AT91C_ST_ALMS; sysClkRunning = FALSE; }}/********************************************************************************* sysClkEnable - turn on system clock interrupts** This routine enables system clock interrupts.** RETURNS: N/A** SEE ALSO: sysClkConnect(), sysClkDisable(), sysClkRateSet()*/void sysClkEnable(void){ if (!sysClkRunning) { AT91_SYS->ST_IER = AT91C_ST_PITS ;/*| AT91C_ST_WDOVF | AT91C_ST_RTTINC | AT91C_ST_ALMS;*/ sysClkRunning = TRUE; }}/********************************************************************************* sysClkRateGet - get the system clock rate** This routine returns the system clock rate.** RETURNS: The number of ticks per second of the system clock.** SEE ALSO: sysClkEnable(), sysClkRateSet()*/int sysClkRateGet(void){ return (sysClkTicksPerSecond);}/********************************************************************************* sysClkRateSet - set the system clock rate** This routine sets the interrupt rate of the system clock. It is called by* usrRoot() in usrConfig.c.** RETURNS: OK, or ERROR if the tick rate is invalid or the timer cannot be set.** SEE ALSO: sysClkEnable(), sysClkRateGet()*/STATUS sysClkRateSet( int ticksPerSecond /* number of clock interrupts per second */ ){ if ((ticksPerSecond < SYS_CLK_RATE_MIN) || (ticksPerSecond > SYS_CLK_RATE_MAX)) { return ERROR; } sysClkTicksPerSecond = ticksPerSecond; sysClkDisable(); AT91_SYS->ST_PIMR = ((CLOCK_TICK_RATE + ticksPerSecond/2) / ticksPerSecond); sysClkEnable(); if (sysClkRunning) { sysClkDisable(); sysClkEnable(); } return OK;}#ifdef INCLUDE_ST_RTT/********************************************************************************* sysClkConnect - connect a routine to the system real time clock interrupt** NOTE : real time clock period is 1 second, * that is it will cause interrupt every 1 second*/STATUS sysRTTClkConnect( FUNCPTR routine, /* routine called at each clock interrupt */ int arg /* argument to clock interrupt routine */ ){ if (sysRTTClkConnectFirstTime) { /* Set initial alarm to 0 */ AT91_SYS->ST_RTAR = 0; /* Real time counter incremented every 30.51758 microseconds AT91_SYS->ST_RTMR = 1; Real time counter incremented every 1 second */ AT91_SYS->ST_RTMR = 0x00008000; sysRTTClkConnectFirstTime = FALSE; } sysRTTClkRoutine = routine; sysRTTClkArg = arg; return OK;}/********************************************************************************* sysClkDisable - turn off system clock interrupts** This routine disables system clock interrupts.** RETURNS: N/A** SEE ALSO: sysClkEnable()*/void sysRTTClkDisable(void){ if (sysRTTClkRunning) { /* Disable timer. */ AT91_SYS->ST_IDR = AT91C_ST_RTTINC; sysRTTClkRunning = FALSE; }}/********************************************************************************* sysClkEnable - turn on system clock interrupts** This routine enables system clock interrupts.** RETURNS: N/A** SEE ALSO: sysClkConnect(), sysClkDisable(), sysClkRateSet()*/void sysRTTClkEnable(void){ if (!sysRTTClkRunning) { AT91_SYS->ST_IER = AT91C_ST_RTTINC; sysRTTClkRunning = TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -