xilinx dma調試筆記

按照官方案例,啓動接收傳輸:

        u32 Status = XAxiDma_SimpleTransfer(&AxiDma, (UINTPTR)RxDMAPtr,
                 (u32)(1024), XAXIDMA_DEVICE_TO_DMA);
        if (Status != XST_SUCCESS) {
            printf("dma from device error:%d\n", Status);
            pthread_exit(0);
        }

發現接收到的中斷總會進入IRQ_ERROR,打印IrqStatus的值

        IrqStatus = XAxiDma_IntrGetIrq(&AxiDma, XAXIDMA_DEVICE_TO_DMA);
        XAxiDma_IntrAckIrq(&AxiDma, IrqStatus, XAXIDMA_DEVICE_TO_DMA);
        if (!(IrqStatus & XAXIDMA_IRQ_ALL_MASK)) {
            printf("all mask = %x\n", IrqStatus);
            continue;
        }
        if ((IrqStatus & XAXIDMA_IRQ_ERROR_MASK)) {
            Error = 1;
            XAxiDma_Reset(&AxiDma);
            TimeOut = RESET_TIMEOUT_COUNTER;
            while (TimeOut) {
                if(XAxiDma_ResetIsDone(&AxiDma)) {
                    break;
                }
                TimeOut -= 1;
            }
            printf("Error:0x%x dma from device %d \n", IrqStatus,TimeOut);
            continue;
        }
        if ((IrqStatus & XAXIDMA_IRQ_IOC_MASK)) {
            RxDone++;
            Packet_Rx_Length = XAxiDma_ReadReg(AxiDma.RxBdRing[0].ChanBase, XAXIDMA_BUFFLEN_OFFSET);
            printf("actural rx length = %ld\n", Packet_Rx_Length);
            sem_post(&c2h_sem);//trig to read
        }

輸出Error:0x5000 dma from device 10000

XAXIDMA_IRQ_ERROR_MASK宏定義爲0x004000

XAXIDMA_IRQ_IOC_MASK宏定義爲0x001000

說明同時接收完畢,也產生了錯誤,官方例程對錯誤的處理是直接對dma進行復位,沒有對錯誤進行分類;

 

查看手冊pg021_axi_dma,找到

S2MM_DMASR (S2MM DMA Status Register – Offset 34h)

This register provides the status for the Stream to Memory Map DMA Channel.

對於Error的分類在低11位,然而讀到IrqStatus低11位全是0,想必在讀函數中做了MASK;果然找到讀出後與0x007000相與,重寫讀IrqStatus;

        IrqStatus = XAxiDma_ReadReg(AxiDma.RegBase + (XAXIDMA_RX_OFFSET * XAXIDMA_DEVICE_TO_DMA), XAXIDMA_SR_OFFSET);

 

打印輸出IrqStatus值爲0x5011,表示DMAIntErr和Halted爲1;

Halted位描述如下

DMA Channel Halted. Indicates the run/stop state of the DMAchannel.

• 0 = DMA channel running.

• 1 = DMA channel halted. For Scatter/Gather Mode this bit gets set when DMACR.RS = 0 and DMA and SG operations have halted. For Direct Register Mode this bit gets set when DMACR.RS = 0 and DMA operations have halted. There can be a lag of time between when DMACR.RS = 0 and when DMASR.Halted = 1.

Note: When halted (RS= 0 and Halted = 1), writing to TAILDESC_PTR pointer registers has no effect on DMA operations when in Scatter Gather Mode. For Direct Register Mode, writing to the LENGTH register has no effect on DMA operations.

DMAIntErr位描述如下:

DMA Internal Error. This error occurs if the buffer length specified in the fetched descriptor is set to 0. Also, when in Scatter Gather Mode and using the status app length field, this error occurs when the Status AXI4-Stream packet RxLength field does not match the S2MM packet being received by the S_AXIS_S2MM interface. When Scatter Gather is disabled, this error is flagged if any error occurs during Memory write or if the incoming packet is bigger than what is specified in the DMA length register.

This error condition causes the AXI DMA to halt gracefully. The DMACR.RS bit is set to 0, and when the engine has completely shut down, the DMASR.Halted bit is set to 1.

• 0 = No DMA Internal Errors.

• 1 = DMA Internal Error detected.

於是找到設置DMA length register:

S2MM_LENGTH (S2MM DMA Buffer Length Register – Offset 58h)

This register provides the length in bytes of the buffer to write data from the Stream to Memory map DMA transfer.

S2MM Length描述爲:

Indicates the length in bytes of the S2MM buffer available to write receive data from the S2MM channel. Writing a non-zero value to this register enables S2MM channel to receive packet data.

At the completion of the S2MM transfer, the number of actual bytes written on the S2MM AXI4 interface is updated to the S2MM_LENGTH register.

Note: This value must be greater than or equal to the largest expected packet to be received on S2MM AXI4-Stream. Values smaller than the received packet result in undefined behavior.

Notes:

1. Width of Length field determined by Buffer Length Register Width parameter. Minimum width is 8 bits (7 to 0) and maximum width is 26 bits (25 to 0).

問題是設置傳輸的S2MM buffer length太小,在傳輸結束後讀取S2MM length可以讀到實際傳輸的包大小;

S2MM Length的位寬可在DMA IP核例化的時候設置。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章