📄 lh7a400_timer_driver.c
字号:
/**********************************************************************
* $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 + -