dev_hid_generic_freertos_twrk65f180m with multiple end points

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

dev_hid_generic_freertos_twrk65f180m with multiple end points

1,476 Views
kirkclendinning
Contributor II

I am trying to add end points to the usb example, dev_hid_generic_freertos_twrk65f180m. I added end points to the descriptor and indeed, the TWR-K65F180M enumerates, correctly for all of the end points. However, when trying to send USB messages, only the first set of end points, 0x01 and 0x81 cause the USB_DeviceGenericCallback() method to be called.

 

In addition, even if the USB_DeviceGenericCallback() were called for all of the end points, I don't see from its arguments class_handle_t handle, uint32_t event and void *param, for which end point the call was made.

 

Is there an HID example that I've missed, which illustrates more than a pair of end points? If not, perhaps someone with more insight into the Kinetis USB middleware stack could point me in the right direction.

Labels (1)
0 Kudos
4 Replies

1,106 Views
ivadorazinova
NXP Employee
NXP Employee

Hi Kirk.

I apologize for the late response, but I consulted your issue with Application Team. Please refer to their answer below.

Regarding the multiple pairs of endpoints enablement, I think you are using the HID generic class driver, for such standard class driver, only one pair of endpoint could be supported for sure. By no means, you could use a standard generic class driver to support a non-standard user case (multiple pairs of endpoints). Instead, you should use the usb_device_hid_generic_lite example, which has no standard class driver, so it is easy for you to add more endpoints support.

  • USB_DEVICE_CONFIG_USE_TASK is a configuration item, means it could be configured by the customers according to their requirements. So whatever it is 0 or 1, our default example should work fine always. You should not assume a mandatory 1 or 0 could work. And from the MACRO word itself, the meaning is very clear, it is a configuration item to choose if the task need to be used.
  • USB_DEVICE_CONFIG_EHCI and USB_DEVICE_CONFIG_EHCI are two configuration item too. In the USB device RM, the description is as below, it is simple but intuitive. Why do you mention it as undefined macros? Why “One would have thought that USB_DEVICE_CONFIG_USE_TASK would have needed to be 1 for the example to work”, the code logic is if you defined USB_DEVICE_CONFIG_USE_TASK, then some additional actions need to be performed; If the macro is not defined, then these actions are not needed. There is no explicit or implicit hint that this USB_DEVICE_CONFIG_USE_TASK need to be 1.

pic.png

I hope this helps.

Best Regards,

Iva

0 Kudos

1,106 Views
kirkclendinning
Contributor II

Sadly, documentation for the FreeRTOS USB stack in SDK is woefully inadequate. If one simply wants to use a template and replace a few constants or rewrite a few methods, it's fine. But, if one wants to understand how the stack works, then too much time is required. The problem is that global macros used to choose between different running options are usually only documented by a comment. Let's take USB_DEVICE_CONFIG_USE_TASK as an example.  Here's the entry from usb_device_config.h.

/*! @brief Whether the device task is enabled. */

#define USB_DEVICE_CONFIG_USE_TASK (0U)

The default is for the task to be disabled. However, in the example, USB appears to work. So, what does this global do? Ah, as a desperate measure, let's check out the documentation. The USB Stack Device reference Manual gives a hint:

#define USB_DEVICE_CONFIG_USE_TASK (0U)

Whether the device task is enabled.

The USB Stack User's Guide omits the Macros. The USB Stack Composite Device User's Guide adds:

10. Poll the device task when the “USB_DEVICE_CONFIG_USE_TASK” is none-zero. Poll the

HID keyboard and HID generic task when these tasks are implemented.

#if USB_DEVICE_CONFIG_USE_TASK #if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U) 
        USB_DeviceEhciTaskFunction(g_UsbDeviceComposite.deviceHandle); #endif 
#if defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0U) 
        USB_DeviceKhciTaskFunction(g_UsbDeviceComposite.deviceHandle); #endif 

#endif

Which brings two more undefined macros into the mix. One would have thought that USB_DEVICE_CONFIG_USE_TASK would have needed to be 1 for the example to work, yet it appears just the opposite. The amount of time needed to wind through the example code is such that it might be quicker to simply write the usb driver one's self.

0 Kudos

1,106 Views
benolayinka
Contributor III

two years later and same thing. it's crazy how much tribal knowledge you have to accumulate to write an app that uses the USB stack. I know NXP ported dean camera's LUFA for some other platforms, would be a heaven send if there were a well documented stack available for the I.MX since one of it's biggest selling points is multiple dual role usb ports.

some of my biggest headaches:

all of the configuration settings you need to uncomment to enable usb stack drivers (USB_CONFIG_AUDIO, USB_DEVICE_CONFIG_KHCI)

if you move the default configuration files, they are silently recreated in source/generated

no simple documentation of the difference between the freeRTOS and regular OSA drivers (what does USB_DEVICE_CONFIG_USE_TASK do?)

no good instructions for writing your own class driver (i've been battling an issue for months where my host instance would stop receiving messages if i paused the debugger and anything came on usb while it was paused. It turns out, in my call to prime the receiver, I requested the size of the receiving buffer rather than the size of of the maximum message the device could send. i only discovered this by copying example drivers line by line until something changed.)

It sounds from Iva response below that NXP doesn't really see how this is a problem on their end..

0 Kudos

1,106 Views
kirkclendinning
Contributor II

I answered half of my own question. The endpoint causing the USBDeviceGenericCallback() to be called can be found by:

    endpointAddress = ((usb_device_hid_struct_t *)handle)->interfaceHandle->endpointList.endpoint->endpointAddress;

0 Kudos