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.

F28035 the maximum frequency of ADC Sampling

Dear all:

              I am working on a project that the ADC Sample is triggered by epwm1 at 350kHZ, and EOC0 trigger the CLAINT1, I read the ADCRESULT0 in the cla isr. I have found the result is unstabled. when I set the SOCAPRD = 2, the result is stabled.

               Is it the sample frequency too high?Here is my part of code.       Please help me figure out.

void InitAdc(void)
{

extern void DSP28x_usDelay(Uint32 Count);

// *IMPORTANT*
// The Device_cal function, which copies the ADC calibration values from TI reserved
// OTP into the ADCREFSEL and ADCOFFTRIM registers, occurs automatically in the
// Boot ROM. If the boot ROM code is bypassed during the debug process, the
// following function MUST be called for the ADC to function according
// to specification. The clocks to the ADC MUST be enabled before calling this
// function.
// See the device data manual and/or the ADC Reference
// Manual for more information.

EALLOW;
SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;
(*Device_cal)();
EDIS;

// To powerup the ADC the ADCENCLK bit should be set first to enable
// clocks, followed by powering up the bandgap, reference circuitry, and ADC core.
// Before the first conversion is performed a 5ms delay must be observed
// after power up to give all analog circuits time to power up and settle

// Please note that for the delay function below to operate correctly the
// CPU_RATE define statement in the DSP2803x_Examples.h file must
// contain the correct CPU clock period in nanoseconds.
EALLOW;
AdcRegs.ADCCTL1.bit.ADCREFSEL = 0; // Select interal BG
AdcRegs.ADCCTL1.bit.ADCBGPWD = 1; // Power ADC BG
AdcRegs.ADCCTL1.bit.ADCREFPWD = 1; // Power reference
AdcRegs.ADCCTL1.bit.ADCPWDN = 1; // Power ADC
AdcRegs.ADCCTL1.bit.ADCENABLE = 1; // Enable ADC

EDIS;

DELAY_US(ADC_usDELAY); // Delay before converting ADC channels

// Configure ADC
EALLOW;

AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1; //ADCINT1 trips after AdcResults latch
AdcRegs.INTSEL1N2.bit.INT1E = 1; //Enabled ADCINT1
AdcRegs.INTSEL1N2.bit.INT1CONT = 1; //Disable ADCINT1 Continuous mode
AdcRegs.INTSEL1N2.bit.INT1SEL = 0; //setup EOC0 to trigger ADCINT1 to fire
//AdcRegs.SOCPRICTL.bit.SOCPRIORITY = 2; //SOC0,SOC1,SOC2 ,SOC3and SOC4 are high priority

AdcRegs.ADCSOC0CTL.bit.CHSEL = 0x1; //set SOC0 channel select to ADCINA1 (V_PI_OUT)
AdcRegs.ADCSOC1CTL.bit.CHSEL = 0x2; //set SOC1 channel select to ADCINA2 (I_PI_OUT)
AdcRegs.ADCSOC2CTL.bit.CHSEL = 0x3; //set SOC2 channel select to ADCINA3 (VO)
AdcRegs.ADCSOC3CTL.bit.CHSEL = 0x4; //set SOC3 channel select to ADCINA4 (IO)
AdcRegs.ADCSOC4CTL.bit.CHSEL = 0x6; //set SOC4 channel select to ADCINA6 (REF_2V5)
AdcRegs.ADCSOC5CTL.bit.CHSEL = 0x7; //set SOC5 channel select to ADCINA7 (V3.3)
AdcRegs.ADCSOC6CTL.bit.CHSEL = 0x8; //set SOC6 channel select to ADCINB0 (12VS)
AdcRegs.ADCSOC7CTL.bit.CHSEL = 0x9; //set SOC7 channel select to ADCINB1 (5VS)
AdcRegs.ADCSOC8CTL.bit.CHSEL = 0xA; //set SOC8 channel select to ADCINB2 (TEMP_HOT)


AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 0x5; //set SOC0 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
AdcRegs.ADCSOC1CTL.bit.TRIGSEL = 0x5; //set SOC1 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
AdcRegs.ADCSOC2CTL.bit.TRIGSEL = 0x5; //set SOC2 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
AdcRegs.ADCSOC3CTL.bit.TRIGSEL = 0x5; //set SOC3 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
AdcRegs.ADCSOC4CTL.bit.TRIGSEL = 0x5; //set SOC4 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
AdcRegs.ADCSOC5CTL.bit.TRIGSEL = 0x5; //set SOC5 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
AdcRegs.ADCSOC6CTL.bit.TRIGSEL = 0x5; //set SOC6 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
AdcRegs.ADCSOC7CTL.bit.TRIGSEL = 0x5; //set SOC7 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
AdcRegs.ADCSOC8CTL.bit.TRIGSEL = 0x5; //set SOC8 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1


AdcRegs.ADCSOC0CTL.bit.ACQPS = 6;//set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
AdcRegs.ADCSOC1CTL.bit.ACQPS = 6;//set SOC1 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
AdcRegs.ADCSOC2CTL.bit.ACQPS = 6;//set SOC2 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
AdcRegs.ADCSOC3CTL.bit.ACQPS = 6;//set SOC3 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
AdcRegs.ADCSOC4CTL.bit.ACQPS = 6;//set SOC4 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
AdcRegs.ADCSOC5CTL.bit.ACQPS = 6;//set SOC5 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
AdcRegs.ADCSOC6CTL.bit.ACQPS = 6;//set SOC6 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
AdcRegs.ADCSOC7CTL.bit.ACQPS = 6;//set SOC7 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
AdcRegs.ADCSOC8CTL.bit.ACQPS = 6;//set SOC8 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

// Assumes ePWM6 clock is already enabled in InitSysCtrl();
EPwm1Regs.ETSEL.bit.SOCAEN = 1;// Enable SOC on A group
EPwm1Regs.ETSEL.bit.SOCASEL = 1;// Enable event time-base counter equal to CMPA. (TBCTR = 0x0000)
EPwm1Regs.ETPS.bit.SOCAPRD = 2; // Generate pulse on 1st ev
EDIS;
// Wait for ADC interrupt
DSP28x_usDelay(100);

}

  • AdcRegs.ADCSOC0CTL.bit.CHSEL = 0x1; //set SOC0 channel select to ADCINA1 (V_PI_OUT)
    AdcRegs.ADCSOC1CTL.bit.CHSEL = 0x2; //set SOC1 channel select to ADCINA2 (I_PI_OUT)

    when EPwm1Regs.ETPS.bit.SOCAPRD = 1,

    AdcResult.ADCRESULT0 is unstabled, the value is between 868 and 902.

    if I use AdcRegs.ADCSOC0CTL.bit.CHSEL = 0x2; AdcRegs.ADCSOC1CTL.bit.CHSEL = 0x1;

    the AdcResult.ADCRESULT1  is stabled, the value is 872. ADCRESULT0 is still unstabled.

  • Hi Edwin,

    You have 9 SOCs at 350kHz = 3.15MSPS.  In overlap mode, the ADC can do 4.6MSPS, so it should be possible.

    However, if the sampling code is interrupt driven, you also have to leave time to collect the samples before they are overwritten.  In this case, the total time for the samples to complete is about 13 * number of samples + 7 ADCCLKs. For 9 samples this is 124 cycles. For 350kHz, you have only 171 cycles between triggers, so the timing will be tight (also keep in mind that time for ISR context switch time is about 14 cycles).

    For the code you posted, INT1SEL is set to 0, so the ISR will be triggered after only ADCRESULT0 has been completed.  This may lead to some instability in other results as you may or may not read updated values depending on when the samples complete.  A better approach would be to trigger the ISR on the second-to-last sample, (INT1SEL = 7), so that by the time the ISR is entered, the last sample has just completed.

    You also should look at the first sample issue in the F28035 errata.  Because of this, you will probably want to add one more conversion to the beginning of your sequence.  You don't need to actually read this conversion result.