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 }