Author Topic: Need help with STM32f103C8 USB HID Joystick  (Read 3981 times)

0 Members and 1 Guest are viewing this topic.

Offline foxmjayTopic starter

  • Contributor
  • Posts: 13
  • Country: ma
Need help with STM32f103C8 USB HID Joystick
« on: May 21, 2020, 06:30:13 pm »
Hi All,
   I've been trying to make a USB HID Joystick with the STM32f103C8 ( The Blue Pill ) but without  luck ! |O .
   
    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: [Select]
/* USB CUSTOM_HID device FS Configuration Descriptor */
__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgFSDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __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: [Select]

/** Usb HID report descriptor. */
__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __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: [Select]
...
extern USBD_HandleTypeDef hUsbDeviceFS;
uint8_t buffer[4]={0,0,0,0};

int main(void){
 
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_USB_DEVICE_Init();

  while (1){

     buffer[0]=0xff;
     buffer[1]=0x00;
     buffer[2]=0xff;
     buffer[3]=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: [Select]
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/input34
May 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/input0
May 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: [Select]
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  idVendor           0x0483 STMicroelectronics
  idProduct          0x575a
  bcdDevice            2.00
  iManufacturer           1
  iProduct                2
  iSerial                 3
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           41
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0xc0
      Self Powered
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 No Subclass
      bInterfaceProtocol      0 None
      iInterface              0
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      53
         Report Descriptors:
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               5
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               5


I 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 .

« Last Edit: May 21, 2020, 06:33:10 pm by foxmjay »
 

Offline foxmjayTopic starter

  • Contributor
  • Posts: 13
  • Country: ma
Re: Need help with STM32f103C8 USB HID Joystick
« Reply #1 on: May 22, 2020, 08:11:06 pm »
It Appears that something was wrong in the Report Descriptor . It's working now after i rewrote it like this :

Code: [Select]
__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __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: [Select]
...
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[0] = 0xff;   //Buttons
buffer[1]= 0xff;   // Buttons
buffer[2]=100;    //  X Axis
buffer[3]=100;    // Y Axis
    USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, buffer, sizeof(buffer));
}else{
  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13,GPIO_PIN_RESET);
}

  buffer[0]=0x00;  //Buttons
  buffer[1]=0x00;  //Buttons
  buffer[2]=0;       //  X Axis
  buffer[3]=0;       //  Y Axis

  USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, buffer, sizeof(buffer));
  HAL_Delay(10);
  }
}
...
 
The following users thanked this post: thm_w


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf