2016年8月28日日曜日

ATmega32U2のMinimus32開発環境―Windows編

さきほどのMinimus32について、プロジェクトのサイトが見つかりましたので最初にご報告。
projects/minimus32 - rlab.org.uk
連合王国でしたのですね。さすが小さなものがお好みなお国柄。あと、同じく連合王国のリーズにあるハックスペースさんでも情報提供が。
Minimus - wiki.leadshackspace.org.uk
MAXIMの1Wireプロトコルの実装by pbrookさんが紹介されています。I2Cがなくても俺たちには1Wireがあるという心意気でしょうか。

それで、WindowsのArduino IDE 1.6.11ではどうだろうと試してみたところ、ZIPを展開した状態ではどうもうまくいかなくて、インストーラで入れた1.6.11に、Surreallitylabsさんの1.6対応の一式を、Macと同様にぶっこんだあと少し調整したら、一応なんとかなっているようです。

  1. c:\Program Files(x86)\Arduino\hardware の下に、minimumというフォルダを作成して、上のをZIPでとってきて展開した「avr」フォルダをそのなかに放り込みます。
  2. 念のため、boards.txtの冒頭に、arduino側と同じ一行「menu.cpu=Processor」を書いておきます。
  3. コンパイルしてみるとplatform.txtの記述が古いよといいつつ終えるのですが、気持ち悪いのでarduino側にあるものをコピーして入替えます。
これで、Arduino IDEを起動すると、ちゃんとMinimus32がCPUとして選べて、コンパイルまで成功します。あ、もし3.3V版にしているのでしたら、先ほどのエントリの内容にしておいてください。

転送、って言ってませんが、avrdudeが一時的に作成されているはずのhexファイルが「見つからない」という理由以上終了し、呼び出したArduino IDE側がJavaランタイムのスタックトレースを吐いてしまいます。

様子がよくわからないので、コマンドプロンプトを開いて、そこからarduino_debug.exeを起動して同じことをやると、不思議なことに、hexファイルを見落とすことなく書き込みまできれいに完了してしまいました。よくわかりませんが。

ということで、まあこれで当面の目的は達成できるのでよしとして、困ったのが、COMポートの番号増加であります。書き込み終了と同時に、USBの抜き差しの音が出たんで嫌な予感がしたんですよね。

なんとなく、シリアルポートが開いた状態で、avrdudeが書き込みを行うときにCPUのリセットをかけてしまうと、Windowsの都合で、開いた状態のポートが消える前に新しいポートを作ろうとして、番号が上がってしまうというではないかと疑っているところです。

ATmega32U2にArduinoのbootloaderを書き込んでArduino IDEが使えるようにした(追記:2016年9月10日)

とある事情から、ATmega32U2をArduino化する必要があり、いろいろと困っておりましたが、解決したので記録を兼ねてご報告。

まずATmega32U2がArduinoになるのか、ということですが、「ATmega32U2にはADCもI2Cもない」。アナログ入力がないわけです。それらが揃っているのはU4のほう。U4はArduino Leonardoに始まり、各種のボードが販売されているものの、U2は機能不足だから商品化するメリットないよね、と納得しました。(追記 2016-09-10:データシート見ると,A0に対するコンパレータはあるようです。端子にAIN0に対してAIN1〜6がMUX経由でコンパレータにつながっている図がありました。ピン配置をみると,Port D(PD1,4-7)がアナログ入力ですね。PC2にAIN2が飛んでいますけど)

とはいえU2ちっちゃいしピン数もU4より少なくて値上がりしたとはいえまだ秋月で400円だし、もう撤退できない状況があるので、検索をGoogleに変更してみたところ、わりとあっさりとkosakailabさんのブログエントリがヒットしまして、
ATmega32U2でArduinoモドキを作る - kosakailab
Minimus32というプロジェクトがあり、一部販売も(?)されたことがあるらしいことを知りました。

kosakailabさんがGitHubリポジトリとbootloader作成の手がかりを示してくださっているほか、こちらMinimus32解析サイトで部品や回路図などが書き起こされていることで、一通りのなかみはわかりました。
pbrook/minimus-arduino - GitHub
実際のところ、5V電源で16MHzのクロックを使うなら、すでにhexが置いてあるのでコンパイルする必要はないんですが、3.3V動作にする都合でクロックを8MHzに変更する必要があり、Makefileを書き換えてコンパイルする必要があった次第。
データシートの26.3項に、「安全動作圏」を示したグラフがあり、8bitのAVRマイコンでは3.3Vでは10MHz以下のクロックにしなければなりません。Arduinoでは3.3V製品としてSparkFun製Arduino Pro Miniの3.3V版があり、それに合わせて8MHz設定が公式ライブラリに追加されているので、3.3V動作の場合、8MHzのクリスタル一択です。
bootloaderコンパイルにはLUFAが必要だよ、と書かれています。Unoが搭載しているUSB-UART変換にいまはATmega8U2が使われていますが、かつてはATmega16U2が使われていたこともあり、それらには、LUFAが活用されているようです。
オフィシャルサイトは「(2013)」と但し書きがついていますが、GitHubリポジトリは今年も更新されているようです。ともかくも、LUFAは、USBつきAVR開発支援軽量ライブラリとのこと。

さてそんじゃあbootloader作るべし、となるのですが、minimusプロジェクトが3年前で止まっているので、ちと工夫が必要でした。

まず、pbrookさんのレポジトリですが、Forkとjoinのグラフをみると、2年前にSurrealityLabsさんが手を加えたのがいまの最新っぽく見えました。
SurrealityLabs/minimus-arduino - GitHub
これを開くといきなり「avr」しか見えなくて不安になりますが大丈夫、全部入ってます。

よって、ここからgit clone。あとLUFAですが、最新のリポジトリからもってきたものはいろいろ構成がかわっているようで、コンパイルが通らず、Makefileに書かれていた111009(2011年10月9日版)を公式サイトからダウンロードしてくるのが簡単でした。

配置ですが、avr-gccなどツールチェインをArduino IDEから借りるのが手っ取り早いので、すでにインストールしてあるArduino IDE 1.6.11に組み込んでしまうのが話が早いです。あと、Windowsではmakeをどうするの、とかよくわからなかったのでコンパイルはMacでやりました。実はBash on Ubuntu on Windows 10でがんばってみたんだけど断念。いま思えばLinux用Arduino IDEから拾えばよかったのかも。

