📄 usbdlib.c
字号:
/* Return result */ if (pPipeHandle != NULL) *pPipeHandle = urb.pipeHandle; return s; }/***************************************************************************** usbdPipeDestroy - Destroys a USB data transfer pipe** This function destroys a pipe previous created by calling usbdPipeCreate(). * The caller must pass the <pipeHandle> originally returned by usbdPipeCreate().** If there are any outstanding transfer requests for the pipe, the USBD will * abort those transfers prior to destroying the pipe. ** RETURNS: OK, or ERROR if unable to destroy pipe.*/STATUS usbdPipeDestroy ( USBD_CLIENT_HANDLE clientHandle, /* Client handle */ USBD_PIPE_HANDLE pipeHandle /* pipe handle */ ) { URB_PIPE_DESTROY urb; /* Initalize URB */ urbInit (&urb.header, clientHandle, USBD_FNC_PIPE_DESTROY, NULL, NULL, sizeof (urb)); urb.pipeHandle = pipeHandle; /* Execute URB */ return urbExecBlock (&urb.header); }/***************************************************************************** usbdTransfer - Initiates a transfer on a USB pipe** A client uses this function to initiate an transfer on the pipe indicated * by <pipeHandle>. The transfer is described by an IRP, or I/O request * packet, which must be allocated and initialized by the caller prior to * invoking usbdTransfer().** The USB_IRP structure is defined in usb.h as:** .CS* typedef struct usb_bfr_list* {* UINT16 pid;* pUINT8 pBfr;* UINT16 bfrLen;* UINT16 actLen;* } USB_BFR_LIST;** typedef struct usb_irp* {* LINK usbdLink; // used by USBD* pVOID usbdPtr; // used by USBD* LINK hcdLink; // used by HCD* pVOID hcdPtr; // used by HCD* pVOID userPtr;* UINT16 irpLen;* int result; // returned by USBD/HCD* IRP_CALLBACK usbdCallback; // used by USBD* IRP_CALLBACK userCallback;* UINT16 dataToggle; // filled in by USBD* UINT16 flags; * UINT32 timeout; // defaults to 5 seconds if zero* UINT16 startFrame;* UINT16 transferLen;* UINT16 dataBlockSize;* UINT16 bfrCount;* USB_BFR_LIST bfrList [1];* } USB_IRP, *pUSB_IRP;* .CE** The length of the USB_IRP structure must be stored in <irpLen> and varies * depending on the number of <bfrList> elements allocated at the end of the * structure. By default, the default structure contains a single <bfrList>* element, but clients may allocate a longer structure to accommodate a larger * number of <bfrList> elements. ** <flags> define additional transfer options. The currently defined flags are:** .IP "USB_FLAG_SHORT_OK"* Treats receive (IN) data underrun as OK.* .IP "USB_FLAG_SHORT_FAIL"* Treats receive (IN) data underrun as error.* .IP "USB_FLAG_ISO_ASAP"* Start an isochronous transfer immediately.** When the USB is transferring data from a device to the host the data may * "underrun". That is, the device may transmit less data than anticipated by * the host. This may or may not indicate an error condition depending on the * design of the device. For many devices, the underrun is completely normal * and indicates the end of data stream from the device. For other devices, * the underrun indicates a transfer failure. By default, the USBD and * underlying USB HCD (Host Controller Driver) treat underrun as the end-of-data * indicator and do not declare an error. If the USB_FLAG_SHORT_FAIL flag is * set, then the USBD/HCD will instead treat underrun as an error condition.** For isochronous transfers the USB_FLAG_ISO_ASAP specifies that the * isochronous transfer should begin as soon as possible. If USB_FLAG_ISO_ASAP* is not specified, then <startFrame> must specify the starting frame number * for the transfer. The usbdCurrentFrameGet() function allows a client to* retrieve the current frame number and a value called the frame scheduling * window for the underlying USB host controller. The frame window specifies * the maximum number of frames into the future (relative to the current frame * number) which may be specified by <startFrame>. <startFrame> should be * specified only for isochronous transfers.** <dataBlockSize> may also be specified for isochronous transfers. If non-0,* the <dataBlockSize> defines the granularity of isochronous data being sent.* When the underlying Host Controller Driver (HCD) breaks up the transfer into* individual frames, it will ensure that the amount of data transferred in * each frame is a multiple of this value. ** <timeout> specifies the IRP timeout in milliseconds. If the caller passes* a value of zero, then the USBD sets a default timeout of USB_TIMEOUT_DEFAULT.* If no timeout is desired, then <timeout> should be set to USB_TIMEOUT_NONE.* Timeouts apply only to control and bulk transfers. Isochronous and* interrupt transfers do not time out.** <bfrList> is an array of buffer descriptors which describe data buffers to * be associated with this IRP. If more than the one <bfrList> element is * required then the caller must allocate the IRP by calculating the size as ** .CS* irpLen = sizeof (USB_IRP) + (sizeof (USB_BFR_DESCR) * (bfrCount - 1))* .CE** <transferLen> must be the total length of data to be transferred. In other * words, transferLen is the sum of all <bfrLen> entries in the <bfrList>.** <pid> specifies the packet type to use for the indicated buffer and is* specified as USB_PID_xxxx.** The IRP <userCallback> routine must point to a client-supplied IRP_CALLBACK* routine. The usbdTransfer() function returns as soon as the IRP has been* successfully enqueued. If there is a failure in delivering the IRP to the* HCD, then usbdTransfer() returns an error. The actual result of the IRP* should be checked after the <userCallback> routine has been invoked.** RETURNS: OK, or ERROR if unable to submit IRP for transfer.*/STATUS usbdTransfer ( USBD_CLIENT_HANDLE clientHandle, /* Client handle */ USBD_PIPE_HANDLE pipeHandle, /* Pipe handle */ pUSB_IRP pIrp /* ptr to I/O request packet */ ) { URB_TRANSFER urb; /* Initalize URB */ urbInit (&urb.header, clientHandle, USBD_FNC_TRANSFER, NULL, NULL, sizeof (urb)); urb.pipeHandle = pipeHandle; urb.pIrp = pIrp; /* Execute URB */ return urbExecBlock (&urb.header); }/***************************************************************************** usbdTransferAbort - Aborts a transfer** This function aborts an IRP which was previously submitted through* a call to usbdTransfer(). ** RETURNS: OK, or ERROR if unable to abort transfer.*/STATUS usbdTransferAbort ( USBD_CLIENT_HANDLE clientHandle, /* Client handle */ USBD_PIPE_HANDLE pipeHandle, /* Pipe handle */ pUSB_IRP pIrp /* ptr to I/O to abort */ ) { URB_TRANSFER urb; /* Initalize URB */ urbInit (&urb.header, clientHandle, USBD_FNC_TRANSFER_ABORT, NULL, NULL, sizeof (urb)); urb.pipeHandle = pipeHandle; urb.pIrp = pIrp; /* Execute URB */ return urbExecBlock (&urb.header); }/***************************************************************************** usbdSynchFrameGet - Returns a device's isochronous synch. frame** It is sometimes necessary for clients to re-synchronize with devices when * the two are exchanging data isochronously. This function allows a client* to query a reference frame number maintained by the device. Please refer * to the USB Specification for more detail.** <nodeId> specifies the node to query and <endpoint> specifies the endpoint * on that device. Upon return the device抯 frame number for the specified * endpoint is returned in <pFrameNo>.** RETURNS: OK, or ERROR if unable to retrieve synch. frame.*/STATUS usbdSynchFrameGet ( USBD_CLIENT_HANDLE clientHandle, /* Client Handle */ USBD_NODE_ID nodeId, /* Node Id of device/hub */ UINT16 endpoint, /* Endpoint to be queried */ pUINT16 pFrameNo /* Frame number returned by device */ ) { URB_SYNCH_FRAME_GET urb; STATUS s; /* Initalize URB */ urbInit (&urb.header, clientHandle, USBD_FNC_SYNCH_FRAME_GET, NULL, NULL, sizeof (urb)); urb.nodeId = nodeId; urb.endpoint = endpoint; /* Execute URB */ s = urbExecBlock (&urb.header); /* Return result */ if (pFrameNo != NULL) *pFrameNo = urb.frameNo; return s; }/***************************************************************************** usbdCurrentFrameGet - Returns the current frame number for a USB** It is sometimes necessary for clients to retrieve the current USB frame * number for a specified host controller. This function allows a client to * retrieve the current USB frame number for the host controller to which* <nodeId> is connected. Upon return, the current frame number is stored * in <pFrameNo>.** If <pFrameWindow> is not NULL, the USBD will also return the maximum frame * scheduling window for the indicated USB host controller. The frame * scheduling window is essentially the number of unique frame numbers * tracked by the USB host controller. Most USB host controllers maintain an * internal frame count which is a 10- or 11-bit number, allowing them to * track typically 1024 or 2048 unique frames. When starting an isochronous * transfer, a client may wish to specify that the transfer will begin in a * specific USB frame. For the given USB host controller, the starting frame * number can be no more than <frameWindow> frames from the current <frameNo>.** Note: The USBD is capable of simultaneously managing multiple USB host * controllers, each of which operates independently. Therefore, it is * important that the client specify the correct <nodeId> when retrieving the * current frame number. Typically, a client will be interested in the * current frame number for the host controller to which a specific device is * attached.** RETURNS: OK, or ERROR if unable to retrieve current frame number.*/STATUS usbdCurrentFrameGet ( USBD_CLIENT_HANDLE clientHandle, /* Client handle */ USBD_NODE_ID nodeId, /* Node Id of node on desired USB */ pUINT32 pFrameNo, /* bfr to receive current frame no. */ pUINT32 pFrameWindow /* bfr to receive frame window */ ) { URB_CURRENT_FRAME_GET urb; STATUS s; /* Initalize URB */ urbInit (&urb.header, clientHandle, USBD_FNC_CURRENT_FRAME_GET, NULL, NULL, sizeof (urb)); urb.nodeId = nodeId; /* Execute URB */ s = urbExecBlock (&urb.header); /* Return result */ if (pFrameNo != NULL) *pFrameNo = urb.frameNo; if (pFrameWindow != NULL) *pFrameWindow = urb.frameWindow; return s; }/***************************************************************************** usbdSofMasterTake - Takes SOF master ownership** A client which is performing isochronous transfers may need to adjust* the USB frame time by a small amount in order to synchronize correctly* with one or more devices. In order to adjust the USB frame interval,* a client must first attempt to become the "SOF Master" for bus to which* a device is attached.** <nodeId> specifies the id of a node on the bus for which the client* wishes to become the SOF master. Each USB managed by the USBD may have* a different SOF master.** RETURNS: OK, or ERROR if client cannot become SOF master*/STATUS usbdSofMasterTake ( USBD_CLIENT_HANDLE clientHandle, /* Client handle */ USBD_NODE_ID nodeId /* Node Id of node on desired USB */ ) { URB_SOF_MASTER urb; /* Initalize URB */ urbInit (&urb.header, clientHandle, USBD_FNC_SOF_MASTER_TAKE, NULL, NULL, sizeof (urb)); urb.nodeId = nodeId; /* Execute URB */ return urbExecBlock (&urb.header); }/***************************************************************************** usbdSofMasterRelease - Releases ownership of SOF master** A client which has previously become the SOF master for a given USB* may release SOF master status by calling this function. <nodeId> should* identify a node on the USB for which SOF master ownership should be * released.** RETURNS: OK, or ERROR if SOF ownership cannot be released*/STATUS usbdSofMasterRelease ( USBD_CLIENT_HANDLE clientHandle, /* Client handle */ USBD_NODE_ID nodeId /* Node Id of node on desired USB */ ) { URB_SOF_MASTER urb; /* Initalize URB */ urbInit (&urb.header, clientHandle, USBD_FNC_SOF_MASTER_RELEASE, NULL, NULL, sizeof (urb)); urb.nodeId = nodeId; /* Execute URB */ return urbExecBlock (&urb.header); }/***************************************************************************** usbdSofIntervalGet - Retrieves current SOF interval for a bus** This function retrieves the current SOF interval for the bus to which* <nodeId> is connected. The SOF interval returned in <pSofInterval> is* expressed in high speed bit times in a frame, with 12,000 being the * typical default value.** NOTE: A client does not need to be the current SOF master in order to* retrieve the SOF interval for a bus.** RETURNS: OK, or ERROR if SOF interval cannot be retrieved.*/STATUS usbdSofIntervalGet ( USBD_CLIENT_HANDLE clientHandle, /* Client handle */ USBD_NODE_ID nodeId, /* Node Id of node on desired USB */ pUINT16
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -