Zynq 怎么增加USB端点传输能力
时间: 2024-03-03 16:47:27 浏览: 149
要增加Zynq的USB端点传输能力,可以按照以下步骤进行:
1. 修改设备树
在设备树中添加USB控制器节点的属性,例如增加端点数量等。设备树是系统启动时用来描述硬件结构的一种数据结构,需要修改设备树来增加USB控制器节点的属性。例如,可以增加如下设备树节点:
```
usb@e0002000 {
compatible = "xlnx,zynq-usb-2.0";
reg = <0xe0002000 0x1000>;
interrupts = <0x0 0x1c 0x4>;
interrupt-parent = <0x3>;
xlnx,num-ep-out = <4>;
xlnx,num-ep-in = <4>;
xlnx,usb-mode = <0>;
xlnx,dr_mode = <1>;
};
```
其中,xlnx,num-ep-out和xlnx,num-ep-in分别表示USB控制器的输出端点和输入端点数量。
2. 修改驱动程序
根据USB控制器节点的属性,修改USB驱动程序,增加端点的处理能力。驱动程序是系统运行时用来管理硬件的程序,需要修改驱动程序来增加端点处理能力。例如,在驱动程序中可以增加如下代码:
```
#define MAX_EP 8
struct xusb_ep {
struct usb_ep ep;
struct xusb_dev *dev;
u32 num;
u32 dir;
u32 type;
u32 maxpacket;
u32 interval;
u32 flags;
u8 *buf;
};
static struct xusb_ep xusb_eps[MAX_EP];
```
其中,xusb_eps数组用来存储USB控制器的端点信息。
3. 配置USB控制器寄存器
通过配置USB控制器寄存器,设置端点的属性,例如端点类型、缓冲区大小等。USB控制器的寄存器用来控制USB传输和处理,需要根据需要来配置寄存器。例如,在驱动程序中可以增加如下代码:
```
#define USB_EP_TYPE_BULK 2
#define USB_EP_TYPE_INT 3
#define XUSB_EP_CFG_TYPE_MASK 0x03
static void xusb_ep_configure(struct xusb_ep *ep)
{
u32 cfg = 0;
if (ep->dir == USB_DIR_IN) {
cfg |= XUSB_EP_CFG_DIR_IN;
} else {
cfg |= XUSB_EP_CFG_DIR_OUT;
}
if (ep->type == USB_EP_TYPE_BULK) {
cfg |= XUSB_EP_CFG_TYPE_BULK;
} else if (ep->type == USB_EP_TYPE_INT) {
cfg |= XUSB_EP_CFG_TYPE_INT;
} else {
cfg |= XUSB_EP_CFG_TYPE_CTRL;
}
cfg |= XUSB_EP_CFG_EN;
xusb_write32(XUSB_EP_CONFIG(ep->num), cfg);
}
```
其中,xusb_ep_configure函数用来配置USB控制器的端点寄存器,包括端点的方向、类型和使能等。
4. 增加USB传输通道
根据需要,增加USB传输通道,例如增加Bulk、Interrupt等传输通道。USB传输通道用来实现具体的数据传输功能,需要根据需要来增加传输通道。例如,在驱动程序中可以增加如下代码:
```
static struct usb_ep_ops xusb_ep_ops = {
.enable = xusb_ep_enable,
.disable = xusb_ep_disable,
.queue = xusb_ep_queue,
.dequeue = xusb_ep_dequeue,
.set_halt = xusb_ep_set_halt,
.clear_halt = xusb_ep_clear_halt,
.set_wedge = xusb_ep_set_wedge,
.clear_stall = xusb_ep_clear_stall,
};
static struct usb_endpoint_descriptor xusb_ep_bulk_out_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_OUT | 1,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
.wMaxPacketSize = cpu_to_le16(512),
.bInterval = 0,
};
static struct usb_endpoint_descriptor xusb_ep_bulk_in_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN | 2,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
.wMaxPacketSize = cpu_to_le16(512),
.bInterval = 0,
};
static struct usb_endpoint_descriptor xusb_ep_int_out_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_OUT | 3,
.bmAttributes = USB_ENDPOINT_XFER_INT,
.wMaxPacketSize = cpu_to_le16(16),
.bInterval = 10,
};
static struct usb_endpoint_descriptor xusb_ep_int_in_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN | 4,
.bmAttributes = USB_ENDPOINT_XFER_INT,
.wMaxPacketSize = cpu_to_le16(16),
.bInterval = 10,
};
static struct usb_endpoint_descriptor *xusb_ep_descs[] = {
&xusb_ep_bulk_out_desc,
&xusb_ep_bulk_in_desc,
&xusb_ep_int_out_desc,
&xusb_ep_int_in_desc,
NULL,
};
```
其中,xusb_ep_ops结构体用来定义USB控制器的端点操作函数;xusb_ep_bulk_out_desc、xusb_ep_bulk_in_desc、xusb_ep_int_out_desc和xusb_ep_int_in_desc结构体用来定义USB控制器的Bulk和Interrupt传输通道的端点描述符。
阅读全文