289 lines
10 KiB
C
289 lines
10 KiB
C
/* ==================================================================================
|
|
File name: F281XPWM.C
|
|
|
|
Originator: Digital Control Systems Group
|
|
Texas Instruments
|
|
|
|
Description: This file contains source for the Full Compare PWM drivers for the F281x
|
|
|
|
Target: TMS320F281x family
|
|
|
|
=====================================================================================
|
|
History:
|
|
-------------------------------------------------------------------------------------
|
|
04-15-2005 Version 3.20: Using DSP281x v. 1.00 or higher
|
|
----------------------------------------------------------------------------------*/
|
|
|
|
#include "DSP281x_Examples.h" // DSP281x Examples Include File
|
|
#include "DSP281x_Device.h" // DSP281x Headerfile Include File
|
|
#include "IQmathLib.h"
|
|
|
|
#include <f281xpwm.h>
|
|
|
|
#include "DSP281x_Ev.h"
|
|
//#include "params.h"
|
|
|
|
|
|
void F281X_EV1_PWM_Init(PWMGEN *p)
|
|
{
|
|
EvaRegs.T1PR = p->PeriodMax; // Init Timer 1 period Register
|
|
EvaRegs.T1CON.all = PWM_INIT_STATE; // Symmetrical Operation
|
|
EvaRegs.DBTCONA.all = DBTCON_INIT_STATE; // Init DBTCONA Register
|
|
EvaRegs.ACTRA.all = ACTR_INIT_STATE; // Init ACTRA Register
|
|
|
|
EvaRegs.COMCONA.all = 0xA600; // Init COMCONA Register
|
|
|
|
EvaRegs.CMPR1 = p->PeriodMax; // Init CMPR1 Register
|
|
EvaRegs.CMPR2 = p->PeriodMax; // Init CMPR2 Register
|
|
EvaRegs.CMPR3 = p->PeriodMax; // Init CMPR3 Register
|
|
EALLOW; // Enable EALLOW
|
|
GpioMuxRegs.GPAMUX.all |= 0x003F; // Setting PWM1-6 as primary output pins
|
|
EDIS; // Disable EALLOW
|
|
}
|
|
|
|
|
|
void F281X_EV1_PWM_Update(PWMGEN *p)
|
|
{
|
|
int16 MPeriod;
|
|
int32 Tmp;
|
|
|
|
// Compute the timer period (Q0) from the period modulation input (Q15)
|
|
Tmp = (int32)p->PeriodMax*(int32)p->MfuncPeriod; // Q15 = Q0*Q15
|
|
MPeriod = (int16)(Tmp>>16) + (int16)(p->PeriodMax>>1); // Q0 = (Q15->Q0)/2 + (Q0/2)
|
|
EvaRegs.T1PR = MPeriod;
|
|
|
|
// Compute the compare 1 (Q0) from the PWM 1&2 duty cycle ratio (Q15)
|
|
Tmp = (int32)MPeriod*(int32)p->MfuncC1; // Q15 = Q0*Q15
|
|
EvaRegs.CMPR1 = (int16)(Tmp>>16) + (int16)(MPeriod>>1); // Q0 = (Q15->Q0)/2 + (Q0/2)
|
|
|
|
// Compute the compare 2 (Q0) from the PWM 3&4 duty cycle ratio (Q15)
|
|
Tmp = (int32)MPeriod*(int32)p->MfuncC2; // Q15 = Q0*Q15
|
|
EvaRegs.CMPR2 = (int16)(Tmp>>16) + (int16)(MPeriod>>1); // Q0 = (Q15->Q0)/2 + (Q0/2)
|
|
|
|
// Compute the compare 3 (Q0) from the PWM 5&6 duty cycle ratio (Q15)
|
|
Tmp = (int32)MPeriod*(int32)p->MfuncC3; // Q15 = Q0*Q15
|
|
EvaRegs.CMPR3 = (int16)(Tmp>>16) + (int16)(MPeriod>>1); // Q0 = (Q15->Q0)/2 + (Q0/2)
|
|
}
|
|
|
|
|
|
void F281X_EV2_PWM_Init(PWMGEN *p)
|
|
{
|
|
EvbRegs.T3PR = p->PeriodMax; // Init Timer 1 period Register
|
|
EvbRegs.T3CON.all = PWM_INIT_STATE; // Symmetrical Operation
|
|
EvbRegs.DBTCONB.all = DBTCON_INIT_STATE; // Init DBTCONA Register
|
|
EvbRegs.ACTRB.all = ACTR_INIT_STATE; // Init ACTRA Register
|
|
|
|
EvbRegs.COMCONB.all = 0xA600; // Init COMCONA Register
|
|
|
|
EvbRegs.CMPR4 = p->PeriodMax; // Init CMPR1 Register
|
|
EvbRegs.CMPR5 = p->PeriodMax; // Init CMPR2 Register
|
|
EvbRegs.CMPR6 = p->PeriodMax; // Init CMPR3 Register
|
|
EALLOW; // Enable EALLOW
|
|
GpioMuxRegs.GPBMUX.all |= 0x003F; // Setting PWM1-6 as primary output pins
|
|
EDIS; // Disable EALLOW
|
|
}
|
|
|
|
|
|
void F281X_EV2_PWM_Update(PWMGEN *p)
|
|
{
|
|
int16 MPeriod;
|
|
int32 Tmp;
|
|
|
|
// Compute the timer period (Q0) from the period modulation input (Q15)
|
|
Tmp = (int32)p->PeriodMax*(int32)p->MfuncPeriod; // Q15 = Q0*Q15
|
|
MPeriod = (int16)(Tmp>>16) + (int16)(p->PeriodMax>>1); // Q0 = (Q15->Q0)/2 + (Q0/2)
|
|
EvbRegs.T3PR = MPeriod;
|
|
|
|
// Compute the compare 1 (Q0) from the PWM 1&2 duty cycle ratio (Q15)
|
|
Tmp = (int32)MPeriod*(int32)p->MfuncC1; // Q15 = Q0*Q15
|
|
EvbRegs.CMPR4 = (int16)(Tmp>>16) + (int16)(MPeriod>>1); // Q0 = (Q15->Q0)/2 + (Q0/2)
|
|
|
|
// Compute the compare 2 (Q0) from the PWM 3&4 duty cycle ratio (Q15)
|
|
Tmp = (int32)MPeriod*(int32)p->MfuncC2; // Q15 = Q0*Q15
|
|
EvbRegs.CMPR5 = (int16)(Tmp>>16) + (int16)(MPeriod>>1); // Q0 = (Q15->Q0)/2 + (Q0/2)
|
|
|
|
// Compute the compare 3 (Q0) from the PWM 5&6 duty cycle ratio (Q15)
|
|
Tmp = (int32)MPeriod*(int32)p->MfuncC3; // Q15 = Q0*Q15
|
|
EvbRegs.CMPR6 = (int16)(Tmp>>16) + (int16)(MPeriod>>1); // Q0 = (Q15->Q0)/2 + (Q0/2)
|
|
|
|
}
|
|
|
|
|
|
|
|
void F281X_EVD_PWM_Init(PWMGEND *p)
|
|
{
|
|
//unsigned int pna=0,pnb=0;
|
|
|
|
EvaRegs.T1PR = p->PeriodMax; // Init Timer 1 period Register
|
|
|
|
#ifdef DOUBLE_UPDATE_PWM
|
|
EvaRegs.T1CON.all = PWM_INIT_STATE_DOUBLE_UPADTE; // Symmetrical Operation + DOUBLE UPDATE
|
|
#else
|
|
EvaRegs.T1CON.all = PWM_INIT_STATE; // Symmetrical Operation
|
|
#endif
|
|
|
|
EvaRegs.DBTCONA.all = DBTCON_INIT_STATE; // Init DBTCONA Register
|
|
EvaRegs.ACTRA.all = ACTR_INIT_STATE; // Init ACTRA Register
|
|
|
|
EvaRegs.COMCONA.all = 0xa600;//0xA600; // Init COMCONA Register
|
|
|
|
EvaRegs.CMPR1 = p->PeriodMax; // Init CMPR1 Register
|
|
EvaRegs.CMPR2 = p->PeriodMax; // Init CMPR2 Register
|
|
EvaRegs.CMPR3 = p->PeriodMax; // Init CMPR3 Register
|
|
EALLOW; // Enable EALLOW
|
|
GpioMuxRegs.GPAMUX.all |= 0x003F; // Setting PWM1-6 as primary output pins
|
|
EDIS; // Disable EALLOW
|
|
|
|
|
|
EvbRegs.T3PR = p->PeriodMax; // Init Timer 1 period Register
|
|
|
|
#ifdef DOUBLE_UPDATE_PWM
|
|
EvbRegs.T3CON.all = PWM_INIT_STATE_DOUBLE_UPADTE; // Symmetrical Operation + DOUBLE UPDATE
|
|
#else
|
|
EvbRegs.T3CON.all = PWM_INIT_STATE; // Symmetrical Operation
|
|
#endif
|
|
|
|
EvbRegs.DBTCONB.all = DBTCON_INIT_STATE; // Init DBTCONA Register
|
|
EvbRegs.ACTRB.all = ACTR_INIT_STATE; // Init ACTRA Register
|
|
|
|
EvbRegs.COMCONB.all = 0xa600;//0xA600; // Init COMCONA Register
|
|
|
|
EvbRegs.CMPR4 = p->PeriodMax; // Init CMPR1 Register
|
|
EvbRegs.CMPR5 = p->PeriodMax; // Init CMPR2 Register
|
|
EvbRegs.CMPR6 = p->PeriodMax; // Init CMPR3 Register
|
|
EALLOW; // Enable EALLOW
|
|
GpioMuxRegs.GPBMUX.all |= 0x003F; // Setting PWM1-6 as primary output pins
|
|
EDIS; // Disable EALLOW
|
|
// pna = p->ShiftPhaseA;//(p->PeriodMax);
|
|
// pnb = p->ShiftPhaseB;
|
|
|
|
|
|
EvaRegs.T1CNT = 0x0000;
|
|
EvbRegs.T3CNT = 0x0000;
|
|
|
|
}
|
|
|
|
#pragma CODE_SECTION(set_predel_dshim,".fast_run");
|
|
int16 set_predel_dshim(int16 dshim,int16 dmin,int16 dpwm)
|
|
{
|
|
if (dshim < dmin)
|
|
{
|
|
dshim = dmin;
|
|
}
|
|
|
|
if (dshim > (dpwm - dmin) )
|
|
{
|
|
dshim = (dpwm - dmin);
|
|
}
|
|
return dshim;
|
|
}
|
|
|
|
#pragma CODE_SECTION(set_predel_dshim_max,".fast_run");
|
|
int16 set_predel_dshim_max(int16 dshim,int16 dmin,int16 dpwm)
|
|
{
|
|
int d2;
|
|
|
|
/*
|
|
if (dshim < dmin)
|
|
{
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
if (dshim > (dpwm - dmin) )
|
|
{
|
|
// dshim = (dpwm + 1);
|
|
return (dpwm + 10);
|
|
}
|
|
else
|
|
return dshim;
|
|
|
|
}
|
|
*/
|
|
|
|
|
|
d2 = dmin/2;
|
|
|
|
if (dshim < d2)
|
|
{
|
|
dshim = 0;
|
|
return dshim;
|
|
}
|
|
|
|
if (dshim < dmin)
|
|
{
|
|
dshim = dmin;
|
|
return dshim;
|
|
}
|
|
|
|
|
|
if (dshim > (dpwm - d2) )
|
|
{
|
|
dshim = dpwm+dmin;
|
|
return dshim;
|
|
}
|
|
|
|
|
|
if (dshim > (dpwm - dmin) )
|
|
{
|
|
dshim = (dpwm - dmin);
|
|
return dshim;
|
|
}
|
|
|
|
return dshim;
|
|
|
|
|
|
}
|
|
|
|
|
|
//#pragma CODE_SECTION(F281X_EVD_PWM_Update,".fast_run");
|
|
void F281X_EVD_PWM_Update(PWMGEND *p)
|
|
{
|
|
int16 MPeriod, Dshim;
|
|
int32 Tmp;
|
|
|
|
|
|
// Compute the timer period (Q0) from the period modulation input (Q15)
|
|
Tmp = (int32)p->PeriodMax*(int32)p->MfuncPeriod; // Q15 = Q0*Q15
|
|
MPeriod = (int16)(Tmp>>16) + (int16)(p->PeriodMax>>1); // Q0 = (Q15->Q0)/2 + (Q0/2)
|
|
EvaRegs.T1PR = MPeriod;
|
|
|
|
// Compute the compare 1 (Q0) from the PWM 1&2 duty cycle ratio (Q15)
|
|
Tmp = (int32)MPeriod*(int32)p->MfuncC1; // Q15 = Q0*Q15
|
|
Dshim = (int16)(Tmp>>16) + (int16)(MPeriod>>1); // Q0 = (Q15->Q0)/2 + (Q0/2)
|
|
EvaRegs.CMPR1 = set_predel_dshim(Dshim,(int16)p->PeriodMin,(int16)MPeriod);
|
|
|
|
// Compute the compare 2 (Q0) from the PWM 3&4 duty cycle ratio (Q15)
|
|
Tmp = (int32)MPeriod*(int32)p->MfuncC2; // Q15 = Q0*Q15
|
|
Dshim = (int16)(Tmp>>16) + (int16)(MPeriod>>1); // Q0 = (Q15->Q0)/2 + (Q0/2)
|
|
EvaRegs.CMPR2 = set_predel_dshim(Dshim,(int16)p->PeriodMin,(int16)MPeriod);
|
|
|
|
// Compute the compare 3 (Q0) from the PWM 5&6 duty cycle ratio (Q15)
|
|
Tmp = (int32)MPeriod*(int32)p->MfuncC3; // Q15 = Q0*Q15
|
|
Dshim = (int16)(Tmp>>16) + (int16)(MPeriod>>1); // Q0 = (Q15->Q0)/2 + (Q0/2)
|
|
EvaRegs.CMPR3 = set_predel_dshim(Dshim,(int16)p->PeriodMin,(int16)MPeriod);
|
|
|
|
|
|
// Compute the timer period (Q0) from the period modulation input (Q15)
|
|
// Tmp = (int32)p->PeriodMax*(int32)p->MfuncPeriod; // Q15 = Q0*Q15
|
|
// MPeriod = (int16)(Tmp>>16) + (int16)(p->PeriodMax>>1); // Q0 = (Q15->Q0)/2 + (Q0/2)
|
|
EvbRegs.T3PR = MPeriod;
|
|
|
|
// Compute the compare 1 (Q0) from the PWM 1&2 duty cycle ratio (Q15)
|
|
Tmp = (int32)MPeriod*(int32)p->MfuncC4; // Q15 = Q0*Q15
|
|
Dshim = (int16)(Tmp>>16) + (int16)(MPeriod>>1); // Q0 = (Q15->Q0)/2 + (Q0/2)
|
|
EvbRegs.CMPR4 = set_predel_dshim(Dshim,(int16)p->PeriodMin,(int16)MPeriod);
|
|
|
|
// Compute the compare 2 (Q0) from the PWM 3&4 duty cycle ratio (Q15)
|
|
Tmp = (int32)MPeriod*(int32)p->MfuncC5; // Q15 = Q0*Q15
|
|
Dshim = (int16)(Tmp>>16) + (int16)(MPeriod>>1); // Q0 = (Q15->Q0)/2 + (Q0/2)
|
|
EvbRegs.CMPR5 = set_predel_dshim(Dshim,(int16)p->PeriodMin,(int16)MPeriod);
|
|
|
|
// Compute the compare 3 (Q0) from the PWM 5&6 duty cycle ratio (Q15)
|
|
Tmp = (int32)MPeriod*(int32)p->MfuncC6; // Q15 = Q0*Q15
|
|
Dshim = (int16)(Tmp>>16) + (int16)(MPeriod>>1); // Q0 = (Q15->Q0)/2 + (Q0/2)
|
|
EvbRegs.CMPR6 = set_predel_dshim(Dshim,(int16)p->PeriodMin,(int16)MPeriod);
|
|
|
|
}
|
|
|