コンパイルに必要な変更は、Makefileの「F_CPU = 16000000」を8000000に変更するだけ。あと、bootloaderはCaterinaを使っていて、USBのVID/PIDは、Arduino LLCのVIDとLeonardoのPIDが書かれたままになっていますが、目をつぶってそのままに。おかげでlsusbすると「Arduino SA Leonardo ( CDC ACM, HID)」と出ますが、まあそういうことであります。

pbrookさんのWikiには、Arduino IDEのhardware/avr以下を置き換えろみたいな乱暴なことが書かれていますが、そうするとMacの場合、Arduino IDEが上がらなくなってしまいました。

で、Windowsのほうではどうだろうと、SurrealityLabsさんのplatform.txtには1.6.0と書かれているので1.6.0でがっつり置き換えると、まあ起動はしましたが、bootloaderを書こうとすると、「書き込み装置の選択をしろ」的なメッセージが出て先に進みません。AVRISP mkIIを使っているので、それを選択してあるんですが、どうもだめ。

そこで再び検索すると、こんなブログエントリがありまして
Arduino IDE on Windows with Minimus32 Profile
なんだか、「一式固めといたよ」としてZIPファイルがリンクされていました。ですが、これを展開するとバッチファイルがありまして、Arduino IDE 1.0.5をダウンロードしてそこに置き換えのツールチェインとpbrookさんのリポジトリのZIPを配置する、というような仕立てになっておりました。

それができた状態で、Macで作ったhexファイルをもとのものと置き換えるものの、こちらではbootloaderを書き込もうとするとJavaのランタイムエラーが出てだめでした。Windows 10(1608版)なんですが。

もうこれはavrdudeのコマンドラインでいくしかないかな、と思いつつ、「もしやMacでこれと同じ構成にしたらうまくいくんではないか?」と思ったところ、うまくいきました。

Arduino IDEの設計は全くわかっていないんですが、hardware以下にarduinoというフォルダがあるところを、上のバッチファイルで作成した1.0.5版では、minimusというフォルダを隣に作り、pbrookさんの一式はこちらにまるっと入れるという仕上がりになっていて、既存のファイル、特にboards.txtなんかは一切書き換えていないのですが、起動したArduino IDEではきちんとminimus以下のboards.txtの内容が反映されていたわけです。

ということで、Macの1.6.11でも同様に、hardware/minimusというフォルダを作り、一式をそこに放り込み、LUFA-111009も放り込んでMakefileavr-gcc等を呼び出すパスの追記やLUFAのパスを現状に合わせます。それから、macOSの認証を通すために一度無改造のままArduino.appを起動してからなかみの変更をする必要がありますが、最初の起動時に、ボード設定その他をJSON形式で ~/Library/Arduino15 以下に置くので、それをリセットするために、このフォルダごと消しておきます。

そして、とても大事なことなんですが、3.3Vにしたので、boards.txtに記述するAVRのフューズビットの設定を変更し、ブラウンアウト(電圧低下)検出 の電圧を3Vから2.7Vにしておかないと不安です。フューズビットは書き込み時にavrdudeのコマンドラインをArduino IDEが生成するときboards.txtを参照するので、その16進の値を理解して、適切に設定した内容を書いておかなければなりません。

ここで、AVR Fuse Calculatorの出番です。ところが検索してもATmega32Uシリーズが入っているものがなかなかありませんが、なんとか見つけました。
Engbedded Atmel AVR® Fuse Calculator - Electronics-Base.com
で、「AVR Part Name」はATmega32U2ですからすぐ終わるわけですが、あとが困ります。わかんねえ。データシート全部読むのめんどい。

Atmelのデータシートの作りも不親切で、Fuse Bitについてまとめた項目がないんですよ。機能の説明があって、そこにFuse Bitはこう設定する、という部分的な表がばらばらにあるので、一覧できない。全部嫁ということになる。

まあいいや、ということで、既存のboards.txtでATmega32U4が採用されているものと、Minimus32の設定を見比べつつ、上の計算機の値をポチポチしてみると、Minimus32とU4採用Arduinoのfuse bitの設定は同じだということに気づくわけです。Yún, Leonardo, Micro, Esplora, Lilypad USB、どれとも共通です。すると問題になるのはBODの電圧設定のみで、それはextendedの項目であり、5V版である既存設定では3.0V。U2の場合選べるのは最低2.7Vしかないので、そこだけを変更。すると、0xf8が0xf6になるだけだ、という結論が導かれました。

ということで、既存のminimus32の設定を複写して、minimus32v33とかクラス名を変更したところで、name=Minimus 32 (3.3V)とか書いて、bootloader.extended_fuses=0xf6と書き換えます。あと、build.f_cpu=8000000L も忘れずに変更しておきます。build.usb_productにも「3V3」を追記して、これでおしまい。

参考までに、作ってみた部分を掲載しておきます。
#############################################################

minimus32v33.name=Minimus 32 (3.3V)
minimus32v33.vid.0=0x2341
minimus32v33.pid.0=0x0036
minimus32v33.vid.1=0x2341
minimus32v33.pid.1=0x8036
minimus32v33.upload.tool=avrdude
minimus32v33.upload.protocol=avr109
minimus32v33.upload.maximum_size=28672
minimus32v33.upload.speed=57600
minimus32v33.upload.disable_flushing=true
minimus32v33.upload.use_1200bps_touch=true
minimus32v33.upload.wait_for_upload_port=true

minimus32v33.bootloader.tool=avrdude
minimus32v33.bootloader.low_fuses=0xff
minimus32v33.bootloader.high_fuses=0xd8
minimus32v33.bootloader.extended_fuses=0xf6
minimus32v33.bootloader.file=caterina/Caterina-Minimus.hex
minimus32v33.bootloader.unlock_bits=0x3F
minimus32v33.bootloader.lock_bits=0x2F

minimus32v33.build.mcu=atmega32u2
minimus32v33.build.f_cpu=8000000L
minimus32v33.build.vid=0x2341
minimus32v33.build.pid=0x8036
minimus32v33.build.usb_product="Minimus32 3V3"
minimus32v33.build.usb_manufacturer="Arduino"
minimus32v33.build.board=MINIMUS32
minimus32v33.build.core=minimus
minimus32v33.build.variant=minimus32
minimus32v33.build.extra_flags={build.usb_flags}
追記するのは、minimusフォルダ以下のboards.txtだけでよいです。arduino以下には一切触りません。

それでArduino IDE 1.6.11を起動して、ボードの選択をすると、ちゃんとArduinoとMinimusでカテゴリが分けられて選択できるようになりました。よくできてる。
ボード選択メニューの下に追加された
この状態で、「ええい、ままよ」と彼岸島な心で「ブートローダーの書き込み」を選択すると、さっくりと書き込まれまして、USBデバイスを再認識したアラーム音がmacOSから鳴りました。ちゃんとシリアルポートも選べます。でかした! ヤンヤヤンヤ

ためしにスケッチを書いて、コンパイルと転送が通るかも試します。といっても、いまは何もないので、SerialオブジェクトがUSBに割り当てられているのを使って、IDEのシリアルモニタから入力があったら"Hello"を印刷する簡単なスケッチを作り、コンパイルと転送してみました。なにやら「Minimusには対応していません」な警告が3つぐらい出ましたが、そのままコンパイルを終えて書き込みまでさくっと完了しました。感動。

USBの標準速度が57600bpsになっているので、Serial.begin(57600); などと書き、シリアルモニタの設定も57600bpsにして適当な文字を入れ、「送信」ボタンを押すと、"Hello"が出ました。動いているようです。これで、追加の回路も載せて制御できる見通しが立ちました。よかったよかった。

なんですが、ひとつ回路について重大なことを書くのが遅くなりました。このブログエントリは流れ的にソフトウェアの話でいったん完結させるしかなかったので、最後ですが、自作されようとする方のために、また自分の作業記録として、書かなければなりませんので、ここに記します。

Minimus32の解析サイトに回路図がありますが、これをみると、普通のArduinoには見慣れない「HWB」というタクトスイッチがあります。pbrookさんのWikiにも図があって、リセットと隣合わせに並んでいるようです。そして、データシートを見ると、2ページのピン配置図では13番ピンに、「#HWB」なる端子があります(#は負論理)。さらに、他のU4を使ったArduinoでもフューズビット設定で、「Hardware Boot Enable」にチェックを入れています。「ハードウェアブート」はArduinoにおいて重要らしい。

Minimus32の商品(?)では、まじめにそのボタンをつけているんですが、U4を使った他のArduinoにそんなボタンはありません。なんでだろうと思ってデータシートを読むと、「HWBがLのときにRESETがUPするとハードウェアリセットがかかる」とありました。めんどくせえ。それで、手持ちのArduino Nanoの回路図をみたところ、HWBのラインは10kΩの抵抗を通してプルダウンされており(GNDに接続)、わざわざ「USB RESET EN」と書かれていました。HWBをプルダウンしておけば、リセットラインのL→Hの瞬間にリセットがかかるわけで、「これでいいのだ」ということのようです。よって、このピンはプルダウンしておきました。

それから、Minimus32はあえてICSP端子を設けていません。が、最初にbootloaderを書くにはICSPの6端子を用意しておいたほうが便利なわけでして、僕はつけておくことにしました。U2だと15ピンがSCK、16ピンがMOSI、17ピンがMISOと、SPI端子が連続しているので作りやすいと思います。

あと、要注意な点として、Minimusのピン配列は普通のArduinoとはだいぶ違います。pbrookさんのWikiの図必携。

具体的には、HardwareSerialSerial1)はD2がRx、D3がTxですし、D6, D7はUSBの送受信表示のLEDに使われています。D8はHWBで今回はプルダウンされたまま。さらにU2の制約として、タイマーは0(16bitカウンタ)と1(8bitカウンタ)の2つしかないのでPWMは4つですが、D1, D17がタイマー0、D19とD21がタイマー1という配置。

タイマーという点では、標準ライブラリのServo()はタイマー1を使うのでたぶん動くと思いますが、タイマー0はmills()delay()など時間関係の関数のために保留されていて、analogWrite()は使えるよう考慮されているものの、Tone()のために使うことはできず鳴りません。ためしにD1を指定してみたものの、コンパイルは通っても実際には鳴りませんでした。

ただ、タイマー1で音を出すライブラリはいくつかあるようなので、Servo()に興味がなく、音を出したいという用途にはそれらを使うのだろうと思います。
最初のは正確な音程とコードのシンプルさ追求、2番目はタイマー出力2ピン両方をスピーカーにつなぐ形での音質追求、最後のはタイマー0のプリスケーラを1にして(分周しない)、超音波まで出せて音量調節まで実現するかわりに時間関数は破綻してよしとするなど、標準ライブラリに物足りない人向けのようです。

長くなりましたが、こちらからは以上です。

ATmega32U2にArduinoのbootloaderを書き込んでArduino IDEが使えるようにした

とある事情から、ATmega32U2をArduino化する必要があり、いろいろと困っておりましたが、解決したので記録を兼ねてご報告。

まずATmega32U2がArduinoになるのか、ということですが、「ATmega32U2にはADCもI2Cもない」。アナログ入力がないわけです。それらが揃っているのはU4のほう。U4はArduino Leonardoに始まり、各種のボードが販売されているものの、U2は機能不足だから商品化するメリットないよね、と納得しました。

とはいえU2ちっちゃいしピン数もU4より少なくて値上がりしたとはいえまだ秋月で400円だし、もう撤退できない状況があるので、検索をGoogleに変更してみたところ、わりとあっさりとkosakailabさんのブログエントリがヒットしまして、
ATmega32U2でArduinoモドキを作る - kosakailab
Minimus32というプロジェクトがあり、一部販売も(?)されたことがあるらしいことを知りました。

