Hi Mark,
Your problem may be caused by a logical bug in the MQX USB device stack (in version <= 4.0.2).
Bug description:
The 'USB_Class_CDC_Send_Data' function in usb_cdc.c uses a variable (uint_8 consumer) to store a local copy of a value changed by the USB completion interrupt (in USB_Service_Cdc_Notif). If this interrupt occurs between the variable being assigned near the start of USB_Class_CDC_Send_Data, and the variable being tested near the end of the function, it will result in the test failing to detect that it is necessary to start sending. Instead it incorrectly assumes there is other packet in the process of being sent. As the next item is only sent from the queue when the previous item completes, nothing is ever sent again and the queue fills up on subsequent calls. This is most likely to happen if 'USB_Class_CDC_Send_Data' is called 2 or more times in quick succession (or in a loop).
Fix:
Modify MQX so it doesn't take a local copy of bin_consumer in the 'USB_Class_CDC_Send_Data' function. Directly test the value changed by the interrupt instead. bin_producer does not suffer the same problem as it is tested but not modified in the interrupt.
Alternatively you could try disabling interrupts before calling USB_Class_CDC_Send_Data, and re-enabling afterwards.
Index: usb_cdc.c
===================================================================
--- usb_cdc.c (revision 21)
+++ usb_cdc.c (revision 22)
@@ -628,7 +628,7 @@
{
#if IMPLEMENT_QUEUING
uint_8 index;
- uint_8 producer, consumer;
+ uint_8 producer;
// USB_ENDPOINTS *usb_ep_data;
#endif
@@ -646,12 +646,12 @@
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;
+ // consumer = cdc_obj_ptr->ep[index].bin_consumer;
- if(((uint_8)(producer - consumer)) != (uint_8)(CDC_MAX_QUEUE_ELEMS))
+ if(((uint_8)(producer - cdc_obj_ptr->ep[index].bin_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;
@@ -658,10 +658,11 @@
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)
+
+ if((uint_8)(producer - cdc_obj_ptr->ep[index].bin_consumer) == (uint_8)1)
{
#endif
status = USB_Class_Send_Data(cdc_obj_ptr->class_handle,
Hope this fixes your problem.
Ian