dev_snd.c 4.01 KB
/*HEADER******************************************************************
**************************************************************************
*** 
*** Copyright (c) 2001-2002 ARC International.
*** All rights reserved                                          
***                                                              
*** This software embodies materials and concepts which are      
*** confidential to ARC International and is made
*** available solely pursuant to the terms of a written license   
*** agreement with ARC International             
***
*** $Workfile:devapi.c$
*** $Revision: 1.1 $
*** $Date: 2003/02/17 20:49:01 $
***
*** Comments:      
***   This file contains the USB device API.
***                                                               
**************************************************************************
*END*********************************************************************/
#ifdef __USB_OS_MQX__
#include "mqx.h"
#include "bsp.h"
#else
#include "devapi.h"
#include "usb.h"
#include "vusb11.h"
#endif
#include "usbprv.h"
#include "usbdprv.h"

/*FUNCTION*----------------------------------------------------------------
* 
* Function Name  : _usb_device_send_data
* Returned Value : USB_OK or error code
* Comments       :
*  The Send Data routine is non-blocking routine that causes a block of data up 
*  to 64k bytes long to be made available for transmission to the USB host. The 
*  inputs to send data are bEP a byte endpoint number in the range 0-15 
*  Send_Data returns a status byte indicating whether the transfer 
*  will be initiated. 
*
*END*--------------------------------------------------------------------*/
uint_8 _usb_device_send_data
   (
      /* [IN] handle to USB device */
      _usb_device_handle handle,
      
      /* [IN] Endpoint to send data to */
      uint_8               endpoint_number,
      
      /* [IN] Pointer to data to send */
      uchar_ptr            buff_ptr,
      
      /* [IN] Length of data to send */
      uint_32              size
   )
{ /* Body */
   XD_STRUCT_PTR              pxd;
   USB_DEV_STATE_STRUCT_PTR   usb_dev_ptr;
   
   usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;

   USB_lock();
   pxd = &usb_dev_ptr->XDSEND[endpoint_number];

   /*
   ** Check if the endpoint is disabled
   */
   if (pxd->STATUS == USB_STATUS_DISABLED) {
      USB_unlock();
      return USBERR_ENDPOINT_DISABLED;
   } /* Endif */
   
   /*
   ** Check if any transfer is in progress on this endpoint
   */
   if (pxd->STATUS == USB_STATUS_TRANSFER_IN_PROGRESS) {
      USB_unlock();
      return USBERR_TRANSFER_IN_PROGRESS;
   } /* Endif */

   if (pxd->TYPE == USB_ISOCHRONOUS_ENDPOINT) {
      /* if Isochronous */
      if (size > pxd->MAXPACKET) {
         /* 
         ** if asked for more than maxPacket
         ** limit request to maxPacket
         */
         size = pxd->MAXPACKET;
      } /* Endif */
   } /* Endif */

   /* The endpoint is enabled and no transfers are pending so queue the 
   ** transmit transfer. 
   */
   pxd->STARTADDRESS = buff_ptr;
   pxd->NEXTADDRESS  = buff_ptr;
   pxd->TODO = size;
   pxd->SOFAR = 0;
   pxd->UNACKNOWLEDGEDBYTES = size;
   pxd->DIRECTION = USB_SEND;
   
   /* return successful transfer initiation status. */
   pxd->STATUS = USB_STATUS_TRANSFER_PENDING;

#ifdef __USB_OS_MQX__
   ((USB_CALLBACK_FUNCTIONS_STRUCT_PTR)usb_dev_ptr->CALLBACK_STRUCT_PTR)->\
      DEV_SEND(handle, USB_SEND, endpoint_number);
#else
   _usb_dci_vusb11_submit_transfer(handle, USB_SEND, endpoint_number);
#endif

   /*
   ** If the endpoint is currently stalled notify the user after the
   ** transfer has been queued.  By queuing the transfer the
   ** operation to revert the stall condition may be separated from
   ** the the data transfer code.
   */
   if (pxd->STATUS == USB_STATUS_STALLED) {
      USB_unlock();
      return USBERR_ENDPOINT_STALLED;
   } /* Endif */

   USB_unlock();
   return USB_OK;
} /* EndBody */

/* EOF */