kosakailabさんがGitHubリポジトリとbootloader作成の手がかりを示してくださっているほか、こちらMinimus32解析サイトで部品や回路図などが書き起こされていることで、一通りのなかみはわかりました。
pbrook/minimus-arduino - GitHub
実際のところ、5V電源で16MHzのクロックを使うなら、すでにhexが置いてあるのでコンパイルする必要はないんですが、3.3V動作にする都合でクロックを8MHzに変更する必要があり、Makefileを書き換えてコンパイルする必要があった次第。
データシートの26.3項に、「安全動作圏」を示したグラフがあり、8bitのAVRマイコンでは3.3Vでは10MHz以下のクロックにしなければなりません。Arduinoでは3.3V製品としてSparkFun製Arduino Pro Miniの3.3V版があり、それに合わせて8MHz設定が公式ライブラリに追加されているので、3.3V動作の場合、8MHzのクリスタル一択です。
bootloaderコンパイルにはLUFAが必要だよ、と書かれています。Unoが搭載しているUSB-UART変換にいまはATmega8U2が使われていますが、かつてはATmega16U2が使われていたこともあり、それらには、LUFAが活用されているようです。
オフィシャルサイトは「(2013)」と但し書きがついていますが、GitHubリポジトリは今年も更新されているようです。ともかくも、LUFAは、USBつきAVR開発支援軽量ライブラリとのこと。

さてそんじゃあbootloader作るべし、となるのですが、minimusプロジェクトが3年前で止まっているので、ちと工夫が必要でした。

まず、pbrookさんのレポジトリですが、Forkとjoinのグラフをみると、2年前にSurrealityLabsさんが手を加えたのがいまの最新っぽく見えました。
SurrealityLabs/minimus-arduino - GitHub
これを開くといきなり「avr」しか見えなくて不安になりますが大丈夫、全部入ってます。

よって、ここからgit clone。あとLUFAですが、最新のリポジトリからもってきたものはいろいろ構成がかわっているようで、コンパイルが通らず、Makefileに書かれていた111009(2011年10月9日版)を公式サイトからダウンロードしてくるのが簡単でした。

配置ですが、avr-gccなどツールチェインをArduino IDEから借りるのが手っ取り早いので、すでにインストールしてあるArduino IDE 1.6.11に組み込んでしまうのが話が早いです。あと、Windowsではmakeをどうするの、とかよくわからなかったのでコンパイルはMacでやりました。実はBash on Ubuntu on Windows 10でがんばってみたんだけど断念。いま思えばLinux用Arduino IDEから拾えばよかったのかも。

コンパイルに必要な変更は、Makefileの「F_CPU = 16000000」を8000000に変更するだけ。あと、bootloaderはCaterinaを使っていて、USBのVID/PIDは、Arduino LLCのVIDとLeonardoのPIDが書かれたままになっていますが、目をつぶってそのままに。おかげでlsusbすると「Arduino SA Leonardo ( CDC ACM, HID)」と出ますが、まあそういうことであります。

pbrookさんのWikiには、Arduino IDEのhardware/avr以下を置き換えろみたいな乱暴なことが書かれていますが、そうするとMacの場合、Arduino IDEが上がらなくなってしまいました。

で、Windowsのほうではどうだろうと、SurrealityLabsさんのplatform.txtには1.6.0と書かれているので1.6.0でがっつり置き換えると、まあ起動はしましたが、bootloaderを書こうとすると、「書き込み装置の選択をしろ」的なメッセージが出て先に進みません。AVRISP mkIIを使っているので、それを選択してあるんですが、どうもだめ。

そこで再び検索すると、こんなブログエントリがありまして
Arduino IDE on Windows with Minimus32 Profile
なんだか、「一式固めといたよ」としてZIPファイルがリンクされていました。ですが、これを展開するとバッチファイルがありまして、Arduino IDE 1.0.5をダウンロードしてそこに置き換えのツールチェインとpbrookさんのリポジトリのZIPを配置する、というような仕立てになっておりました。

それができた状態で、Macで作ったhexファイルをもとのものと置き換えるものの、こちらではbootloaderを書き込もうとするとJavaのランタイムエラーが出てだめでした。Windows 10(1608版)なんですが。

もうこれはavrdudeのコマンドラインでいくしかないかな、と思いつつ、「もしやMacでこれと同じ構成にしたらうまくいくんではないか?」と思ったところ、うまくいきました。

Arduino IDEの設計は全くわかっていないんですが、hardware以下にarduinoというフォルダがあるところを、上のバッチファイルで作成した1.0.5版では、minimusというフォルダを隣に作り、pbrookさんの一式はこちらにまるっと入れるという仕上がりになっていて、既存のファイル、特にboards.txtなんかは一切書き換えていないのですが、起動したArduino IDEではきちんとminimus以下のboards.txtの内容が反映されていたわけです。

ということで、Macの1.6.11でも同様に、hardware/minimusというフォルダを作り、一式をそこに放り込み、LUFA-111009も放り込んでMakefileavr-gcc等を呼び出すパスの追記やLUFAのパスを現状に合わせます。それから、macOSの認証を通すために一度無改造のままArduino.appを起動してからなかみの変更をする必要がありますが、最初の起動時に、ボード設定その他をJSON形式で ~/Library/Arduino15 以下に置くので、それをリセットするために、このフォルダごと消しておきます。

そして、とても大事なことなんですが、3.3Vにしたので、boards.txtに記述するAVRのフューズビットの設定を変更し、ブラウンアウト(電圧低下)検出 の電圧を3Vから2.7Vにしておかないと不安です。フューズビットは書き込み時にavrdudeのコマンドラインをArduino IDEが生成するときboards.txtを参照するので、その16進の値を理解して、適切に設定した内容を書いておかなければなりません。

ここで、AVR Fuse Calculatorの出番です。ところが検索してもATmega32Uシリーズが入っているものがなかなかありませんが、なんとか見つけました。
Engbedded Atmel AVR® Fuse Calculator - Electronics-Base.com
で、「AVR Part Name」はATmega32U2ですからすぐ終わるわけですが、あとが困ります。わかんねえ。データシート全部読むのめんどい。

Atmelのデータシートの作りも不親切で、Fuse Bitについてまとめた項目がないんですよ。機能の説明があって、そこにFuse Bitはこう設定する、という部分的な表がばらばらにあるので、一覧できない。全部嫁ということになる。

まあいいや、ということで、既存のboards.txtでATmega32U4が採用されているものと、Minimus32の設定を見比べつつ、上の計算機の値をポチポチしてみると、Minimus32とU4採用Arduinoのfuse bitの設定は同じだということに気づくわけです。Yún, Leonardo, Micro, Esplora, Lilypad USB、どれとも共通です。すると問題になるのはBODの電圧設定のみで、それはextendedの項目であり、5V版である既存設定では3.0V。U2の場合選べるのは最低2.7Vしかないので、そこだけを変更。すると、0xf8が0xf6になるだけだ、という結論が導かれました。

ということで、既存のminimus32の設定を複写して、minimus32v33とかクラス名を変更したところで、name=Minimus 32 (3.3V)とか書いて、bootloader.extended_fuses=0xf6と書き換えます。あと、build.f_cpu=8000000L も忘れずに変更しておきます。build.usb_productにも「3V3」を追記して、これでおしまい。

参考までに、作ってみた部分を掲載しておきます。
#############################################################

minimus32v33.name=Minimus 32 (3.3V)
minimus32v33.vid.0=0x2341
minimus32v33.pid.0=0x0036
minimus32v33.vid.1=0x2341
minimus32v33.pid.1=0x8036
minimus32v33.upload.tool=avrdude
minimus32v33.upload.protocol=avr109
minimus32v33.upload.maximum_size=28672
minimus32v33.upload.speed=57600
minimus32v33.upload.disable_flushing=true
minimus32v33.upload.use_1200bps_touch=true
minimus32v33.upload.wait_for_upload_port=true

minimus32v33.bootloader.tool=avrdude
minimus32v33.bootloader.low_fuses=0xff
minimus32v33.bootloader.high_fuses=0xd8
minimus32v33.bootloader.extended_fuses=0xf6
minimus32v33.bootloader.file=caterina/Caterina-Minimus.hex
minimus32v33.bootloader.unlock_bits=0x3F
minimus32v33.bootloader.lock_bits=0x2F

minimus32v33.build.mcu=atmega32u2
minimus32v33.build.f_cpu=8000000L
minimus32v33.build.vid=0x2341
minimus32v33.build.pid=0x8036
minimus32v33.build.usb_product="Minimus32 3V3"
minimus32v33.build.usb_manufacturer="Arduino"
minimus32v33.build.board=MINIMUS32
minimus32v33.build.core=minimus
minimus32v33.build.variant=minimus32
minimus32v33.build.extra_flags={build.usb_flags}
追記するのは、minimusフォルダ以下のboards.txtだけでよいです。arduino以下には一切触りません。

それでArduino IDE 1.6.11を起動して、ボードの選択をすると、ちゃんとArduinoとMinimusでカテゴリが分けられて選択できるようになりました。よくできてる。
ボード選択メニューの下に追加された
この状態で、「ええい、ままよ」と彼岸島な心で「ブートローダーの書き込み」を選択すると、さっくりと書き込まれまして、USBデバイスを再認識したアラーム音がmacOSから鳴りました。ちゃんとシリアルポートも選べます。でかした! ヤンヤヤンヤ

ためしにスケッチを書いて、コンパイルと転送が通るかも試します。といっても、いまは何もないので、SerialオブジェクトがUSBに割り当てられているのを使って、IDEのシリアルモニタから入力があったら"Hello"を印刷する簡単なスケッチを作り、コンパイルと転送してみました。なにやら「Minimusには対応していません」な警告が3つぐらい出ましたが、そのままコンパイルを終えて書き込みまでさくっと完了しました。感動。

USBの標準速度が57600bpsになっているので、Serial.begin(57600); などと書き、シリアルモニタの設定も57600bpsにして適当な文字を入れ、「送信」ボタンを押すと、"Hello"が出ました。動いているようです。これで、追加の回路も載せて制御できる見通しが立ちました。よかったよかった。

なんですが、ひとつ回路について重大なことを書くのが遅くなりました。このブログエントリは流れ的にソフトウェアの話でいったん完結させるしかなかったので、最後ですが、自作されようとする方のために、また自分の作業記録として、書かなければなりませんので、ここに記します。

Minimus32の解析サイトに回路図がありますが、これをみると、普通のArduinoには見慣れない「HWB」というタクトスイッチがあります。pbrookさんのWikiにも図があって、リセットと隣合わせに並んでいるようです。そして、データシートを見ると、2ページのピン配置図では13番ピンに、「#HWB」なる端子があります(#は負論理)。さらに、他のU4を使ったArduinoでもフューズビット設定で、「Hardware Boot Enable」にチェックを入れています。「ハードウェアブート」はArduinoにおいて重要らしい。

Minimus32の商品(?)では、まじめにそのボタンをつけているんですが、U4を使った他のArduinoにそんなボタンはありません。なんでだろうと思ってデータシートを読むと、「HWBがLのときにRESETがUPするとハードウェアリセットがかかる」とありました。めんどくせえ。それで、手持ちのArduino Nanoの回路図をみたところ、HWBのラインは10kΩの抵抗を通してプルダウンされており(GNDに接続)、わざわざ「USB RESET EN」と書かれていました。HWBをプルダウンしておけば、リセットラインのL→Hの瞬間にリセットがかかるわけで、「これでいいのだ」ということのようです。よって、このピンはプルダウンしておきました。

それから、Minimus32はあえてICSP端子を設けていません。が、最初にbootloaderを書くにはICSPの6端子を用意しておいたほうが便利なわけでして、僕はつけておくことにしました。U2だと15ピンがSCK、16ピンがMOSI、17ピンがMISOと、SPI端子が連続しているので作りやすいと思います。

あと、要注意な点として、Minimusのピン配列は普通のArduinoとはだいぶ違います。pbrookさんのWikiの図必携。

具体的には、HardwareSerialSerial1)はD2がRx、D3がTxですし、D6, D7はUSBの送受信表示のLEDに使われています。D8はHWBで今回はプルダウンされたまま。さらにU2の制約として、タイマーは0(16bitカウンタ)と1(8bitカウンタ)の2つしかないのでPWMは4つですが、D1, D17がタイマー0、D19とD21がタイマー1という配置。

タイマーという点では、標準ライブラリのServo()はタイマー1を使うのでたぶん動くと思いますが、タイマー0はmills()delay()など時間関係の関数のために保留されていて、analogWrite()は使えるよう考慮されているものの、Tone()のために使うことはできず鳴りません。ためしにD1を指定してみたものの、コンパイルは通っても実際には鳴りませんでした。

ただ、タイマー1で音を出すライブラリはいくつかあるようなので、Servo()に興味がなく、音を出したいという用途にはそれらを使うのだろうと思います。
最初のは正確な音程とコードのシンプルさ追求、2番目はタイマー出力2ピン両方をスピーカーにつなぐ形での音質追求、最後のはタイマー0のプリスケーラを1にして(分周しない)、超音波まで出せて音量調節まで実現するかわりに時間関数は破綻してよしとするなど、標準ライブラリに物足りない人向けのようです。

