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.

28335 ADC



Hi,

with the F28335 Experimenter’s Kit I tried to sampling 16signals with the built-in ADC module in the quickest way. I programmed the ADC in simultaneous sampling mode using the ePWM1A to drive the ADC SOC signal.

To measure the timing I rise a GPIO at the start of the interrupt adc_isr.

The result is that between the center PWM of the ePWM1A and the start of the interrupt adc_isr there is 1,66uS.

1)     It is not too high ? From the datasheet I think that it must be about td+tsh+tdschB0_0+ tdschB0_n1*7=100+40+200+120*7=1180nS.

2)     I rise a GPIO drive from a the epwm1_isr programmed to start when the counter equal to period and I found a delay from the center PWM of the ePWM1A of 290nS, is this correct ?

3)     I use another interrupt link to timer0 but when it start near the adc_isr it block  the start of the adc_isr. What can I do ?

 

Thanks in advance for all your support.

 

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

#include "IQmathLib.h"

#include <stdio.h>

_iq angolo;

_iq sinOut;

 

 

// Prototype statements for functions found within this file.

void InitEPwm1Example(void);

interrupt void epwm1_isr(void);

//void update_compare(EPWM_INFO*);

void updateCompare(void);

//interrupt void epwm1_tzint_isr(void);

interrupt void adc_isr(void);

interrupt void cpu_timer0_isr(void);

 

 

 

 // Configure the period for each timer

 #define EPWM1_TIMER_TBPRD  20000  // Period register

 //#define EPWM1_MAX_CMPA     1950

 #define EPWM1_MIN_CMPA       50

 #define EPWM1_MAX_CMPB     1950

 #define EPWM1_MIN_CMPB       50

 

 

 // To keep track of which way the compare value is moving

 #define EPWM_CMP_UP   1

 #define EPWM_CMP_DOWN 0

 

// Maximum Dead Band values

 

#define EPWM1_DB   100

 

 

#define PUNTIACQ   100

 

// Global variables used in this example:

Uint16 LoopCount;

Uint16 ConversionCount;

Uint16 Voltage1[PUNTIACQ];

Uint16 Voltage2[PUNTIACQ];

Uint16 Voltage3[PUNTIACQ];

Uint16 Voltage4[PUNTIACQ];

Uint16 Voltage5[PUNTIACQ];

Uint16 Voltage6[PUNTIACQ];

Uint16 Voltage7[PUNTIACQ];

Uint16 Voltage8[PUNTIACQ];

Uint16 Voltage9[PUNTIACQ];

Uint16 Voltage10[PUNTIACQ];

Uint16 Voltage11[PUNTIACQ];

Uint16 Voltage12[PUNTIACQ];

Uint16 Voltage13[PUNTIACQ];

Uint16 Voltage14[PUNTIACQ];

Uint16 Voltage15[PUNTIACQ];

Uint16 Voltage16[PUNTIACQ];

 

// These are defined by the linker (see F28335.cmd)

extern Uint16 RamfuncsLoadStart;

extern Uint16 RamfuncsLoadEnd;

extern Uint16 RamfuncsRunStart;

 

 

float y1, y2;

float m1, m2;

float x1, x2;

float b1, b2;

 

int32 yInt32;

int32 mInt32;

int32 xInt32;

int32 bInt32;

 

void main(void)

{

   extern void DSP28x_usDelay(Uint32 Count);

// Step 1. Initialize System Control:

// PLL, WatchDog, enable Peripheral Clocks

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

   InitSysCtrl();

 

// Default - 150 MHz SYSCLKOUT

   #define ADC_MODCLK 0x3 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3)   = 25.0 MHz

 

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

   EDIS;

 

// Step 2. Initalize 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

 

   InitEPwm1Gpio();

 

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

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

 

   MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);

   InitFlash(); // The flash initialization routine should be executed from RAM.

 

// 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 registers

   PieVectTable.TINT0 = &cpu_timer0_isr;

   PieVectTable.EPWM1_INT = &epwm1_isr;

   PieVectTable.ADCINT = &adc_isr;

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

 

// Step 4. Initialize the Device Peripheral. This function can be

//         found in DSP2833x_CpuTimers.c

   InitCpuTimers();   // For this example, only initialize the Cpu Timers

 

// Configure CPU-Timer 0 to interrupt every 500 milliseconds:

// 150MHz CPU Freq, 50 millisecond Period (in uSeconds)

//  ConfigCpuTimer(&CpuTimer0, 150, 500000);

   ConfigCpuTimer(&CpuTimer0, 150,     100); // 0.1uS

 

 

// To ensure precise timing, use write-only instructions to write to the entire register. Therefore, if any

// of the configuration bits are changed in ConfigCpuTimer and InitCpuTimers (in DSP2833x_CpuTimers.h), the

// below settings must also be updated.

 

   CpuTimer0Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0

 

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

 

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

 

 

 

// Configure GPIO32 as a GPIO output pin

   EALLOW;

   GpioCtrlRegs.GPAMUX2.bit.GPIO31 = 0;

   GpioCtrlRegs.GPADIR.bit.GPIO31 = 1;

   GpioCtrlRegs.GPAMUX2.bit.GPIO30 = 0;

   GpioCtrlRegs.GPADIR.bit.GPIO30 = 1;

   SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;

   EDIS;

 

   InitEPwm1Example();

 

   EALLOW;

   SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;

   EDIS;

 

 

// Enable CPU INT3 which is connected to EPWM1-3 INT:

   IER |= M_INT2;

 

// Enable TINT0 in the PIE: Group 1 interrupt 7

   PieCtrlRegs.PIEIER1.bit.INTx7 = 1;

 

// Enable EPWM INTn in the PIE: Group 2 interrupt 1-3

   PieCtrlRegs.PIEIER2.bit.INTx1 = 1;

   PieCtrlRegs.PIEIER2.bit.INTx2 = 1;

 

// Enable CPU INT3 which is connected to EPWM1-3 INT:

   IER |= M_INT3;

 

// Enable EPWM INTn in the PIE: Group 3 interrupt 1-3

   PieCtrlRegs.PIEIER3.bit.INTx1 = 1;

 

// Enable ADCINT in PIE

   PieCtrlRegs.PIEIER1.bit.INTx6 = 1;

   IER |= M_INT1; // Enable CPU Interrupt 1

 

// Enable global Interrupts and higher priority real-time debug events:

   EINT;   // Enable Global interrupt INTM

   ERTM;   // Enable Global realtime interrupt DBGM

 

   angolo=0;

   sinOut=0;

 

   LoopCount = 0;

   ConversionCount = 0;

 

// Configure ADC

// Simultaneous Sampling Dual Sequencer Mode Example

 

 

   AdcRegs.ADCREFSEL.bit.REF_SEL = 0;

 

   AdcRegs.ADCTRL3.bit.ADCBGRFDN = 0x3;    /* bit7-6(11): ADCBGRFDN, reference power, 00=off, 11=on */

   AdcRegs.ADCTRL3.bit.ADCPWDN = 0x1;      /* bit5(1): ADCPWDN, main ADC power, 0=off, 1=on */

   AdcRegs.ADCTRL3.bit.ADCCLKPS = 0x0;/* bit4-1(0100): ADCCLKPS, clock prescaler, ADCLK=HSPCLK/[(2*ADCCLKPS)*(ADCTRL1[7] + 1)] */

   AdcRegs.ADCTRL3.bit.SMODE_SEL = 0x1;    /* bit0(1): SMODE_SEL, 0=sequential sampling, 1=simultaneous sampling */

 

   DSP28x_usDelay(5000);                            /* Wait 5ms before using the ADC */

   AdcRegs.ADCMAXCONV.all = 0x0007;        /* 8 double conv's (16 total) */

 

   AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0;  /* Setup conv from ADCINA0 and ADCINB0 */

   AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1;  /* Setup conv from ADCINA1 and ADCINB1 */

   AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x2;  /* Setup conv from ADCINA2 and ADCINB2 */

   AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x3;  /* Setup conv from ADCINA3 and ADCINB3 */

   AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x4;  /* Setup conv from ADCINA4 and ADCINB4 */

   AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x5;  /* Setup conv from ADCINA5 and ADCINB5 */

   AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x6;  /* Setup conv from ADCINA6 and ADCINB6 */

   AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x7;  /* Setup conv from ADCINA7 and ADCINB7 */

 

   AdcRegs.ADCTRL1.bit.RESET = 0x0;            /* bit14(0): RESET, 0=no action, 1=reset ADC */

   AdcRegs.ADCTRL1.bit.SUSMOD = 0x00;      /* bit13-12(00): emulation suspend is ignored */

   AdcRegs.ADCTRL1.bit.ACQ_PS = 0x00; // 0x07;       /* bit11-8(0111): ACQ_PS (Acquisition), 0100 = 5 x ADCCLK */

   AdcRegs.ADCTRL1.bit.CPS = 0x0;        /* bit7(0): CPS (Core clock), 0: ADCCLK=FCLK/1, 1: ADCCLK=FCLK/2 */

   AdcRegs.ADCTRL1.bit.CONT_RUN = 0x0;   /* bit6(0): CONT_RUN, 0=start/stop mode, 1=continuous run */

   AdcRegs.ADCTRL1.bit.SEQ_OVRD = 0x0;    /* bit5(0): SEQ_OVRD, 0=disabled, 1=enabled */

   AdcRegs.ADCTRL1.bit.SEQ_CASC = 0x1; //0x1;    /* bit4(1): SEQ_CASC, 0=dual sequencer, 1=cascaded sequencer */

 

 

 

   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)

 

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

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

   EPwm1Regs.ETSEL.bit.SOCASEL = 2;  //Enable event time-base counter equal to period (TBCTR = TBPRD)

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

 

 

   y1 = 0;

   y2 = 0;

   m1 = .5;

   m2 = .6;

   x1 = 3.4;

   x2 = 7.3;

   b1 = 4.2;

   b2 = 8.9;

 

 

   yInt32 = 0;

   mInt32 = 100;

   xInt32 = 200;

   bInt32 = 50;

 

   printf(" hello world!\n");

 

 

