cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L0 USB CUSTOMHID Bidirectional

fussenegger
Associate II
Posted on November 03, 2015 at 13:26

Hi guys,

I am working on a solution to implement generic bidirectional data transfer over the USB interface. I am using the current CubeL0 library (version 1.3.0) and the USB library provided in this package. I implemented the CUSTOM HID class and stick to the standard implementation provided by the class. My project is compiled using the Sourcery CodeBench Lite toolchain.

My problem is that I cannot receive data from my PC without corrupting the implemented USB HID stack. Sending and receiving data on my PC works perfectly, with any data byte sizes (2-64 byte). But after my microcontroller received the first HID package from my PC the stack gets corrupted. Based on the byte width this can have different effects on the system. For byte widths below 8 byte data transfer is still working, but the USB HID descriptor changes. I have two html files (

http://www.fussenegger.it/USBHIDDevice_Before.html

;

http://www.fussenegger.it/USBHIDDevice_After.html

) which show this effect, the first file was captured before a package was received and the second one was after one package was received. The device strings are not more provided after the first HID receive, which results that my Python HID script cannot list my device anymore.

If I increase the byte width of the HID report buffer to 16 byte, then the complete communication is getting corrupted. Somehow the received bytes are wrong and the second incoming packet is never received.

After all this error looks really strange and I wasn't able to figure out where the corruption happens. Has anyone any clues where I should look to find the problem? Also, are any bidirectional HID examples for my device (STM32L052) available? I only could find examples with other USB libraries or which are only sending data. As said, sending data is working fine, receiving causes the problems.

Best Greetings

Markus

#usb-stm32l0-hid-customhid
2 REPLIES 2
fussenegger
Associate II
Posted on November 04, 2015 at 11:32

Finally, I got it working. There were two errors in my application:

1. The static malloc function I created didn't allocate enough memory, therefore the transmission has overwritten crucial properties of the USB_Device instance.

2. The endpoint addresses were ''wrong'', or better said just not working.

#define CUSTOM_HID_EPIN_ADDR                 0x81       

#define CUSTOM_HID_EPIN_SIZE                    64

#define CUSTOM_HID_EPOUT_ADDR                0x82

#define CUSTOM_HID_EPOUT_SIZE                   64

Wit these endpoint configurations it works, I am finally able to transmit 64byte in both directions.

Greetings

Markus

fussenegger
Associate II
Posted on November 05, 2015 at 11:07

Well, yesterdays solution wasn't correct either. But I think now I got it. For anyone who is interested, this is my configuration:

#define CUSTOM_HID_EPIN_ADDR                 0x81      

#define CUSTOM_HID_EPIN_SIZE                 64

#define CUSTOM_HID_EPOUT_ADDR                0x01       

#define CUSTOM_HID_EPOUT_SIZE                64

  // control endpoints, fixed addresses, 64bit width

  HAL_PCDEx_PMAConfig(pdev->pData , 0x00 , PCD_SNG_BUF, 0x18);

  HAL_PCDEx_PMAConfig(pdev->pData , 0x80 , PCD_SNG_BUF, 0x58);

  // user defined endpoints, 64bit width; endpoint addresses need to match with hid endpoints

  HAL_PCDEx_PMAConfig(pdev->pData , 0x81 , PCD_SNG_BUF, 0x98);

  HAL_PCDEx_PMAConfig(pdev->pData , 0x01 , PCD_SNG_BUF, 0xD8);

The PMA Configs in the file ''usbd_conf.c'' need to match the endpoint configuration given in the ''customhid.h'' header file. The first two endpoints with addresses 0x00 and 0x80 are mandatory as they are used for the control endpoint. They should not be changed.

The other two 0x81 and 0x01 are my user definend enpoints. The 0x81 is the IN endpoint (It is an in endpoint if bit 7 is 1), the other one is the OUT endpoint. The PMA addresses of the first two endpoints should also not be changed (0x18, 0x58). If the addresses are configured like above every buffer has 64 byte (0x40), which is the maximum. Therefore the first user defined pma buffer starts at 0x98 and the second at 0xD8.

My system is now stable, and provides correct data. I hope I could help someone (or help someone in the future) as I wasted a lot of time only because of my messy configuration.

Best Regards

Markus