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

📄 xsusbhostapi.c

📁 优龙YLP270开发板 光盘自带的BIOS和实验例程源码 强烈推荐
💻 C
📖 第 1 页 / 共 5 页
字号:
      bufAlloc[i] = 1;
*/
    if (*(bufAllocP + i) == 0) {
      *(bufAllocP + i) = 1;

      return &bufListP[i*USBD_BUFSIZ];
    }
  }
  return NULL;
}

/*----------------------------------------------------------------------
 * Get/free general transfer descriptors, init with defaults
 */
static
void freeGeneralTransfer(USB_TransferDescriptor_T * p)
{
    if (p->Control.s.Used == 0) 
    {
        DM_CwDbgPrintf(DM_CW_USB_HOST_1, "Attempt to free non allocated transfer descriptor!\n");
        LOGERRORX(UsbHost.loggedError, ERR_L_USB, ERR_S_XSUSB_NODESCRIPTOR, 1, ERR_T_ILLPARAM,
                  0, 0, 0);  
        return;
    }
    
    DM_CwDbgPrintf(DM_CW_USB_HOST_0, "Free transfer %x\n", p);
    memset(p,0,sizeof(USB_TransferDescriptor_T));
}

/*----------------------------------------------------------------------
 *
 */
static
USB_TransferDescriptor_T * newGeneralTransfer (void)
{
  int i;
  USB_TransferDescriptor_T * this = NULL;

  for (i=0; i < USBD_MAX_TD; i++) {
    if (!tdListP[i].Control.s.Used) {
      this = (USB_TransferDescriptor_T *)&tdListP[i];
      break;
    }
  }
  if (this == NULL) {
    DM_CwDbgPrintf(DM_CW_USB_HOST_0, "No more transfer descriptors\n");
    return NULL;
  }

  DM_CwDbgPrintf(DM_CW_USB_HOST_0, "Allocate transfer %x\n", this);

  memset(this,0,sizeof(USB_TransferDescriptor_T));
  this->Control.s.Used = 1;

  return this;
}

/*----------------------------------------------------------------------
 * Get/free isochronous transfer descriptors, init with defaults
 */
static
void freeIsoTransfer(USB_IsoTransferDescriptor_T * p)
{
    if (p->Control.s.Used == 0)
    {
        DM_CwDbgPrintf(DM_CW_USB_HOST_1, "Attempt to free non allocated transfer descriptor!\n");
        LOGERRORX(UsbHost.loggedError, ERR_L_USB, ERR_S_XSUSB_NODESCRIPTOR, 2, ERR_T_ILLPARAM,
                  0, 0, 0);  
        return;
    }
    
    DM_CwDbgPrintf(DM_CW_USB_HOST_0, "Free transfer %x\n", p);
    memset(p,0,sizeof(USB_IsoTransferDescriptor_T));
}

/*----------------------------------------------------------------------
 *
 */
static
USB_IsoTransferDescriptor_T * newIsoTransfer(void)
{
  int i;
  USB_IsoTransferDescriptor_T * this = NULL;

  for (i=0; i < USBD_MAX_TD; i++) {
    if (!tdIsoListP[i].Control.s.Used) {
      this = (USB_IsoTransferDescriptor_T *)&tdIsoListP[i];
      break;
    }
  }
  if (this == NULL) {
    DM_CwDbgPrintf(DM_CW_USB_HOST_0, "No more transfer descriptors\n");
    return NULL;
  }

  DM_CwDbgPrintf(DM_CW_USB_HOST_0, "Allocate transfer %x\n", this);

  memset(this,0,sizeof(USB_IsoTransferDescriptor_T));
  this->Control.s.Used = 1;

  return this;
}

/*----------------------------------------------------------------------
 *
 */
static
void freeGeneralTransferList(USB_TransferDescriptor_T * firstP)
{
  USB_TransferDescriptor_T * nextP, * tdP;
  for(tdP=firstP->NextTD.p; tdP; tdP = nextP) {
    nextP = tdP->NextTD.p;
    freeGeneralTransfer(tdP);
  }
  firstP->NextTD.p = NULL;
}

/*----------------------------------------------------------------------
 * Get/free endpoint descriptors, init with defaults
 */
static
void freeEndpoint(USB_EndpointDescriptor_T * p)
{
    if (p->Control.s.Used == 0)
    {
        DM_CwDbgPrintf(DM_CW_USB_HOST_1, "Attempt to free non allocated endpoint descriptor!\n");
        LOGERRORX(UsbHost.loggedError, ERR_L_USB, ERR_S_XSUSB_NODESCRIPTOR, 3, ERR_T_ILLPARAM,
                  0, 0, 0);  
        return;
    }
    DM_CwDbgPrintf(DM_CW_USB_HOST_0, "Free endpoint %x\n", p);
    memset(p,0,sizeof(USB_EndpointDescriptor_T));
}

/*
*******************************************************************************
*
* FUNCTION:			newEndpoint
*
* DESCRIPTION:		This procedure configures the new endpoint. It gets the pointer
*					to the first empty slot in endpoints list, loads the endpoint
*					descriptor with a default settings,	gets the pointer to the
*					new the transfer descriptor and adds it to the TD list.
*
* INPUT PARAMETERS:	INT format - indicates the format of the Transfer Descriptor
*					linked to the Endpoint descriptor. 0 for General TD and 1 for ISO TD 
*
* RETURNS:			USB_EndpointDescriptor_T * is a pointer to the Endpoint Descriptor 
*
* GLOBAL EFFECTS:	none.
*
* ASSUMPTIONS:		none.
*
* CALLS:			newGeneralTransfer, newIsoTransfer
*
* CALLED BY:		addEndpoint
*
* PROTOTYPE:		USB_EndpointDescriptor_T * newEndpoint(int format)
*
*******************************************************************************
*/
static
USB_EndpointDescriptor_T * newEndpoint(int format)
{
  	int i;
  	USB_EndpointDescriptor_T * this = NULL;

  	for (i=0; i < USBD_MAX_ED; i++) 
  	{
    	if (!edListP[i].Control.s.Used) 
    	{
      		this = (USB_EndpointDescriptor_T *)&edListP[i];
      		break;
    	}
  	}
  	
  	if (this == NULL) 
  	{
    	DM_CwDbgPrintf(DM_CW_USB_HOST_0, "No more ED descriptors!\n");
   		return NULL;
  	}

  	DM_CwDbgPrintf(DM_CW_USB_HOST_0, "Allocate endpoint %x\n", this);

  	// Init the endpoint, caller can override these defaults.
  	memset(this,0,sizeof(USB_EndpointDescriptor_T));
  	this->Control.s.Used = 1;
  	this->Control.s.Direction = UsbEDFromTD;
  	this->Control.s.Format = format;
  	this->Control.s.MaximumPacketSize = 64; 	// Default to largest for control
  	this->Control.s.EndpointId = i;
  	// Get the pointer to the new TD
  	if (format)
    	this->HeadP.ip = newIsoTransfer();
  	else
    	this->HeadP.p = newGeneralTransfer();
  	// Add new TD to the tail of the TD list
  	this->TailP.p = this->HeadP.p;
 	this->NextED.p = NULL;

  	// Return the pointer to the Endpoint Descriptor
  	return this;
}

/*----------------------------------------------------------------------
 * Get/free device descriptors, init with defaults
 */
static
void freeDevice(USBD_Device_T * p)
{
    if (p->State == UsbdStateFree)
    {
        DM_CwDbgPrintf(DM_CW_USB_HOST_1, "Attempt to free non allocated device!\n");
        LOGERRORX(UsbHost.loggedError, ERR_L_USB, ERR_S_XSUSB_BADDEVICE, 1, ERR_T_ILLPARAM,
                  0, 0, 0);  
        return;
    }
    CheckCallback(UsbdStateFree, p);
    DM_CwDbgPrintf(DM_CW_USB_HOST_0, "Free device %x\n", p);
    memset(p,0,sizeof(USBD_Device_T));
}


/*
*******************************************************************************
*
* FUNCTION:			newDevice
*
* DESCRIPTION:		This procedure allocates the memory in the device table,
*					returns the pointer to this entry and marks this entry as used 
*
* INPUT PARAMETERS:	INT portId - Port ID number
*
* RETURNS:			USBD_Device_T * is a pinter to new entry in device table
*
* GLOBAL EFFECTS:	none.
*
* ASSUMPTIONS:		none.
*
* CALLS:			none.
*
* CALLED BY:		addDevice
*
* PROTOTYPE:		USBD_Device_T * newDevice (int portId)
*
*******************************************************************************
*/
static
USBD_Device_T * newDevice (int portId)
{
  	USBD_Device_T * this = NULL;

  	if (deviceTable[portId].State == UsbdStateFree) 
  	{
    	// Set the pointer to the new entry in the table
    	this = &deviceTable[portId];

    	DM_CwDbgPrintf(DM_CW_USB_HOST_0, "Allocate device %x\n", this);

    	memset(this,0,sizeof(USBD_Device_T));
   		// Mark this entry as used by USBD
   		this->State = UsbdStateUsed;
  	}

  	return this;
}

/*----------------------------------------------------------------------
 * Remove transfer descriptors from halted (or stopped) endpoint.
 */
static
void clearTDs(USB_EndpointDescriptor_T* edP)
{
  USB_TransferDescriptor_T * tdP, * nextP;
  int controlListEnable = hcP->HcControl.rw.ControlListEnable;
  int bulkListEnable = hcP->HcControl.rw.BulkListEnable;
  int oldSkip = edP->Control.s.sKip;

  edP->Control.s.sKip = 1;

  hcP->HcControl.rw.ControlListEnable = 0;
  hcP->HcControl.rw.BulkListEnable = 0;

  DM_WaitMs(5);
    
  for (tdP = (USB_TransferDescriptor_T*)(edP->HeadP.s.HeadP << 4);
       tdP != edP->TailP.p; tdP = nextP) {
    if ((nextP = tdP->NextTD.p) == NULL)
    {
        DM_CwDbgPrintf(DM_CW_USB_HOST_1, "NULL tail pointer\n");
        LOGERRORX(UsbHost.loggedError, ERR_L_USB, ERR_S_XSUSB_CLEARTD, 1, ERR_T_ILLPARAM,
                  0, 0, 0);  
        break;
    }
    DM_CwDbgPrintf(DM_CW_USB_HOST_0, "Remove TD %x, cc %d\n", tdP, tdP->Control.s.ConditionCode);
    freeGeneralTransfer(tdP);
  }

  /* Reset the head pointer, clear halted and leave ToggleCarry.
   */
  edP->HeadP.s.HeadP = (unsigned)edP->TailP.p >> 4;
  edP->HeadP.s.Halted = 0;

  edP->Control.s.sKip = oldSkip;
  
  hcP->HcControl.rw.ControlListEnable = controlListEnable;
  hcP->HcControl.rw.BulkListEnable = bulkListEnable;

}

/*----------------------------------------------------------------------
 * Initialize the periodic list. We use a slightly modified algorithm from
 * that described in the OHCI spec.
 */
static
void initPeriodicLists()
{
  int i, j;
  int thisBase;
  int nextBase;

  for (i=5; i > 0; i--) 
  { /* Loop thru all lists (32ms,16ms,8ms,4ms,2ms,1ms) */
    thisBase = (1 << i) - 1; /* Base index of this list set */
    nextBase = (1 << (i-1)) - 1; /* Base index of next list set */
    for (j=0; j < (1 << i); j++) 
    {   /* Loop thru all lists in this set */
        periodicTableP[j + thisBase].NextED.p =
	    (USB_EndpointDescriptor_T *)&periodicTableP[(j & nextBase) + nextBase];
         periodicTableP[j + thisBase].Control.s.sKip = 1;
    }
  }
  periodicTableP[0].Control.s.sKip = 1;

  /* Set the base pointers in the HCCA */
  for (i=0; i < USB_HCCA_MAX_INT_LIST; i++)
    hccaP->HccaInterruptTable[i].p =
      (USB_EndpointDescriptor_T *)&periodicTableP[USBD_32MS_BASE+i];
}

/*----------------------------------------------------------------------
 * Process descriptors on the done queue
 */
static
void processDoneQueue()
{
  USB_TransferDescriptor_T * tdP, * nextP;
  USB_IsoTransferDescriptor_T * itdP;
  volatile USB_EndpointDescriptor_T * edP;

  /* Enable the HC to update again.
   */
  tdP = (USB_TransferDescriptor_T*)hccaP->HccaDoneHead.p;
  hccaP->HccaDoneHead.p = NULL;
  hcP->HcInterruptStatus.rw.WritebackDoneHead = 1;

  /* Process the list of descriptors
   */
  for (/* Empty */; tdP; tdP = nextP) {
    int bytes = 0;
    if ((nextP = tdP->NextTD.p) == NULL) {
#if 0 /* Wait until next interrupt */
      nextP = (USB_TransferDescriptor_T*)hccaP->HccaDoneHead.p;
      hccaP->HccaDoneHead.p = NULL;
      hcP->HcInterruptStatus.rw.WritebackDoneHead = 1;
#endif
    }

    /* Look for control bits cleared problem
     */
    if (((unsigned)tdP & 0xffff) == 0)
    {
        DM_CwDbgPrintf(DM_CW_USB_HOST_0,"TD control bits cleared!\n");
    }

    /* Cheezy overlay use of format bit ;-) */
    if (tdP->Control.s.Format == UsbFormatGeneral)
      edP=&edListP[tdP->Control.s.EndpointId];
    else
      edP=&edListP[((USB_IsoTransferDescriptor_T*)tdP)->Control.s.EndpointId];

    DM_CwDbgPrintf(DM_CW_USB_HOST_0, "Done q, edp %x, tdp %x, *tdp %x\n", edP, tdP, tdP->Control.d);

    /* Get the endpoint reference and handle packet type */
    if (edP != NULL) {

      /* General packet decrements the outstanding counter (used to indicate
       * message complete) and updates the byte transfer counts.
       */
      if (edP->Control.s.Format == UsbFormatGeneral) {
	edP->TotalOutstandingTD--;
	if (tdP->Control.s.DataTransfer) {
	  if (tdP->CurrentBufferPointer.p) /* zero on success/full buffer */
	    bytes = ((int)tdP->Control.s.ByteCount -
		     (int)((char*)tdP->BufferEnd.p+1 -
			   (char*)tdP->CurrentBufferPointer.p));
	  else
	    bytes = (int)tdP->Control.s.ByteCount;
	  
	  edP->TotalTransferBytes += bytes;
	}

	DM_CwDbgPrintf(DM_CW_USB_HOST_0, "Done general TD %x, cc %d, size %d, bytes %d, reqs %d\n",
		   tdP,
		   tdP->Control.s.ConditionCode,
		   tdP->Control.s.ByteCount,
		   bytes,
		   edP->TotalOutstandingTD);
	DM_CwDbgPrintf(DM_CW_USB_HOST_0, "             cbp %x, be %x\n",
		   tdP->CurrentBufferPointer.p,
		   tdP->BufferEnd.p);

	/* If this is the last transfer in a message call the completion
	 * routine. If the endpoint has halted we to call also as there
	 * will be no more descriptors retired.
	 */
	if (edP->CompletionFunction) {
	  int reason = edP->HeadP.s.Halted ? USBD_CompletionHalted :
	    USBD_CompletionNormal;
	  edP->CompletionFunction(reason,
				  tdP,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -