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

📄 lh79520_pwm_driver.c

📁 Sharp Lh79520 PWM驱动源码.
💻 C
📖 第 1 页 / 共 2 页
字号:
/***********************************************************************
 * $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 + -