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.

CCS/TMDSDOCK28335: How to confirm that DF22 controller is working fine with TMDSDOCK28335?

Part Number: TMDSDOCK28335
Other Parts Discussed in Thread: SFRA, C2000WARE, CONTROLSUITE

Tool/software: Code Composer Studio

Sir,

I have calculated the Plant transfer function for the Boost Converter and also designed a type-2 compensator for the same using SISO tool in MATLAB. Then I have converted the Transfer function from s-domain to z-domain using ...... method and obtained the coefficients and also implemented in CCS with a DF22 controller. 

Please suggest me anyway to check the performance of this controller.

Regards,

Soumya

  • Soumya,

    There are several ways to do this. However nothing in DCL or elsewhere from TI is pre-configured so you will have some work to do.

    Assuming your original design specifications were in the frequency domain (i.e. pole-zero frequencies, for example), and you have an actual physical plant (i.e. you're not just simulating this), the best way is to connect the controller and measure the actual frequency response. You could attach a separate frequency analyzer instrument, or use the SFRA utility in the digital power SDK which allows you to do that without any external test equipment. It will measure the plant, open loop, and closed loop frequency responses as Bode plots. You can then compare the result curves with your original simulation to confirm you are getting what you expect.

    If you do not have a physical plant but do have a plant model, one way is to run a transient response test in Simuink, capture the controller input and output data, then run these through the controller on the device and compare with the original simulation. This will show the controller on the device is behaving exactly as the simulation does. It's complicated, but you can use the Simulink PID example in DCLv3 as a starting point. As you have already used SISOtool I'm assuming you are familiar with and have access to Simulink.

    You can find the Matlab file "PID_example.m" at:
    C:\ti\c2000\C2000Ware_1_00_05_00\libraries\control\DCL\c28\models
    You can modify this example to use the DF22 controller and your own plant. Open the DCL Simulink block set (DCL.slx in the same directory) from within the PID model. Find the DF22_C1 block and add it to the model. Delete the PID block and insert the DF22 controller in its' place. You connect the e(k) input to the line going to the "ferror" variable. Double-click the DF22 controller block and type in your coefficients. Modify the plant model with your own - the transfer function is in the file "PID_config.m" which opens when you run the model. In "PID_example.m" you'll need to modify line 66 to capture "ferror" instead of "finput". You may have other changes to make too depending on your system.

    After you succeed in running the model and get the results you expect, you'll find a file called "PID_input.dat" has been created in the directory above. This is the data stream going into the controller. You can use this directly in place of "DF22_edata.dat" in the DF22 example in the DCL. By now you have modified that code to run on F28335, so simply follow the instructions in the DCL User's Guide (p.126) to load the .dat file into "eBuf" and run the code. You can then copy the controller output data buffer (u1k or u2k) into another data file (in CCS, "Tools -> Save memory...") which you can import into your Matlab workspace and compare with "fcontrol" from the simulation.

    This is just my suggestion, and you'll have to work through the details. Alternatively, you may prefer to create a new model instead of using the PID example as a template. It's really up to you.

    I hope this helps.

    Regards,

    Richard
  • Sir,
    Actually, I have Boost converter as my plant and also designed the type-2 compensator for its closed loop operation. But now I am confused about, how to give the input data to the controller (DF22).
    Whether I have to enter it in the main program or in the sub-routine void adc_isr(void)?

    In DF22 example it has just taken the default values.

  • Hi Soumya,

    The call to DCL_runDF22 has happen in the ISR so it happens at the control loop rate, but you can define and modify rk in your main program.  Typically that's what would be done.

    For a voltage mode boost converter the control loop just has the controller in cascade connection (see attached, from the C2000 bi-directional DC/DC kit documentation).  In your ADC ISR code, you'll read the ADC (Vhv_fb in the attachment), convert to float, subtract from your reference, and then pass this to the DF22 controller.  Something like this:

    yk = ((float) AdcRegs.ADCRESULT0) / 4096.0f;

    ek = rk - yk;

    uk = DCL_runDF22_C1(&controller1, ek);

    Regards,

    Richard

    User_Guide_v1.0 48.pdf

  • Sir,
    I have gone through the said procedure.
    Still I am a bit confused about it's implementation.
    Here is my code for interrupt void adc_isr(void).

    __interrupt void adc_isr(void)
    {
    /*.....................................CONTROL BLOCK.............................*/
    adc_out= (AdcRegs.ADCRESULT0 >>4)/4096.0f;
    yk=(float) adc_out ;
    float rk= 12.5f/4096f;
    ek=rk-yk;
    u1k = DCL_runDF22_C1(&controller1, ek);
    out = int(u1k);




    // clear timer flag & acknowledge interrupt
    CpuTimer0Regs.TCR.bit.TIF = 1;
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;

    // read data & run controllers
    if (eBuf.dptr < eBuf.lptr)
    {
    // read input data
    ek = DCL_readLog(&eBuf);

    // run full controller
    u1k = DCL_runDF22_C1(&controller1, ek);

    // run pre-computed controller
    u2k = DCL_runDF22_C2(&controller2, ek);
    v = DCL_runClamp_C1(&u2k, upperLim, lowerLim);
    if (0 == v)
    {
    DCL_runDF22_C3(&controller2, ek, u2k);
    }

    // compute difference
    dk = u1k - u2k;

    // store results
    DCL_writeLog(&u1Buf, u1k);
    DCL_writeLog(&u2Buf, u2k);
    DCL_writeLog(&dBuf, dk);
    }
    else
    {
    // place break-point here
    asm(" NOP");
    }

    IsrCount++;


    if(IdleLoopCount==0)
    {
    if(v == DATA_LENGTH)
    {
    v = 0;
    IdleLoopCount=1;
    }
    else
    {
    vadc = (AdcRegs.ADCRESULT0 >>4) ;
    e_array[v]= vadc;
    v++;
    }

    }
    // Reinitialize for next ADC sequence
    AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1
    AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // Clear INT SEQ1 bit
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE


    return;
    }

    Please check the code once.

    Regards,
    Soumya.
  • Soumya,

    It looks like you have placed something like the code I suggested near the top of this ISR, but further down is other code which looks like the DCL example and seems to be doing something similar (anyway u1k is over-written there).

    I was expecting you to place your own code inside the ISR. Unless you want to run the DCL example in parallel, you do not need the lines between...

    // read data & run controllers
    ...and..
    // Reinitialize for next ADC sequence

    That's where your code should go. Can you expand a little on what is confusing please?

    Regards,

    Richard
  • Sir,

    I am trying to run the Boost converter in closed loop voltage control mode. Also, I have Simulated and run the model in MATLAB successfully.

    Now I have written the code you suggested earlier inside the conditional loop. Still, there is no output on the EPwm2 port.

    Also, I am attaching the final code with this. 

    //###########################################################################
    // $TI Release: F2833x/F2823x Header Files and Peripheral Examples V142 $
    // $Release Date: November  1, 2016 $
    // $Copyright: Copyright (C) 2007-2016 Texas Instruments Incorporated -
    //             http://www.ti.com/ ALL RIGHTS RESERVED $
    //###########################################################################
    
    #include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
    #include "DCL.h"
    // #include "F2833x_Device.h"
    // #include "F2833x_Examples.h"
    // #include "F2833x_GlobalPrototypes.h"
    #include "DCLF32.h"
    #include "DCL_fdlog.h"
    
    // Prototype statements for functions found within this file.
    __interrupt void adc_isr(void);
     void InitEPwm2Example(void);
    #define EPWM1_TIMER_TBPRD  1500  // Period register
    #define EPWM1_CMPA     1050
    //INPUT DATA
    #define DATA_LENGTH 1601
    #pragma DATA_SECTION(e_array, "PDataLogSection")
    float e_array[DATA_LENGTH];
    FDLOG eBuf = FDLOG_DEFAULTS;
    
    // full controller results
    #pragma DATA_SECTION(u1_array, "QDataLogSection")
    float u1_array[DATA_LENGTH];
    FDLOG u1Buf = FDLOG_DEFAULTS;
    
    // pre-computed controller results
    #pragma DATA_SECTION(u2_array, "RDataLogSection")
    float u2_array[DATA_LENGTH];
    FDLOG u2Buf = FDLOG_DEFAULTS;
    
    // controller difference data
    #pragma DATA_SECTION(d_array, "SDataLogSection")
    float d_array[DATA_LENGTH];
    FDLOG dBuf = FDLOG_DEFAULTS;
    
    // extern interrupt void control_Isr(void);
    __interrupt void adc_isr(void);
    // global  variables
    long IdleLoopCount = 0;
    long IsrCount = 0;
    float u1k;
    float u2k;
    float dk;
    float upperLim;
    float lowerLim;
    uint16_t v;
    DCL_DF22 controller1 = DF22_DEFAULTS;
    DCL_DF22 controller2 = DF22_DEFAULTS;
    int vadc=0;
    FDLOG eBUf = FDLOG_DEFAULTS;
     int out=0;
    // Global variables used in this example:
    // Uint16 ConversionCount;
    float rk = (1.26f) / (4096.0f);
    float ek;
    float yk;
    main()
    {
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the DSP2833x_SysCtrl.c file.
    
        InitSysCtrl();
       DINT;
       InitEPwm2Gpio();
        /*.............................ADC_BLOCK..........................*/
       EALLOW;
       #if (CPU_FRQ_150MHZ)     // Default - 150 MHz SYSCLKOUT
         #define ADC_MODCLK 0x3 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3)   = 25.0 MHz
       #endif
       #if (CPU_FRQ_100MHZ)
         #define ADC_MODCLK 0x2 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 100/(2*2)   = 25.0 MHz
       #endif
       EDIS;
    
       // Define ADCCLK clock frequency ( less than or equal to 25 MHz )
       // Assuming InitSysCtrl() has set SYSCLKOUT to 150 MHz
       EALLOW;
       SysCtrlRegs.HISPCP.all = ADC_MODCLK; // High Speed Periphal clock set to 25 MHz
       EDIS;
    
    // Step 2. Initialize GPIO:
    // This example function is found in the DSP2833x_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    // InitGpio();  // Skipped for this example
    
    // Step 3. Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
    
    
    // Initialize the PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the DSP2833x_PieCtrl.c file.
       EALLOW;
           SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
          EDIS;
               InitEPwm2Example();
            EALLOW;
           SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
        EDIS;
    
       InitPieCtrl();
    
    // Disable CPU interrupts and clear all CPU interrupt flags:
       IER = 0x0000;
       IFR = 0x0000;
    
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in DSP2833x_DefaultIsr.c.
    // This function is found in DSP2833x_PieVect.c.
       InitPieVectTable();
    
    // Interrupts that are used in this example are re-mapped to
    // ISR functions found within this file.
       EALLOW;  // This is needed to write to EALLOW protected register
       PieVectTable.ADCINT = &adc_isr;
       PieVectTable.TINT0 = &adc_isr;
       EDIS;    // This is needed to disable write to EALLOW protected registers
    
    // Step 4. Initialize all the Device Peripherals:
    // This function is found in DSP2833x_InitPeripherals.c
    // InitPeripherals(); // Not required for this example
       InitAdc();  // For this example, init the ADC
    
    // Step 5. User specific code, enable interrupts:
    
    // Enable ADCINT in PIE
       PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
       IER |= M_INT1; // Enable CPU Interrupt 1
       EINT;          // Enable Global interrupt INTM
       ERTM;          // Enable Global realtime interrupt DBGM
       v = 0;
      // Configure ADC
       AdcRegs.ADCTRL1.bit.ACQ_PS = 0x2;
       AdcRegs.ADCTRL1.bit.CPS = 0x1;
       //AdcRegs.ADCTRL3.bit.ADCCLKPS = 0x1;
       AdcRegs.ADCMAXCONV.all = 0x0000;       // Setup 2 conv's on SEQ1
       AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; // Setup ADCINA0 as 1st SEQ1 conv.
       //AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1; // Setup ADCINA1 as 2nd SEQ1 conv.
       AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;// Enable SOCA from ePWM to start SEQ1
       AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;  // Enable SEQ1 interrupt (every EOS)
       AdcRegs.ADCTRL3.bit.SMODE_SEL = 1;
    
    // Assumes ePWM1 clock is already enabled in InitSysCtrl();
       EPwm1Regs.ETSEL.bit.SOCAEN = 1;        // Enable SOC on A group
       EPwm1Regs.ETSEL.bit.SOCASEL = 2;       // Select SOC from from CPMA on upcount
       EPwm1Regs.ETPS.bit.SOCAPRD = 1;        // Generate pulse on 1st event
       EPwm1Regs.CMPA.half.CMPA = 0x08FF;     // Set compare A value
       EPwm1Regs.TBPRD = 0x0FFF;              // Set period for ePWM1
       EPwm1Regs.TBCTL.bit.SYNCOSEL = 0x01;
       EPwm1Regs.TBCTL.bit.CTRMODE = 0;       // count up and start
    
    // Wait for ADC interrupt
      /* for(;;)
       {
    
       } */
       /*............... CONTROLLER SECTION....................*/
    
       // configure CPU timer 0
        InitCpuTimers();
        ConfigCpuTimer(&CpuTimer0, 90.0, 1.0e+03);
    
        // initialise data arrays
        DCL_initLog(&eBuf, e_array, DATA_LENGTH);
        DCL_initLog(&u1Buf, u1_array, DATA_LENGTH);
        DCL_initLog(&u2Buf, u2_array, DATA_LENGTH);
        DCL_initLog(&dBuf, d_array, DATA_LENGTH);
        DCL_clearLog(&u1Buf);
        DCL_clearLog(&u2Buf);
        DCL_fillLog(&dBuf, 1.234567f);
    
        // initialise full controller
        controller1.a1 = -0.5075f;
        controller1.a2 = -0.4925f;
        controller1.b0 = 0.01614f;
        controller1.b1 = 3.84e-5f;
        controller1.b2 = -0.0161f;
    
        // Initialize Pre-computed controller
        controller2.a1 = controller1.a1;
        controller2.a2 = controller1.a2;
        controller2.b0 = controller1.b0;
        controller2.b1 = controller1.b1;
        controller2.b2 = controller1.b2;
    
        // clamp limits
        upperLim = 1000.0f;
        lowerLim = -1000.0f;
    
        // enable interrupts
        PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
        IER |= M_INT1;
        EINT;
        StartCpuTimer0();
    
        // idle loop
        while(1)
        {
            IdleLoopCount++;
        }
    
    } // end of main
    
    
    
    __interrupt void  adc_isr(void)
    {
         /*.....................................CONTROL BLOCK.............................*/
    
    
        // clear timer flag & acknowledge interrupt
            CpuTimer0Regs.TCR.bit.TIF = 1;
            PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
    
            // read data & run controllers
            if (eBuf.dptr < eBuf.lptr)
            {
                // read input data
                  yk = ((float) AdcRegs.ADCRESULT0) / 4096.0f;
    
                   ek = rk - yk;
               // run full controller
                u1k = DCL_runDF22_C1(&controller1, ek);
                out = (int) u1k;
                EPwm2Regs.CMPA.half.CMPA = u1k * 4096.0f;
    
                // run pre-computed controller
                u2k = DCL_runDF22_C2(&controller2, ek);
                v = DCL_runClamp_C1(&u2k, upperLim, lowerLim);
                if (0 == v)
                {
                    DCL_runDF22_C3(&controller2, ek, u2k);
                }
    
                // compute difference
                dk = u1k - u2k;
    
                // store results
                DCL_writeLog(&u1Buf, u1k);
                DCL_writeLog(&u2Buf, u2k);
                DCL_writeLog(&dBuf, dk);
            }
            else
            {
                // place break-point here
                asm(" NOP");
            }
    
            IsrCount++;
    
    
     if(IdleLoopCount==0){
      if(v == DATA_LENGTH)
      {
         v = 0;
         IdleLoopCount=1;
      }
      else
      {
          vadc = (AdcRegs.ADCRESULT0 >>4) /4096.0f ;
      //    iadc = ~((AdcRegs.ADCRESULT1 >>4) - 3478)+1;
          e_array[v]= vadc;
        //  adc_val2[ConversionCount]= iadc;
          v++;
    
      }
    
      }
      // Reinitialize for next ADC sequence
      AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;         // Reset SEQ1
      AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;       // Clear INT SEQ1 bit
      PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;   // Acknowledge interrupt to PIE
      return;
    }
    
     void InitEPwm2Example()
    {
       // Setup TBCLK
       EPwm2Regs.TBPRD = 0x0FFF;           // Set timer period 801 TBCLKs
       EPwm2Regs.TBPHS.half.TBPHS = 0x0000;           // Phase is 0
       EPwm2Regs.TBCTR = 0x0000;                      // Clear counter
    
       // Set Compare values
       EPwm2Regs.CMPA.half.CMPA = vadc * 4096.0f;     // Set compare A value old data 1953
       EPwm2Regs.CMPB = EPWM1_CMPA;               // Set Compare B value
    
       // Setup counter mode
       EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up n down
       EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE;        // Disable phase loading
       EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
       EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;
       EPwm2Regs.TBCTL.bit.SYNCOSEL = 0x00;
    
       // Setup shadowing
       EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
       EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
       EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;  // Load on Zero
       EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    
    
       // Set actions
       EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;             // Set PWM1A on event A, up count
       EPwm2Regs.AQCTLA.bit.CAD = AQ_SET;           // Clear PWM1A on event A, down count
    }

    Please help me out, where I am going wrong?

    N.B:- While I am commenting in the infinite for loop, one warning named "can't reach the statement InitCpuTimers();" is showing.

    Regards,

    Soumya.

    //###########################################################################// Description//! \addtogroup f2833x_example_list//! <h1> ADC Start of Conversion (adc_soc)</h1>//!//! This ADC example uses ePWM1 to generate a periodic ADC SOC on SEQ1.//! Two channels are converted, ADCINA3 and ADCINA2.//!//! \b Watch \b Variables \n//! - Voltage1[10]  - Last 10 ADCRESULT0 values//! - Voltage2[10]  - Last 10 ADCRESULT1 values//! - ConversionCount   - Current result number 0-9//! - LoopCount     - Idle loop counter//////###########################################################################// $TI Release: F2833x/F2823x Header Files and Peripheral Examples V142 $// $Release Date: November  1, 2016 $// $Copyright: Copyright (C) 2007-2016 Texas Instruments Incorporated -//             http://www.ti.com/ ALL RIGHTS RESERVED $//###########################################################################
    #include "DSP28x_Project.h"     // Device Headerfile and Examples Include File#include "DCL.h"// #include "F2833x_Device.h"// #include "F2833x_Examples.h"// #include "F2833x_GlobalPrototypes.h"#include "DCLF32.h"#include "DCL_fdlog.h"
    // Prototype statements for functions found within this file.__interrupt void adc_isr(void); void InitEPwm2Example(void);#define EPWM1_TIMER_TBPRD  1500  // Period register#define EPWM1_CMPA     1050//INPUT DATA#define DATA_LENGTH 1601#pragma DATA_SECTION(e_array, "PDataLogSection")float e_array[DATA_LENGTH];FDLOG eBuf = FDLOG_DEFAULTS;
    // full controller results#pragma DATA_SECTION(u1_array, "QDataLogSection")float u1_array[DATA_LENGTH];FDLOG u1Buf = FDLOG_DEFAULTS;
    // pre-computed controller results#pragma DATA_SECTION(u2_array, "RDataLogSection")float u2_array[DATA_LENGTH];FDLOG u2Buf = FDLOG_DEFAULTS;
    // controller difference data#pragma DATA_SECTION(d_array, "SDataLogSection")float d_array[DATA_LENGTH];FDLOG dBuf = FDLOG_DEFAULTS;
    // extern interrupt void control_Isr(void);__interrupt void adc_isr(void);// global  variableslong IdleLoopCount = 0;long IsrCount = 0;float u1k;float u2k;float dk;float upperLim;float lowerLim;uint16_t v;DCL_DF22 controller1 = DF22_DEFAULTS;DCL_DF22 controller2 = DF22_DEFAULTS;int vadc=0;FDLOG eBUf = FDLOG_DEFAULTS; int out=0;// Global variables used in this example:// Uint16 ConversionCount;float rk = (1.26f) / (4096.0f);float ek;float yk;main(){// Step 1. Initialize System Control:// PLL, WatchDog, enable Peripheral Clocks// This example function is found in the DSP2833x_SysCtrl.c file.
        InitSysCtrl();   DINT;   InitEPwm2Gpio();    /*.............................ADC_BLOCK..........................*/   EALLOW;   #if (CPU_FRQ_150MHZ)     // Default - 150 MHz SYSCLKOUT     #define ADC_MODCLK 0x3 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3)   = 25.0 MHz   #endif   #if (CPU_FRQ_100MHZ)     #define ADC_MODCLK 0x2 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 100/(2*2)   = 25.0 MHz   #endif   EDIS;
       // Define ADCCLK clock frequency ( less than or equal to 25 MHz )   // Assuming InitSysCtrl() has set SYSCLKOUT to 150 MHz   EALLOW;   SysCtrlRegs.HISPCP.all = ADC_MODCLK; // High Speed Periphal clock set to 25 MHz   EDIS;
    // Step 2. Initialize GPIO:// This example function is found in the DSP2833x_Gpio.c file and// illustrates how to set the GPIO to it's default state.// InitGpio();  // Skipped for this example
    // Step 3. Clear all interrupts and initialize PIE vector table:// Disable CPU interrupts

    // Initialize the PIE control registers to their default state.// The default state is all PIE interrupts disabled and flags// are cleared.// This function is found in the DSP2833x_PieCtrl.c file.   EALLOW;       SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;      EDIS;           InitEPwm2Example();        EALLOW;       SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;    EDIS;
       InitPieCtrl();
    // Disable CPU interrupts and clear all CPU interrupt flags:   IER = 0x0000;   IFR = 0x0000;
    // Initialize the PIE vector table with pointers to the shell Interrupt// Service Routines (ISR).// This will populate the entire table, even if the interrupt// is not used in this example.  This is useful for debug purposes.// The shell ISR routines are found in DSP2833x_DefaultIsr.c.// This function is found in DSP2833x_PieVect.c.   InitPieVectTable();
    // Interrupts that are used in this example are re-mapped to// ISR functions found within this file.   EALLOW;  // This is needed to write to EALLOW protected register   PieVectTable.ADCINT = &adc_isr;   PieVectTable.TINT0 = &adc_isr;   EDIS;    // This is needed to disable write to EALLOW protected registers
    // Step 4. Initialize all the Device Peripherals:// This function is found in DSP2833x_InitPeripherals.c// InitPeripherals(); // Not required for this example   InitAdc();  // For this example, init the ADC
    // Step 5. User specific code, enable interrupts:
    // Enable ADCINT in PIE   PieCtrlRegs.PIEIER1.bit.INTx6 = 1;   IER |= M_INT1; // Enable CPU Interrupt 1   EINT;          // Enable Global interrupt INTM   ERTM;          // Enable Global realtime interrupt DBGM   v = 0;  // Configure ADC   AdcRegs.ADCTRL1.bit.ACQ_PS = 0x2;   AdcRegs.ADCTRL1.bit.CPS = 0x1;   //AdcRegs.ADCTRL3.bit.ADCCLKPS = 0x1;   AdcRegs.ADCMAXCONV.all = 0x0000;       // Setup 2 conv's on SEQ1   AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; // Setup ADCINA0 as 1st SEQ1 conv.   //AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1; // Setup ADCINA1 as 2nd SEQ1 conv.   AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;// Enable SOCA from ePWM to start SEQ1   AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;  // Enable SEQ1 interrupt (every EOS)   AdcRegs.ADCTRL3.bit.SMODE_SEL = 1;
    // Assumes ePWM1 clock is already enabled in InitSysCtrl();   EPwm1Regs.ETSEL.bit.SOCAEN = 1;        // Enable SOC on A group   EPwm1Regs.ETSEL.bit.SOCASEL = 2;       // Select SOC from from CPMA on upcount   EPwm1Regs.ETPS.bit.SOCAPRD = 1;        // Generate pulse on 1st event   EPwm1Regs.CMPA.half.CMPA = 0x08FF;     // Set compare A value   EPwm1Regs.TBPRD = 0x0FFF;              // Set period for ePWM1   EPwm1Regs.TBCTL.bit.SYNCOSEL = 0x01;   EPwm1Regs.TBCTL.bit.CTRMODE = 0;       // count up and start
    // Wait for ADC interrupt  /* for(;;)   {
       } */   /*............... CONTROLLER SECTION....................*/
       // configure CPU timer 0    InitCpuTimers();    ConfigCpuTimer(&CpuTimer0, 90.0, 1.0e+03);
        // initialise data arrays    DCL_initLog(&eBuf, e_array, DATA_LENGTH);    DCL_initLog(&u1Buf, u1_array, DATA_LENGTH);    DCL_initLog(&u2Buf, u2_array, DATA_LENGTH);    DCL_initLog(&dBuf, d_array, DATA_LENGTH);    DCL_clearLog(&u1Buf);    DCL_clearLog(&u2Buf);    DCL_fillLog(&dBuf, 1.234567f);
        // initialise full controller    controller1.a1 = -0.5075f;    controller1.a2 = -0.4925f;    controller1.b0 = 0.01614f;    controller1.b1 = 3.84e-5f;    controller1.b2 = -0.0161f;
        // Initialize Pre-computed controller    controller2.a1 = controller1.a1;    controller2.a2 = controller1.a2;    controller2.b0 = controller1.b0;    controller2.b1 = controller1.b1;    controller2.b2 = controller1.b2;
        // clamp limits    upperLim = 1000.0f;    lowerLim = -1000.0f;
        // enable interrupts    PieCtrlRegs.PIEIER1.bit.INTx7 = 1;    IER |= M_INT1;    EINT;    StartCpuTimer0();
        // idle loop    while(1)    {        IdleLoopCount++;    }
    } // end of main


    __interrupt void  adc_isr(void){     /*.....................................CONTROL BLOCK.............................*/

        // clear timer flag & acknowledge interrupt        CpuTimer0Regs.TCR.bit.TIF = 1;        PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
            // read data & run controllers        if (eBuf.dptr < eBuf.lptr)        {            // read input data              yk = ((float) AdcRegs.ADCRESULT0) / 4096.0f;
                   ek = rk - yk;           // run full controller            u1k = DCL_runDF22_C1(&controller1, ek);            out = (int) u1k;            EPwm2Regs.CMPA.half.CMPA = u1k * 4096.0f;
                // run pre-computed controller            u2k = DCL_runDF22_C2(&controller2, ek);            v = DCL_runClamp_C1(&u2k, upperLim, lowerLim);            if (0 == v)            {                DCL_runDF22_C3(&controller2, ek, u2k);            }
                // compute difference            dk = u1k - u2k;
                // store results            DCL_writeLog(&u1Buf, u1k);            DCL_writeLog(&u2Buf, u2k);            DCL_writeLog(&dBuf, dk);        }        else        {            // place break-point here            asm(" NOP");        }
            IsrCount++;

     if(IdleLoopCount==0){  if(v == DATA_LENGTH)  {     v = 0;     IdleLoopCount=1;  }  else  {      vadc = (AdcRegs.ADCRESULT0 >>4) /4096.0f ;  //    iadc = ~((AdcRegs.ADCRESULT1 >>4) - 3478)+1;      e_array[v]= vadc;    //  adc_val2[ConversionCount]= iadc;      v++;
      }
      }  // Reinitialize for next ADC sequence  AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;         // Reset SEQ1  AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;       // Clear INT SEQ1 bit  PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;   // Acknowledge interrupt to PIE  return;}
     void InitEPwm2Example(){   // Setup TBCLK   EPwm2Regs.TBPRD = 0x0FFF;           // Set timer period 801 TBCLKs   EPwm2Regs.TBPHS.half.TBPHS = 0x0000;           // Phase is 0   EPwm2Regs.TBCTR = 0x0000;                      // Clear counter
       // Set Compare values   EPwm2Regs.CMPA.half.CMPA = vadc * 4096.0f;     // Set compare A value old data 1953   EPwm2Regs.CMPB = EPWM1_CMPA;               // Set Compare B value
       // Setup counter mode   EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up n down   EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE;        // Disable phase loading   EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT   EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;   EPwm2Regs.TBCTL.bit.SYNCOSEL = 0x00;
       // Setup shadowing   EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;   EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;   EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;  // Load on Zero   EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

       // Set actions   EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;             // Set PWM1A on event A, up count   EPwm2Regs.AQCTLA.bit.CAD = AQ_SET;           // Clear PWM1A on event A, down count}

  • Soumya,

    I think the brackets are messed up. Count them inside adc_isr: I think there might be one too many closing braces, probably the one in line 280 shouldn't be there.  

    Once you've fixed that, place a break-point on the first line in the ISR and run the code.  Does the program get into the ISR?

    If so, is the PWM2 counter incrementing?  I don't see where you're enabling counting in PWM2 (CTRMODE in TBCTL).

    Regards,

    Richard

  • Sir,

    There is no such extra braces in the adc_isr. Also placed a break point and run the program, It's getting into the ISR.

    There are neither any errors nor any  warnings while running the program.

    But there is no output PWM pulses on EPwm2 port.

    A screenshot is attached for your reference, where the values of u1k and u2k seems to be unusual.

    My plant is working with a input voltage of 5V and output voltage  12.5V (i.e with duty cycle 0.6) , Sensor gain is 1/10.

    Waiting for your guidance.

    Regards,

    Soumya.

  • Sir,
    I am in think, I need to store the value of ek in e_array by writing something like DCL_writeLog(&eBuf, ek); .
    But where to put this line? Also suggest me if I am wrong in my program. Please have a detailed look into the program.
    Eagerly waiting for your reply.
    Regards,
    Soumya.
  • Sir,
    I am in think, I need to store the value of ek in e_array by writing something like DCL_writeLog(&eBuf, ek); .
    But where to put this line? Also suggest me if I am wrong in my program. Please have a detailed look into the program.
    Eagerly waiting for your reply.
    Regards,
    Soumya.
  • Soumya,

    Not sure I understand what you're trying to do in the program. The DCL example uses the data loggers to stream data samples through the controllers and check the results. If you're controlling a physical plant you don't need the loggers unless you actually want to record control data for some reason.

    What is the "if (eBuf.dptr < eBuf.lptr)" for?

    Regards,

    Richard
  • Sir,
    I have to run the boost converter in closed loop voltage control.
    While running this program, there is no output pulse on GPIO2.
    So , Please let me know what are the modifications needed in my code to obtain the output.

    I have taken the statement 'if (eBuf.dptr < eBuf.lptr)"  from the example itself. And I think it is for traversing through the data array. If this condition is not needed then what should be the code modification to run the plant in closed loop. 


    Regards,
    Soumya.

  • Dear Sir,
    One more thing, based on what I have to choose the value of upper limit and lower limit in line number 198 and 199?
    Waiting for your help!

    Regards,
    Soumya
  • Sir,

    I have marked something new.

    While I am running the program, Its going into the ILLEGAL_ISR(void). Why it is going so?

    Is there any mistake which leads t this situation?

    A screenshot is attached with this for your reference.

    But , after this If I press the RESUME button again, the program is running without any error or warning.

    Waiting for your guidance.

    Regards,

    Soumya.

  • Soumya,

    You have posted several different questions, so I'll try to deal with them in order.

    1. - "Please let me know what are the modifications needed in my code to obtain the output."
    This is relating to having no output on PWM2. Assuming you have correctly configured the PWM module and the counter is incrementing (I asked you to check that in an earlier post), the issue is most likely to do with GPIO pin configuration. Check you have configured the required PWM2 pins as outputs (GPIO2 and GPIO3 on F28069) - see the user's guide and header file examples for more information.

    2. - "...what should be the code modification to run the plant in closed loop."
    You should remove the "if (eBuf.dptr < eBuf.lptr)" test. Unless you are working with a test data, the ISR only needs to read the input, run the controller, and compute and output the PWM duty cycle.

    3. - "...based on what I have to choose the value of upper limit and lower limit in line number 198 and 199?"
    It's not clear to me which controller you are running. The example code showed both full (C1) and pre-computed (C2 & C3) forms of the DF22 compensator. You only need the clamp with the pre-computed type. The upper and lower limits bound the output of the controller. Since I think you are working with normalized duty cycle, typically the lower limit will be zero and the upper limit 1.0f, but it depends how you have scaled the variables in the loop. Think about what the numbers mean in terms of the plant.

    4. - "While I am running the program, Its going into the ILLEGAL_ISR(void). Why it is going so?"
    The Illegal ISR usually happens because an attempt has been made to access invalid memory. It's probably because you are indexing beyond the end of a buffer. Might be #2, above.

    BTW, this thread is getting quite long. I suggest closing it and opening a new one so others on this forum can see the question without going through multiple pages. Thanks.

    Regards,

    Richard

  • Dear Sir,

    I have gone through your point number 1,2 and 3 and checked everything. Still the programme is entering into "interrupt void

    ILLEGAL_ISR(void)".  

    And about incrementing the counter value of EPwm2, it is reaching a certain value and not incrementing after that.

    As per your recommendation, I am opening a new thread for illegal isr.

    Also, I am attaching few screenshots showing the values of TBCTR and the variables.

    With warm Regards,

    Soumya.

  • Sir,
    I have posted a new thread as you advised. One has replied but he is not replying subsequently.
    Do I need to create another thread to receive reply from your side?
    Else, Please reply here. I am stuck at the point of ILLEGAL_ISR(void). Please help me out.
    Regards,
    Soumya.
  • Soumya,

    Please ping the other thread again.  I guess sometimes things get dropped accidentally so there's nothing wrong with sending a reminder.  This thread is getting hard to follow because there are so many posts.  I'll comment here, but please concentrate on the new thread.

    There's not enough information in the post to determine why your code is ending up in ILLEGAL_ISR.  It's most likely because you are accessing invalid memory, but to find out where and why that's happening isn't apparent. Look carefully through your code for un-initialized variables or arrays being indexed out of range.  Also look at your .map file to check all your program and data sections are where you expect them to be.  It could be an error in the linker command file.

    If you still don't find it, try setting up break-points and single stepping through the code to see if you can find it.  If not, you'll have to back-track by removing code until it starts working and then build up from there.  Remember, the TI examples in C2000Ware can be relied on to work so it's worth comparing your code carefully with a similar example, such as an F2833x PWM example.  There's no simple answer, unfortunately.

    Regards, 

    Richard

  • Sir,

    The link for my latest post is  

    I have concisely defined my problems there.

    Please respond to it, there.

    Regards,

    Soumya.

  • I have created a new project including all the files (header and source) from C2000ware and Now it is not entering into ILLEGAL_isr mode. Previously I think I have added some files from C2000 ware and some from ControlSuite.
    Now my project is running well.
    Thank you all experts who made the journey of learning DSP an easy one for me.
    Thank you everyone.

    With warm Regards,
    Soumya.