This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Compiler/UCD3138064EVM-166: UCD3138064EVM-166 Program

Part Number: UCD3138064EVM-166
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.
}


  • Hello,

    Your question has been forwarded to the appropriate engineer.

    Thanks,

    Amiel

  • I can't really debug your program for you. You just say it works and doesn't work, so presumably when you just leave both DPWM pins out of I/O mode, you get the same signal on both. If this is true, then you either have an issue with the ADC reading or with the disabling of the DPWM pins, or both. I'd suggest debugging one at a time. First see if the ADC is working, and the Ic value is changing properly with the input signal. You can do this using the open loop board and a voltage source. Or you could set up an I/O pin to be high when the Ic value is above .5, and low when it is below. This is good for dynamic testing.

    Then test the I/O enable/disable independently as well.

    Probably you've already done this and it's running?