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.

LAUNCHXL-F28379D: Can ADC run continuously without being interrupted by EPWM interrupt?

Part Number: LAUNCHXL-F28379D
Other Parts Discussed in Thread: C2000WARE

Hi,

I am having trouble with running ADC continuously.

I set the ADC to run continuously in the main code (initial SOC is software and afterwards is EOC) while the control for the circuit is done in the EPWM interrupt. However, based on my measurement results, it seems that  ADC will only do one conversion (the initial conversion), not run continuously as expected. Could you please tell me whether ADC can run continuously without being interrupted by other interrupts in the system? 

Thanks a lot!

Following is part of my code related to this question:

---------------------------------------------------------------

...

#define RESULTS_BUFFER_SIZE 1000
Uint16 AdcaResults[RESULTS_BUFFER_SIZE];


void InitEPwm2Example(void);
void ConfigureADC(void);
__interrupt void epwm2_isr(void); // interrupt from EPWM2 is used for the control code for the circuit

...

void main(void)
{
InitSysCtrl();
EALLOW;
ClkCfgRegs.PERCLKDIVSEL.bit.EPWMCLKDIV = 1; //EPWMCLK = 100MHz
EDIS;
InitGpio();
CpuSysRegs.PCLKCR2.bit.EPWM1=1;
CpuSysRegs.PCLKCR2.bit.EPWM2=1;
CpuSysRegs.PCLKCR2.bit.EPWM6=1;
InitEPwm1Gpio();
InitEPwm2Gpio();
InitEPwm6Gpio();
DINT;
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.EPWM2_INT = &epwm2_isr;
EDIS; // This is needed to disable write to EALLOW protected registers
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC =0;
EDIS;

InitEPwm1Example();
InitEPwm2Example();
InitEPwm6Example();
ConfigureADC();
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC =1;
EDIS;
IER |= M_INT3;
PieCtrlRegs.PIEIER3.bit.INTx2 = 1;
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM

for(resultsIndex = 0; resultsIndex < RESULTS_BUFFER_SIZE; resultsIndex++)
{
AdcaResults[resultsIndex] = 0;
}
resultsIndex = 0;

//
//software force start SOC0
//
AdcaRegs.ADCSOCFRC1.all = 0x0001;
AdcbRegs.ADCSOCFRC1.all = 0x0001;
AdccRegs.ADCSOCFRC1.all = 0x0001;
// after this, ADC is expected to run continuously since in the ConfigureADC function, it is set "ADCINT1 will trigger SOCs", but the measurement shows that ADC doesn't continuously run

for(;;)
{
asm (" NOP");
}

}

__interrupt void epwm2_isr(void)
{
...// control code omitted

if(resultsIndex <= 800)
{
AdcaResults[resultsIndex++] = AdcaResultRegs.ADCRESULT0;
}// register initalization  cannot readout correct results


EPwm2Regs.ETCLR.bit.INT = 1;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;

}

void InitEPwm2Example()
{
EALLOW;
// Assumes ePWM clock is already enabled
EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
EPwm2Regs.TBPRD = 75; // Same period as PWM1 (PWM1 setting omitted)
EPwm2Regs.TBCTL.bit.PHSEN = 1; // Enable phase loading
EPwm2Regs.TBPHS.bit.TBPHS = 0; // Phase
EPwm2Regs.TBCTR = 0x0000; // Clear counter
EPwm2Regs.TBCTL.bit.HSPCLKDIV = 0; // Clock ratio to SYSCLKOUT
EPwm2Regs.TBCTL.bit.CLKDIV = 0;
EPwm2Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event
EPwm2Regs.ETSEL.bit.INTEN = 1; // Enable INT
EPwm2Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event
EDIS;
}

void ConfigureADC(void)
{
EALLOW;

//
//write configurations
//
AdcaRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4
AdcbRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4
AdccRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4

AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
AdcSetMode(ADC_ADCB, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
AdcSetMode(ADC_ADCC, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
//
//Set pulse positions to late
//
AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;
AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1;
AdccRegs.ADCCTL1.bit.INTPULSEPOS = 1;
//
//power up the ADC
//
AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;
AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1;
AdccRegs.ADCCTL1.bit.ADCPWDNZ = 1;
//
//delay for 1ms to allow ADC time to power up
//
DELAY_US(1000);

EDIS;


EALLOW;
AdcaRegs.ADCSOC0CTL.bit.CHSEL = 5; //SOC0 will convert on ADCINA5 (CS1)
AdcbRegs.ADCSOC0CTL.bit.CHSEL = 2; //SOC0 will convert on ADCINB2 (VS2)
AdccRegs.ADCSOC0CTL.bit.CHSEL = 5; //SOC0 will convert on ADCINC5 (VS1)

AdcaRegs.ADCSOC0CTL.bit.ACQPS = 29; //sample window is acqps + 1 SYSCLK cycles = 150 ns
AdcbRegs.ADCSOC0CTL.bit.ACQPS = 29;
AdccRegs.ADCSOC0CTL.bit.ACQPS = 29;

AdcaRegs.ADCINTSEL1N2.bit.INT1E = 0; //disable INT1 flag
AdcaRegs.ADCINTSEL1N2.bit.INT2E = 0; //disable INT2 flag
AdcaRegs.ADCINTSEL3N4.bit.INT3E = 0; //disable INT3 flag
AdcaRegs.ADCINTSEL3N4.bit.INT4E = 0; //disable INT4 flag
AdcbRegs.ADCINTSEL1N2.bit.INT1E = 0; //disable INT1 flag
AdcbRegs.ADCINTSEL1N2.bit.INT2E = 0; //disable INT2 flag
AdcbRegs.ADCINTSEL3N4.bit.INT3E = 0; //disable INT3 flag
AdcbRegs.ADCINTSEL3N4.bit.INT4E = 0; //disable INT4 flag
AdccRegs.ADCINTSEL1N2.bit.INT1E = 0; //disable INT1 flag
AdccRegs.ADCINTSEL1N2.bit.INT2E = 0; //disable INT2 flag
AdccRegs.ADCINTSEL3N4.bit.INT3E = 0; //disable INT3 flag
AdccRegs.ADCINTSEL3N4.bit.INT4E = 0; //disable INT4 flag

AdcaRegs.ADCINTSEL1N2.bit.INT1CONT = 0;
AdcaRegs.ADCINTSEL1N2.bit.INT2CONT = 0;
AdcaRegs.ADCINTSEL3N4.bit.INT3CONT = 0;
AdcaRegs.ADCINTSEL3N4.bit.INT4CONT = 0;
AdcbRegs.ADCINTSEL1N2.bit.INT1CONT = 0;
AdcbRegs.ADCINTSEL1N2.bit.INT2CONT = 0;
AdcbRegs.ADCINTSEL3N4.bit.INT3CONT = 0;
AdcbRegs.ADCINTSEL3N4.bit.INT4CONT = 0;
AdccRegs.ADCINTSEL1N2.bit.INT1CONT = 0;
AdccRegs.ADCINTSEL1N2.bit.INT2CONT = 0;
AdccRegs.ADCINTSEL3N4.bit.INT3CONT = 0;
AdccRegs.ADCINTSEL3N4.bit.INT4CONT = 0;

AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0; //end of SOC0 will set INT1 flag
AdcbRegs.ADCINTSEL1N2.bit.INT1SEL = 0; //end of SOC0 will set INT1 flag
AdccRegs.ADCINTSEL1N2.bit.INT1SEL = 0; //end of SOC0 will set INT1 flag

AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;
AdcaRegs.ADCINTFLGCLR.all = 0x000F;
AdcbRegs.ADCINTSEL1N2.bit.INT1E = 1;
AdcbRegs.ADCINTFLGCLR.all = 0x000F;
AdccRegs.ADCINTSEL1N2.bit.INT1E = 1;
AdccRegs.ADCINTFLGCLR.all = 0x000F;

//
//ADCINT1 will trigger SOCs
//
AdcaRegs.ADCINTSOCSEL1.bit.SOC0 = 1;
AdcbRegs.ADCINTSOCSEL1.bit.SOC0 = 1;
AdccRegs.ADCINTSOCSEL1.bit.SOC0 = 1;

EDIS;
}

  • Le Wang,

    Please try this C2000Ware example to see if continuous sampling works:

    ~\C2000Ware_XXXX\device_support\f2837xd\examples\cpu1\adc_soc_continuous

    If it does work, you can refer to its ADC software configuration. If it does not work, there may be something wrong with the hardware.

    -Tommy

  • Hi Tommy,

    Thank you for your reply. But this example code doesn't help my question since there is no EPWM interrupt in this example. I can run ADC continuously well also if there is no EPWM interrupt. My question is, for C2000, is it that  ADC cannot run continuously without being interrupted when there is other EPWM interrupt in the system?

    Thanks.

    Le 

  • Le,

    I am having difficulty in understanding your intent. Perhaps there is some difference in interpretation of terminology.

    Can you restate your desired behavior for the system with an example sequence of events?

    -Tommy