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

timer.c

00001 /*! \file timer.c \brief Timer Support Library for LPC2100. */
00002 //*****************************************************************************
00003 //
00004 // File Name    : 'timer.c'
00005 // Title        : Timer Support Library for LPC2100
00006 // Author       : Pascal Stang - Copyright (C) 2004
00007 // Created      : 2004.05.05
00008 // Revised      : 2004.07.12
00009 // Version      : 0.1
00010 // Target MCU   : ARM processors
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 #include "lpc2000.h"
00023 #include "processor.h"
00024 
00025 #include "global.h"
00026 #include "timer.h"
00027 #include "rprintf.h"
00028 
00029 typedef void (*voidFuncPtr)(void);
00030 volatile static voidFuncPtr TimerIntrFunc[TIMER_NUM_INTERRUPTS];
00031 
00032 volatile u32 Timer0Pause;
00033 volatile u32 Timer0OverflowCount;
00034 volatile u32 Timer1OverflowCount;
00035 
00036 void delay(unsigned long d)
00037 {     
00038     for(; d; --d)
00039     {
00040         asm volatile ("nop");
00041     }
00042 }
00043 
00044 
00045 void timerInit(void)
00046 {
00047     u08 intNum;
00048     // detach all user functions from interrupts
00049     for(intNum=0; intNum<TIMER_NUM_INTERRUPTS; intNum++)
00050         timerDetach(intNum);
00051 
00052     // initialize timer0
00053     timer0Init();
00054     // initialize timer1
00055     timer1Init();
00056     // enable IRQ interrupts
00057     processorEnableInt(CPSR_MASK_IRQ);
00058 }
00059 
00060 void timer0Init(void)
00061 {
00062     // setup timer0
00063     // set prescaler
00064     timer1PrescalerSet(1);
00065     // reset timer
00066     T0TCR = TCR_RESET;
00067     delay(10);
00068     // start timer
00069     T0TCR = TCR_ENABLE;
00070 
00071     // setup timer0 for IRQ
00072     // set interrupt as IRQ
00073     VICIntSelect &= ~(1<<VIC_TIMER0);
00074     // assign VIC slot
00075     VICVectCntl4 = VIC_ENABLE | VIC_TIMER0;
00076     VICVectAddr4 = (u32)timer0Service;
00077     // enable interrupt
00078     VICIntEnable |= (1<<VIC_TIMER0);
00079 
00080     // setup MR0 value
00081     T0MR0 = PCLK/1000;
00082     // enable timer0 interrupt and reset on MR0 match
00083     T0MCR |= TMCR_MR0_I | TMCR_MR0_R;
00084 
00085 }
00086 
00087 void timer1Init(void)
00088 {
00089     // setup timer1
00090     // set prescaler
00091     timer1PrescalerSet(1);
00092     // reset timer
00093     T1TCR = TCR_RESET;
00094     delay(10);
00095     // start timer
00096     T1TCR = TCR_ENABLE;
00097 
00098     // setup timer1 for IRQ
00099     // set interrupt as IRQ
00100     VICIntSelect &= ~(1<<VIC_TIMER1);
00101     // assign VIC slot
00102     VICVectCntl5 = VIC_ENABLE | VIC_TIMER1;
00103     VICVectAddr5 = (u32)timer1Service;
00104     // enable interrupt
00105     VICIntEnable |= (1<<VIC_TIMER1);
00106 }
00107 
00108 void timer0PrescalerSet(u32 clockDiv)
00109 {
00110     // timer0 increments every PR+1 cycles
00111     // subtract 1 so the argument is a true division ratio
00112     T0PR = clockDiv-1;
00113 }
00114 void timer1PrescalerSet(u32 clockDiv)
00115 {
00116     // timer1 increments every PR+1 cycles
00117     // subtract 1 so the argument is a true division ratio
00118     T1PR = clockDiv-1;
00119 }
00120 
00121 void timerAttach(u08 interruptNum, void (*userFunc)(void) )
00122 {
00123     // make sure the interrupt number is within bounds
00124     if(interruptNum < TIMER_NUM_INTERRUPTS)
00125     {
00126         // set the interrupt function to run
00127         // the supplied user's function
00128         TimerIntrFunc[interruptNum] = userFunc;
00129     }
00130 }
00131 
00132 void timerDetach(u08 interruptNum)
00133 {
00134     // make sure the interrupt number is within bounds
00135     if(interruptNum < TIMER_NUM_INTERRUPTS)
00136     {
00137         // set the interrupt function to run nothing
00138         TimerIntrFunc[interruptNum] = 0;
00139     }
00140 }
00141 
00142 void timerPause(unsigned long pause_ms)
00143 {
00144     Timer0Pause = pause_ms;
00145 
00146     while(Timer0Pause)
00147     {
00148         //rprintfu32(Timer0Pause);
00149         //rprintfCRLF();
00150     }
00151 }
00152 
00153 void timer0ClearOverflowCount(void)
00154 {
00155     Timer0OverflowCount = 0;
00156 }
00157 
00158 u32 timer0GetOverflowCount(void)
00159 {
00160     return Timer0OverflowCount;
00161 }
00162 
00163 void timer1ClearOverflowCount(void)
00164 {
00165     Timer1OverflowCount = 0;
00166 }
00167 
00168 u32 timer1GetOverflowCount(void)
00169 {
00170     return Timer1OverflowCount;
00171 }
00172 
00173 void timer0Match0Set(u32 value)
00174 {
00175     T0MR0 = value;
00176 }
00177 
00178 void timer0Match1Set(u32 value)
00179 {
00180     T0MR1 = value;
00181 }
00182 
00183 void timer1Match0Set(u32 value)
00184 {
00185     T1MR0 = value;
00186 }
00187 
00188 void timer1Match1Set(u32 value)
00189 {
00190     T1MR1 = value;
00191 }
00192 
00193 void timer0Capture0Init(unsigned int edge)
00194 {
00195     // setup timer0 capture0
00196     if(edge)
00197     {
00198         // pin select
00199         PINSEL0 &= ~(3<<(2*2)); // clear pin select bits for P0.2 -> GPIO
00200         PINSEL0 |=  (2<<(2*2)); // set pin select bits for P0.2 -> Capture0.0
00201         // enable timer0 interrupt on rising/falling edge of CR0 capture
00202         T0CCR &= ~(TCCR_CR0_R | TCCR_CR0_F);
00203         T0CCR |= TCCR_CR0_I | (edge);
00204     }
00205     else
00206     {
00207         // pin select
00208         PINSEL0 &= ~(3<<(2*2)); // clear pin select bits for P0.2 -> GPIO
00209         // disable timer0 interrupt on rising/falling edge of CR0 capture
00210         T0CCR &= ~(TCCR_CR0_I);
00211     }
00212 }
00213 
00214 void timer0Capture1Init(unsigned int edge)
00215 {
00216     // setup timer0 capture1
00217     if(edge)
00218     {
00219         // pin select
00220         PINSEL0 &= ~(3<<(4*2)); // clear pin select bits for P0.4 -> GPIO
00221         PINSEL0 |=  (2<<(4*2)); // set pin select bits for P0.4 -> Capture0.1
00222         // enable timer0 interrupt on rising/falling edge of CR1 capture
00223         T0CCR |= TCCR_CR1_I | (edge<<3);
00224     }
00225     else
00226     {
00227         // pin select
00228         PINSEL0 &= ~(3<<(4*2)); // clear pin select bits for P0.4 -> GPIO
00229         // disable timer0 interrupt on rising/falling edge of CR1 capture
00230         T0CCR &= ~(TCCR_CR1_I);
00231     }
00232 }
00233 
00234 void timer1Capture0Init(unsigned int edge)
00235 {
00236     // setup timer1 capture0
00237     if(edge)
00238     {
00239         // pin select
00240         PINSEL0 &= ~(3<<(10*2));    // clear pin select bits for P0.10 -> GPIO
00241         PINSEL0 |=  (2<<(10*2));    // set pin select bits for P0.10 -> Capture0.0
00242         // enable timer0 interrupt on rising/falling edge of CR0 capture
00243         T1CCR &= ~(TCCR_CR0_R | TCCR_CR0_F);
00244         T1CCR |= TCCR_CR0_I | (edge);
00245     }
00246     else
00247     {
00248         // pin select
00249         PINSEL0 &= ~(3<<(10*2));    // clear pin select bits for P0.10 -> GPIO
00250         // disable timer0 interrupt on rising/falling edge of CR0 capture
00251         //T0CCR &= ~(TCCR_CR0_I | TCCR_CR0_R);
00252         T1CCR &= ~(TCCR_CR0_I);
00253     }
00254 }
00255 
00256 void timer1Capture1Init(unsigned int edge)
00257 {
00258     // setup timer1 capture1
00259     if(edge)
00260     {
00261         // pin select
00262         PINSEL0 &= ~(3<<(11*2));    // clear pin select bits for P0.11 -> GPIO
00263         PINSEL0 |=  (2<<(11*2));    // set pin select bits for P0.11 -> Capture0.0
00264         // enable timer0 interrupt on rising/falling edge of CR0 capture
00265         T1CCR &= ~(TCCR_CR0_R | TCCR_CR0_F);
00266         T1CCR |= TCCR_CR1_I | (edge<<3);
00267     }
00268     else
00269     {
00270         // pin select
00271         PINSEL0 &= ~(3<<(11*2));    // clear pin select bits for P0.11 -> GPIO
00272         // disable timer0 interrupt on rising/falling edge of CR0 capture
00273         //T0CCR &= ~(TCCR_CR0_I | TCCR_CR0_R);
00274         T1CCR &= ~(TCCR_CR1_I);
00275     }
00276 }
00277 
00278 void timer0Service(void)
00279 {
00280     ISR_ENTRY();
00281     
00282     // check the interrupt sources
00283     if(T0IR & TIR_MR0I)
00284     {
00285         // clear MR0 Interrupt
00286         T0IR |= TIR_MR0I;
00287         if(Timer0Pause)
00288             Timer0Pause--;
00289         Timer0OverflowCount++;
00290         // if a user function is defined, execute it
00291         if(TimerIntrFunc[TIMER0MATCH0_INT])
00292             TimerIntrFunc[TIMER0MATCH0_INT]();
00293     }
00294     else if(T0IR & TIR_CR0I)
00295     {
00296         // clear CR0 Interrupt
00297         T0IR |= TIR_CR0I;
00298         // if a user function is defined, execute it
00299         if(TimerIntrFunc[TIMER0CAPTURE0_INT])
00300             TimerIntrFunc[TIMER0CAPTURE0_INT]();
00301     }
00302     else if(T0IR & TIR_CR1I)
00303     {
00304         // clear CR1 Interrupt
00305         T0IR |= TIR_CR1I;
00306         // if a user function is defined, execute it
00307         if(TimerIntrFunc[TIMER0CAPTURE1_INT])
00308             TimerIntrFunc[TIMER0CAPTURE1_INT]();
00309     }
00310     
00311     VICSoftIntClear = (1<<VIC_TIMER0);
00312     VICVectAddr = 0x00000000;             // clear this interrupt from the VIC
00313     ISR_EXIT();                           // recover registers and return
00314 }
00315 
00316 void timer1Service(void)
00317 {
00318     ISR_ENTRY();
00319 
00320     if(T1IR & TIR_MR0I)
00321     {
00322         // clear MR0 Interrupt
00323         T1IR |= TIR_MR0I;
00324         Timer1OverflowCount++;
00325         // if a user function is defined, execute it
00326         if(TimerIntrFunc[TIMER1MATCH0_INT])
00327             TimerIntrFunc[TIMER1MATCH0_INT]();
00328     }
00329     else if(T1IR & TIR_CR0I)
00330     {
00331         // clear CR0 Interrupt
00332         T1IR |= TIR_CR0I;
00333         // if a user function is defined, execute it
00334         if(TimerIntrFunc[TIMER1CAPTURE0_INT])
00335             TimerIntrFunc[TIMER1CAPTURE0_INT]();
00336     }
00337     else if(T1IR & TIR_CR1I)
00338     {
00339         // clear CR1 Interrupt
00340         T1IR |= TIR_CR1I;
00341         // if a user function is defined, execute it
00342         if(TimerIntrFunc[TIMER1CAPTURE1_INT])
00343             TimerIntrFunc[TIMER1CAPTURE1_INT]();
00344     }
00345     
00346     VICSoftIntClear = (1<<VIC_TIMER1);
00347     VICVectAddr = 0x00000000;             // clear this interrupt from the VIC
00348     ISR_EXIT();                           // recover registers and return
00349 }

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