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-F28379D: Synchronized Continuous ADC with DMA

Part Number: LAUNCHXL-F28379D

Tool/software:

Hello, I took a look at the adc continuous dma example. It was configured to only do one adc transfer, then the program ends. I made some modifications to the program so that when the DMA ends it begins a new ADC DMA. This all works perfectly however when I specify a set sample amount (64) for a waveform that is 60Hz, I get discontinuities on the edge of each DMA cycle. I tried adjusting the EPWM module to have a frequency that matches the scenario but changing the EPWM count did not appear to do anything. Does anyone know how I can configure this so it has consistent timing?

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//###########################################################################
//
// FILE: adc_ex6_soc_continuous_dma.c
//
// TITLE: ADC continuous conversions read by DMA.
//
//! \addtogroup driver_example_list
//! <h1> ADC Continuous Conversions Read by DMA (adc_soc_continuous_dma)</h1>
//!
//! This example sets up two ADC channels to convert simultaneously. The
//! results will be transferred by the DMA into a buffer in RAM.
//!
//! \b External \b Connections \n
//! - A3 & D3 pins should be connected to signals to convert
//!
//! \b Watch \b Variables \n
//! - \b adcADataBuffer \b: a digital representation of the voltage on pin A3\n
//! - \b adcDDataBuffer \b: a digital representation of the voltage on pin D3\n
//!
//
//#############################################################################
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Attached is an imgur link to a video of what the graph of the buffer looks like

https://imgur.com/a/TLmagBq

  • Hi,

    The attached buffer is your ADCA buffer? 

    Best Regards,

    Ben Collier

  • Yes it is a graph of the expression "adcADataBuffer" and has clear discontinuities at the edges of the buffer (every 64 points).

  • My only recommendation would be to make sure that you are not doing any conversions with SOCs while you are transferring data from those SOCs.

    You could set up two DMA channels so that one transfers data for RESULT0-RESULT7 after EOC7, while the other transfers data for RESULT8-RESULT15 after EOC15. This way, the DMA will only be transferring data for the SOCs that aren't actively converting. 

  • The only code running is what I included in the original post. The recommendation of a second DMA to transfer data is useful for my intended application because I want to manipulate the data in between dma ISRs, but I am not sure why you split it in groups of 8 in your discussion. I thought this would perform a burst of 64 conversions.

  • Please let me get back to you about this tomorrow. 

  • Thanks for the help, I will also be trying to deconstruct this and make something similar using syscfg

  • Ok Dylan, I think I have a better understanding of what is happening in you code now. Please excuse the crude diagram, but this shows how various tasks are being triggered: 

    ** Also the first SOC1 should have been SOC0, sorry for that error

     

    ADCA INT2 disables the PWM that was originally used to trigger ADCA SOC0, so the PWM frequency will not really have an effect on the example.

    ADCA INT2 triggers SOC0, and SOC0 triggers ADCA INT1 which in turn triggers all of the SOCs. Finally SOC15 triggers ADCA INT2. Since the interrupt flags are never cleared and continuous mode is enabled for these ADC INTS, all SOCs are going to be continuously triggered. You will have a constant ADC frequency of ~4MSPS depending on acqps. 

    Your DMA bursts, each writing 16 words (entirety of ADC RESULTS REGs), are in turn triggered by the ADC INT A2.

    Here is where I am confused: 

    Since the ADC INT A2 is never cleared, it seems possible to me that the DMA bursts are simply done continuously instead of being triggered by SOC15. If this is the case, you will have a discontinuity after every 16 results.

    What are the setting for your CCS graph? Is it possible that there is actually a discontinuity for every 16 results? 

    Either way, I think that if you want to be able to change your ADC sampling frequency, continuous ADC sampling may not be right for your application. I think you could instead use a PWM module to trigger SOC0-SOC15, then trigger an ADC INT with SOC15, and trigger your DMA burst with the ADC INT. If you try this approach, I think you would be able to achieve your desired results. This will add a very small CPU overhead since you will have an ADC ISR and you will need to clear it every time after SOC15. 

    Best Regards,

    Ben Collier

  • Ok, I am still new to working with SOC's, but the behavior I get seems to suggest it operates a bit differently, because I receive almost one whole wave per 64 sample window with an acq of 8ns. If the samples received relied purely on the acq value I would expect to not be able to see the wave at all.

    I do agree that the suggested approach will probably be necessary since I can't seem to find a way to have the adc sample continuously at exactly 3840Hz. I'll try to build based on the example "soc_epwm" since it uses PWM to control the sample period of the ADC, then I will try to add DMA to this example so that it can do other operations while the buffer is filling. Is there a way to make a DMA have double buffers / alternating buffers? So it does not overwrite itself while its writing the new buffer?

  • Dylan,

    Is there a way to make a DMA have double buffers / alternating buffers? So it does not overwrite itself while its writing the new buffer?

    Is there a reason that you cannot just increase the size of your buffer? 

  • The system is sending data frames to a computer, so it needs to use the CPU to package and transmit data while it is collecting the next data frame. I think what I will do is use 2 DMA's and trigger the second DMA to copy the first DMA triggered in the first DMA's ISR.

  • Hi Dylan,

    If You are still looking for a way using alternating buffers instead of 2 DMA's, take a look at this example DMA Lab (ti.com) it uses ping-pong buffer where the address of the buffer pointer is alternated at the end of each transfer to prevent the DMA from overwriting the buffer.

    Best Regards,

    Rupesh Yadav

  • Thanks Rupesh, that lab is exactly what I am trying to accomplish!

  • Hi Dylan,

    If the question is resolved with the DMA lab from Rupesh, I can go ahead and close this thread. Feel free to open a new one should you run into further issues!

    Best Regards,

    Allison