www.pudn.com > LPC2148_IAR_LPC2148.zip > lpc_timer.c
/*************************************************************************
*
* Used with ICCARM and AARM.
*
* (c) Copyright IAR Systems 2003
*
* File name : LPC_Timer.c
* Description : Define API for Timer system
*
* History :
* 1. Date: July 08, 2004
* Author: Wilson Liu
* Description: Create the basic function
*
* 2. Date: August 12, 2004
* Author: Shawn Zhang
* Description: Re-write some API interface
*
* 3. Data : Oct 10, 2004
* Author : Stanimir Bonev
* Description : Modify some functions interface
*
* $Revision: 1.1.2.1 $
**************************************************************************/
#include "LPC_Timer.h"
LPC_Timer_Config_t Timer0Config, Timer1Config;
/*************************************************************************
* Function Name: TIMER_Init
* Parameters: LPC_TimerChanel_t DevNum
* unsigned int precision -- the timer precision (Unit: us), general setting is 10 us
* Return: int
* 0: success
* non-zero: error number
* Description: Initialize Timer, Set the PR register that represent the precision of timer.
*
*************************************************************************/
int TIMER_Init(LPC_TimerChanel_t DevNum, unsigned long precision)
{
int i;
//all registers are set to 0;
switch (DevNum)
{
case TIMER0:
// Set globe variable
Timer0Config.Precision = precision;
// PR = Precision(us) * Pclk
if(precision)
{
Timer0Config.Prescaler = (precision * SYS_GetFpclk()) / 1000000;
}
else
{
Timer0Config.Prescaler = 1;
}
for (i=0; i= CH_MAXNUM)
return 1;
switch(DevNum)
{
case TIMER0:
*pMatchValue = Timer0Config.MatchCH[MRNum].TimeValue;
*pAction = Timer0Config.MatchCH[MRNum].Action;
break;
case TIMER1:
*pMatchValue = Timer1Config.MatchCH[MRNum].TimeValue;
*pAction = Timer1Config.MatchCH[MRNum].Action;
break;
default:
return 1;
}
return 0;
}
/*************************************************************************
* Function Name: TIMER_SetMatchAction
* Parameters: LPC_TimerChanel_t DevNum -- Device Number
* unsigned int MRNum -- Match Channel Number
* unsigned int action -- General Interrupt | Reset Timer | Stop Timer
* unsigned int Timevalue -- the time value (Unit: us)
* void (* Fnpr)(void *) -- ISR function pointer
* void * FnprArg -- relative argument
* LPC_Timer_ExtAction_t ExtAction -- External Match Control Action
*
* Return: int
* 0: success
* non-zero: error number
* Description: Set correponding matching action and other information to the channel
* for specific timer.
*
*************************************************************************/
int TIMER_SetMatchAction(LPC_TimerChanel_t DevNum,
unsigned int MRNum,
unsigned int action ,
unsigned long TimeValue,
void (* Fnpr)(void *),
void * FnprArg,
LPC_Timer_ExtAction_t ExtAction)
{
// Check parameter valid
if (action>TimerAction_StopTimer+TimerAction_ResetTimer+TimerAction_Interrupt)
return 1;
if (ExtAction > TOGGLE)
return 1;
switch (DevNum)
{
case TIMER0:
// Set Mash register
switch (MRNum)
{
case CH0:
T0MR0=TimeValue;
break;
case CH1:
T0MR1=TimeValue;
break;
case CH2:
T0MR2=TimeValue;
break;
case CH3:
T0MR3=TimeValue;
break;
default:
return 1;
}
Timer0Config.MatchCH[MRNum].Enable = true;
Timer0Config.MatchCH[MRNum].Action = action;
Timer0Config.MatchCH[MRNum].TimeValue= TimeValue;
Timer0Config.ExtAction[MRNum]= ExtAction;
// Clear actions
T0MCR &= ~(7<<(MRNum*3));
//Set Reset on Match
if (action & TimerAction_ResetTimer)
T0MCR |= TimerAction_ResetTimer << (3*MRNum);
//Set StopWatch on Match
if (action & TimerAction_StopTimer)
T0MCR |= TimerAction_StopTimer << (3*MRNum);
//Set Interrupt on Match
if (action & TimerAction_Interrupt)
{
Timer0Config.MatchCH[MRNum].Fnpr = Fnpr;
Timer0Config.MatchCH[MRNum].FnprArg = FnprArg;
T0MCR |= TimerAction_Interrupt << (3*MRNum);
}
// Clear External action
T0EMR &= ~(3 << (4 + 2*MRNum));
// Set External action
switch (MRNum)
{
case CH0:
// Set External action type
T0EMR_bit.EMC0 = ExtAction;
// Assign pin to match modyle
if (ExtAction != DONOTHING)
PINSEL0_bit.P0_3 = 0x2;
break;
case CH1:
// Set External action type
T0EMR_bit.EMC1 = ExtAction;
// Assign pin to match modyle
if (ExtAction != DONOTHING)
PINSEL0_bit.P0_5 = 0x2;
break;
case CH2:
// Set External action type
T0EMR_bit.EMC2 = ExtAction;
// Assign pin to match modyle
if (ExtAction != DONOTHING)
PINSEL1_bit.P0_16 = 0x2;
break;
case CH3:
// Set External action type
T0EMR_bit.EMC3 = ExtAction;
break;
}
return 0;
case TIMER1:
// Set Mash register
switch (MRNum)
{
case CH0:
T1MR0=TimeValue;
break;
case CH1:
T1MR1=TimeValue;
break;
case CH2:
T1MR2=TimeValue;
break;
case CH3:
T1MR3=TimeValue;
break;
default:
return 1;
}
Timer1Config.MatchCH[MRNum].Enable = true;
Timer1Config.MatchCH[MRNum].Action = action;
Timer1Config.MatchCH[MRNum].TimeValue= TimeValue;
Timer1Config.ExtAction[MRNum]= ExtAction;
// Clear actions
T1MCR &= ~(7<<(MRNum*3));
//Set Reset on Match
if (action & TimerAction_ResetTimer)
T1MCR |= TimerAction_ResetTimer << (3*MRNum);
//Set StopWatch on Match
if (action & TimerAction_StopTimer)
T1MCR |= TimerAction_StopTimer << (3*MRNum);
//Set Interrupt on Match
if (action & TimerAction_Interrupt)
{
Timer1Config.MatchCH[MRNum].Fnpr = Fnpr;
Timer1Config.MatchCH[MRNum].FnprArg = FnprArg;
T1MCR |= TimerAction_Interrupt << (3*MRNum);
}
// Clear External action
T1EMR &= ~(3 << (4 + 2*MRNum));
// Set External action
switch (MRNum)
{
case CH0:
// Set External action type
T1EMR_bit.EMC0 = ExtAction;
// Assign pin to match modyle
if (ExtAction != DONOTHING)
PINSEL0_bit.P0_12 = 0x2;
break;
case CH1:
// Set External action type
T1EMR_bit.EMC1 = ExtAction;
// Assign pin to match modyle
if (ExtAction != DONOTHING)
PINSEL0_bit.P0_13 = 0x2;
break;
case CH2:
// Set External action type
T1EMR_bit.EMC2 = ExtAction;
// Assign pin to match modyle
if (ExtAction != DONOTHING)
PINSEL1_bit.P0_19 = 0x2;
break;
case CH3:
// Set External action type
T0EMR_bit.EMC3 = ExtAction;
// Assign pin to match modyle
if (ExtAction != DONOTHING)
PINSEL1_bit.P0_20 = 0x2;
break;
}
return 0;
}
return 1;
}
/*************************************************************************
* Function Name: TIMER_GetTimerExternalMatch
* Parameters: LPC_TimerChanel_t DevNum
* unsigned int MRNum,
* unsigned int *pAction,
* unsigned int *pExternalMatchValue
* Return: int
* 0: success
* non-zero: error number
* Description: Get correponding external matching information from specific timer.
*
*************************************************************************/
int TIMER_GetTimerExternalMatch(LPC_TimerChanel_t DevNum, unsigned int MRNum,
unsigned int * pAction , unsigned int *pExternalMatchValue)
{
if (MRNum >= CH_MAXNUM)
return 1;
switch(DevNum)
{
case TIMER0:
*pExternalMatchValue = Timer0Config.ExtAction[MRNum];
*pAction = Timer0Config.MatchCH[MRNum].Action;
break;
case TIMER1:
*pExternalMatchValue = Timer1Config.ExtAction[MRNum];
*pAction = Timer1Config.MatchCH[MRNum].Action;
break;
default:
return 1;
}
return 0;
}
/*************************************************************************
* Function Name: TIMER_GetTimerCapture
* Parameters: LPC_TimerChanel_t DevNum,
* unsigned int CRNum,
* unsigned int * pCaptureValue
* Return: int
* 0: success
* non-zero: error number
* Description: Get correponding capture information from specific timer.
*
*************************************************************************/
int TIMER_GetTimerCapture(LPC_TimerChanel_t DevNum, unsigned int CRNum,
unsigned int * pCaptureValue)
{
switch(DevNum)
{
case TIMER0:
if (CRNum >= CPCH_MAXNUM-1)
return 1;
*pCaptureValue = Timer0Config.CaptureCH[CRNum].CPValue;
break;
case TIMER1:
if (CRNum >= CPCH_MAXNUM)
return 1;
*pCaptureValue = Timer1Config.CaptureCH[CRNum].CPValue;
break;
default:
return 1;
}
return 0;
}
/*************************************************************************
* Function Name: TIMER_SetCaptureAction
* Parameters: LPC_TimerChanel_t DevNum -- Device Number
* unsigned char CPCHNum -- Capture Channel Number
* unsigned char TriggerType -- Rising edge | Falling edge
* bool EnableInt -- whether interrupt is generated
* void (* Fnpr)(void *) -- ISR function pointer
* void * FnprArg -- relative argument
*
* Return: int
* 0: success
* non-zero: error number
* Description: Set correponding capture trigger type and other information to the channel
* for specific timer.
*
*************************************************************************/
int TIMER_SetCaptureAction (LPC_TimerChanel_t DevNum,
unsigned char CPCHNum,
unsigned char TriggerType,
bool EnableInt,
void (* Fnpr)(void *),
void * FnprArg )
{
// Check parameter valid
if (TriggerType > TimerCPTrigger_Rising+TimerCPTrigger_Falling)
return 1;
switch (DevNum)
{
case TIMER0:
if (CPCHNum > CPCH_MAXNUM-2) // for timer 0 cature chanel 3 is not exist
return 1;
Timer0Config.CaptureCH[CPCHNum].Enable = true;
Timer0Config.CaptureCH[CPCHNum].TriggerType = TriggerType;
// Clear Capture actions
T0CCR &= ~(7 << (3*CPCHNum));
// Assign of pin to capture module
switch (CPCHNum)
{
case CH0:
if (TriggerType == 0)
PINSEL0_bit.P0_2 = 0;
else
PINSEL0_bit.P0_2 = 0x2;
break;
case CH1:
if (TriggerType == 0)
PINSEL0_bit.P0_4 = 0;
else
PINSEL0_bit.P0_4 = 0x2;
break;
case CH2:
if (TriggerType == 0)
PINSEL0_bit.P0_6 = 0;
else
PINSEL0_bit.P0_6 = 0x2;
break;
}
//Set Capture on Rising Edge
if (TriggerType & TimerCPTrigger_Rising)
T0CCR |= TimerCPTrigger_Rising << (3*CPCHNum);
//Set Capture on Falling Edge
if (TriggerType & TimerCPTrigger_Falling)
T0CCR |= TimerCPTrigger_Falling << (3*CPCHNum);
//Set Interrupt on Capture
if (EnableInt && TriggerType)
{
Timer0Config.CaptureCH[CPCHNum].EnableInt = true;
Timer0Config.CaptureCH[CPCHNum].Fnpr = Fnpr;
Timer0Config.CaptureCH[CPCHNum].FnprArg = FnprArg;
T0CCR |= 0x4 << (3*CPCHNum);
}
else
{
Timer0Config.CaptureCH[CPCHNum].EnableInt = false;
Timer0Config.CaptureCH[CPCHNum].Fnpr = NULL;
Timer0Config.CaptureCH[CPCHNum].FnprArg = (void *)0;
}
return 0;
case TIMER1:
if (CPCHNum > CPCH_MAXNUM-1)
return 1;
Timer1Config.CaptureCH[CPCHNum].Enable = true;
Timer1Config.CaptureCH[CPCHNum].TriggerType = TriggerType;
// Clear Capture actions
T1CCR &= ~(7 << (3*CPCHNum));
// Assign of pin to capture module
switch (CPCHNum)
{
case CH0:
if (TriggerType == 0)
PINSEL0_bit.P0_10 = 0;
else
PINSEL0_bit.P0_10 = 0x2;
break;
case CH1:
if (TriggerType)
PINSEL0_bit.P0_11 = 0x2;
break;
case CH2:
if (TriggerType == 0)
PINSEL1_bit.P0_17 = 0;
else
PINSEL1_bit.P0_17 = 0x2;
break;
case CH3:
if (TriggerType == 0)
PINSEL1_bit.P0_18 = 0;
else
PINSEL1_bit.P0_18 = 0x2;
break;
}
//Set Capture on Rising Edge
if (TriggerType & TimerCPTrigger_Rising)
T1CCR |= TimerCPTrigger_Rising << (3*CPCHNum);
//Set Capture on Falling Edge
if (TriggerType & TimerCPTrigger_Falling)
T1CCR |= TimerCPTrigger_Falling << (3*CPCHNum);
//Set Interrupt on Capture
if (EnableInt && TriggerType)
{
Timer1Config.CaptureCH[CPCHNum].EnableInt = true;
Timer1Config.CaptureCH[CPCHNum].Fnpr = Fnpr;
Timer1Config.CaptureCH[CPCHNum].FnprArg = FnprArg;
T1CCR |= 0x4 << (3*CPCHNum);
}
else
{
Timer1Config.CaptureCH[CPCHNum].EnableInt = false;
Timer1Config.CaptureCH[CPCHNum].Fnpr = NULL;
Timer1Config.CaptureCH[CPCHNum].FnprArg = (void *)0;
}
return 0;
}
return 1;
}
/*************************************************************************
* Function Name: TIMER_GetREGValue_CR
* Parameters: LPC_TimerChanel_t DevNum
* int CRNum
* Return: unsigned long
*
* Description: Get CR register value
*
*************************************************************************/
unsigned long TIMER_GetREGValue_CR(LPC_TimerChanel_t DevNum, int CRNum)
{
switch (DevNum)
{
case TIMER0:
switch(CRNum)
{
case CPCH0:
return T0CR0;
case CPCH1:
return T0CR1;
case CPCH2:
return T0CR2;
case CPCH3:
return T0CR3;
}
case TIMER1:
switch(CRNum)
{
case CPCH0:
return T1CR0;
case CPCH1:
return T1CR1;
case CPCH2:
return T1CR2;
case CPCH3:
return T1CR3;
}
}
return (unsigned int)-1;
}
/*************************************************************************
* Function Name: TIMER_GetREGValue_TC
* Parameters: LPC_TimerChanel_t DevNum
* Return: unsigned long
*
* Description: Get TC register value
*
*************************************************************************/
unsigned long TIMER_GetREGValue_TC(LPC_TimerChanel_t DevNum)
{
switch (DevNum)
{
case TIMER0:
return T0TC;
case TIMER1:
return T1TC;
}
return (unsigned int)-1;
}
/*************************************************************************
* Function Name: TIMER_CheckIntSrc
* Parameters: LPC_TimerChanel_t DevNum
* Return: unsigned long
* TIMERMR0...3Int | TIMERCR0...3Int
*
* Description: Get Timer interrupt Type
*
*************************************************************************/
unsigned long TIMER_CheckIntType(LPC_TimerChanel_t DevNum)
{
switch (DevNum)
{
case TIMER0:
return (T0IR & 0xFF);
case TIMER1:
return (T1IR & 0xFF);
default:
return (unsigned long)-1;
}
}
/*************************************************************************
* Function Name: RTC_ClearInt
* Parameters: LPC_TimerChanel_t DevNum
* int IntType
*
* Return: unsigned long
* 0: sucess
* 1: fail
*
* Description: Clear Timer interrupt.
*
*************************************************************************/
unsigned long TIMER_ClearInt(LPC_TimerChanel_t DevNum, int IntType)
{
if (IntType<1 || IntType>0xFF)
return 1;
switch (DevNum)
{
case TIMER0:
T0IR = (IntType & 0xFF);
break;
case TIMER1:
T1IR = (IntType & 0xFF);
break;
default:
return 1;
}
return 0;
}
/*************************************************************************
* Function Name: T0ISR
* Parameters: void
* Return: void
*
* Description: TIMER0 interrupt subroutine
*
*************************************************************************/
void TIMER0_ISR ()
{
int IntStatus;
IntStatus = TIMER_CheckIntType(TIMER0);
TIMER_ClearInt(TIMER0, IntStatus);
/* Match Register Interrupt */
if (IntStatus & TIMERMR0Int)
{
(Timer0Config.MatchCH[0].Fnpr)((void *)Timer0Config.MatchCH[0].FnprArg);
}
if (IntStatus & TIMERMR1Int)
{
(Timer0Config.MatchCH[1].Fnpr)((void *)Timer0Config.MatchCH[1].FnprArg);
}
if (IntStatus & TIMERMR2Int)
{
(Timer0Config.MatchCH[2].Fnpr)((void *)Timer0Config.MatchCH[2].FnprArg);
}
if (IntStatus & TIMERMR3Int)
{
(Timer0Config.MatchCH[3].Fnpr)((void *)Timer0Config.MatchCH[3].FnprArg);
}
/* Capture Register Interrupt */
if (IntStatus & TIMERCR0Int)
{
Timer0Config.CaptureCH[0].CPValue = TIMER_GetREGValue_CR(TIMER0, CPCH0);
(Timer0Config.CaptureCH[0].Fnpr)((void *)Timer0Config.CaptureCH[0].FnprArg);
}
if (IntStatus & TIMERCR1Int)
{
Timer0Config.CaptureCH[1].CPValue = TIMER_GetREGValue_CR(TIMER0, CPCH1);
(Timer0Config.CaptureCH[1].Fnpr)((void *)Timer0Config.CaptureCH[1].FnprArg);
}
if (IntStatus & TIMERCR2Int)
{
Timer0Config.CaptureCH[2].CPValue = TIMER_GetREGValue_CR(TIMER0, CPCH2);
(Timer0Config.CaptureCH[2].Fnpr)((void *)Timer0Config.CaptureCH[2].FnprArg);
}
if (IntStatus & TIMERCR3Int)
{
Timer0Config.CaptureCH[3].CPValue = TIMER_GetREGValue_CR(TIMER0, CPCH3);
(Timer0Config.CaptureCH[3].Fnpr)((void *)Timer0Config.CaptureCH[3].FnprArg);
}
VICVectAddr = 0; // Clear interrupt in VIC.
}
/*************************************************************************
* Function Name: T1ISR
* Parameters: void
* Return: void
*
* Description: TIMER1 interrupt subroutine
*
*************************************************************************/
void TIMER1_ISR ()
{
int IntStatus;
IntStatus = TIMER_CheckIntType(TIMER1);
TIMER_ClearInt(TIMER1, IntStatus);
/* Match Register Interrupt */
if (IntStatus & TIMERMR0Int)
{
(Timer1Config.MatchCH[0].Fnpr)((void *)Timer1Config.MatchCH[0].FnprArg);
}
if (IntStatus & TIMERMR1Int)
{
(Timer1Config.MatchCH[1].Fnpr)((void *)Timer1Config.MatchCH[1].FnprArg);
}
if (IntStatus & TIMERMR2Int)
{
(Timer1Config.MatchCH[2].Fnpr)((void *)Timer1Config.MatchCH[2].FnprArg);
}
if (IntStatus & TIMERMR3Int)
{
(Timer1Config.MatchCH[3].Fnpr)((void *)Timer1Config.MatchCH[3].FnprArg);
}
/* Capture Register Interrupt */
if (IntStatus & TIMERCR0Int)
{
Timer1Config.CaptureCH[0].CPValue = TIMER_GetREGValue_CR(TIMER1, CPCH0);
(Timer1Config.CaptureCH[0].Fnpr)((void *)Timer1Config.CaptureCH[0].FnprArg);
}
if (IntStatus & TIMERCR1Int)
{
Timer1Config.CaptureCH[1].CPValue = TIMER_GetREGValue_CR(TIMER1, CPCH1);
(Timer1Config.CaptureCH[1].Fnpr)((void *)Timer1Config.CaptureCH[1].FnprArg);
}
if (IntStatus & TIMERCR2Int)
{
Timer1Config.CaptureCH[2].CPValue = TIMER_GetREGValue_CR(TIMER1, CPCH2);
(Timer1Config.CaptureCH[2].Fnpr)((void *)Timer1Config.CaptureCH[2].FnprArg);
}
if (IntStatus & TIMERCR3Int)
{
Timer1Config.CaptureCH[3].CPValue = TIMER_GetREGValue_CR(TIMER1, CPCH3);
(Timer1Config.CaptureCH[3].Fnpr)((void *)Timer1Config.CaptureCH[3].FnprArg);
}
VICVectAddr = 0; // Clear interrupt in VIC.
}