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.

Is there any alternate way to read ADC result data using DMA other than FIFO incase if multiple channels are configured in single group

Other Parts Discussed in Thread: TMS570LS3137, HALCOGEN

Hi,

I have configured 3 DMA channels which are chained to read the result of 3 ADC channels in Group-1. 

FIFO buffer is the source for DMA channels.

What I am observing is sometimes, DMA Ch-1 is copying ADC Ch-2 data into ADC Ch-1 result buffer i.e., channel results are not being placed into destination as per their ID's.

DMA channels are chained to make sure that they will be triggered in proper sequence.

ADC is configured in such a way that it will set end of conversion trigger to DMA when it completes 30 conversions & 3 channels are configured. That is 10 conversions per each channel and Element count of each DMA channel is 10.

Incase of ID mismatch in the result buffer, we have to add the validation of Channel ID which will again add CPU overhead incase if more no of samples are used.

So, I am interested to know if there is any way to obtain ADC result data with varied locations for each channel rather than having same source address for all the 3 DMA channels.

  • Satya,

    If I understand your application, you have ADC group 1 configured to convert 3 channels. Let say Chan0, Chan1, Chan2.
    The converted data (and ID) will be stored in ADC_RAM as following:

    Chan0
    Chan1
    Chan2
    Chan0
    Chan1
    Chan2....

    Because you want 10 conversion for each channel, a total of 30 buffers will be assigned to ADC group1.

    To make this example easier read I will name the first converted data for Chan0 -> Chan0_0 and the last one Chan0_9. The same will be done for Chan1 and Chan2.

    So now in the buffer we have:

    Chan0_0
    Chan1_0
    Chan2_0
    Chan0_1
    Chan1_1
    Chan2_1

    ....

    Chan0_9
    Chan1_9
    Chan2_9

    When all conversion are done, you want the DMA to transfer and organize your converted data as following:

    RAM_Buffer_0: Chan0_0;Chan0_1;Chan0_2;Chan0_3;Chan0_4;Chan0_5;Chan0_6;Chan0_7;Chan0_8;Chan0_9
    RAM_Buffer_1: Chan1_0;Chan1_1;Chan1_2;Chan1_3;Chan1_4;Chan1_5;Chan1_6;Chan1_7;Chan0_8;Chan1_9
    RAM_Buffer_2: Chan2_0;Chan2_1;Chan2_2;Chan2_3;Chan2_4;Chan2_5;Chan2_6;Chan2_7;Chan0_8;Chan2_9

    Please correct any miss-understanding from my side.

    Based on your reply I will provide a solution.

  • Hi Jean,

    Thanks for your kind reply.

    Yes, I want the data to be organized in that scenario. Hence, I configured 3 DMA channels in which Ch-2 is chained with Ch-1 and Ch-3 is chained with Ch-2 to make sure that DMA channels -1,2 & 3 will be triggered sequentially in an order.

    But the result buffers are not containing the respective channel's data i.e., ADC Ch-1 buffer contains ADC Ch-1 or Ch-2 or Ch-3 and it is varying.

    In this scenario, I have to provide validation of channel data by checking the channel id which I don't want.

    Please suggest.

  • Satya,


    In your scenario, when all 3 x 10 conversions are performed, is it ok to stop conversion and than transfer via DMA?
    When transfer is done, is it ok to restart conversion sequence for another 3 x 10 conversion?
    Or do you need the conversion to run non stop in background?

    Also, which device/board are you using?

    Please let me know.
    I will be busy this morning, but plan to work on a solution this afternoon (US central time)

  • Jean,

    We are using TMS570LS3137 controller.

    I need ADC to run in continuous conversion mode

  • Hi Jean,

    Can you please reply to my query as I need to identify the root cause behind the mismatch of ADC Channel ID for which I have to provide solution at the earliest.

     

    Thank & Regards,

    Satya Sudhir Sure

  • Satya,

    When ADC is used in Continuous mode, whenever the buffer area defined for the given group is full the next write will create an overrun condition, and this write will be discarded. When some data are read (by CPU or DMA) this will allow the ADC to store new converted data.
    Write from ADC to buffer and read from CPU or DMA are not in synch.

    An option to bypass this condition is to configure the group with the OVR_Gx_RAM_IGN bit set in ADGxMODECR Register.
    Here is the description from TRM:

    That way, the data in buffer will always be in order:

    Chan0
    Chan1
    Chan2
    Chan0
    Chan1
    Chan2....

    (Assuming you are doing conversion of 3 channels, 0 1 and 2)

    The DMA (or CPU) can now read the data directly from the ADC_RAM and store to your 3 buffer in RAM.

    Halcogen does not provide a way to set the OVR_Gx_RAM_IGN bit in ADGxMODECR so you will have to patch the adcInit() routine as following:

        /** - Setup group 1 conversion mode
        *     - Setup data format
        *     - Enable/Disable channel id in conversion result
        *     - Enable/Disable continuous conversion
        */
        adcREG1->GxMODECR[1U] = (uint32)ADC_12_BIT
                              | (uint32)0x00000030U      //Channel ID and OVR_G1_RAM_IGN
                              | (uint32)0x00000000U  
                              | (uint32)0x00000002U;    //Continuous mode

    This example assumes Group1 is used.

    Please have a try and let me know.

  • Satya,


    I've build an project that is using 3 DMA channels to move the converted data from 3 ADC channels to 3 buffers in RAM.

    ADC is configured in Continuous mode, with OVR_G1_RAM_IGN Set. As said in a previous post, this bit is not controlled by Halcogen
    so I modified the adcInit() after generation as following:

        adcREG1->GxMODECR[1U] = (uint32)ADC_12_BIT
                              | (uint32)0x00000030U            // G1_CHID and OVR_G1_RAM_IGN
                              | (uint32)0x00000000U
                              | (uint32)0x00000002U;           // Continuous mode

    Also, it is necessary to configure the ADC DMA Register. This is also not under Halcogen control. So at the end of adcInit() I've added:

    /* USER CODE BEGIN (4) */
        adcREG1->G1DMACR=0x001E0005;                       // After 30 conversions (0x1E) generate a block DMA Request
                                                                                                     // G1_BLK_XFER = 1
                                                                                                     // G1_DMA_ENA = 1
    /* USER CODE END */

    Because this code is in a USER CODE BEGIN/USER CODE END, it will be preserved.

    Here is the full project (CCS and Halcogen)

    4628.TMS570LS3137_ADC_DMA.zip

    Please have a try and let me know your feedback.

  • Satya,

    What is the status on your problem?
    Does the provided code helped you?

    If so, can you mark this thread as answered?

  • Thanks for explaining about overrun bit in Group Mode Control Register. This suggestion helped me.

  • Thanks for your explanation.