A related question is a question created from another question. When the related question is created, it will be automatically linked to the original question.
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.
TMS320F28379D: config ADC to perform sequential SOC conversions ons SW trigger
Hello there, I´m a bit confused About how to configure the ADC to do Serial conversions on a few SOC´s. The Controller has 3 ADC´s 1 to 3. On each ADC I want SOC 0 to 3 to perform a sequential conversion and SOC3 of ADC_A to throw an Interrupt when done. Until 2 weeks ago everything worked fine but now I observe faulty behavior and I´m doubting if I have done the a correct configuration.
1st Thing I don´t understand is the difference of ADCIN1/2 and the "four flexible PIE Interrupts" (see spruhm8f / Reference Manual -> 10.1.1 Features) I think ADCIN1/2 do NOT mean an Interrupt to the CPU but only for ADC internal Purpose?
2nd Thing in spruhm8f / Reference Manual -> 10.1.4.2 Trigger Operation it is said, "This is useful for creating continuous conversions." I think it means continous conversions of the same SOC? Or does it mean one SOC can trigger another one? How would one configure that? 3thrd my solution Regading my Goal to create a sequential conversion of SOC 0 to 3, I make use of the round Robin scheeme explained in spruhm8f / Reference Manual -> 10.1.6 ADC Conversion Priority. The way I understand this is it is good, if I set SOC 3 to throw an Interrupt when done and trigger the SOC´s all together. Plus I´m not sure what is best practice to check, if the ADC is busy. I´ve see, there are busy flags, but I´m not 100% sure how to use them properly.
See below the Adc_Trigger and Init ans ISR. best regards, Moe
In ISR I do AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;// Acknowledge this interrupt to receive more interrupts from group 1 void StartCon(void) { EALLOW; AdccRegs.ADCSOCFRC1.all = 15 ; AdcbRegs.ADCSOCFRC1.all = 15 ; AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 3; //end of SOC3 will set INT1 flag AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1; //enable INT1 flag AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared AdcaRegs.ADCSOCFRC1.all = 15 ; EDIS; } InitAdc() { // TODO Auto-generated constructor stub EALLOW;
AdccRegs.ADCCTL2.bit.PRESCALE = 4; //set ADCCLK divider to /4 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;
Uint16 acqps;
// //determine minimum acquisition window (in SYSCLKS) based on resolution // if(ADC_RESOLUTION_12BIT == AdcaRegs.ADCCTL2.bit.RESOLUTION) { acqps = 14; //75ns } else //resolution is 16-bit { acqps = 63; //320ns }
// //Select the channels to convert and end of conversion flag // EALLOW; AdccRegs.ADCSOC0CTL.bit.CHSEL = 2; //SOC0 will convert pin A0 AdccRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles AdccRegs.ADCINTSOCSEL1.bit.SOC0 = 0;
AdcaRegs.ADCSOC0CTL.bit.CHSEL = 14; //SOC0 will convert pin A1 AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles AdcaRegs.ADCINTSOCSEL1.bit.SOC0 = 0;
AdccRegs.ADCSOC1CTL.bit.CHSEL = 5; //SOC0 will convert pin A2 AdccRegs.ADCSOC1CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles AdccRegs.ADCINTSOCSEL1.bit.SOC1 = 0;
AdccRegs.ADCSOC2CTL.bit.CHSEL = 4; //SOC0 will convert pin A3 AdccRegs.ADCSOC2CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles AdccRegs.ADCINTSOCSEL1.bit.SOC2 = 0;
AdcaRegs.ADCSOC1CTL.bit.CHSEL = 4; //SOC0 will convert pin A4 AdcaRegs.ADCSOC1CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles AdcaRegs.ADCINTSOCSEL1.bit.SOC1 = 0;
//AdcaRegs.ADCINTSEL1N2.bit.INT1CONT = 1; // make it unnesessarry to set back IntFlag by Code AdcbRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared/**/
/* * The application uses ADC´s a, b and c. together with thier SOC´s. Since all SOC´s are * serving the same amount channels and are all triggered at the same time, * it is sufficient to activate only one ADC interrupt. */ IER |= M_INT1; PieCtrlRegs.PIEIER1.bit.INTx1 = 1;// Enable TINT0 in the PIE: Group 1 interrupt 7
I think you are on the right track; you want one trigger to set SOC0 through SOC3 on all the ADCs. At the end, only one ADC needs to generate an ISR.
The ADCINT flag has multiple uses:
-Can be checked directly by SW to see if results are done
-Can be allowed to propagate through to PIE to interrupt the CPU
-Can be looped back as a trigger to make ADC convert continuously
This 3rd case is enabled by 'ADCINTSOCSEL1', which doesn't sound like something you want. Have a read through the TRM about these registers.
After a cursory look though your code, you might also want to investigate:
AdcaRegs.ADCCTL2.bit.PRESCALE = 4; //set ADCCLK divider to /4
The comment doesn't align with the setting. 4 does not result in /4 ; check the register descriptions.