From 79b6705bfc60ed17ddbf6c36ead99e9f5c3c7404 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Wed, 26 Feb 2014 21:06:30 +0100 Subject: Old SPI code is now disabled, new SPI code succesfully reads out WM8523 chip id. Needs lots of cleaning... --- firmware/drivers/timer.c | 572 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 572 insertions(+) create mode 100644 firmware/drivers/timer.c (limited to 'firmware/drivers/timer.c') 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 + +//#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 +******************************************************************************/ -- cgit v1.2.3