📄 lh7a400_timer_driver.c
字号:
/***********************************************************************
* $Workfile: lh7a400_timer_driver.c $
* $Revision: 1.1 $
* $Author: WellsK $
* $Date: Aug 13 2003 10:54:58 $
*
* Project: LH7A400 timer driver
*
* Description:
* This file contains driver support for the timer modules on the
* LH7A400
*
* Revision History:
* $Log: //smaicnt2/pvcs/VM/sharpmcu/archives/sharpmcu/software/csps/lh7a400/source/lh7a400_timer_driver.c-arc $
*
* Rev 1.1 Aug 13 2003 10:54:58 WellsK
* Corrected logic for timer_wait_us function.
*
* Rev 1.0 Jun 09 2003 16:52:26 WellsK
* Initial revision.
*
*
***********************************************************************
* SHARP MICROELECTRONICS OF THE AMERICAS MAKES NO REPRESENTATION
* OR WARRANTIES WITH RESPECT TO THE PERFORMANCE OF THIS SOFTWARE,
* AND SPECIFICALLY DISCLAIMS ANY RESPONSIBILITY FOR ANY DAMAGES,
* SPECIAL OR CONSEQUENTIAL, CONNECTED WITH THE USE OF THIS SOFTWARE.
*
* SHARP MICROELECTRONICS OF THE AMERICAS PROVIDES THIS SOFTWARE SOLELY
* FOR THE PURPOSE OF SOFTWARE DEVELOPMENT INCORPORATING THE USE OF A
* SHARP MICROCONTROLLER OR SYSTEM-ON-CHIP PRODUCT. USE OF THIS SOURCE
* FILE IMPLIES ACCEPTANCE OF THESE CONDITIONS.
*
* COPYRIGHT (C) 2001 SHARP MICROELECTRONICS OF THE AMERICAS, INC.
* CAMAS, WA
**********************************************************************/
#include "lh7a400_timer_driver.h"
/***********************************************************************
* Timer clock frequencies
**********************************************************************/
/* Timer 3 clock source */
#define TIMER3_CLK (CLOCK_MAINOSC / 2)
/* Timers 1 and 2 2KHz clock source */
#define TIMER12_CLK2K (CLOCK_MAINOSC / 7373)
/* Timers 1 and 2 508KHz clock source */
#define TIMER12_CLK508K (CLOCK_MAINOSC / 29)
/* Number of microSeconds in a second */
#define USEC_PER_SEC 1000000
/***********************************************************************
* Timer driver private data and types
**********************************************************************/
/* Timer device configuration structure type */
typedef struct
{
BOOL_32 init; /* Device initialized flag */
TIMER_REGS_T *regptr; /* Pointer to Timer registers */
} TIMER_CFG_T;
/* Timer device configuration structure */
STATIC TIMER_CFG_T timer1cfg, timer2cfg, timer3cfg;
/***********************************************************************
* Timer driver private functions
**********************************************************************/
/***********************************************************************
*
* Function: timer_set_delay
*
* Purpose: Set timer delay (undeflow) value in 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.
*
* Parameters:
* timer : Must be TIMER1, TIMER2 or TIMER3
* time_in_us : The desired delay in microseconds
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: None
*
**********************************************************************/
STATIC void timer_set_delay(TIMER_REGS_T *timer,
UNS_32 time_in_us)
{
INT_64 count;
UNS_32 tmp;
if ((timer == TIMER1) || (timer == TIMER2))
{
/* Check if timing is possible with a 508KHz clock first */
tmp = timer->control & ~(TIMER_CTRL_2K | TIMER_CTRL_508K);
count = ((((INT_64)TIMER12_CLK508K * (INT_64)time_in_us) /
(INT_64)USEC_PER_SEC)) - 1;
/* Is the count value to large for the timer load word? */
if (count > (INT_64)TIMER_MAXCOUNT)
{
/* Use the 2KHz timer instead */
count = ((((INT_64)TIMER12_CLK2K * (INT_64)time_in_us) /
(INT_64)USEC_PER_SEC)) - 1;
timer->control = tmp | (TIMER_CTRL_2K |
TIMER_CTRL_PERIODIC);
}
else
{
timer->control = tmp | (TIMER_CTRL_508K |
TIMER_CTRL_PERIODIC);
}
timer->load = (UNS_32)(TIMER_LOAD(count));
}
else if (timer == TIMER3)
{
count = ((((INT_64)TIMER3_CLK * (INT_64)time_in_us) /
(INT_64)USEC_PER_SEC)) - 1;
timer->load = (UNS_32)(TIMER_LOAD(count));
}
}
/***********************************************************************
* Timer driver public functions
**********************************************************************/
/***********************************************************************
*
* Function: timer_open
*
* Purpose: Open the timer
*
* Processing:
* Determine the timer configuration structure to use based on the
* passed arg value. If the arg value doesn't match an available
* timer, return NULL to the caller. Otherwise, check the status of
* the init flag. If it is TRUE, return NULL to the caller.
* Otherwise, set init to TRUE and save the pointer to the timer
* registers. Disable the timer and set the timer base clock to
* 2KHz (Timer 3 only supports 7.4MHz) and freerunning mode. Clear
* any pending timer interrupts. If this is timer 1, set the BZTOG
* output low. Return the pointer to the UART config structure to
* the caller.
*
* Parameters:
* ipbase: Pointer to a timer peripheral block
* arg : Not used
*
* Outputs: None
*
* Returns: The pointer to a timer config structure or NULL
*
* Notes: None
*
**********************************************************************/
INT_32 timer_open(void *ipbase, INT_32 arg)
{
TIMER_CFG_T *timercfg;
if ((TIMER_REGS_T *) ipbase == TIMER1)
{
/* Timer 1 selected */
timercfg = &timer1cfg;
}
else if ((TIMER_REGS_T *) ipbase == TIMER2)
{
/* Timer 2 selected */
timercfg = &timer2cfg;
}
else if ((TIMER_REGS_T *) ipbase == TIMER3)
{
/* Timer 3 selected */
timercfg = &timer3cfg;
}
else
{
/* Invalid timer */
timercfg = (TIMER_CFG_T *) NULL;
}
if (timercfg != (TIMER_CFG_T *) NULL)
{
/* Valid timer selected, has it been previously initialized? */
if (timercfg->init == FALSE)
{
/* Device not initialized and it usable, so set it to
used */
timercfg->init = TRUE;
/* Save address of register block */
timercfg->regptr = (TIMER_REGS_T *) ipbase;
/* Set default timer state to disabled, 2KHz clock - timer
3 only supports 7.37MHz and the extra bits do nothing */
timercfg->regptr->control = (TIMER_CTRL_DISABLE |
TIMER_CTRL_FREERUN | TIMER_CTRL_2K);
/* Clear pending interrupt */
timercfg->regptr->clear = 0x00000000;
/* Disable buzzer on timer 1 only (TBUZ driven low) */
if ((TIMER_REGS_T *) ipbase == TIMER1)
{
BZCONT = 0x00000000;
}
}
}
return (INT_32) timercfg;
}
/***********************************************************************
*
* Function: timer_close
*
* Purpose: Close the timer
*
* Processing:
* If init is not TRUE, then return _ERROR to the caller as the
* device was not previously opened. Otherwise, disable the timer,
* set init to FALSE, and return _NO_ERROR to the caller.
*
* Parameters:
* devid: Pointer to timer config structure
*
* Outputs: None
*
* Returns: The status of the close operation
*
* Notes: None
*
**********************************************************************/
STATUS timer_close(INT_32 devid)
{
TIMER_CFG_T *timercfgptr = (TIMER_CFG_T *) devid;
STATUS status = _ERROR;
if (timercfgptr->init == TRUE)
{
/* Disable timer */
timercfgptr->regptr->control = TIMER_CTRL_DISABLE;
/* Set timer as uninitialized */
timercfgptr->init = FALSE;
/* Successful operation */
status = _NO_ERROR;
}
return status;
}
/***********************************************************************
*
* Function: timer_ioctl
*
* Purpose: Timer configuration block
*
* Processing:
* This function is a large case block. Based on the passed function
* and option values, set or get the appropriate timer parameter.
*
* Parameters:
* devid: Pointer to timer config structure
* cmd: ioctl command
* arg: ioctl argument
*
* Outputs: None
*
* Returns: The status of the ioctl operation
*
* Notes: None
*
**********************************************************************/
STATUS timer_ioctl(INT_32 devid,
INT_32 cmd,
INT_32 arg)
{
TIMER_REGS_T *timerregs;
TIMER_CFG_T *timercfgptr = (TIMER_CFG_T *) devid;
STATUS status = _ERROR;
if (timercfgptr->init == TRUE)
{
status = _NO_ERROR;
timerregs = timercfgptr->regptr;
switch (cmd)
{
case TIMER_ENABLE:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -