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