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. 
}