OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3915|回复: 4

[XILINX] ZYNQ 7020 AXI_DMA 及LWIP使用问题请教

[复制链接]

1

主题

3

帖子

0

精华

新手入门

积分
7
金钱
7
注册时间
2021-12-27
在线时间
2 小时
发表于 2021-12-27 09:21:58 | 显示全部楼层 |阅读模式
1金钱
大家好,想请教一下,我在做一个pl从上位机收数据用dma发送给ps端通过用网口发送的小工程,在《DMA_LWIP》例程外我加了个fifo,现在数据能发送但是有错误,用ila检查发现是因为axi stream data fifo没有正常写入,S_AXIS_tready信号突然拉低,导致我添加的fifo溢出 ,想请教一下是什么原因导致写入的问题以及该怎么解决呢? 谢谢各位!

ila图中可以根据我从axi_data_fifo中接出的axis_wr_data_count信号,发现数据并没有正确的给dma,每次传输只有10个数左右,很费解

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

1979

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
5520
金钱
5520
注册时间
2018-10-21
在线时间
1561 小时
发表于 2021-12-27 11:20:12 | 显示全部楼层
可以检查下DMA相关的配置和使用了
回复

使用道具 举报

1

主题

3

帖子

0

精华

新手入门

积分
7
金钱
7
注册时间
2021-12-27
在线时间
2 小时
 楼主| 发表于 2021-12-27 17:19:09 | 显示全部楼层
QinQZ 发表于 2021-12-27 11:20
可以检查下DMA相关的配置和使用了

麻烦您能帮忙看下具体是哪里的问题吗,感谢大佬!
main.c

  1. #include "dma_intr.h"
  2. #include "timer_intr.h"
  3. #include "sys_intr.h"

  4. #include "lwip/err.h"
  5. #include "lwip/tcp.h"
  6. #include "lwipopts.h"
  7. #include "netif/xadapter.h"
  8. #include "lwipopts.h"
  9. #include "tcp_transmission.h"

  10. static  XScuGic Intc; //GIC
  11. static  XScuTimer Timer;//timer
  12. XAxiDma AxiDma;
  13. u32         *RxBufferPtr[2];  /* ping pong buffers*/

  14. volatile u32 RX_success;
  15. volatile u32 TX_success;

  16. volatile u32 RX_ready=1;
  17. volatile u32 TX_ready=1;

  18. #define TIMER_LOAD_VALUE    XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ / 8 //0.25S

  19. int init_intr_sys(void)
  20. {
  21.         DMA_Intr_Init(&AxiDma,0);//initial interrupt system
  22.         Timer_init(&Timer,TIMER_LOAD_VALUE,0);
  23.         Init_Intr_System(&Intc); // initial DMA interrupt system
  24.         Setup_Intr_Exception(&Intc);
  25.         DMA_Setup_Intr_System(&Intc,&AxiDma,0,RX_INTR_ID);//setup dma interrpt system
  26.         Timer_Setup_Intr_System(&Intc,&Timer,TIMER_IRPT_INTR);
  27.         DMA_Intr_Enable(&Intc,&AxiDma);

  28. }

  29. int main(void)
  30. {
  31.         int Status;
  32.         struct netif *netif, server_netif;
  33.         struct ip_addr ipaddr, netmask, gw;
  34.         err_t err;

  35.         /* the mac address of the board. this should be unique per board */
  36.         unsigned char mac_ethernet_address[] = { 0x00, 0x0a, 0x35, 0x00, 0x01, 0x02 };

  37.         /* Initialize the ping pong buffers for the data received from axidma */
  38.         RxBufferPtr[0] = (u32 *)RX_BUFFER0_BASE;
  39.         RxBufferPtr[1] = (u32 *)RX_BUFFER1_BASE;

  40.         init_intr_sys();
  41.         TcpTmrFlag = 0;

  42.         netif = &server_netif;

  43.         IP4_ADDR(&ipaddr,  192, 168,   1,  10);
  44.         IP4_ADDR(&netmask, 255, 255, 255,  0);
  45.         IP4_ADDR(&gw,      192, 168,   1,  10);

  46.         /*lwip library init*/
  47.         lwip_init();
  48.         /* Add network interface to the netif_list, and set it as default */
  49.         if (!xemac_add(netif, &ipaddr, &netmask, &gw, mac_ethernet_address, XPAR_XEMACPS_0_BASEADDR)) {
  50.                 xil_printf("Error adding N/W interface\r\n");
  51.                 return -1;
  52.         }
  53.         netif_set_default(netif);

  54.         /* specify that the network if is up */
  55.         netif_set_up(netif);

  56.         /* initialize tcp pcb */
  57.         tcp_send_init();

  58.         Timer_start(&Timer);


  59.         while (1)
  60.         {
  61.                 /* call tcp timer every 250ms */
  62.                 if(TcpTmrFlag)
  63.                 {
  64.                         if(request_pcb->state == CLOSED || (request_pcb->state == SYN_SENT && request_pcb->nrtx == TCP_SYNMAXRTX))
  65.                         {
  66.                                 request_pcb = tcp_new();
  67.                                 if (!request_pcb) {
  68.                                         xil_printf("txperf: Error creating PCB. Out of Memory\r\n");
  69.                                         return -1;
  70.                                 }

  71.                                 //ip_set_option(request_pcb, SOF_REUSEADDR);

  72.                                 err = tcp_connect(request_pcb, &ipaddress, port, tcp_connected_callback);
  73.                                 if (err != ERR_OK) {
  74.                                         xil_printf("txperf: tcp_connect returned error: %d\r\n", err);
  75.                                         return err;
  76.                                 }
  77.                         }
  78.                         tcp_tmr();
  79.                         TcpTmrFlag = 0;
  80.                 }
  81.                 /*receive input packet from emac*/
  82.                 xemacif_input(netif); //将MAC队列里的packets传输到你的LwIP/IP stack里
  83.                 /* if connected to the server, start receive data from PL through axidma, then transmit the data to the PC software by TCP*/
  84.                 if(tcp_client_connected)
  85.                         send_received_data();
  86.         }
  87.         return 0;

  88. }
