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: Configuration for max ADC throughput

Part Number: MSPM0G3507
Other Parts Discussed in Thread: SYSCONFIG,

Tool/software:

The high level is I want something like a ring buffer, where i can keep say 256 from an ADC channel, and when a value is over some threshold, continue sampling only for 192 more, than stop.
I have this running slowly using interrupts, but now i'd like to see how fast i can make this run.

If i wanted to do this at max possible speeds. I wanted to get this question started before i've finished going through the documentation (there is a lot to parse).  a few questions...

1) first i want to note, i dont have an external clock, so i think i'm limited to 32mhz CPUCLK and ULPCLK  what is the max throughput of the ADC with these limitations?

2) side question, I used the sysconfig to setup the chip, now i just saw someone reference the Analog Configurator, is one recommended over the other?  I haven't installed the Analog Configurator yet, i have not seen its features or how to use it with CCS yet.

3) what is my best bet for filling the ring buffer, fifo or DMA?  i could imagine pulling from the fifo, checking the threshold and then putting it into my own buffer.  if i pull from the fifo, i imagine i could do it at max sample speed?

4) if i use the fifo, how do i know how many items are in the fifo? i see CCS function DL_ADC12_getFIFOData, i see in the technical reference the register, but i dont see a count.  I dont see the data format either.  in a different e2e post, i saw something about a data valid bit with the data, but i'm not seeing it.

