?? lh79520_pwm_driver.c
字號:
/***********************************************************************
* $Workfile: lh79520_pwm_driver.c $
* $Revision: 1.0 $
* $Author: LiJ $
* $Date: Jul 07 2003 16:40:00 $
*
* Project: LH79520 PWM driver
*
* Description:
* This file contains driver support for the PWM module on the
* LH79520
*
* Revision History:
* $Log: //smaicnt2/pvcs/VM/sharpmcu/archives/sharpmcu/software/csps/lh79520/source/lh79520_pwm_driver.c-arc $
*
* Rev 1.0 Jul 07 2003 16:40:00 LiJ
* 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 "lh79520_rcpc.h"
#include "lh79520_iocon.h"
#include "lh79520_pwm_driver.h"
/***********************************************************************
* PWM driver private data
**********************************************************************/
/* PWM device configuration structure */
STATIC PWM_CFG_T pwmcfg;
/***********************************************************************
* PWM driver public functions
**********************************************************************/
#define PWM_RCPC_PRESCALE(n) (_BITMASK(15) & (n))
/***********************************************************************
*
* Function: pwm_open
*
* Purpose: Open the PWM controller
*
* Processing:
* If init is not FALSE, return 0x00000000 to the caller. Otherwise,
* return a pointer to the PWM config structure to the caller.
*
* Parameters:
* ipbase: PWM descriptor device address
* arg : Not used
*
* Outputs: None
*
* Returns: The pointer to a PWM config structure or 0
*
* Notes: None
*
**********************************************************************/
INT_32 pwm_open(void *ipbase, INT_32 arg)
{
INT_32 status = 0;
if ((pwmcfg.init == FALSE) && ((PWM_REGS_T *) ipbase == PWM))
{
/* Device is valid and not previously initialized */
pwmcfg.init = TRUE;
/* Save and return address of peripheral block */
pwmcfg.regptr = (PWM_REGS_T *) ipbase;
/* Return pointer to PWM configuration structure */
status = (INT_32) &pwmcfg;
}
return status;
}
/***********************************************************************
*
* Function: pwm_close
*
* Purpose: Close the PWM controller
*
* Processing:
* If init is not TRUE, then return _ERROR to the caller as the
* device was not previously opened. Otherwise, disable the PWM, set
* init to FALSE, and return _NO_ERROR to the caller.
*
* Parameters:
* devid: Pointer to PWM config structure
*
* Outputs: None
*
* Returns: The status of the close operation
*
* Notes: None
*
**********************************************************************/
STATUS pwm_close(INT_32 devid)
{
PWM_CFG_T *pwmcfgptr = (PWM_CFG_T *) devid;
STATUS status = _ERROR;
if (pwmcfgptr->init == TRUE)
{
status = _NO_ERROR;
pwmcfgptr->init = FALSE;
}
return status;
}
/***********************************************************************
*
* Function: pwm_ioctl
*
* Purpose: PWM configuration block
*
* Processing:
* This function is a large case block. Based on the passed function
* and option values, set or get the appropriate PWM
* parameter.
*
* Parameters:
* devid: Pointer to PWM config structure
* cmd: ioctl command
* arg: ioctl argument
*
* Outputs: None
*
* Returns: The status of the ioctl operation
*
* Notes: None
*
**********************************************************************/
STATUS pwm_ioctl(INT_32 devid,
INT_32 cmd,
INT_32 arg)
{
PWM_REGS_T *pwm;
PWM_CFG_T *pwmcfgptr = (PWM_CFG_T *) devid;
STATUS status = _ERROR;
UNS_32 pclk, pwm0clk, pwm1clk,prescale;
UNS_32 div;
UNS_16 period;
UNS_32 duty_cycle, prev_dc, prev_dc_percent;
if (pwmcfgptr->init == TRUE)
{
status = _NO_ERROR;
pwm = pwmcfgptr->regptr;
switch (cmd)
{
case PWM0_ENABLE:
/* Enable PWM0 output, arg = 1, enable PWM0. arg = 1,
disable PWM0 */
if (arg == 1)
{
RCPC->periphclkctrl &= ~RCPC_CLKCTRL_PWM0_DISABLE;
/* Prescaler for PWM0 is 1 in RCPC on enable */
RCPC->pwm0prescale = PWM_RCPC_PRESCALE(1);
IOCON->miscmux |= MISCMUX_PWM0;
/* Normal output */
PWM0->sync = PWM_SYNC_NORMAL;
}
else if (arg == 0)
{
RCPC->periphclkctrl |= RCPC_CLKCTRL_PWM0_DISABLE;
RCPC->pwm0prescale = 0x1;
IOCON->miscmux &= ~MISCMUX_PWM0;
}
else
{
status = _ERROR;
}
break;
case PWM1_ENABLE:
/* Enable PWM1 output, arg = 1, enable PWM1. arg = 1,
disable PWM1 */
if (arg == 1)
{
RCPC->periphclkctrl &= ~RCPC_CLKCTRL_PWM1_DISABLE;
RCPC->pwm1prescale = PWM_RCPC_PRESCALE(1);
IOCON->miscmux |= MISCMUX_PWM1;
}
else if (arg == 0)
{
RCPC->periphclkctrl |= RCPC_CLKCTRL_PWM1_DISABLE;
RCPC->pwm1prescale = 0x1;
IOCON->miscmux &= ~MISCMUX_PWM1;
}
else
{
status = _ERROR;
}
break;
case PWM0_SET_MODE:
/* Set PWM0 working mode, arg = 1, PWM0 working as synchronous
mode, output start sync. with SYNC pin. arg = 0, PWM0 working
in normal mode */
if (arg == 1)
{
PWM0->sync = PWM_SYNC_SYNC;
IOCON->miscmux |= MISCMUX_PWM0SYNC;
}
else if (arg == 0)
{
PWM0->sync = PWM_SYNC_NORMAL;
}
else
{
status = _ERROR;
}
break;
case PWM0_START:
/* Start PWM0 output, no arg */
PWM0->en = PWM_EN_ENABLE;
break;
case PWM0_STOP:
/* Stop PWM0 output, no arg */
PWM0->en = ~PWM_EN_ENABLE;
break;
case PWM1_START:
/* Start PWM1 output, no arg */
PWM1->en = PWM_EN_ENABLE;
break;
case PWM1_STOP:
/* Stop PWM1 output, no arg */
PWM1->en = ~PWM_EN_ENABLE;
break;
case PWM0_SET_FREQ:
/* Set PWM0 frequency, arg = is the frequency in Hz */
pclk = (CLOCK_MAINOSC * 21)/(RCPC->hclkprescale * 2);
prescale = RCPC->pwm0prescale;
if (prescale > 0)
{
pwm0clk = pclk / (prescale * 2);
}
else
{
//this should not happen
status = _ERROR;
break;
}
div = pwm0clk / arg;
while (div > 32768 && prescale <= 32768)
{
prescale += 1;
RCPC->pwm0prescale = prescale;
pwm0clk = pclk / (prescale * 2);
div = pwm0clk / arg;
}
PWM0->tc = div;
break;
case PWM0_SET_DUTY_CYCLE:
/* Set PWM0 duty cycle, arg = 1 to 100 for 1% to 100 % */
period = (UNS_16) PWM0->tc;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -