⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xsusbhostapi.c

📁 优龙YLP270开发板 光盘自带的BIOS和实验例程源码 强烈推荐
💻 C
📖 第 1 页 / 共 5 页
字号:
  }

  /* 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 + -