static int Xil_DMA_Prep_Buf_Ctl(xil_dma* const me, int device_id, uint32_t * ptr, uint32_t length, enum xdma_direction dir) { struct xdma_buf_info buf; buf.chan = (dir==XDMA_MEM_TO_DEV? me->xdma_devices[device_id].tx_chan:me->xdma_devices[device_id].rx_chan); buf.completion = (dir==XDMA_MEM_TO_DEV? me->xdma_devices[device_id].tx_cmp:me->xdma_devices[device_id].rx_cmp); buf.cookie = 0; buf.buf_offset = (u32) xdma_calc_offset(me, ptr); buf.buf_size = (u32) (length * sizeof(ptr[0])); buf.dir = dir; int ret = (int)ioctl(me->fd, XDMA_PREP_BUF, &buf); if(ret < 0) { printf("Error ioctl set %s buf", dir==XDMA_MEM_TO_DEV?"tx":"rx"); return ret; } return 0; }
/* Perform DMA transaction * * To perform a one-way transaction set the unused directions pointer to NULL * or length to zero. */ int xdma_perform_transaction(int device_id, enum xdma_wait wait, uint32_t * src_ptr, uint32_t src_length, uint32_t * dst_ptr, uint32_t dst_length) { int ret = 0; struct xdma_buf_info dst_buf; struct xdma_buf_info src_buf; struct xdma_transfer dst_trans; struct xdma_transfer src_trans; const bool src_used = ((src_ptr != NULL) && (src_length != 0)); const bool dst_used = ((dst_ptr != NULL) && (dst_length != 0)); if (device_id >= num_of_devices) { perror("Error invalid device ID"); return -1; } if (src_used) { src_buf.chan = xdma_devices[device_id].tx_chan; src_buf.completion = xdma_devices[device_id].tx_cmp; src_buf.cookie = 0; src_buf.buf_offset = (u32) xdma_calc_offset(src_ptr); src_buf.buf_size = (u32) (src_length * sizeof(src_ptr[0])); src_buf.dir = XDMA_MEM_TO_DEV; ret = (int)ioctl(fd, XDMA_PREP_BUF, &src_buf); if (ret < 0) { perror("Error ioctl set src (tx) buf"); return ret; } } if (dst_used) { dst_buf.chan = xdma_devices[device_id].rx_chan; dst_buf.completion = xdma_devices[device_id].rx_cmp; dst_buf.cookie = 0; dst_buf.buf_offset = (u32) xdma_calc_offset(dst_ptr); dst_buf.buf_size = (u32) (dst_length * sizeof(dst_ptr[0])); dst_buf.dir = XDMA_DEV_TO_MEM; ret = (int)ioctl(fd, XDMA_PREP_BUF, &dst_buf); if (ret < 0) { perror("Error ioctl set dst (rx) buf"); return ret; } } if (src_used) { src_trans.chan = xdma_devices[device_id].tx_chan; src_trans.completion = xdma_devices[device_id].tx_cmp; src_trans.cookie = src_buf.cookie; src_trans.wait = (0 != (wait & XDMA_WAIT_SRC)); ret = (int)ioctl(fd, XDMA_START_TRANSFER, &src_trans); if (ret < 0) { perror("Error ioctl start src (tx) trans"); return ret; } } if (dst_used) { dst_trans.chan = xdma_devices[device_id].rx_chan; dst_trans.completion = xdma_devices[device_id].rx_cmp; dst_trans.cookie = dst_buf.cookie; dst_trans.wait = (0 != (wait & XDMA_WAIT_DST)); ret = (int)ioctl(fd, XDMA_START_TRANSFER, &dst_trans); if (ret < 0) { perror("Error ioctl start dst (rx) trans"); return ret; } } return ret; }