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.
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?
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.
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
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;
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;
//
//write configurations
//
AdcaRegs.ADCCTL2.bit.PRESCALE = 4; //set ADCCLK divider to /4
AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
//write configurations
//
AdcaRegs.ADCCTL2.bit.PRESCALE = 4; //set ADCCLK divider to /4
AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
AdcbRegs.ADCCTL2.bit.PRESCALE = 4; //set ADCCLK divider to /4
AdcSetMode(ADC_ADCB, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
AdcSetMode(ADC_ADCB, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
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;
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;
//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);
//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
}
//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;
//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;
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.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;
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.ADCSOC1CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
AdcaRegs.ADCINTSOCSEL1.bit.SOC1 = 0;
AdcbRegs.ADCSOC0CTL.bit.CHSEL = 5; //SOC0 will convert pin A0
AdcbRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
AdcbRegs.ADCINTSOCSEL1.bit.SOC0 = 0;
///////////////////////////////////////////////////////////////////////////////////////////////
AdcbRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
AdcbRegs.ADCINTSOCSEL1.bit.SOC0 = 0;
///////////////////////////////////////////////////////////////////////////////////////////////
AdcbRegs.ADCSOC1CTL.bit.CHSEL = 2; //SOC0 will convert pin A0
AdcbRegs.ADCSOC1CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
AdcbRegs.ADCINTSOCSEL1.bit.SOC1 = 0;
AdcbRegs.ADCSOC1CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
AdcbRegs.ADCINTSOCSEL1.bit.SOC1 = 0;
AdccRegs.ADCSOC3CTL.bit.CHSEL = 3; //SOC0 will convert pin A1
AdccRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
AdccRegs.ADCINTSOCSEL1.bit.SOC3 = 0;
AdccRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
AdccRegs.ADCINTSOCSEL1.bit.SOC3 = 0;
AdcaRegs.ADCSOC2CTL.bit.CHSEL = 3; //SOC0 will convert pin A2
AdcaRegs.ADCSOC2CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
AdcaRegs.ADCINTSOCSEL1.bit.SOC2 = 0;
AdcaRegs.ADCSOC2CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
AdcaRegs.ADCINTSOCSEL1.bit.SOC2 = 0;
AdcbRegs.ADCSOC2CTL.bit.CHSEL = 4; //SOC0 will convert pin A3
AdcbRegs.ADCSOC2CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
AdcbRegs.ADCINTSOCSEL1.bit.SOC2 = 0;
AdcbRegs.ADCSOC2CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
AdcbRegs.ADCINTSOCSEL1.bit.SOC2 = 0;
AdcbRegs.ADCSOC3CTL.bit.CHSEL = 3; //SOC0 will convert pin A4
AdcbRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
AdcbRegs.ADCINTSOCSEL1.bit.SOC3 = 0;
AdcbRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
AdcbRegs.ADCINTSOCSEL1.bit.SOC3 = 0;
AdcaRegs.ADCSOC3CTL.bit.CHSEL = 5; //SOC0 will convert pin A0
AdcaRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
AdcaRegs.ADCINTSOCSEL1.bit.SOC3 = 0;
AdcaRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
AdcaRegs.ADCINTSOCSEL1.bit.SOC3 = 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/**/
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
PieVectTable.ADCA1_INT = &adcAint;
EDIS;
}
}