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.

tm4c1294 mcu UART port DMA sending interrupt got failure

Hi,
We are using tm4c1294 mcu to control 79616 to get the voltages and temperatures by UART. It sends cmds using DMA and receives data with DMA-pingpong mode, we found the send interrupts got lost sometimes. We have the following question:
1 What is the possible reason of the DMA send interrupt failure(got lost)?
2 How the mcu can know the failure of the DMA sending? What methord it used to identify the failure?

  • Hello Lijun,

    1 What is the possible reason of the DMA send interrupt failure(got lost)?

    If the uDMA channel is indicating an error, then it is typically due to a bus or memory protection error.

    2 How the mcu can know the failure of the DMA sending? What methord it used to identify the failure?

    If the μDMA controller encounters a bus or memory protection error as it attempts to perform a data transfer, it disables the μDMA channel that caused the error and generates an interrupt on the μDMA error interrupt vector. The processor can read the DMA Bus Error Clear (DMAERRCLR) register to determine if an error is pending. The ERRCLR bit is set if an error occurred. The error can be cleared by writing a 1 to the ERRCLR bit.

    Best Regards,

    Ralph Jacobi

  • Hi, Jacobi

    Thanks for your reply.

    We still don't know why bus or memory protection error may occur. Following is the source code we are using, please help to check it. If no error, every time Rs485_Write's excution will cause ISR got called, but sometimes the ISR didn't get called

    Init function

    void Control_Rs485Init(U32 baud)
    {
    S32 DoStatus;

    DoStatus = 1;
    io_manager(IO_MB1_DE,1,&DoStatus);
    DoStatus = 0;
    io_manager(IO_MB1_RE,1,&DoStatus);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART4);
    GPIOPinConfigure(GPIO_PA3_U4TX);
    GPIOPinConfigure(GPIO_PA2_U4RX);
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_3 | GPIO_PIN_2);
    GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_3|GPIO_PIN_2, GPIO_STRENGTH_8MA, GPIO_PIN_TYPE_STD_WPU);

    UARTConfigSetExpClk(UART4_BASE, g_ui32SysClock, baud,
    UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
    UART_CONFIG_PAR_NONE);
    UARTFIFOLevelSet(UART4_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8);
    UARTEnable(UART4_BASE);
    //HWREG(UART7_BASE + UART_O_CTL) |= UART_CTL_LBE;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    uDMAChannelAssign(UDMA_CH19_UART4TX);
    uDMAChannelAttributeDisable(UDMA_CHANNEL_UART4TX,
    UDMA_ATTR_ALTSELECT |
    UDMA_ATTR_HIGH_PRIORITY |
    UDMA_ATTR_REQMASK);

    uDMAChannelAttributeEnable(UDMA_CHANNEL_UART4TX, UDMA_ATTR_USEBURST);

    uDMAChannelControlSet(UDMA_CHANNEL_UART4TX | UDMA_PRI_SELECT,
    UDMA_SIZE_8 | UDMA_SRC_INC_8 |
    UDMA_DST_INC_NONE |
    UDMA_ARB_4);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    uDMAChannelAssign(UDMA_CH18_UART4RX);

    uDMAChannelAttributeDisable(UDMA_CHANNEL_UART4RX,
    UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
    UDMA_ATTR_HIGH_PRIORITY |
    UDMA_ATTR_REQMASK);

    uDMAChannelControlSet(UDMA_CHANNEL_UART4RX | UDMA_PRI_SELECT,
    UDMA_SIZE_8 | UDMA_SRC_INC_NONE |
    UDMA_DST_INC_8 |
    UDMA_ARB_4);

    uDMAChannelControlSet(UDMA_CHANNEL_UART4RX | UDMA_ALT_SELECT,
    UDMA_SIZE_8 | UDMA_SRC_INC_NONE |
    UDMA_DST_INC_8 |
    UDMA_ARB_4);
    while (UARTCharsAvail(UART4_BASE)) {
    UARTCharGetNonBlocking(UART4_BASE);
    }
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    UARTIntEnable(UART4_BASE,UART_INT_DMARX|UART_INT_DMATX);
    IntEnable(INT_UART4);
    }

    Write function

    Uart_ReturnType Rs485_Write(U8 Handler,U8 *Buf,U16 Length)
    {
    Uart_ReturnType ret =UART_NOT_OK;
    U16 pLength = Length;

    if((Buf == NULL)||(Length < 4)||(Length > 1020))
    {
    return ret;
    }
    #if 0
    while(pLength--)
    {
    UARTCharPut(UART7_BASE, *Buf++);
    }
    Rs485TxStatus =1;
    #else
    if(Handler == 3)
    {
    //handler 3 for pcs communication using
    uDMAChannelTransferSet(UDMA_CHANNEL_UART4TX | UDMA_PRI_SELECT,
    UDMA_MODE_BASIC, Buf,
    (void *)(UART4_BASE + UART_O_DR),
    pLength);
    uDMAChannelEnable(UDMA_CHANNEL_UART4TX);
    UARTDMAEnable(UART4_BASE, UART_DMA_TX);
    Control_Rs485TxStatus =0;
    }
    else if((Handler == 0)||(Handler == 1))
    {
    while(pLength--)
    {
    UARTCharPut(UART7_BASE, *Buf++);
    }
    Rs485TxStatus =1;
    }
    else
    {
    //handler 0,1,2 for 79616
    uDMAChannelTransferSet(UDMA_CHANNEL_UART7TX | UDMA_PRI_SELECT,
    UDMA_MODE_BASIC, Buf,
    (void *)(UART7_BASE + UART_O_DR),
    pLength);
    uDMAChannelEnable(UDMA_CHANNEL_UART7TX);
    UARTDMAEnable(UART7_BASE, UART_DMA_TX);
    Rs485TxStatus =0;

    }
    #endif
    ret = UART_OK;
    return ret;
    }

    ISR 

    void UART7IntHandler(void)
    {
    uint32_t ui32Status=0;

    ui32Status = UARTIntStatus(UART7_BASE, 1);
    UARTIntClear(UART7_BASE, ui32Status);

    if(ui32Status & UART_INT_DMATX)
    {
    if(UDMA_MODE_STOP == uDMAChannelModeGet(UDMA_CHANNEL_UART7TX | UDMA_PRI_SELECT))
    {
    Rs485TxStatus =1;
    uDMAChannelDisable(UDMA_CHANNEL_UART7TX);
    UARTDMADisable(UART7_BASE, UART_DMA_TX);
    }
    else
    {
    Rs485TxStatus =1;
    uDMAChannelDisable(UDMA_CHANNEL_UART7TX);
    UARTDMADisable(UART7_BASE, UART_DMA_TX);
    }
    }

    if(ui32Status & UART_INT_DMARX)
    {
    if(UDMA_MODE_STOP == uDMAChannelModeGet(UDMA_CHANNEL_UART7RX | UDMA_PRI_SELECT))
    {
    (Rs485DmaRunData[0].step)++;
    uDMAChannelTransferSet(UDMA_CHANNEL_UART7RX | UDMA_PRI_SELECT,
    UDMA_MODE_PINGPONG,
    (void *)(UART7_BASE + UART_O_DR),
    (Rs485DmaRunData[0].p[2]), (Rs485DmaRunData[0].len[2]));
    }
    else if(UDMA_MODE_STOP == uDMAChannelModeGet(UDMA_CHANNEL_UART7RX | UDMA_ALT_SELECT))
    {
    (Rs485DmaRunData[0].step)++;
    uDMAChannelTransferSet(UDMA_CHANNEL_UART7RX | UDMA_ALT_SELECT,
    UDMA_MODE_PINGPONG,
    (void *)(UART7_BASE + UART_O_DR),
    (Rs485DmaRunData[0].p[3]), (Rs485DmaRunData[0].len[3]));
    }
    else
    {
    (Rs485DmaRunData[0].step) =0xff;
    uDMAChannelDisable(UDMA_CHANNEL_UART7RX);
    UARTDMADisable(UART7_BASE, UART_DMA_RX);
    }
    if((Rs485DmaRunData[0].step) == 4)
    {
    (Rs485DmaRunData[0].step) = 0;
    Rs485RxStatus =1;
    uDMAChannelDisable(UDMA_CHANNEL_UART7RX);
    UARTDMADisable(UART7_BASE, UART_DMA_RX);
    }
    }
    }

  • Hello Lijun,

    Honestly, its a bit hard to follow your code with how disjointed the setup is and I am not sure if that is causing some of the issue.

    But also seeing the variable length used for the uDMAChannelTransferSet for UART4, I am wondering if maybe you need to look into the uDMAChannelControlSet settings you have if the size of the transfers configured there is too high. That could be one possible cause for an error I could think of.

    Beyond that I think you need to dig into your code deeper to understand what is triggering the error cases via debugging what is occurring in the system when the errors are being triggered. Look for elements like not enough data being available or incorrect addresses for buffers or even stack overflow potentially (though I would expect that would crash your code entirely).

    Best Regards,

    Ralph Jacobi