||
自己整理的CC2640的PWM驱动,目前只写了两通道,其它通道设置相同,欢迎测试,先做个备份,回头详细整理:
/**************************************************************************************************
Filename: cc2640_pwm.c
Revised: $Date: 2016-10-01 11:43:11 -0700 (Sat, 01 Otc 2016) $
Revision: R00
Author: Mark Xu / QQ:2912615383
Description: This file contains the pwm driver for cc2640
Copyright 2009 - 2016 Mark Xu Work Studio. All rights reserved.
**************************************************************************************************/
#include <ti/sysbios/family/arm/cc26xx/Power.h>
#include <ti/sysbios/family/arm/cc26xx/PowerCC2650.h>
#include <driverlib/timer.h>
#include <ti/drivers/pin/PINCC26XX.h>
#include <hal_types.h>
/* the output Pin*/
#define PWM_CHAN_TIM0A_PIN IOID_3
#define PWM_CHAN_TIM0B_PIN IOID_4
/* the initial value of the duty */
#define PWM_TIM0A_INIT_DUTY 500
#define PWM_TIM0B_INIT_DUTY 500
/* the frequence of the PWM */
#define PWM_FREQUENCE 250000ul
#define PWM_TIM_LOAD_VAL (uint32_t)(48000000ul / PWM_FREQUENCE)
#define PWM_METCH_VAL(X) (uint32_t)(PWM_TIM_LOAD_VAL * (1000 - X) / 1000)
PIN_Config PWMPinTable[] =
{
PWM_CHAN_TIM0A_PIN | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_INPUT_DIS | PIN_DRVSTR_MAX,
PWM_CHAN_TIM0B_PIN | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_INPUT_DIS | PIN_DRVSTR_MAX,
PIN_TERMINATE
};
static PIN_Handle pinHandle;
static PIN_State pinState;
static bool PWM_Init_Flag = false;
/**************************************************************************************************
* @fn board_pwm_init
*
* @brief pwm initial
*
* @param None
*
* @return None
**************************************************************************************************/
void board_pwm_init(void)
{
if(!PWM_Init_Flag)
{
PWM_Init_Flag =true;
// Initial the port
pinHandle = PIN_open(&pinState, PWMPinTable);
//RTOS: Enable peripheral domain and clocks for timer
Power_setDependency(PERIPH_GPT0);
PINCC26XX_setMux(pinHandle, PWM_CHAN_TIM0A, IOC_PORT_MCU_PORT_EVENT0);
PINCC26XX_setMux(pinHandle, PWM_CHAN_TIM0B, IOC_PORT_MCU_PORT_EVENT1);
TimerConfigure(GPT0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PWM | TIMER_CFG_B_PWM);
HWREG(GPT0_BASE + GPT_O_CTL) &= ~(GPT_CTL_TAEN | GPT_CTL_TBEN); /* stop the pwm */
HWREG(GPT0_BASE + GPT_O_TAILR) = PWM_TIM_LOAD_VAL;
HWREG(GPT0_BASE + GPT_O_TAMATCHR) = PWM_METCH_VAL(PWM_TIM0A_INIT_DUTY);
HWREG(GPT0_BASE + GPT_O_TBILR) = PWM_TIM_LOAD_VAL;
HWREG(GPT0_BASE + GPT_O_TBMATCHR) = PWM_METCH_VAL(PWM_TIM0B_INIT_DUTY);
HWREG(GPT0_BASE + GPT_O_CTL) |= (GPT_CTL_TAEN|GPT_CTL_TBEN); /* start to pwm*/
}
}
/**************************************************************************************************
* @fn pwm_onoff_ctrl
*
* @brief contol the pwm
*
* @param sw - the action
*
* the data type timPwmDef defined as below:
* typedef enum {
* TIM0A_ON=0,
* TIM0A_OFF,
* TIM0B_ON,
* TIM0B_OFF,
* TIM0AB_ON,
* TIM0AB_OFF
* }pwmSwDef;
*
* @return None
**************************************************************************************************/
void pwm_onoff_ctrl(pwmSwDef sw)
{
switch(sw)
{
case TIM0A_ON:
HWREG(GPT0_BASE + GPT_O_CTL) |= GPT_CTL_TAEN;
break;
case TIM0A_OFF:
HWREG(GPT0_BASE + GPT_O_CTL) &= ~GPT_CTL_TAEN;
break;
case TIM0B_ON:
HWREG(GPT0_BASE + GPT_O_CTL) |= GPT_CTL_TBEN;
break;
case TIM0B_OFF:
HWREG(GPT0_BASE + GPT_O_CTL) &= ~GPT_CTL_TBEN;
break;
case TIM0AB_ON:
HWREG(GPT0_BASE + GPT_O_CTL) |= (GPT_CTL_TAEN|GPT_CTL_TBEN);
break;
case TIM0AB_OFF:
HWREG(GPT0_BASE + GPT_O_CTL) &= ~(GPT_CTL_TAEN|GPT_CTL_TBEN);
break;
}
}
/**************************************************************************************************
* @fn pwm_set_duty
*
* @brief set the pwm duty
*
* @param chan - the channel of the pwm
*
* the data type timPwmDef defined as below:
* typedef enum{
* TIM0A_CHAN=0,
* TIM0B_CHAN,
* }
* timPwmDef;
*
* duty - pwm duty,the value range is :0-1000
*
* @return None
**************************************************************************************************/
void pwm_set_duty(timPwmDef chan,uint16 duty)
{
if(chan == TIM0A_CHAN)
{
if(duty == 0)
HWREG(GPT0_BASE + GPT_O_TAMATCHR) = PWM_TIM_LOAD_VAL-1;
else if(duty == 1000)
HWREG(GPT0_BASE + GPT_O_TAMATCHR) = (uint32)1;
else
HWREG(GPT0_BASE + GPT_O_TAMATCHR) = PWM_METCH_VAL(duty);
}
else
{
if(duty == 0)
HWREG(GPT0_BASE + GPT_O_TBMATCHR) = PWM_TIM_LOAD_VAL-1;
else if(duty == 1000)
HWREG(GPT0_BASE + GPT_O_TBMATCHR) = (uint32)1;
else
HWREG(GPT0_BASE + GPT_O_TBMATCHR) = PWM_METCH_VAL(duty);
}
}