目录
(2).将USB配置信息UsbConfigPtr挂接到XUsbPS对象实例UsbInstance上去
(4).初始化USB设备配置信息DeviceConfig并将USB设备配置信息DeviceConfig挂接到XUsbPS对象实例UsbInstance上去
1.USB数据结构
static XUsbPs UsbInstance; /* The instance of the USB Controller */
XUsbPs_Config *UsbConfigPtr;
XUsbPs_DeviceConfig DeviceConfig;
2.USB设备启动流程和工作方式
(1)通过ID查找USB配置信息UsbConfigPtr
UsbConfigPtr = XUsbPs_LookupConfig(UsbDeviceId);
if (NULL == UsbConfigPtr) {
goto out;
}
(2)将USB配置信息UsbConfigPtr挂接到XUsbPS对象实例UsbInstance上去
Status = XUsbPs_CfgInitialize(UsbInstancePtr,
UsbConfigPtr,
UsbConfigPtr->BaseAddress);
if (XST_SUCCESS != Status) {
goto out;
}
(3)创建USB的中断函数
XusbPs_IntrHandler为XUsbPS对象中断的第1级入口,以后所有的回调函数都是通过次函数分发出去的
Status = UsbSetupIntrSystem(IntcInstancePtr,
UsbInstancePtr,
UsbIntrId);
if (XST_SUCCESS != Status)
{
goto out;
}
进入函数-->
Status = XScuGic_Connect(IntcInstancePtr, UsbIntrId,
(Xil_ExceptionHandler)XUsbPs_IntrHandler,
(void *)UsbInstancePtr);
if (Status != XST_SUCCESS) {
return Status;
}
(4)初始化USB设备配置信息DeviceConfig并将USB设备配置信息DeviceConfig挂接到XUsbPS对象实例UsbInstance上去
DeviceConfig.EpCfg[0].Out.Type = XUSBPS_EP_TYPE_CONTROL;
DeviceConfig.EpCfg[0].Out.NumBufs = 2;
DeviceConfig.EpCfg[0].Out.BufSize = 64;
DeviceConfig.EpCfg[0].Out.MaxPacketSize = 64;
DeviceConfig.EpCfg[0].In.Type = XUSBPS_EP_TYPE_CONTROL;
DeviceConfig.EpCfg[0].In.NumBufs = 2;
DeviceConfig.EpCfg[0].In.MaxPacketSize = 64;
DeviceConfig.EpCfg[1].Out.Type = XUSBPS_EP_TYPE_BULK;
DeviceConfig.EpCfg[1].Out.NumBufs = 16;
DeviceConfig.EpCfg[1].Out.BufSize = 512;
DeviceConfig.EpCfg[1].Out.MaxPacketSize = 512;
DeviceConfig.EpCfg[1].In.Type = XUSBPS_EP_TYPE_BULK;
DeviceConfig.EpCfg[1].In.NumBufs = 16;
DeviceConfig.EpCfg[1].In.MaxPacketSize = 512;
DeviceConfig.NumEndpoints = NumEndpoints;
MemPtr = (u8 *)&Buffer[0];
memset(MemPtr,0,MEMORY_SIZE);
Xil_DCacheFlushRange((unsigned int)MemPtr, MEMORY_SIZE);
/* Finish the configuration of the DeviceConfig structure and configure
* the DEVICE side of the controller.
*/
DeviceConfig.DMAMemPhys = (u32) MemPtr;
Status = XUsbPs_ConfigureDevice(UsbInstancePtr, &DeviceConfig);
if (XST_SUCCESS != Status) {
goto out;
}
(5)注册用户中断,用户可以任意设定
/* Set the handler for receiving frames. */
Status = XUsbPs_IntrSetHandler(UsbInstancePtr, UsbIntrHandler, NULL,
XUSBPS_IXR_UE_MASK);
if (XST_SUCCESS != Status) {
goto out;
}
进入函数--->
/*****************************************************************************/
/**
* This function registers the user callback handler for controller
* (non-endpoint) interrupts.
*
*
******************************************************************************/
int XUsbPs_IntrSetHandler(XUsbPs *InstancePtr,
XUsbPs_IntrHandlerFunc CallBackFunc,
void *CallBackRef, u32 Mask)
{
Xil_AssertNonvoid(InstancePtr != NULL);
InstancePtr->HandlerFunc = CallBackFunc;
InstancePtr->HandlerRef = CallBackRef;
InstancePtr->HandlerMask = Mask;
return XST_SUCCESS;
}
(6)设置端点中断入口
核心的核心:此处都为OUT是因为所有的传输事务都是由主机HOST发起的,当主机HOST发起事务后进入对应端点的中断,所以为都OUT,这里的IN、OUT都是针对主机HOST来讲的。
就是接收到主机发起的事务之后,回调的函数。如果参数为IN,则为设备发送数据完毕之后回调的函数。
/* Set the handler for handling endpoint 0 events. This is where we
* will receive and handle the Setup packet from the host.
*/
Status = XUsbPs_EpSetHandler(UsbInstancePtr, 0,
XUSBPS_EP_DIRECTION_OUT,
XUsbPs_Ep0EventHandler, UsbInstancePtr);
/* Set the handler for handling endpoint 1 events.
*
* Note that for this example we do not need to register a handler for
* TX complete events as we only send data using static data buffers
* that do not need to be free()d or returned to the OS after they have
* been sent.
*/
Status = XUsbPs_EpSetHandler(UsbInstancePtr, 1,
XUSBPS_EP_DIRECTION_OUT,
XUsbPs_Ep1EventHandler, UsbInstancePtr);
(7)启动USB
/* Start the USB engine */
XUsbPs_Start(UsbInstancePtr);
(8)启动后
启动后就开始监听主机HOST的传输事务,一但有相应的事务或者连接,就会进入XUsbPs_IntrHandler中断函数,此函数会根据中断类型去分发到相应的回调函数,其他USB设备工作方式也是大同小异。