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/TMS320F28335: how to read ADC values simultaneously and as fast as possible?

Part Number: TMS320F28335


Tool/software: Code Composer Studio

Hello

I am trying to do a project in which I need to read three values using ADC and do some processing on these data and select appropriate GPIO. Also I need to measure the elapsed time in each loop and use that time in my calculations. I have used three examples : ADCSOC, CpuTimer, GPIOSetup. My questions:

1. When I get ADC values, and watch them in variables they change to a value and then change to zero and continue to do this. How can I read the ADC values simultaneously and as fast as possible. (I don't know which triggering is the fastest). Which parts of the code should I change?

2. After building the project I get an error: "warning #10063-D: entry-point symbol other than "_c_int00" specified:  "code_start"". What is this error?

I am copying my code here, I really appreciate it if you take a look and see which part of the code I need to change:



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

// functions
void delay_loop(void);
void Gpio_select(void);
void Gpio_setup1(void);
void Gpio_setup2(void);
void Gpio_setup3(void);
void StartTimer(void);
void StopTimer(void);
void adc_isr(void);

double phi1(double cur, double vol, double t);

double phi2(double cur, double vol, double t);

double phi3(double cur, double vol, double t);

double phi4(double cur, double vol, double t);

double phi5(double cur, double vol, double t);

double phi6(double cur, double vol, double t);


double phi16(double cur, double vol, double t);


double phi17(double cur, double vol, double t) ;

double phi18(double cur, double vol, double t);

double phi31(double cur, double vol, double t);

double phi32(double cur, double vol, double t);

double phi33(double cur, double vol, double t);



double f1_1(double cur, double vol);

double f1_2(double cur, double vol);

double f2_1(double cur, double vol);

double f2_2(double cur, double vol);

double f3_1(double cur, double vol);

double f3_2(double cur, double vol);




//global variables
int fr=50;    //frequency in Hertz
int fr_unit_change=1;
long double t1=0;
long double delta_time;
double cpuTime1;
double cpuTime2;
double cpuTime;
double LoopCount;
double ConversionCount;
double Voltage1;
double Voltage2;
double Voltage3;
double current=0;
double voltage=0;
double vol1=0;
double cur1=0;
double dt=0.00002;
double sum1=0;
double sum2=0;
double sum3=0;
double W[12] = {  115.9200,
                 0.4708,
                 1.0362,
                14.8852,
               228.9501,
                84.3829,
                -1.7023,
                -0.9528,
                -3.9271,
                -1.6024,
               -89.6407,
              -470.1129};

int R1=10;     //inductor internal resistance
double L1=560e-6;  //inductor
double C1=100e-6;  //capacitor
double Vs=3.3;       // input DC voltage
int RL=10;      // Load

int f=1;   // Changing time unit   t=f*tau
int a=1;       // normalizing capacitor voltage   Vc=a*vol
int b=1;       // normalizing inductor current   Il=b*cur
double w=2*3.14;



void main(void)
{
    InitSysCtrl();




    EALLOW;
    #define ADC_MODCLK 0x3
    EDIS;


    EALLOW;
    SysCtrlRegs.HISPCP.all = ADC_MODCLK;
    EDIS;

    DINT;
    InitPieCtrl();

    Gpio_select();

    //
    // 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();

    InitCpuTimers();   // For this example, only initialize the Cpu Timers
for(;;){
    StartTimer();
    EALLOW;  // This is needed to write to EALLOW protected register
    PieVectTable.ADCINT = &adc_isr;
    EDIS;    // This is needed to disable write to EALLOW protected registers

    InitAdc();  // For this example, init the ADC
    PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
    IER |= M_INT1;      // Enable CPU Interrupt 1
    EINT;               // Enable Global interrupt INTM
    ERTM;               // Enable Global realtime interrupt DBGM

    //

      LoopCount = 0;
      ConversionCount = 0;

      //
      // Configure ADC
      //
      AdcRegs.ADCMAXCONV.all = 0x0002;       // Setup 2 conv's on SEQ1
      AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x2; // Setup ADCINA2 as 1st SEQ1 conv.
      AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x3; // Setup ADCINA3 as 2nd SEQ1 conv.
      AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x4;
      //
      // Enable SOCA from ePWM to start SEQ1
      //
      AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;

      AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;  // Enable SEQ1 interrupt (every EOS)

      //
      // 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 from CPMA on upcount
      EPwm1Regs.ETPS.bit.SOCAPRD = 1;     // Generate pulse on 1st event
      EPwm1Regs.CMPA.half.CMPA = 0x0080;  // Set compare A value
      EPwm1Regs.TBPRD = 0xFFFF;           // Set period for ePWM1
      EPwm1Regs.TBCTL.bit.CTRMODE = 0;    // count up and start

      //
      // Wait for ADC interrupt
      //

      vol1 = voltage*3/4095;
      cur1 = current*3/4095;

      sum1=W[0]*phi1(f1_1(cur1,vol1),f1_2(cur1,vol1),fmod(t1,1)+dt)+W[1]*phi2(f1_1(cur1,vol1),f1_2(cur1,vol1),fmod(t1,1)+dt)+W[2]*phi3(f1_1(cur1,vol1),f1_2(cur1,vol1),fmod(t1,1)+dt)+W[3]*phi4(f1_1(cur1,vol1),f1_2(cur1,vol1),fmod(t1,1)+dt)+W[4]*phi5(f1_1(cur1,vol1),f1_2(cur1,vol1),fmod(t1,1)+dt)+W[5]*phi6(f1_1(cur1,vol1),f1_2(cur1,vol1),fmod(t1,1)+dt)+W[6]*phi16(f1_1(cur1,vol1),f1_2(cur1,vol1),fmod(t1,1)+dt)+W[7]*phi17(f1_1(cur1,vol1),f1_2(cur1,vol1),fmod(t1,1)+dt)+W[8]*phi18(f1_1(cur1,vol1),f1_2(cur1,vol1),fmod(t1,1)+dt)+W[9]*phi31(f1_1(cur1,vol1),f1_2(cur1,vol1),fmod(t1,1)+dt)+W[10]*phi32(f1_1(cur1,vol1),f1_2(cur1,vol1),fmod(t1,1)+dt)+W[11]*phi33(f1_1(cur1,vol1),f1_2(cur1,vol1),fmod(t1,1)+dt);

      sum2=W[0]*phi1(f2_1(cur1,vol1),f2_2(cur1,vol1),fmod(t1,1)+dt)+W[1]*phi2(f2_1(cur1,vol1),f2_2(cur1,vol1),fmod(t1,1)+dt)+W[2]*phi3(f2_1(cur1,vol1),f2_2(cur1,vol1),fmod(t1,1)+dt)+W[3]*phi4(f2_1(cur1,vol1),f2_2(cur1,vol1),fmod(t1,1)+dt)+W[4]*phi5(f2_1(cur1,vol1),f2_2(cur1,vol1),fmod(t1,1)+dt)+W[5]*phi6(f2_1(cur1,vol1),f2_2(cur1,vol1),fmod(t1,1)+dt)+W[6]*phi16(f2_1(cur1,vol1),f2_2(cur1,vol1),fmod(t1,1)+dt)+W[7]*phi17(f2_1(cur1,vol1),f2_2(cur1,vol1),fmod(t1,1)+dt)+W[8]*phi18(f2_1(cur1,vol1),f2_2(cur1,vol1),fmod(t1,1)+dt)+W[9]*phi31(f2_1(cur1,vol1),f2_2(cur1,vol1),fmod(t1,1)+dt)+W[10]*phi32(f2_1(cur1,vol1),f2_2(cur1,vol1),fmod(t1,1)+dt)+W[11]*phi33(f2_1(cur1,vol1),f2_2(cur1,vol1),fmod(t1,1)+dt);

      sum3=W[0]*phi1(f3_1(cur1,vol1),f3_2(cur1,vol1),fmod(t1,1)+dt)+W[1]*phi2(f3_1(cur1,vol1),f3_2(cur1,vol1),fmod(t1,1)+dt)+W[2]*phi3(f3_1(cur1,vol1),f3_2(cur1,vol1),fmod(t1,1)+dt)+W[3]*phi4(f3_1(cur1,vol1),f3_2(cur1,vol1),fmod(t1,1)+dt)+W[4]*phi5(f3_1(cur1,vol1),f3_2(cur1,vol1),fmod(t1,1)+dt)+W[5]*phi6(f3_1(cur1,vol1),f3_2(cur1,vol1),fmod(t1,1)+dt)+W[6]*phi16(f3_1(cur1,vol1),f3_2(cur1,vol1),fmod(t1,1)+dt)+W[7]*phi17(f3_1(cur1,vol1),f3_2(cur1,vol1),fmod(t1,1)+dt)+W[8]*phi18(f3_1(cur1,vol1),f3_2(cur1,vol1),fmod(t1,1)+dt)+W[9]*phi31(f3_1(cur1,vol1),f3_2(cur1,vol1),fmod(t1,1)+dt)+W[10]*phi32(f3_1(cur1,vol1),f3_2(cur1,vol1),fmod(t1,1)+dt)+W[11]*phi33(f3_1(cur1,vol1),f3_2(cur1,vol1),fmod(t1,1)+dt);

      if ((sum1<=sum2) && (sum1<=sum3)) {
          Gpio_setup1();
      }
      else if ((sum2<=sum1) && (sum2<=sum3)) {
          Gpio_setup2();
      }
      else {
          Gpio_setup3();
      }

      StopTimer();
      delta_time=cpuTime*6.66e-9;
      t1=t1+delta_time;
}
}

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////

void Gpio_select(void)
{
    EALLOW;
    //GpioCtrlRegs.GPAPUD.bit.GPIO6 = 0;   // Enable pullup on GPIO6

    GpioCtrlRegs.GPAMUX1.bit.GPIO6 = 0; // GPIO6 = GPIO6
    GpioCtrlRegs.GPADIR.bit.GPIO6 = 1;   // GPIO6 = output
    GpioCtrlRegs.GPAMUX1.bit.GPIO7 = 0;
    GpioCtrlRegs.GPADIR.bit.GPIO7 = 1;
    GpioCtrlRegs.GPAMUX1.bit.GPIO8 = 0;
    GpioCtrlRegs.GPADIR.bit.GPIO8 = 1;
    GpioCtrlRegs.GPAMUX1.bit.GPIO9 = 0;
    GpioCtrlRegs.GPADIR.bit.GPIO9 = 1;
    EDIS;
}

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////


void StartTimer(void)
{
   // cpuTime1 = 0;

    EALLOW;
    CpuTimer2Regs.TCR.bit.TRB = 1;        // Reset CPU timer to period value
    CpuTimer2Regs.TCR.bit.TSS = 0;        // Start or reset CPU timer 2
    cpuTime1 = CpuTimer2Regs.TIM.all;     // Get value of CPU Timer 2 before code
    EDIS;
}

void StopTimer(void)
{

    EALLOW;
    cpuTime2 = CpuTimer2Regs.TIM.all;    // Get value of CPU Timer 2 after code
    cpuTime = cpuTime1 - cpuTime2;     // Calculate time using cpuTimer2
    CpuTimer2Regs.TCR.bit.TSS = 1;        // Start or reset CPU timer 2
    EDIS;
}

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
__interrupt void
adc_isr(void)
{
    Voltage1 = AdcRegs.ADCRESULT0 >>4;
    Voltage2 = AdcRegs.ADCRESULT1 >>4;
    Voltage3 = AdcRegs.ADCRESULT2 >>4;
    current = Voltage2- Voltage1;
    voltage = Voltage3- Voltage2;

    //
    // If 40 conversions have been logged, start over
    //

    //
    // 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;
}

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////

  • Ata,

    It looks like you have the full module initialization calls inside of your main() loop.  This is not recommended because the initialization sequence can intrusively disrupt the modules during operation.  I suspect this is why your ADC results are resetting to 0.

    The ADC ISR is generally the easiest way to access the results soon after they are ready.

    The entry-point warning is showing because by default the compiler will begin code execution at "_c_int00" where the C-environment is initialized.  For these example projects, the code execution entry-point is overridden to "code_start" in xxx_CodeStartBranch.asm.  This is primarily so that the watchdog can be disabled before jumping to the "_c_int00" section.

    -Tommy

  • Thank you Tommy.
    Could you please specify which initialization you mean? because in the template examples all the initialization are in the main () loop.
  • Just about everything in the for(;;) loop except for the actual math.

    Module / Lab 6 might be helpful for reference: processors.wiki.ti.com/.../C2000_Archived_Workshops