Hiển thị các bài đăng có nhãn STM32 USB-HID. Hiển thị tất cả bài đăng
Hiển thị các bài đăng có nhãn STM32 USB-HID. Hiển thị tất cả bài đăng

Thứ Năm, 28 tháng 7, 2016

STM32 USB-HID

KHỞI TẠO USB HID STM32F103C8T6 ĐƠN GIẢN BẰNG STM32CUBEMX

1. Hardware

Kit STM32F103C8T6


Schematic kit


2. Khởi tạo STM32CubeMx

STEP 1:

Vào chương trình STM32CubeMX -> Chon Create new project. -> Chọn MCU STM32F103C8Tx( STM32F103C8T6).



STEP 2:

Trong muc Pinout.

 Peripherals => USB => Tick vào Device(FS)

 Middlewares=> Custom Human Interface Device Class(HID).




 STEP 3:

Trong mục Pinout.

Peripherals => RCC => High Speed Clock (HSE) =>Chọn => Crytal/Ceramic Resonator.



STEP 4:

Trong mục Clock configuration.

Config Clock USB => 48Mhz.



STEP 5:

Trong mục Configuration.

Trong cửa sổ chính => Connectivity => USB.



STEP 6:

Xuất hiện hôp thoại USB Configuration => Tab Parameter settings => Basic parameters =>  Endpoint 0 Max Packet size => 64 byte. (Maximum gói data endpoint 0 là 64 byte)



STEP 7: 

Trong mục Configuration.

Trong cửa sổ chính => Middlewares =>USB_DEVICE.



STEP 8:

Xuất hiện hôp thoại USB_DEVICE Configuration => Tab Parameter settings => Class parameters :
  • USBD_CUSTOM_HID_REPORT_DESC_SIZE (Total length for Report descriptor (IN ENDPOINT)): 32 (32 byte mô tả report input).
  • USBD_CUSTOMHID_OUTREPORT_BUF_SIZE (Maximum report buffer size (OUT ENDPOINT)): 64 ( maximum 64 byte buffer report output ).



STEP 9:

Xuất hiện hôp thoại USB_DEVICE Configuration => Tab Device Descriptor => Device Descriptor FS => PRODUCT_STRING (Product Identifier) =>Đổi Product string USB HID.


3. Config file mô tả USB HID (USB HID Report Descriptor).




  • Trong file usbd_custom_hid_if.c



__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
{
  /* USER CODE BEGIN 0 */ 
  0x00, 
  /* USER CODE END 0 */ 
  0xC0    /*     END_COLLECTION             */
 
};

Sửa thành=====>

__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
{
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    0x09, 0x00,                    // USAGE (Undefined)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255)
    0x85, 0x01,                    //   REPORT_ID (1) //report id input là 0x01
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x95, 0x3F,                    //   REPORT_COUNT (63)//report input gồm có 63 byte data và một byte ID=0x01
    0x09, 0x00,                    //   USAGE (Undefined)
    0x81, 0x82,                    //   INPUT (Data,Var,Abs,Vol) - to the host
    0x85, 0x02,                    //   REPORT_ID (2)//report id output là 0x02
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x95, 0x3F,                    //   REPORT_COUNT (63)//report output gồm có 63 byte data và một byte ID=0x02
    0x09, 0x00,                    //   USAGE (Undefined)
    0x91, 0x82,                    //   OUTPUT (Data,Var,Abs,Vol) - from the host
    0xc0                           // END_COLLECTION
};

USBD_CUSTOM_HID_REPORT_DESC_SIZE: 32 byte mô tả đã config trên soft STM32CubeMX.

  • Trong file usb_customhid.h


#define CUSTOM_HID_EPIN_ADDR                 0x81
#define CUSTOM_HID_EPIN_SIZE                 0x02

#define CUSTOM_HID_EPOUT_ADDR                0x01
#define CUSTOM_HID_EPOUT_SIZE                0x02

Sửa thành===>

#define CUSTOM_HID_EPIN_ADDR                 0x81
#define CUSTOM_HID_EPIN_SIZE                 64

#define CUSTOM_HID_EPOUT_ADDR                0x01
#define CUSTOM_HID_EPOUT_SIZE                64
///////////////////////////////

4. Send và Receive data.

  •  Send data:

uint8_t USBD_CUSTOM_HID_SendReport     (USBD_HandleTypeDef  *pdev, uint8_t *report, uint16_t len);
VD: 

uint8_t data[64];

data[0]=0x01;  //report id input là 0x01, byte đầu tiên phải là report id.

USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS,data,64); 

Khi config USBD_CUSTOM_HID_REPORT_DESC_SIZE=64 thì gửi gói data luôn có len=64.

Note: Nếu muốn gửi và nhận gói data >64 byte VD 128 byte có thể sửa như sau:

USBD_CUSTOM_HID_REPORT_DESC_SIZE=128

CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
{
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    0x09, 0x00,                    // USAGE (Undefined)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255)
    0x85, 0x01,                    //   REPORT_ID (1) //report id input là 0x01
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x95, 127,                    //   REPORT_COUNT (127)//report input gồm có 127 byte data và một byte ID=0x01
    0x09, 0x00,                    //   USAGE (Undefined)
    0x81, 0x82,                    //   INPUT (Data,Var,Abs,Vol) - to the host
    0x85, 0x02,                    //   REPORT_ID (2)//report id output là 0x02
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x95, 127,                    //   REPORT_COUNT (127)//report output gồm có 127 byte data và một byte ID=0x02
    0x09, 0x00,                    //   USAGE (Undefined)
    0x91, 0x82,                    //   OUTPUT (Data,Var,Abs,Vol) - from the host
    0xc0                           // END_COLLECTION
};

uint8_t data[128];

data[0]=0x01;  //report id input là 0x01, byte đầu tiên phải là report id.

USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS,data,128); 

  • Receive data:

 Trong file usbd_customhid.c thêm vào phần màu đỏ:

uint8_t My_Buffer[USBD_CUSTOMHID_OUTREPORT_BUF_SIZE];

static uint8_t  USBD_CUSTOM_HID_DataOut (USBD_HandleTypeDef *pdev,
                              uint8_t epnum)
{

  USBD_CUSTOM_HID_HandleTypeDef     *hhid = (USBD_CUSTOM_HID_HandleTypeDef*)pdev->pClassData;

 ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->OutEvent(hhid->Report_buf[0],         hhid->Report_buf[1]);
///////////////////////////////
for(uint8_t i=0;i<64;i++)
{
    My_Buffer[i]=hhid->Report_buf[i];  //gán buffer Report_buf vào My_Buffer để truy xuất data.
}
//////////////////
  USBD_LL_PrepareReceive(pdev, CUSTOM_HID_EPOUT_ADDR , hhid->Report_buf,
                         USBD_CUSTOMHID_OUTREPORT_BUF_SIZE);

  return USBD_OK;
}

5. Example code:


  •   Code nhận data và gửi data đã nhận lên máy tính. Test bằng phần mềm USB HID Demonstrator(v1.02)

  /////////////////////////////////////////////////
  uint8_t data[64];
  data[0]=0x01;
  while (1)
  {
if(check_usb==1)
{
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
for(uint8_t i=1;i<64;i++)
{
    data[i]=My_Buffer[i];
}
USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS,data,64);   
check_usb=0;
}
  }
  /////////////////////////////////////////////
Link demo code:
https://drive.google.com/file/d/0B9pHWA4exz3gU3lzZDBlMWExMGM/view?usp=sharing

USB HID Demonstrator(v1.02): https://drive.google.com/file/d/0B9pHWA4exz3gNWNGak9zY1dVakU/view?usp=sharing

Video demo: