Other Parts Discussed in Thread: UCD3138, UCD3138064
Tool/software: TI C/C++ Compiler
I am giving below my source code, which is for sensing Ic in AD0 and generating DPWM0B and DPWM1B as per the state of sensing parameter Ic. If Ic is greater than 0.5 then DPWM0B is generating switching signal and DPWM1B is on continuously and it is other way when Ic is less than 0.5. This program works fine when AD0 sensing is not included but does not give satisfactory result when sensing is included. Please help me to solve this problem.
#define MAIN 1
#include "system_defines.h"
#include "Cyclone_Device.h"
#include "pmbus_commands.h"
#include "pmbus_common.h"
#include "pmbus_topology.h"
#include "variables.h"
#include "functions.h"
#include "software_interrupts.h"
#include "cyclone_defines.h"
#include "stdio.h"
#include "math.h"
//#include "include.h"
#define PCLK_PERIOD 4.0e-9
#define PERIOD_SECONDS 10.0e-6
#define PERIOD ((int)(PERIOD_SECONDS/PCLK_PERIOD)<<4)
#define EVENT1 (int)(PERIOD*0.00)
#define EVENT2 (int)(PERIOD*0.25)
#define EVENT3 (int)(PERIOD*0.50)
#define EVENT4 (int)(PERIOD*0.75)
int ram_eadcdac;
// comment for hyperknob [min=0, max=16383, step=256]
Uint16 i;
int ram_cpu_sample,vout;
float ch1[334],sinth,wt,w,t;
//Uint32 Ic;
void init_ADC_polled(void)
{
AdcRegs.ADCCTRL.bit.MAX_CONV = 6; // A total of 5 conversions (0 to 4)
AdcRegs.ADCCTRL.bit.SINGLE_SWEEP = 1;
AdcRegs.ADCCTRL.bit.ADC_EN = 1;
AdcRegs.ADCSEQSEL0.bit.SEQ0 = 0; // ad00 AC-L order0
AdcRegs.ADCSEQSEL0.bit.SEQ1 = 2; // AD01 IIN
AdcRegs.ADCSEQSEL0.bit.SEQ2 = 3; // AD03 VB
AdcRegs.ADCSEQSEL0.bit.SEQ3 = 4; // ad04 AC-N
AdcRegs.ADCSEQSEL1.bit.SEQ4 = 6; // ad06 CT-1 order4
AdcRegs.ADCSEQSEL1.bit.SEQ5 = 7; // ad07 VB-OV
AdcRegs.ADCSEQSEL1.bit.SEQ6 = 13; // ad13 CT-2
AdcRegs.ADCSEQSEL1.bit.SEQ7 = 9; // ad09
AdcRegs.ADCSEQSEL2.bit.SEQ8 = 13; // ad13
AdcRegs.ADCAVGCTRL.bit.AVG0_CONFIG = 0; // Average 4 samples of ad06
AdcRegs.ADCAVGCTRL.bit.AVG0_EN = 1; // Module0 averaging enabled
AdcRegs.ADCAVGCTRL.bit.AVG1_CONFIG = 1; // Average 8 samples of AD02
AdcRegs.ADCAVGCTRL.bit.AVG1_EN = 1; // Module1 averaging enabled
AdcRegs.ADCAVGCTRL.bit.AVG2_CONFIG = 2; // Average 16 samples of AD04
AdcRegs.ADCAVGCTRL.bit.AVG2_EN = 1; // Module2 averaging enabled
AdcRegs.ADCAVGCTRL.bit.AVG3_CONFIG = 3; // Average 32 samples of ad06
AdcRegs.ADCAVGCTRL.bit.AVG3_EN = 1; // Module3 averaging enabled
AdcRegs.ADCAVGCTRL.bit.AVG4_CONFIG = 3; // Average 4 samples of ad08
AdcRegs.ADCAVGCTRL.bit.AVG4_EN = 1; // Module4 averaging enabled
AdcRegs.ADCAVGCTRL.bit.AVG5_CONFIG = 3; // Average 4 samples of ad08
AdcRegs.ADCAVGCTRL.bit.AVG5_EN = 1; // Module4 averaging enabled
AdcRegs.ADCCTRL.bit.SW_START = 1; // trigger a new measurement sequence
}
void init_dpwm0(void)
{
Dpwm0Regs.DPWMCTRL0.bit.PWM_EN = 0; //disable everything
Dpwm0Regs.DPWMCTRL1.bit.GPIO_A_EN = 1; //turn off DPWM1A for now
Dpwm0Regs.DPWMCTRL1.bit.GPIO_B_EN = 1; //turn off DPWM1B for now
// Enable CBC and Blanking windows
Dpwm0Regs.DPWMCTRL0.bit.CBC_PWM_AB_EN = 1; // Enable cycle by cycle current limit.
Dpwm0Regs.DPWMCTRL0.bit.BLANK_B_EN = 1; // Enable blanking
Dpwm0Regs.DPWMBLKBBEG.all = 0x0000;
Dpwm0Regs.DPWMBLKBEND.all = 0x0500;
Dpwm0Regs.DPWMFLTCTRL.bit.B_MAX_COUNT = 2;
Dpwm0Regs.DPWMFLTCTRL.bit.ALL_FAULT_EN = 1; //enable this for OVP
Dpwm0Regs.DPWMCTRL2.bit.SAMPLE_TRIG_1_EN = 1; //enable sample trigger1
Dpwm0Regs.DPWMCTRL0.bit.PWM_MODE = 3; //triangular mode
Dpwm0Regs.DPWMCTRL1.bit.EVENT_UP_SEL = 0; //update right away
Dpwm0Regs.DPWMCTRL0.bit.CLA_EN = 1;
Dpwm0Regs.DPWMCTRL0.bit.PWM_EN = 1;
Dpwm0Regs.DPWMPRD.all=PERIOD;// NEW
}
void init_dpwm1(void)
{
Dpwm1Regs.DPWMCTRL0.bit.PWM_EN = 0; //disable everything
Dpwm1Regs.DPWMCTRL1.bit.GPIO_A_EN = 1; //turn off DPWM1A for now
Dpwm1Regs.DPWMCTRL1.bit.GPIO_B_EN = 1; //turn off DPWM1B for now
// Enable CBC and Blanking windows
Dpwm1Regs.DPWMCTRL0.bit.CBC_PWM_AB_EN = 1; // Enable cycle by cycle current limit.
Dpwm1Regs.DPWMCTRL0.bit.BLANK_B_EN = 1; // Enable blanking
Dpwm1Regs.DPWMBLKBBEG.all = 0x0000;
Dpwm1Regs.DPWMBLKBEND.all = 0x0500;
Dpwm1Regs.DPWMFLTCTRL.bit.B_MAX_COUNT = 2;
Dpwm1Regs.DPWMFLTCTRL.bit.ALL_FAULT_EN = 1; //enable this for OVP
Dpwm1Regs.DPWMCTRL2.bit.SAMPLE_TRIG_1_EN = 1; //enable sample trigger1
Dpwm1Regs.DPWMCTRL0.bit.PWM_MODE = 3; //triangular mode
Dpwm1Regs.DPWMCTRL0.bit.MSYNC_SLAVE_EN = 0;//NEW
Dpwm1Regs.DPWMCTRL1.bit.EVENT_UP_SEL = 0; //update right away
Dpwm1Regs.DPWMCTRL2.bit.SAMPLE_TRIG1_MODE = 0;//NEW
Dpwm1Regs.DPWMCTRL0.bit.CLA_EN = 1;
Dpwm1Regs.DPWMCTRL0.bit.PWM_EN = 1;
Dpwm1Regs.DPWMPRD.all=PERIOD;// NEW
}
void init_dpwm2(void)
{
Dpwm2Regs.DPWMCTRL0.bit.PWM_EN = 0; // disable locally for init
//Dpwm1Regs.DPWMCTRL1.bit.GPIO_A_EN = 1; //turn off DPWM1A for now
//Dpwm1Regs.DPWMCTRL1.bit.GPIO_B_EN = 1; //turn off DPWM1B for now
Dpwm2Regs.DPWMCTRL0.bit.CLA_EN = 1; // default is 1 - use cla
Dpwm2Regs.DPWMPRD.all = PERIOD; // use .all for all values, so that the scaling matches
Dpwm2Regs.DPWMEV1.all = EVENT1; // set EVENT 1 to 0% (start) of period
Dpwm2Regs.DPWMEV2.all = EVENT2; // set EVENT 2 to 25% of period
Dpwm2Regs.DPWMEV3.all = EVENT3; // set EVENT 3 to 50% of period
Dpwm2Regs.DPWMEV4.all = EVENT4; // set EVENT 4 to 75% of period
Dpwm2Regs.DPWMSAMPTRIG1.all = (PERIOD * 3)/4; //3/4 of period
Dpwm2Regs.DPWMCTRL2.bit.SAMPLE_TRIG_1_EN = 1; //enable 1 sample trigger
Dpwm2Regs.DPWMCTRL1.bit.EVENT_UP_SEL = 1; //update at end of period
Dpwm2Regs.DPWMCTRL0.bit.PWM_MODE =0; //normal mode (this is NOT the default)
//Dpwm1Regs.DPWMCTRL1.bit.GPIO_A_EN =1; //turn off DPWM1A for now
//Dpwm1Regs.DPWMCTRL1.bit.GPIO_B_EN =1; //turn off DPWM1B for now
Dpwm2Regs.DPWMCTRL0.bit.PWM_EN =1; // enable DPWM0 locally
Dpwm2Regs.DPWMPRD.all=PERIOD;// NEW
}
void init_dpwm3(void)
{
Dpwm3Regs.DPWMCTRL0.bit.PWM_EN = 0; // disable locally for init
//Dpwm1Regs.DPWMCTRL1.bit.GPIO_A_EN = 1; //turn off DPWM1A for now
//Dpwm1Regs.DPWMCTRL1.bit.GPIO_B_EN = 1; //turn off DPWM1B for now
Dpwm3Regs.DPWMCTRL0.bit.CLA_EN = 1; // default is 1 - use cla
Dpwm3Regs.DPWMPRD.all = PERIOD; // use .all for all values, so that the scaling matches
Dpwm3Regs.DPWMEV1.all = EVENT1; // set EVENT 1 to 0% (start) of period
Dpwm3Regs.DPWMEV2.all = EVENT2; // set EVENT 2 to 25% of period
Dpwm3Regs.DPWMEV3.all = EVENT3; // set EVENT 3 to 50% of period
Dpwm3Regs.DPWMEV4.all = EVENT4; // set EVENT 4 to 75% of period
Dpwm3Regs.DPWMSAMPTRIG1.all = (PERIOD * 3)/4; //3/4 of period
Dpwm3Regs.DPWMCTRL2.bit.SAMPLE_TRIG_1_EN = 1; //enable 1 sample trigger
Dpwm3Regs.DPWMCTRL1.bit.EVENT_UP_SEL = 1; //update at end of period
Dpwm3Regs.DPWMCTRL0.bit.PWM_MODE =0; //normal mode (this is NOT the default)
//Dpwm1Regs.DPWMCTRL1.bit.GPIO_A_EN =1; //turn off DPWM1A for now
//Dpwm1Regs.DPWMCTRL1.bit.GPIO_B_EN =1; //turn off DPWM1B for now
Dpwm3Regs.DPWMCTRL0.bit.PWM_EN =1; // enable DPWM0 locally
Dpwm3Regs.DPWMPRD.all=PERIOD;// NEW
}
void init_filter0(void)
{ //PID setup taken from a random topology - lab is for closi ng loop, not tuning parameters.
Filter0Regs.FILTERKPCOEF0.bit.KP_COEF_0 = 800;
Filter0Regs.FILTERKICOEF0.bit.KI_COEF_0 = 50;
Filter0Regs.FILTERKDCOEF0.bit.KD_COEF_0 = 1500;
Filter0Regs.FILTERKDALPHA.bit.KD_ALPHA_0 = -1;
Filter0Regs.FILTERKICLPHI.bit.KI_CLAMP_HIGH = 0x7FFFFF;
Filter0Regs.FILTERKICLPLO.bit.KI_CLAMP_LOW = 0;
Filter0Regs.FILTEROCLPHI.bit.OUTPUT_CLAMP_HIGH = 0x7FFFFF;
Filter0Regs.FILTEROCLPLO.bit.OUTPUT_CLAMP_LOW = 0;
Filter0Regs.FILTERCTRL.bit.FILTER_EN = 1;
// enable OK here, because nothing will happen until DPWM and front end are globally enabled
// Better option for handling shoot through - uses full dynamic range of filter
LoopMuxRegs.FILTERKCOMPA.bit.KCOMP0 = (PERIOD/2) >> 4; // KCOMP is at 4 ns, period is at 250 ps
Filter0Regs.FILTERCTRL.bit.OUTPUT_MULT_SEL = 0; // select half period kcomp for output multiplier
}
void init_loop_mux(void)
{
LoopMuxRegs.DPWMMUX.bit.DPWM0_FILTER_SEL = 0; // use filter 0 for DPWM 0
LoopMuxRegs.SAMPTRIGCTRL.bit.FE0_TRIG_DPWM0_EN = 1; // use DPWM0 for filter0 sample trigger
}
void global_enable(void)
{
union GLBEN_REG glben_store; // collect global enable bits for simultaneous use
glben_store.all = 0;
glben_store.bit.DPWM0_EN = 1;
glben_store.bit.DPWM1_EN = 1;
glben_store.bit.DPWM2_EN = 1;
glben_store.bit.DPWM3_EN = 1;
glben_store.bit.FE_CTRL0_EN = 1;
LoopMuxRegs.GLBEN = glben_store;
}
void init_front_end0(void)
{
FeCtrl0Regs.EADCDAC.bit.DAC_VALUE = 0;
FeCtrl0Regs.EADCCTRL.bit.AFE_GAIN = 2;
}
void init_timer_interrupt(void)
{
TimerRegs.T16PWM0CMP0DAT.all = 312; //approx 50KHz. by spec
TimerRegs.T16PWM0CMP1DAT.all = 0xffff;
TimerRegs.T16PWM0CMPCTRL.all = 2;
TimerRegs.T16PWM0CNTCTRL.all = 0x00c;
//write_reqmask(CIMINT_ALL_FAULT_COMP); //enable pwm2cmp
//enable_interrupt();
disable_interrupt();
disable_fast_interrupt();
//interrupt_status = FaultMuxRegs.FAULTMUXINTSTAT.all;
//Configure IRQ
write_reqmask(CIMINT_ALL_FAULT_MUX|CIMINT_ALL_PWM0_COMP|CIMINT_ALL_PWM1_COMP);
//Configure FIQ
write_firqpr (CIMINT_ALL_FAULT_MUX);
//Enable interrupts
enable_interrupt();
enable_fast_interrupt();
}
void main()
{
MiscAnalogRegs.IOMUX.all = 0;
if(GioRegs.FAULTIN.bit.FLT3_IN == 1)
{
clear_integrity_word();
}
#if (UCD3138|UCD3138064)
MiscAnalogRegs.CLKTRIM.bit.HFO_LN_FILTER_EN = 0;
MiscAnalogRegs.CSTRIM.bit.RESISTOR_TRIM =23; //28;
#endif
init_pmbus(0x58); // initialize PMBus handler
init_dpwm0(); // initialize DPWM0
init_dpwm1(); // initialize DPWM1
init_dpwm2(); // initialize DPWM2
init_dpwm3(); // initialize DPWM3
init_filter0();
init_loop_mux();
init_front_end0();
global_enable();
init_timer_interrupt();
init_ADC_polled();
//string_out_0("\033[2J");
//init_uart();
ram_eadcdac = FeCtrl0Regs.EADCDAC.bit.DAC_VALUE; //initialize hyperknob
for(;;)
{
pmbus_handler();
FeCtrl0Regs.EADCDAC.bit.DAC_VALUE = ram_eadcdac; //put hyperknob value into register
}
}
#pragma INTERRUPT(c_int00,RESET)
void c_int00(void)
{
main();
}
/////////////////////////////////////////////////////////////
/// Standard interrupt /////////////
////////////////////////////////////////////////////////////
#include "system_defines.h"
#include "Cyclone_Device.h"
#include "pmbus_commands.h"
#include "pmbus_common.h"
#include "pmbus_topology.h"
#include "variables.h"
#include "functions.h"
#include "software_interrupts.h"
#include "cyclone_defines.h"
#include "stdio.h"
#include "math.h"
Uint32 Ic;
//#pragma CODE_STATE(standard_interrupt, 32) // this will ensure that this code builds in ARM mode
#pragma FUNC_ALWAYS_INLINE (poll_adc)
void poll_adc(void)
{
if(AdcRegs.ADCSTAT.bit.ADC_INT == 1)//If the conversion is not complete
{
Ic = AdcRegs.ADCAVGRESULT[0].bit.RESULT;
}
AdcRegs.ADCCTRL.bit.SW_START = 1; //RESTART
}
#pragma FUNC_ALWAYS_INLINE (rectify_vac)
inline rectify_vac(void)
{
Dpwm0Regs.DPWMCTRL1.bit.GPIO_B_EN = 1;
Dpwm1Regs.DPWMCTRL1.bit.GPIO_B_EN = 1;
LoopMuxRegs.FILTERMUX.bit.FILTER1_FE_SEL = 0; //use EADC2 to drive filter 1
// Ic = AdcRegs.ADCAVGRESULT[0].bit.RESULT;
if(Ic<0.5)
{
Dpwm0Regs.DPWMCTRL1.bit.GPIO_B_EN = 0; //now turn on neutral PWM
Dpwm1Regs.DPWMCTRL1.bit.GPIO_B_VAL = 1; //and then drive line always high
}
else
{
Dpwm0Regs.DPWMCTRL1.bit.GPIO_B_VAL = 1; //line drive low
Dpwm1Regs.DPWMCTRL1.bit.GPIO_B_EN = 0; //now disable neutral PWM
}
}
#pragma INTERRUPT(standard_interrupt,IRQ)
void standard_interrupt(void)
{
poll_adc();
rectify_vac();
FaultMuxRegs.ACOMPCTRL3.bit.ACOMP_G_THRESH = 21;
TimerRegs.T16PWM0CMPCTRL.all = 3; //clear interrupt bit by a read/write.
}