Hello Edwin,
USB callbacks are needed to handle USB communication correctly. After enumeration has been done and setConfiguration command is received from Host, an USB event is received (USB_DEV_EVENT_CONFIG_CHANGED), after this event is received, USB VCOM example calls the USB_Class_CDC_Recv_Data API to receive data from Host:
else if (event_type == USB_DEV_EVENT_CONFIG_CHANGED)
{
USB_Class_CDC_Recv_Data(handle, DIC_BULK_OUT_ENDPOINT, g_curr_recv_buf, g_bulk_out_max_packet_size);
start_app = TRUE;
}
Then, program can do other thing and when data is finally received, another event is got: USB_DEV_EVENT_DATA_RECEIVED (it is handled on USB_App_Class_Callback)
case USB_DEV_EVENT_DATA_RECEIVED:
{
if ((start_app == TRUE) && (start_transactions == TRUE))
{
g_recv_size = *size;
if (!g_recv_size)
{
/* Schedule buffer for next receive event */
USB_Class_CDC_Recv_Data(handle, DIC_BULK_OUT_ENDPOINT, g_curr_recv_buf, g_bulk_out_max_packet_size);
}
}
Here you can get data from Host and process it.
On the other hand, for sending data, you can call USB_Class_CDC_Send_Data function in your main application and once data has been sent correctly, a new event is called (USB_DEV_EVENT_SEND_COMPLETE).
You have to be sure to complete any event (receive or send data) before calling a new receive/send API. In case that these procedures are not completed an you trigger a new request, these requests will be enqueued and, if more than 12 requests are enqueued, USB application will crash (there is only 12 spaces for these requests). So, be sure to complete every request before triggering a new one (reception needs to be completed before a new receive API is called, same for transmission, it needs to be completed before a new Send API is used).
Hope this helps!
Regards,
Isaac