2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

STM32 NUCLEO-F446REでGamepadを読む方法

Posted at

STM32 NUCLEO-F446REにはUSBのホスト機能がありますが、HIDデバイスは標準でマウスとキーボードにしか対応していません。それを有線コントローラーに対応させる方法について書きました(この方法でコントローラー以外のHIDデバイスも対応できます)。

必要なもの

  • STM32 NUCLEO-F446RE

STM32 NUCLEO-F446REでUSB機能を使うには外部クロックが必要です。
各自用意してください。

  • HID Gamepad(有線)
    自分はELECOMのJC-GP20SBKを使いました。おすすめです。

XInputは基本的に読めないので、DirectInputモードで読みましょう。
LogicoolのF310など、DirectInputでも読めない機種もあります。
(恐らくHIDのプロトコルに完全に準拠しているわけではないことが原因)

  • USB Type-Aメス端子
  • STM32 CubeIDE

設定

まずCubeIDEを開いて新しくF446REのプロジェクトを作成してください。
iocファイルで以下の設定をしましょう。
1.png
ConnectivityのUSB_OTG_FSタブを開いてModeをHost_Onlyにしましょう。

2.png
SpeedをHost Low Speed 1.5MBit/sにしましょう。(全然この速度でも高速で読めるのでLow Speedにしました。)

5.png
クロックの設定はこんな感じです。これは外部クロックに8MHzを使った場合です。各自で外部クロックに合わせて、To USBに48MHzが供給されるように設定しましょう。

設定は以上です。
コードをジェネレートしてください。

プログラム

6.png
新しくソースフォルダ「usbh_hid_unknown」を作成してください。

7.png
このフォルダを右クリックしてAdd/remove include pathを押してそのままOKしてください。

そして上のリンクのusbh_hid_unknown.cとusbh_hid_unknown.hをこのフォルダに入れてください。

次にプロジェクト内のMiddlewares\ST\STM32_USB_Host_Library\Class\HIDのIncとSrcを開き、usbh_hid.hとusbh_hid.cを編集します。

iocファイルを変更するとusbh_hid.hとusbh_hid.cの中身が元に戻ってしまうため、その都度編集してください。

usbh_hid.hの31行目付近

usbh_hid.h
#include "usbh_hid_mouse.h"
#include "usbh_hid_keybd.h"
+ #include "usbh_hid_unknown.h"

/** @addtogroup USBH_LIB

usbh_hid.hの252行目付近

usbh_hid.h

/* Interface Descriptor field values for HID Boot Protocol */
- #define HID_BOOT_CODE                                 0x01U
+ #define HID_BOOT_CODE                                 0xFFU
#define HID_KEYBRD_BOOT_CODE                          0x01U
#define HID_MOUSE_BOOT_CODE                           0x02U

usbh_hid.cの109行目付近

usbh_hid.c
extern USBH_StatusTypeDef USBH_HID_MouseInit(USBH_HandleTypeDef *phost);
extern USBH_StatusTypeDef USBH_HID_KeybdInit(USBH_HandleTypeDef *phost);
+ extern USBH_StatusTypeDef USBH_HID_UnknownInit(USBH_HandleTypeDef *phost);

USBH_ClassTypeDef  HID_Class =

usbh_hid.cの189行目付近

usbh_hid.c
  else
  {
-     USBH_UsrLog("Protocol not supported.");
-     return USBH_FAIL;
+ 	  USBH_UsrLog("Unknown device found!");
+ 	  HID_Handle->Init = USBH_HID_UnknownInit;
  }

main.cで

main.c
#include "usb_host.h"
#include "usbh_core.h"
#include "usbh_hid.h"

上記をインクルードしてUSER CODE BEGIN 0に

main.c
uint8_t gamepad_data[USBH_HID_UNKNOWN_REPORT_SIZE];
void USBH_HID_EventCallback(USBH_HandleTypeDef *phost)
{
    HID_TypeTypeDef hidType;
    uint8_t* unknown_info;

    hidType = USBH_HID_GetDeviceType(phost);
    if(hidType == HID_UNKNOWN){
    	unknown_info = USBH_HID_GetUnknownInfo(phost);
    	for(int i = 0; i < sizeof(gamepad_data); i ++){
    		gamepad_data[i] = unknown_info[i];
    	}
    }
}

を書いてください。

Let's read ゲームパッド

配線

F446RE Type-A
VDD VCC
PA12 D+
PA11 D-
GND GND

Image.jpg
こんな感じ

Image (1).jpg
DirectInputにするのを忘れずに

実行

デバッグを開始し、Live Expressionにgamepad_dataと入力して中身を見ると、ゲームパッドの各データをあります。比較的わかりやすいデータ構造なので各自で解読して使ってください。
スクリーンショット 2024-10-09 164954.png

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?