예제 #1
0
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_device_init
*  Returned Value : USB_OK or error code
*  Comments       :
*        Initializes the USB device specific data structures and calls 
*  the low-level device controller chip initialization routine.
*
*END*-----------------------------------------------------------------*/
uint_8 _usb_device_init
   (
      /* [IN] the USB device controller to initialize */
      uint_8                    devnum,

      /* [OUT] the USB_USB_dev_initialize state structure */
      _usb_device_handle _PTR_  handle,
            
      /* [IN] number of endpoints to initialize */
      uint_8                    endpoints 
   )
{ /* Body */

   USB_DEV_STATE_STRUCT_PTR         usb_dev_ptr;
   XD_STRUCT_PTR                    xd_ptr;
   uint_8                           temp, i, error;
   SCRATCH_STRUCT_PTR               temp_scratch_ptr;
   //uint_32                          total_memory;
   //uint_8_ptr                       stack_mem_ptr;
   
   #ifdef _DEVICE_DEBUG_
      DEBUG_LOG_TRACE("_usb_device_init");
   #endif
   
   #ifndef REDUCED_ERROR_CHECKING                   
      
      if (devnum > MAX_USB_DEVICES) 
      {
         #ifdef _DEVICE_DEBUG_
            DEBUG_LOG_TRACE("_usb_device_init, error invalid device number");
         #endif
         return USBERR_INVALID_DEVICE_NUM;
      } /* Endif */
   #endif
      
   /**************************************************************
   All memory allocations should be consolidated in one.
   **************************************************************/
                                       
         /* Allocate memory for the state structure */
         //usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)
         //   USB_memalloc(sizeof(USB_DEV_STATE_STRUCT));
         usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)
            malloc(sizeof(USB_DEV_STATE_STRUCT));
      
         if (usb_dev_ptr == NULL) 
         {
            #ifdef _DEVICE_DEBUG_
               DEBUG_LOG_TRACE("_usb_device_init, error NULL device handle");
            #endif
            return USBERR_ALLOC_STATE;
         } /* Endif */
   
         /* Zero out the internal USB state structure */
         USB_memzero((char *)usb_dev_ptr,sizeof(USB_DEV_STATE_STRUCT));
  
   /**************************************************************
   **************************************************************/
        
   /* Multiple devices will have different base addresses and 
   ** interrupt vectors (For future)
   */   
   //usb_dev_ptr->DEV_PTR = 0x1cb20100;
   usb_dev_ptr->DEV_PTR = (VUSB20_REG_STRUCT_PTR)otg_base + 0x100;
   usb_dev_ptr->DEV_VEC = otg_irq;
   usb_dev_ptr->USB_STATE = USB_STATE_UNKNOWN;
   
   usb_dev_ptr->MAX_ENDPOINTS = endpoints;

   #ifndef SMALL_CODE_SIZE                   
      temp = (usb_dev_ptr->MAX_ENDPOINTS * 2);
   #endif
                
      /* Allocate MAX_XDS_FOR_TR_CALLS */
      xd_ptr = (XD_STRUCT_PTR)
         malloc(sizeof(XD_STRUCT) * MAX_XDS_FOR_TR_CALLS);
         //USB_memalloc(sizeof(XD_STRUCT) * MAX_XDS_FOR_TR_CALLS);
      if (xd_ptr == NULL) 
      {
         #ifdef _DEVICE_DEBUG_
            DEBUG_LOG_TRACE("_usb_device_init, malloc error");
         #endif
         return USBERR_ALLOC_TR;
      }

      USB_memzero((char *)xd_ptr, sizeof(XD_STRUCT) * MAX_XDS_FOR_TR_CALLS);

      /* Allocate memory for internal scratch structure */   
      usb_dev_ptr->XD_SCRATCH_STRUCT_BASE = (SCRATCH_STRUCT_PTR)
         malloc(sizeof(SCRATCH_STRUCT)*MAX_XDS_FOR_TR_CALLS);
         //USB_memalloc(sizeof(SCRATCH_STRUCT)*MAX_XDS_FOR_TR_CALLS);
   
      if (usb_dev_ptr->XD_SCRATCH_STRUCT_BASE == NULL) 
      {
         #ifdef _DEVICE_DEBUG_
            DEBUG_LOG_TRACE("_usb_device_init, malloc error");
         #endif
         return USBERR_ALLOC;
      } /* Endif */
   
   usb_dev_ptr->XD_BASE = xd_ptr;
   

   temp_scratch_ptr = usb_dev_ptr->XD_SCRATCH_STRUCT_BASE;
   
   #ifndef SMALL_CODE_SIZE
      usb_dev_ptr->XD_HEAD = NULL;
      usb_dev_ptr->XD_TAIL = NULL;
      usb_dev_ptr->XD_ENTRIES = 0;
   #endif
   
   /* Enqueue all the XDs */   
   for (i=0;i<MAX_XDS_FOR_TR_CALLS;i++) {
      xd_ptr->SCRATCH_PTR = temp_scratch_ptr;
      xd_ptr->SCRATCH_PTR->FREE = _usb_device_free_XD;
      xd_ptr->SCRATCH_PTR->PRIVATE = (pointer)usb_dev_ptr;
      _usb_device_free_XD((pointer)xd_ptr);
      xd_ptr++;
      temp_scratch_ptr++;
   } /* Endfor */

      usb_dev_ptr->TEMP_XD_PTR = (XD_STRUCT_PTR)malloc(sizeof(XD_STRUCT));
      USB_memzero((char *)usb_dev_ptr->TEMP_XD_PTR, sizeof(XD_STRUCT));
      
   /* Initialize the USB controller chip */

   error = _usb_dci_vusb20_init(devnum, usb_dev_ptr);

   if (error) 
   {
      #ifdef _DEVICE_DEBUG_
         DEBUG_LOG_TRACE("_usb_device_init, init failed");
      #endif
      return USBERR_INIT_FAILED;
   } /* Endif */
   
   *handle = usb_dev_ptr;
   #ifdef _DEVICE_DEBUG_
      DEBUG_LOG_TRACE("_usb_device_init, SUCCESSFUL");
   #endif
   return USB_OK;
   
} /* EndBody */
예제 #2
0
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_dci_vusb20_cancel_transfer
*  Returned Value : USB_OK or error code
*  Comments       :
*        Cancels a transfer
*
*END*-----------------------------------------------------------------*/
uint_8 _usb_dci_vusb20_cancel_transfer
   (
      /* [IN] the USB_dev_initialize state structure */
      _usb_device_handle         handle,
     
      /* [IN] the Endpoint number */
      uint_8                     ep_num,
            
      /* [IN] direction */
      uint_8                     direction
   )
{ /* Body */
   USB_DEV_STATE_STRUCT_PTR             usb_dev_ptr;
   VUSB20_REG_STRUCT_PTR                dev_ptr;
   VUSB20_EP_TR_STRUCT_PTR              dTD_ptr, check_dTD_ptr;
   VUSB20_EP_QUEUE_HEAD_STRUCT_PTR      ep_queue_head_ptr;
   XD_STRUCT_PTR                        xd_ptr;
   uint_32                              temp, bit_pos;
   volatile unsigned long               timeout, status_timeout;
   
   usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;
   dev_ptr = (VUSB20_REG_STRUCT_PTR)usb_dev_ptr->DEV_PTR;
   
   bit_pos = (1 << (16 * direction + ep_num));
   temp = (2*ep_num + direction);
   
   ep_queue_head_ptr = (VUSB20_EP_QUEUE_HEAD_STRUCT_PTR)usb_dev_ptr->EP_QUEUE_HEAD_PTR + temp;
   
   /* Unlink the dTD */
   dTD_ptr = usb_dev_ptr->EP_DTD_HEADS[temp];
   
   if (dTD_ptr) 
   {
      ARC_DEBUG_CODE(ARC_DEBUG_FLAG_STATS, (usb_dev_ptr->STATS.usb_cancel_count++));

      check_dTD_ptr = (VUSB20_EP_TR_STRUCT_PTR)USB_DTD_PHYS_TO_VIRT(usb_dev_ptr, 
                            ((uint_32)USB_32BIT_LE(dTD_ptr->NEXT_TR_ELEM_PTR) & VUSBHS_TD_ADDR_MASK));

      if (USB_32BIT_LE(dTD_ptr->SIZE_IOC_STS) & VUSBHS_TD_STATUS_ACTIVE) 
      {
         /* Flushing will halt the pipe */
         /* Write 1 to the Flush register */
         dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTFLUSH = USB_32BIT_LE(bit_pos);

         /* Wait until flushing completed */
         timeout = 0x1000000;
         while (USB_32BIT_LE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTFLUSH) & bit_pos) 
         {
            /* ENDPTFLUSH bit should be cleared to indicate this operation is complete */
            timeout--;
            if(timeout == 0)
            {
                USB_printf("USB Cancel: - TIMEOUT for ENDPTFLUSH=0x%x, bit_pos=0x%x \n", 
                      (unsigned)USB_32BIT_LE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTFLUSH), 
                      (unsigned)bit_pos);
                break;
            }
         } /* EndWhile */
         status_timeout = 0x100000;
         while (USB_32BIT_LE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTSTATUS) & bit_pos) 
         {
            status_timeout--;
            if(status_timeout == 0)
            {
                USB_printf("USB Cancel: - TIMEOUT for ENDPTSTATUS=0x%x, bit_pos=0x%x\n", 
                      (unsigned)USB_32BIT_LE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTSTATUS), 
                      (unsigned)bit_pos);
                break;
            }

            /* Write 1 to the Flush register */
            dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTFLUSH = USB_32BIT_LE(bit_pos);
         
            /* Wait until flushing completed */
            timeout = 0x1000000;
            while (USB_32BIT_LE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTFLUSH) & bit_pos) 
            {
               /* ENDPTFLUSH bit should be cleared to indicate this operation is complete */
               timeout--;
               if(timeout == 0)
                {
                    USB_printf("USB Cancel: - TIMEOUT for ENDPTFLUSH=0x%x, ENDPTSTATUS=0x%x, bit_pos=0x%x\n", 
                            (unsigned)USB_32BIT_LE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTFLUSH), 
                            (unsigned)USB_32BIT_LE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTSTATUS),
                            (unsigned)bit_pos);
                    break;
                }
            } /* EndWhile */
         } /* EndWhile */
      } /* Endif */
      
      /* Retire the current dTD */
      dTD_ptr->SIZE_IOC_STS = 0;
      dTD_ptr->NEXT_TR_ELEM_PTR = USB_32BIT_LE(VUSBHS_TD_NEXT_TERMINATE);
      
      /* The transfer descriptor for this dTD */
      xd_ptr = (XD_STRUCT_PTR)dTD_ptr->SCRATCH_PTR->XD_FOR_THIS_DTD;
      dTD_ptr->SCRATCH_PTR->PRIVATE = (pointer)usb_dev_ptr;

      ARC_DEBUG_TRACE(ARC_DEBUG_FLAG_TRANSFER,
                      "cncl_%d: fri=0x%x, ep=%d%s, buf=%p, size=%d, xd=%p, dTD=%p %p, bit=0x%x\n",
                       usb_dev_ptr->STATS.usb_cancel_count & 0xFFFF, 
                       USB_32BIT_LE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.USB_FRINDEX), 
                       ep_num, direction ? "in" : "out", 
                       xd_ptr->WSTARTADDRESS, xd_ptr->WTOTALLENGTH, xd_ptr, 
                       dTD_ptr, check_dTD_ptr, bit_pos);
       
      /* Free the dTD */
      _usb_dci_vusb20_free_dTD((pointer)dTD_ptr);
      
      /* Update the dTD head and tail for specific endpoint/direction */
      if (!check_dTD_ptr) 
      {
         usb_dev_ptr->EP_DTD_HEADS[temp] = NULL;
         usb_dev_ptr->EP_DTD_TAILS[temp] = NULL;
         if (xd_ptr) 
         {
            xd_ptr->SCRATCH_PTR->PRIVATE = (pointer)usb_dev_ptr;
            /* Free the transfer descriptor */
            _usb_device_free_XD((pointer)xd_ptr);
         } /* Endif */
         /* No other transfers on the queue */
         ep_queue_head_ptr->NEXT_DTD_PTR = USB_32BIT_LE(VUSB_EP_QUEUE_HEAD_NEXT_TERMINATE);
         ep_queue_head_ptr->SIZE_IOC_INT_STS = 0;
      } 
      else 
      {
         usb_dev_ptr->EP_DTD_HEADS[temp] = check_dTD_ptr;
            
         if (xd_ptr) 
         {
            if ((uint_32)check_dTD_ptr->SCRATCH_PTR->XD_FOR_THIS_DTD != (uint_32)xd_ptr) 
            {
               xd_ptr->SCRATCH_PTR->PRIVATE = (pointer)usb_dev_ptr;
               /* Free the transfer descriptor */
               _usb_device_free_XD((pointer)xd_ptr);
            } /* Endif */
         } /* Endif */
         
         if (USB_32BIT_LE(check_dTD_ptr->SIZE_IOC_STS) & VUSBHS_TD_STATUS_ACTIVE) 
         {         
            /* Start CR 1015 */
            /* Prime the Endpoint */
            dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTPRIME = USB_32BIT_LE(bit_pos);

            if (!(USB_32BIT_LE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTSTATUS) & bit_pos)) 
            {
               timeout = 0x100000;
               while (USB_32BIT_LE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTPRIME) & bit_pos) 
               {
                  /* Wait for the ENDPTPRIME to go to zero */
                  timeout--;
                  if(timeout == 0)
                  {
                      USB_printf("USB Cancel: - TIMEOUT for ENDPTPRIME=0x%x, bit_pos=0x%x\n", 
                                (unsigned)USB_32BIT_LE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTPRIME), 
                                (unsigned)bit_pos);
                      break;
                  }
               } /* EndWhile */

               if (USB_32BIT_LE(dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTSTATUS) & bit_pos) 
               {
                  /* The endpoint was not not primed so no other transfers on 
                  ** the queue 
                  */
                  goto done;
               } /* Endif */
            } 
            else 
            {
               goto done;
            } /* Endif */

            /* No other transfers on the queue */
            ep_queue_head_ptr->NEXT_DTD_PTR = (uint_32)USB_32BIT_LE((uint_32)check_dTD_ptr);
            ep_queue_head_ptr->SIZE_IOC_INT_STS = 0;
   
            /* Prime the Endpoint */
            dev_ptr->REGISTERS.OPERATIONAL_DEVICE_REGISTERS.ENDPTPRIME = USB_32BIT_LE(bit_pos);
         } /* Endif */
      } /* Endif */
   } /* Endif */
   
done:

   /* End CR 1015 */  
   return USB_OK;
} /* EndBody */
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_device_init
*  Returned Value : USB_OK or error code
*  Comments       :
*        Initializes the USB device specific data structures and calls 
*  the low-level device controller chip initialization routine.
*
*END*-----------------------------------------------------------------*/
uint_8 _usb_device_init
   (
      /* [IN] the USB device controller to initialize */
      uint_8                    devnum,

      /* [OUT] the USB_USB_dev_initialize state structure */
      _usb_device_handle*       handle
   )
{ /* Body */
   USB_DEV_STATE_STRUCT_PTR         usb_dev_ptr;
   XD_STRUCT_PTR                    xd_ptr;
   uint_8                           i, error;
   SCRATCH_STRUCT_PTR               temp_scratch_ptr;

   /* global_import_funcs must be initailized before */
   if(global_import_funcs == NULL)
       return USBERR_INIT_FAILED;

   if (devnum > MAX_USB_DEVICES) 
   {
        USB_printf("_usb_device_init, error invalid device number");
        return USBERR_INVALID_DEVICE_NUM;
   } /* Endif */
   
   /* Allocate memory for the state structure */
   usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)USB_memalloc(sizeof(USB_DEV_STATE_STRUCT));      
   if (usb_dev_ptr == NULL) 
   {
        USB_printf("_usb_device_init, malloc of %d bytes for USB_DEV_STATE_STRUCT failed\n", 
                    sizeof(USB_DEV_STATE_STRUCT));
        return USBERR_ALLOC_STATE;
   } /* Endif */
   
   /* Zero out the internal USB state structure */
   USB_memzero(usb_dev_ptr, sizeof(USB_DEV_STATE_STRUCT));
    
   usb_dev_ptr->DEV_NUM = devnum;

   /* Multiple devices will have different base addresses and 
   ** interrupt vectors (For future)
   */   
   usb_dev_ptr->USB_STATE = ARC_USB_STATE_UNKNOWN;
   
   /* Allocate MAX_XDS_FOR_TR_CALLS */
   xd_ptr = (XD_STRUCT_PTR)USB_memalloc(sizeof(XD_STRUCT) * MAX_XDS_FOR_TR_CALLS);      
   if (xd_ptr == NULL) 
   {
        _usb_device_cleanup(usb_dev_ptr);
        USB_printf("_usb_device_init, malloc of %d bytes for %d XD_STRUCT failed\n", 
                        sizeof(XD_STRUCT) * MAX_XDS_FOR_TR_CALLS, MAX_XDS_FOR_TR_CALLS);
        return USBERR_ALLOC_TR;
   } /* Endif */
   
   usb_dev_ptr->XD_BASE = xd_ptr;

   _usb_clear_stats(usb_dev_ptr);

   USB_memzero(xd_ptr, sizeof(XD_STRUCT) * MAX_XDS_FOR_TR_CALLS);

   /* Allocate memory for internal scratch structure */   
   usb_dev_ptr->XD_SCRATCH_STRUCT_BASE = (SCRATCH_STRUCT_PTR)
                    USB_memalloc(sizeof(SCRATCH_STRUCT) * MAX_XDS_FOR_TR_CALLS);
   if (usb_dev_ptr->XD_SCRATCH_STRUCT_BASE == NULL) 
   {
        _usb_device_cleanup(usb_dev_ptr);
        USB_printf("_usb_device_init, malloc of %d bytes for %d XD_STRUCT failed\n", 
                        sizeof(SCRATCH_STRUCT) * MAX_XDS_FOR_TR_CALLS, MAX_XDS_FOR_TR_CALLS);
        return USBERR_ALLOC;
   } /* Endif */

   temp_scratch_ptr = usb_dev_ptr->XD_SCRATCH_STRUCT_BASE;
   usb_dev_ptr->XD_HEAD = NULL;
   usb_dev_ptr->XD_TAIL = NULL;
   usb_dev_ptr->XD_ENTRIES = 0;

   /* Enqueue all the XDs */   
   for (i=0;i<MAX_XDS_FOR_TR_CALLS;i++) 
   {
      xd_ptr->SCRATCH_PTR = temp_scratch_ptr;
      xd_ptr->SCRATCH_PTR->FREE = _usb_device_free_XD;
      xd_ptr->SCRATCH_PTR->PRIVATE = (pointer)usb_dev_ptr;
      _usb_device_free_XD((pointer)xd_ptr);
      xd_ptr++;
      temp_scratch_ptr++;
   } /* Endfor */

   usb_dev_ptr->TEMP_XD_PTR = (XD_STRUCT_PTR)USB_memalloc(sizeof(XD_STRUCT));
   if(usb_dev_ptr->TEMP_XD_PTR == NULL)
   {
        USB_printf("_usb_device_init, malloc of %d bytes for TEMP_XD_STRUCT failed\n", 
                        sizeof(XD_STRUCT));
        _usb_device_cleanup(usb_dev_ptr);
        return USBERR_ALLOC;
   }
   USB_memzero(usb_dev_ptr->TEMP_XD_PTR, sizeof(XD_STRUCT));

   /* Allocate 2 bytes for USB_STATUS to be sent over USB, so Cache line aligned */
   usb_dev_ptr->STATUS_UNAIGNED_PTR = (uint_8*)USB_memalloc(sizeof(uint_16) + PSP_CACHE_LINE_SIZE);
   if(usb_dev_ptr->STATUS_UNAIGNED_PTR == NULL)
   {
        USB_printf("_usb_device_init, malloc of %d bytes for USB_STATUS failed\n", 
                        sizeof(uint_16) + PSP_CACHE_LINE_SIZE);
        _usb_device_cleanup(usb_dev_ptr);
        return USBERR_ALLOC;
   }
   USB_memzero(usb_dev_ptr->STATUS_UNAIGNED_PTR, sizeof(uint_16) + PSP_CACHE_LINE_SIZE);
   usb_dev_ptr->STATUS_PTR = (uint_16*)USB_CACHE_ALIGN((uint_32)usb_dev_ptr->STATUS_UNAIGNED_PTR);

   /* Allocate 53 bytes for USB Test packet to be sent over USB, so Cache line aligned */
   usb_dev_ptr->TEST_PKT_UNAIGNED_PTR = (uint_8*)USB_memalloc(USB_TEST_MODE_TEST_PACKET_LENGTH + PSP_CACHE_LINE_SIZE);
   if(usb_dev_ptr->TEST_PKT_UNAIGNED_PTR == NULL)
   {
        USB_printf("_usb_device_init, malloc of %d bytes for USB Test packet failed\n", 
                        USB_TEST_MODE_TEST_PACKET_LENGTH + PSP_CACHE_LINE_SIZE);
        _usb_device_cleanup(usb_dev_ptr);
        return USBERR_ALLOC;
   }
   USB_memzero(usb_dev_ptr->TEST_PKT_UNAIGNED_PTR, USB_TEST_MODE_TEST_PACKET_LENGTH + PSP_CACHE_LINE_SIZE);
   usb_dev_ptr->TEST_PKT_PTR = (uint_8*)USB_CACHE_ALIGN((uint_32)usb_dev_ptr->TEST_PKT_UNAIGNED_PTR);

   /* Initialize the USB controller chip */
   error = _usb_dci_vusb20_init(devnum, usb_dev_ptr);
   if (error) 
   {
        _usb_device_cleanup(usb_dev_ptr);
        USB_printf("_usb_device_init, init failed");
        return USBERR_INIT_FAILED;
   } /* Endif */

   USB_printf("device_init: pDev=0x%x, pXD(%d)=0x%x, pSCRATCH(%d)=0x%x, pTempXD=0x%x\n",
                (unsigned)usb_dev_ptr, MAX_XDS_FOR_TR_CALLS, (unsigned)usb_dev_ptr->XD_BASE,
                MAX_XDS_FOR_TR_CALLS, (unsigned)usb_dev_ptr->XD_SCRATCH_STRUCT_BASE,
                (unsigned)usb_dev_ptr->TEMP_XD_PTR);

   *handle = usb_dev_ptr;
   return USB_OK;   
} /* EndBody */