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

📄 td1120p.c

📁 Usb Host/Periphel Control TD1120 codes
💻 C
📖 第 1 页 / 共 5 页
字号:
      /* Disable OUT EP */
      SYS_Write1120P_Register(pc->ioBase, TD1120_DEV_EP_OUT_EN_CLEAR_REG, \
         (1 << ep->epNumber));
      }
   }


/*------------------------------------------------------------------------------
Name      : TD1120P_DestroyEp
Purpose   : De-initialize the endpoint and de-allocate the EP structure
Arguments : pc - peripheral controller handle
            ep - endpoint structure pointer
Returns   : 
Notes     :
-----------------------------------------------------------------------------*/
SctStatus TD1120P_DestroyEp(TdiPeriphController *pc, TdiPeriphEp* ep)
   {
   
   if (pc == NULL)
      {
      PRINTF1(("\nTD1120P_DestroyEp: Invalid handle."));
      return SCS_ERROR_INVALID_HANDLE;
      }
      
   if (ep == NULL)
      {
      PRINTF1(("\nTD1120P_DestroyEp: Invalid EP handle."));
      return SCS_EP_INVALID;
      }
      
   TD1120P_EpDeinitialize(pc, ep);
   pc->ep[ep->epNumber] = NULL;
   SYS_Free(ep);
   
   return (SCS_SUCCESS);
   }
   
/*------------------------------------------------------------------------------
Name      : TD1120P_EpDisable
Purpose   : Disable the endpoint
Arguments : pc - peripheral controller handle
            ep - endpoint structure pointer
Returns   : 
Notes     :
-----------------------------------------------------------------------------*/
SctStatus TD1120P_EpDisable(TdiPeriphController *pc, TdiPeriphEp* ep)
   {

   if (pc == NULL) 
      {
      PRINTF1(("\nTD1120P_EpDisable: Invalid handle."));
      return SCS_ERROR_INVALID_HANDLE;
      }
   
   if (ep == NULL)
      {
      PRINTF1(("\nTD1120P_EpDisable: Invalid EP handle."));
      return SCS_EP_INVALID;
      }
            
   if (ep->direction == USB_REQUEST_DIRECTION_IN)
      {
      /* Disable IN EP */
      SYS_Write1120P_Register(pc->ioBase, TD1120_DEV_EP_IN_EN_CLEAR_REG, \
         (1 << ep->epNumber));
      }
   else
      {
      /* Disable OUT EP */
      SYS_Write1120P_Register(pc->ioBase, TD1120_DEV_EP_OUT_EN_CLEAR_REG, \
         (1 << ep->epNumber));
      }
      
   return (SCS_SUCCESS);
   }
   
/*------------------------------------------------------------------------------
Name      : TD1120P_EpEnable
Purpose   : Enable the endpoint
Arguments : pc - peripheral controller handle
            ep - endpoint structure pointer
Returns   : 
Notes     :
-----------------------------------------------------------------------------*/
SctStatus TD1120P_EpEnable(TdiPeriphController* pc, TdiPeriphEp* ep)
   {
   if (pc == NULL)
      {
      PRINTF1(("\nTD1120P_EpEnable: Invalid handle."));
      return SCS_ERROR_INVALID_HANDLE;
      }
      
   if (ep == NULL)
      {
      PRINTF1(("\nTD1120P_EpEnable: Invalid EP handle."));
      return SCS_EP_INVALID;
      }

   if (ep->direction == USB_REQUEST_DIRECTION_IN)
      {
      /* Enable IN EP */
      SYS_Write1120P_Register(pc->ioBase, TD1120_DEV_EP_IN_EN_SET_REG, \
         (1 << ep->epNumber));
      }
   else
      {
      /* Enable OUT EP */
      SYS_Write1120P_Register(pc->ioBase, TD1120_DEV_EP_OUT_EN_SET_REG, \
         (1 << ep->epNumber));
  
      /* Set OUT NAK so that we don't receive anything before the software wants to */
      SYS_Write1120P_Register(pc->ioBase, TD1120_DEV_EP_OUT_NAK_SET_REG, \
         (1 << ep->epNumber));
      }
   return (SCS_SUCCESS);
   }
   
/*------------------------------------------------------------------------------
Name      : TD1120P_GetEpStatus
Purpose   : Get the status of the endpoint specified
Arguments : periphHandle - peripheral controller handle
            periphEp - endpoint structure pointer
Returns   : 
Notes     :
-----------------------------------------------------------------------------*/
SctStatus TD1120P_GetEpStatus(TdiPeriphController* pc, TdiPeriphEp* ep)
   {
   if (pc == NULL)
      {
      PRINTF1(("\nTD1120P_GetEpStatus: Invalid handle."));
      return SCS_ERROR_INVALID_HANDLE;
      }
      
   if (ep == NULL)
      {
      PRINTF1(("\nTD1120P_GetEpStatus: Invalid EP handle."));
      return SCS_EP_INVALID;
      }
      
   /* Nothing to do for TD1120 */
   return (SCS_SUCCESS);
   }
   
/*------------------------------------------------------------------------------
Name      : TD1120P_GetFrameNumber
Purpose   : Get the status of the endpoint specified
Arguments : pc - peripheral controller handle 
            frameNumber - frame number
Returns   : SctStatus
Notes     :
-----------------------------------------------------------------------------*/
SctStatus TD1120P_GetFrameNumber(TdiPeriphController* pc, U32* frameNumber)
   {
   
   if (pc == NULL)
      {
      PRINTF1(("\nTD1120P_GetFrameNumber: Invalid handle."));
      return SCS_ERROR_INVALID_HANDLE;
      }
      
   *frameNumber = (U32)SYS_Read1120P_Register(pc->ioBase, TD1120_DEV_FRAME_NUM_REG);
   return (SCS_SUCCESS);
   }
   
/*------------------------------------------------------------------------------
Name      : TD1120_FindBit
Purpose   : Get which bit is set
Arguments : regValue - value of the register on which to find non-zero bit
Returns   : position of the bit
Notes     :
-----------------------------------------------------------------------------*/
U8 TD1120_FindBit(U32 regValue)
   {
   U8 returnVal;
   int ii;

   for (ii = 0; ii < 16; ii++)
      {
      if ((regValue >> ii) & 0x1)
         {
         returnVal = ii;
         break;
         }
      }
   return returnVal;
   }

/*------------------------------------------------------------------------------
Name      : TD1120P_ClearPrevXfers
Purpose   : Cancel the previous transfers on the specified endpoint
Arguments : pc - peripheral controller handle
            epNumber - endpoint number
Returns   : None
Notes     : It's called in the interrupt context so there's no need to disable
            interrupt
-----------------------------------------------------------------------------*/
void TD1120P_ClearPrevXfers(TdiPeriphController* pc, U8 epNumber)
   {
   U32 readRegister;
   
   /* Presuming that the control endpoint will be only endpoint 0 and no other one */
   /* Check for any pending incomplete OUT transfers */
   readRegister = SYS_Read1120P_Register(pc->ioBase, TD1120_DEV_EP_OUT_THRSHLD_AVAIL_REG);
   if (readRegister)
      {
      if (epNumber == TD1120_FindBit(readRegister))
         {
         /* Clear the OUT threshold available interrupt */
         SYS_Write1120P_Register(pc->ioBase, TD1120_DEV_EP_OUT_THRSHLD_AVAIL_REG, 1 << epNumber);
         }
      }
   
   /* Check for any done OUT transfers */
   readRegister = SYS_Read1120P_Register(pc->ioBase, TD1120_DEV_EP_OUT_XFER_RCVD_REG);
   if (readRegister)
      {
      if (epNumber == TD1120_FindBit(readRegister))
         {
         /* Clear the xfer recved interrupt */
         SYS_Write1120P_Register(pc->ioBase, TD1120_DEV_EP_OUT_XFER_RCVD_REG, (1 << epNumber));
         }
      }
   
   /* Check for any pending IN transfers */   
   readRegister = SYS_Read1120P_Register(pc->ioBase, TD1120_DEV_EP_IN_THRSHLD_AVAIL_REG);
   if (readRegister)
      {
      if (epNumber == TD1120_FindBit(readRegister))
         {
         SYS_Write1120P_Register(pc->ioBase, TD1120_DEV_EP_IN_THRSHLD_AVAIL_REG, (1 << epNumber));
         }
      }
   
   readRegister = SYS_Read1120P_Register(pc->ioBase, TD1120_DEV_EP_IN_XFER_SENT_REG);
   if (readRegister)
      {
      if (epNumber == TD1120_FindBit(readRegister))
         {
         SYS_Write1120P_Register(pc->ioBase, TD1120_DEV_EP_IN_XFER_SENT_REG, (1 << epNumber));
         }
      }
   }
   
/*------------------------------------------------------------------------------
Name      : TD1120P_PeripheralInit
Purpose   : TD1120 initialization--physical
Arguments : pc - peripheral controller handle
Returns   : None
Notes     : 
-----------------------------------------------------------------------------*/
void TD1120P_PeripheralInit(TdiPeriphController* pc)
   {
   pc->controllerResourceAddress = 0;
   /* Reset the controller */
   SYS_Write1120P_Register(pc->ioBase, TD1120_DEV_CTRL_SET_REG, TD1120_DEV_CTRL_SOFT_RESET);
   
   /* Enable All Interrupts in FPGA */
   SYS_Write1120P_Register(pc->ioBase, TD1120_DEV_INTR_ENABLES_SET_REG, 0xffff);

   /* Enable Read DWord */
   SYS_Write1120P_Register(pc->ioBase, TD1120_DEV_CTRL_SET_REG, TD1120_DEV_CTRL_READ_DWORD_EN);

   /* Enable OUT packet count feature */
   SYS_Write1120P_Register(pc->ioBase, TD1120_DEV_CTRL_SET_REG, TD1120_DEV_CTRL_OUT_PKT_EN);
   }

/*------------------------------------------------------------------------------
Name      : TD1120P_InterruptHandler
Purpose   : ISR for the 1120 device.
Arguments : handle - unused parameter
Returns   : None.
Notes     : None.
------------------------------------------------------------------------------*/
void TD1120P_InterruptHandler(S32 handle)
   {
   TdiPeriphController* pc = localHandle;
   U32 intStatus, i;
   U32 readRegister;
   U32 readInThreshold = 0, readInSent = 0, readOutThreshold = 0, readOutRx = 0;
   U8 epNumber;
   
   SYS_Write1120P_Register(pc->ioBase, TD1120_INTR_ENABLE_CLEAR,
      TD1120_INTR_ENABLE_PERIPHERAL);

   /* Read the interrupt status register */
   intStatus = SYS_Read1120P_Register(pc->ioBase, TD1120_DEV_INTR_STATUS_REG);

   /* Clear the interrupt status register */
   SYS_Write1120P_Register(pc->ioBase, TD1120_DEV_INTR_CLEAR_REG, intStatus);
   
   /* VBus Interrupt Handler */
   if (intStatus & TD1120_DEV_INTR_VBUS_CHANGE)
      {
      readRegister = SYS_Read1120P_Register(pc->ioBase, TD1120_DEV_CTRL_SET_REG);
      if (readRegister & TD1120_DEV_CTRL_VBUS)
         {
         TD1120P_CallEventService(pc, USB_SERVICE_VBUS_CHANGE_EVENT, NULL);
         }
      else
         {
         /* Detach the device by disconnecting the resistor on D+ */
         SYS_Write1120P_Register(pc->ioBase, TD1120_DEV_CTRL_CLEAR_REG, \
                               TD1120_DEV_CTRL_CONNECT_RESISTOR);
         TD1120P_PeripheralInit((TdiPeriphController*)pc);
         }
      }
      
   /* Some Interrupts Require Additional Work To Process */
   if (intStatus & TD1120_DEV_INTR_RESET_STARTED)
      {
      SYS_Write1120P_Register(pc->ioBase, TD1120_DEV_ADDRESS_REG, 0);
      }

   if (intStatus & TD1120_DEV_INTR_RESET_FINISHED)
      {
      pc->speed = (SYS_Read1120P_Register(pc->ioBase, TD1120_DEV_CTRL_SET_REG) & \
         TD1120_DEV_CTRL_SPEED);
      TD1120P_CallEventService(pc, USB_SERVICE_BUS_RESET_EVENT, NULL);
      TD1120P_CallEventService(pc, USB_SERVICE_SPEED_DETECTION_EVENT, \
                               (void*)&pc->speed);
      }
      
   if (intStatus & TD1120_DEV_INTR_SUSPEND_DETECTED)
      {
      TD1120P_GoSuspend((TdiPeriphController*)pc);
      }

   if (intStatus & TD1120_DEV_INTR_RESUME_DETECTED)
      {
      TD1120P_GoResume((TdiPeriphController*)pc);
      }

   if (intStatus & TD1120_DEV_INTR_SOF_DETECTED)
      {
      pc->isSuspended = SCC_FALSE;
      SYS_Write1120P_Register(pc->ioBase, TD1120_DEV_INTR_ENABLES_CLEAR_REG, \
         TD1120_DEV_INTR_SOF_DETECTED);
      }

   /* SETUP Packet Received Handler */
   if (intStatus & TD1120_DEV_INTR_SETUP_TKN_RX)
      {
      /* Determine which Endpoint Received the Setup Packet */
      readRegister = SYS_Read1120P_Register(pc->ioBase, TD1120_DEV_EP_SETUP_RCVD_REG);
      epNumber = TD1120_FindBit(readRegister);
      
      /* Ensure all previous control transfers get cancelled */
      TD1120P_ClearPrevXfers((TdiPeriphController *)pc, epNumber);

      /* Process new SETUP token */
      TD1120P_CallEventService(pc, USB_SERVICE_SETUP_PACKET, (void *)&epNumber);
      }
   else
      {
      /* Read all possible IN/OUT interrupt sources */
      if (intStatus & TD1120_DEV_INTR_IN_THRSHLD_EMPTIED)
         {
         readInThreshold = SYS_Read1120P_Register(pc->ioBase, TD1120_DEV_EP_IN_THRSHLD_AVAIL_REG);
         }
         
      if (intStatus & TD1120_DEV_INTR_IN_XFER_SENT)
         {
         readInSent = SYS_Read1120P_Register(pc->ioBase, TD1120_DEV_EP_IN_XFER_SENT_REG);
         }
         
      if (intStatus & TD1120_DEV_INTR_OUT_THRSHLD_FILLED)
         {
         readOutThreshold = SYS_Read1120P_Register(pc->ioBase, TD1120_DEV_EP_OUT_THRSHLD_AVAIL_REG);
         }
         
      if (intStatus & TD1120_DEV_INTR_OUT_XFER_RX)
         {
         readOutRx = SYS_Read1120P_Register(pc->ioBase, TD1120_DEV_EP_OUT_XFER_RCVD_REG);
         }
         
      /* Check if its control endpoint and if its both IN and OUT interrrupts at the same time */      
      if (((readInThreshold | readInSent) & 0x1) && ((readOutThreshold | readOutRx) & 0x1))
         {
         /* Both OUT and IN token interrupts have been notified at the same time.
         ** Its a control endpoint so we should process the data 
         ** phase before the status phase. So find out of it is a control 

⌨️ 快捷键说明

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