mbedを使ってSTM32-NUCLEOのUSBを動かす

最近(2017年)になって、STが開発したmbed向けSTM32 USBライブラリが公開されていたので試してみました。

STM32-NUCLEOで USB ライブラリ [USBDEVICE](https://developer.mbed.org/teams/ST/code/USBDEVICE/) と [USBHOST](https://developer.mbed.org/teams/ST/code/USBHOST) の動作が確認できました。

秋月電子で購入できる部品を使いました。

* [NUCLEO-F411RE](http://www.st.com/en/evaluation-tools/nucleo-f411re.html)
* [ブレッドボード用マイクロＢメスＵＳＢコネクタＤＩＰ化キット](http://akizukidenshi.com/catalog/g/gK-06656/)
* [ＵＳＢコネクタＤＩＰ化キット　（Ａメス）](http://akizukidenshi.com/catalog/g/gK-07429/)

![20170716_123033571_iOS.jpg](https://qiita-image-store.s3.amazonaws.com/0/42120/43b44247-c861-8697-6f89-de1acf7d95eb.jpeg)
![20170716_110702234_iOS.jpg](https://qiita-image-store.s3.amazonaws.com/0/42120/ff5161b7-f547-337a-9e49-5eb3fc5499aa.jpeg)

# USB Device
STM32をUSB Deviceとして使います。
## Hardware
STM32-NUCLEO と マイクロＢメスＵＳＢコネクタを接続します。

| STM32-NUCLEO | USB |
|:-:|:-:|
| PA11 (CN10-14) | D-  |
| PA12 (CN10-12) | D+  |
| GND (CN10-20)  | GND |

VBUSの電源はNUCLEOのST-LINK側のUSBから供給しているので未接続です。

ST-LINK側のUSBを繋いでいない場合は、「U5V (CN10-8) 」と「 VBUS 」を繋げてください。

NUCLEO_F103RBを使う場合はD+を1.5kohmでプルアップしくださいとの記載が、[ソースコードにコメント](https://github.com/ARMmbed/mbed-os/blob/mbed-os-5.5/features/unsupported/USBDevice/USBDevice/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/USBHAL_STM32F103RB.h)してありました。

## Software
[Nucleo_usbmouse](https://developer.mbed.org/teams/ST/code/Nucleo_usbmouse/)をコンパイルして書き込む。

Nucleo_usbhostはUSBメモリとマウスとキーボードが動作します。起動時に刺してあるデバイスに応じて動作します。

このデモはUSB HID マウスを使ってカーソルを円を描くように移動させます。

使用したソフトのリビジョンです。

| Name | hash |
|:-:|:-:|
| [ST/Nucleo_usbmouse](https://developer.mbed.org/teams/ST/code/Nucleo_usbmouse/)  | b6e9ca6a0bf6   |
| [ST/USBDEVICE](https://developer.mbed.org/teams/ST/code/USBDEVICE/)  | 50ec00aa4515   |
| mbed  | 22da6e220af6 (Relase146)  |

FLASH:38.8KB RAM:3.6KB

## Result
PCに挿すとマウスとして認識されてカーソルがクルクル回りました。

シリアルポート出力結果

```
cos: 5000.000000, sin: 0.000000
cos: 4993.154618, sin: 705.600040
cos: 4972.637216, sin: -1397.077491
cos: 4938.503974, sin: 2060.592426
cos: 4890.848353, sin: -2682.864590
cos: 4829.800843, sin: 3251.439201
cos: 4755.528600, sin: -3754.936234
cos: 4668.234993, sin: 4183.278193
cos: 4568.159046, sin: -4527.891810
cos: 4455.574781, sin: 4781.879642
cos: 4330.790472, sin: -4940.158120
cos: 4194.147797, sin: 4999.559301
cos: 4046.020905, sin: -4958.894267
```

# USB Host
STM32をUSB Hostとして使います。

## Hardware
STM32-NUCLEO と ＡメスＵＳＢコネクタを接続します。

| STM32-NUCLEO | USB |
|:-:|:-:|
| U5V (CN10-8)   | VBUS  |
| PA11 (CN10-14) | D-  |
| PA12 (CN10-12) | D+  |
| GND (CN10-20)  | GND |

## Software
[Nucleo_usbhost](https://developer.mbed.org/teams/ST/code/Nucleo_usbhost/)をコンパイルして書き込む。

Nucleo_usbhostはUSBメモリとマウスとキーボードが動作します。USBコネクタに挿したデバイスに応じて動作します。

Nucleo_usbhostはThreadを使っているので、mbed　os 5を使ってます。

使用したソフトのリビジョンです。

| Name | hash |
|:-:|:-:|
| [ST/Nucleo_usbhost](https://developer.mbed.org/teams/ST/code/Nucleo_usbhost/)  | 2ca820a42fd5  |
| [ST/USBHOST](https://developer.mbed.org/teams/ST/code/USBHOST)  | d3ac9e1c0035  |
| mbed-os  | 42be5c0 (mbed-os-5.4.3)  |

FLASH:67.5KB RAM:12.3KB

## Result

起動後に抜き差しして、別デバイスをさしても動作していました。

マウスを挿して、ボタンを押したり、動かすとシリアルに出力されます。

```
 [USB_INFO: /src/USBHOST/USBHost/USBHost.cpp:169]New device connected: 2000680c [hub: 0 - port: 1]
 [USB_INFO: /src/USBHOST/USBHostHID/USBHostMouse.cpp:72]New Mouse device: VID:046d PID:c06c [dev: 2000680c - intf: 0]
 buttons: 0, x: 1, y: -1, z: 0
 buttons: 0, x: 50, y: -39, z: 0
 buttons: 0, x: 82, y: -38, z: 0
 buttons: 0, x: 23, y: -31, z: 0
 buttons: 0, x: 7, y: -64, z: 0
 buttons: 0, x: 15, y: -52, z: 0
 buttons: 0, x: 8, y: -21, z: 0
 buttons: 1, x: 0, y: 0, z: 0
 ..
 [USB_INFO: /src/USBHOST/USBHost/USBHost.cpp:491]Device disconnected [2000680c - Mouse - hub: 0 - port: 1]
 mouse seen disconnected
```

キーボードを挿して、キーを押すとシリアルに出力されます。

```
 [USB_INFO: /src/USBHOST/USBHost/USBHost.cpp:169]New device connected: 2000680c [hub: 0 - port: 1]
 [USB_INFO: /src/USBHOST/USBHostHID/USBHostKeyboard.cpp:127]New Keyboard device: VID:413c PID:2107 [dev: 2000680c - intf: 0]
 Key: j
 Key: j
 Key: a
 Key: b
 Key: c
 Key: d
 Key: e
 Key: f
 Key: g
```
USBメモリを挿すと下記が表示されましたが、途中でエラーになって止まりました。Capacityの値が異常でした。

```
 USB_INFO: /src/USBHOST/USBHost/USBHost.cpp:169]New device connected: 2000680c [hub: 0 - port: 1]
 [USB_INFO: /src/USBHOST/USBHostMSD/USBHostMSD.cpp:88]New MSD device: VID:13fe PID:1f23 [dev: 2000680c - intf: 0]
 file system mounted
                    [USB_INFO: /src/USBHOST/USBHostMSD/USBHostMSD.cpp:175]MSD [dev: 2000680c] - Vendor ID: silicon
 [USB_INFO: /src/USBHOST/USBHostMSD/USBHostMSD.cpp:179]MSD [dev: 2000680c] - Product ID: -power
 [USB_INFO: /src/USBHOST/USBHostMSD/USBHostMSD.cpp:183]MSD [dev: 2000680c] - Product rev: 0.00
 [USB_INFO: /src/USBHOST/USBHostMSD/USBHostMSD.cpp:148]MSD [dev: 2000680c] - blockCount: 7827455, blockSize: 512, Capacity: -287310336
```
# 感想、その他
* 本当にUSBが動くのか半信半疑でしたが、すんなりと動きました。
* 最初はOkamotoさんが作った[F401RE-USBHost](https://developer.mbed.org/users/va009039/code/F401RE-USBHost/)を使おうと思って調べてる途中で、今回のST製のライブラリの存在を知りました。mbedのライブラリの情報を探すのは難しいですね。
* STM32のOTG-FSコントローラを使う場合はマイコンの端子とD+とD-とGNDを繋げば動くことが分かった。（D+のプルアップはマイコンに内蔵されている。)
* USBのライブラリがmbed-osのソースツリーの[features/unsupported](https://github.com/ARMmbed/mbed-os/tree/mbed-os-5.5/features/unsupported)にある意図が良く分からない。mbed os 5としては現状は非サポートという意味のような気がします。Renesas AZ1用のUSBライブラリもRenesasがPublishしている。待っていればそのうちmbed os でサポートされるようになるでしょう。 
* このUSBライブラリは内部的にはSTM32Cubeを使っており。今のところはSTの人がSTM32Cubeのバージョンアップ作業をやってくれている。