5) would i need to use the DMA?  how would you do something like a ring buffer with the dma, and would the samples be interrupted?  (i could imagine setting up a dma for 32 samples, then on complete move the buffer location and re-enabling the dma, then during this time i could try to look through the previous samples to see if i need to stop.

6) regardless of how i get the data, i was imagining that the ADC samples are automatically running, whats the best way to do this?  i had setup the ADC to trigger off a timer interrupt, but then i had to look at the ADC interrupt in order to allow it to sample again, is this a necessary step?  or is there a way to just have the ADC go continuously?

  • Hi,

    1) A total conversion time for a ADC channel is combined with two part: ADC sampling + ADC conversion:

    • ADC conversion is sourced by a internal 80MHz oscillator within the ADC IP, so the conversion time for 12bit ADC data is less than 1us.
    • ADC sampling clock and sampling time are configurable in sysconfig, it depends on your requirement.
    • Need to guarantee the sampling period (the sampling gap between to sampling data) large thant the total time above.  

    2) Analog Configurator is designed for some simple analog peripheral connection for MSPM0 evaluation, not recommend to use it for engineer development.

    3) 4) We could only get the FIFO status (like FULL, Empty), you could fetch the data in FIFO unitil it get empty status

    5) Yes, i think your proposal is fine, DMA could achieve the data transfer without CPU. But there is a problem, DMA target address could be set as fix address or increase by 1,2.., but I do not think it could meet your ring buffer function requirement.

    6) You could use a timer to continuously trigger a ADC sampling, and in ADC module, you just need to enable "repeat mode", and it could continuously conversion without any other "enable" operation. 

    Best Regards,

    Pengfei

  • I was hoping for details in any of the answers.

    1) how can the ADC be 4MSPS if the conversion takes 1us?

    3/4) what register and bits?  can you point to both the documenation and the CCS name?

    6) can you point me at how to do this?  in  SLAU846B i see "repeat mode" only a single place, around it, there is reference to repeat mode, but not how to do it.  in Sysconfig i setup the ADC in my best guess, and had it triggered on an event, the event coming from a timer, but the fifo data is always 0, and i'm not sure how to tell if a conversion triggered.

  • Hi,

    1) I mean "less than" 1us, actually the exact conversion time is 12*1/80MHz -> 0.15us. You could refer TRM 10.2.8 Sampling Trigger Sources and Sampling Modes for more details of ADC sampling timing.

    3) 4) Sorry I need to update, the FIFO empty or full status could only be checked by the OVIFG and UVIFG flag. You could use either a ADC result load interrupt or DMA to fetch result.

    6) The repeat mode could be configure in sysconfig. And in repeat mode, ADC conversion will always be enabled, and could continuously trigger ADC sampling at a trigger signal. And for timer event trigger configuration, I think you could refer example adc12_simultaneous_trigger_event_LP_MSPM0G3507_nortos_ticlang.

    Best Regards,

    Pengfei

  • 3/4
    a) can you please look into this more?  it doesn't make sense to have a fifo where the only way to use it is to try to read until you underflow or wait until it overflows.

    b) the fifo for DAC has interrupts at a configurable level which would work as well, is this available for the ADC?

    c) how big is the ADC fifo?

    d) If i can't use the fifo directly, then i have to do the DMA, i see there is an example, but what i would need to know is what happens with the fifo when a DMA is complete.  for example if the fifo was 8 deep and the DMA was set to 16, when i get the dma complete interrupt, lets say i queue up a process to deal with the new data.  i go to move the dma destination to a new location and enable the dma again, but by this time 2 ADC samples have occurred, did they overwrite anything in the existing buffer? are they lost?  are they waiting in the fifo? and will transfer as soon as the DMA is re enabled?


  • Hi,

    b) ADC could use "result load" to trigger a interrupt or DMA operation. 

      

    c) ADC FIFO is organized by ADC MEMRES, and there is 6 * 32bit FIFO in MSPM0G3507 ADC module.

    d) There is a MSPM0 DMA ping pong with ADC application note to answer your question: DMA Ping Pong With ADC (Rev. A)

    Best Regards

    Pengfei

  • b)
    i'm not sure what you are suggesting, generally when using a fifo, its because there is some latency until you have a time to pull data from it, at that point, you dont know how many are in it.  thats the information which makes a fifo useful.

    c)
    can you point me to the documentation of the fifo organization and usage?  are you saying that the there is a single fifo that is 6 deep and 32 bits wide? 

    d)
    thank you for pointing out this example, I didnt realize that msp_subsystems had examples (similar to the folder i was looking in: driverlib)

    I think i was able to make this work in my code, i can't be sure because while i'm getting samples they seem a bit funny.
    i'm going to try to slow down the signal i'm sampling to get a better idea of what the issue is, but i also have many questions regarding the example.

    it sets the DMA Samples Count to 6 and Enable DMA Triggers to Mem11, why and what are the effects of this?

    5) 
    this is what i'm looking to do, so i wanted to elaborate on what i was tryign to say...
    instead of a ring buffer  of say 512 samples, i would have it a ring buffer of  16x32 samples.  where the dma would be 32, and each time a dma is complete i move on to the next of 16 blocks.  re-writing the blocks until i want it to stop.

    to keep processing time at a minimum, i wanted to use:
    12.2.12.2 Window Comparator
    There is one window comparator unit available in the ADC

    this way i dont have to look at all the data, i can use the window comparator to know when to stop the samples.

    a) any problem with what i've described?
    b) how do i enable the comparator in sysconfig?  i see it as an interrupt output from the ADC, but i cannot select it (i probalby have to first insert it?)

  • Hi,

    Let me answer some of your questions firstly:

    c) you could refer TRM 10.2.12.3 DMA and FIFO Operation.

    5 a) I am not sure what is the input of your window comparator? And when do you want to stop ADC conversion?

    5 b) You could refer our SDK examples of COMP, it could source from external pins or DAC or OPA output.

    Best Regards,

    Pengfei

  • 3/4
    c)

    where is TRM 10.2.12.3 ?  how is one supposed to know where these documents are.  if i google this, i only find an E2E reference but no link.  a search in MSPM0_SDK_User_Guide doesnt turn up anything.  to be honest I think I'm missing the big picture of how developing with TI is supposed to go.  i tried to start from the data sheet and the technical reference, the SDK has a lot of folders, is there a goto place to figure out how to navigate the sdk?  i see the top level user guide.

    in general i'm frustrated that if i need to implement something i have to spend hours searching for references to it.

    do you have any helpful advice?

    5)
    the section i pointed to says:
    There is one window comparator unit available in the ADC which can be used to check if the input signal is
    within predefined threshold values set by software. The ADC result that goes into MEMRES or FIFO is what gets
    checked against the threshold values of the window comparator.

    i just found ad12_window_comparator which uses the feature i was looking for. (almost)


    i haven't compiled the test yet as this requires a pretty big rework to my code.  what worries me is this feature now has an additional "trigger mode" which seems to indicate that samples may not flow to the fifo unless the window critera is met?  (which is not at all what i want, i only want to receive the interrupt)

  • Hi,

    #1 For ADC FIFO information, sorry I used a older version of Technical Reference Manual. You could refer to 12.2.12.3 DMA and FIFO Operation of MSPM0 G-Series 80-MHz Microcontrollers Technical Reference Manual (Rev. B).

    #2 To get quick start of CCS/Sysconfig/MSPM0 SDK, you could refer the MSPM0 Design Flow Guide (Rev. D). It includes some step by step introduction of have to get start of MSPM0.

    #3 The "trigger mode" is say that whether the "trigger source" condition need to met to make ADC step to the next conversion. If you use the default configuration of this example,  the ADC will continuously sampling after the first software trigger is generated (DL_ADC12_startConversion(ADC12_0_INST);).

    Best Regards,

    Pengfei

  • I implemented some code that has a 256 DW buffer and was doing 16DW DMA to fill it (advancing the pointer 32 (16bit) samples each time.
    its mostly working, but i was seeing some odd hiccups in the data.

    in order to try to eliminate issues in how i advance pointers, when, and restarting the dma i changed my dma size to the full buffer, i haven't fully verified that my setup is correct but the way that this error is showing up, i thought you might have an idea...

    the bottom is the data that i received and the top is what it looks like if i make a few data swaps shown.  

    it seems interesting to me that the amount is about 6 and DMA Samples Count is 6.  sometimes the data is in the right order, sometimes its not.

    any ideas?

  • Hi,

    I got your point that the result get smooth if we change some order of results. But I see the "error data" amount is not exact 6(some times 5 or 7 from the picture). So I'm not sure whether it is caused by DMA.

    Could you please give the configuration of your DMA? (the source and target address, the increment of these address)

    And I think by configure the DMA size to a large one (such as you said the size to the buffer) and test again, the result could show whether the "error data" is related to the DMA size.

    Best Regards,

    Pengfei

  • That was with the full size dma transfer, though in debugging i see some other stuff i didnt expect.

    i was surprised that in my interrupt routine for DMA complete
    first i did
    DL_ADC12_stopConversion(ADC12_1_INST);
    and later after setting up the next dma did
    DL_DMA_enableChannel(DMA, DMA_CH0_CHAN_ID);
    the DMA completed before i did startConversion, i single stepped past this line in studio and the dma size went to zero and the buffer data changed.  I would have expected if i stopped the conversion, that no data would go into the fifo, therefore the DMA would not proceed.  any thoughts on this?

    regarding the miss ordered data, here is a dump, does this have what you requested?

    521177 10
    R PC 0x0000000B 0x00000F7C
    R SP 0x0000000B 0x20207EB4
    R LR 0x0000000B 0x000004F9
    R xPSR 0x0000000B 0x21000000
    R R0 0x0000000B 0x00020100
    R R1 0x0000000B 0x00000100
    R R2 0x0000000B 0x40003104
    R R3 0x0000000B 0x00000000
    R R4 0x0000000B 0x00000001
    R R5 0x0000000B 0x4042B200
    R R6 0x0000000B 0x00302200
    R R7 0x0000000B 0x00302202
    R R8 0x0000000B 0xFFFFFFFF
    R R9 0x0000000B 0xFFFFFFFF
    R R10 0x0000000B 0xFFFFFFFF
    R R11 0x0000000B 0xFFFFFFFF
    R R12 0x0000000B 0x20200000
    R R13 0x0000000B 0x20207EB4
    R R14 0x0000000B 0x000004F9
    R MSP 0x0000000B 0x20207EB4
    R PSP 0x0000000B 0xFFFFFFFC
    R CTRL_PRI 0x0000000B 0x00000000
    R adc1_ADC1_GPRCM_ADC1_PWREN 0x0000000B 0x00000001
    R adc1_ADC1_GPRCM_ADC1_RSTCTL 0x0000000B 0x00000000
    R adc1_ADC1_GPRCM_ADC1_CLKCFG 0x0000000B 0x00000001
    R adc1_ADC1_GPRCM_ADC1_STAT 0x0000000B 0x00010000
    R adc1_ADC1_INT_EVENT0_ADC1_INT_EVENT0_IIDX 0x0000000B 0x00000005
    R adc1_ADC1_INT_EVENT0_ADC1_INT_EVENT0_IMASK 0x0000000B 0x00000030
    R adc1_ADC1_INT_EVENT0_ADC1_INT_EVENT0_RIS 0x0000000B 0x000FFF1F
    R adc1_ADC1_INT_EVENT0_ADC1_INT_EVENT0_MIS 0x0000000B 0x00000010
    R adc1_ADC1_INT_EVENT0_ADC1_INT_EVENT0_ISET 0x0000000B 0x00000000
    R adc1_ADC1_INT_EVENT0_ADC1_INT_EVENT0_ICLR 0x0000000B 0x00000000
    R adc1_ADC1_INT_EVENT1_ADC1_INT_EVENT1_IIDX 0x0000000B 0x00000000
    R adc1_ADC1_INT_EVENT1_ADC1_INT_EVENT1_IMASK 0x0000000B 0x00000000
    R adc1_ADC1_INT_EVENT1_ADC1_INT_EVENT1_RIS 0x0000000B 0x0000011C
    R adc1_ADC1_INT_EVENT1_ADC1_INT_EVENT1_MIS 0x0000000B 0x00000000
    R adc1_ADC1_INT_EVENT1_ADC1_INT_EVENT1_ISET 0x0000000B 0x00000000
    R adc1_ADC1_INT_EVENT1_ADC1_INT_EVENT1_ICLR 0x0000000B 0x00000000
    R adc1_ADC1_INT_EVENT2_ADC1_INT_EVENT2_IIDX 0x0000000B 0x00000000
    R adc1_ADC1_INT_EVENT2_ADC1_INT_EVENT2_IMASK 0x0000000B 0x00080000
    R adc1_ADC1_INT_EVENT2_ADC1_INT_EVENT2_RIS 0x0000000B 0x00000300
    R adc1_ADC1_INT_EVENT2_ADC1_INT_EVENT2_MIS 0x0000000B 0x00000000
    R adc1_ADC1_INT_EVENT2_ADC1_INT_EVENT2_ISET 0x0000000B 0x00000000
    R adc1_ADC1_INT_EVENT2_ADC1_INT_EVENT2_ICLR 0x0000000B 0x00000000
    R adc1_ADC1_MEMCTL_0 0x0000000B 0x10000200
    R adc1_ADC1_MEMCTL_1 0x0000000B 0x00000000
    R adc1_ADC1_MEMCTL_2 0x0000000B 0x00000000
    R adc1_ADC1_MEMCTL_3 0x0000000B 0x00000000
    R adc1_ADC1_MEMCTL_4 0x0000000B 0x00000000
    R adc1_ADC1_MEMCTL_5 0x0000000B 0x00000000
    R adc1_ADC1_MEMCTL_6 0x0000000B 0x00000000
    R adc1_ADC1_MEMCTL_7 0x0000000B 0x00000000
    R adc1_ADC1_MEMCTL_8 0x0000000B 0x00000000
    R adc1_ADC1_MEMCTL_9 0x0000000B 0x00000000
    R adc1_ADC1_MEMCTL_10 0x0000000B 0x00000000
    R adc1_ADC1_MEMCTL_11 0x0000000B 0x00000000
    R adc1_ADC1_SVT_MEMRES_0 0x0000000B 0x0000025E
    R adc1_ADC1_SVT_MEMRES_1 0x0000000B 0x000008E4
    R adc1_ADC1_SVT_MEMRES_2 0x0000000B 0x000008DD
    R adc1_ADC1_SVT_MEMRES_3 0x0000000B 0x000008E6
    R adc1_ADC1_SVT_MEMRES_4 0x0000000B 0x000008E4
    R adc1_ADC1_SVT_MEMRES_5 0x0000000B 0x0000025E
    R adc1_ADC1_SVT_MEMRES_6 0x0000000B 0x000008E7
    R adc1_ADC1_SVT_MEMRES_7 0x0000000B 0x000008E7
    R adc1_ADC1_SVT_MEMRES_8 0x0000000B 0x00000597
    R adc1_ADC1_SVT_MEMRES_9 0x0000000B 0x000008CB
    R adc1_ADC1_SVT_MEMRES_10 0x0000000B 0x0000025A
    R adc1_ADC1_SVT_MEMRES_11 0x0000000B 0x000008E3
    R adc1_ADC1_FSUB_0 0x0000000B 0x00000000
    R adc1_ADC1_FPUB_1 0x0000000B 0x00000000
    R adc1_ADC1_EVT_MODE 0x0000000B 0x00000009
    R adc1_ADC1_DESC 0x0000000B 0x26110010
    R adc1_ADC1_CTL0 0x0000000B 0x00010001
    R adc1_ADC1_CTL1 0x0000000B 0x00020000
    R adc1_ADC1_CTL2 0x0000000B 0x00003400
    R adc1_ADC1_CLKFREQ 0x0000000B 0x00000005
    R adc1_ADC1_SCOMP0 0x0000000B 0x00000008
    R adc1_ADC1_SCOMP1 0x0000000B 0x00000000
    R adc1_ADC1_WCLOW 0x0000000B 0x00000000
    R adc1_ADC1_WCHIGH 0x0000000B 0x00000800
    R adc1_ADC1_STATUS 0x0000000B 0x00000001
    R adc1_ADC1_SVT_FIFODATA 0x0000000B 0x08DF08E3
    R dma_DMA_INT_EVENT_[0]_DMA_IIDX 0x0000000B 0x00000001
    R dma_DMA_INT_EVENT_[0]_DMA_IMASK 0x0000000B 0x00010001
    R dma_DMA_INT_EVENT_[0]_DMA_RIS 0x0000000B 0x00000001
    R dma_DMA_INT_EVENT_[0]_DMA_MIS 0x0000000B 0x00000001
    R dma_DMA_INT_EVENT_[0]_DMA_ISET 0x0000000B 0x00000000
    R dma_DMA_INT_EVENT_[0]_DMA_ICLR 0x0000000B 0x00000000
    R dma_DMA_INT_EVENT_[1]_DMA_IIDX 0x0000000B 0x00000000
    R dma_DMA_INT_EVENT_[1]_DMA_IMASK 0x0000000B 0x00000000
    R dma_DMA_INT_EVENT_[1]_DMA_RIS 0x0000000B 0x00000001
    R dma_DMA_INT_EVENT_[1]_DMA_MIS 0x0000000B 0x00000000
    R dma_DMA_INT_EVENT_[1]_DMA_ISET 0x0000000B 0x00000000
    R dma_DMA_INT_EVENT_[1]_DMA_ICLR 0x0000000B 0x00000000
    R dma_DMA_DMATRIG_[0]_DMA_DMATCTL 0x0000000B 0x00000018
    R dma_DMA_DMATRIG_[1]_DMA_DMATCTL 0x0000000B 0x00000000
    R dma_DMA_DMATRIG_[2]_DMA_DMATCTL 0x0000000B 0x00000000
    R dma_DMA_DMATRIG_[3]_DMA_DMATCTL 0x0000000B 0x00000000
    R dma_DMA_DMATRIG_[4]_DMA_DMATCTL 0x0000000B 0x00000000
    R dma_DMA_DMATRIG_[5]_DMA_DMATCTL 0x0000000B 0x00000000
    R dma_DMA_DMATRIG_[6]_DMA_DMATCTL 0x0000000B 0x00000000
    R dma_DMA_DMACHAN_[0]_DMA_DMACTL 0x0000000B 0x00302202
    R dma_DMA_DMACHAN_[0]_DMA_DMASA 0x0000000B 0x40558160
    R dma_DMA_DMACHAN_[0]_DMA_DMADA 0x0000000B 0x20200000
    R dma_DMA_DMACHAN_[0]_DMA_DMASZ 0x0000000B 0x00000100
    R dma_DMA_DMACHAN_[1]_DMA_DMACTL 0x0000000B 0x00000000
    R dma_DMA_DMACHAN_[1]_DMA_DMASA 0x0000000B 0x00000000
    R dma_DMA_DMACHAN_[1]_DMA_DMADA 0x0000000B 0x00000000
    R dma_DMA_DMACHAN_[1]_DMA_DMASZ 0x0000000B 0x00000000
    R dma_DMA_DMACHAN_[2]_DMA_DMACTL 0x0000000B 0x00000000
    R dma_DMA_DMACHAN_[2]_DMA_DMASA 0x0000000B 0x00000000
    R dma_DMA_DMACHAN_[2]_DMA_DMADA 0x0000000B 0x00000000
    R dma_DMA_DMACHAN_[2]_DMA_DMASZ 0x0000000B 0x00000000
    R dma_DMA_DMACHAN_[3]_DMA_DMACTL 0x0000000B 0x00000000
    R dma_DMA_DMACHAN_[3]_DMA_DMASA 0x0000000B 0x00000000
    R dma_DMA_DMACHAN_[3]_DMA_DMADA 0x0000000B 0x00000000
    R dma_DMA_DMACHAN_[3]_DMA_DMASZ 0x0000000B 0x00000000
    R dma_DMA_DMACHAN_[4]_DMA_DMACTL 0x0000000B 0x00000000
    R dma_DMA_DMACHAN_[4]_DMA_DMASA 0x0000000B 0x00000000
    R dma_DMA_DMACHAN_[4]_DMA_DMADA 0x0000000B 0x00000000
    R dma_DMA_DMACHAN_[4]_DMA_DMASZ 0x0000000B 0x00000000
    R dma_DMA_DMACHAN_[5]_DMA_DMACTL 0x0000000B 0x00000000
    R dma_DMA_DMACHAN_[5]_DMA_DMASA 0x0000000B 0x00000000
    R dma_DMA_DMACHAN_[5]_DMA_DMADA 0x0000000B 0x00000000
    R dma_DMA_DMACHAN_[5]_DMA_DMASZ 0x0000000B 0x00000000
    R dma_DMA_DMACHAN_[6]_DMA_DMACTL 0x0000000B 0x00000000
    R dma_DMA_DMACHAN_[6]_DMA_DMASA 0x0000000B 0x00000000
    R dma_DMA_DMACHAN_[6]_DMA_DMADA 0x0000000B 0x00000000
    R dma_DMA_DMACHAN_[6]_DMA_DMASZ 0x0000000B 0x00000000
    R dma_DMA_FSUB_0 0x0000000B 0x00000000
    R dma_DMA_FSUB_1 0x0000000B 0x00000000
    R dma_DMA_FPUB_1 0x0000000B 0x00000000
    R dma_DMA_PDBGCTL 0x0000000B 0x00000003
    R dma_DMA_EVT_MODE 0x0000000B 0x00000009
    R dma_DMA_DESC 0x0000000B 0x25116000
    R dma_DMA_DMAPRIO 0x0000000B 0x00000000
    

  • Hi WorkerBee,

    A assumption from mine is that: our DMA use its "DMASZx == Zero" as the trigger condition of the transfer complete interrupt. So if you do not re-configure the DMA channel again, the complete interrupt will remain to be set.

    You could try below steps (about DMA) in DMA complete interrupt: 

    • Set DMA source address (may not change if you use the previous ADC result memory address)
    • Set DMA destination address (result store buffer index increase by the DMA size)
    • Reset DMA size by DL_DMA_setTransferSize()
    • DL_DMA_enableChannel

    Best Regards,

    Pengfei

  • I guess i didnt make my questions clear...

    the primary issue isn't that i can't get the dma to go or complete, its that the data in the middle seems mis ordered, you requested my settings which i provided.  that transfer if you look should have been very large, and the mis-order occurs in the middle of it multiple times.

    i had asked another question, but it was more out of curiosity.  again, it wasn't an issue of the dma not going, i was saying that with the conversion stopped, when i enabled the channel, it seems that the adc was still running and the dma completed, but i would have thought that if i had DL_ADC12_stopConversion that the dma and conversions would not do anything until i startConversion again.  you can ignore this question as its of no concequence

  • Hi WorkerBee,

    I think you descript clearly about your issues. 

    For the primary issue, sorry I have no idea about why the result get the mis order currently. So if you could give more information about your DMA configuration,maybe the sysconfig and source code may be helpful. What I want to know is the DMA address configuration and how you update the address after DMA complete.

    For the another question, I got your point. Please see my last reply. I mean the "DMA complete" is triggered by DMA size decrease to Zero. So if you do not re-configure the DMA size by  DL_DMA_setTransferSize() after last DMA complete, it is possible that "DMA complete" occurs again because the DMA size remain as Zero. So I have given you my suggestion of re-configuring DMA address and size in DMA complete interrupt.

    Best Regards,

    Pengfei

  • for context, basically if you haven't figured it out, i'm sort of using this as a logic analyzer, capturing a waveform.  i set a trigger value and type, and how much storage before the trigger 1/4,1/2,3/4.  so i use the window interrupt to decide how much data to continue to capture after it occurs.

    I thought that the register dump i gave you had information about both, it shows all my dma and ADC settings.  you can see how its setup right before enabling the dma and starting conversion.

    so regarding the mis-ordered data, i'll follow this up with some extra code information.

    regarding the other issue, what i'm trying to say is that i've already done that... i can see that the size is non zero, then after in the debugger i single step over the dma enable, i can look at the registers and size has gone to zero and the buffer has new data.  so it seems that the stop conversion didn't stop samples from occuring and as soon as i enabled the channel it completed because samples were still occurring.

    my code is a bit complicated , but i'll try to summarize the steps... i can give you my code, but i dont want the full code to be public if you have another way of contact.

    setup:
    DL_ADC12_disableDMA(ADC12_1_INST);
    DL_ADC12_stopConversion(ADC12_1_INST);
    DL_DMA_setSrcAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t)DL_ADC12_getFIFOAddress(ADC12_1_INST));
    DL_DMA_setDestAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t)&pBuffer_[0]);
    DL_DMA_setTransferSize(DMA, DMA_CH0_CHAN_ID, ADC_FIFO_SAMPLES);
    DL_DMA_enableChannel(DMA, DMA_CH0_CHAN_ID);

    DL_ADC12_configWinCompLowThld(ADC12_1_INST,0x0);
    DL_ADC12_configWinCompHighThld(ADC12_1_INST,0x800);

    DL_ADC12_startConversion(ADC12_1_INST);
    DL_ADC12_enableDMA(ADC12_1_INST);

    on window interrupt:
    i calculate how many dma bursts i want to transfer before ending the data capture.
    DL_ADC12_configWinCompLowThld(ADC12_1_INST,0xFFFF);
    DL_ADC12_configWinCompHighThld(ADC12_1_INST,0x0);
    (my window interrupt is  when both are true, this should never happen, so basically disabling the window interrupt)

    on dma complete interrupt & the last section of my buffer has transfered:
    DL_ADC12_disableDMA(ADC12_1_INST);
    DL_ADC12_stopConversion(ADC12_1_INST);

    on dma complete and last section has not been transfered
    next_ += ADC_SAMPLE_SIZE; //dma just completed so advance the index
    if((next_ + ADC_SAMPLE_SIZE)> length_) next_ = 0; //if the next index plus buffer size is over the buffer length set it back to 0

    DL_DMA_setDestAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t)&pBuffer_[next_]);
    DL_DMA_setTransferSize(DMA, DMA_CH0_CHAN_ID, ADC_FIFO_SAMPLES); //??? is this needed???
    DL_DMA_enableChannel(DMA, DMA_CH0_CHAN_ID);
    DL_ADC12_enableDMA(ADC12_1_INST); //???is this needed???

    as i mentioned, the design is to break the large buffer into many smaller transfers (so that i have some trigger granularity, i use the window to trigger to choose some amount around it...

    in "setup" note that i disable the dma so that i can cancel any existing operation and restart cleanly.  in case a capture operation was active, but never triggered, and then someone wants to restart it.

  • Hi WorkerBee,

    i can see that the size is non zero, then after in the debugger i single step over the dma enable, i can look at the registers and size has gone to zero and the buffer has new data.  so it seems that the stop conversion didn't stop samples from occuring and as soon as i enabled the channel it completed because samples were still occurring.

    I'm sorry to misunderstand your clarification. And thanks for your patient to plain your setup, the code you attached seems good. I have requested for your friendship, and you could send my your example so it may be more convenient for me to reproduce your problem and take further analysis (sysconfig configuration is also an important part). 

    By the way, another assumption from my side is that if the DMA size is less than FIFO size, there is a possibility that before you stop ADC conversion, the ADC is continuously sampling (if the sampling rate is very high) and the FIFO has became full or nearly full. So just after you enable DMA and conversion, the DMA transfer completed.

    Thanks and Best Regards,

    Pengfei

  • i took the sample ping pong and modified it very slightly (speed, which channel)
    i ran it, hit 2 break points (filling first ping then pong)
    then copied the values out of the debugger and pasted them into excel to create this:

    adc_dmg_ping_pong_512fast.zip

    the problem seemed to recreate, so this should be easy for you to work with.
    thank you.

  • Hi WorkerBee,

    Well received. I will take test based on the example and update to you.

    Best Regards,

    Pengfei

  • Hi WorkerBee,

    Thanks for your example to identify problem. I could also reproduce the same problem with the example. 

    Actually this issue occurs when a high sampling frequency is applied in this example. The root cause is:

    • In the sysconfig, the DMA trigger is set as MEM11 result loaded, that means, when 6*32bit data (12*16bit ADC result) is loaded in ADC FIFO, a DMA transfer is triggered and start to transfer data from MEM0 to MEM11. If in a high ADC sampling rate (low ADC sampling time), the MEM0, MEM1 ... may be reloaded to a updated ADC results before DMA transfer them. Thus it causes a mis-order issue.
    • Please just try to change the DMA trigger and DMA samples count to below: 

          

    Another question about ADC running after DMA transfer completed, it is the normal operation for ADC module. Because we configure ADC in a repeat mode, and just after the "DL_ADC12_startConversion()", ADC will continuously sampling and conversion, until a DL_ADC12_stopConversion() is executed.

    Best Regards,

    Pengfei

     e2e_adc_dma_ping_pong_512fast.zip

  • better, still a few questions.

    what is the actual sampling period?  I thought i saw it in sysconfig, but not seeing it now.
    there is the "Desired Sample Time", if i set it to 0, it says actual is 0... it can't be 0 right?

    how does the sample time translate into sample period?

    when i run the ping pong test, i think there is data lost between ping and pong.
    I run my test and 12 samples are missing between ping and pong. (the period is shorter before and after the 512 mark.



    ignore the red lines, i think i had read that the vref needs time to stabilize and i assume  thats what is happening there.  so i'm not concerned.

  • Hi Workerbee,

    Sorry for late reply.

    there is the "Desired Sample Time", if i set it to 0, it says actual is 0... it can't be 0 right?

    The "Desired Sample Time" is used for setting sampling timer counter value, is could not be zero. 

    A complete ADC samples process is "sampling + conversion", and in this example, after a conversion finished, the next sampling continues. In the example, as ADCCLK is 32MHz, so the conversion is about 6 ADCCLK cycles (187ns), and the sampling time is set as 250ns, and there is a cycle between different samples, so the time for a sample is around 500ns. There is not a exactly value of sampling period. If you want to to sampling with a high accuracy sampling period, a timer event trigger may need to be used.

    when i run the ping pong test, i think there is data lost between ping and pong.

    In this example, during the time MCU re-configure DMA, the ADC sampling data will be lost. So it may have some data lost between ping and pong. 

    Best Regards,

    Pengfei

  • so how can someone get all of the data?

    in general the point of a ping pong buffer is to fill one buffer while processing the second.

    the time it takes to write a couple of registers to start the next dma should be much less than the time it takes for the ADC's fifo to fill up. 

    regarding the dma... is there a dma engine / second processor that does it or is this really code running on the processor?

    i have a fifo question, i'll follow up with another reply shortly.

  • Hi WorkerBee,

    the time it takes to write a couple of registers to start the next dma should be much less than the time it takes for the ADC's fifo to fill up. 

    No exactly. Actually we need to consider the time of entering and exiting from an interrupt and also the DMA configuration time.  

    is there a dma engine / second processor that does it or is this really code running on the processor?

    Sorry there is only one processor. But I'm not sure what you mean "really code".

    Best Regards,

    Pengfei