⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lh7a400_timer_driver.c

📁 sharp flash blob 的烧写代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/**********************************************************************
 *	$Workfile:   LH7A400_timer_driver.c  $
 *	$Revision:   1.7  $
 *	$Author:   MaysR  $
 *	$Date:   Aug 01 2002 19:16:42  $
 *
 *	Project: LH7A400
 *
 *	Description:
 *      This file contains driver support for the timer modules 
 *      on the LH7A400. Except as noted, the following functions 
 *      work with TIMER1, TIMER2, or TIMER3
 *      timer_init() -- restore the timer to its reset default
 *      timer_irq_setup() -- install an IRQ handler function 
 *                           for this timer with a given priority
 *      timer_start() -- start the timer
 *      timer_stop() -- stop the timer
 *      timer_set_counts() -- setup the timer counts independent of
 *                            timer clock
 *      timer_clock_2k() -- for TIMER1 & TIMER2 only
 *                          make input clock approx 2kHz
 *      timer_clock_508k() -- for TIMER1 & TIMER2 only
 *                            make input clock approx 508kHz
 *      timer_set_delay() -- set the timer counts to overflow after a
 *                           specified number of microseconds. Return the
 *                           actual number of microseconds of delay. For
 *                           delays too large for a given timer, set the
 *                           maximum delay interval. If clock is selectable
 *                           use the fastest clock possible to get the
 *                           highest timing resolution.
 *      timer_get_delay() -- return the timer countdown interval for 
 *                           the specified timer in microseconds.
 *      timer_set_overflow_rate -- set the overflow rate in overflows
 *                                 per second and return the actual rate
 *      timer_get_overflow_rate -- return the overflow rate in overflows
 *                                 per second
 *      timer_periodic() -- specified timer automatically reloads the count
 *                          from the load register after timer overflow
 *      timer_free_run() -- timer count overflows from 0 to 0xffff
 *      timer_int_enable() -- enable the overflow interrupt for the 
 *                            specified timer
 *      timer_int_clear() -- clear the timer overflow flag for the 
 *                           specified timer
 *      timer_int_disable() -- disable the overflow interrupt for the
 *                             specified timer
 *      buzzer_high() -- set the buzzer output high.
 *      buzzer_low() -- set the buzzer output pin low
 *      buzzer_timer1() -- connect the buzzer output to a flip-flop that
 *                         is clocked on TIMER1 overflow.
 *      buzzer_squarewave_start() -- make the buzzer ouput a square wave
 *                                with a specified period in microseconds.
 *                                This function consumes TIMER1 and
 *                                disables any TIMER1 interrupts.   
 *      buzzer_squarewave_stop() -- This function stops TIMER1 and
 *                                  immmediately makes the buzzer output
 *                                  low.
 *
 *	References:
 *
 * Requires;
 *   LH7A400_int_driver.h and all files included by it.
 *
 *	Revision History:
 *	$Log:   //smaicnt2/pvcs/VM/CHIPS/archives/LH7A400/Timer/Drivers/LH7A400_timer_driver.c-arc  $
 * 
 *    Rev 1.7   Aug 01 2002 19:16:42   MaysR
 * Added int_init_irq_handler(0) call to timer_irq_setup function.
 * Corrected tab spacing.
 * 
 *    Rev 1.6   Jun 19 2002 16:58:30   BarnettH
 * Changed all INTR_xxx to INTR_xxx_BIT
 * 
 *    Rev 1.5   Jun 13 2002 11:13:34   MaysR
 * Changed constant labels to corrolate with changes to interrupt
 * driver.
 * Fixed compile warnings.
 * 
 *    Rev 1.4   Jan 04 2002 16:44:12   KovitzP
 * Added a functions to set and get timer overflows per second.
 * 
 *    Rev 1.3   Nov 30 2001 13:43:40   KovitzP
 * Got buzzer functions for setting the buzzer bit high and wiring it
 * to Timer1 backwards.
 * 
 *    Rev 1.2   Nov 20 2001 09:59:48   KovitzP
 * Added function description blocks. Added timer argument
 * checking to functions that didn't have it. Fixed argument
 * checking bugs on timer_clock_2k() and timer_clock_508k()
 * 
 *    Rev 1.1   Nov 13 2001 16:30:08   KovitzP
 * Added dependencies to comments.
 * 
 *    Rev 1.0   Nov 13 2001 16:19:32   KovitzP
 * Initial revision.
 * 
 *
 *	COPYRIGHT (C) 2001 SHARP MICROELECTRONICS OF THE AMERICAS, INC.
 *		CAMAS, WA
 *********************************************************************/
#include "LH7A400_timer_driver.h"
#include "LH7A400_int_driver.h"

/**********************************************************************
*
* Function: timer_init
*
* Purpose:
*  restore the timer to its reset default
*
* Processing:
*  if the timer argument is a valid TIMER, then make sure
*  the timer is off, clear the count, disable the
*  timer interrupt, and clear any pending timer interrupt.
*
* Parameters:
*  timer: Must be one of TIMER1, TIMER2 or TIMER3 as defined in
*         LH7A400_map.h
*
* Outputs: None
*
* Returns: Nothing
*
* Notes:
*
**********************************************************************/
void timer_init(TIMERREGS * timer)
{
    if (timer == TIMER1 ||
        timer == TIMER2 ||
        timer == TIMER3)
    {
        timer->control = 0;
        timer->load = 0;
        timer_int_disable(timer);
        timer_int_clear(timer);
    }
}

/**********************************************************************
*
* Function: timer_irq_setup
*
* Purpose:
*  install an IRQ handler function for this timer with 
*  a given priority
*
* Processing:
*  If the timer parameter is valid, call int_install_irq_handler()
*  with the appropriate interrupt controller source bit; pass along
*  the priority argument and the handler argument. 
*  If the timer argument not a valid TIMER, do nothing.
*
* Parameters: 
*  timer:    Must be one of TIMER1, TIMER2 or TIMER3 as defined in
*            LH7A400_map.h
*  priority: The interrupt priority
*  handler:  A pointer to the handler function.
* 
* Outputs: None
*
* Returns: Nothing
*
* Notes:
*
**********************************************************************/
void timer_irq_setup(TIMERREGS * timer, 
                     INT_32 priority, 
                     void (*handler)(void) )
{
    if (timer == TIMER1 || timer == TIMER2 || timer == TIMER3)
        int_init_irq_handler(0);
    if (timer == TIMER1)
        int_install_irq_handler(INTC_TC1OINTR_BIT, priority, handler);
    else if (timer == TIMER2)
        int_install_irq_handler(INTC_TC2OINTR_BIT, priority, handler);
    else if (timer == TIMER3)
        int_install_irq_handler(INTC_TC3OINTR_BIT, priority, handler);
}

/**********************************************************************
*
* Function: timer_start
*
* Purpose:
*   start the timer
*
* Processing:
*  If the timer argument is a valid timer, set the enable bit in
*  the timer control register. Otherwise, do nothing.
*
* Parameters: 
*  timer: Must be one of TIMER1, TIMER2 or TIMER3 as defined in
*         LH7A400_map.h
*
* Outputs: None
*
* Returns: Nothing
*
* Notes:
*
**********************************************************************/
void timer_start(TIMERREGS * timer)
{
    if (timer == TIMER1 ||
        timer == TIMER2 ||
        timer == TIMER3)
    {
        timer->control |= TIMER_CTRL_ENABLE;
    }
}

/**********************************************************************
*
* Function: timer_stop
*
* Purpose:
*   stop the timer
*
* Processing:
*  If the timer argument is a valid timer, clear the enable bit in
*  the timer control register. Otherwise, do nothing.
*
* Parameters: 
*  timer: Must be one of TIMER1, TIMER2 or TIMER3 as defined in
*         LH7A400_map.h
*
* Outputs: None
*
* Returns: Nothing
*
* Notes:
*
**********************************************************************/
void timer_stop(TIMERREGS * timer)
{
    if (timer == TIMER1 ||
        timer == TIMER2 ||
        timer == TIMER3)
    {
        timer->control &= ~TIMER_CTRL_ENABLE;
    }
}

/**********************************************************************
*
* Function: timer_set_counts
*
* Purpose:
*  setup the timer counts independent of timer clock
*
* Processing:
*  If the timer argument is a valid timer, set the timer load register
*  to the counts argument. Otherwise, do nothing.
*
* Parameters: 
*  timer:  Must be one of TIMER1, TIMER2 or TIMER3 as defined in
*          LH7A400_map.h
*  counts: Number of timer clocks that must occur befor the timer
*          overflows.
*
* Outputs: None
*
* Returns: Nothing
*
* Notes:
*
**********************************************************************/
void timer_set_counts(TIMERREGS * timer, UNS_16 counts)
{
    if (timer == TIMER1 ||
        timer == TIMER2 ||
        timer == TIMER3)
    {
        timer->load = counts;
    }
}