// Step 6. IDLE loop. Just sit and loop forever (optional):

  for(;;)

   {

     y1 = m1*x1 + b1; //160nS

 

     yInt32 = mInt32 * xInt32 + bInt32;

   }

}

 

 

 

 

interrupt void  adc_isr(void)

{

  GpioDataRegs.GPACLEAR.bit.GPIO31 = 1;

 

  Voltage1[ConversionCount] = AdcRegs.ADCRESULT0 >>4;

  Voltage2[ConversionCount] = AdcRegs.ADCRESULT1 >>4;

  Voltage3[ConversionCount] = AdcRegs.ADCRESULT2 >>4;

  Voltage4[ConversionCount] = AdcRegs.ADCRESULT3 >>4;

  Voltage5[ConversionCount] = AdcRegs.ADCRESULT4 >>4;

  Voltage6[ConversionCount] = AdcRegs.ADCRESULT5 >>4;

  Voltage7[ConversionCount] = AdcRegs.ADCRESULT6 >>4;

  Voltage8[ConversionCount] = AdcRegs.ADCRESULT7 >>4;

  Voltage9[ConversionCount] = AdcRegs.ADCRESULT8 >>4;

  Voltage10[ConversionCount] = AdcRegs.ADCRESULT9 >>4;

  Voltage11[ConversionCount] = AdcRegs.ADCRESULT10 >>4;

  Voltage12[ConversionCount] = AdcRegs.ADCRESULT11 >>4;

  Voltage13[ConversionCount] = AdcRegs.ADCRESULT12 >>4;

  Voltage14[ConversionCount] = AdcRegs.ADCRESULT13 >>4;

  Voltage15[ConversionCount] = AdcRegs.ADCRESULT14 >>4; //  ADCINA7 -> ADCRESULT14

  Voltage16[ConversionCount] = AdcRegs.ADCRESULT15 >>4;

 

  if(ConversionCount == 99)

     ConversionCount = 0;

  else

         ConversionCount++;

 

  updateCompare();

 

 

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

}

 

 

 

interrupt void cpu_timer0_isr(void)

{

   // 0.1uS

 

 

   GpioDataRegs.GPASET.bit.GPIO30 = 1;

 

 

   sinOut= _IQ15sin(_IQ15(angolo*2*3.14/200));

 

   sinOut = _IQ15mpy(sinOut ,EPWM1_TIMER_TBPRD/2);

 

   if (angolo <=200 )

          angolo++;

   else

          angolo=0;

 

   GpioDataRegs.GPACLEAR.bit.GPIO30 = 1;

 

   // Acknowledge this interrupt to receive more interrupts from group 1

   PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;

}

 

 

interrupt void epwm1_isr(void)

{

   GpioDataRegs.GPASET.bit.GPIO31 = 1;

 

// Clear INT flag for this timer

   EPwm1Regs.ETCLR.bit.INT = 1;

 

// Acknowledge this interrupt to receive more interrupts from group 3

   PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;

}

 

void InitEPwm1Example()

{

   // Setup TBCLK

   EPwm1Regs.TBPRD = EPWM1_TIMER_TBPRD;           // Set timer period 801 TBCLKs

   EPwm1Regs.TBPHS.half.TBPHS = 0x0000;           // Phase is 0

   EPwm1Regs.TBCTR = 0x0000;                      // Clear counter

 

   // Set Compare values

   EPwm1Regs.CMPA.half.CMPA = EPWM1_MIN_CMPA;     // Set compare A value

   EPwm1Regs.CMPB = EPWM1_MAX_CMPB;               // Set Compare B value

 

   // Setup counter mode

   EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up

   EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;        // Disable phase loading

   EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT

   EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;

 

   // Setup shadowing

   EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;

   EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;

   EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;  // Load on Zero

   EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

 

   // Set actions

   EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;             // Set PWM1A on event A, up count

   EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;           // Clear PWM1A on event A, down count

 

   EPwm1Regs.AQCTLB.bit.CBU = AQ_SET;             // Set PWM1B on event B, up count

   EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR;           // Clear PWM1B on event B, down count

 

 

// Interrupt where we will change the Compare Values

   EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_PRD;

   EPwm1Regs.ETSEL.bit.INTEN = 1;                 // Enable INT

   EPwm1Regs.ETPS.bit.INTPRD =1;

 

}

 

 

void updateCompare(void)

{

       EPwm1Regs.CMPA.half.CMPA=  EPWM1_TIMER_TBPRD/2 + sinOut;

       EPwm1Regs.CMPB=  EPWM1_TIMER_TBPRD/2 - sinOut;

}