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