長くなりましたが、こちらからは以上です。

ATmega32U2にArduinoのbootloaderを書き込んでArduino IDEが使えるようにした

とある事情から、ATmega32U2をArduino化する必要があり、いろいろと困っておりましたが、解決したので記録を兼ねてご報告。

まずATmega32U2がArduinoになるのか、ということですが、「ATmega32U2にはADCもI2Cもない」。アナログ入力がないわけです。それらが揃っているのはU4のほう。U4はArduino Leonardoに始まり、各種のボードが販売されているものの、U2は機能不足だから商品化するメリットないよね、と納得しました。

とはいえU2ちっちゃいしピン数もU4より少なくて値上がりしたとはいえまだ秋月で400円だし、もう撤退できない状況があるので、検索をGoogleに変更してみたところ、わりとあっさりとkosakailabさんのブログエントリがヒットしまして、
ATmega32U2でArduinoモドキを作る - kosakailab
Minimus32という商品(?)がかつてあったらしいことを知りました。

こちらMinimus32解析サイトによりますと、www.minimususb.comというドメインがOfficialだということでリンクが貼ってあるんですが、いま見ても日本語で2015年頃にゲーミングマウスがどうとかいう数個のエントリが掲載されたブログが表示されるのみでして、経緯がよくわかりません。他のリンク先もドメインが無効だったりして、情報不足であります。

ただ、kosakailabさんがGitHubリポジトリとbootloader作成の手がかりを示してくださっているので、一通り道具は揃いました。
pbrook/minimus-arduino - GitHub
実際のところ、5V電源で16MHzのクロックを使うなら、すでにhexが置いてあるのでコンパイルする必要はないんですが、3.3V動作にする都合でクロックを8MHzに変更する必要があり、Makefileを書き換えてコンパイルする必要があった次第。
データシートの26.3項に、「安全動作圏」を示したグラフがあり、8bitのAVRマイコンでは3.3Vでは10MHz以下のクロックにしなければなりません。Arduinoでは3.3V製品としてSparkFun製Arduino Pro Miniの3.3V版があり、それに合わせて8MHz設定が公式ライブラリに追加されているので、3.3V動作の場合、8MHzのクリスタル一択です。
bootloaderコンパイルにはLUFAが必要だよ、と書かれています。Unoが搭載しているUSB-UART変換にいまはATmega8U2が使われていますが、かつてはATmega16U2が使われていたこともあり、それらには、LUFAが活用されているようです。
オフィシャルサイトは「(2013)」と但し書きがついていますが、GitHubリポジトリは今年も更新されているようです。ともかくも、LUFAは、USBつきAVR開発支援軽量ライブラリとのこと。

さてそんじゃあbootloader作るべし、となるのですが、minimusプロジェクトが3年前で止まっているので、ちと工夫が必要でした。

まず、pbrookさんのレポジトリですが、Forkとjoinのグラフをみると、2年前にSurrealityLabsさんが手を加えたのがいまの最新っぽく見えました。
SurrealityLabs/minimus-arduino - GitHub
これを開くといきなり「avr」しか見えなくて不安になりますが大丈夫、全部入ってます。

よって、ここからgit clone。あとLUFAですが、最新のリポジトリからもってきたものはいろいろ構成がかわっているようで、コンパイルが通らず、Makefileに書かれていた111009(2011年10月9日版)を公式サイトからダウンロードしてくるのが簡単でした。

配置ですが、avr-gccなどツールチェインをArduino IDEから借りるのが手っ取り早いので、すでにインストールしてあるArduino IDE 1.6.11に組み込んでしまうのが話が早いです。あと、Windowsではmakeをどうするの、とかよくわからなかったのでコンパイルはMacでやりました。実はBash on Ubuntu on Windows 10でがんばってみたんだけど断念。いま思えばLinux用Arduino IDEから拾えばよかったのかも。

コンパイルに必要な変更は、Makefileの「F_CPU = 16000000」を8000000に変更するだけ。あと、bootloaderはCaterinaを使っていて、USBのVID/PIDは、Arduino LLCのVIDとLeonardoのPIDが書かれたままになっていますが、目をつぶってそのままに。おかげでlsusbすると「Arduino SA Leonardo ( CDC ACM, HID)」と出ますが、まあそういうことであります。

pbrookさんのWikiには、Arduino IDEのhardware/avr以下を置き換えろみたいな乱暴なことが書かれていますが、そうするとMacの場合、Arduino IDEが上がらなくなってしまいました。

で、Windowsのほうではどうだろうと、SurrealityLabsさんのplatform.txtには1.6.0と書かれているので1.6.0でがっつり置き換えると、まあ起動はしましたが、bootloaderを書こうとすると、「書き込み装置の選択をしろ」的なメッセージが出て先に進みません。AVRISP mkIIを使っているので、それを選択してあるんですが、どうもだめ。

そこで再び検索すると、こんなブログエントリがありまして
Arduino IDE on Windows with Minimus32 Profile
なんだか、「一式固めといたよ」としてZIPファイルがリンクされていました。ですが、これを展開するとバッチファイルがありまして、Arduino IDE 1.0.5をダウンロードしてそこに置き換えのツールチェインとpbrookさんのリポジトリのZIPを配置する、というような仕立てになっておりました。

それができた状態で、Macで作ったhexファイルをもとのものと置き換えるものの、こちらではbootloaderを書き込もうとするとJavaのランタイムエラーが出てだめでした。Windows 10(1608版)なんですが。

もうこれはavrdudeのコマンドラインでいくしかないかな、と思いつつ、「もしやMacでこれと同じ構成にしたらうまくいくんではないか?」と思ったところ、うまくいきました。

Arduino IDEの設計は全くわかっていないんですが、hardware以下にarduinoというフォルダがあるところを、上のバッチファイルで作成した1.0.5版では、minimusというフォルダを隣に作り、pbrookさんの一式はこちらにまるっと入れるという仕上がりになっていて、既存のファイル、特にboards.txtなんかは一切書き換えていないのですが、起動したArduino IDEではきちんとminimus以下のboards.txtの内容が反映されていたわけです。

ということで、Macの1.6.11でも同様に、hardware/minimusというフォルダを作り、一式をそこに放り込み、LUFA-111009も放り込んでMakefileavr-gcc等を呼び出すパスの追記やLUFAのパスを現状に合わせます。それから、macOSの認証を通すために一度無改造のままArduino.appを起動してからなかみの変更をする必要がありますが、最初の起動時に、ボード設定その他をJSON形式で ~/Library/Arduino15 以下に置くので、それをリセットするために、このフォルダごと消しておきます。

そして、とても大事なことなんですが、3.3Vにしたので、boards.txtに記述するAVRのフューズビットの設定を変更し、ブラウンアウト(電圧低下)検出 の電圧を3Vから2.7Vにしておかないと不安です。フューズビットは書き込み時にavrdudeのコマンドラインをArduino IDEが生成するときboards.txtを参照するので、その16進の値を理解して、適切に設定した内容を書いておかなければなりません。

ここで、AVR Fuse Calculatorの出番です。ところが検索してもATmega32Uシリーズが入っているものがなかなかありませんが、なんとか見つけました。
Engbedded Atmel AVR® Fuse Calculator - Electronics-Base.com
で、「AVR Part Name」はATmega32U2ですからすぐ終わるわけですが、あとが困ります。わかんねえ。データシート全部読むのめんどい。

Atmelのデータシートの作りも不親切で、Fuse Bitについてまとめた項目がないんですよ。機能の説明があって、そこにFuse Bitはこう設定する、という部分的な表がばらばらにあるので、一覧できない。全部嫁ということになる。

まあいいや、ということで、既存のboards.txtでATmega32U4が採用されているものと、Minimus32の設定を見比べつつ、上の計算機の値をポチポチしてみると、Minimus32とU4採用Arduinoのfuse bitの設定は同じだということに気づくわけです。Yún, Leonardo, Micro, Esplora, Lilypad USB、どれとも共通です。すると問題になるのはBODの電圧設定のみで、それはextendedの項目であり、5V版である既存設定では3.0V。U2の場合選べるのは最低2.7Vしかないので、そこだけを変更。すると、0xf8が0xf6になるだけだ、という結論が導かれました。

ということで、既存のminimus32の設定を複写して、minimus32v33とかクラス名を変更したところで、name=Minimus 32 (3.3V)とか書いて、bootloader.extended_fuses=0xf6と書き換えます。あと、build.f_cpu=8000000L も忘れずに変更しておきます。build.usb_productにも「3V3」を追記して、これでおしまい。

参考までに、作ってみた部分を掲載しておきます。
#############################################################

minimus32v33.name=Minimus 32 (3.3V)
minimus32v33.vid.0=0x2341
minimus32v33.pid.0=0x0036
minimus32v33.vid.1=0x2341
minimus32v33.pid.1=0x8036
minimus32v33.upload.tool=avrdude
minimus32v33.upload.protocol=avr109
minimus32v33.upload.maximum_size=28672
minimus32v33.upload.speed=57600
minimus32v33.upload.disable_flushing=true
minimus32v33.upload.use_1200bps_touch=true
minimus32v33.upload.wait_for_upload_port=true

minimus32v33.bootloader.tool=avrdude
minimus32v33.bootloader.low_fuses=0xff
minimus32v33.bootloader.high_fuses=0xd8
minimus32v33.bootloader.extended_fuses=0xf6
minimus32v33.bootloader.file=caterina/Caterina-Minimus.hex
minimus32v33.bootloader.unlock_bits=0x3F
minimus32v33.bootloader.lock_bits=0x2F

minimus32v33.build.mcu=atmega32u2
minimus32v33.build.f_cpu=8000000L
minimus32v33.build.vid=0x2341
minimus32v33.build.pid=0x8036
minimus32v33.build.usb_product="Minimus32 3V3"
minimus32v33.build.usb_manufacturer="Arduino"
minimus32v33.build.board=MINIMUS32
minimus32v33.build.core=minimus
minimus32v33.build.variant=minimus32
minimus32v33.build.extra_flags={build.usb_flags}
追記するのは、minimusフォルダ以下のboards.txtだけでよいです。arduino以下には一切触りません。

それでArduino IDE 1.6.11を起動して、ボードの選択をすると、ちゃんとArduinoとMinimusでカテゴリが分けられて選択できるようになりました。よくできてる。
ボード選択メニューの下に追加された
この状態で、「ええい、ままよ」と彼岸島な心で「ブートローダーの書き込み」を選択すると、さっくりと書き込まれまして、USBデバイスを再認識したアラーム音がmacOSから鳴りました。ちゃんとシリアルポートも選べます。やったー!

ためしにスケッチを書いて、コンパイルと転送が通るかも試します。といっても、いまは何もないので、SerialオブジェクトがUSBに割り当てられているのを使って、IDEのシリアルモニタから入力があったら"Hello"を印刷する簡単なスケッチを作り、コンパイルと転送してみました。なにやら「Minimusには対応していません」な警告が3つぐらい出ましたが、そのままコンパイルを終えて書き込みまでさくっと完了しました。感動。

USBの標準速度が57600bpsになっているので、Serial.begin(57600); などと書き、シリアルモニタの設定も57600bpsにして適当な文字を入れ、「送信」ボタンを押すと、"Hello"が出ました。動いているようです。これで、追加の回路も載せて制御できる見通しが立ちました。よかったよかった。

なんですが、ひとつ回路について重大なことを書くのが遅くなりました。このブログエントリは流れ的にソフトウェアの話でいったん完結させるしかなかったので、最後ですが、自作されようとする方のために、また自分の作業記録として、書かなければなりませんので、ここに記します。

Minimus32の解析サイトに回路図がありますが、これをみると、普通のArduinoには見慣れない「HWB」というタクトスイッチがあります。pbrookさんのWikiにも図があって、リセットと隣合わせに並んでいるようです。そして、データシートを見ると、2ページのピン配置図では13番ピンに、「#HWB」なる端子があります(#は負論理)。さらに、他のU4を使ったArduinoでもフューズビット設定で、「Hardware Boot Enable」にチェックを入れています。「ハードウェアブート」はArduinoにおいて重要らしい。

Minimus32の商品(?)では、まじめにそのボタンをつけているんですが、U4を使った他のArduinoにそんなボタンはありません。なんでだろうと思ってデータシートを読むと、「HWBがLのときにRESETがUPするとハードウェアリセットがかかる」とありました。めんどくせえ。それで、手持ちのArduino Nanoの回路図をみたところ、HWBのラインは10kΩの抵抗を通してプルダウンされており(GNDに接続)、わざわざ「USB RESET EN」と書かれていました。HWBをプルダウンしておけば、リセットラインのL→Hの瞬間にリセットがかかるわけで、「これでいいのだ」ということのようです。よって、このピンはプルダウンしておきました。

それから、Minimus32はあえてICSP端子を設けていません。が、最初にbootloaderを書くにはICSPの6端子を用意しておいたほうが便利なわけでして、僕はつけておくことにしました。U2だと15ピンがSCK、16ピンがMOSI、17ピンがMISOと、SPI端子が連続しているので作りやすいと思います。

あと、要注意な点として、Minimusのピン配列は普通のArduinoとはだいぶ違います。pbrookさんのWikiの図必携。

具体的には、HardwareSerialSerial1)はD2がRx、D3がTxですし、D6, D7はUSBの送受信表示のLEDに使われています。D8はHWBで今回はプルダウンされたまま。さらにU2の制約として、タイマーは0(16bitカウンタ)と1(8bitカウンタ)の2つしかないのでPWMは4つですが、D1, D17がタイマー0、D19とD21がタイマー1という配置。

タイマーという点では、標準ライブラリのServo()はタイマー1を使うのでたぶん動くと思いますが、タイマー0はmills()delay()など時間関係の関数のために保留されていて、analogWrite()は使えるよう考慮されているものの、Tone()のために使うことはできず鳴りません。ためしにD1を指定してみたものの、コンパイルは通っても実際には鳴りませんでした。

ただ、タイマー1で音を出すライブラリはいくつかあるようなので、Servo()に興味がなく、音を出したいという用途にはそれらを使うのだろうと思います。
最初のは正確な音程とコードのシンプルさ追求、2番目はタイマー出力2ピン両方をスピーカーにつなぐ形での音質追求、最後のはタイマー0のプリスケーラを1にして(分周しない)、超音波まで出せて音量調節まで実現するかわりに時間関数は破綻してよしとするなど、標準ライブラリに物足りない人向けのようです。

長くなりましたが、こちらからは以上です。

2016年8月15日月曜日

FTDI VCPドライバが正常動作しない場合(El Capitan 10.11.6)

Arduino Nanoを最近使っていて、Macでシリアルデバイスが突然消えるので困っていた。

最初は/dev/{cu,tty}.usbserial-xxxxが生えるのだが、ポートを開いたり閉じたりしているといつのまにかデバイスが消えている。kextstatすればFTDIのカーネルモジュールはロードされているし、なにが起きているのかよくわからなかった。

というわけで、Google先生にお伺いを立ててみたところ、我らがParallaxのページに、「バージョン2.2.18と2.3があるが、10.9 (Mavericks)以後は2.3じゃないとだめだよ」ときちんと書いてあった。

いやまさか、最新ドライバに入れ替えたはずだと思ってFTDIのVCPドライバのページを見ると、同じことが書いてあり、El Capitanなら2.3の一択。間違えようがない。

不審に思ってkextstatすると、「com.FTDI.driver.FTDIUSBSerialDriver (2.2.18)」。ああすみません(泣)。

カーネルモジュールなので、kextunloadできるはずだと実行するも、「1 instanceがあるからunloadできないよ」と言われる。さっきまでつないでいたFTDIチップ搭載基板(Modern Device社のUSB BUB初代品)のせいで作られたインスタンスがなにかをつかんでいて消えないんだろう。

やむなく
# rm -rf /System/Library/Extensions/FTDIUSBSerialDriver.kext
を実行して再起動。そして、バージョン2.3を確認してダウンロードし、インストール。基板を接続すると、ちゃんと /dev/{cu,tty}.usbserial-xxxx が生えてきたのでkextstat。無事「com.FTDI.driver.FTDIUSBSerialDriver (2.3)」がおりました。よしよし。

カーネルモジュールちゃんとあるよね、と/System以下を見るも見当たらず、mdfindしたら、/Library/Extensions/FTDIUSBSerialDriver.kextに移動していた。あとからインストールしたものだから、たしかにこちらにあるべきで、いままでは何かの理由で/System以下に置いていたのだろうか、謎。

検索では「Mavericks以後はApple版のFTDIドライバがいるけれど不具合が云々」、というエントリがたくさんヒットしたのだけれど、「ドライバのバージョン間違いしてないか」を確かめることを注意したものが見当たらなかったので、書いておくことにしました。いや、そんな間抜けはいないのかもしれませんが、ここに1名おりまして。

それらの解説では、MavericksではApple版とFTDI版のkext両方がロードされてコンフリクトするようですが、El Capitanでは、FTDI版があればApple版ドライバがロードされることはないようでした。為念。

2016年8月10日水曜日

Raspbian JessieがWindows用USBタッチスクリーンディスプレイに対応していた件

モンゴル方面からテクニカルな相談が相次ぐ昨今、Raspberry Piのタッチディスプレイをプロジェクタに映せないかという、検索するとよくある「それできません」な要件がありました。

いろいろ調べてみたところ、usbtouchdisplayというドライバがLinux kernel 3のどこかで入った模様をつかみ、だめもとで、Windows 10で使っている「Dell S2340T」23インチ10点マルチタッチディスプレイをUSBとHDMI接続して、Raspbianをそのまま起動してみました。

lsusbしてみた結果がこれ。
Raspbian JessieにDell S2340Tを接続してlsusb
"MicroTouch Systems, Inc"というのが見えますね。さらにDisplayLinkも見えました。いや素晴らしい。HDMIなくてもDisplayLinkに対応していればUSBだけでいけるということなんではないでしょうか(そっちも試せという声が... いやすみません)。

試しにタッチしてみました。
どうもキャリブレーションは必要なようですが、とにかく指に反応する様子は確認できました。

検索では皆さんいろいろご苦労されている様子があったので、ゆうべはずいぶん悩んで調べていたのですが、たぶん、たいていのWindows用外部ディスプレイのUSBマルチタッチは対応しているんではないかと思います。

モンゴル方面には、なにか適当なマルチタッチディスプレイとHDMIスプリッタを用意せよと連絡して完了。よかった。

ひとまず速報的にお知らせいたします。