본문 바로가기

[STM32F746G-DISCO] USB 키보드로 사용하기 (Device Mode)

by rudals.kim 2024. 7. 15. 댓글 개
반응형
아래 테스트는 STM32CubeIDE 1.6.1/STM32Cube_FW_F7_V1.16.1를 사용하여 테스트 되었습니다.


STM32F746G-DISCO 보드에는 USB FS/HS 단자가 있습니다.
이중 FS 포트를 사용하여 USB Device Mode에서 키보드 테스트를 해 보았습니다.


STM32CubeIDE에서 새 프로젝트를 생성 후 핀 초기화 후 SYS/USART1/I2C3/USB_OTG_FS/USB_DEVICE만 설정하였습니다.

USB_DEVICE관련 설정은 기본값을 사용하였습니다.

가장 중요한 설정이 클럭 설정인데 USB 디바이스는 48MHz를 사용해야 합니다.

소스코드를 빌드하여 보드에 다운로드를 해 보았습니다.
정상적으로 다운로드가 된것을 확인한 후 Micro USB 케이블을 CN13(USB_FS) 단자에 꽂습니다.
아래와 같이 윈도우 PC에서 STM32F746G-DISCO 보드를 정상적인 HID로 인식하였습니다.

제어판의 '장치 및 프린터'를 보면 'STM32 Human Interface' 이름의 키보드가 추가된 것을 확인할 수 있습니다.

또는 설정의 장치 항목을 보면 아래와 같이 등록되어져 있습니다.

STM32F746G-DISCO 보드가 HID 키보드 장치로 등록만 되어 있을 뿐 다른 기능은 추가하지 않아 실질적인 키보드로써의 기능은 없습니다. 그래서 STM32F746G-DISCO 보드에서 키보드 값을 전송하여 간단한 문자열을 찍는 테스트를 해 보았습니다.

현재 middleware의 STM32_USB_Device_Library는 기본적으로 usb descriptor가 mouse로 설정됩니다.
키보드로 사용하기 위해서는 이 descriptor를 변경해야 하는데 아래를 참고하시기 바랍니다.
(키보드용 descriptor를 새로 만들어서 적용해야 하는데 귀찮아서 기존 mouse 데이터를 삭제 후 대체해 넣었습니다.)

usbd_hid.h를 아래와 같이 수정하였습니다.

//#define HID_MOUSE_REPORT_DESC_SIZE  74U
#define HID_MOUSE_REPORT_DESC_SIZE  45U


usbd_hid.c의 HID_MOUSE_ReportDesc를 아래와 같이 변경하였습니다.

  0x05, 0x01, // USAGE_PAGE (Generic Desktop)
  0x09, 0x06, // USAGE (Keyboard)
  0xa1, 0x01, // COLLECTION (Application)
  0x05, 0x07, // USAGE_PAGE (Keyboard)
  0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
  0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
  0x15, 0x00, // LOGICAL_MINIMUM (0)
  0x25, 0x01, // LOGICAL_MAXIMUM (1)
  0x75, 0x01, // REPORT_SIZE (1)
  0x95, 0x08, // REPORT_COUNT (8)
  0x81, 0x02, // INPUT (Data,Var,Abs) //1 byte
  0x95, 0x01, // REPORT_COUNT (1)
  0x75, 0x08, // REPORT_SIZE (8)
  0x81, 0x03, // INPUT (Cnst,Var,Abs) //1 byte
  0x95, 0x06, // REPORT_COUNT (6)
  0x75, 0x08, // REPORT_SIZE (8)
  0x15, 0x00, // LOGICAL_MINIMUM (0)
  0x25, 0x65, // LOGICAL_MAXIMUM (101)
  0x05, 0x07, // USAGE_PAGE (Keyboard)
  0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
  0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
  0x81, 0x00, // INPUT (Data,Ary,Abs) //6 bytes
  0xc0 // END_COLLECTION


USB용 키보드값이 정의된 파일입니다.
(참고 URL : https://gist.githubusercontent.com/MightyPork/6da26e382a7ad91b5496ee55fdc73db2/raw/e91b2eca00fdf3d8b51a4dddc658913d2baa40e0/usb_hid_keys.h)

usb_hid_keys.h
0.01MB


전송을 위해 아래 함수를 사용하였습니다.

buffer[0] : modifier
buffer[1] : reserved
buffer[7..2] : keycodes

이렇게 데이터를 넣어 전송 후 buffer[2] = 0x0을 넣어 키보드가 눌렸다가 떼어졌음을 알려줍니다.

uint8_t buffer[9];
void keycode_write(uint8_t ch){
    buffer[2] = ch;
    USBD_HID_SendReport(&hUsbDeviceFS,buffer,sizeof(buffer));
    HAL_Delay(50);

    buffer[2] = 0x0;
    USBD_HID_SendReport(&hUsbDeviceFS,buffer,sizeof(buffer));
    HAL_Delay(50);
}


HID에 대한 자세한 사항은 USB 1.1 데이터시트를 참고하시기 바랍니다.
(참고 : https://www.usb.org/sites/default/files/hid1_11.pdf)

빌드 & 다운로드를 한 후 Micro USB 케이블을 CN13(USB_FS) 단자에 꽂습니다.
테스트를 해 보면 아래와 같이 "Hello World"가 제대로 출력되고 있습니다.

코드를 좀 더 수정하여 한/영 키보드 전환 동작을 추가해 보았습니다.



반응형

댓글