Main Page | Modules | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

timer.c

00001 /*! \file timer.c \brief Timer Support Library for AT91SAM7S. */
00002 //*****************************************************************************
00003 //
00004 // File Name    : 'timer.c'
00005 // Title        : Timer Support Library for AT91SAM7S
00006 // Author       : Pascal Stang - Copyright (C) 2005-2006
00007 // Created      : 2005.05.26
00008 // Revised      : 2006.07.27
00009 // Version      : 0.1
00010 // Target MCU   : Atmel ARM AT91SAM7S Series
00011 // Editor Tabs  : 4
00012 //
00013 // NOTE: This code is currently below version 1.0, and therefore is considered
00014 // to be lacking in some functionality or documentation, or may not be fully
00015 // tested.  Nonetheless, you can expect most functions to work.
00016 //
00017 // This code is distributed under the GNU Public License
00018 //      which can be found at http://www.gnu.org/licenses/gpl.txt
00019 //
00020 //*****************************************************************************
00021 
00022 // system includes
00023 #include "at91sam7s64.h"
00024 // local includes
00025 #include "processor.h"
00026 #include "timer.h"
00027 // project includes
00028 #include "global.h"
00029 
00030 typedef void (*voidFuncPtr)(void);
00031 volatile static voidFuncPtr TimerIntFunc[TIMER_NUM_INTERRUPTS];
00032 
00033 // counter/timer registers
00034 volatile DWORD TimerPauseReg;
00035 volatile DWORD PitCounter;
00036 
00037 
00038 // functions
00039 void delay_us(unsigned long t)
00040 {
00041     // this function is not yet calibrated
00042     while(t--)
00043     {
00044         asm volatile ("nop\r\n nop\r\n nop\r\n nop\r\n nop\r\n nop\r\n nop\r\n nop\r\n");
00045         asm volatile ("nop\r\n nop\r\n nop\r\n nop\r\n nop\r\n nop\r\n nop\r\n nop\r\n");
00046         asm volatile ("nop\r\n nop\r\n nop\r\n nop\r\n nop\r\n nop\r\n nop\r\n nop\r\n");
00047         asm volatile ("nop\r\n nop\r\n nop\r\n nop\r\n nop\r\n nop\r\n nop\r\n nop\r\n");
00048         asm volatile ("nop\r\n nop\r\n nop\r\n nop\r\n nop\r\n nop\r\n nop\r\n nop\r\n");
00049         asm volatile ("nop\r\n nop\r\n nop\r\n nop\r\n nop\r\n nop\r\n nop\r\n nop\r\n");
00050     }
00051 }
00052 
00053 void timerInit(void)
00054 {
00055     int i;
00056     // initialize interrupt handlers
00057     for(i=0; i<TIMER_NUM_INTERRUPTS; i++)
00058         timerAttach(i,0);
00059 
00060     // initialize various timers
00061 
00062     // default PIT setup is 1000Hz or 1ms interval
00063     // This default is for code compatibility,
00064     // simply call timerInitPit() yourself if you need a different rate.
00065     timerInitPit(1000);
00066 }
00067 
00068 void timerInitPit(int rate)
00069 {
00070     // PIT is the Periodic Interval Timer
00071     
00072     // PIT is part of system peripherals so no need to enable clock
00073 
00074     // enable and setup the PIT  for specified interval
00075     AT91C_BASE_PITC->PITC_PIMR = AT91C_PITC_PITEN|AT91C_PITC_PITIEN|(F_CPU/(16*rate)-1);
00076     // reset the div counter by reading PIVR
00077     AT91C_BASE_PITC->PITC_PIVR;
00078 
00079     // init global variables
00080     TimerPauseReg = 0;
00081     PitCounter = 0;
00082 
00083     // attach interrupt handlers
00084     processorAicAttachSys(SYSPID_PITC, timerServicePit);
00085 }
00086 
00087 void timerAttach(u08 interruptNum, void (*userFunc)(void) )
00088 {
00089     // make sure the interrupt number is within bounds
00090     if(interruptNum < TIMER_NUM_INTERRUPTS)
00091     {
00092         // set the interrupt function to run
00093         // the supplied user's function
00094         TimerIntFunc[interruptNum] = userFunc;
00095     }
00096 }
00097 
00098 void timerPause(int pause)
00099 {
00100     // wait until [pause] number of pit overflows goes by
00101     TimerPauseReg = pause;
00102     while(TimerPauseReg);
00103 }
00104 
00105 
00106 // interrupt handlers
00107 
00108 // This function is the handler for interrupts generated by the PIT
00109 void timerServicePit(void)
00110 {
00111     // PITC interval interrupt has fired
00112     // read PIVR (this also clears int flag)
00113     PitCounter+=AT91C_BASE_PITC->PITC_PIVR>>20;
00114     
00115     // decrement the pause register if non-zero
00116     if(TimerPauseReg)
00117         TimerPauseReg--;
00118 
00119     // execute user handler if pointer to routine is NOT null.
00120     if(TimerIntFunc[TIMER_PITOVERFLOW_INT])
00121         TimerIntFunc[TIMER_PITOVERFLOW_INT]();
00122 }
00123 

Generated on Mon Nov 6 23:36:58 2006 for Procyon ARMlib by  doxygen 1.4.2