Hello,
I have been trying to get the Training Lab 4 (closed loop control of DPWM's) to work for the past few days with no success. I have tried writing to various different registers etc. but cannot get closed loop control to work. I see a burst of pulses for a very short time (very narrow pulses for about 10ms's) before they completely die off. I'm not sure what I'm doing wrong, I have followed everything on the training videos word for word, including setting up the jumpers on the UCD3138 development board. Lab 2 and 3 work well, and I am able to fully control the code...so I know my development environment is set up correct. I will really appreciate some help on this as I am trying to implement this closed loop code into my project. I have attached the code below.
#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"
#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]
void init_dpwm0(void)
{
Dpwm0Regs.DPWMCTRL0.bit.PWM_EN = 0; // disable locally for init
Dpwm0Regs.DPWMCTRL0.bit.CLA_EN = 1; // default is 1 - use cla
Dpwm0Regs.DPWMPRD.all = PERIOD; // use .all for all values, so that the scaling matches
Dpwm0Regs.DPWMEV1.all = EVENT1; // set EVENT 1 to 0% (start) of period
Dpwm0Regs.DPWMEV2.all = EVENT2; // set EVENT 2 to 25% of period
Dpwm0Regs.DPWMEV3.all = EVENT3; // set EVENT 3 to 50% of period
Dpwm0Regs.DPWMEV4.all = EVENT4; // set EVENT 4 to 75% of period
Dpwm0Regs.DPWMSAMPTRIG1.all = (PERIOD * 3)/4; //3/4 of period
Dpwm0Regs.DPWMCTRL2.bit.SAMPLE_TRIG_1_EN = 1; //enable 1 sample trigger
Dpwm0Regs.DPWMCTRL1.bit.EVENT_UP_SEL = 1; //update at end of period
Dpwm0Regs.DPWMCTRL0.bit.PWM_MODE = 0; //normal mode (this is NOT the default)
Dpwm0Regs.DPWMCTRL0.bit.PWM_EN = 1; // enable DPWM0 locally
}
void init_filter0(void)
{ //PID setup taken from a random topology - lab is for closing loop, not tuning parameters.
//Filter0Regs.FILTERCTRL.bit.USE_CPU_SAMPLE = 1; // enable CPU Sample
//Filter0Regs.CPUXN.bit.CPU_SAMPLE = 200; // set to 1/4
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.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 main()
{
// enable JTAG
MiscAnalogRegs.IOMUX.all = 0;
//---------------------------------------------------------------------------
// IMPORTANT: READ BELOW, OR CODE MAY NOT EXECUTE CORRECTLY
//---------------------------------------------------------------------------
// tie pin FAULT3 to ground for normal operation
// tie pin FAULT3 to 3.3V to clear checksum
//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_filter0();
init_loop_mux();
init_front_end0();
global_enable();
ram_eadcdac = 1000;//FeCtrl0Regs.EADCDAC.bit.DAC_VALUE; //initialize hyperknob
/* GioRegs.FAULTINTENA.bit.FLT2_INT_EN = 1;
GioRegs.FAULTDIR.bit.FLT2_DIR = 0;
GioRegs.FAULTIN.bit.FLT2_IN = 0; //1 - Fault pin must be driven High. 0 - Driven Low to trigger Interrupt
GioRegs.FAULTINTPOL.bit.FLT2_INT_POL = 0; //Interrupt will be generated on 1 = Rising Edge, 0 = Falling Edge
disable_interrupt();
disable_fast_interrupt(); //make sure fast interrupt is disabled
write_reqmask( CIMINT_ALL_FAULT_PIN); //enable pwm2cmp and DPWM0 interrupt(End of 16th period)(int-priority29)
write_firqpr (CIMINT_ALL_FAULT_PIN); // DPWM0 interrupt(End of 16th period) is mapped to FIQ
enable_fast_interrupt();
enable_interrupt();
MiscAnalogRegs.GLBIOEN.bit.DPWM1A_IO_EN = 1;
MiscAnalogRegs.GLBIOOE.bit.DPWM1A_IO_OE = 1;
MiscAnalogRegs.GLBIOVAL.bit.DPWM1A_IO_VALUE = 0;*/
for(;;)
{
pmbus_handler();
FeCtrl0Regs.EADCDAC.bit.DAC_VALUE = ram_eadcdac+1; //put hyperknob value into register
}
}
//#pragma INTERRUPT(c_int00,RESET)
void c_int00(void)
{
main();
}