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

📄 lh7a400_timer_driver.c

📁 在sharp 404开发板的串口测试代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/***********************************************************************
 * $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 + -