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