avr/samd21/nrf52用hoboNicolaライブラリ

概要

    • samd21とnRF52840 (および従来のATmega32U4)を使ったマイコンボードで使うhoboNicolaアダプタ用のライブラリ (hoboNicola 1.6.1版) を作成した。
    • samd21については先日作成したSAMD21用hoboNicolaアダプタを使って、Seeeduino XIAO-m0およびAdafrut QT Py SAMD21の2つのボードで動作を確認した。

      hoboNicola XIAOアダプター
    • nrf52 についてはSparkfun Pro Microとピン互換のスイッチサイエンス社のISP1807 Microボードを対象とした。こちらは最初に作ったPro Micro + miniUHS構成のアダプターの、マイコンボードを差し換えるだけで動作するようにした。

      ISP1807Micro + miniUHS

hoboNicola1.6.1の更新内容について

ほぼNICOLAキーボード用アダプターとしての機能は、以前のhoboNicola1.5.0 とあまり変わらない。今回は以下のような項目についての追加や更新を行った。

対応マイコンの追加

ATmega32U4に加えて、samd21およびnRF52840(ISP1807)への対応を追加した。

samd21およびnRF52は、ともにARMコアを採用した32ビットマイコンでとても高性能である。USBコントローラを内蔵していることと、内蔵メモリ(フラッシュおよびSRAM)も豊富なこと、消費電流も抑えられていることなどから、ATmega32U4から乗り換えにちょうどいい。

ボード マイコン(Soc) コード用フラッシュメモリ SRAM
SparkFun
Pro Micro
ATmega32U4
3.3V / 8MHz
32KB 2.5KB
Seeeduino
XIAO-m0
ATSAMD21G-18-A
3.3V / 48MHz
256KB 32KB
Adafruit
QT Py SAMD21
ATSAMD21E-18-A
3.3V / 48MHz
256KB 32KB
SwitchScience
ISP1807 MB
ISP1807 (nRF52840)
3.3V / 64MHz
1MB 256KB

スリープ時の省電流化 (AVR, SAMD, nRF52)

省電流のため、hoboNicolaアダプターのホスト側(PCまたはハブ側)のUSBがサスペンド状態になったことを検出すると、アダプター自体(マイコンおよびMAX3421E)の消費電流を減らすとともに、接続中のUSBキーボードを擬似的なサスペンド状態に置くようにした。

うちで使っている富士通コンポーネント社のFKB8769-052 を接続している場合、スリープに入ることでアダプターに流れるVBUS電流が約70mA減る (キーボード+MAX3421Eが約62mA、マイコンのスリープで約7~10mA)。

Pro Micro + miniUHS
Pro Micro + miniUHSの2階建て版と日本語キーボード

MAX3421Eとキーボードの擬似的なサスペンドは、USBデバイスへのSOFを停止するコマンドやパワーダウン状態に入るためのコマンドをSPIを通じて発行することで実現した。

miniUHSに接続するキーボードによっては、擬似的なサスペンド状態によって機能しなくなるものもありそうなので、擬似サスペンドを使う/使わないを設定できるようにした(初期状態ではオフ)。

Mass Storage ClassによるIME状態通知 (SAMD, nRF52)

今までのhoboNicolaでは、Scroll LockキーのLED状態に応じてNICOLA配列にするかどうかを決めることができた。PC側のソフトウェア (observe_ime.exe) でIMEの入力文字種(英数 or かな)を調べ、 (WIN32 APIの SendInput() を用いて) Scroll Lockキーを操作することで、hoboNicolaに通知するという仕組み。

ただ、Scroll LockをかけてしまうとMicrosoft Excel を使うときに迷惑でしょうがないという話もあり、代替の通知方式としてキーボードとは無関係の Mass Strorage Class を利用することにした。

samd21版およびnRF52版のhoboNicolaアダプタをPCに接続すると、USBメモリを差したときのようにPCにドライブが一つ追加される。

hoboNicolaドライブ

このドライブにある HOBONICO.BIN というファイルを、 observe_ime.exe から操作してやることでIME状態をアダプターに知らせるようにした。この絵では、ドライブ L: になっているが、ドライブ名は動作環境によって変わるだろう。observe_ime.exe もこのMSC通知機能に対応できるように修正した。

注意点として、MSC通知機能をもつアダプターが複数台接続されていても、通知を受け取れるのは最初に接続した1台のみになる。Scroll Lockによる通知はすべてのアダプターに届くが、MSCでは1台に限定される。

この機能は、残念ながらAVRマイコンでは使えない

Bluetooth LE キーボード化 (nRF52)

Adafruit の Bluefruit ライブラリに含まれている、BLEHidGeneric クラスを拡張して ほぼNICOLA配列を実現するBLEキーボードアダプターとして使えるようにした。

hoboNicola BLE
hoboNicola BLE

USBケーブルでPCにつなぐとUSBキーボードとして動作し、その状態でBLE機能を有効にすればBLEキーボードとして動作する。USBケーブルをPCではなくモバイルバッテリにつないで利用することもできる。

BLEドングルを差したPCとの接続ではちょっと遅さを感じるが案外と実用的。ほかにAndroid スマートフォンへの接続も確認しており文字入力は問題ない。

ただ、AndroidのIMEをうまく操作してストレスなく日本語入力するためのキーコード設定などは入れていないので、今のところ実用的ではない。タブレットでも使ってるとすぐに実装するんだろうけど、とりあえずはまだ。当たり前ですがBLE接続中はMSC通知はできません。

その他の変更/更新

AVR用も含めた更新項目としては、おもに以下のとおり。

検索フィールドでのキーの取りこぼし対策

Windows Explorer (Windows10) の検索フィールドでのキーの取りこぼしを防ぐため、連続した出力時(ローマ字での xyoやxtuなど)に遅延を置くようにした。これは、2019年のWindows10の更新 (1903あたり?) から出ている現象で、Windows Explorerでファイル検索しようとするとキー入力を取りこぼしてしまうというもの。ExplorerでEXIFタグを入力しているときや、ファイル名のリネームをしているときには何の問題もないのに検索フィールドだけは取りこぼすという、ひどいバグをなかなか直してくれない。

NumLock  による状態通知

 Scroll LockかけなければExcelも困らないだろうということで、ScrLock LEDの代わりにNumLock LEDを使った状態通知も受け付けるようにした。テンキーを使う人には迷惑な機能か。また、テンキーレスのキーボードでも、NumLock時にはキーボードの一部がテンキーパッドになってしまうコンパクトキーボードもあって、果たして世の中の役に立つのか疑問ではあるのだけど。

部分的にテンキーパッドが出現する
TinyUSBライブラリの利用

samd21およびnRF52のUSBコントローラを使うため、Adafruitが公開しているTinyUSBライブラリのArduino版 (Adafruit_TinyUSB_Arduino) を利用した。AVRについては従来とおりだが、2種類のライブラリの相違を吸収する簡単なラッパーモジュールを用意することで、全体の変更を少なくした。

USB Host Shield Library 2.0はインストール不要

従来のhoboNicolaライブラリで使っていた、MAX3421EをUSBホストとして使うためのUSB Host Shield Library 2.0 (以下、UHSライブラリと記述) については、Arduino IDEの追加ライブラリとしてではなく、hoboNicolaのソースツリー内に包含することにした。このため新たに追加する必要はなくなった。すでにArduino IDEにライブラリとして追加してあっても、ビルド時に問題は生じない(はず)。

包含するようにした理由は、UHSライブラリの中身にちょっと手を加える必要が生じたためで詳しくは別稿にまとめる予定。

EEPROMのないマイコンへの対応

ATmega32U4は1KBytesのEEPROMを内蔵しているが、samd21やnRF52には備わっていないため、おのおののマイコン用のライブラリ(samd21はFlashStorage、nRF52はInternalFS) を利用してフラッシュメモリ内にデータを記憶/参照するようにし、AVRマイコンと同じような設定を行えるようにした。

ハードウェアなど

ちょっと加工したmini USB Host Shield 2.0 (以下、miniUHS) と数種類のマイコンボードを組合せているが、なるべく共通化できるようにしてきた。

