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ファイルで以下の設定をしましょう。
ConnectivityのUSB_OTG_FSタブを開いてModeをHost_Onlyにしましょう。
SpeedをHost Low Speed 1.5MBit/sにしましょう。(全然この速度でも高速で読めるのでLow Speedにしました。)
クロックの設定はこんな感じです。これは外部クロックに8MHzを使った場合です。各自で外部クロックに合わせて、To USBに48MHzが供給されるように設定しましょう。
設定は以上です。
コードをジェネレートしてください。
プログラム
新しくソースフォルダ「usbh_hid_unknown」を作成してください。
このフォルダを右クリックして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行目付近
#include "usbh_hid_mouse.h"
#include "usbh_hid_keybd.h"
+ #include "usbh_hid_unknown.h"
/** @addtogroup USBH_LIB
usbh_hid.hの252行目付近
/* 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行目付近
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行目付近
else
{
- USBH_UsrLog("Protocol not supported.");
- return USBH_FAIL;
+ USBH_UsrLog("Unknown device found!");
+ HID_Handle->Init = USBH_HID_UnknownInit;
}
main.cで
#include "usb_host.h"
#include "usbh_core.h"
#include "usbh_hid.h"
上記をインクルードしてUSER CODE BEGIN 0に
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 |
実行
デバッグを開始し、Live Expressionにgamepad_data
と入力して中身を見ると、ゲームパッドの各データをあります。比較的わかりやすいデータ構造なので各自で解読して使ってください。