summaryrefslogtreecommitdiff
path: root/firmware/drivers/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/timer.c')
-rw-r--r--firmware/drivers/timer.c572
1 files changed, 572 insertions, 0 deletions
diff --git a/firmware/drivers/timer.c b/firmware/drivers/timer.c
new file mode 100644
index 0000000..ed9680b
--- /dev/null
+++ b/firmware/drivers/timer.c
@@ -0,0 +1,572 @@
+/****************************************************************************
+ * $Id:: timer.c 5823 2010-12-07 19:01:00Z usb00423 $
+ * Project: NXP LPC17xx Timer for PWM example
+ *
+ * Description:
+ * This file contains timer code example which include timer
+ * initialization, timer interrupt handler, and APIs for timer access.
+ *
+ ****************************************************************************
+ * Software that is described herein is for illustrative purposes only
+ * which provides customers with programming information regarding the
+ * products. This software is supplied "AS IS" without any warranties.
+ * NXP Semiconductors assumes no responsibility or liability for the
+ * use of the software, conveys no license or title under any patent,
+ * copyright, or mask work right to the product. NXP Semiconductors
+ * reserves the right to make changes in the software without
+ * notification. NXP Semiconductors also make no representation or
+ * warranty that such application will be suitable for the specified
+ * use without further testing or modification.
+****************************************************************************/
+#include <LPC17xx.h>
+
+//#include "lpc_types.h"
+#define FALSE 0
+#define TRUE 1
+
+#include "timer.h"
+
+volatile uint32_t timer0_m0_counter = 0;
+volatile uint32_t timer1_m0_counter = 0;
+volatile uint32_t timer2_m0_counter = 0;
+volatile uint32_t timer3_m0_counter = 0;
+volatile uint32_t timer0_m1_counter = 0;
+volatile uint32_t timer1_m1_counter = 0;
+volatile uint32_t timer2_m1_counter = 0;
+volatile uint32_t timer3_m1_counter = 0;
+
+volatile uint32_t timer0_capture0 = 0;
+volatile uint32_t timer1_capture0 = 0;
+volatile uint32_t timer2_capture0 = 0;
+volatile uint32_t timer3_capture0 = 0;
+volatile uint32_t timer0_capture1 = 0;
+volatile uint32_t timer1_capture1 = 0;
+volatile uint32_t timer2_capture1 = 0;
+volatile uint32_t timer3_capture1 = 0;
+
+/*****************************************************************************
+** Function name: delayMs
+**
+** Descriptions: Start the timer delay in milo seconds
+** until elapsed
+**
+** parameters: timer number, Delay value in milo second
+**
+** Returned value: None
+**
+*****************************************************************************/
+void delayMs(uint8_t timer_num, uint32_t delayInMs)
+{
+ if ( timer_num == 0 )
+ {
+ LPC_TIM0->TCR = 0x02; /* reset timer */
+ LPC_TIM0->PR = 0x00; /* set prescaler to zero */
+ LPC_TIM0->MR0 = (SystemCoreClock / 4) / (1000/delayInMs); //enter delay time
+ LPC_TIM0->IR = 0xff; /* reset all interrrupts */
+ LPC_TIM0->MCR = 0x04; /* stop timer on match */
+ LPC_TIM0->TCR = 0x01; /* start timer */
+
+ /* wait until delay time has elapsed */
+ while (LPC_TIM0->TCR & 0x01);
+
+ }
+ else if ( timer_num == 1 )
+ {
+ LPC_TIM1->TCR = 0x02; /* reset timer */
+ LPC_TIM1->PR = 0x00; /* set prescaler to zero */
+ LPC_TIM0->MR0 = (SystemCoreClock / 4) / (1000/delayInMs); //enter delay time
+ LPC_TIM1->IR = 0xff; /* reset all interrrupts */
+ LPC_TIM1->MCR = 0x04; /* stop timer on match */
+ LPC_TIM1->TCR = 0x01; /* start timer */
+
+ /* wait until delay time has elapsed */
+ while (LPC_TIM1->TCR & 0x01);
+ }
+
+ else if ( timer_num == 2 )
+ {
+ LPC_TIM2->TCR = 0x02; /* reset timer */
+ LPC_TIM2->PR = 0x00; /* set prescaler to zero */
+ LPC_TIM0->MR0 = (SystemCoreClock / 4) / (1000/delayInMs); //enter delay time
+ LPC_TIM2->IR = 0xff; /* reset all interrrupts */
+ LPC_TIM2->MCR = 0x04; /* stop timer on match */
+ LPC_TIM2->TCR = 0x01; /* start timer */
+
+ /* wait until delay time has elapsed */
+ while (LPC_TIM2->TCR & 0x01);
+ }
+
+ else if ( timer_num == 3 )
+ {
+ LPC_TIM3->TCR = 0x02; /* reset timer */
+ LPC_TIM3->PR = 0x00; /* set prescaler to zero */
+ LPC_TIM0->MR0 = (SystemCoreClock / 4) / (1000/delayInMs); //enter delay time
+ LPC_TIM3->IR = 0xff; /* reset all interrrupts */
+ LPC_TIM3->MCR = 0x04; /* stop timer on match */
+ LPC_TIM3->TCR = 0x01; /* start timer */
+
+ /* wait until delay time has elapsed */
+ while (LPC_TIM3->TCR & 0x01);
+ }
+ return;
+}
+
+/******************************************************************************
+** Function name: Timer0_IRQHandler
+**
+** Descriptions: Timer/Counter 0 interrupt handler
+**
+** parameters: None
+** Returned value: None
+**
+******************************************************************************/
+void TIMER0_interrupt (void)
+{
+ if ( LPC_TIM0->IR & (0x1<<0) )
+ {
+ LPC_TIM0->IR = 0x1<<0; /* clear interrupt flag */
+ timer0_m0_counter++;
+ }
+ if ( LPC_TIM0->IR & (0x1<<1) )
+ {
+ LPC_TIM0->IR = 0x1<<1; /* clear interrupt flag */
+ timer0_m1_counter++;
+ }
+ if ( LPC_TIM0->IR & (0x1<<4) )
+ {
+ LPC_TIM0->IR = 0x1<<4; /* clear interrupt flag */
+ timer0_capture0++;
+ }
+ if ( LPC_TIM0->IR & (0x1<<5) )
+ {
+ LPC_TIM0->IR = 0x1<<5; /* clear interrupt flag */
+ timer0_capture1++;
+ }
+ return;
+}
+
+/******************************************************************************
+** Function name: Timer1_IRQHandler
+**
+** Descriptions: Timer/Counter 1 interrupt handler
+**
+** parameters: None
+** Returned value: None
+**
+******************************************************************************/
+void TIMER1_interrupt (void)
+{
+ if ( LPC_TIM1->IR & (0x1<<0) )
+ {
+ LPC_TIM1->IR = 0x1<<0; /* clear interrupt flag */
+ timer1_m0_counter++;
+ }
+ if ( LPC_TIM1->IR & (0x1<<1) )
+ {
+ LPC_TIM1->IR = 0x1<<1; /* clear interrupt flag */
+ timer1_m1_counter++;
+ }
+ if ( LPC_TIM1->IR & (0x1<<4) )
+ {
+ LPC_TIM1->IR = 0x1<<4; /* clear interrupt flag */
+ timer1_capture0++;
+ }
+ if ( LPC_TIM1->IR & (0x1<<5) )
+ {
+ LPC_TIM1->IR = 0x1<<5; /* clear interrupt flag */
+ timer1_capture1++;
+ }
+ return;
+}
+
+/******************************************************************************
+** Function name: Timer2_IRQHandler
+**
+** Descriptions: Timer/Counter 2 interrupt handler
+**
+** parameters: None
+** Returned value: None
+**
+******************************************************************************/
+void TIMER2_interrupt (void)
+{
+ if ( LPC_TIM2->IR & (0x1<<0) )
+ {
+ LPC_TIM2->IR = 0x1<<0; /* clear interrupt flag */
+ timer2_m0_counter++;
+ }
+ if ( LPC_TIM2->IR & (0x1<<1) )
+ {
+ LPC_TIM2->IR = 0x1<<1; /* clear interrupt flag */
+ timer2_m1_counter++;
+ }
+ if ( LPC_TIM2->IR & (0x1<<4) )
+ {
+ LPC_TIM2->IR = 0x1<<4; /* clear interrupt flag */
+ timer2_capture0++;
+ }
+ if ( LPC_TIM2->IR & (0x1<<5) )
+ {
+ LPC_TIM2->IR = 0x1<<5; /* clear interrupt flag */
+ timer2_capture1++;
+ }
+ return;
+}
+
+/******************************************************************************
+** Function name: Timer3_IRQHandler
+**
+** Descriptions: Timer/Counter 3 interrupt handler
+**
+** parameters: None
+** Returned value: None
+**
+******************************************************************************/
+void TIMER3_interrupt (void)
+{
+ if ( LPC_TIM3->IR & (0x1<<0) )
+ {
+ LPC_TIM3->IR = 0x1<<0; /* clear interrupt flag */
+ timer3_m0_counter++;
+ }
+ if ( LPC_TIM3->IR & (0x1<<1) )
+ {
+ LPC_TIM3->IR = 0x1<<1; /* clear interrupt flag */
+ timer3_m1_counter++;
+ }
+ if ( LPC_TIM3->IR & (0x1<<4) )
+ {
+ LPC_TIM3->IR = 0x1<<4; /* clear interrupt flag */
+ timer3_capture0++;
+ }
+ if ( LPC_TIM3->IR & (0x1<<5) )
+ {
+ LPC_TIM3->IR = 0x1<<5; /* clear interrupt flag */
+ timer3_capture1++;
+ }
+ return;
+}
+
+/******************************************************************************
+** Function name: enable_timer
+**
+** Descriptions: Enable timer
+**
+** parameters: timer number: 0 or 1 or 2 or 3
+** Returned value: None
+**
+******************************************************************************/
+void enable_timer( uint8_t timer_num )
+{
+ if ( timer_num == 0 )
+ {
+ LPC_TIM0->TCR = 1;
+ }
+ else if ( timer_num == 1 )
+ {
+ LPC_TIM1->TCR = 1;
+ }
+ else if ( timer_num == 2 )
+ {
+ LPC_TIM2->TCR = 1;
+ }
+ else if ( timer_num == 3 )
+ {
+ LPC_TIM3->TCR = 1;
+ }
+ return;
+}
+
+/******************************************************************************
+** Function name: disable_timer
+**
+** Descriptions: Disable timer
+**
+** parameters: timer number: 0 or 1 oe 2 or 3
+** Returned value: None
+**
+******************************************************************************/
+void disable_timer( uint8_t timer_num )
+{
+ if ( timer_num == 0 )
+ {
+ LPC_TIM0->TCR = 0;
+ }
+ else if ( timer_num == 1 )
+ {
+ LPC_TIM1->TCR = 0;
+ }
+ else if ( timer_num == 2 )
+ {
+ LPC_TIM2->TCR = 0;
+ }
+ else if ( timer_num == 3 )
+ {
+ LPC_TIM2->TCR = 0;
+ }
+ return;
+}
+
+/******************************************************************************
+** Function name: reset_timer
+**
+** Descriptions: Reset timer
+**
+** parameters: timer number: 0 or 1 or 2 or 3
+** Returned value: None
+**
+******************************************************************************/
+void reset_timer( uint8_t timer_num )
+{
+ uint32_t regVal;
+
+ if ( timer_num == 0 )
+ {
+ regVal = LPC_TIM0->TCR;
+ regVal |= 0x02;
+ LPC_TIM0->TCR = regVal;
+ }
+ else if ( timer_num == 1 )
+ {
+ regVal = LPC_TIM1->TCR;
+ regVal |= 0x02;
+ LPC_TIM1->TCR = regVal;
+ }
+ else if ( timer_num == 2 )
+ {
+ regVal = LPC_TIM2->TCR;
+ regVal |= 0x02;
+ LPC_TIM2->TCR = regVal;
+ }
+ else if ( timer_num == 3 )
+ {
+ regVal = LPC_TIM3->TCR;
+ regVal |= 0x02;
+ LPC_TIM3->TCR = regVal;
+ }
+ return;
+}
+
+/******************************************************************************
+** Function name: init_timer
+**
+** Descriptions: Initialize timer, set timer interval, reset timer,
+** install timer interrupt handler
+**
+** parameters: timer number and timer interval
+** Returned value: true or false, if the interrupt handler can't be
+** installed, return false.
+**
+******************************************************************************/
+uint32_t TimerInit( uint8_t timer_num, uint32_t TimerInterval )
+{
+ uint32_t pclkdiv, pclk;
+ (void)pclk;
+
+ if ( timer_num == 0 )
+ {
+ timer0_m0_counter = 0;
+ timer0_m1_counter = 0;
+ timer0_capture0 = 0;
+ timer0_capture1 = 0;
+ LPC_SC->PCONP |= (0x01<<1);
+#if TIMER_MATCH
+ LPC_PINCON->PINSEL3 &= ~((0x3<<24)|(0x3<<26));
+ LPC_PINCON->PINSEL3 |= ((0x3<<24)|(0x3<<26));
+#else
+ LPC_PINCON->PINSEL3 &= ~((0x3<<20)|(0x3<<22));
+ LPC_PINCON->PINSEL3 |= ((0x3<<20)|(0x3<<22));
+#endif
+ LPC_TIM0->IR = 0x0F; /* Clear MATx interrupt include DMA request */
+
+ /* By default, the PCLKSELx value is zero, thus, the PCLK for
+ all the peripherals is 1/4 of the SystemCoreClock. */
+ /* Bit 2~3 is for TIMER0 */
+ pclkdiv = (LPC_SC->PCLKSEL0 >> 2) & 0x03;
+ switch ( pclkdiv )
+ {
+ case 0x00:
+ default:
+ pclk = SystemCoreClock/4;
+ break;
+ case 0x01:
+ pclk = SystemCoreClock;
+ break;
+ case 0x02:
+ pclk = SystemCoreClock/2;
+ break;
+ case 0x03:
+ pclk = SystemCoreClock/8;
+ break;
+ }
+ LPC_TIM0->PR = 0;
+
+ LPC_TIM0->MR0 = TimerInterval/4;
+ LPC_TIM0->MR1 = TimerInterval/4;
+#if TIMER_MATCH
+ LPC_TIM0->EMR &= ~(0xFF<<4);
+ LPC_TIM0->EMR |= ((0x3<<4)|(0x3<<6));
+#else
+ /* Capture 0 and 1 on rising edge, interrupt enable. */
+ LPC_TIM0->CCR = (0x1<<0)|(0x1<<2)|(0x1<<3)|(0x1<<5);
+#endif
+ LPC_TIM0->MCR = (0x3<<0)|(0x3<<3); /* Interrupt and Reset on MR0 and MR1 */
+ NVIC_EnableIRQ(TIMER0_IRQn);
+ return (TRUE);
+ }
+ else if ( timer_num == 1 )
+ {
+ timer1_m0_counter = 0;
+ timer1_m1_counter = 0;
+ timer1_capture0 = 0;
+ timer1_capture1 = 0;
+ LPC_SC->PCONP |= (0x1<<2);
+#if TIMER_MATCH
+ LPC_PINCON->PINSEL3 &= ~((0x3<<12)|(0x3<<18));
+ LPC_PINCON->PINSEL3 |= ((0x3<<12)|(0x3<<18));
+#else
+ LPC_PINCON->PINSEL3 &= ~((0x3<<4)|(0x3<<6));
+ LPC_PINCON->PINSEL3 |= ((0x3<<4)|(0x3<<6));
+#endif
+ LPC_TIM1->IR = 0x0F; /* Clear MATx interrupt include DMA request */
+ /* By default, the PCLKSELx value is zero, thus, the PCLK for
+ all the peripherals is 1/4 of the SystemCoreClock. */
+ /* Bit 4~5 is for TIMER0 */
+ pclkdiv = (LPC_SC->PCLKSEL0 >> 4) & 0x03;
+ switch ( pclkdiv )
+ {
+ case 0x00:
+ default:
+ pclk = SystemCoreClock/4;
+ break;
+ case 0x01:
+ pclk = SystemCoreClock;
+ break;
+ case 0x02:
+ pclk = SystemCoreClock/2;
+ break;
+ case 0x03:
+ pclk = SystemCoreClock/8;
+ break;
+ }
+ LPC_TIM1->PR = 0;
+ LPC_TIM1->MR0 = TimerInterval/4;
+ LPC_TIM1->MR1 = TimerInterval/4;
+#if TIMER_MATCH
+ LPC_TIM1->EMR &= ~(0xFF<<4);
+ LPC_TIM1->EMR |= ((0x3<<4)|(0x3<<6));
+#else
+ /* Capture 0/1 on rising edge, interrupt enable. */
+ LPC_TIM1->CCR = (0x1<<0)|(0x1<<2)|(0x1<<3)|(0x1<<5);
+#endif
+ LPC_TIM1->MCR = (0x3<<0)|(0x3<<3); /* Interrupt and Reset on MR0 and MR1 */
+ NVIC_EnableIRQ(TIMER1_IRQn);
+ return (TRUE);
+ }
+
+ else if ( timer_num == 2 )
+ {
+ timer2_m0_counter = 0;
+ timer2_m1_counter = 0;
+ timer2_capture0 = 0;
+ timer2_capture1 = 0;
+ LPC_SC->PCONP |= (0x1<<22);
+ #if TIMER_MATCH
+ LPC_PINCON->PINSEL3 &= ~((0x3<<12)|(0x3<<18));
+ LPC_PINCON->PINSEL3 |= ((0x3<<12)|(0x3<<18));
+ #else
+ LPC_PINCON->PINSEL3 &= ~((0x3<<4)|(0x3<<6));
+ LPC_PINCON->PINSEL3 |= ((0x3<<4)|(0x3<<6));
+ #endif
+ LPC_TIM2->IR = 0x0F; /* Clear MATx interrupt include DMA request */
+ /* By default, the PCLKSELx value is zero, thus, the PCLK for
+ all the peripherals is 1/4 of the SystemCoreClock. */
+ /* Bit 12~13 is for TIMER2 */
+ pclkdiv = (LPC_SC->PCLKSEL1 >> 12) & 0x03;
+ switch ( pclkdiv )
+ {
+ case 0x00:
+ default:
+ pclk = SystemCoreClock/4;
+ break;
+ case 0x01:
+ pclk = SystemCoreClock;
+ break;
+ case 0x02:
+ pclk = SystemCoreClock/2;
+ break;
+ case 0x03:
+ pclk = SystemCoreClock/8;
+ break;
+ }
+ LPC_TIM2->PR = 0;
+ LPC_TIM2->MR0 = TimerInterval/4;
+ LPC_TIM2->MR1 = TimerInterval/4;
+ #if TIMER_MATCH
+ LPC_TIM2->EMR &= ~(0xFF<<4);
+ LPC_TIM2->EMR |= ((0x3<<4)|(0x3<<6));
+ #else
+ /* Capture 0/1 on rising edge, interrupt enable. */
+ LPC_TIM2->CCR = (0x1<<0)|(0x1<<2)|(0x1<<3)|(0x1<<5);
+ #endif
+ LPC_TIM2->MCR = (0x3<<0)|(0x3<<3); /* Interrupt and Reset on MR0 and MR1 */
+ NVIC_EnableIRQ(TIMER2_IRQn);
+ return (TRUE);
+ }
+
+ else if ( timer_num == 3 )
+ {
+ timer3_m0_counter = 0;
+ timer3_m1_counter = 0;
+ timer3_capture0 = 0;
+ timer3_capture1 = 0;
+ LPC_SC->PCONP |= (0x1<<23);
+ #if TIMER_MATCH
+ LPC_PINCON->PINSEL3 &= ~((0x3<<12)|(0x3<<18));
+ LPC_PINCON->PINSEL3 |= ((0x3<<12)|(0x3<<18));
+ #else
+ LPC_PINCON->PINSEL3 &= ~((0x3<<4)|(0x3<<6));
+ LPC_PINCON->PINSEL3 |= ((0x3<<4)|(0x3<<6));
+ #endif
+ LPC_TIM3->IR = 0x0F; /* Clear MATx interrupt include DMA request */
+ /* By default, the PCLKSELx value is zero, thus, the PCLK for
+ all the peripherals is 1/4 of the SystemCoreClock. */
+ /* Bit 14~15 is for TIMER3 */
+ pclkdiv = (LPC_SC->PCLKSEL1 >> 14) & 0x03;
+ switch ( pclkdiv )
+ {
+ case 0x00:
+ default:
+ pclk = SystemCoreClock/4;
+ break;
+ case 0x01:
+ pclk = SystemCoreClock;
+ break;
+ case 0x02:
+ pclk = SystemCoreClock/2;
+ break;
+ case 0x03:
+ pclk = SystemCoreClock/8;
+ break;
+ }
+ LPC_TIM3->PR = 0;
+ LPC_TIM3->MR0 = TimerInterval/4;
+ LPC_TIM3->MR1 = TimerInterval/4;
+ #if TIMER_MATCH
+ LPC_TIM3->EMR &= ~(0xFF<<4);
+ LPC_TIM3->EMR |= ((0x3<<4)|(0x3<<6));
+ #else
+ /* Capture 0/1 on rising edge, interrupt enable. */
+ LPC_TIM3->CCR = (0x1<<0)|(0x1<<2)|(0x1<<3)|(0x1<<5);
+ #endif
+ LPC_TIM3->MCR = (0x3<<0)|(0x3<<3); /* Interrupt and Reset on MR0 and MR1 */
+ NVIC_EnableIRQ(TIMER3_IRQn);
+ return (TRUE);
+ }
+
+ return (FALSE);
+}
+
+/******************************************************************************
+** End Of File
+******************************************************************************/