Pro Micro + miniUHS
Pro Micro + miniUHSの2階建て版

ハードウェアの配線やminiUHSの改造方法については今まで何度か載せている。samd21については直前の投稿を参照のこと。また、SparkFun Pro Micro (ATmega32U4) を使った2階建て仕立てのアダプターについては、こちらの投稿を参照。

スイッチサイエンス社のISP1807 Microボード を使ったアダプターは、 SparkFun Pro Microとピン互換なことを活かして、2階建て仕立てアダプターのマイコンボードを差し替え、ブレッドボードにLEDや抵抗を立てると出来上がる。配線図などは以下の投稿を参照のこと。

ISP1807Microボード用のUSB Host Shield Library2.0の修正

上記の投稿では、ISP1807に合わせてUHSライブラリに修正を加えているが、今回のhoboNicolaライブラリからその作業は不要にした。

LEDについて

hoboNicola XIAOアダプター

hoboNicolaアダプターには、2つから3つのLEDを載せる(あるいは、オンボードのLEDを利用する)ようにしているが、以下のような役割で使っている。

シンボル名 用途 備考
LED1 NICOLAモードのとき点灯
設定モードのとき点滅
緑色を推奨
LED2 何かのエラー時に点滅
CapsLock LEDとして機能
赤色を推奨
BLE_LED BLE接続中に緩慢に点滅 青色を推奨
analogWrite() を使用

これらのシンボル名は、examples/usb_hobo_nicola/device_setup.h で定義している。Pro MicroやLeonardoについてはオンボードLEDを利用するようにしており、以下のようにしている。

また、XIAO-m0も3つのオンボードLEDが載っているので以下のようにした。

キーボード側LEDについて

オリジナルのUHSライブラリには、ロックキー(CapsLock, NumLock, Scroll Lock)の押下に応じて(アダプターからの指示とは無関係に)キーボードLEDを点灯させるコードが入っている。そのため、日本語キーボードとして使っているときも、CapsLock(英数)キー単独でキーボードのCapsLock LEDが点灯していた。

個人的にはLEDインジケータのあるキーボードは常用していないのであまり気にしていなかったのだが、今回はそのあたりにも手を入れ、UHSライブラリによるLED制御を止めて、PCからのLED通知だけでキーボードLEDをコントロールするようにした。

ダウンロード、ファイル構成、ビルド

hoboNicolaライブラリ1.6.1 を収めた hoboNicola161.zip のダウンロードはこちらからできます。

hoboNicola161.zip  の中身は以下のようなディレクトリ構成になっている。

zipファイルを展開して都合のよいフォルダに置いてもいいし、Arduino IDEの スケッチ/ライブラリをインクルード/.ZIP形式のライブラリをインストール…  でhoboNicola161.zip を選択し、Arduinoライブラリとして追加することもできる。inoスケッチを改造して使うような場合、ライブラリして追加しておくのがいいだろう。

Arduinoのライブラリとして追加する場合、hoboNicolaの以前のライブラリを別のフォルダ(libraries フォルダの外)に移動しておかないと、競合してビルドが失敗するかもしれない。

各ソースファイルの中身については、おいおい投稿していく予定です。

ビルドのための構成について

ビルドは、Windows10でArduino IDE 1.8.19 (Windows App版ではなく通常のインストール版) を使っておこなった。1.8.19版はlog4jを一切排除したリビジョンのようである。

Arduino IDE

AVRマイコン以外をビルドするので、各Arduinoボード用にメーカーが提供してくれているボードサポートパッケージ(BSP)や、マイコンに依存したライブラリをいくつか導入する必要がある。

ボードサポートパッケージ(BSP)

Arduino IDEのツール/ボード/ボードマネージャ… でインストールする、Arduinoボードのマイコンに応じたコンパイラツールチェーン、ライブラリ、構成ファイルをひとまとめにしたパッケージをBSPと称している。

samd21用

AdafruitのQT Py SAMD21用のBSPを導入する。Seeeduino XIAO-m0用のBSPの導入は不要。XIAO用のBSPは、なにか工夫が足りないのかもしれないが、今回用いる別のライブラリと共存できなかったので、Adafruit SAMDボードの一種(バリアント)として扱うことにした。バリアントとして扱うために必要なファイルは当サイトからダウンロードできるようにした。

なお、XIAO用のBSPを導入しておいてもビルド時にターゲットボードとして選択しなければ害はない。

Adafruit社のQT Py SAMD21のガイダンスにある手順にしたがって、ファイル/環境設定追加のボードマネージャーURL に以下を追加する。

そして、ツール/ボード/ボードマネージャ… で、まずArduino SAMD Boards (32bits ARM Cortex-m0+) をインストールする。今回はバージョン1.8.13 が入った。このBSPを導入することで、ARM用のgccツールチェーンだのARM CMSIS関連ファイルだのが大量に導入されるので、ちょっと時間がかかる。

続いて Adafruit SAMD Boards をインストールし、いったんArduino IDEを終了して開き直す。再度ツール/ボード/ボードマネージャ…を選択して 検索をフィルタ… となっているフィールドに、”SAMD”と入力して絞り込んでやると、以下のように2つのBSPが INSTALLED となっているはず。

ボードマネージャ

ツール/ボード を選択して Adafruit SAMD (32bit…) を選択すると、Adafruit社が出しているSAMD21ボードの名前がずらずらとメニューに並ぶ。

Arduino IDE Boards…

ここまで来たら、ひとまずLチカスケッチでも書いて、SAMD21用のビルドできることや、マイコンボードに書き込めることなどを確認するのがいいだろう。

Seeeduino XIAO-m0用追加ファイルと導入方法

Seeeduino XIAO-m0 をAdafruit SAMDボードのバリアントとして扱うためには、こちらのZIPファイル ( XIAO_m0.zip) をダウンロードして展開し、Adafruit SAMDボード用のフォルダ (うちのPCでは、 C:\Users\[user-name]\AppData\Local\Arduino15\packages\adafruit\hardware\samd\1.7.9\variants  内) に XIAO_m0 というフォルダを作ってコピーする(あるいは、直接zipを展開する)。

XIAO_m0.zip の内容は以下のようになっている。

これらのファイルは、もともとはSeeed StudioがSeeeduino XIAO-m0用に提供していたものだが、Adafruitのバリアントとして問題なく使うために数か所変更を加えた。すべて Arduino LLC がGNUライセンスで提供してくれているものなので、修正したり再配布は問題ないだろう。

次に、ボードが追加されたことをArduino IDEに教えるため、以下の内容をboards.txt の末尾に追加する。boards.txt は、 ...\adafruit\hardware\samd\1.7.9 フォルダの中にある。

このフラグメントは、Seeeduino SAMD向けの boards.txtから抜粋した。

上記の導入作業を行ったあとで Arduino IDEを開くと、ツール/ボード/Adafruit  SAMD(32bit….) メニューの中から Seeed XIAO-m0 が選択可能となっているはず。

XIAO-m0 追加
XIAO-m0関係の注意事項
  1. 上記の作業(zipの展開とboards.txtへの追記) は、Adafruit SAMDボード用BSPを更新するたびに行う必要がある。そうしないと、XIAO-m0は選択できなくなる。
  2. variants フォルダにXIAO-m0用追加のためのフォルダを作成するときには、名前は必ず XIAO_m0 とする。もしも名前を変更したいときは、boards.txtに追記する項目の、 seeed_XIAO_m0.build.variant=XIAO_m0  の右辺も変更のこと。
  3. Adafruit ライブラリに合わせて、USBを介したシリアル通信用オブジェクト (XIAOでのSerialUSB) は、Serialに変更しその別名としてSerialUSB も指定できるようにした。

nrf52(ISP1807)用

スイッチサイエンス社のISP1807 Microボード用BSPの導入方法については、以前ISP1807とテンキーパッドを接続したお話で書いているのでそちらを参照のこと。Adafruit nRF52Switch Science nRF52 Boards という2つのBSPを導入するが、以下のバージョンで動作を確認している。

  • Switch Science nRF52 Boards : 0.1.9
  • Adafruit nRF52 : 1.3.0

追加のライブラリについて

Adafruit_TinyUSB_Arduinoの導入

