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

📄 td1120p.c

📁 Usb Host/Periphel Control TD1120 codes
💻 C
📖 第 1 页 / 共 5 页
字号:
      urb->lengthSoFar += size;

      /* Transfer finished, no more data */
      if (urb->dataPosition >= urb->length)
         {
         if (!(urb->dataPosition % ep->maxPktSize))
            {
            /* There will be no "done" interrupt because the last packet 
            is not less than maxpacketsize 
            */
            TD1120P_EpTransferDone(pc, ep->epNumber, ISOUT);
            }
         /* Enable interrupts on the controller */
         PCD_EnableControllerIntr(pc);
         return;
         }

      /* Get the received bytes from EP descriptor */
      size = TD1120P_GetReceivedByteCount(pc->ioBase, ep->epNumber);
      
      if (!size)
         {
         /* Enable interrupts on the controller */
         PCD_EnableControllerIntr(pc);
         return;
         }
      } while (size);
   /* Enable interrupts on the controller */
   PCD_EnableControllerIntr(pc);
   }

/*------------------------------------------------------------------------------
Name      : TD1120P_DoEpIn
Purpose   : Copy data to chip and update the status after In token completed.
Arguments : dc - Device controller handle
            urb - pointer to urb structure
Return    : None
Notes     : 
------------------------------------------------------------------------------*/
void TD1120P_DoEpIn(TdiPeriphController* pc, TdiPurb* urb)
   {
   volatile U32 filledSize, emptySize, temp;
   TdiPeriphEp* ep;
   U32 size;
   
   ep = urb->ep;

   /* Disable interrupts on the controller */
   PCD_DisableControllerIntr(pc);

   /* Transfer finished, no more data */
   if (urb->dataPosition >= urb->length)
      {
      if (!(urb->dataPosition % ep->maxPktSize))
         {
         /* There will be no "done" interrupt because the last packet 
         is not less than maxpacketsize 
         */
         TD1120P_EpTransferDone(pc, ep->epNumber, ISIN);
         }
      /* Enable interrupts on the controller */
      PCD_EnableControllerIntr(pc);
      return;
      }

   do
      {
      /* Read the number of bytes in the FIFO */
      filledSize = (SYS_Read1120P_Register(pc->ioBase, \
         TD1120_DEV_EP_IN_BYTE_COUNT_REG(ep->epNumber)) & \
         TD1120_DEV_IN_BYTE_COUNT_MASK); 
         
      emptySize = ep->controllerBufferSize;

      if (filledSize)
         {
         emptySize -= filledSize;
         }

      if (!emptySize)
         {
         /* Enable interrupts on the controller */
         PCD_EnableControllerIntr(pc);
         return;
         }

      size = urb->length - urb->dataPosition;
      if (size > emptySize)
         {
         temp = emptySize/ep->maxPktSize;
         if (temp)
            {
            size = (ep->maxPktSize * temp);
            }
         else
            {
            /* Enable interrupts on the controller */
            PCD_EnableControllerIntr(pc);
            return;
            }
         }

      /* Write the data to the FIFO */
      TD1120P_Write1120Buffer(pc->ioBase, \
         TD1120_DEV_EP_IN_FIFO_WRITE(ep->epNumber), ep->epNumber, 
         (urb->data + urb->dataPosition), size);
      urb->dataPosition += size;
      urb->lengthSoFar += size;
      } 
   while (urb->length - urb->dataPosition);
   
   /* Enable interrupts on the controller */
   PCD_EnableControllerIntr(pc);
   }

/*------------------------------------------------------------------------------
Name      : TD1120P_DoEpTransfer
Purpose   : service routine with Ep1-15 
Arguments : pc - peripheral controller handle
            epNumber - endpoint number
            type - In or Out direction
Return    : None
Notes     : 
------------------------------------------------------------------------------*/
void TD1120P_DoEpTransfer(TdiPeriphController *pc, U32 epNumber, U8 type)
   {
   TdiPeriphEp *ep;

   /* For other endpoints */
   ep = pc->ep[epNumber];
   if (ep == NULL)
      {
      return;
      }

   if (ep->urb == NULL)
      {
      return;
      }
  
   if (type == ISIN)
      {
      /* send */
      TD1120P_DoEpIn((TdiPeriphController *)pc, ep->urb);
      }
   else if (type == ISOUT)
      {
      /* recv */
      TD1120P_DoEpOut((TdiPeriphController *)pc, ep->urb);
      }
   }


