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/TMS320F28069: Two PWMs trigger two SOC and result ADC1 and ADC2 interrupt with different frequency

Part Number: TMS320F28069


Tool/software: Code Composer Studio

Hi,

Recently we faced one issue from F2806x ADC.

Our goal is to set SOC0~SOC5 with high priority, PWM trigger frequency like 40KHz with ADC interrupt 1; set SOC6~SOC15 round robin, another PWM trigger frequency like 20KHz with ADC interrupt 2.

No matter how we configure, we find that the two ADC interrupts frequency are the same. There's one exception, that's to set ADC interrupt 2's EOC like EOC7 or EOC6.

Will you help to take a look please? Thanks in advance.

 

Here's the code: ADC interrupt 4 is used.

//###########################################################################

// Description:

//! \addtogroup f2806x_example_list

//! <h1> ADC Start of Conversion (adc_soc)</h1>

//!

//! This ADC example uses ePWM1 to generate a periodic ADC SOC - ADCINT1.

//! Two channels are converted, ADCINA4 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: F2806x C/C++ Header Files and Peripheral Examples V151 $

// $Release Date: February  2, 2016 $

// $Copyright: Copyright (C) 2011-2016 Texas Instruments Incorporated -

//             http://www.ti.com/ ALL RIGHTS RESERVED $

//###########################################################################

 

#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File

 

// Prototype statements for functions found within this file.

__interrupt void adc_isr(void);

__interrupt void adc_isr2(void);

void Adc_Config(void);

 

#define hoFault_LED()    0//GpioDataRegs.GPBSET.bit.GPIO43 = 1

#define loFault_LED()    0//GpioDataRegs.GPBCLEAR.bit.GPIO43 = 1

#define hoFault_LED1()   GpioDataRegs.GPBSET.bit.GPIO43 = 1

#define loFault_LED1()   GpioDataRegs.GPBCLEAR.bit.GPIO43 = 1

 

 

#define hoComm_LED()     0//GpioDataRegs.GPASET.bit.GPIO0 = 1

#define loComm_LED()     0//GpioDataRegs.GPACLEAR.bit.GPIO0 = 1

#define hoComm_LED1()    GpioDataRegs.GPASET.bit.GPIO0 = 1

#define loComm_LED1()    GpioDataRegs.GPACLEAR.bit.GPIO0 = 1

 

// Global variables used in this example:

Uint16 LoopCount;

Uint16 ConversionCount;

Uint16 Voltage1[10];

Uint16 Voltage2[10];

 

int32 user_max_speed, user_min_speed, temp_speed, num_isr1, num_isr2;

Uint16 ain_speed, flag_need, flag_start_command;

#define MIN_AIN      250

Uint16 Flag1 =0;

Uint16 Flag2 =0;

main()

{

 

// Step 1. Initialize System Control:

// PLL, WatchDog, enable Peripheral Clocks

// This example function is found in the F2806x_SysCtrl.c file.

 

       //////

 

   InitSysCtrl();

 

////////

 

 

// Step 2. Initialize GPIO:

// This example function is found in the F2806x_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

   DINT;

 

// 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 F2806x_PieCtrl.c file.

   InitPieCtrl();

 

// Disable CPU interrupts and clear all CPU interrupt flags:

   IER = 0x0000;

   IFR = 0x0000;

   EALLOW;

   GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0;  //comm led

   GpioCtrlRegs.GPADIR.bit.GPIO0  = 1;

   GpioCtrlRegs.GPAPUD.bit.GPIO0  = 0;

   GpioDataRegs.GPACLEAR.bit.GPIO0 = 1; //default off

   GpioCtrlRegs.GPBMUX1.bit.GPIO43 = 0;  //FAULT LED

   GpioCtrlRegs.GPBDIR.bit.GPIO43  = 1;

   GpioCtrlRegs.GPBPUD.bit.GPIO43  = 0;

   GpioDataRegs.GPBCLEAR.bit.GPIO43 = 1;  //default off

   EDIS;

// 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 F2806x_DefaultIsr.c.

// This function is found in F2806x_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.ADCINT1 = &adc_isr;

//   PieVectTable.ADCINT2 = &adc_isr2;

   PieVectTable.ADCINT4 = &adc_isr2;

   EDIS;    // This is needed to disable write to EALLOW protected registers

 

// Step 4. Initialize all the Device Peripherals:

// This function is found in F2806x_InitPeripherals.c

// InitPeripherals(); // Not required for this example

   InitAdc();  // For this example, init the ADC

   AdcOffsetSelfCal();

 

// Step 5. User specific code, enable interrupts:

 

// Enable ADCINT1 in PIE

   PieCtrlRegs.PIEIER1.bit.INTx1 = 1;    // Enable INT 1.1 in the PIE

   PieCtrlRegs.PIEIER10.bit.INTx4 = 1;   // Enable INT 10.2 in the PIE

//   PieCtrlRegs.PIEIER10.bit.INTx4 = 1;

   IER |= M_INT1;                                      // Enable CPU Interrupt 1

   IER |= M_INT10;

   EINT;                                               // Enable Global interrupt INTM

   ERTM;                                               // Enable Global realtime interrupt DBGM

 

   LoopCount = 0;

   ConversionCount = 0;

   num_isr1=0;

   num_isr2=0;

 

// Configure ADC

    EALLOW;

    AdcRegs.ADCCTL2.bit.ADCNONOVERLAP = 0;      // Enable non-overlap mode

    AdcRegs.ADCCTL1.bit.INTPULSEPOS   = 1;   // ADCINT1 trips after AdcResults latch

   AdcRegs.SOCPRICTL.bit.SOCPRIORITY = 0x05;

    AdcRegs.INTSEL1N2.bit.INT1E     = 1;     // Enabled ADCINT1

    AdcRegs.INTSEL1N2.bit.INT1CONT  = 0;     // 0 Disable ADCINT1 Continuous mode

    AdcRegs.INTSEL1N2.bit.INT1SEL = 4;    // setup EOC1 to trigger ADCINT1 to fire

 

    AdcRegs.ADCSOC0CTL.bit.CHSEL = 0;    // set SOC0 channel select to ADCINA4

    AdcRegs.ADCSOC1CTL.bit.CHSEL = 1;    // set SOC1 channel select to ADCINA2

    AdcRegs.ADCSOC2CTL.bit.CHSEL = 2;    // set SOC1 channel select to ADCINA2

    AdcRegs.ADCSOC3CTL.bit.CHSEL = 3;    // set SOC1 channel select to ADCINA2

    AdcRegs.ADCSOC4CTL.bit.CHSEL = 4;    // set SOC1 channel select to ADCINA2

 

    AdcRegs.ADCSOC0CTL.bit.TRIGSEL       = 5;    // set SOC0 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1

    AdcRegs.ADCSOC1CTL.bit.TRIGSEL       = 5;    // set SOC1 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1

    AdcRegs.ADCSOC2CTL.bit.TRIGSEL       = 5;    // set SOC1 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1

    AdcRegs.ADCSOC3CTL.bit.TRIGSEL       = 5;    // set SOC1 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1

    AdcRegs.ADCSOC4CTL.bit.TRIGSEL       = 5;    // set SOC1 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1

 

    AdcRegs.ADCSOC0CTL.bit.ACQPS      = 8;   // set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

    AdcRegs.ADCSOC1CTL.bit.ACQPS      = 8;   // set SOC1 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

    AdcRegs.ADCSOC2CTL.bit.ACQPS      = 8;   // set SOC1 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

    AdcRegs.ADCSOC3CTL.bit.ACQPS      = 8;   // set SOC1 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

    AdcRegs.ADCSOC4CTL.bit.ACQPS      = 8;   // set SOC1 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

 

//     AdcRegs.INTSEL1N2.bit.INT2E     = 1;     // Enabled ADCINT2

//     AdcRegs.INTSEL1N2.bit.INT2CONT  = 0;     // Disable ADCINT2 Continuous mode

//    AdcRegs.INTSEL1N2.bit.INT2SEL      = 4;    // setup EOC4 to trigger ADCINT2 to fire

       AdcRegs.INTSEL3N4.bit.INT4E     = 1;     // Enabled ADCINT4

       AdcRegs.INTSEL3N4.bit.INT4CONT  = 0;     // 0 Disable ADCINT4 Continuous mode

AdcRegs.INTSEL3N4.bit.INT4SEL =0xF;  //7;    // setup EOC4 to trigger ADCINT4 to fire

 

    AdcRegs.ADCSOC5CTL.bit.CHSEL  = 5;    // set SOC2 channel select to ADCINA4

    AdcRegs.ADCSOC6CTL.bit.CHSEL  = 6;    // set SOC3 channel select to ADCINA2

    AdcRegs.ADCSOC7CTL.bit.CHSEL  = 7;    // set SOC4 channel select to ADCINA2

    AdcRegs.ADCSOC8CTL.bit.CHSEL  = 8;    // set SOC4 channel select to ADCINA2

    AdcRegs.ADCSOC9CTL.bit.CHSEL  = 9;    // set SOC4 channel select to ADCINA2

    AdcRegs.ADCSOC10CTL.bit.CHSEL = 10;    // set SOC4 channel select to ADCINA2

    AdcRegs.ADCSOC11CTL.bit.CHSEL = 11;    // set SOC4 channel select to ADCINA2

    AdcRegs.ADCSOC12CTL.bit.CHSEL = 12;    // set SOC4 channel select to ADCINA2

    AdcRegs.ADCSOC13CTL.bit.CHSEL = 13;    // set SOC4 channel select to ADCINA2

    AdcRegs.ADCSOC14CTL.bit.CHSEL = 14;    // set SOC4 channel select to ADCINA2

    AdcRegs.ADCSOC15CTL.bit.CHSEL = 15;    // set SOC4 channel select to ADCINA2

 

    AdcRegs.ADCSOC5CTL.bit.TRIGSEL        = 8;    // set SOC2 start trigger on EPWM2B, due to round-robin SOC0 converts first then SOC1

    AdcRegs.ADCSOC6CTL.bit.TRIGSEL        = 8;    // set SOC3 start trigger on EPWM2B, due to round-robin SOC0 converts first then SOC1

    AdcRegs.ADCSOC7CTL.bit.TRIGSEL        = 8;    // set SOC4 start trigger on EPWM2B, due to round-robin SOC0 converts first then SOC1

    AdcRegs.ADCSOC8CTL.bit.TRIGSEL        = 8;    // set SOC2 start trigger on EPWM2B, due to round-robin SOC0 converts first then SOC1

    AdcRegs.ADCSOC9CTL.bit.TRIGSEL        = 8;    // set SOC3 start trigger on EPWM2B, due to round-robin SOC0 converts first then SOC1

    AdcRegs.ADCSOC10CTL.bit.TRIGSEL       = 8;    // set SOC4 start trigger on EPWM2B, due to round-robin SOC0 converts first then SOC1

    AdcRegs.ADCSOC11CTL.bit.TRIGSEL       = 8;    // set SOC2 start trigger on EPWM2B, due to round-robin SOC0 converts first then SOC1

    AdcRegs.ADCSOC12CTL.bit.TRIGSEL       = 8;    // set SOC3 start trigger on EPWM2B, due to round-robin SOC0 converts first then SOC1

    AdcRegs.ADCSOC13CTL.bit.TRIGSEL       = 8;    // set SOC4 start trigger on EPWM2B, due to round-robin SOC0 converts first then SOC1

    AdcRegs.ADCSOC14CTL.bit.TRIGSEL       = 8;    // set SOC2 start trigger on EPWM2B, due to round-robin SOC0 converts first then SOC1

    AdcRegs.ADCSOC15CTL.bit.TRIGSEL       = 8;    // set SOC3 start trigger on EPWM2B, due to round-robin SOC0 converts first then SOC1

 

    AdcRegs.ADCSOC5CTL.bit.ACQPS       = 8;   // set SOC2 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

    AdcRegs.ADCSOC6CTL.bit.ACQPS       = 8;   // set SOC3 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

    AdcRegs.ADCSOC7CTL.bit.ACQPS       = 8;   // set SOC4 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

    AdcRegs.ADCSOC8CTL.bit.ACQPS       = 8;   // set SOC2 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

    AdcRegs.ADCSOC9CTL.bit.ACQPS       = 8;   // set SOC3 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

    AdcRegs.ADCSOC10CTL.bit.ACQPS      = 8;   // set SOC4 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

    AdcRegs.ADCSOC11CTL.bit.ACQPS      = 8;   // set SOC2 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

    AdcRegs.ADCSOC12CTL.bit.ACQPS      = 8;   // set SOC3 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

    AdcRegs.ADCSOC13CTL.bit.ACQPS      = 8;   // set SOC4 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

    AdcRegs.ADCSOC14CTL.bit.ACQPS      = 8;   // set SOC2 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

    AdcRegs.ADCSOC15CTL.bit.ACQPS      = 8;   // set SOC3 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

 

       EDIS;

 

// Assumes ePWM1 clock is already enabled in InitSysCtrl();

   EPwm1Regs.ETSEL.bit.SOCAEN     = 1;          // Enable SOC on A group

   EPwm1Regs.ETSEL.bit.SOCASEL    = 4;          // Select SOC from CMPA on upcount

   EPwm1Regs.ETPS.bit.SOCAPRD     = 1;          // Generate pulse on 1st event

   EPwm1Regs.CMPA.half.CMPA       = 0x10;     // Set compare A value

   EPwm1Regs.TBPRD                = 0x8000;     // Set period for ePWM1

   EPwm1Regs.TBCTL.bit.CTRMODE    = 0;          // count up and start

 

   // Assumes ePWM2 clock is already enabled in InitSysCtrl();

//      EPwm2Regs.ETSEL.bit.SOCAEN  = 1;          // Enable SOC on B group

//      EPwm2Regs.ETSEL.bit.SOCASEL = 4;          // Select SOC from CMPB on upcount

//      EPwm2Regs.ETPS.bit.SOCAPRD = 1;          // Generate pulse on 1st event

//      EPwm2Regs.CMPA.half.CMPA       = 10;     // Set compare B value

//      EPwm2Regs.TBPRD                = 2250;     // Set period for ePWM1

//      EPwm2Regs.TBCTL.bit.CTRMODE = 0;          // count up and start

 

      EPwm2Regs.ETSEL.bit.SOCBEN  = 1;          // Enable SOC on B group

      EPwm2Regs.ETSEL.bit.SOCBSEL = 6;          // Select SOC from CMPB on upcount

      EPwm2Regs.ETPS.bit.SOCBPRD = 1;          // Generate pulse on 1st event

      EPwm2Regs.CMPB       = 0x2020;     // Set compare B value

      EPwm2Regs.TBPRD                = 0xFFF0;     // Set period for ePWM1

      EPwm2Regs.TBCTL.bit.CTRMODE = 0;          // count up and start

 

      // Wait for ADC interrupt

      // Wait for ADC interrupt

      // Wait for ADC interrupt

// Wait for ADC interrupt

   for(;;)

   {

      LoopCount++;

 

if(flag_need==1)

{

              // Speed from AIN, 3.3V~0.2V==max_speed~min_speedRPM

              temp_speed = user_max_speed/4095;

              temp_speed *= ain_speed;

              // if AIN below 0.2V, set to 0RPM

              if(temp_speed > user_min_speed)

              {

                     flag_start_command=0x00;

              }

              else

              {      //_IQ(1)=16777216~1000RPM, 16777~1RPM

                     //temp_speed *=16777;

                     flag_start_command=0x01;

              }

              flag_need=0;

}

 

   }

 

}

 

 

__interrupt void  adc_isr(void)

{

    hoFault_LED1();

    /*

    if(Flag1 == 0)

    {

       hoFault_LED1();

       Flag1 = 1;

    }

    else

    {

       loFault_LED1();

       Flag1 = 0;

    }

    */

  Voltage1[ConversionCount] = AdcResult.ADCRESULT0;

  Voltage2[ConversionCount] = AdcResult.ADCRESULT1;

  num_isr1++;

 

  // If 20 conversions have been logged, start over

  if(ConversionCount == 9)

  {

     ConversionCount = 0;

  }

  else ConversionCount++;

 

  AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;         //Clear ADCINT1 flag reinitialize for next SOC

  PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;   // Acknowledge interrupt to PIE

//  PieCtrlRegs.PIEACK.bit.ACK1=1;

//  loFault_LED1();

  return;

}

 

__interrupt void  adc_isr2(void)

{

    hoComm_LED1();

    /*

    if(Flag2 == 0)

    {

       hoComm_LED1();

       Flag2 = 1;

    }

    else

    {

       loComm_LED1();

       Flag2 = 0;

    }

    */

  Voltage1[ConversionCount] = AdcResult.ADCRESULT2;

  Voltage2[ConversionCount] = AdcResult.ADCRESULT3;

  Voltage2[ConversionCount] = AdcResult.ADCRESULT4;

  num_isr2++;

 

  // If 20 conversions have been logged, start over

  if(ConversionCount == 9)

  {

     ConversionCount = 0;

  }

  else ConversionCount++;

 

  AdcRegs.ADCINTFLGCLR.bit.ADCINT4 = 1;         //Clear ADCINT1 flag reinitialize for next SOC

//  PieCtrlRegs.PIEACK.all = PIEACK_GROUP10;   // Acknowledge interrupt to PIE

//  PieCtrlRegs.PIEACK.bit.ACK1 = 1;

//  AdcRegs.ADCINTFLGCLR.bit.ADCINT4 = 1;              //Clear ADCINT1 flag reinitialize for next SOC

  PieCtrlRegs.PIEACK.all = PIEACK_GROUP10;   // Acknowledge interrupt to PIE

// loComm_LED1();

  return;

}