Пример #1
0
/*
** ===================================================================
**     Method      :  usb_mems_USB_Class_Mems_Send_Data (component USB_MEMS_CLASS)
**     Description :
**         This fucntion is used by Application to send data through
**         Mems class
**     Parameters  :
**         NAME            - DESCRIPTION
**         controller_ID   - 
**         ep_num          - 
**         app_buff        - 
**         size            - 
**     Returns     :
**         ---             - Error code
** ===================================================================
*/
uint_8 USB_Class_Mems_Send_Data(
uint_8 controller_ID,
uint_8 ep_num,
uint_8_ptr app_buff,
USB_PACKET_SIZE size
)
{
    uint_8 status = USB_OK;
    PTR_USB_CLASS_MEMS_QUEUE queue_tmp;
    uint_8 index;
    uint_8 producer, queue_num;

    USB_ENDPOINTS *usb_ep_data = (USB_ENDPOINTS *)
    USB_Desc_Get_Endpoints(controller_ID);

    /* map the endpoint num to the index of the endpoint structure */

    for(index = 0; index < usb_ep_data->count; index++)
    {
        if(usb_ep_data->ep[index].ep_num == ep_num)
        break;
    }

    producer = g_mems_endpoint_data.ep[index].bin_producer;
    queue_num = g_mems_endpoint_data.ep[index].queue_num;

    //if queue_num==1,there is already a queue,USB is busy
    //if queue_num!=1,there USB queue is empty
    if(MAX_QUEUE_ELEMS != queue_num) 
    {
        /* the bin is not full*/
        /* put all send request parameters in the endpoint data structure */
        queue_tmp = &(g_mems_endpoint_data.ep[index].queue[producer]);
        queue_tmp->controller_ID  = controller_ID;
        queue_tmp->channel        = ep_num;
        queue_tmp->app_buff       = app_buff;
        queue_tmp->size           = size;

        /* increment producer bin by 1*/
        if (producer == (MAX_QUEUE_ELEMS - 1))
        {
            g_mems_endpoint_data.ep[index].bin_producer = 0;
        }
        else
        {
            g_mems_endpoint_data.ep[index].bin_producer++;
        }
        g_mems_endpoint_data.ep[index].queue_num++;

        if(g_mems_endpoint_data.ep[index].queue_num == 1)
        {
            status = USB_Class_Send_Data(controller_ID, ep_num, app_buff,size);
        }
    }
    else /* bin is full */
    {
        status = USBERR_DEVICE_BUSY;
    }
    return status;
}
Пример #2
0
/**************************************************************************//*!
 *
 * @name  USB_Service_Video_Isochronous
 *
 * @brief The funtion ic callback function of Video Isochronous IN endpoint 
 *
 * @param event
 *
 * @return None       
 *
 ****************************************************************************
 * The function is called in response to Isochronous IN Service  
 ******************************************************************************/
void USB_Service_Video_Isochronous(PTR_USB_DEV_EVENT_STRUCT event)
{

#if IMPLEMENT_QUEUING
	uint_8 index;
	uint_8 producer, consumer;
	/*Body*/

	USB_ENDPOINTS *usb_ep_data = (USB_ENDPOINTS *)
        		USB_Desc_Get_Endpoints(event->controller_ID);

	/* map the endpoint num to the index of the endpoint structure */
	for(index = 0; index < usb_ep_data->count; index++) 
	{
		if(usb_ep_data->ep[index].ep_num ==event->ep_num)
			break;
	}/*EndFor*/

	producer = g_video_endpoint_data.ep[index].bin_producer;	  
	/* if there are no errors de-queue the queue and decrement the no. of
       transfers left, else send the same data again */
	if(event->errors == 0)
	{
		/* de-queue if the send is complete without an error */
		if ((MAX_QUEUE_ELEMS-1) == g_video_endpoint_data.ep[index].bin_consumer)
		{
			g_video_endpoint_data.ep[index].bin_consumer = 0;
		} else {
			g_video_endpoint_data.ep[index].bin_consumer++;
		}/*EndIf*/
		g_video_endpoint_data.ep[index].queue_num--;
	}/*EndIf*/

	consumer = g_video_endpoint_data.ep[index].bin_consumer;

	if(0 != g_video_endpoint_data.ep[index].queue_num)
	{
		/*if bin is not empty */
		USB_CLASS_VIDEO_QUEUE queue;
		/* send the next packet in queue */
		queue = g_video_endpoint_data.ep[index].queue[consumer];

		(void)USB_Class_Send_Data(queue.controller_ID, queue.channel,
				queue.app_buff, queue.size);
	}/*EndIf*/
#endif    

	if(g_video_class_callback != NULL)
	{
		uint_8 event_type = USB_APP_SEND_COMPLETE;

		if(event->errors != 0)
		{
			event_type = USB_APP_ERROR;
		}/*EndIf*/
		g_video_class_callback(event->controller_ID, event_type,
				(uint_8*)(&(event->errors)));
	}/*EndIf*/
}/*EndBody*/
Пример #3
0
/**************************************************************************//*!
 *
 * @name  USB_Class_CDC_Service_Dic_Bulk_In
 *
 * @brief The funtion is callback function of DIC Bulk In Endpoint
 *
 * @param event : Pointer to USB Event Structure
 *
 * @return None
 *
 ******************************************************************************
 * Called by Lower Layer when Data on DIC SEND Interface is sent
 *****************************************************************************/
static void USB_Class_CDC_Service_Dic_Bulk_In (
    PTR_USB_DEV_EVENT_STRUCT event /* [IN] Pointer to USB Event Structure */
)
{
    APP_DATA_STRUCT bulk_in_recv;

#if IMPLEMENT_QUEUING
    uint_8 index;
    uint_8 producer, consumer;
    USB_ENDPOINTS *usb_ep_data = (USB_ENDPOINTS *)
        USB_Desc_Get_Endpoints(event->controller_ID);

    USB_CLASS_CDC_QUEUE queue;

    bulk_in_recv.data_ptr = event->buffer_ptr;
    bulk_in_recv.data_size = event->len;

    /* map the endpoint num to the index of the endpoint structure */
    for(index = 0; index < usb_ep_data->count; index++)
    {
        if(usb_ep_data->ep[index].ep_num == event->ep_num)
        break;
    }

    producer = g_cdc_ep[index].bin_producer;

    /* if there are no errors de-queue the queue and decrement the no. of
       transfers left, else send the same data again */
    if(event->errors == 0)
    {
        g_cdc_ep[index].bin_consumer++;
    }

    consumer = g_cdc_ep[index].bin_consumer;

    if(consumer != producer)
    {/*if bin is not empty */

        queue = g_cdc_ep[index].queue[consumer%MAX_QUEUE_ELEMS];

        (void)USB_Class_Send_Data(queue.controller_ID, queue.channel,
            queue.app_data.data_ptr, queue.app_data.data_size);
    }
#endif
    if(g_cdc_class_callback != NULL)
    {
        if(event->errors != 0)
        {
            g_cdc_class_callback(event->controller_ID, USB_APP_ERROR,
                (uint_8*)(&(event->errors)));
        }
        else
        {
            g_cdc_class_callback(event->controller_ID, USB_APP_SEND_COMPLETE,
                (void*)&bulk_in_recv);
        }
    }
}
Пример #4
0
/**************************************************************************//*!
 *
 * @name  USB_Class_CDC_Send_Data
 *
 * @brief 
 *
 * @param handle          :   handle returned by USB_Class_CDC_Init
 * @param ep_num          :   endpoint num 
 * @param app_buff        :   buffer to send
 * @param size            :   length of the transfer   
 *
 * @return status       
 *         USB_OK         : When Successfull 
 *         Others         : Errors
 *****************************************************************************/
uint_8 USB_Class_CDC_Send_Data
(
    CDC_HANDLE handle,
    uint_8 ep_num,
    uint_8_ptr app_buff,
    uint_32 size
) 
{
    #if IMPLEMENT_QUEUING
        uint_8 index;
        uint_8 producer, consumer; 
        USB_ENDPOINTS *usb_ep_data; 
    #endif    
        
    CDC_DEVICE_STRUCT_PTR cdc_obj_ptr;
    uint_8 status = USB_OK;

    cdc_obj_ptr = USB_Cdc_Get_Device_Ptr(handle);
    if (NULL == cdc_obj_ptr)
      return USBERR_ERROR;
    
    #if IMPLEMENT_QUEUING
        usb_ep_data = cdc_obj_ptr->usb_ep_data;
      
        /* map the endpoint num to the index of the endpoint structure */
        index = USB_Map_Ep_To_Struct_Index(cdc_obj_ptr, ep_num); 
                
        producer = cdc_obj_ptr->ep[index].bin_producer;
        consumer = cdc_obj_ptr->ep[index].bin_consumer;
                                
        if(((uint_8)(producer - consumer)) != (uint_8)(CDC_MAX_QUEUE_ELEMS))  
        {   /* the bin is not full*/        
            uint_8 queue_num = (uint_8)(producer % CDC_MAX_QUEUE_ELEMS);
            
            /* put all send request parameters in the endpoint data structure*/
            cdc_obj_ptr->ep[index].queue[queue_num].channel = ep_num;
            cdc_obj_ptr->ep[index].queue[queue_num].app_data.data_ptr = app_buff;
            cdc_obj_ptr->ep[index].queue[queue_num].app_data.data_size = size; 
            cdc_obj_ptr->ep[index].queue[queue_num].handle = 
            cdc_obj_ptr->controller_handle;         
            /* increment producer bin by 1*/       
            cdc_obj_ptr->ep[index].bin_producer = ++producer;

            if((uint_8)(producer - consumer) == (uint_8)1)         
            {          
    #endif      
                status = USB_Class_Send_Data(cdc_obj_ptr->class_handle,
                 ep_num, app_buff,size);
    #if IMPLEMENT_QUEUING
            }
        }
        else /* bin is full */
        {
            status = USBERR_DEVICE_BUSY; 
        }    
    #endif 
    return status;
}
Пример #5
0
/**************************************************************************//*!
 *
 * @name  USB_Class_CDC_Send_Data
 *
 * @brief This function is used to send data from CDC Class over send endpoints
 *
 * @param controller_ID : Controller ID
 * @param ep_num        : Endpoint number
 * @param app_buff      : Buffer to send
 * @param size          : Length of the transfer
 *
 * @return status
 *         USB_OK           : When Successfull
 *         Others           : Errors
 ******************************************************************************
 * Helper function. Sends DATA over CIC and DIC Interfaces to Host
 *****************************************************************************/
uint_8 USB_Class_CDC_Send_Data (
    uint_8 controller_ID,   /* [IN] Controller ID */
    uint_8 ep_num,          /* [IN] Endpoint Number */
    uint_8_ptr app_buff,    /* Pointer to Application Buffer */
    USB_PACKET_SIZE size    /* Size of Application Buffer */
)
{
    uint_8 status = USB_OK;

#if IMPLEMENT_QUEUING
    uint_8 index;
    uint_8 producer, consumer;

    USB_ENDPOINTS *usb_ep_data = (USB_ENDPOINTS *)
                                    USB_Desc_Get_Endpoints(controller_ID);

    /* map the endpoint num to the index of the endpoint structure */
    for(index = 0; index < usb_ep_data->count; index++)
    {
        if(usb_ep_data->ep[index].ep_num == ep_num)
        {
            break;
        }
    }

    producer = g_cdc_ep[index].bin_producer;
    consumer = g_cdc_ep[index].bin_consumer;

    if(((uint_8)(producer - consumer)) != (uint_8)(MAX_QUEUE_ELEMS))
    {
        /* the bin is not full*/

        uint_8 queue_num = (uint_8)(producer % MAX_QUEUE_ELEMS);

        /* put all send request parameters in the endpoint data structure */
        g_cdc_ep[index].queue[queue_num].controller_ID = controller_ID;
        g_cdc_ep[index].queue[queue_num].channel = ep_num;
        g_cdc_ep[index].queue[queue_num].app_data.data_ptr = app_buff;
        g_cdc_ep[index].queue[queue_num].app_data.data_size = size;

        /* increment producer bin by 1*/
        g_cdc_ep[index].bin_producer = ++producer;

        if((uint_8)(producer - consumer) == (uint_8)1)
        {
#endif
            status = USB_Class_Send_Data(controller_ID, ep_num, app_buff,size);
#if IMPLEMENT_QUEUING
        }
    }
    else /* bin is full */
    {
        status = USBERR_DEVICE_BUSY;
    }
#endif
    return status;
}
Пример #6
0
/*
** ===================================================================
**     Method      :  USB_Service_Mems_Status_Interrupt (component USB_MEMS_CLASS)
**
**     Description :
**         The funtion is callback function of Mems Status Interrupt 
**         endpoint
**         This method is internal. It is used by Processor Expert only.
** ===================================================================
*/
static void USB_Service_Mems_Status_Interrupt(
PTR_USB_DEV_EVENT_STRUCT event
)
{
    uint_8 index;
    uint_8 producer, consumer;
    USB_ENDPOINTS *usb_ep_data = (USB_ENDPOINTS *)USB_Desc_Get_Endpoints(event->controller_ID);

    /* map the endpoint num to the index of the endpoint structure */
    for(index = 0; index < usb_ep_data->count; index++)
    {
        if(usb_ep_data->ep[index].ep_num == event->ep_num)
        break;
    }

    producer = g_mems_endpoint_data.ep[index].bin_producer;
    consumer = g_mems_endpoint_data.ep[index].bin_consumer;
    /* if there are no errors de-queue the queue and decrement the no. of
    transfers left, else send the same data again */
    if (event->errors == 0)
    {
        /* de-queue if the send is complete without an error */
        if((MAX_QUEUE_ELEMS-1) == consumer)
        {
            g_mems_endpoint_data.ep[index].bin_consumer = 0;
        }
        else
        {
            g_mems_endpoint_data.ep[index].bin_consumer++;
        }
    }

    consumer = g_mems_endpoint_data.ep[index].bin_consumer;
    g_mems_endpoint_data.ep[index].queue_num--;

    if(0 == g_mems_endpoint_data.ep[index].queue_num)
    {
        /*if bin is not empty */
        USB_CLASS_MEMS_QUEUE queue;
        /* send the next packet in queue */
        queue = g_mems_endpoint_data.ep[index].queue[consumer];
        (void)USB_Class_Send_Data(queue.controller_ID, queue.channel,
        queue.app_buff, queue.size);
    }

    if(g_param_callback != NULL)
    {
        uint_8 event_type = USB_APP_SEND_COMPLETE;
        if(event->errors != 0)
        {
            event_type = USB_APP_ERROR;
        }
        g_param_callback(event->controller_ID, event_type,
        (uint_8*)(&(event->errors)));
    }
}
Пример #7
0
/**************************************************************************//*!
 *
 * @name  USB_Service_Hid
 *
 * @brief The function is a callback function of HID endpoint
 *
 * @param event : Pointer to USB Event Structure
 *
 * @return None
 *
 ******************************************************************************
 * This function is called from lower layer when data is transfer is completed
 * on HID endpoint (non control endpoint)
 *****************************************************************************/
void USB_Service_Hid (
    PTR_USB_DEV_EVENT_STRUCT event /* [IN] Pointer to USB Event Structure */
)
{
    uint_8 index;
    uint_8 producer, consumer;
    USB_ENDPOINTS *ep_desc_data = (USB_ENDPOINTS *)
        USB_Desc_Get_Endpoints(event->controller_ID);

     /* map the endpoint num to the index of the endpoint structure */
    index = USB_Map_Ep_To_Struct_Index(event->controller_ID, event->ep_num);

    producer = g_hid_endpoint_data.ep[index].bin_producer;

    /* if there are no errors de-queue the queue and decrement the no. of
       transfers left, else send the same data again */
    if(event->errors == 0)
    {
        /* de-queue if the send is complete without an error */
        g_hid_endpoint_data.ep[index].bin_consumer++;
    }
    else
    {
        /* notify the application of the error */
        g_hid_class_callback(event->controller_ID, USB_APP_ERROR,
            (uint_8*)(&(event->errors)));
    }
    consumer = g_hid_endpoint_data.ep[index].bin_consumer;

    if(consumer != producer)
    {
        /*if bin is not empty */
        USB_CLASS_HID_QUEUE queue;
        /* send the next packet in queue */
        queue = g_hid_endpoint_data.ep[index].
            queue[consumer % MAX_QUEUE_ELEMS];

        (void)USB_Class_Send_Data(queue.controller_ID, queue.channel,
            queue.app_buff, queue.size);
    }

    /* notify the app of the send complete */
    g_hid_class_callback(event->controller_ID, USB_APP_SEND_COMPLETE, 0);
}
Пример #8
0
/**************************************************************************//*!
 *
 * @name  USB_Service_Dic_Bulk_In
 *
 * @brief The funtion ic callback function of DIC Bulk In Endpoint 
 *
 * @param event
 *
 * @return None       
 *
 *****************************************************************************/
void USB_Service_Dic_Bulk_In(PTR_USB_EVENT_STRUCT event,pointer arg)
{
    APP_DATA_STRUCT bulk_in_recv;
    uint_8 event_type;
    CDC_DEVICE_STRUCT_PTR cdc_obj_ptr = (CDC_DEVICE_STRUCT_PTR)arg;
    
    #if IMPLEMENT_QUEUING
        uint_8 index;
        uint_8 producer, consumer;
        USB_ENDPOINTS *usb_ep_data = cdc_obj_ptr->usb_ep_data;
        
        USB_CLASS_CDC_QUEUE queue;

        /* map the endpoint num to the index of the endpoint structure */
        index = USB_Map_Ep_To_Struct_Index(cdc_obj_ptr, event->ep_num); 
        producer = cdc_obj_ptr->ep[index].bin_producer;         
        /* if there are no errors de-queue the queue and decrement the no. of 
           transfers left, else send the same data again */
        cdc_obj_ptr->ep[index].bin_consumer++;                  
        consumer = cdc_obj_ptr->ep[index].bin_consumer;
            
        if(consumer != producer) 
        {/*if bin is not empty */
                            
            queue = cdc_obj_ptr->ep[index].queue[consumer%CDC_MAX_QUEUE_ELEMS];
                            
            (void)USB_Class_Send_Data(cdc_obj_ptr->class_handle, queue.channel, 
                queue.app_data.data_ptr, queue.app_data.data_size);
        }          
    #endif
    
    if(cdc_obj_ptr->param_callback.callback != NULL) 
    {
        event_type = USB_APP_SEND_COMPLETE;
        bulk_in_recv.data_ptr = event->buffer_ptr;
        bulk_in_recv.data_size = event->len;
        cdc_obj_ptr->param_callback.callback(event_type,
                (void*)&bulk_in_recv,cdc_obj_ptr->param_callback.arg);             
    }
}
Пример #9
0
/**************************************************************************//*!
 *
 * @name  USB_Service_Hid
 *
 * @brief The funtion ic callback function of HID endpoint 
 *
 * @param event
 *
 * @return None       
 *
 *****************************************************************************/
void USB_Service_Hid(PTR_USB_EVENT_STRUCT event,pointer arg)
{
    uint_8 index;
    uint_8 producer, consumer;
    HID_DEVICE_STRUCT_PTR  devicePtr;
    USB_ENDPOINTS *ep_desc_data;
    
    devicePtr = (HID_DEVICE_STRUCT_PTR)arg;
    
    ep_desc_data = devicePtr->ep_desc_data; 

     /* map the endpoint num to the index of the endpoint structure */
    index = HID_USB_Map_Ep_To_Struct_Index(devicePtr, event->ep_num); 
                                               
    producer = devicePtr->hid_endpoint_data.ep[index].bin_producer;    
        
    /* if there are no errors de-queue the queue and decrement the no. of 
     transfers left, else send the same data again */
     /* de-queue if the send is complete with no error */
   devicePtr->hid_endpoint_data.ep[index].bin_consumer++;  
        
    consumer = devicePtr->hid_endpoint_data.ep[index].bin_consumer;
        
    if(consumer != producer) 
    {/*if bin is not empty */
        
        USB_CLASS_HID_QUEUE queue;    
        /* send the next packet in queue */                
        queue = devicePtr->hid_endpoint_data.ep[index].
                                         queue[consumer % HID_MAX_QUEUE_ELEMS];
                        
        (void)USB_Class_Send_Data(devicePtr->class_handle, queue.channel, 
                                      queue.app_buff, queue.size);                                                                                                
    }        
    
    /* notify the app of the send complete */
    devicePtr->hid_class_callback.callback(USB_APP_SEND_COMPLETE, 0,
    devicePtr->hid_class_callback.arg); 
}
Пример #10
0
/**************************************************************************//*!
 *
 * @name  USB_Class_CDC_Service_Cic_Notify
 *
 * @brief The function is callback function of CIC Notification endpoint
 *
 * @param event : Pointer to USB Event Structure
 *
 * @return None
 *
 ******************************************************************************
 * Called by Lower layer when data on CIC Endpoint is sent
 *****************************************************************************/
void USB_Class_CDC_Service_Cic_Notify (
    PTR_USB_DEV_EVENT_STRUCT event  /* [IN] Pointer to USB Event Structure */
)
{
#if IMPLEMENT_QUEUING
    uint_8 index;
    uint_8 producer, consumer;
    USB_ENDPOINTS *usb_ep_data = (USB_ENDPOINTS *)
        USB_Desc_Get_Endpoints(event->controller_ID);

    USB_CLASS_CDC_QUEUE queue;

    /* map the endpoint num to the index of the endpoint structure */
    for(index = 0; index < usb_ep_data->count; index++)
    {
        if(usb_ep_data->ep[index].ep_num == event->ep_num)
        break;
    }

    producer = g_cdc_ep[index].bin_producer;

    /* if there are no errors de-queue the queue and decrement the no. of
       transfers left, else send the same data again */
    if(event->errors == 0)
    {
        g_cdc_ep[index].bin_consumer++;
    }

    consumer = g_cdc_ep[index].bin_consumer;

    if(consumer != producer)
    {/*if bin is not empty */

        queue = g_cdc_ep[index].queue[consumer%%MAX_QUEUE_ELEMS];

        (void)USB_Class_Send_Data(queue.controller_ID, queue.channel,
            queue.app_data.data_ptr, queue.app_data.data_size);
    }
Пример #11
0
/**************************************************************************//*!
 *
 * @name  USB_Service_Dic_Bulk_In
 *
 * @brief The function ic callback function of DIC Bulk In Endpoint
 *
 * @param event
 *
 * @return None
 *
 *****************************************************************************/
void USB_Service_Dic_Bulk_In(usb_event_struct_t* event, void* arg)
{
    uint8_t event_type;
    cdc_device_struct_t * cdc_obj_ptr = (cdc_device_struct_t *)arg;

    //if(USB_UNINITIALIZED_VAL_32 == event->len) return;
#if CDC_IMPLEMENT_QUEUING
    uint8_t index;
    uint8_t producer, consumer;
//        usb_endpoints_t *usb_ep_data = cdc_obj_ptr->usb_ep_data;

    cdc_queue_struct_t queue;
    usb_status status = USB_OK;

    /* map the endpoint num to the index of the endpoint structure */
    index = USB_Map_Ep_To_Struct_Index(cdc_obj_ptr, event->ep_num);
    USB_Cdc_Ep_Mutex_Lock(cdc_obj_ptr, event->ep_num);
    producer = cdc_obj_ptr->ep[index].bin_producer;
    consumer = cdc_obj_ptr->ep[index].bin_consumer;

    /* No pending transfer */
    if(producer == consumer)
    {
        return;
    }
    /* if there are no errors de-queue the queue and decrement the no. of
     transfers left, else send the same data again */
    cdc_obj_ptr->ep[index].bin_consumer++;
    consumer = cdc_obj_ptr->ep[index].bin_consumer;

    while(consumer != producer)
    {
        queue = cdc_obj_ptr->ep[index].queue[consumer%CDC_MAX_QUEUE_ELEMS];

        status = USB_Class_Send_Data(cdc_obj_ptr->class_handle, queue.channel,
                                     queue.app_data.data_ptr, queue.app_data.data_size);
        if(USB_OK == status)
        {
            break;
        }
        else
        {
            USB_Cdc_Ep_Mutex_Unlock(cdc_obj_ptr, event->ep_num);
            if(cdc_obj_ptr->class_specific_callback.callback != NULL)
            {
                event_type = USB_DEV_EVENT_SEND_COMPLETE;
                event->len = 0xFFFFFFFF;
                cdc_obj_ptr->class_specific_callback.callback(event_type,
                        USB_REQ_VAL_INVALID,
                        &(event->buffer_ptr),
                        &(event->len),
                        cdc_obj_ptr->class_specific_callback.arg);
            }
            USB_Cdc_Ep_Mutex_Lock(cdc_obj_ptr, event->ep_num);
            producer = cdc_obj_ptr->ep[index].bin_producer;
            cdc_obj_ptr->ep[index].bin_consumer++;
            consumer = cdc_obj_ptr->ep[index].bin_consumer;
        }
    }
    USB_Cdc_Ep_Mutex_Unlock(cdc_obj_ptr, event->ep_num);
#endif

    if (cdc_obj_ptr->class_specific_callback.callback != NULL)
    {
        event_type = USB_DEV_EVENT_SEND_COMPLETE;
        cdc_obj_ptr->class_specific_callback.callback(event_type,
                USB_REQ_VAL_INVALID,
                &(event->buffer_ptr),
                &(event->len),
                cdc_obj_ptr->class_specific_callback.arg);
    }
}
Пример #12
0
/**************************************************************************//*!
 *
 * @name  USB_Class_Video_Send_Data
 *
 * @brief This fucntion is used by Application to send data through Video class
 *
 * @param controller_ID     : Controller ID
 * @param ep_num            : Endpoint number
 * @param app_buff          : Buffer to send
 * @param size              : Length of the transfer
 *
 * @return status:
 *                        USB_OK        : When Successfull
 *                        Others        : When Error
 *
 ******************************************************************************
 * This fucntion is used by Application to send data through Video class
 *****************************************************************************/
uint_8 USB_Class_Video_Send_Data (
		uint_8 controller_ID,       /* [IN] Controller ID */
		uint_8 ep_num,              /* [IN] Endpoint Number */
		uint_8_ptr app_buff,        /* [IN] Buffer to Send */
		USB_PACKET_SIZE size        /* [IN] Length of the Transfer */
)
{
	uint_8 status = USB_OK;
	PTR_USB_CLASS_VIDEO_QUEUE queue_tmp;

#if IMPLEMENT_QUEUING
	uint_8 index;
	uint_8 producer, queue_num;

	USB_ENDPOINTS *usb_ep_data = (USB_ENDPOINTS *)
                                    		USB_Desc_Get_Endpoints(controller_ID);

	/*Body*/                                    
	/* map the endpoint num to the index of the endpoint structure */

	for(index = 0; index < usb_ep_data->count; index++) 
	{
		if(usb_ep_data->ep[index].ep_num == ep_num)
			break;
	}/*EndFor*/

	producer = g_video_endpoint_data.ep[index].bin_producer;
	queue_num = g_video_endpoint_data.ep[index].queue_num;

	if(MAX_QUEUE_ELEMS != queue_num)
	{
		/* the bin is not full*/
		/* put all send request parameters in the endpoint data structure */
		queue_tmp = &(g_video_endpoint_data.ep[index].queue[producer]);
		queue_tmp->controller_ID  = controller_ID;
		queue_tmp->channel        = ep_num;
		queue_tmp->app_buff       = app_buff;
		queue_tmp->size           = size;

		/* increment producer bin by 1*/
		if (producer == (MAX_QUEUE_ELEMS - 1))
		{
			g_video_endpoint_data.ep[index].bin_producer = 0;
		} /*Else*/
		else 
		{
			g_video_endpoint_data.ep[index].bin_producer++;
		}/*EndElse*/
		g_video_endpoint_data.ep[index].queue_num++;

		if(g_video_endpoint_data.ep[index].queue_num == 1)
		{
#endif
			status = USB_Class_Send_Data(controller_ID, ep_num, app_buff,size);
#if IMPLEMENT_QUEUING
		}/*EndIf*/
	}/*Else*/
	else /* bin is full */
	{
		status = USBERR_DEVICE_BUSY;
	}/*EndIf*/
#endif
	return status;
}/*EndBody*/