📄 xsusbhostapi.c
字号:
}
/* Unfortunate side effect of simple design is only one parameter per
* endpoint, not buffer.
*/
edP->CompletionFunction = completion;
edP->CompletionParam = param;
#if 1
dumpTransferList((USB_TransferDescriptor_T*)itdP);
#endif
/* Just bump the tail pointer of the endpoint, the rest is magic.
*/
edP->IsoStartFrame = itdP->Control.s.StartFrame;
edP->TailP.ip = itdP->NextTD.p;
return UsbdNoError;
}
/*----------------------------------------------------------------------
* Start a bulk transfer, assume buffers are in non cached space
*/
extern
UINT XsUsbHostStartBulkTransfer(USB_EndpointDescriptor_T * edP,
char * bufP,
int length,
int varOK,
int errCount,
USB_DirectionTD_T dir,
USBD_CompletionCallback_T completion,
USBD_CallbackParam_T param)
{
USB_TransferDescriptor_T * firstP = edP->TailP.p;
USB_TransferDescriptor_T * lastP = edP->TailP.p;
USB_TransferDescriptor_T * tdP = edP->TailP.p;
void * lBuffer = bufP;
int lBufSize = length;
int bytes;
usbxStats.bulkStarts++;
/* Check to see if the endpoint has halted and kick it if so.
*/
#if 0
if (edP->HeadP.s.Halted) { /* Endpoint halted ?? */
edP->HeadP.s.Halted = 0;
//return UsbdHalted;
}
#endif
edP->TotalTransferBytes = 0;
edP->TotalOutstandingTD = 0;
/* Loop and build the data packets for the message body (if any). The
* packets must be larger or equal to the maximum packet size for the
* endpoint (endpoint processing will halt otherwise).
*/
while(lBufSize > 0) {
bytes = lBufSize;
if (bytes > edP->Control.s.MaximumPacketSize)
bytes = edP->Control.s.MaximumPacketSize;
tdP->Control.s.Direction_PID = dir;
tdP->Control.s.DelayInterrupt = USB_NoInterrupt;
tdP->Control.s.DataToggle = USB_DataToggle;
tdP->Control.s.ConditionCode = UsbNotAccessed;
tdP->Control.s.BufferRounding = varOK;
tdP->Control.s.EndpointId = edP->Control.s.EndpointId;
tdP->Control.s.DataTransfer = 1; /* Mark for completion processing */
tdP->Control.s.ByteCount = bytes; /* Mark for completion processing */
tdP->Control.s.ErrorCount = USB_MaxErrorCount-errCount;
tdP->CurrentBufferPointer.p = lBuffer;
tdP->BufferEnd.p = (char*)lBuffer + bytes-1;
if ((tdP->NextTD.p = newGeneralTransfer()) == NULL)
{
if (firstP->NextTD.p != NULL)
freeGeneralTransferList(firstP->NextTD.p);
usbxStats.noTransfer++;
LOGERRORX(UsbHost.loggedError, ERR_L_USB, ERR_S_XSUSB_STARTBULK, 1, ERR_T_NOTRANSFER,
usbxStats.noTransfer, UsbdNoTransfer, 0);
return UsbHost.loggedError;
}
lastP = tdP;
tdP = tdP->NextTD.p;
edP->TotalOutstandingTD++;
lBuffer = (char*)lBuffer + bytes;
lBufSize -= bytes;
}
/* Enable interrupts on the last packet for synchronization
*/
lastP->Control.s.DelayInterrupt = 0;
lastP->Control.s.LastTD = 1;
#if 1
dumpTransferList((USB_TransferDescriptor_T*)tdP);
#endif
/* Unfortunate side effect of simple design is only one parameter per
* endpoint, not buffer.
*/
edP->CompletionFunction = completion;
edP->CompletionParam = param;
/* Update the tail pointer and kick the host controller
*/
edP->TailP.p = tdP;
hcP->HcCommandStatus.rw.BulkListFilled = 1;
return UsbdNoError;
}
/*----------------------------------------------------------------------
* Start an interrupt transfer, assume buffers are in non cached space
*/
extern
UINT XsUsbHostStartIntTransfer(USB_EndpointDescriptor_T * edP,
char * bufP,
int length,
USBD_CompletionCallback_T completion,
USBD_CallbackParam_T param)
{
USB_TransferDescriptor_T * firstP = edP->TailP.p;
USB_TransferDescriptor_T * lastP = edP->TailP.p;
USB_TransferDescriptor_T * tdP = edP->TailP.p;
int bytes;
usbxStats.intStarts++;
DM_CwDbgPrintf(DM_CW_USB_HOST_0, "Start INT %x, buf %x\n",
tdP,
bufP);
/* Check to see if the endpoint has halted and kick it if so.
*/
#if 0
if (edP->HeadP.s.Halted) { /* Endpoint halted ?? */
edP->HeadP.s.Halted = 0;
//return UsbdHalted;
}
#endif
edP->TotalTransferBytes = 0;
edP->TotalOutstandingTD = 0;
/* Unfortunate side effect of simple design is only one parameter per
* endpoint, not buffer.
*/
edP->CompletionFunction = completion;
edP->CompletionParam = param;
/* Loop and build the data packets for the message body (if any). The
* packets must be larger or equal to the maximum packet size for the
* endpoint (endpoint processing will halt otherwise).
*/
while(length > 0) {
bytes = length;
if (bytes > edP->Control.s.MaximumPacketSize)
bytes = edP->Control.s.MaximumPacketSize;
tdP->Control.s.Direction_PID = edP->Control.s.Direction;
tdP->Control.s.DelayInterrupt = USB_NoInterrupt;
tdP->Control.s.DataToggle = USB_DataToggle;
tdP->Control.s.ConditionCode = UsbNotAccessed;
tdP->Control.s.BufferRounding = USBD_VarOK;
tdP->Control.s.EndpointId = edP->Control.s.EndpointId;
tdP->Control.s.DataTransfer = 1; /* Mark for completion processing */
tdP->Control.s.ByteCount = bytes; /* Mark for completion processing */
tdP->CurrentBufferPointer.p = bufP;
tdP->BufferEnd.p = bufP + bytes-1;
if ((tdP->NextTD.p = newGeneralTransfer()) == NULL)
{
if (firstP->NextTD.p != NULL)
freeGeneralTransferList(firstP->NextTD.p);
usbxStats.noTransfer++;
LOGERRORX(UsbHost.loggedError, ERR_L_USB, ERR_S_XSUSB_STARTINT, 1, ERR_T_NOTRANSFER,
usbxStats.noTransfer, UsbdNoTransfer, 0);
return UsbHost.loggedError;
}
lastP = tdP;
tdP = tdP->NextTD.p;
edP->TotalOutstandingTD++;
bufP += bytes;
length -= bytes;
}
/* Enable interrupts on the last packet for synchronization
*/
lastP->Control.s.DelayInterrupt = 0;
lastP->Control.s.LastTD = 1;
#if 1
dumpTransferList(firstP);
#endif
/* Just bump the tail pointer of the endpoint, the rest is magic.
*/
edP->TailP.p = tdP;
return UsbdNoError;
}
/*----------------------------------------------------------------------
* Clear an endpoint after a failure
*/
extern
void XsUsbHostClearEndpoint(USB_EndpointDescriptor_T * ctrlEdP,
USB_EndpointDescriptor_T * edP)
{
/* Clear all transfer descriptors queued to the endpoint
*/
clearTDs(edP);
/* Issue ClearFeature(HALT) to the client
*/
XsUsbHostDoCommand(ctrlEdP,
UsbReqTypeEndpoint,
UsbClearFeature, /* ClearFeature */
UsbFeatureHalt, /* Halt endpoint */
edP->Control.s.EndpointNumber, /* Endpoint number */
0,
NULL);
/* And reset the toggle back to DATA0
*/
edP->HeadP.s.ToggleCarry = 1;
}
/*----------------------------------------------------------------------
* Set a new port's address (portId based addressing)
*/
static
UINT setAddress(USBD_Device_T * devP, int addr)
{
USB_EndpointDescriptor_T * edP = devP->Endpoints[0];
USB_DeviceRequest_T * setuP;
int length;
int i;
UINT rc = UsbdNoError;
if ((setuP = (USB_DeviceRequest_T*)newBuffer()) == NULL)
{
DM_CwDbgPrintf(DM_CW_USB_HOST_1, "Failed to allocate setup buffer!\n");
LOGERRORX(UsbHost.loggedError, ERR_L_USB, ERR_S_XSUSB_SETADDRESS, 1, ERR_T_NOBUFFER,
usbxStats.noBuffer, UsbdNoBuffer, 0);
return UsbHost.loggedError;
}
memset((char*)setuP,0,sizeof(USB_DeviceRequest_T));
setuP->bmRequestType.s.toHost = 0;
setuP->bmRequestType.s.recipient = UsbReqTypeDevice;
setuP->bmRequestType.s.type = UsbReqTypeStandard;
setuP->bRequest = UsbSetAddress;
setuP->wValue.d = addr;
setuP->wIndex.d = 0;
setuP->wLength = 0;
rc = sendMessage(edP,
(void*)setuP,
NULL,
0,
USBD_VarOK,
UsbTDOut,
&length);
if (rc != ERR_T_NONE)
{
DM_CwDbgPrintf(DM_CW_USB_HOST_1, "SetAddress failed - %d!\n", length);
LOGERRORX(UsbHost.loggedError, ERR_L_USB, ERR_S_XSUSB_SETADDRESS, 2, ERR_T_UNEXPECTED,
rc, length, 0);
freeBuffer((void*)setuP);
return UsbHost.loggedError;
}
// Save the device address and set all endpoints to the same
devP->DeviceAddress = addr;
for (i=0; i < USBD_MAX_DEV_ED; i++)
{
if (devP->Endpoints[i])
devP->Endpoints[i]->Control.s.FunctionAddress = addr;
}
DM_CwDbgPrintf(DM_CW_USB_HOST_0, "SetAddress OK\n");
freeBuffer((void*)setuP);
return UsbdNoError;
}
/*----------------------------------------------------------------------
* Set an interface and setting
*/
static
UINT setConfiguration(USBD_Device_T * devP,
int configNum,
int interfaceNum,
int altNum)
{
USB_EndpointDescriptor_T * edP = devP->Endpoints[0];
USB_DeviceRequest_T * setuP;
int length;
UINT rc = UsbdNoError;
if ((setuP = (USB_DeviceRequest_T*)newBuffer()) == NULL)
{
DM_CwDbgPrintf(DM_CW_USB_HOST_1, "Failed to allocate buffer!\n");
LOGERRORX(UsbHost.loggedError, ERR_L_USB, ERR_S_XSUSB_SETCONFIG, 1, ERR_T_NOBUFFER,
usbxStats.noBuffer, UsbdNoBuffer, 0);
return UsbHost.loggedError;
}
memset((char*)setuP,0,sizeof(USB_DeviceRequest_T));
setuP->bmRequestType.s.toHost = 0;
setuP->bmRequestType.s.recipient = UsbReqTypeDevice;
setuP->bmRequestType.s.type = UsbReqTypeStandard;
setuP->bRequest = UsbSetConfiguration;
setuP->wValue.d = configNum;
setuP->wIndex.d = 0;
setuP->wLength = 0;
rc = sendMessage(edP,
(void*)setuP,
NULL,
0,
USBD_VarOK,
UsbTDOut,
&length);
if (rc != ERR_T_NONE)
{
DM_CwDbgPrintf(DM_CW_USB_HOST_1, "SetConfiguration failed - %d!\n", length);
LOGERRORX(UsbHost.loggedError, ERR_L_USB, ERR_S_XSUSB_SETCONFIG, 2, ERR_T_NOTRANSFER,
rc, length, 0);
freeBuffer((void*)setuP);
return UsbHost.loggedError;
}
// Save the configuration selected
devP->ConfigSelect = configNum;
if (interfaceNum || altNum)
{
// Setup the set interface packet
memset((char*)setuP,0,sizeof(USB_DeviceRequest_T));
setuP->bmRequestType.s.toHost = 0;
setuP->bmRequestType.s.recipient = UsbReqTypeInterface;
setuP->bmRequestType.s.type = UsbReqTypeStandard;
setuP->bRequest = UsbSetInterface;
setuP->wValue.d = altNum;
setuP->wIndex.d = interfaceNum;
setuP->wLength = 0;
rc = sendMessage(edP,
(void*)setuP,
NULL,
0,
USBD_VarOK,
UsbTDOut,
&length);
if (rc != ERR_T_NONE)
{
DM_CwDbgPrintf(DM_CW_USB_HOST_1, "SetInterface failed - %d!\n", length);
LOGERRORX(UsbHost.loggedError, ERR_L_USB, ERR_S_XSUSB_SETCONFIG, 3, ERR_T_NOTRANSFER,
rc, length, 0);
freeBuffer((void*)setuP);
return UsbHost.loggedError;
}
}
devP->InterfaceSelect = interfaceNum;
devP->AlternateSetting = altNum;
DM_CwDbgPrintf(DM_CW_USB_HOST_0, "SetConfiguration OK\r\n");
freeBuffer((void*)setuP);
return UsbdNoError;
}
/*----------------------------------------------------------------------
*
*/
static
UINT getDeviceDescriptor(USBD_Device_T * devP,
USB_DeviceDescriptor_T *bufP,
int len,
int * length)
{
USB_EndpointDescriptor_T * edP = devP->Endpoints[0];
USB_DeviceRequest_T * setuP;
USB_DeviceDescriptor_T * devdP;
UINT rc = UsbdNoError;
if ((setuP = (USB_DeviceRequest_T*)newBuffer()) == NULL)
{
DM_CwDbgPrintf(DM_CW_USB_HOST_1, "Failed to allocate setup buffer!\n");
LOGERRORX(UsbHost.loggedError, ERR_L_USB, ERR_S_XSUSB_GETDEVDESCR, 1, ERR_T_NOBUFFER,
usbxStats.noBuffer, UsbdNoBuffer, 0);
return UsbHost.loggedError;
}
devdP = (USB_DeviceDescriptor_T *)(setuP + 1);
memset((char*)setuP,0,sizeof(USB_DeviceRequest_T));
setuP->bmRequestType.s.toHost = 1;
setuP->bmRequestType.s.recipient = UsbReqTypeDevice;
setuP->bmRequestType.s.type = UsbReqTypeStandard;
setuP->bRequest = UsbGetDescriptor;
setuP->wValue.desc.index = 0;
setuP->wValue.desc.type = UsbDescTypeDevice;
setuP->wIndex.d = 0;
setuP->wLength = len;
// Send the request off and get the reply.
rc = sendMessage(edP,
(void*)setuP,
(void*)devdP,
setuP->wLength,
#if 1 /* Allow short packets length */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -