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.

LP-MSPM0L1306: How to reconfigure ADC in repeat mode with FIFO?

Part Number: LP-MSPM0L1306

Here is my usage:

ADC configured in repeat sequence mode, sequence length is 2.

FIFO is enabled and I use DMA to transfer FIFO data.

I need 6 conversion results each time, so DMA transfer size is 3 (16bits *2 for each DMA transfer).

After DMA transmission completed, I stop ADC and reconfigured it to different channels.

Then I start ADC and DMA again wait for new 6 results.

Here is my problem:

The TRM said that stop ADC in repeat mode may cause additional ADC conversion, it really happens.

When additional conversion start, this new conversion result will be loaded into FIFO, it caused an extra data inside the FIFO, and the order of data I read from FIFO will be changed.

Is there anyway to flush FIFO when I reconfigure the ADC?

Or it there anyway to stop ADC in repeat mode and do not trigger a new conversion?

  • _iq5 Driver_ADCInitAndSampling(
        uint32_t adcChannel, uint32_t vrefSource, tStatus highAvg)
    {
        _iq5 iq5AdcConvResult;
        uint32_t u32AdcSum = 0;
        uint16_t u16Counter;
        uint16_t u16AdcResult;
    
        gCheckADC = false;
        DL_ADC12_reset(ADC12_INST);
        DL_ADC12_enablePower(ADC12_INST);
        DL_ADC12_setClockConfig(
            ADC12_INST, (DL_ADC12_ClockConfig *) &gADC12_0ClockConfig);
        DL_ADC12_initSingleSample(ADC12_INST, DL_ADC12_REPEAT_MODE_ENABLED,
            DL_ADC12_SAMPLING_SOURCE_AUTO, DL_ADC12_TRIG_SRC_SOFTWARE,
            DL_ADC12_SAMP_CONV_RES_12_BIT,
            DL_ADC12_SAMP_CONV_DATA_FORMAT_UNSIGNED);
        DL_ADC12_configConversionMem(ADC12_INST, DL_ADC12_MEM_IDX_0, adcChannel,
            vrefSource, DL_ADC12_SAMPLE_TIMER_SOURCE_SCOMP0,
            DL_ADC12_AVERAGING_MODE_ENABLED, DL_ADC12_BURN_OUT_SOURCE_DISABLED,
            DL_ADC12_TRIGGER_MODE_AUTO_NEXT, DL_ADC12_WINDOWS_COMP_MODE_DISABLED);
        DL_ADC12_setPowerDownMode(ADC12_INST, DL_ADC12_POWER_DOWN_MODE_MANUAL);
        if (highAvg == eTrue) {
            DL_ADC12_configHwAverage(ADC12_INST, DL_ADC12_HW_AVG_NUM_ACC_128,
                DL_ADC12_HW_AVG_DEN_DIV_BY_128);
        } else {
            DL_ADC12_configHwAverage(ADC12_INST, DL_ADC12_HW_AVG_NUM_ACC_4,
                DL_ADC12_HW_AVG_DEN_DIV_BY_4);
        }
    
        DL_ADC12_setSampleTime0(ADC12_INST, ADC_SAMPLE_TIME);
        DL_ADC12_enableDMA(ADC12_INST);
        DL_ADC12_setDMASamplesCnt(ADC12_INST, 1);
        DL_ADC12_enableDMATrigger(ADC12_INST, DL_ADC12_DMA_MEM0_RESULT_LOADED);
        /* Enable ADC12 interrupt */
        DL_ADC12_clearInterruptStatus(ADC12_INST, (DL_ADC12_INTERRUPT_DMA_DONE));
        DL_ADC12_enableInterrupt(ADC12_INST, (DL_ADC12_INTERRUPT_DMA_DONE));
    
        DL_DMA_initChannel(DMA, DMA_CH0_SEL, (DL_DMA_Config *) &gDMA_CH0Config);
        /* Configure DMA source, destination and size */
        DL_DMA_setSrcAddr(DMA, DMA_CH0_SEL,
            (uint32_t) DL_ADC12_getMemResultAddress(
                ADC12_INST, DL_ADC12_MEM_IDX_0));
        DL_DMA_setDestAddr(DMA, DMA_CH0_SEL, (uint32_t) &gADCSamples[0]);
        DL_DMA_setTransferSize(DMA, DMA_CH0_SEL, ADC_AVERAGE_TIMES);
    
        DL_DMA_enableChannel(DMA, DMA_CH0_SEL);
    
        /* Setup interrupts on device */
        NVIC_EnableIRQ(ADC12_INST_INT_IRQN);
    
        DL_ADC12_enableConversions(ADC12_INST);
        DL_ADC12_startConversion(ADC12_INST);
    
        while (false == gCheckADC) {
            __WFE();
        }
    
        for (u16Counter = 0; u16Counter < ADC_AVERAGE_TIMES; u16Counter++) {
            u32AdcSum += gADCSamples[u16Counter];
        }
        iq5AdcConvResult = _IQ5div(_IQ5(u32AdcSum), _IQ5(ADC_AVERAGE_TIMES));
    
        return iq5AdcConvResult;
    }
    
    void ADC12_INST_IRQHandler(void)
    {
        switch (DL_ADC12_getPendingInterrupt(ADC12_INST)) {
            case DL_ADC12_IIDX_DMA_DONE:
                gCheckADC = true;
                break;
            default:
                break;
        }
    }

    Here is the code generated by me. You can take it as a reference.

  • Thanks for your answer!

    I read this example and found this example did not use ADC FIFO and only configured one channel.

    So it will not cause order mess in any case.

    For my usage, I need 6 results each round, so I can only enable ADC FIFO for MSPM0Lx.

  • 1. You can flush the FIFO but you can't flush the FIFO count. The easy way is to reset the ADC.

    2. If you want to use stop ADC in repeat mode, can you use DL_ADC12_IIDX_DMA_DONE interrupt to stop ADC conversion? You can set DMA in repeat single mode, then you don't need to set the DMA again.