Need help with STM32f103C8 USB HID Joystick  - Page 1
Forum section: electronics / general

author: foxmjay
author_rank: Contributor
timestamp: May 21, 2020, 06:30:13 pm
content: Hi All,I've been trying to make a USB HID Joystick with the STM32f103C8 ( The Blue Pill ) but without luck !.I've started a project with "Custom Human Interface Class (HID)" using STM32CubeIDE .The STM32f103C8 RCC set to HSE with external Crystal 8Mhz, which gave me a 72Mhz HCLK , and 48Mhz to the USB .The Configuration Descriptor in usbd_customhid.c looks like this :Code:/* USB CUSTOM_HID device FS Configuration Descriptor */__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgFSDesc __ALIGN_END = {0x09,/* bLength: Configuration Descriptor size */USB_DESC_TYPE_CONFIGURATION,/* bDescriptorType: Configuration = 0x02U */USB_CUSTOM_HID_CONFIG_DESC_SIZ,0x00,/* wTotalLength: Bytes returned = 41U,0x00 */0x01,/*bNumInterfaces: 1 interface*/0x01,/*bConfigurationValue: Configuration value*/0x00,/*iConfiguration: Index of string descriptor describing the configuration*/0xC0,/*bmAttributes: bus powered */0x32,/*MaxPower 100 mA: this current is used for detecting Vbus*//************** Descriptor of CUSTOM HID interface *****************************/ /* 09 */0x09,/*bLength: Interface Descriptor size*/USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type = 0x04U */0x00,/*bInterfaceNumber: Number of Interface*/0x00,/*bAlternateSetting: Alternate setting*/0x02,/*bNumEndpoints*/0x03,/*bInterfaceClass: CUSTOM_HID*/0x00,/*bInterfaceSubClass : 1=BOOT, 0=no boot*/0x00,/*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/0,/*iInterface: Index of string descriptor*//******************** Descriptor of CUSTOM_HID *********************************/ /* 18 */0x09,/*bLength: CUSTOM_HID Descriptor size*/CUSTOM_HID_DESCRIPTOR_TYPE,/*bDescriptorType: CUSTOM_HID = 0x21U*/0x11,/*bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number*/0x01,0x00,/*bCountryCode: Hardware target country*/0x01,/*bNumDescriptors: Number of CUSTOM_HID class descriptors to follow*/0x22,/*bDescriptorType*/USBD_CUSTOM_HID_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor = 53 */0x00,/******************** Descriptor of Custom HID endpoints **********************/ /* 27 */0x07,/*bLength: Endpoint Descriptor size*/USB_DESC_TYPE_ENDPOINT,/*bDescriptorType: = 0x05U */CUSTOM_HID_EPIN_ADDR,/*bEndpointAddress: Endpoint Address (IN) = 0x81U */0x03,/*bmAttributes: Interrupt endpoint*/CUSTOM_HID_EPIN_SIZE,0x00,/*wMaxPacketSize: 2 Byte max = 0x40U,0x00 */CUSTOM_HID_FS_BINTERVAL,/*bInterval: Polling Interval = 0x5 *//*****************************************************************************/* 34 */0x07,/* bLength: Endpoint Descriptor size */USB_DESC_TYPE_ENDPOINT,/* bDescriptorType: = 0x05U */CUSTOM_HID_EPOUT_ADDR,/*bEndpointAddress: Endpoint Address (OUT) = 0x01U */0x03,/* bmAttributes: Interrupt endpoint */CUSTOM_HID_EPOUT_SIZE,0x00,/* wMaxPacketSize: 2 Bytes max = 0x40U,0x00 */CUSTOM_HID_FS_BINTERVAL,/* bInterval: Polling Interval = 0x5 *//*****************************************************************************/* 41 */};I set HID Report descriptor in usbd_custom_hid.c like this :Code:/** Usb HID report descriptor. */__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS __ALIGN_END = {/* USER CODE BEGIN 0 */0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */0x09, 0x05, /* USAGE (Game Pad) */0xa1, 0x01, /* COLLECTION (Application) */0xa1, 0x03, /* COLLECTION (Report) */0x85, 0x01, /* REPORT_ID (1) */0x05, 0x09, /* USAGE_PAGE (Button) */0x19, 0x01, /* USAGE_MINIMUM (Button 1) */0x29, 0x0e, /* USAGE_MAXIMUM (Button 14) */0x15, 0x00, /* LOGICAL_MINIMUM (0) */0x25, 0x01, /* LOGICAL_MAXIMUM (1) */0x95, 0x0e, /* REPORT_COUNT (14) */0x75, 0x01, /* REPORT_SIZE (1) */0x81, 0x02, /* INPUT (Data,Var,Abs) */0x95, 0x01, /* REPORT_COUNT (1) */0x75, 0x02, /* REPORT_SIZE (2) */0x81, 0x03, /* INPUT (Cnst) */0xa1, 0x00, /* COLLECTION (Physical) */0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */0x09, 0x30, /* USAGE (X) */0x09, 0x31, /* USAGE (Y) */0x15, 0x00, /* LOGICAL_MINIMUM (0) */0x25, 0x64, /* LOGICAL_MAXIMUM (100) */0x75, 0x08, /* REPORT_SIZE (8) */0x95, 0x02, /* REPORT_COUNT (2) */0x81, 0x02, /* INPUT (Data,Var,Abs) */0xc0, /* END_COLLECTION */0xc0, /* END_COLLECTION */0xC0 /* END_COLLECTION*//********************* 53 **************************//* USER CODE END 0 */};And in the main.c , i wrote a simple loop that sends 4 Bytes , which corresponds to 14 buttons , X Axis and Y Axis :Code:...extern USBD_HandleTypeDef hUsbDeviceFS;uint8_t buffer={0,0,0,0};int main(void){HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_USB_DEVICE_Init();while (1){buffer=0xff;buffer=0x00;buffer=0xff;buffer=0x00;USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, buffer, sizeof(buffer));HAL_Delay(1000);}}...When i plug the USB , the game-pad is detected on my Linux :Code:May 21 17:57:44 kernel: [16166.179757] input: STMicroelectronics STM32 Custom Human interface as /devices/pci0000:00/0000:00:14.0/usb1/1-3/1-3:1.0/0003:0483:575A.0011/input/input34May 21 17:57:44 kernel: [16166.233467] hid-generic 0003:0483:575A.0011: input,hidraw5: USB HID v1.11 Gamepad [STMicroelectronics STM32 Custom Human interface] on usb-0000:00:14.0-3/input0May 21 17:57:44 mtp-probe: checking bus 1, device 24: "/sys/devices/pci0000:00/0000:00:14.0/usb1/1-3"But no activity is shown in Joystick viewer UI ( jstest-gtk ) :https://i.ibb.co/VJtrGt3/jstest.png(Sorry. Image attachement through forum not working for me somehow )The lsusb -v looks like this :Code:Device Descriptor:bLength 18bDescriptorType 1bcdUSB 2.00bDeviceClass 0 (Defined at Interface level)bDeviceSubClass 0bDeviceProtocol 0bMaxPacketSize0 64idVendor 0x0483 STMicroelectronicsidProduct 0x575abcdDevice 2.00iManufacturer 1iProduct 2iSerial 3bNumConfigurations 1Configuration Descriptor:bLength 9bDescriptorType 2wTotalLength 41bNumInterfaces 1bConfigurationValue 1iConfiguration 0bmAttributes 0xc0Self PoweredMaxPower 100mAInterface Descriptor:bLength 9bDescriptorType 4bInterfaceNumber 0bAlternateSetting 0bNumEndpoints 2bInterfaceClass 3 Human Interface DevicebInterfaceSubClass 0 No SubclassbInterfaceProtocol 0 NoneiInterface 0HID Device Descriptor:bLength 9bDescriptorType 33bcdHID 1.11bCountryCode 0 Not supportedbNumDescriptors 1bDescriptorType 34 ReportwDescriptorLength 53Report Descriptors:** UNAVAILABLE **Endpoint Descriptor:bLength 7bDescriptorType 5bEndpointAddress 0x81 EP 1 INbmAttributes 3Transfer Type InterruptSynch Type NoneUsage Type DatawMaxPacketSize 0x0040 1x 64 bytesbInterval 5Endpoint Descriptor:bLength 7bDescriptorType 5bEndpointAddress 0x01 EP 1 OUTbmAttributes 3Transfer Type InterruptSynch Type NoneUsage Type DatawMaxPacketSize 0x0040 1x 64 bytesbInterval 5I even did capture usb packet for it , and i do see the data coming in :https://i.ibb.co/4PPTH9G/capture.png(Sorry. Image attachement through forum not working for me somehow )I'm not sure what I'm missing. I would appreacate any help .Thanks in advance .

author: foxmjay
author_rank: Contributor
timestamp: May 22, 2020, 08:11:06 pm
content: It Appears that something was wrong in the Report Descriptor . It's working now after i rewrote it like this :Code:__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS __ALIGN_END ={/* USER CODE BEGIN 0 */0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */0x09, 0x05, /* USAGE (Game Pad) */0xa1, 0x01, /* COLLECTION (Application) */0xa1, 0x00, /* COLLECTION (Physical) */0x05, 0x09, /* USAGE_PAGE (Button) */0x19, 0x01, /* USAGE_MINIMUM (Button 1) */0x29, 0x0e, /* USAGE_MAXIMUM (Button 14) */0x15, 0x00, /* LOGICAL_MINIMUM (0) */0x25, 0x01, /* LOGICAL_MAXIMUM (1) */0x95, 0x0e, /* REPORT_COUNT (14) */0x75, 0x01, /* REPORT_SIZE (1) */0x81, 0x02, /* INPUT (Data,Var,Abs) */0x95, 0x01, /* REPORT_COUNT (1) */0x75, 0x02, /* REPORT_SIZE (2) */0x81, 0x03, /* INPUT (Cnst) */0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */0x09, 0x30, /* USAGE (X) */0x09, 0x31, /* USAGE (Y) */0x15, 0x00, /* LOGICAL_MINIMUM (0) */0x25, 0x64, /* LOGICAL_MAXIMUM (100) */0x75, 0x08, /* REPORT_SIZE (8) */0x95, 0x02, /* REPORT_COUNT (2) */0x81, 0x02, /* INPUT (Data,Var,Abs) */0xc0, /*END_COLLECTION *//* USER CODE END 0 */0xC0 /* END_COLLECTION*/};And I'm testing like this in main.c :Code:...int main(void){/* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* Configure the system clock */SystemClock_Config();/* Initialize all configured peripherals */MX_GPIO_Init();MX_USB_DEVICE_Init();while (1) {if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == GPIO_PIN_RESET){HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13,GPIO_PIN_SET);buffer = 0xff; //Buttonsbuffer= 0xff; // Buttonsbuffer=100; // X Axisbuffer=100; // Y AxisUSBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, buffer, sizeof(buffer));}else{HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13,GPIO_PIN_RESET);}buffer=0x00; //Buttonsbuffer=0x00; //Buttonsbuffer=0; // X Axisbuffer=0; // Y AxisUSBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, buffer, sizeof(buffer));HAL_Delay(10);}}...