/*------------------------------------------------------------------------------
Name      : TD1120P_GoSuspend
Purpose   : set dc suspend.
Arguments : pc - peripheral controller handle
Return    : None
Notes     : 
------------------------------------------------------------------------------*/
void TD1120P_GoSuspend(TdiPeriphController* pc)
   {
   /* Just notify for now */
   pc->isSuspended = SCC_TRUE;
   TD1120P_CallEventService(pc, USB_SERVICE_SUSPEND_EVENT, 0);
   }


/*------------------------------------------------------------------------------
Name      : TD1120P_GoResume
Purpose   : set dc back from suspend.
Arguments : pc - peripheral controller handle
Return    : None
Notes     : 
------------------------------------------------------------------------------*/
void TD1120P_GoResume(TdiPeriphController* pc)
   {
   /* Just notify for now */
   pc->isSuspended = SCC_FALSE;
   TD1120P_CallEventService(pc, USB_SERVICE_RESUME_EVENT, 0);
   }

/*------------------------------------------------------------------------------
Name      : TD1120P_Transfer
Purpose   : Get ready for a new Urb.
Arguments : pc - peripheral controller handle
            urb - pointer to urb structure
Returns   : Success
Notes     : This function will be called for any endpoint.
            Control enpoint will directly call TD1120P_DoEp0XXX by dbase, which
            is little confusing.
-----------------------------------------------------------------------------*/
SctStatus TD1120P_Transfer(TdiPeriphController* pc, TdiPurb* urb)
   {
   U16 pktCount = 0;
   TdiPeriphEp *ep;
   
   if (pc == NULL)
      {
      return SCS_ERROR_INVALID_HANDLE;
      }
   
   ep = urb->ep;
   
   if (ep == NULL)
      {
      return SCS_EP_INVALID;
      }

   if (urb->direction == USB_REQUEST_DIRECTION_IN)
      {
      if (urb->length == 0)
         {
         /* Send zero length packet */
         /* Explicitly Validate FIFO */
         SYS_Write1120P_Register(pc->ioBase, TD1120_DEV_EP_IN_VALIDATION_REG, \
            ((ep->epNumber << 4) | TD1120_DEV_EP_VALID_CODE_0_BYTE));
         }
      else
         {
         /* copy data to TD1120 data buffer */
         TD1120P_DoEpIn(pc, urb);
         }
      }
   else
      {
      if (urb->length)
         {
         pktCount = (urb->length / ep->maxPktSize);

         if (urb->length % ep->maxPktSize)
            {
            pktCount++;
            }
         }
      else
         {
         pktCount = 1;
         }

      SYS_Write1120P_Register(pc->ioBase, \
         TD1120_DEV_EP_OUT_PKT_COUNT_REG(ep->epNumber), pktCount);
      
      /* Clear OUT NAK so that we can receive packets */
      SYS_Write1120P_Register(pc->ioBase, TD1120_DEV_EP_OUT_NAK_CLEAR_REG, \
         (1 << urb->ep->epNumber));
      }
      return (SCS_SUCCESS);
   }
   
