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.

TMS570LC4357: Hardware Triggering ADC + DMA causes ADC Overrun

Part Number: TMS570LC4357

Hi,

I am currently trying to accomplish the following goals:

  1. Have some ADC1 channels (in the event group) be hardware triggered.
  2. Use DMA to transfer ADC readings from ADC1's RAM to CPU's RAM (SRAM).

My implementation is able to accomplish these goals. However, ADC1's memory overruns (indicated by ADEVINTFLG), after DMA completes its transfer of ADC readings once.

The ADC readings that are transferred are correct, and DMA's PEND register shows its not waiting for services.

Thanks for your help!

  • Sorry, I want to add that DMA is directly reading from ADC1's result memory, instead of its FIFO registers.

  • I want to add again that same issue (memory overruns) occurs, if CPU reads directly from ADC1's RAM. However, the issue disappears, if DMA/CPU reads from ADC1's FIFO registers.

  • Got your question, and will give you my comments later.

  • If using group block DMA transfer (EV_BLK_XFER=1), a DMA request is generated when the ADC has written EV_BLOCKS number of buffers into the Event Group memory.

    In DMA packet configuration, the element size should be equal to EV_BLOCKS. Otherwise you may get overrun interrupt.

  • Hi, QJ Wang

    Thanks for your attention and response!

    I am using frame transfer for DMA channels and (DMA_EV_END = 1) for ADCs.

    Do I have to use block transfer (DMA) and EV_BLK_XFER instead?

    Here is my current settings:

    DMA:

        dmaChannelAdc1Rx[EventGroup] = DMA_CH26;
        dmaControlAdc1Rx[EventGroup].SADD = adc1SourceAddresses[EventGroup];
        dmaControlAdc1Rx[EventGroup].DADD = (uint32_t)settings->dmaAdc1RxBuffer[EventGroup];
        dmaControlAdc1Rx[EventGroup].CHCTRL = 0U;
        dmaControlAdc1Rx[EventGroup].FRCNT = 1U;
        dmaControlAdc1Rx[EventGroup].ELCNT = settings->dmaAdc1RxBufferSize[EventGroup];
        dmaControlAdc1Rx[EventGroup].ELDOFFSET = 0U;
        dmaControlAdc1Rx[EventGroup].ELSOFFSET = 0U;
        dmaControlAdc1Rx[EventGroup].FRDOFFSET = 0U;
        dmaControlAdc1Rx[EventGroup].FRSOFFSET = 0U;
        dmaControlAdc1Rx[EventGroup].PORTASGN = PORTB_READ_PORTA_WRITE;
        dmaControlAdc1Rx[EventGroup].RDSIZE = ACCESS_32_BIT;
        dmaControlAdc1Rx[EventGroup].WRSIZE = ACCESS_32_BIT;
        dmaControlAdc1Rx[EventGroup].TTYPE = FRAME_TRANSFER;
        dmaControlAdc1Rx[EventGroup].ADDMODERD = ADDR_INC1;
        dmaControlAdc1Rx[EventGroup].ADDMODEWR = ADDR_INC1;
        dmaControlAdc1Rx[EventGroup].AUTOINIT = AUTOINIT_ON;

    ADC:

    ADEVDMACR: 0x0000 0008
    ADEVMODECR: 0x0000 0000
    ADEVSRC: EPWM
    
    ADCLOCKCR, ADEVSAMP, and ADEVSAMPDISEN are all set.

  • I tried the following settings. The memory overrun issue still occur.

    DMA:

        dmaChannelAdc1Rx[EventGroup] = DMA_CH26;
        dmaControlAdc1Rx[EventGroup].SADD = adc1SourceAddresses[EventGroup];
        dmaControlAdc1Rx[EventGroup].DADD = (uint32_t)settings->dmaAdc1RxBuffer[EventGroup];
        dmaControlAdc1Rx[EventGroup].CHCTRL = 0U;
        dmaControlAdc1Rx[EventGroup].FRCNT = 1U;
        dmaControlAdc1Rx[EventGroup].ELCNT = settings->dmaAdc1RxBufferSize[EventGroup];
        dmaControlAdc1Rx[EventGroup].ELDOFFSET = 0U;
        dmaControlAdc1Rx[EventGroup].ELSOFFSET = 0U;
        dmaControlAdc1Rx[EventGroup].FRDOFFSET = 0U;
        dmaControlAdc1Rx[EventGroup].FRSOFFSET = 0U;
        dmaControlAdc1Rx[EventGroup].PORTASGN = PORTB_READ_PORTA_WRITE;
        dmaControlAdc1Rx[EventGroup].RDSIZE = ACCESS_32_BIT;
        dmaControlAdc1Rx[EventGroup].WRSIZE = ACCESS_32_BIT;
        dmaControlAdc1Rx[EventGroup].TTYPE = BLOCK_TRANSFER;
        dmaControlAdc1Rx[EventGroup].ADDMODERD = ADDR_INC1;
        dmaControlAdc1Rx[EventGroup].ADDMODEWR = ADDR_INC1;
        dmaControlAdc1Rx[EventGroup].AUTOINIT = AUTOINIT_ON;

    ADC:

    ADEVDMACR: 0x0002 0004
    ADEVMODECR: 0x0000 0000
    ADEVSRC: EPWM
    
    ADCLOCKCR, ADEVSAMP, and ADEVSAMPDISEN are all set.

    Unfortunately, I am not able to show more code. Are there any registers or directions that I can look further, to probe the root cause?

  • If EV_BLK_XFER=0, ADC module generates a DMA request for each write to the Event memory if EV_DMA_EN is set.
    If EV_BLK_XFER=1, ADC module generates a DMA request when the ADC has written EV_BLOCKS number of buffers into the Event memory.

    The element size of DMA packet should be the same as EV_BLOCKS.

    DMA controller should complete reading out 2 data (EV_BLOCKS=2 in your config) before next set of 2 conversions complete.

  • Update on the status of this post:

    I have tried the recommended fixes in the post, but they did not work for me. (This does not invalidate the fact that these recommendations are in fact correct.)

  • We suspect this issue may be caused by the way we trigger the ADC module.

    We have decided not to use ADC with DMA, so this post may not have a resolution.

    Edit: grammar