Hello Marco,
USB CDC class has two API for sending and receiving data to/from host:
USB_Class_CDC_Send_Data
(
cdc_handle_t handle,
uint8_t ep_num,
uint8_t* app_buff, /* [IN] buffer to send */
uint32_t size /* [IN] length of the transfer */
);
USB_Class_CDC_Recv_Data
(
cdc_handle_t cdc_handle,
uint8_t ep_num,
uint8_t* buff_ptr, /* [IN] buffer to send */
uint32_t size /* [IN] length of the transfer */
);
These functions require to receive the buffer to be sent or be used to stored the data and the size for the data to be sent/received. You can request these transactions in order to send or received data to Host.
In KSDK 1.3 CDC example, there is a loopback implementation that does the following procedure:
- After CDC device is enumerated, Device request a USB_Class_CDC_Recv_data from host:
else if (event_type == USB_DEV_EVENT_CONFIG_CHANGED)
{
/* Schedule buffer for receive */
USB_Class_CDC_Recv_Data(handle, DIC_BULK_OUT_ENDPOINT, g_curr_recv_buf, g_bulk_out_max_packet_size);
start_app = TRUE;
}
- After data is received, these data is copied in a global buffer
case USB_DEV_EVENT_DATA_RECEIVED:
{
if ((start_app == TRUE) && (start_transactions == TRUE))
{
g_recv_size = *size;
- Then, in virtual_com_app function, these data is copied to another buffer that will be sent to host by using USB_Class_CDC_Send_Data API:
void Virtual_Com_App(void)
{
/* User Code */
if ((0 != g_recv_size) && (0xFFFFFFFF != g_recv_size))
{
int32_t i;
/* Copy Buffer to Send Buff */
for (i = 0; i < g_recv_size; i++)
{
//USB_PRINTF("Copied: %c\n", g_curr_recv_buf[i]);
g_curr_send_buf[g_send_size++] = g_curr_recv_buf[i];
}
g_recv_size = 0;
}
if (g_send_size)
{
uint8_t error;
uint32_t size = g_send_size;
g_send_size = 0;
error = USB_Class_CDC_Send_Data(g_app_handle, DIC_BULK_IN_ENDPOINT,
g_curr_send_buf, size);
- After data is sent, a new reception request is made and the cycle repeats:
case USB_DEV_EVENT_SEND_COMPLETE:
{
if ((size != NULL) && (*size != 0) && (!(*size % g_bulk_in_max_packet_size)))
{
/* If the last packet is the size of endpoint, then send also zero-ended packet,
** meaning that we want to inform the host that we do not have any additional
** data, so it can flush the output.
*/
USB_Class_CDC_Send_Data(g_app_handle, DIC_BULK_IN_ENDPOINT, NULL, 0);
}
else if ((start_app == TRUE) && (start_transactions == TRUE))
{
if ((*data != NULL) || ((*data == NULL) && (*size == 0)))
{
/* User: add your own code for send complete event */
/* 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);
So basically, you manage requests for sending and receive data form Host. If you desired to implement an asynchronous half duplex scheme, you will need to modify current logic from example as it is mentioned here: https://community.freescale.com/thread/359149
I hope this can help you!
Regards,
Isaac