Post Go back to editing

Troubleshooting Rx DMA Transmission Restart Issues in EMAC

Category: Hardware
Product Number: ADSP-SC598

1. how to restart Rx DMA transmission? if i have 4 Rx descriptors with own bits seted as 0 1 0 0, adi_emac_RxDescriptorPoll() will not restart transmission.

2. why the size of EMAC_DMA0_RXDSC_TLPTR is NO_OF_DESCS + 4?

3 when  "Current Descriptor Pointer == Descriptor Tail Pointer" , how to restart transmission?



Updating subject to be relevant to content.
[edited by: StephenV at 12:22 PM (GMT -4) on 20 Aug 2024]
  • Hi,

    We are currently analyzing the initialization of the EMAC DMA.We will update you with the relevant information shortly.

    Regards,
    Nandini.C

  • Hi,

    Please find the inline response below.

    Q1 & Q3>>  We suggest you refer the section "Stopping and Starting Transmission"[Page No: 2080/4482] in ADSP-SC598 Hardware reference Manual from the below link,
    www.analog.com/.../adsp-sc595-sc596-sc598-hrm.pdf

    For more information, Please refer the sections "DMA Receive Operation"[Page No: 1898/4482] and "DMA Controller (EMAC DMA)" [Page No :1890/4482] in the above linked ADSP-SC598 Hardware reference Manual.

    Q2>> The EMAC DMA has separate transmit and receive engines, as well as a control and status register (CSR) space. The transmit engine moves data from system memory to the FIFO (MTL), while the receive engine transfers data from the FIFO (MTL) to system memory. The DMA engine uses descriptors to efficiently transfer data with minimal processor core intervention.

    In adi_emac_dma_queue_v2.c, the adi_emac_SubmitDescriptorListRx API works as expected.

    The line:
    pEmacInfo->pEMAC_REGS->EMAC_DMA0_RXDSC_TLPTR =(uintptr_t)adi_rtl_internal_to_system_addr(((uintptr_t)&pRxDescriptor[nNoOfDescr-1])+4, 1);
    It sets the EMAC_DMA0_RXDSC_TLPTR register. The additional 4 bytes in EMAC_DMA0_RXDSC_TLPTR are included to ensure efficient data transfers from the FIFO (MTL) to system memory.
     
    The internal address used by the hardware component is converted to a system-wide address that the operating system or other system parts can recognize. This conversion maps addresses from the hardware’s internal format to the system’s address space.

    Regards,
    Nandini.C

  • The hardware we used are sc598som and somcrr-ezkit. And we have read the hrm pdf file, the debug result is inconsistent with the hardware manual.

    Actually we have to use functions such as adi_emac_xxx to manipulate the transportation rather than using registers described in hrm manual.

    When DMA transportation stopped at middle descriptors, the adi_emac_RxDescriptorPoll function won't resume the transportation. It is inconsistent with  the 4 point in sections "Receive Descriptor Acquisition"[Page No: 1899/4482]. The sections "Stopping and Starting Transmission"[Page No: 2080/4482] don;'t tell the detailed instrctions to restart transportation.

    The EMAC_DMA[n]_RXDSC_CUR doesn't update with transportation which should be updated according to [Page No: 1891/4482], but pEmacInfo->pDevice->RxChannel[0].nIndex does. 

    For Q1 and Q3, there are not  detailed instrctions in the sections you provide.

    Regards,

  • Hi,

    We tried to replicate your issue using the EMACPhyLoopback example code available in the ADSP-SC594 BSP. We analyzed the issue that before using the adi_emac_RxDescriptorPoll() API, you should use the adi_emac_ReSubmitDescriptorTx() API to restart the receive DMA. Additionally, make sure to submit the descriptor back to the DMA using the  adi_emac_ReSubmitDescriptorTx()API.

    We are still analyzing this and will get back to you on this.

    In meanwhile, can you please provide further comments on below points to assist you better on this issue.

    1. We hope, are you using the adi_emac_ReSubmitDescriptorTx() API before using the adi_emac_RxDescriptorPoll() API?
    2. How do you verify whether your DMA descriptor is suspended (using interrupts or the DMA Status registers)?
    3. What steps or procedures are you following to restart the Rx DMA? Additionally, how many descriptors are you using in total for your application?
    4. Which specific function from the adi_emac_xxx library are you using to manage transmission? Have you made any changes to the EMAC DMA driver code?
    5. Can you check the EMAC_DMA[n]_STAT register to see if any status bits are set after the transmission has stopped/before restarting poll API ?
    6. Before restarting the RX transmission, did you check and confirm that the first descriptor contains the correct data in both the TX and RX descriptors?

    Regards,
    Nandini C

  • adi_emac_SubmitDescriptorRx() does not exists, only adi_emac_ReSubmitDescriptorRx() is found. Your answer "use the adi_emac_ReSubmitDescriptorTx() API to restart the receive DMA" is really correct? 

    About your questions:
    1. We use the  adi_emac_ReSubmitDescriptorRx() before using the adi_emac_RxDescriptorPoll() API, rather than adi_emac_ReSubmitDescriptorTx().
    2. The Rx callback function is not called. 
    3. We have tried two ways:

    (1) We use the initialization procedure of Rx descriptors in EMACPhyLoopback example, it works.
    (2) We use the combination of adi_emac_ReSubmitDescriptorRx() API and adi_emac_RxDescriptorPoll() API , it works when DMA suspends at the firsrt descriptor. 

    4. Use adi_emac_SubmitDescriptorListRx() to restart transmission. We don't change driver code.

    5. The register value is different according to the poll condition. 

    6. We reset the descriptors to initialization value.

    More, we found that the desciptor status are valetile and not synchronous with data buffer. for example, the data has been writeen to the receive buffer,but the OWN bit and IOC bit are still 1'b1.

  • Hi,

    Apologies for the confusion

    Please find the attached EMAC example code for using adi_emac_ReSubmitDescriptorRx() and adi_emac_RxDescriptorPoll API. In that example code, we configured the 4 descriptors with the OWN bits set as 0 1 0 0. After DMA suspension , We called both the resubmit and poll APIs to restart the Tx-Rx based on the buffer available status via EmacStatCallback() function. Whenever the buffer is unavailable for DMA (i.e., owned by application), the EmacStatCallback() called and it will update the flag bit for retransmission.

    ADSP_SC598_EMAC_Example.zip

    For best practices, Please reset the board before each debugging/testing session.

    Regards,
    Nandini C

  • Hi,

    The ZIP file you provided may be missing files, the src folder in CORE1 is empty. Is the EmacStatCallback function the same as the EmacDMARxCallback or the EmacDMATxCallback function? From your answer, can we infer that the correct timing to call the resubmit function and the poll function is within the callback function? And please provide the interface function for the flag bit for retransmission, is it just using resubmit function and poll function?

    Thanks for your reply.

  • Hi,

    Sorry for the inconvenience caused.

    we have attached the complete example project with the source file.

    Is the EmacStatCallback function the same as the EmacDMARxCallback or the EmacDMATxCallback function?
    >> The EmacStatCallback() function is called based on the DMA/Queue status of the EMAC. We used adi_emac_RegisterDMAQueueStatusCallback() API to register the EmacStatCallback.
     
    From your answer, can we infer that the correct timing to call the resubmit function and the poll function is within the callback function?
    >> It is not recommended to write too many task inside the callback function. You can use flags (Boolean) to indicate the status of the buffer to call the resubmit and poll functions.

    is it just using resubmit function and poll function?
    >> Yes, you are right we are using resubmit function and poll function for re-transmission.


    EMACPhyLoopback.zip

    Regards,
    Nandini C

  • Hi, 

    Can you provide a code example that can run in normal mode on the ARM core, not in loopback mode, and not just processing the entire descriptor queue in a single transaction? I don't think the receive and transmit process described in the hardware reference is consistent with the actual runtime behavior. And the receive processing and transmit processing in hardware reference can not be realized with adi_emac_xxx functoins.

  • Hi,

    Currently, we only have example code for EMAC loopback, which can also be used for the ARM core.
    For ARM in CCES, on the Import Projects page, select General > Existing Projects into Workspace, click Next, then browse and import EMACPhyLoopback_SC598_Cortex_Core0 (ARM), and it should work as expected.
    Please use this code as a reference and modify it as needed to meet your specific requirements.

    1. In our example code, we are used various APIs such as EMAC Tx/Rx enable, Tx/RxDescriptorPoll..Etc. Can you specify which ones are not processing as expected?

    2.In the example code, we configured 4 descriptors with the OWN bits set as 0 1 0 0. After DMA suspension, based on the RBU and TBU bits in the status register, the EmacStatCallback is called with ADI_EMAC_EVENT_RX_UNAVAILABLE and ADI_EMAC_EVENT_TX_UNAVAILABLE events. Once these events occur, we use the ReSubmitDescriptorRx API to change the descriptors from application mode to DMA mode and use the RxDescriptorPoll API to restart the DMA channel for transmit/receive operations.

    Regards,
    Nandini C