AnsweredAssumed Answered

K65 USB CDC implementation in MQX

Question asked by annamol alex on Aug 10, 2017
Latest reply on Sep 5, 2017 by annamol alex

Hi,

I am trying to implement USB CDC using MQX on K65F180M. I created a new project using USB_v2 stack and made the following changes to stream  data via VCOM. While implementing the same, these issues were faced and it would be great if someone can point me in the right direction and correct me if I have done something wrong. 

  1. Created a new workspace  and added USBD project and USBCDC project  along with BSP and PSP
  2. Fixed all linking issues by modifying  compiler and linker settings
  3. The default code worked without any issues, whatever data is input via serial monitor is displayed back on the screen. The serial monitor used was realterm and it worked smoothly.
  4. Then modified code for streaming, by making the following change in Virtual_com_app ()

    void Virtual_Com_App(void)
    {

    while(1)
    {
    uint8_t error;
    uint32_t size = sizeof(transmit_data);
    g_send_size = 0;

    error = USB_Class_CDC_Send_Data(g_app_handle, DIC_BULK_IN_ENDPOINT,
    transmit_data, size);

    if (error != USB_OK)
    {
    /* Failure to send Data Handling code here */
    }
    }

In this implementation, it was keeping on waiting for an input(enter key press) on serial monitor to display the data. If I send the buffer again in USB_DEV_EVENT_SEND_COMPLETE again. It will push data continuously, which is actually unnecessary as per my understanding of USB CDC implementation. In CDC,  USB_DEV_EVENT_SEND_COMPLETE event gets set after you call USB_Class_CDC_Send_Data() in Virtual_Com_app() and is used only to send NULL packet after a successful transfer as well as to wait for next input. With these streaming modifications, port gets enumerated but in realterm it won't open the port and will fail with some timeout or IO_error, but can see data in teraterm. 

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, transmit_data, sizeof(transmit_data));
}
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);
#if USBCFG_DEV_KEEP_ALIVE_MODE
#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK)
waitfordatareceive = 1;
usb_hal_khci_disable_interrupts((uint32_t)USB0, INTR_SOFTOK);
#endif
#endif
}
}
}
break;

In standard IO it prints out the message "usb_device_send_data: DEV_GET_XD failed". Does this mean it is a faulty implementation? 

While skimming through the USB_DEV_EVENT_SEND_COMPLETE, to remove the waiting for another input and usb_device_send_data: DEV_GET_XD failed message, I removed 

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);
#if USBCFG_DEV_KEEP_ALIVE_MODE
#if (OS_ADAPTER_ACTIVE_OS == OS_ADAPTER_SDK)
waitfordatareceive = 1;
usb_hal_khci_disable_interrupts((uint32_t)USB0, INTR_SOFTOK);
#endif
#endif
}

and then kept a delay in virtual_com_App

while(1)
// if (g_send_size)
{
uint8_t error;
uint32_t size = sizeof(transmit_data);
g_send_size = 0;

error = USB_Class_CDC_Send_Data(g_app_handle, DIC_BULK_IN_ENDPOINT,
transmit_data, size);
for(int i=0;i<10000;i++)
for(int k=0;k<10;k++);

if (error != USB_OK)
{
int a=10;
/* Failure to send Data Handling code here */
}
}

Now I don't get the error message and streaming also happens. Is this implementation ok?

Finally I am looking at  asynchronous reception of data via USB along with streaming at the maximum data rate possible.Though I don't understand why the data streaming fails in real term

 

It would be really helpful if anyone can let me know whether this implementation is ok or not?

Outcomes