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.

AM62P: UART with DMA mode: cannot receive data when communicating with GMSL

Part Number: AM62P
Other Parts Discussed in Thread: SYSCONFIG

Hi,

I try to establish a communication between AM62P and a GMSL chip on cusomized board and the MCU+SDK version I am using is 11.01.01.08. 

The current situation is that I could implement uart_echo example successfully. In this project, I used self-encapsulated API for uart transmission. The snipped code is attached below.  

 status = SemaphoreP_constructBinary(&gUartWriteDoneSem_gmsl1, 0);
  status = SemaphoreP_constructBinary(&gUartReadDoneSem_gmsl1, 0);

uint8_t gUartTxBuffer[200] __attribute__((aligned(CacheP_CACHELINE_ALIGNMENT)));
    uint8_t gUartRxBuffer[8] __attribute__((aligned(CacheP_CACHELINE_ALIGNMENT)));
    strncpy(&gUartTxBuffer[0],"[MCU] uart DMA test. Please enter\r\n", 200);
    length = strlen(&gUartTxBuffer[0]);
    status = uart_txEncap(0, gUartTxBuffer, length);

    status = uart_rxEncap(0, gUartRxBuffer, 8);

    status = uart_txEncap(0, gUartRxBuffer, 8);
    
    strncpy(&gUartTxBuffer[0],"\r\n[MCU] At the end of test... \r\n", 200);
    length = strlen(&gUartTxBuffer[0]);
    status = uart_txEncap(0, gUartTxBuffer, length);

The snipped code for self-encapsulated API is shown below.

int32_t uart_txEncap(uint8_t u8_core_sel, uint8_t *tx_AppBuffer, uint32_t tx_bufSize)
{
    int32_t status;
    UART_Transaction uartTrans;

    /* Cache write-back before DMA - ensures DMA reads updated data from memory */
    CacheP_wb((void *)&tx_AppBuffer[0], tx_bufSize, CacheP_TYPE_ALL);

    UART_Transaction_init(&uartTrans);
    uartTrans.count = tx_bufSize;
    uartTrans.buf = &tx_AppBuffer[0U];


    status = UART_write(gUartHandle[u8_core_sel], &uartTrans);
    UART_flushTxFifo(gUartHandle[u8_core_sel]);

    if (u8_core_sel == 0) 
    {
        SemaphoreP_pend(&gUartWriteDoneSem_gmsl1, SystemP_WAIT_FOREVER);
    }
    else if (u8_core_sel == 1)
    {
        SemaphoreP_pend(&gUartWriteDoneSem_gmsl2, SystemP_WAIT_FOREVER);
    } 

    if (SystemP_SUCCESS != (status))
    {
        return status;
    }
    else
    {
        return SystemP_SUCCESS;
    }
}

int32_t uart_rxEncap(uint8_t u8_core_sel, uint8_t *rx_AppBuffer, uint32_t rx_bufSize, uint32_t semaPend_us)
{
    int32_t status;
    UART_Transaction uartTrans;
    uint32_t lineStatus, atLeastCharInFifo = 0;

    /* Cache write-back before DMA - ensures DMA reads updated data from memory */
    CacheP_wbInv((void *)&rx_AppBuffer[0], rx_bufSize, CacheP_TYPE_ALL);

    UART_Transaction_init(&uartTrans);
    uartTrans.count = rx_bufSize;
    uartTrans.buf = &rx_AppBuffer[0U];

    status = UART_read(gUartHandle[u8_core_sel], &uartTrans);

    if (u8_core_sel == 0) 
    {
        SemaphoreP_pend(&gUartReadDoneSem_gmsl1, SystemP_WAIT_FOREVER);
    }
    else if (u8_core_sel == 1)
    {
        SemaphoreP_pend(&gUartReadDoneSem_gmsl2, SystemP_WAIT_FOREVER);
    } 

    if (SystemP_SUCCESS != (status))
    {
        return status;
    }
    else
    {
        return SystemP_SUCCESS;
    }
}

The test results is attahced below and I think everything work good. For sysconfig configuration, the baud rate is 115200, the uart is configured as DMA+callback mode, the peripheral hardware I used is USART3. 
screenshot-20260625-141439.png
screenshot-20260625-181157.png
Until now, everything works fine and I try to use those encapsulated API to communicate with GMSL. The sysconfig does not need any change except its baud rate is 1M Hz. But I found I cannot receive the response from GMSL. When I debugging, I found status of uart_tx is success and the program is blocking in uart_rxEncap, which implies soc does not receive the response of GMSL. However, I could measure the correct signal on UART_RX line as below. I wonder why this happens?

uint8_t tx_buf1[4] __attribute__((aligned(CacheP_CACHELINE_ALIGNMENT)))= {0x79, 0xC5, 0x08, 0x01};
    uint8_t rx_buf1[2] __attribute__((aligned(CacheP_CACHELINE_ALIGNMENT)))= { 0 };
    status = uart_txEncap(0, tx_buf1, 4);
    status = uart_rxEncap(0, rx_buf1, 2);

screenshot-20260625-134548.png

Regards,

Bomiao

  • Hi,

    Let me read through this and get back to you.

    Regards,

    Vaibhav

  • Hi Fan,

    When I debugging, I found status of uart_tx is success and the program is blocking in uart_rxEncap, which implies soc does not receive the response of GMSL. However, I could measure the correct signal on UART_RX line as below. I wonder why this happens?

    I have few questions.

    Wad the transmit and receive operations working correctly previously?

    If yes, then did you on a random application run(lets say nth run), found out that the receive is not happening?

    Regards,

    Vaibhav

  • Hi Vaibhav,

    (1). 

    Wad the transmit and receive operations working correctly previously?

    Previously, the uart is configured as interrupt with callback mode, the transmit and receive are working correctly. When I switch to DMA+callback mode, the problem occurs. For those two situations, they use the same protocol configuration(baud rate=1M, data length=8, stop bit=1, parity=even).

    (2).

    If yes, then did you on a random application run(lets say nth run), found out that the receive is not happening?

    No, I am not on a random run. This problem occurs every time when I using uart DMA+callback mode to communicate with GMSL.

    Since the response of GMSL signal (i.e. {0xC3, 0X0B}) could be measured on the physical line, I think there is a problem on DMA transferring. 

    Btw, the version of MCU+SDK I am using is 11.01.01.08. I want to check whether this version is fine.

    Regards,

    Bomiao

  • Hi Fan,

    Btw, the version of MCU+SDK I am using is 11.01.01.08. I want to check whether this version is fine.

    This version is fine.

    Could you explain how your reads are called? Also is the read called inside the callback again, like in a looping format?

    I am checking the fragmented code you shared above, but would like a bit of clarity on the above query.

    [Updated EDIT:] Are you making sure that your RX buffer for UART at the application layer is following all of these?

    - The RX buffer is aligned to cache line boundary using:
    uint8_t uartReceiveBuffer[APP_UART_RECEIVE_BUFSIZE] __attribute__((aligned(CacheP_CACHELINE_ALIGNMENT)));
    - This is mandatory for DMA transfers to prevent partial cache-line sharing (false sharing), which can corrupt adjacent data.

    - Before initiating UART_read(), a cache writeback-invalidate is performed on the RX buffer:
    CacheP_wbInv((void *)&uartReceiveBuffer[0U], APP_UART_RECEIVE_BUFSIZE, CacheP_TYPE_ALL);
    - This ensures:
    - Any dirty cache lines are written back to memory (writeback).
    - The cache lines are then invalidated so the CPU does not serve stale data after DMA fills the buffer.

    - All cache operations use CacheP_TYPE_ALL, meaning they apply to all cache levels (L1, L2, etc.), ensuring full coherency for DMA.

    Looking forward to your responses.

    Regards,

    Vaibhav

  • Hi Vaibhav,

    Sorry for the late response.

    This problem have already been solved. The problem is related to the position where I put the breakpoints, which leads to time sequence inconsistency. 

    I really appreciate your advice and patience. This thread could be closed.

    Regards,

    Bomiao