etpu_pwm.c

来自「mpc55**系列芯片的例程 包括SCI,SPI,TIMER,FIT,EDMA」· C语言 代码 · 共 261 行

C
261
字号
/**************************************************************************
 * FILE NAME: $RCSfile: etpu_pwm.c,v $       COPYRIGHT (c) FREESCALE 2004 *
 * DESCRIPTION:                                     All Rights Reserved   *
 * This file contains the eTPU Pulse Width Modulation(PWM) API.           *
 *========================================================================*
 * ORIGINAL AUTHOR: Jeff Loeliger (r12110)                                *
 * $Log: etpu_pwm.c,v $
 * Revision 2.0  2004/12/22 13:46:31  r12110
 * -First release into CVS.
 * -Added support for utils 2.0 functions.
 *
 *........................................................................*
 * 0.1   J. Loeliger  16/Sep/03  Initial version.                         *
 * 0.8   J. Loeliger  19/Jul/04   Fixed pwm_update need to use coherent   *
 *                                 update HSR.                            *
 * 0.9   J. Loeliger  20/Jul/04   Updated for new eTPU code, added masks  *
 *                                 for acceses to period parameter.       *
 **************************************************************************/
#include "etpu_util.h"		    /* Utility routines for working eTPU */
#include "etpu_pwm.h"			/* eTPU PWM API defines */
extern uint32_t fs_etpu_data_ram_start;

/******************************************************************************
FUNCTION     : fs_etpu_pwm_init
PURPOSE      : To initialize an eTPU channel to generate a PWM output.
INPUTS NOTES : This function has 7 parameters:
               channel - This is the channel number.
                          0-31 for FS_ETPU_A and 64-95 for FS_ETPU_B.
               freq - This is the frequency of the PWM. This is an unint32_t
                        but the value range is only 24 bits. The range of
                        this parameter is determine by the complete system but
                        normally would be between 1Hz-100kHz.
               duty - This is the initial duty cycle of the PWM. This is a
                        uint16_t with a range of 0-10000. To represent 0-100%
                        with 0.01% resolution.
               priority - This is the priority to assign to the channel.
                          This parameter should be assigned a value of:
                          FS_ETPU_PRIORITY_HIGH, FS_ETPU_PRIORITY_MIDDLE or
                          FS_ETPU_PRIORITY_LOW.
               polarity - This is the polarity of the channel. This parameter
                            should be assigned a value of:
                            FS_ETPU_PWM_ACTIVEHIGH or FS_ETPU_PWM_ACTIVELOW
               timebase - This is the timer to use as a reference for the PWM
                         signal. This parameter should be assigned to a value
                         of: FS_ETPU_TCR1 or FS_ETPU_TCR2.
               timebase_freq - This is the frequency of the selected timebase.
                 The range of this is the same as the range of the timebase
                 frequency on the device. This parameter is a uint32_t.
RETURNS NOTES: Error code if channel could not be initialized. Error code that
                 can be returned are: FS_ETPU_ERROR_MALLOC ,
                 FS_ETPU_ERROR_FREQ
WARNING      : *This function does not configure the pin only the eTPU. In a
                  system a pin may need to be configured to select the eTPU.
******************************************************************************/
int32_t fs_etpu_pwm_init( uint8_t channel, uint8_t priority, uint32_t freq, 
      uint16_t duty, uint8_t polarity, uint8_t timebase, uint32_t timebase_freq)
{
    uint32_t *pba;	/* parameter base address for channel */
    uint32_t chan_period;

	/* Disable channel to assign function safely */
	fs_etpu_disable( channel );

    if (eTPU->CHAN[channel].CR.B.CPBA == 0 )
    {
        /* get parameter RAM
        number of parameters passed from eTPU C code */
        pba = fs_etpu_malloc(FS_ETPU_PWM_NUM_PARMS);

    	if (pba == 0)
    	{
    		return (FS_ETPU_ERROR_MALLOC);
    	}
    }
    else /*set pba to what is in the CR register*/
    {
    	pba=fs_etpu_data_ram(channel);
    }

    /* Determine frequency of output waveform */
	chan_period = timebase_freq / freq;

	if ((chan_period == 0) || (chan_period > 0x007FFFFF ))
		return( FS_ETPU_ERROR_FREQ);

	/* write parameters to data memory */
	*(pba + ((FS_ETPU_PWM_PERIOD_OFFSET - 1)>>2)) = chan_period;
	*(pba + ((FS_ETPU_PWM_ACTIVE_OFFSET - 1)>>2))  = 
			(chan_period * duty) / 10000;

	/* write channel configuration register */
	eTPU->CHAN[channel].CR.R = (priority << 28) + 
				(FS_ETPU_PWM_TABLE_SELECT << 24) +
	                        (FS_ETPU_PWM_FUNCTION_NUMBER << 16) +
	                        (((uint32_t)pba - fs_etpu_data_ram_start)>>3);

	/* write FM (function mode) bits */
	eTPU->CHAN[channel].SCR.R = (timebase << 1) + polarity;

	/* write hsr to start channel running */
	eTPU->CHAN[channel].HSRR.R = FS_ETPU_PWM_INIT;

	return(0);
}

/******************************************************************************
FUNCTION     : fs_etpu_pwm_duty
PURPOSE      : To update a channel dutycycle using a 16 bit integer value. The
                 ineteger value is the percentage *100, so 20% would be 2000.
INPUTS NOTES : This function has 2 parameters:
               channel - This is the channel number.
                           0-31 for FS_ETPU_A and 64-95 for FS_ETPU_B.
               duty - This is the duty cycle of the PWM. This is a
                        uint16 with a range of 0-10000. To represent 0-100%
                        with 0.01% resolution.
RETURNS NOTES: none
WARNING      :
******************************************************************************/
void fs_etpu_pwm_duty( uint8_t channel, uint16_t duty)
{
	uint32_t *pba;
	uint32_t period;

	pba = fs_etpu_data_ram (channel);

	period = *(pba + FS_ETPU_PWM_PERIOD_OFFSET-1);
	period = period & 0xFFFFFF;

	pba += ((FS_ETPU_PWM_ACTIVE_OFFSET-1)>>2);
	*pba = (period * duty) / 10000;

}

/******************************************************************************
FUNCTION     : fs_etpu_pwm_duty_immed
PURPOSE      : To immedately update a channel dutycycle using a 16 bit integer value.
                This function will update the dutycycle during the current period
                if possible. The ineteger value is the percentage *100, so 20% would
                be 2000.
INPUTS NOTES : This function has 2 parameters:
               channel - This is the channel number.
                           0-31 for FS_ETPU_A and 64-95 for FS_ETPU_B.
               duty - This is the duty cycle of the PWM. This is a
                        uint16 with a range of 0-10000. To represent 0-100%
                        with 0.01% resolution.
******************************************************************************/
void fs_etpu_pwm_duty_immed( uint8_t channel, uint16_t duty)
{
	uint32_t *pba;
	uint32_t period;

	pba = fs_etpu_data_ram (channel);

	period = *(pba + FS_ETPU_PWM_PERIOD_OFFSET-1);

	pba += ((FS_ETPU_PWM_ACTIVE_OFFSET-1)>>2);
	period = period & 0xFFFFFF;
	*pba = (period * duty) / 10000;

	/* do immediate update of duty cycle is possible */
	eTPU->CHAN[channel].HSRR.R = FS_ETPU_PWM_IMM_UPDATE;

}

/******************************************************************************
FUNCTION     : fs_etpu_pwm_update
PURPOSE      : To update a PWM output's frequency and dutycycle
INPUTS NOTES : This function has 6 parameters:
               channel - This is the channel number.
                           0-31 for FS_ETPU_A and 64-95 for FS_ETPU_B.
               freq - This is the frequency of the PWM. This is an unint32_t
                        but the value range is only 24 bits. The range of
                        this parameter is determine by the complete system but
                        normally would be between 1Hz-100kHz.
               duty - This is the initial duty cycle of the PWM. This is a
                        uint16_t with a range of 0-10000. To represent 0-100%
                        with 0.01% resolution.
               timebase_freq - This is the frequency of the selected timebase.
                 The range of this is the same as the range of the timebase
                 frequency on the device. This parameter is a uint32_t.
RETURNS NOTES: Error code if frequency is out of range: FS_ETPU_ERROR_FREQ
******************************************************************************/
int32_t fs_etpu_pwm_update( uint8_t channel, uint32_t freq, uint16_t duty, 
       uint32_t timebase_freq)
{
	uint32_t *pba;
	uint32_t chan_period;

	pba = fs_etpu_data_ram (channel);

    /* Determine frequency of output waveform */
	chan_period = timebase_freq / freq;

	if ((chan_period == 0) || (chan_period > 0x007FFFFF ))
		return( FS_ETPU_ERROR_FREQ);

	/* write parameters to data memory */
	*(pba + ((FS_ETPU_PWM_CO_PERIOD_OFFSET - 1)>>2)) = chan_period;
	*(pba + ((FS_ETPU_PWM_CO_ACTIVE_OFFSET - 1)>>2))  = (chan_period * duty) / 10000;

	eTPU->CHAN[channel].HSRR.R = FS_ETPU_PWM_CO_UPDATE;

}

/******************************************************************************
FUNCTION     : fs_etpu_pwm_get_freq
PURPOSE      : To determine the actual frequency by the PWM channel.
INPUTS NOTES : This function has 1 parameters:
               channel - This is the channel number.
                           0-31 for FS_ETPU_A and 64-95 for FS_ETPU_B.
               timebase_freq - This is the frequency of the selected timebase.
                 The range of this is the same as the range of the timebase
                 frequency on the device. This parameter is a uint32_t.
RETURNS NOTES: The actual frequency as an integer.
WARNING      :
******************************************************************************/
uint32_t fs_etpu_pwm_get_freq( uint8_t channel, uint32_t timebase_freq)
{
	uint32_t chan_period;
	uint32_t *pba;

	pba = fs_etpu_data_ram (channel);

	chan_period = *(pba + ((FS_ETPU_PWM_PERIOD_OFFSET - 1)>>2));
	chan_period = chan_period & 0xFFFFFF;

	return( timebase_freq / chan_period );

}

/*********************************************************************
 *
 * Copyright:
 *	Freescale Semiconductor, INC. All Rights Reserved.
 *  You are hereby granted a copyright license to use, modify, and
 *  distribute the SOFTWARE so long as this entire notice is
 *  retained without alteration in any modified and/or redistributed
 *  versions, and that such modified versions are clearly identified
 *  as such. No licenses are granted by implication, estoppel or
 *  otherwise under any patents or trademarks of Freescale
 *  Semiconductor, Inc. This software is provided on an "AS IS"
 *  basis and without warranty.
 *
 *  To the maximum extent permitted by applicable law, Freescale
 *  Semiconductor DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
 *  INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
 *  PARTICULAR PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
 *  REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
 *  AND ANY ACCOMPANYING WRITTEN MATERIALS.
 *
 *  To the maximum extent permitted by applicable law, IN NO EVENT
 *  SHALL Freescale Semiconductor BE LIABLE FOR ANY DAMAGES WHATSOEVER
 *  (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
 *  BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER
 *  PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.
 *
 *  Freescale Semiconductor assumes no responsibility for the
 *  maintenance and support of this software
 ********************************************************************/

⌨️ 快捷键说明

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