复制代码


dma_intr.h

  1. #include "dma_intr.h"

  2. int DMA_CheckData(int Length, u8 StartValue)
  3. {
  4.         u32 *RxPacket;
  5.         int Index = 0;
  6.         u32 Value;

  7.         RxPacket = (u32 *) RX_BUFFER_BASE;
  8.         Value = StartValue;

  9.         /* Invalidate the DestBuffer before receiving the data, in case the
  10.          * Data Cache is enabled
  11.          */
  12. #ifndef __aarch64__
  13.         Xil_DCacheInvalidateRange((u32)RxPacket, Length* sizeof(u32));
  14. #endif

  15.         for(Index = 0; Index < Length; Index++) {
  16.                 if (RxPacket[Index] != Value) {
  17.                         /*xil_printf("Data error %d: %x/%x\r\n",
  18.                             Index, RxPacket[Index], Value);*/

  19.                         return XST_FAILURE;
  20.                 }
  21.                 Value = (Value + 1) & 0xFF;
  22.         }

  23.         return XST_SUCCESS;
  24. }

  25. void DMA_DisableIntrSystem(XScuGic * IntcInstancePtr,
  26.                                         u16 TxIntrId, u16 RxIntrId)
  27. {
  28. #ifdef XPAR_INTC_0_DEVICE_ID
  29.         /* Disconnect the interrupts for the DMA TX and RX channels */
  30.         //XIntc_Disconnect(IntcInstancePtr, TxIntrId);
  31.         XIntc_Disconnect(IntcInstancePtr, RxIntrId);
  32. #else
  33.         //XScuGic_Disconnect(IntcInstancePtr, TxIntrId);
  34.         XScuGic_Disconnect(IntcInstancePtr, RxIntrId);
  35. #endif
  36. }

  37. static void DMA_TxIntrHandler(void *Callback)
  38. {

  39.         u32 IrqStatus;
  40.         int TimeOut;
  41.         XAxiDma *AxiDmaInst = (XAxiDma *)Callback;

  42.         /* Read pending interrupts */
  43.         IrqStatus = XAxiDma_IntrGetIrq(AxiDmaInst, XAXIDMA_DMA_TO_DEVICE);

  44.         /* Acknowledge pending interrupts */


  45.         XAxiDma_IntrAckIrq(AxiDmaInst, IrqStatus, XAXIDMA_DMA_TO_DEVICE);

  46.         /*
  47.          * If no interrupt is asserted, we do not do anything
  48.          */
  49.         if (!(IrqStatus & XAXIDMA_IRQ_ALL_MASK)) {

  50.                 return;
  51.         }

  52.         /*
  53.          * If error interrupt is asserted, raise error flag, reset the
  54.          * hardware to recover from the error, and return with no further
  55.          * processing.
  56.          */
  57.         if ((IrqStatus & XAXIDMA_IRQ_ERROR_MASK)) {
  58.                 xil_printf("rx error! \r\n");
  59.                 /*
  60.                  * Reset should never fail for transmit channel
  61.                  */
  62.                 XAxiDma_Reset(AxiDmaInst);

  63.                 TimeOut = RESET_TIMEOUT_COUNTER;

  64.                 while (TimeOut) {
  65.                         if (XAxiDma_ResetIsDone(AxiDmaInst)) {
  66.                                 break;
  67.                         }

  68.                         TimeOut -= 1;
  69.                 }

  70.                 return;
  71.         }

  72.         /*
  73.          * If Completion interrupt is asserted, then set the TxDone flag
  74.          */
  75.         if ((IrqStatus & XAXIDMA_IRQ_IOC_MASK)) {

  76.                 TxDone = 1;
  77.         }
  78. }


  79. static void DMA_RxIntrHandler(void *Callback)
  80. {
  81.         u32 IrqStatus;
  82.         int TimeOut;
  83.         XAxiDma *AxiDmaInst = (XAxiDma *)Callback;

  84.         /* Read pending interrupts */
  85.         IrqStatus = XAxiDma_IntrGetIrq(AxiDmaInst, XAXIDMA_DEVICE_TO_DMA);

  86.         /* Acknowledge pending interrupts */
  87.         XAxiDma_IntrAckIrq(AxiDmaInst, IrqStatus, XAXIDMA_DEVICE_TO_DMA);

  88.         /*
  89.          * If no interrupt is asserted, we do not do anything
  90.          */
  91.         if (!(IrqStatus & XAXIDMA_IRQ_ALL_MASK)) {
  92.                 return;
  93.         }

  94.         /*
  95.          * If error interrupt is asserted, raise error flag, reset the
  96.          * hardware to recover from the error, and return with no further
  97.          * processing.
  98.          */
  99.         if ((IrqStatus & XAXIDMA_IRQ_ERROR_MASK)) {
  100.                 xil_printf("rx error! \r\n");
  101.                 return;
  102.         }

  103.         /*
  104.          * If completion interrupt is asserted, then set RxDone flag
  105.          */
  106.         if ((IrqStatus & XAXIDMA_IRQ_IOC_MASK)) {
  107.                 if(packet_trans_done)
  108.                         xil_printf("last transmission has not finished!\r\n");
  109.                 else
  110.                         /*set the axidma done flag*/
  111.                     packet_trans_done = 1;
  112.         }
  113. }

  114. int DMA_Setup_Intr_System(XScuGic * IntcInstancePtr,XAxiDma * AxiDmaPtr, u16 TxIntrId, u16 RxIntrId)
  115. {
  116.         int Status;
  117.         //XScuGic_SetPriorityTriggerType(IntcInstancePtr, TxIntrId, 0xA0, 0x3);

  118.         XScuGic_SetPriorityTriggerType(IntcInstancePtr, RxIntrId, 0xA0, 0x3);
  119.         /*
  120.          * Connect the device driver handler that will be called when an
  121.          * interrupt for the device occurs, the handler defined above performs
  122.          * the specific interrupt processing for the device.
  123.          */
  124.         /*
  125.         Status = XScuGic_Connect(IntcInstancePtr, TxIntrId,
  126.                                 (Xil_InterruptHandler)DMA_TxIntrHandler,
  127.                                 AxiDmaPtr);
  128.         if (Status != XST_SUCCESS) {
  129.                 return Status;
  130.         }
  131. */
  132.         Status = XScuGic_Connect(IntcInstancePtr, RxIntrId,
  133.                                 (Xil_InterruptHandler)DMA_RxIntrHandler,
  134.                                 AxiDmaPtr);
  135.         if (Status != XST_SUCCESS) {
  136.                 return Status;
  137.         }

  138.         //XScuGic_Enable(IntcInstancePtr, TxIntrId);
  139.         XScuGic_Enable(IntcInstancePtr, RxIntrId);
  140.         return XST_SUCCESS;
  141. }



  142. int DMA_Intr_Enable(XScuGic * IntcInstancePtr,XAxiDma *DMAPtr)
  143. {

  144.         /* Disable all interrupts before setup */
  145. /*
  146.         XAxiDma_IntrDisable(DMAPtr, XAXIDMA_IRQ_ALL_MASK,
  147.                                                 XAXIDMA_DMA_TO_DEVICE);
  148. */
  149.         XAxiDma_IntrDisable(DMAPtr, XAXIDMA_IRQ_ALL_MASK,
  150.                                 XAXIDMA_DEVICE_TO_DMA);

  151.         /* Enable all interrupts */
  152. /*
  153.         XAxiDma_IntrEnable(DMAPtr, XAXIDMA_IRQ_ALL_MASK,
  154.                                                         XAXIDMA_DMA_TO_DEVICE);
  155. */
  156.         XAxiDma_IntrEnable(DMAPtr, XAXIDMA_IRQ_ALL_MASK,
  157.                                                         XAXIDMA_DEVICE_TO_DMA);
  158.         return XST_SUCCESS;

  159. }


  160. int DMA_Intr_Init(XAxiDma *DMAPtr,u32 DeviceId)
  161. {
  162.         int Status;
  163.         XAxiDma_Config *Config=NULL;

  164.         Config = XAxiDma_LookupConfig(DeviceId);
  165.         if (!Config) {
  166.                 xil_printf("No config found for %d\r\n", DeviceId);
  167.                 return XST_FAILURE;
  168.         }

  169.         /* Initialize DMA engine */
  170.         Status = XAxiDma_CfgInitialize(DMAPtr, Config);

  171.         if (Status != XST_SUCCESS) {
  172.                 xil_printf("Initialization failed %d\r\n", Status);
  173.                 return XST_FAILURE;
  174.         }

  175.         if(XAxiDma_HasSg(DMAPtr)){
  176.                 xil_printf("Device configured as SG mode \r\n");
  177.                 return XST_FAILURE;
  178.         }
  179.         return XST_SUCCESS;

  180. }
复制代码
回复

使用道具 举报

3

主题

1979

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
5520
金钱
5520
注册时间
2018-10-21
在线时间
1561 小时
发表于 2021-12-27 20:03:53 | 显示全部楼层
我这里有以前调试过的,摄像头经AXI DMA传到PS,经PS网口传给上位机的,可以参考下。因为时间太长,细节忘了
链接:https://pan.baidu.com/s/1XSoABwroFOCo-k4TIXRoDQ
提取码:np42
回复

使用道具 举报

1

主题

3

帖子

0

精华

新手入门

积分
7
金钱
7
注册时间
2021-12-27
在线时间
2 小时
 楼主| 发表于 2021-12-28 09:14:42 | 显示全部楼层
QinQZ 发表于 2021-12-27 20:03
我这里有以前调试过的,摄像头经AXI DMA传到PS,经PS网口传给上位机的,可以参考下。因为时间太长,细节忘 ...

十分感谢!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-10-3 22:23

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表