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

📄 lh79524_timer_driver.c

📁 SHARP_ARM720T_LH79524/5软件开发包_支持TFT_LCD_NAND_FLASH_ETH_USB
💻 C
📖 第 1 页 / 共 2 页
字号:
/***********************************************************************
 * $Workfile:   lh79524_timer_driver.c  $
 * $Revision:   1.0  $
 * $Author:   ZhangJ  $
 * $Date:   Oct 20 2004 09:48:56  $
 *
 * Project: LH79524 timer driver
 *
 * Description:
 *     This file contains driver support for the timer modules on the
 *     LH79524
 *
 * Revision History:
 * $Log::   //smaicnt2/pvcs/VM/sharpmcu/archives/sharpmcu/software/csps$
 * 
 *    Rev 1.0   Oct 20 2004 09:48:56   ZhangJ
 * Initial revision.
 * 
 *    Rev 1.1   Jul 20 2004 16:50:32   PattamattaD
 * Updated comments.
 * 
 *    Rev 1.0   Jun 15 2004 14:01:56   PattamattaD
 * Initial revision.
 * 
 * 
 * 
 ***********************************************************************
 * 
 *  Copyright (c) 2004 Sharp Microelectronics of the Americas 
 * 
 *  All rights reserved 
 * 
 *  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. 
 * 
 **********************************************************************/

#include "lh79524_rcpc.h"
#include "lh79524_timer_driver.h"

/* Defines for the ip block base address and driver control object */
#define REGS_T   TIMER_REGS_T
#define DRIVER_T TIMER_T

/* Forward declarations of private methods */
static void timer1_isr (void);
static void timer2_isr (void);
static void timer_default_isr (INT_32 devid);
static INT_32 timer_set_interval(TIMER_REGS_T* timer_regs, 
                    UNS_32 usec, UNS_32 xtal_in);

/* Table of device base addresses */
static UNS_32 driverid[N_TIMER] = 
{
/* Timer 1 Base Address */
    TIMER1_BASE,
/* Timer 2 Base Address */
    TIMER2_BASE
};
    
/* Instansiations of the driver control object */
static DRIVER_T driver[N_TIMER];

/* Address of the driver control objects */
static DRIVER_T* pdriver[N_TIMER] = 
{
    (DRIVER_T*)&driver[0],
    (DRIVER_T*)&driver[1]
};

/* Address of the driver interrupt handlers  */
static void* driver_isr[N_TIMER] =
{
    (void*)timer1_isr,
    (void*)timer2_isr
};

/***********************************************************************
 * 
 * Function: timer_open
 * 
 * Purpose: 
 *  Initialize the specified timer
 * 
 * Processing: 
 *  Sets up the device control structure for the timer.
 *
 * Parameters: 
 *  ipbase - ipbase is used as the device id
 *  arg    - optional default config flag
 * 
 * Outputs: 
 *  None
 * 
 * Returns: 
 *  device id or 0
 * 
 * Notes: 
 *  None
 * 
 **********************************************************************/

INT_32 timer_open (INT_32 ipbase, INT_32 arg)
{
  INT_32    dev_exists = FALSE;
  INT_32    devid      = 0;
  CHAR*     dst        = NULL;
  INT_32    idx        = 0;
  REGS_T*   pregs      = NULL;
  DRIVER_T* pdev       = NULL;      
  
  /* Find the device in the driver table */
  for (devid = 0; devid < NELEMENTS(driverid); devid++)
  {
    /* Do we have a match */
    if (ipbase == driverid[devid])
    {
      /* Found the device */
      dev_exists = TRUE;
      break;
    }
  }
  /* Check to make sure that the device exists */
  if (dev_exists == FALSE)
  {
    return (0);
  }
  
  /* Attach to the base address of the device */
  pdev = (DRIVER_T*)pdriver[devid];
  
  /* Make sure the device is not already opened */
  if (pdev->init == TRUE)
  {
    /* Device has already been opened */
    return (0);
  }
  
  /* Clear the driver control structure */
  dst = (CHAR*)pdev;
  for (idx = 0; idx < sizeof (DRIVER_T); idx++)
  {
    *dst++ = 0;
  }
  
  /* Attach to the base address of the selected uart */
  pdev->regs = (void*)driverid[devid];
  pregs      = (REGS_T*)pdev->regs;
  
  /* Mask all interrupts interrupts at the source */
  pregs->int_ctrl = ~TM12_INTCTRL_ALL;
  
  /* Clear the interrupt status register */
  pregs->status = TM12_INTCTRL_ALL;
  
  /* Save the default timer interrupt service routine */
  pdev->irq_hdlr = driver_isr[devid];
  
  /* Mark the device as open */
  pdev->init = TRUE;
  
  /* return device id */
  return ((INT_32)pdev);
}

/***********************************************************************
 * 
 * Function: timer_close
 * 
 * Purpose: 
 *  Turn the driver off
 * 
 * Processing: 
 *
 * Parameters: 
 *  devid - device id
 * 
 * Outputs: 
 *  None
 * 
 * Returns: 
 *  _NO_ERROR if device is closed successfully.
 *  _ERROR otherwise.
 * 
 * Notes: None
 * 
 **********************************************************************/

STATUS timer_close (INT_32 devid)
{
  STATUS    status = _NO_ERROR;
  INT_32    idx    = 0;
  CHAR*     dst    = NULL;
  DRIVER_T* pdev   = NULL;
  
  /* Sanity check */
  if (devid == 0)
  {
    /* device not opened or non-valid file handle */
    return (_ERROR);
  }
  
  /* Bind to the device control structure */
  pdev = (DRIVER_T*)devid;
  
  /* Make sure the device is already opened */
  if (pdev->init == FALSE)
  {
    return (_ERROR);
  }
  
  /* Stop the timer */
  (void) timer_ioctl (devid, TIMER_STOP, 0);
  
  /* Clear the counter */
  (void) timer_ioctl (devid, TIMER_CLEAR_CNT, 0);
  
  /* Disable all interrupts */
  (void) timer_ioctl (devid, TIMER_DISABLE_INT, TM0_INTCTRL_ALL);
  
  /* Invalidate the device */
  pdev->init = FALSE;
  
  /* Clear the serial driver control structure */
  dst = (CHAR*)pdev;
  for (idx = 0; idx < sizeof (DRIVER_T); idx++)
  {
    *dst++ = 0;
  }
  
  /* Done */
  return (status);
}

/***********************************************************************
 * 
 * Function: timer_read
 * 
 * Purpose: 
 *  Read the specified timer data.
 * 
 * Processing: 
 *
 * Parameters: 
 *  devid      - device id 
 *  buffer     - data buffer
 *  max_bytes  - maximum number of bytes to read
 * 
 * Outputs: 
 *  None
 * 
 * Returns: 
 *  n_bytes - the actual number of bytes read 
 *  
 * Notes: 
 *  Not supported with this driver
 * 
 **********************************************************************/

INT_32 timer_read (INT_32 devid, 
                   CHAR*  buffer, 
                   INT_32 max_bytes)
{
  /* Not supported with this driver */
  return (0);
}

/***********************************************************************
 * 
 * Function: timer_write
 * 
 * Purpose: 
 *  Write data to the timer.
 * 
 * Processing: 
 *
 * Parameters: 
 *  devid   - device id (UART0 or UART1)
 *  buffer  - data buffer 
 *  n_bytes - number of bytes to write.
 * 
 * Outputs: 
 *  None
 * 
 * Returns: 
 *  actual_bytes - number of bytes written.
 * 
 * Notes: 
 *  Not supported with this driver
 * 
 **********************************************************************/

INT_32 timer_write (INT_32 devid, 
                    CHAR*  buffer, 
                    INT_32 n_bytes)
{
  /* Not supported with this driver */
  return (0);
}

/***********************************************************************
 * 
 * Function: timer_ioctl
 * 
 * Purpose: 
 *  handle timert control requests.
 * 
 * Processing: Set/resets designated state in the device.
 *  
 *
 * Parameters:
 *  devid - device id
 *  cmd   - request to process
 *  arg   - generic argument 
 * 
 * Outputs: 
 *  None
 * 
 * Returns: 
 *  _NO_ERROR if device controlled successfully.
 *  _ERROR otherwise.
 * 
 * Notes: 
 *  None
 * 
 **********************************************************************/

STATUS timer_ioctl (INT_32 devid, 
                    INT_32 cmd, 
                    INT_32 arg)
{
  UNS_32    temp   = 0; 
  INT_32    status = _NO_ERROR; 
  REGS_T*   pregs  = NULL;
  DRIVER_T* pdev   = NULL;
  
  /* Sanity check */
  if (devid == 0)
  {
    /* Null pointer */
    return (0);
  }
  
  /* Attach to the base address of the driver */
  pdev = (DRIVER_T*)devid;
  
  /* Make sure the device is already opened */
  if (pdev->init == FALSE)
  {
    return (_ERROR);
  }
  
  /* Attach to the base address of the selected timer */
  pregs = (REGS_T*)pdev->regs;
  
  /* Service the users request */
  switch (cmd)
  {
    /* Start a timer */  
  case TIMER_START:
    /* Get the current contents on the register */
    temp = pregs->ctrl;
    /* Set the CS bit B[1] = 1 */
    temp |= _SBF(1,1);
    /* Update the register */
    pregs->ctrl = temp;
    break;
    /* Stop a timer */
  case TIMER_STOP:
    /* Get the current contents on the register */
    temp = pregs->ctrl;
    /* Clear the CS bit B[1] = 0 */
    temp &= ~_SBF(1,1);
    /* Update the register */
    pregs->ctrl = temp;
    break;
    /* Clear a counter */
  case TIMER_CLEAR_CNT:
    /* Get the current contents on the register */
    temp = pregs->ctrl;
    /* Set the CCL bit B[0] = 1 */
    temp |= _SBF(0,1);
    /* Update the register */
    pregs->ctrl = temp;
    break;
    /* Set the clock rate */
  case TIMER_SET_CLK_RATE:
    {
      UNS_32 running = 0;
      /* Get the current state */
      temp = pregs->ctrl;
      /* Save the current counter state (start/stop) */
      running = temp & _SBF(1,1);
      /* First stop the counter */
      /* Clear the CS bit B[1] = 0 */
      temp &= ~_SBF(1,1);
      /* Update the register */
      pregs->ctrl = temp;
      /* Set the new time base */
      temp = pregs->ctrl;
      /* Clear the current count clock bit field B[4:2] */
      temp &= ~_SBF(2,7); 
      /* Set up the new clock rate - set B[4:2] */
      temp |= _SBF(2,arg);
      /* Update the config structure */
      pdev->cfg.clock_rate = _SBF(2,arg);
      /* Restore the intial timer state (start/stop) */
      pregs->ctrl = (temp | running);
    }
    break;
    /* Set the clock rate */
  case TIMER_GET_CLK_RATE:
    /* Sanity check */
    if ((void*)arg == NULL)
    {
      status = _ERROR;
      break;
    }
    /* Return the driver interrupt service routine */
    *(INT_32*)arg = pdev->cfg.clock_rate;
    break;
    /* Enable PWM mode */
  case TIMER_SET_PWM_MODE:
    /* Get the current contents on the register */
    temp = pregs->ctrl;
    /* Clear the CMP1 and CMP0 fields B[13:12] and B[11:10] */
    temp &= ~(_SBF(12,3) | _SBF(10,3));
    temp |= _SBF(14,1) |  /* PWM bit set B[14] = 1 */
      _SBF(13,1)    |  /* TC bit set  B[13] = 1 */       
      _SBF(11,2)    |  /* CMP1 B[12:11] = 10    */
      _SBF(9,1);       /* CMP0 B[10:9]  = 01    */
    /* Update the register */

⌨️ 快捷键说明

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