/**********************************************************************
*
* Function: timer_clock_2k
*
* Purpose:
*  for TIMER1 & TIMER2 only make input clock approx 2kHz
*
* Processing:
*  If the timer is TIMER1 or TIMER2, clear the TIMER_CTRL_508K bit
*
* Parameters: 
*  timer: Must be one of TIMER1, TIMER2 as defined in
*         LH7A400_map.h
*
* Outputs: None
*
* Returns: Nothing
*
* Notes:
*
**********************************************************************/
void timer_clock_2k(TIMERREGS * timer)
{
    if (timer == TIMER1 ||
        timer == TIMER2)
    {
        timer->control &= ~TIMER_CTRL_508K;
    }
}

/**********************************************************************
*
* Function: timer_clock_508k
*
* Purpose:
*  for TIMER1 & TIMER2 only make input clock approx 508kHz
*
* Processing:
*  If the timer is TIMER1 or TIMER2, set the TIMER_CTRL_508K bit
*
* Parameters: 
*  timer: Must be one of TIMER1, TIMER2 as defined in
*         LH7A400_map.h
*
* Outputs: None
*
* Returns: Nothing
*
* Notes:
*
**********************************************************************/
void timer_clock_508k(TIMERREGS * timer)
{
    if (timer == TIMER1 ||
        timer == TIMER2)
    {
        timer->control |= TIMER_CTRL_508K;
    }
}

/**********************************************************************
*
* Function: timer_set_delay
*
* Purpose:
*   set the timer counts to overflow after a specified number of
*   microseconds.
*
* Processing:
*  TIMER3 is clocked differently from TIMER1 and TIMER2, so treat each
*  separately. For TIMER1 or TIMER2, first convert the time in
*  microseconds to counts per 508 kHz clock tick. If the time interval
*  is too long to be obtained using the 508 kHz clock, convert the time
*  in microseconds to counts per 2 kHz clock tick. If the time interval
*  is too long to be obtained using the 2 kHz clock, set the count
*  interval to the maximum possible count.
*
*  For TIMER3, convert the time in microseconds to counts per
*  (roughly) 7.4MHz clock tick. If the time interval is too long
*  to be obtained using TIMER3, set the count to the maximum possible
*  count.
*  
*  Finally, for all timers, return timer_get_delay() to return the
*  actual interval or return 0 if the timer parameter was not
*  TIMER1, TIMER2, or TIMER3.
*
* Parameters: 
*  timer:      Must be one of TIMER1, TIMER2 or TIMER3 as defined in
*              LH7A400_map.h
*  time_in_us: The desired delay in microseconds
*
* Outputs: None
*
* Returns:
*  The actual delay interval that will result given the clocking
*  options. If the interval in microseconds is longer than it is
*  possible to generate with the given timer, the longest possible
*  interval is returned. Return 0 if the timer is invalid.
*
* Notes:
*
**********************************************************************/
UNS_32 timer_set_delay(TIMERREGS * timer, UNS_32 time_in_us)
{
   /* use double-precision integer arithmetic */
   INT_64 counts;
   
    if (timer == TIMER1 || timer == TIMER2)
    {
      /* set up counts */
        timer_clock_508k(timer);
        counts = (((INT_64)CLKSC_TIMER_SEL1_CLK 
                  * (INT_64)time_in_us) / (INT_64)1000000) - 1;
        if (counts != TIMER_LOAD(counts) )
        {
            timer_clock_2k(timer);
            counts = (((INT_64)CLKSC_TIMER_SEL0_CLK 
                      * (INT_64)time_in_us) / (INT_64)1000000) - 1;
            if (counts != TIMER_LOAD(counts) )
            {
            /* delay interval is too long to happen on this timer */
                counts = TIMER_LOAD(0xffff);
            }
        }
    }
    else if (timer == TIMER3)
    {
      /* choose the only available time base */
        counts = (((INT_64)CLKSC_TIMER3_CLK 
                  * (INT_64)time_in_us) / (INT_64)1000000) - 1;
        if (counts != TIMER_LOAD(counts ) )
        {
         /* delay interval is too long to happen on this timer */
            counts = TIMER_LOAD(0xffff);
        }
    }
    else
        return 0; /* illegal timer */

    timer->load = (UNS_32)(TIMER_LOAD(counts - 1));
    return timer_get_delay(timer);
}

/**********************************************************************
*
* Function: timer_get_delay
*
* Purpose:
*  return the timer countdown interval for the specified timer 
*  in microseconds.
*
* Processing:
*  If timer is TIMER1, TIMER2, or TIMER3, figure out number of
*  counts per second (the timer clock as currently configured).
*  Divide the timer load value by the counts per second and multiply
*  by 1 million to get the interval in microseconds.
*
* Parameters: 
*  timer: Must be one of TIMER1, TIMER2 or TIMER3 as defined in

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -