[MQX4.1]: Is there data sending event in USB host stack?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

[MQX4.1]: Is there data sending event in USB host stack?

Jump to solution
907 Views
huishao2
Contributor IV

Hi-

One USB device side, there is a notification callback to inform about USB_APP_DATA_RECEIVED from USB device stack. My question is, is there a similar data sent event that can be obtained from callback function on USB host side?

thanks!

Hui

Labels (1)
0 Kudos
1 Solution
665 Views
isaacavila
NXP Employee
NXP Employee

Hello Hui,

In CDC example, there are two different interfaces, one for control (ACM) and other for data, both interfaces have their own callback (usb_host_cdc_acm_event and usb_host_cdc_data_event).

In ACM's callback, you will find a usb_class_cdc_init_ipipe function that starts the interrupt endpoint to poll for any interrupt transaction on device's side, so, this TR for interrupt endpoint is already installed.

For Data's callback, you can see the usb_class_cdc_install_driver function that installs USB device, this way, you can use fopen, fread and fwrite functions in order to open, read, write for USB device, these functions call the respective _io_cdc_serial function. (You can see usb_host_cdc.c file in Host stack for more details)

Like driver is already installed and driver uses events to signal incoming data, you will only need to use fread and fwrite functions (as shown in USB2UART_Task and UART2USB_Task) and internally, usb_class_cdc functions will wait/post for these events and manage all service needed in order to complete these transactions.

If you look in _io_cdc_serial_read or _io_cdc_serial_write functions, you will see that these TR are managed internally as well:

usb_hostdev_tr_init(&tr, (tr_callback) usb_class_cdc_out_data_callback, (void *) data_instance);

        tr.G.TX_BUFFER = (unsigned char *) data_ptr;

        tr.G.TX_LENGTH = num_left;

        _lwevent_clear(event, USB_DATA_SEND_COMPLETE);

        status = _usb_host_send_data(if_ptr->CDC_G.G.host_handle, if_ptr->out_pipe, &tr);

        if (status == USB_STATUS_TRANSFER_QUEUED) {

            USB_unlock();

This example was built this way to make it easy to use and be compatible with POSIX standard.

I hope this can help you!

Beswt Regards,

Isaac

----------------------------------------------------------------------------------------------------------------------------------------

Note: If this post answers your question, please click the Correct Answer button. Thank you!

----------------------------------------------------------------------------------------------------------------------------------------

View solution in original post

0 Kudos
3 Replies
665 Views
isaacavila
NXP Employee
NXP Employee

Hello Hui,

In Host stack, it is quite different, you need to initialize a transfer request and then set a callback that you can use to signal an event when transaction (either recepcion or transmission) has completed. For more information, you can read the MQX_USB_Host_User_Guide, section 4.2.4.6 Sending/Receiving Data to/from Device.

Also, you can see host's examples and could notice (for example, en hid example) how this TR is used:

/******************************************************************

                    Initiate a transfer request on the interrupt pipe

                    ******************************************************************/

                    usb_hostdev_tr_init(&tr, usb_host_hid_recv_callback, NULL);

                    tr.G.RX_BUFFER = buffer;

                    tr.G.RX_LENGTH = pipe->MAX_PACKET_SIZE;                    

                       

                    status = _usb_host_recv_data(host_handle, pipe, &tr);

This TR is a structure that describes a transfer in its entirety, then you can request/transmit data using this TR and after this transaction is completed, callback function is called. In this callback you can use an event to inform about success/failure for transmission/reception:

void usb_host_hid_recv_callback

   (

      /* [IN] pointer to pipe */

      _usb_pipe_handle  pipe_handle,

      /* [IN] user-defined parameter */

      void             *user_parm,

      /* [IN] buffer address */

      unsigned char         *buffer,

      /* [IN] length of data transferred */

      uint32_t           buflen,

      /* [IN] status, hopefully USB_OK or USB_DONE */

      USB_STATUS        status

   )

{ /* Body */

    if (status == USB_OK) {

        /* notify application that data are available */

        _lwevent_set(&USB_Event, USB_EVENT_DATA);

    }

    else {

        /* notify application that data are available */

        _lwevent_set(&USB_Event, USB_EVENT_DATA_CORRUPTED);

    } 

}

I hope this can help you!

Best Regards,

Isaac Avila

----------------------------------------------------------------------------------------------------------------------------------------

Note: If this post answers your question, please click the Correct Answer button. Thank you!

----------------------------------------------------------------------------------------------------------------------------------------

665 Views
huishao2
Contributor IV

Hi Issac

It is very helpful. However, I am looking at the CDC class example under Freescale_MQX_4_1\usb\host\examples\cdc\cdc_serial. There the USB port is opened by

..

     if (NULL == (s_f_usb_info.f_usb = fopen(device_name, (void*) &usb_open_param))) {

..

When I write something to the USB port opened above

..

            num_done = fwrite(buffer, sizeof(buffer[0]), num, s_f_usb_info.f_usb);

..

Given I have only usb_host_cdc_acm_event and usb_host_cdc_data_event registered in driver info table, how can I apply the TR onto this mechanism?

Thanks!

Hui

0 Kudos
666 Views
isaacavila
NXP Employee
NXP Employee

Hello Hui,

In CDC example, there are two different interfaces, one for control (ACM) and other for data, both interfaces have their own callback (usb_host_cdc_acm_event and usb_host_cdc_data_event).

In ACM's callback, you will find a usb_class_cdc_init_ipipe function that starts the interrupt endpoint to poll for any interrupt transaction on device's side, so, this TR for interrupt endpoint is already installed.

For Data's callback, you can see the usb_class_cdc_install_driver function that installs USB device, this way, you can use fopen, fread and fwrite functions in order to open, read, write for USB device, these functions call the respective _io_cdc_serial function. (You can see usb_host_cdc.c file in Host stack for more details)

Like driver is already installed and driver uses events to signal incoming data, you will only need to use fread and fwrite functions (as shown in USB2UART_Task and UART2USB_Task) and internally, usb_class_cdc functions will wait/post for these events and manage all service needed in order to complete these transactions.

If you look in _io_cdc_serial_read or _io_cdc_serial_write functions, you will see that these TR are managed internally as well:

usb_hostdev_tr_init(&tr, (tr_callback) usb_class_cdc_out_data_callback, (void *) data_instance);

        tr.G.TX_BUFFER = (unsigned char *) data_ptr;

        tr.G.TX_LENGTH = num_left;

        _lwevent_clear(event, USB_DATA_SEND_COMPLETE);

        status = _usb_host_send_data(if_ptr->CDC_G.G.host_handle, if_ptr->out_pipe, &tr);

        if (status == USB_STATUS_TRANSFER_QUEUED) {

            USB_unlock();

This example was built this way to make it easy to use and be compatible with POSIX standard.

I hope this can help you!

Beswt Regards,

Isaac

----------------------------------------------------------------------------------------------------------------------------------------

Note: If this post answers your question, please click the Correct Answer button. Thank you!

----------------------------------------------------------------------------------------------------------------------------------------

0 Kudos