Example #1
0
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_device_recv_data
*  Returned Value : USB_OK or error code
*  Comments       :
*        Receives data on a specified endpoint.
*
*END*-----------------------------------------------------------------*/
uint_8 _usb_device_recv_data
   (
      /* [IN] the USB_USB_dev_initialize state structure */
      _usb_device_handle         handle,
            
      /* [IN] the Endpoint number */
      uint_8                     ep_num,
            
      /* [IN] buffer to receive data */
      uint_8_ptr                  buff_ptr,
            
      /* [IN] length of the transfer */
      uint_32                    size
   )
{ /* Body */
   uint_8                           error = USB_OK;
   XD_STRUCT_PTR                    xd_ptr;
   USB_DEV_STATE_STRUCT_PTR         usb_dev_ptr;
   
   if (handle == NULL)
   {
      return USBERR_ERROR;
   }
   
   usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;
   
   #if PSP_HAS_DATA_CACHE
      /********************************************************
       If system has a data cache, it is assumed that buffer
       passed to this routine will be aligned on a cache line
       boundry. The following code will invalidate the
       buffer before passing it to hardware driver.   
      ********************************************************/
       USB_dcache_invalidate_mlines((pointer)buff_ptr,size);   
   #endif

         
   USB_lock();

   if (!usb_dev_ptr->XD_ENTRIES) 
   {
      USB_unlock();
      return USB_STATUS_TRANSFER_IN_PROGRESS;
   } /* Endif */

   /* Get a transfer descriptor for the specified endpoint 
   ** and direction 
   */
   USB_XD_QGET(usb_dev_ptr->XD_HEAD, usb_dev_ptr->XD_TAIL, xd_ptr);
   
   usb_dev_ptr->XD_ENTRIES--;

   /* Initialize the new transfer descriptor */      
   xd_ptr->EP_NUM = ep_num;
   xd_ptr->BDIRECTION = USB_RECV;
   xd_ptr->WTOTALLENGTH = size;
   xd_ptr->WSTARTADDRESS = buff_ptr;
   xd_ptr->WSOFAR = 0;
   
   xd_ptr->BSTATUS = USB_STATUS_TRANSFER_ACCEPTED;
   

   if (((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)\
      usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_RECV != NULL)
   {
     error = ((USB_DEV_CALLBACK_FUNCTIONS_STRUCT_PTR)\
      usb_dev_ptr->CALLBACK_STRUCT_PTR)->DEV_RECV(handle, xd_ptr);  
   }
   else
   {
      #if _DEBUG
        printf("_usb_device_recv_data: DEV_RECV is NULL\n");                      
      #endif    
      return USBERR_ERROR;
   }
       
   USB_unlock();
   
   if (error) 
   {
      return USBERR_RX_FAILED;
   } /* Endif */
   
   return error;
} /* EndBody */
Example #2
0
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_device_recv_data
*  Returned Value : USB_OK or error code
*  Comments       :
*        Receives data on a specified endpoint.
*
*END*-----------------------------------------------------------------*/
uint_8 _usb_device_recv_data
   (
      /* [IN] the USB_USB_dev_initialize state structure */
      _usb_device_handle         handle,
            
      /* [IN] the Endpoint number */
      uint_8                     ep_num,
            
      /* [IN] buffer to receive data */
      uchar_ptr                  buff_ptr,
            
      /* [IN] length of the transfer */
      uint_32                    size
   )
{ /* Body */

   #ifdef _DEVICE_DEBUG_
      DEBUG_LOG_TRACE("_usb_device_recv_data");
   #endif

   uint_8                           error = USB_OK;
   XD_STRUCT_PTR                    xd_ptr;
   USB_DEV_STATE_STRUCT_PTR         usb_dev_ptr;
   
   usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;
   
   USB_lock();

   if (!usb_dev_ptr->XD_ENTRIES) 
   {
      USB_unlock();
      #ifdef _DEVICE_DEBUG_
         DEBUG_LOG_TRACE("_usb_device_recv_data, transfer in progress");
      #endif
      return USB_STATUS_TRANSFER_IN_PROGRESS;
   } /* Endif */

   /* Get a transfer descriptor for the specified endpoint 
   ** and direction 
   */
   USB_XD_QGET(usb_dev_ptr->XD_HEAD, usb_dev_ptr->XD_TAIL, xd_ptr);
   
   usb_dev_ptr->XD_ENTRIES--;

   /* Initialize the new transfer descriptor */      
   xd_ptr->EP_NUM = ep_num;
   xd_ptr->BDIRECTION = USB_RECV;
   xd_ptr->WTOTALLENGTH = size;
   xd_ptr->WSOFAR = 0;
   xd_ptr->WSTARTADDRESS = buff_ptr;
   
   xd_ptr->BSTATUS = USB_STATUS_TRANSFER_ACCEPTED;

  error = _usb_dci_vusb20_recv_data(handle, xd_ptr);

   USB_unlock();
   
   if (error) 
   {
      #ifdef _DEVICE_DEBUG_
         DEBUG_LOG_TRACE("_usb_device_recv_data, receive failed");
      #endif
      return USBERR_RX_FAILED;
   } /* Endif */
   
   return error;

} /* EndBody */
Example #3
0
uint_8 _usb_prepare_to_send(void*   handle)
{
    XD_STRUCT_PTR               xd_ptr;
    USB_DEV_STATE_STRUCT_PTR    usb_dev_ptr;
    uint_8*                     buff_ptr;
    uint_8*			            tmp_buff;
    uint_32                     size;
    int                         num_dma, tail_dma, i;
    uint_8			            error = 0;

    usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;

    tail_dma = usbSendQueue.tail_dma;
    num_dma = usbSendQueue.num_dma;
    buff_ptr = usbSendQueue.buff_ptr[tail_dma];
    size = usbSendQueue.size[tail_dma];

    if(num_dma == 0)
	    return 0;

/*
    USB_printf("_usb_prepare_to_send: num=%d, tail=%d, sentSize=%d, size=%d, buff=%p\n", 
                num_dma, tail_dma, usbSentSize, size, buff_ptr);
*/
    for(i=0; i<global_wa_sram_parts; i++)
    {
	    if(sram_parts[dma_index] != S_FREE)
	        break;
	
	    if(usbDmaSize >= usbSendQueue.size[tail_dma])
	    {
	        /* Remove from the usbSendQueues */
	        num_dma--;
            tail_dma++;
            if(tail_dma == MAX_XDS_FOR_TR_CALLS)
                tail_dma = 0;

            usbSendQueue.tail_dma = tail_dma;
            usbSendQueue.num_dma = num_dma;
            usbDmaSize = 0;

            if(num_dma == 0)
                break;
        }

	    buff_ptr = usbSendQueue.buff_ptr[tail_dma] + usbDmaSize;
	    size = MIN(usbSramPartSize, (usbSendQueue.size[tail_dma] - usbDmaSize) ); 

	    usbDmaSize += size;

	    if(size > global_wa_threshold)
	    {
	        tmp_buff = buff_ptr;
	        buff_ptr = (uint_8*)((int)usbSramBase + (dma_index * usbSramPartSize));
	        USB_idma_copy(buff_ptr, tmp_buff, size);

	        sram_parts[dma_index] = S_BUSY;
            dma_index++;
            if(dma_index == global_wa_sram_parts)
                dma_index = 0;
	    }
        

	    /* Get a transfer descriptor */
	    USB_XD_QGET(usb_dev_ptr->XD_HEAD, usb_dev_ptr->XD_TAIL, xd_ptr);

	    usb_dev_ptr->XD_ENTRIES--;
	    USB_dcache_flush((pointer)buff_ptr, size);   

	    /* Initialize the new transfer descriptor */      
	    xd_ptr->EP_NUM = usbSendQueue.ep_num[tail_dma];
	    xd_ptr->BDIRECTION = ARC_USB_SEND;
	    xd_ptr->WTOTALLENGTH = size;
	    xd_ptr->WSOFAR = 0;
	    xd_ptr->WSTARTADDRESS = buff_ptr;   
	    xd_ptr->BSTATUS = ARC_USB_STATUS_TRANSFER_ACCEPTED;

	    error = _usb_dci_vusb20_add_dTD(handle, xd_ptr);

	    if(error)
	        break;
    }

    return error;    
}
Example #4
0
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_device_send_data
*  Returned Value : USB_OK or error code
*  Comments       :
*        Sends data on a specified endpoint.
*
*END*-----------------------------------------------------------------*/
uint_8 _usb_device_send_data
   (
      /* [IN] the USB_USB_dev_initialize state structure */
      _usb_device_handle         handle,
            
      /* [IN] the Endpoint number */
      uint_8                     ep_num,
            
      /* [IN] buffer to send */
      uint_8_ptr                 buff_ptr,
            
      /* [IN] length of the transfer */
      uint_32                    size
   )
{ /* Body */
   int 	                        lockKey;
   uint_8                       error = 0;
   XD_STRUCT_PTR                xd_ptr;
   USB_DEV_STATE_STRUCT_PTR     usb_dev_ptr;
   boolean                      toSend = TRUE;

   usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;

   ARC_DEBUG_TRACE(ARC_DEBUG_FLAG_TX,
       "send_data: handle=%p, ep=%d, pBuf=0x%x, size=%d, EP_QH=%p\n", 
       handle, ep_num, (unsigned)buff_ptr, (int)size, usb_dev_ptr->EP_QUEUE_HEAD_PTR);

   ARC_DEBUG_CODE(ARC_DEBUG_FLAG_STATS, (usb_dev_ptr->STATS.usb_send_count++));
      
   lockKey = USB_lock();

   if (!usb_dev_ptr->XD_ENTRIES) 
   {
      USB_unlock(lockKey);
      USB_printf("_usb_device_send_data, transfer in progress\n");
      return ARC_USB_STATUS_TRANSFER_IN_PROGRESS;
   } /* Endif */

#if defined(USB_UNDERRUN_WA)
    {
        int 			                head;
       	VUSB20_EP_QUEUE_HEAD_STRUCT* 	ep_queue_head_ptr;

		ep_queue_head_ptr = (VUSB20_EP_QUEUE_HEAD_STRUCT_PTR)usb_dev_ptr->EP_QUEUE_HEAD_PTR + 
                       						                  2*ep_num + ARC_USB_SEND;

        if( ((ep_queue_head_ptr->MAX_PKT_LENGTH >> 16) & 0x7FF) > global_wa_threshold) 
        {
            /* Only Endpoints with maxPktSize more than 128 bytes need special processing */
            if( (size > global_wa_threshold) || 
                (usbSendQueue.num != 0) )
            {
/*
                USB_printf("_usb_device_send_data: ep_num=%d, maxPktSize=%d, size=%d\n",
                        ep_num, (ep_queue_head_ptr->MAX_PKT_LENGTH >> 16) & 0x7FF, size);
*/
                /* Check if usbSendQueue is not Full */
                if(usbSendQueue.num == MAX_XDS_FOR_TR_CALLS)
                {
                    USB_printf("ep=%d: usbSendQueue is FULL\n", ep_num);
                    USB_unlock(lockKey);
                    return USBERR_TX_FAILED;
                }

                /* Add to usbSendQueu */
                head = usbSendQueue.head;

                usbSendQueue.num++;
		        usbSendQueue.num_dma++;
                usbSendQueue.size[head] = size;
                usbSendQueue.buff_ptr[head] = buff_ptr;
                usbSendQueue.ep_num[head] = ep_num;

                head++;
                if(head == MAX_XDS_FOR_TR_CALLS)
                    head = 0;

                usbSendQueue.head = head;

                /* Process first usbSendQueue element if possible */
                if(usbSendQueue.num == 1)
                {
		            error = _usb_prepare_to_send(handle);
		        }
		        toSend = FALSE;
            }
        }
    }
#endif /* USB_UNDERRUN_WA */

    if(toSend == TRUE)
    {
        /* Get a transfer descriptor */
        USB_XD_QGET(usb_dev_ptr->XD_HEAD, usb_dev_ptr->XD_TAIL, xd_ptr);

        usb_dev_ptr->XD_ENTRIES--;

        if(buff_ptr != NULL)
            USB_dcache_flush((pointer)buff_ptr, size);   

        /* Initialize the new transfer descriptor */      
        xd_ptr->EP_NUM = ep_num;
        xd_ptr->BDIRECTION = ARC_USB_SEND;
        xd_ptr->WTOTALLENGTH = size;
        xd_ptr->WSOFAR = 0;
        xd_ptr->WSTARTADDRESS = buff_ptr;   
        xd_ptr->BSTATUS = ARC_USB_STATUS_TRANSFER_ACCEPTED;

        error = _usb_dci_vusb20_add_dTD(handle, xd_ptr);
    }
    USB_unlock(lockKey);
   
    if (error) 
    {
        USB_printf("_usb_device_send_data, transfer failed\n");
        return USBERR_TX_FAILED;
    } /* Endif */
    return error;

} /* EndBody */
Example #5
0
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_device_recv_data
*  Returned Value : USB_OK or error code
*  Comments       :
*        Receives data on a specified endpoint.
*
*END*-----------------------------------------------------------------*/
uint_8 _usb_device_recv_data
   (
      /* [IN] the USB_USB_dev_initialize state structure */
      _usb_device_handle         handle,
            
      /* [IN] the Endpoint number */
      uint_8                     ep_num,
            
      /* [IN] buffer to receive data */
      uint_8_ptr                 buff_ptr,
            
      /* [IN] length of the transfer */
      uint_32                    size
   )
{ /* Body */
    int                              lockKey;
    uint_8                           error = USB_OK;
    XD_STRUCT_PTR                    xd_ptr;
    USB_DEV_STATE_STRUCT_PTR         usb_dev_ptr;
   
    usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;

    ARC_DEBUG_TRACE(ARC_DEBUG_FLAG_RX, "recv_data: ep=%d, buf_ptr=0x%x, size=%d\n",
                                       ep_num, (unsigned)buff_ptr, (int)size);

    ARC_DEBUG_CODE(ARC_DEBUG_FLAG_STATS, (usb_dev_ptr->STATS.usb_recv_count++));

    if(buff_ptr != NULL)
        USB_dcache_inv((pointer)buff_ptr,size);   
    
    lockKey = USB_lock();

    if (!usb_dev_ptr->XD_ENTRIES) 
    {
        USB_unlock(lockKey);
        USB_printf("_usb_device_recv_data, transfer in progress\n");
        return ARC_USB_STATUS_TRANSFER_IN_PROGRESS;
    } /* Endif */

    /* Get a transfer descriptor for the specified endpoint 
    ** and direction 
    */
    USB_XD_QGET(usb_dev_ptr->XD_HEAD, usb_dev_ptr->XD_TAIL, xd_ptr);
   
    usb_dev_ptr->XD_ENTRIES--;

    /* Initialize the new transfer descriptor */      
    xd_ptr->EP_NUM = ep_num;
    xd_ptr->BDIRECTION = ARC_USB_RECV;
    xd_ptr->WTOTALLENGTH = size;
    xd_ptr->WSOFAR = 0;
    xd_ptr->WSTARTADDRESS = buff_ptr;
   
    xd_ptr->BSTATUS = ARC_USB_STATUS_TRANSFER_ACCEPTED;

    error = _usb_dci_vusb20_add_dTD(handle, xd_ptr);

    USB_unlock(lockKey);
   
    if (error) 
    {
        USB_printf("_usb_device_recv_data, receive failed\n");
        return USBERR_RX_FAILED;
    } /* Endif */

    return error;

} /* EndBody */
Example #6
0
/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : _usb_device_recv_data
*  Returned Value : USB_OK or error code
*  Comments       :
*        Receives data on a specified endpoint.
*
*END*-----------------------------------------------------------------*/
uint8_t _usb_device_recv_data(
				   /* [IN] the USB_USB_dev_initialize state structure */
				   _usb_device_handle handle,
				   /* [IN] the Endpoint number */
				   uint8_t ep_num,
				   /* [IN] buffer to receive data */
				   uint8_t * buff_ptr,
				   /* [IN] length of the transfer */
				   uint32_t size)
{				/* Body */
	uint8_t error = USB_OK;
	XD_STRUCT_PTR xd_ptr;
	USB_DEV_STATE_STRUCT_PTR usb_dev_ptr;

	TOMBSTONE_USB_DEVICE_DEBUG(0x40210000);

#ifdef _DEVICE_DEBUG_
	DEBUG_LOG_TRACE("_usb_device_recv_data");
#endif

	usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR) handle;

#ifdef ENABLE_DCACHE
   /********************************************************
   If system has a data cache, it is assumed that buffer
   passed to this routine will be aligned on a cache line
   boundry. The following code will invalidate the
   buffer before passing it to hardware driver.
   ********************************************************/
	USB_dcache_invalidate_mlines((void *)buff_ptr, size);

#endif

	USB_device_lock();

	if (!usb_dev_ptr->XD_ENTRIES) {
		TOMBSTONE_USB_DEVICE_DEBUG(0x40210001);

		USB_device_unlock();
#ifdef _DEVICE_DEBUG_
		DEBUG_LOG_TRACE("_usb_device_recv_data, transfer in progress");
#endif
		TOMBSTONE_USB_DEVICE_DEBUG(0x40210002);
		return USB_STATUS_TRANSFER_IN_PROGRESS;
	}

	/* Endif */
	/* Get a transfer descriptor for the specified endpoint
	 ** and direction
	 */
	USB_XD_QGET(usb_dev_ptr->XD_HEAD, usb_dev_ptr->XD_TAIL, xd_ptr);

	usb_dev_ptr->XD_ENTRIES--;

	/* Initialize the new transfer descriptor */
	xd_ptr->EP_NUM = ep_num;
	xd_ptr->BDIRECTION = USB_RECV;
	xd_ptr->WTOTALLENGTH = size;
	xd_ptr->WSOFAR = 0;
	xd_ptr->WSTARTADDRESS = buff_ptr;

	xd_ptr->BSTATUS = USB_STATUS_TRANSFER_ACCEPTED;

	TOMBSTONE_USB_DEVICE_DEBUG(0x40210003);
	error = _usb_dci_vusb20_recv_data(handle, xd_ptr);
	TOMBSTONE_USB_DEVICE_DEBUG(0x40210004);

	USB_device_unlock();

	if (error) {
		TOMBSTONE_USB_DEVICE_DEBUG(0x40210005);
#ifdef _DEVICE_DEBUG_
		DEBUG_LOG_TRACE("_usb_device_recv_data, receive failed");
#endif
		return USBERR_RX_FAILED;
	}
	/* Endif */
	TOMBSTONE_USB_DEVICE_DEBUG(0x40210099);
	return error;
}				/* EndBody */