【原創】ZYNQ AXIDMA IP Multichannel mode開發日記


為了測試AXI DMA IP的multi-channel mode,我們需要搭建一個簡單的硬件平台。具體的硬件電路見下圖:

 Diagram

從上圖可以看出,DMA的發送端和接收端都使用了兩個通道。這兩個通道之間通過data fifo做緩存,並且構成回路。由於AXI DMA IP的multi-channel mode的AXI4-stream接口通過TDEST、TID來區分不同的通道,因此需要AXI4-Stream Interconnect IP將兩個AXI4-Stream接口“耦合”成一個AXI4-Stream接口。值得一提的是,data fifo的AXI4-Stream接口信號中必須包含TDEST、TID,否則無法區分出這兩個通道。

軟件部分(SDK)很簡單,配置玩兩個發送和接口通道后就可以進行數據的收發了。數據收發的測試采用的方式是TX0 channel對應RX0 channel,TX1 channel對應RX1 channel,構成兩對回路先后分別測試。main函數的內容如下:

int main(void)
{
    int Status;
    XAxiDma_Config *Config;

    /* Initial setup for Uart16550 */
#ifdef XPAR_UARTNS550_0_BASEADDR

    Uart550_Setup();

#endif

    xil_printf("\r\n--- Entering main() --- \r\n");

    Config = XAxiDma_LookupConfig(DMA_DEV_ID);
    if (!Config) {
        xil_printf("No config found for %d\r\n", DMA_DEV_ID);

        return XST_FAILURE;
    }

    /* Initialize DMA engine */
    XAxiDma_CfgInitialize(&AxiDma, Config);

    if(!XAxiDma_HasSg(&AxiDma)) {
        xil_printf("Device configured as Simple mode \r\n");
        return XST_FAILURE;
    }

    /* Set up TX/RX channels to be ready to transmit and receive packets */
    Status = TxSetup(&AxiDma);
    if (Status != XST_SUCCESS) {

        xil_printf("Failed TX setup\r\n");
        return XST_FAILURE;
    }

    Status = RxSetup(&AxiDma);
    if (Status != XST_SUCCESS) {
        xil_printf("Failed RX setup\r\n");
        return XST_FAILURE;
    }

    /* Set up Interrupt system  */
    Status = SetupIntrSystem(&Intc, &AxiDma, TX_INTR_ID,
                    RX_INTR_ID, 1);
    if (Status != XST_SUCCESS) {
        xil_printf("Failed intr setup\r\n");
        return XST_FAILURE;
    }

    /* Initialize flags before start transfer test  */
    TxDone = 0;
    RxDone = 0;
    Error = 0;

    /* Send a packet */
    Status = SendPacket(&AxiDma, TDEST0, TID0, PACKET0_DATA);
    if (Status != XST_SUCCESS) {
        xil_printf("Failed send packet\r\n");
        return XST_FAILURE;
    }

    /*
     * Wait TX done and RX done
     */
    while (((TxDone < NUMBER_OF_BDS_TO_TRANSFER) ||
            (RxDone < NUMBER_OF_BDS_TO_TRANSFER)) && !Error) {
        /* NOP */
    }

    if (Error) {
        xil_printf("Failed test transmit%s done, "
            "receive%s done\r\n", TxDone? "":" not",
                RxDone? "":" not");
        goto Done;
    }else {
        /*
         * Test finished, check data
         */



//        Status = CheckData(MAX_PKT_LEN * NUMBER_OF_BDS_TO_TRANSFER,
//                            RxPacket1, PACKET0_DATA);
        Status = CheckData(MAX_PKT_LEN * NUMBER_OF_BDS_TO_TRANSFER,
                            RxPacket0, PACKET0_DATA);





        if (Status != XST_SUCCESS) {
            xil_printf("Data check failed\r\n");
            goto Done;
        }
    }

    xil_printf("Sent Packet with Tdest 0 Successfully\n\r");

    /* Initialize flags before start transfer test  */
    TxDone = 0;
    RxDone = 0;
    Error = 0;

    /* Send a packet */
    Status = SendPacket(&AxiDma, TDEST1, TID1, PACKET1_DATA);
    if (Status != XST_SUCCESS) {
        xil_printf("Failed send packet\r\n");
        return XST_FAILURE;
    }

    /*
     * Wait TX done and RX done
     */
    while (((TxDone < NUMBER_OF_BDS_TO_TRANSFER) ||
        (RxDone < NUMBER_OF_BDS_TO_TRANSFER)) && !Error) {
        /* NOP */
    }


    if (Error) {
        xil_printf("Failed test transmit%s done, "
                "receive%s done\r\n", TxDone? "":" not",
                RxDone? "":" not");
        goto Done;
    }else {
        /*
         * Test finished, check data
         */





//        Status = CheckData(MAX_PKT_LEN * NUMBER_OF_BDS_TO_TRANSFER,
//                    RxPacket0, PACKET1_DATA);
        Status = CheckData(MAX_PKT_LEN * NUMBER_OF_BDS_TO_TRANSFER,
                    RxPacket1, PACKET1_DATA);





        if (Status != XST_SUCCESS) {
            xil_printf("Data check failed\r\n");
            goto Done;
        }
    }

    /* Disable TX and RX Ring interrupts and return success */
    DisableIntrSystem(&Intc, TX_INTR_ID, RX_INTR_ID);

    xil_printf("Sent Packet with Tdest 1 Successfully\n\r");

    xil_printf("AXI DMA SG interrupt Test passed\r\n");

Done:

    xil_printf("--- Exiting main() --- \r\n");

    if (Status != XST_SUCCESS) {
        return XST_FAILURE;
    }

    return XST_SUCCESS;
}

測試結果(UART打印信息)如下:

--- Entering main() ---
Sent Packet with Tdest 0 Successfully

Sent Packet with Tdest 1 Successfully

AXI DMA SG interrupt Test passed
--- Exiting main() ---

 

原創聲明:本文版權歸 霸天虎1108 所有,轉載請注明出處。

本文標題:ZYNQ AXIDMA IP Multichannel mode開發日記

本文網址:https://www.cnblogs.com/batianhu/p/zynq_axidma_multichannelmode_diary1.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM