【原创】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

posted @ 2018-06-28 03:34  霸天虎1108  阅读(4270)  评论(0编辑  收藏  举报