samd21およびnrf52で動作するhoboNicolaをビルドするには、Adafruit_TinyUSB_Arduinoを導入しておく必要がある(AVR用しかビルドしない場合は不要)。

このライブラリは TinyUSBライブラリのArduino版で、USBの下回りからHIDやMSC(Mass Storage Class) といった上位機能までカバーしてくれる。中身や変更履歴については  https://github.com/adafruit/Adafruit_TinyUSB_Arduino を参照。最初にArduino IDEに追加したときには以下の手順を使った

  1. https://www.arduino.cc/reference/en/libraries/adafruit-tinyusb-library/ から最新のzipファイルをダウンロードして保存。
  2. Arduino IDEの スケッチ/ライブラリをインクルード/.ZIP形式のライブラリをインストール… を開き、ダウンロードしたzipファイルを選択して読ませる。

なお、すでに追加済のライブラリを更新するときには、スケッチ/ライブラリをインクルード/ライブラリを管理 を開き、以下に示すライブラリマネージャで対象ライブラリを選び、バージョンを選択してインストールする。

Arduino IDE

今回のhoboNicola (1.6.1版) では、Adafruit_TinyUSB_Arduino の 1.10.0版での動作を確認した。 このライブラリは今のところかなり頻繁に更新が行われているので、リビジョンが大きく変わったようなときは注意が必要かもしれない。

Adafruit_TinyUSB_Arduino は、Adafruitの各BSP(samd21およびnRF52) にも含まれているが、バージョンがそろっていなかったり、BSPに含まれているものは古いことが多い。そのために独立したライブラリとして導入することにした。

ビルドの実行時にArduino IDEはBSP内のライブラリも見つけてしまうのだが、新しい方?を優先して使ってくれるようで以下のように表示される。

Seeeduino XIAO用のBSPを使わない理由もこのあたりにあって、こちらの場合はビルドエラーで止まってしまう。

ビルドについて

Arduino IDEでふつうにビルドするときのいくつかの注意点を書いておく。

接続するハードウェアにあったボードを選択する

今回から対応するマイコンボードの数が増えたので、接続するボードに応じてちゃんと選択し、オプション項目も正しく選択しておく。

Pro Micro (純正、互換品) + mini UHS

SparkFun AVR Boards から、SparkFun Pro Microを選択しプロセッサとしてATmega32U4 (3.3V, 8MHz) を選択する。

Arduino Leonardo + USB Host Shield

Arduino AVR Boards から、Arduino Leonardo を選択。UHSは+5Vロジックで接続できること。ATmega32U4 5V/16MHz を使ったオリジナル回路も同様にする。

Pro Micro (+5V) + PS/2

SparkFun AVR Boards から、SparkFun Pro Microを選択しプロセッサとしてATmega32U4 (5V, 16MHz) を選択する。今回は特に変更は行わなかったが、動作は確認している。

Adafruit QT Py SAMD21 + miniUHS

Adafruit SAMD (32bit ARM….) から、Adafruit QT Py M0 (SAMD21) を選択し、USB Stack を TinyUSBに。Debug: を “On”にすると、gcc(g++)のオプションとして “-g” が追加されてデバッグ情報が生成されるようである。

Seeeduino XIAO-m0 + miniUHS

Adafruit SAMD (32bit ARM….) から、Seeeduino XIAO を選択し、USB Stack を TinyUSBに。Debug: を “On”にするとgcc(g++)のオプションとして “-g” と -DDEBUG=1 が追加されるので、スケッチやプログラムで #if DEBUG ~ #endif とか書いたときに便利である。

USB Stack は TinyUSBを選択

samd21ボードを使うときには、ビルド時のオプションに、USB Stack: という項目があるので必ず TinyUSB を選択すること。

Arduino IDE

別のボードから切り替えたようなとき、USB Stackの初期値は Arduino になる。Arduino のままビルドすると、fatal error: PluggableUSB.h: No such file or directory といったエラーを吐いてビルドは停止するはずなのですぐ分かる。

ビルド結果

Arduino IDEでのビルド結果(メモリ使用量など)を以下に記録しておく(ZIPを展開してビルドしたとき若干の相違があっても問題ありません)。

SparkFun Pro Micro (USBアダプター)

ブートローダーサイズが4KBなので、プログラムで使える領域は28KBのみ。けっこう、いっぱいになってきた。

QT Py SAMD21

XIAO-m0

当初Arduino IDEでsamd21用スケッチをビルドしたとき、RAMの使用量が表示されなかったので、platform.txtの一部を以下のように変更した。

フラッシュメモリの使用量は .text + .data、SRAMは、.data + .bss で算出するようにした。

ISP1807

Adafruit のnRF52840用ブートローダーを入れたシステムでは、スケッチ用のフラッシュメモリサイズは1MBytesのうちの796KBに限定されており、他にユーザーデータ領域(28KB)、ブートローダー領域(48KB)、SoftDevice領域(152KB)がある  ( https://learn.adafruit.com/introducing-the-adafruit-nrf52840-feather/hathach-memory-map ) 。

設定項目について

Ctrl + Fn + S  および(NICOLAモードで) 親指キー + Pause の同時打鍵 によって入る設定モードでトグルできる項目は3つ増えた。

MSC NOTIFY

Mキーでは、Mass Storage Class を使ったIME状態通知を有効にするかどうかを設定する。有効になっているとき、hoboNicolaアダプターが作成する小さなディスクドライブ内のファイルに対する操作するでIME状態が通知され、アダプターが同時打鍵を有効にするかどうかが決まる。

従来からある SCRLOCK = NICOLA MODE (Scroll Lock LEDによる状態通知)と新設の NUMLOCK = NICOLA MODE (NumLock LED) が有効で、なおかつ MSC NOTIFYのいずれもが有効な場合、MSC通知が最も優先される。

AVRを使ったアダプターの場合、Mキーの操作は無視される。

PSEUDO SUSPEND

Kキーでは、MAX3421Eおよびキーボードの擬似サスペンドを有効にするかどうかを設定する。初期値は無効になっているので、PCをスリープさせたり電源オフしても、マイコンがスリープするだけで大した省電流効果はない (7~10mA程度)。

接続するキーボードによってはサスペンドさせると復帰できない可能性もあるので初期値を無効にした。もしも擬似サスペンドを有効にしてスリープさせたときにキーボードを使った復帰ができなければ、別の手段(マウスとか)で復帰させればいいだろう。

NUMLOCK  = NICOLA MODE

Nキーでは、NumLock LEDが点灯しているときNICOLAモードで動作するようになる。SCRLOCK = NICOLA MODE も有効にしている場合、Scroll Lock LEDによる通知が優先する。通知を行うobserve_imeでは、Scroll Lockを使うかNum Lock  を使うかを選択できる。

MSC通知対応のobserve_imeについて

MSC通知に対応したWindows PC用のobserve_ime (1.1.0版)については、こちらのページからダウンロードできます。Microsoft Visual Studio Community 2017 (15.9.39)  でビルドするための一式とx64版およびx86版のバイナリを含んでいます。

きょうのまとめ

  • 数種類のマイコンボードに対応したから、何か直すと他のマイコンに影響がないことを確認するなどしたので、思っていたよりも時間がかかってしまった。ブログに書く内容もなかなかまとまらず、まとまりのつかないまま公開することになった。
  • 前にも書いたが、XIAOやQT Pyにはピン互換で他のマイコンを使ったバリエーションもあるので、いずれ対応していく予定。
  • プログラム内部の実装については、覚えているうちに別稿にまとめる予定です。

追記

2022/4/4

早速バグを見つけた。device_setup.h の100行目あたりにある #endif の位置が間違っていて、これではQT Pyのときに APBCMASK.reg への書き込みが行われない。たぶん、消費電流が想定より1~1.5mAほど大きくなっています。次のリリース時には直します。

2022/5/8
  • XIAO_m0.zip がリンク切れになっていたのを修正。
  • hoboNicola161.zipの内容のうち、examples/xd87 の内容が1.6.0版から更新されていなかったので、1.6.1版用のxd87一式をダウンロードページに別途用意しました。examples/xd87の内容を入れ替えてください。