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-F280049C: Multiple triggering when using CPU Timer 1 to start ADC conversion

Part Number: LAUNCHXL-F280049C

The problem is that I use CPU timer 1 to trigger ADC conversion. If the timer is configured faster than 35us (for example 30us), once in a while the end of conversion interrupt is triggered two times. The interrupt takes less than 2us to run. If I use 35us then I don't have double pulses. I will assert a GPIO-pin at a first line in interrupt and set it at the end. To measure times I use oscilloscope. What could be the limitation? The ADC interrupt has the highest priority.

Initialization:

EALLOW;
    CpuSysRegs.PCLKCR13.bit.ADC_A = 1;
    (*Device_cal)();
    EDIS;

    // Setup VREF as internal
    SetVREF(ADC_ADCA, ADC_INTERNAL, ADC_VREF3P3);

    EALLOW;
    // Set ADCCLK divider to /4
    AdcaRegs.ADCCTL2.bit.PRESCALE = 6;
    // Set pulse positions to late
    AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;
    // Power up the ADC and then delay for 1 ms
    AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;
    EDIS;

    DELAY_US(1000);

    // Configure SOC
    EALLOW;
    AdcaRegs.ADCSOC0CTL.bit.CHSEL = 1;      // SOC0 will convert pin A1
                                            // 0:A0  1:A1  2:A2  3:A3
                                            // 4:A4   5:A5   6:A6   7:A7
                                            // 8:A8   9:A9   A:A10  B:A11
                                            // C:A12  D:A13  E:A14  F:A15
    AdcaRegs.ADCSOC0CTL.bit.ACQPS = 9;      // Sample window is 10 SYSCLK cycles
    AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 2;    // Trigger on CPU1 Timer 1, TINT1n

    AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0;  // End of SOC0 will set INT1 flag
    AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;    // Enable INT1 flag
    AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;  // Make sure INT1 flag is cleared

    // Enable ADCINT1 in PIE
    PieCtrlRegs.PIEIER1.bit.INTx1 = 1;      // Enable INT 1.1 in the PIE
    IER |= M_INT1;                          // Enable CPU Interrupt 1
    EDIS;

    // Configure CPU1 Timer 1
    // Enable clock for CPU1 timer 1
    EALLOW;
    CpuSysRegs.PCLKCR0.bit.CPUTIMER1 = 1;
    EDIS;
    // CPU Frequency in MHz, period in uSeconds
    ConfigCpuTimer(&CpuTimer1, 100000000 / 1000000U, 30);
    // Start timer
    CpuTimer1Regs.TCR.all = 0x4000;

Interrupt:

__interrupt void ADC_isr(void)
{
    GpioDataRegs.GPACLEAR.bit.GPIO8 = 1;

    // Set interrupt priority:
    volatile Uint16 TempPIEIER = PieCtrlRegs.PIEIER1.all;
    IER |= M_INT1;
    IER &= MINT1;                       // Set "global" priority
    PieCtrlRegs.PIEIER1.all &= MG11;    // Set "group"  priority
    PieCtrlRegs.PIEACK.all = 0xFFFF;    // Enable PIE interrupts
    asm(" NOP");                        // Wait for PIEACK to exit the pipeline
    EINT;

    some code.... (takes less than 2us)

    // Clear the interrupt flag
    AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;

    GpioDataRegs.GPASET.bit.GPIO8 = 1;

    // Restore registers saved:
    DINT;
    PieCtrlRegs.PIEIER1.all = TempPIEIER;
}

JHi

  • Hi Juhis,

    I think it is happening because the interupt is getting acknlowledged first in ISR and then the ADCINTFLG is clear. The correct sequence would be:
    //
    // Clear the interrupt flag and issue ACK
    //
    AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;

    Thanks
    Vasudha
  • Didn't help. What I just noticed is that I can only trigger the ADC with the  minimum 35us. If I set the timer interrupt to 20us, I still get interrupts every ~35us and I guess that's why there are two interrupts. What I don't understand is why this happens, because the ADC end of conversion is the only interrupt enabled at the moment so there should not be anything blocking it.

    JHi

  • I did two measurements and I have attached the oscilloscope images of them. The pin will be set in a timer 1 interrupt and cleared when the ADC end of conversion interrupt is ready. In a first picture the timer is 35us and in a second one 20us. I really can't understand why in the second image the interrupt seems to take so much longer.

    JHi

  • I forgot to mention that if I toggle the pin from the timer interrupt, the timing will match to what I set it to be. Mean with 20us the pulses comes every 20us. There seems to be something fishy when using timer to trigger ADC conversion.

    JHi

  • Any one? I'm still struggling with this.
  • Hi,

    Can you share the code as we need more details to understand the problem?

    Thanks
    Vasudha
  • I founf the solution to my problem. I was using floats in my interrupt and I just copy and pasted the IQ to float function and it really didn't use the FPU -> interrupt was taking too long and that's why it was called multiple times.

    JHi