/*------------------------------------------------------------------------------
Name      : TD1120P_SetTestMode
Purpose   : Set Test Mode
Arguments : pc - peripheral controller handle
            testMode - test mode
Returns   : None
Notes     : 
-----------------------------------------------------------------------------*/
void TD1120P_SetTestMode(TdiPeriphController* pc, U32 testMode)
   {
   if (pc->testModePending)
      {
      if (pc->testModePending == 3)
         {
         /* Empty the IN endpoint so that it NAKs --- Clear the IN FIFO */
         SYS_Write1120P_Register(pc->ioBase, TD1120_DEV_EP_IN_FIFO_CLEAR_REG, 1);
         }
      else
         {
         if (pc->testModePending == 4)
            {
            pc->testModePending = 3;
            /* Initialize the control endpoint 0 */
            TD1120P_Configure_EP(pc->ioBase, 1, 0, 1, 64, 64, \
               0x100, 0x17C);  /* Control EP 0 */
            SYS_Write1120P_Register(pc->ioBase, TD1120_DEV_EP_IN_EN_SET_REG, 0x2);
            SYS_Write1120P_Register(pc->ioBase, TD1120_DEV_EP_IN_FIFO_CLEAR_REG, 0x2);
            TD1120P_Write1120Buffer(pc->ioBase, TD1120_DEV_EP_IN_FIFO_WRITE(1), 1, \
               testPacket, 53);
            SYS_Write1120P_Register(pc->ioBase, TD1120_DEV_ADDRESS_REG, 0x0);
            SYS_Write1120P_Register(pc->ioBase, TD1120_DEV_CTRL_SET_REG, \
                                  TD1120_DEV_CTRL_PSEUDO_SOF_EN);
            /* Explicitly Validate FIFO */
            }
         pc->testModePending |= TD1120_DEV_TEST_MODE_EN;
         SYS_Write1120P_Register(pc->ioBase, TD1120_DEV_TEST_MODE_REG, pc->testModePending);   
         }
      }
   else
      {
      pc->testModePending = ((testMode & 0xFF00) >> 8);
      /* Explicitly Validate FIFO */
      SYS_Write1120P_Register(pc->ioBase, TD1120_DEV_EP_IN_VALIDATION_REG, ((0 << 4) | \
         TD1120_DEV_EP_VALID_CODE_0_BYTE));
      }
   }
   
/*------------------------------------------------------------------------------
Name      : TD1120P_ResetTestMode
Purpose   : Reset Test Mode
Arguments : pc - peripheral controller handle
            testMode - test mode
Returns   : None
Notes     : 
-----------------------------------------------------------------------------*/
void TD1120P_ResetTestMode(TdiPeriphController* pc, U32 testMode)
   {
   SYS_Write1120P_Register(pc->ioBase, TD1120_DEV_TEST_MODE_REG, 0);
   }
   
/*------------------------------------------------------------------------------
Name      : TD1120P_GetSpeed
Purpose   : Get the negotiated speed of the peripheral
Arguments : pc - peripheral controller handle
            speed - speed of the bus
Returns   : None
Notes     : This should be called only after bus reset operation is completed.
-----------------------------------------------------------------------------*/
SctStatus TD1120P_GetSpeed(TdiPeriphController* pc, U32* speed)
   {
   if (pc == NULL)
      {
      PRINTF1(("\nTD1120P_GetSpeed: Invalid handle."));
      return SCS_ERROR_INVALID_HANDLE;
      }
      
   *speed = (SYS_Read1120P_Register(pc->ioBase, TD1120_DEV_CTRL_SET_REG) & \
         TD1120_DEV_CTRL_SPEED);
         
   return (SCS_SUCCESS);
   }
   
/*------------------------------------------------------------------------------
Name      : TD1120P_RegisterDescriptor
Purpose   : Register the USB descriptors
Arguments : pc - peripheral controller handle
            descrType - type of descriptor
            descriptor - pointer to descriptor
            index - descriptor index
Returns   : None
Notes     : 
-----------------------------------------------------------------------------*/
SctStatus TD1120P_RegisterDescriptor(TdiPeriphController* pc, U32 descrType, \
                                     U8* descriptor, U8 index)
   {
   
   if (pc == NULL)
      {
      PRINTF1(("\nTD1120P_RegisterDescriptor: Invalid handle."));
      return SCS_ERROR_INVALID_HANDLE;
      }
      
   switch (descrType)
      {
      case USB_DEVICE_DESCRIPTOR:
         pc->currentDeviceDescriptor = descriptor;
      break;
      case USB_CONFIG_DESCRIPTOR:
         pc->currentConfigDescriptors[index] = descriptor;
      break;
      case USB_DEVICE_QUALIFIER_DESCRIPTOR:
         pc->deviceQualifierDescriptor = descriptor;
      break;
      case USB_OTHER_SPEED_CONFIG_DESCRIPTOR:
         pc->currentOtherSpeedConfigDescriptors[index] = descriptor;
      break;
      case USB_STRING_DESCRIPTOR:
         pc->stringDescriptors[index] = descriptor;
      break;
      default:
         return (SCS_ERROR);
      break;
      }
   return (SCS_SUCCESS);
   }

/*------------------------------------------------------------------------------
Name      : TD1120P_IsVBusOn
Purpose   : Check whether Vbus is on
Arguments : pc - peripheral controller handle
Return    : SCC_TRUE if on, else SCC_FALSE

⌨️ 快捷键说明

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