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.

TMS320F28379D: ADC with DMA for all adc channels

Part Number: TMS320F28379D

.Hello guys, I need advice how to solve my problem:

I have 6x ADC Inputs:
1 - AdcCregs ADCINC2 - ADCINC3 (DMA Channel 1)
2 - AdcAregs ADCINA4 - ADCINA5 (DMA Channel 2)

3 - AdcAregs ADCINA2 - ADCINA3 (DMA Channel 3)
4 - AdcDregs ADCIND0 - ADCIND1 (DMA Channel 4)

5 - AdcBregs ADCINB2 - ADCINB3 (DMA Channel 5)
6 - AdcDregs ADCIND2 - ADCIND3 (DMA Channel 6)

I have successfully done the function for 1,2 and 5,6 channels, where based on the EPwm1 and EPwm3 trigger I start the ADC conversion and fill the buffers using DMA (Samples must be processed in real time). As you may have noticed, I use differential measurement. The problem occurs when I want to embed channels 3 and 4 who share the same ADC registers. I would have to constantly switch registers (ADCSOC1 CHSEL) for conversion for 3, 4 inputs, while 1 - 2, 5 - 6 inputs they would not be able to store samples in DMA buffers at that time.

Would you advise me or give me any idea how to do it ? Thanks.

- Mark

  • Mark,

    As I understand your problem, ADCA/B/C/D all are utilized while operating channels 1,2,5 and 6. The parallelism for these channels will be possible but not for channels 3 and 4.

    Since there are 16 SOCs for each ADC, you need not switch the CHSEL register everytime, rather initialize the channels with different numbered SOC. That should eliminate the need to update the SOCxCTL register everytime.

    Are you need of operating all the channels in parallel with data being sent to the DMA at the same instant for all channels? If so, you can try reading the data in the ISR only when the last conversion is complete. This will reduce the output frequency but will suffice the need to synchronize the operation.

    Thanks,

    Aditya

  • Hello Aditya,

    Yes, you got it right. Im using SOC0 - SOC9 for oversample. So I only have to do it in series and gradually switch dma buffers and ADC channels with CHSEL. It would be best if all adc channels work in parallel. I don't know if I will have enough time to process the sampled buffers in series.

    Or, can i feed buffers with round robin algorithm only with 2 DMA channels ?
    Example: Set DMA Source CH1 for Buffer1, after conversion 1sample CHSEL to another adc channel, and change DMA Source CH1 Buffer3  1 sample and again... Same for DMA CH2 .. But this seems be slower, i need faster method its realtime signal.

    - Mark

  • Mark,

    If you are fine oversampling using SOC0-7 (we will divide into two sets of 8 for each conversion), then another solution can be tried.

    DMA Ch 1: AdcCregs (ADCC: SOC 0 - 7)

    DMA Ch 2: AdcAregs (ADCA: SOC 0 - 7)

     

    DMA Ch 3: AdcAregs (ADCA: SOC 8 - 15)

    DMA Ch 4: AdcDregs (ADCD: SOC 8 - 15)

    DMA Ch 5: AdcBregs (ADCB: SOC 0 - 7)

    DMA Ch 6: AdcDregs (ADCD: SOC 0 - 7)

    Generate interrupt at the end of ADCA/D SOC15 completion and trigger the DMA channel transfer. You may not need to change the CHSEL bit.

    Does this idea help your application?

    Aditya

  • Thanks for answer. So for DMA CH1 and CH2 ISR I just trigger ADCC at SOC7 ? and for DMA CH3 ADC/A or D ?
    Like this ?

    static void DMA_CH1_Init(volatile Uint16 *adcRes)
    {
        DMACH1ModeConfig(DMA_ADCCINT1, PERINT_ENABLE, ONESHOT_DISABLE,
                         CONT_ENABLE, SYNC_DISABLE, SYNC_SRC,
                         OVRFLOW_DISABLE, SIXTEEN_BIT, CHINT_END,
                         CHINT_ENABLE);
    }
    
    static void DMA_CH3_Init(volatile Uint16 *adcRes)
    {
        DMACH1ModeConfig(DMA_ADCAINT1, PERINT_ENABLE, ONESHOT_DISABLE, //Trigger Set ADC A
                         CONT_ENABLE, SYNC_DISABLE, SYNC_SRC,
                         OVRFLOW_DISABLE, SIXTEEN_BIT, CHINT_END,
                         CHINT_ENABLE);
    }

    ADAINTSEL1N2.bit.INT1SEL = 15;
    ADBINTSEL1N2.bit.INT1SEL = 7;
    ADCINTSEL1N2.bit.INT1SEL = 7;
    ADDINTSEL1N2.bit.INT1SEL = 15;


  • Mark,

    This looks good to me. Did you try this on the setup? Were the results in line with expectations?

    Thanks,

    Aditya

  • Hi, I did it and it works perfectly for me. Simple and quick solution to the problem, thank you very much for the information.