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.

MSPM0G3507: ADC Sample 4 Channels and read via DMA

Part Number: MSPM0G3507

Tool/software:

Hi,

I have the Launchpad for the mspsm0g.
I want to sample data with 10bit from 4 channels into a ring buffer(uint16). I set mem0 to 3.3V and mem1-3 on GND. So what I do is:
1) Configure Transfer Size > 0  (60 in my case)
2) Configure DMA Samples Count = 6 (= 12 x 16 bit) -> total of 60*12 = 720 samples
3) DMA Trigger on MEM11 result loaded
4) On DL_ADC12_IIDX_DMA_DONE I set the next address an reenable dma (DMA single Mode - Like the Ping Pong example)

When the ADC interrput is hit (on DL_ADC12_IIDX_DMA_DONE), I only see ~120 values written to the buffer.

The values are like 300, 1020, 0,0, 300, 1020,0,0.

Where I would expext 1020,0,0,0,1020,0,0,0 and so on

Questions:

1) Is there an example for my use case? I looked at the adc ping pong example already (single channel)
2) When is DL_ADC12_IIDX_DMA_DONE triggered, after a single transfer or alle transfers configured?

  • Hi Kai,

    Please share you whole DMA setting screenshot, I want to double check its setting.

    4) On DL_ADC12_IIDX_DMA_DONE I set the next address an reenable dma (DMA single Mode - Like the Ping Pong example)

    Why not firstly check the transfer size =1 /2 to see whether the output is correct.

    2) When is DL_ADC12_IIDX_DMA_DONE triggered, after a single transfer or alle transfers configured?

    It will be triggered after transfer size decrase to 0.

    B.R.

    Sal

  • See screenshots below and some stripped down code for what I'm doing.

    Update wrt to my original post: the "wrong" values (300) are gone, but when I break the first time after the dma interrupt, mem0 is still not the first entry.

    Wrt to the transfer size, I noticed setting the transfer size to half the buffer size, I get a filled buffer, but still the ordering seems wrong. Since this would mean I have a dma samples count of 1, I added the explict setting of the sampls count in the main(), still the same result. It seems the dma samples count is ignored?



    int main(void) {
    
      SYSCFG_DL_init();
    
      /* Configure DMA source, destination and size */
      DL_ADC12_setDMASamplesCnt(ADC12_0_INST,6);
      DL_DMA_setSrcAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t)DL_ADC12_getFIFOAddress(ADC12_0_INST));
      DL_DMA_setDestAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t)pool.getNext());
      DL_DMA_setTransferSize(DMA, DMA_CH0_CHAN_ID, transferSize); 
      DL_DMA_enableChannel(DMA, DMA_CH0_CHAN_ID);
    
      /* Setup interrupts on device */
      NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);
      
      /* The ADC is configured for Repeat Single Conversion,
       * so the ADC will continue until DL_ADC12_disableConversions() is called */
      DL_ADC12_startConversion(ADC12_0_INST);
    
      while (true) {
        // Check if the currently configured buffer is full
        if(g_adcBufferFilled){
            auto ptr = // get next prt code;
            DL_DMA_setSrcAddr(DMA, DMA_CH0_CHAN_ID, DL_ADC12_getFIFOAddress(ADC12_0_INST));
            DL_DMA_setDestAddr(DMA, DMA_CH0_CHAN_ID, reinterpret_cast<uint32_t>(ptr));
            DL_DMA_setTransferSize(DMA, DMA_CH0_CHAN_ID, transferSize); 
            DL_DMA_enableChannel(DMA, DMA_CH0_CHAN_ID);
            DL_ADC12_enableDMA(ADC12_0_INST);
            g_adcBufferFilled = false;
        }
    }
    
    extern "C" void ADC12_0_INST_IRQHandler() {
        const auto pendingInt = DL_ADC12_getPendingInterrupt(ADC12_0_INST);
        switch (pendingInt) {
            case DL_ADC12_IIDX_DMA_DONE:
            {
                g_adcBufferFilled = true;
                break;
            }
            default:
            break;
    }

    DMA_CH0_CHAN_ID is defined to be 1...
  • Hi Kai,

    See screenshots below and some stripped down code for what I'm doing.

    Something is incorrect:

    You need set the DMA trigger as MEMRES11.

    I noticed setting the transfer size to half the buffer size

    That is correct. You enabled FIFO, and FIFO data is 32-bit which contains two sample result within one data (high 16-bit and low 16-bit).

    You need manually handle it in software, or you need select source/destination length as 16-bit.

    B.R.

    Sal

  • Hi,

    You need set the DMA trigger as MEMRES11.

    I played around with it since I have 1.2Mhz sampling (Overall - 400khz per Channel) and I've seen posts we're DMA was too slow and needed to he triggered earlier.

    So the total amount of samples is not calculated with

    Samples = Transfersize * DMA Samples Count * 2

    It's Just

    Samples = Transfersize * 2

    When would you need to set the DMA samples count then?

  • Another update:
    I changed the adc ping pong example so that it matches to what I want to do, it delivers the results I want.

    I compared the syscfg files, no difference to my project. Only difference there is left is that my project is in c++ .

  • Hi Kai,

    I played around with it since I have 1.2Mhz sampling (Overall - 400khz per Channel) and I've seen posts we're DMA was too slow and needed to he triggered earlier.

    Okay, that could do, due to we need transfer the fisrt 10 data and then the last two data.

    When would you need to set the DMA samples count then?

    For 16-bit transfer length, you need set the sample counts as 12.

    Transfer size is the variable which determine how many times you want to transfer the total 12 channels data.

    I compared the syscfg files, no difference to my project. Only difference there is left is that my project is in c++ .

    No idea here.

    B.R.

    Sal

  • Transfer size is the variable which determine how many times you want to transfer the total 12 channels data.

    If you Set Transfer size to half the Buffer than this is not true, right?

    Sample Count ist the number of DMA triggers after Trigger Event (memresx loaded). Transfer size is decremented with each trigger. One Transfer ist 2 Samples in fifo Mode.

    For completness: I think I found my problem. I have the Buffer in a struct which also had a boolean flag as a member. This caused alignment issues.

    My bad

  • Hi Kai,

    Sample Count ist the number of DMA triggers after Trigger Event (memresx loaded). Transfer size is decremented with each trigger.

    Yes, this is correct.

    My statement is that:

    Due to you set Sample count = 6, so it will contains 12 conversion data in 32-bit transfer length as your expectation.

    In this scenario, the transfer size means "how many times you want to transfer the total 12 channels data.

    I am glad you find the issues, I will close the thread.

    B.R.

    Sal