STM32 USB HID - more buttons problem (button box / joystick buttons)
Hello, dear community!
I have a problem with adding more than one button to my STM32 Button Box / joystick with buttons. I am using USB HID.
I made it as simple as possible - only two buttons, simplest descriptor. The problem may be trivial, but after 4 days and ~8 hours per day - I can't find solution. I watched most of the STM32 USB training course (on yt), I was digging deep in st forum and google/bing/yahoo, but nothing helped. I think there is not a ready answer to my problem in the whole internet.
About the problem: One button (the first one) is working flawlessly, but when i try to USBD_HID_SendReport for another button - nothing happens.
My descriptor:
// HID Report Descriptor
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x04, // Usage (Joystick)
0xA1, 0x01, // Collection (Application)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1 bit)
0x95, 0x02, // Report Count (2 buttons)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (Button 1)
0x29, 0x02, // Usage Maximum (Button 2)
0x81, 0x02, // Input (Data, Var, Abs) - Button states
// Padding to align to a byte
0x75, 0x07, // Report Size (7 bits, for padding)
0x95, 0x02, // Report Count (2 bits for padding)
0x81, 0x03, // Input (Const, Var, Abs) - Padding byte
0xC0 // End Collection
And code from main.c:
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USB_DEVICE_Init();
/* USER CODE BEGIN 2 */
extern USBD_HandleTypeDef hUsbDeviceFS;
typedef struct
{
uint8_t button1;
uint8_t button2;
} joystickHID;
joystickHID joystickhid = {0};
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{ // start probing every of the input pins
if( HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1)
|| HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_2)
|| HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3)
|| HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4)
|| HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5)
|| HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6)
|| HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7)
|| HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0)
) // end probing
{ // if any input pin get input then
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET); // turn on onboard LED
joystickhid.button1 = 1; // set button1 to active
joystickhid.button2 = 1; // set button2 to active
HAL_Delay(200); // wait
}
else{ // if none of the input pins get input then
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET); // turn off onboard LED
joystickhid.button1 = 0; // set button1 to non-active
joystickhid.button2 = 0; // set button2 to non-active
HAL_Delay(200); // wait
}
USBD_HID_SendReport(&hUsbDeviceFS, (uint8_t*)&joystickhid, sizeof( joystickHID )); // send usb report with buttons states
HAL_Delay(5);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
And how it looks in windows gaming devices (sorry for non-english screenshot, but I think you'll get the point. Button1 on, Button2 off):

Summary: Descriptor - works, device is properly recognized as 2 buttons device
button1 - works as intended
button2 - does not work and this is my problem
Disclaimer: I will not leave this thread unresolved - I want to share the solution that will be achieved either by you, the best programmers :D, or me (if I find the solution, I will share it here).
