20120225

Blink the LED!


前回に引き続きUSB-1608FSネタ。

あの後、取り込みを行おうと色々やってみても上手くいかなかったので、とりあえずより簡単そうな「LEDの点滅」でヒントを手に入れようと。
参考にしたのはSnoopyProの出力とUSB-1608FSのLinux向けサードパーティ製ドライバのソースコード(C言語)
それと、数々の先人達のページ等々(最後に列挙)。

SnoopyProは、PCとUSB機器の間で行われる通信を「嗅ぎ回る(snoop)」ソフトウェア。
上の画像のような結果が得られます。
因みにアイコンはスヌーピー。
ヘルプも読まず、しばらく使い方が分からずにいたのは自分です。
これは残念ながらLinuxでは使えなかったのでWindowsでsnoopしました。

ドライバのほうは、これを入れてしまえばPythonからC言語のライブラリを扱えるctypeで使うことが出来る、と踏んでいたのに上手いことインストール出来ず断念。
中でやっていることをPyUSB的に書き直す、という具合のことをやっております。

さて、USB-1608FSに付属のInstaCalでインジケータLEDを点滅させたところまでのsnoop結果が上の画像になります。
初期化云々で436パケット、その後のLED点滅で2パケット増加しましたので、その最後の2パケットに「LED点滅命令」が含まれているはず!
「TransferBuffer」のある227 out downが怪しいと考え、各種引数に対応する(と思う)値を代入して

USB1608FS.ctrl_transfer(0x22, 0x09, 0x40, 0x02, [0x40, 0x00])

しましたが

USBError: Input/output error

ここでまたもやしばらく悩むことに。
しかしながら何故か閃き

USB1608FS.ctrl_transfer(0x21, 0x09, 0x40, 0x02, [0x40, 0x00])

という具合に第1引数(bmRequestType)を227 out downに続く227 out upで使われている値に変更したところ、通った!点滅した!


よし、この勢いで取り込み!
とはいきません…


因みに

USB1608FS.ctrl_transfer(0x21, 0x09, 0x0, 0x0, [0x40, 0x00])



USB1608FS.ctrl_transfer(0x21, 0x09, 0x40, 0x02, [0x40])

でも点滅したので実際のところ重要なのは「0x21」「0x09」「[0x40]」っぽいです。
最後の引数はリストにしないと「繰り返し不可」みたいなエラーが返ってきます。



参考ページ

libusbについて - Linux工作室
技術資料 - C言語 演算子
libusb: Synchronous device I/O
libusb-1.0 – libUSBとは 技術解説 電子デバイス・半導体 : 富士通usb
Hacking the Kinect - How to hack USB device drivers

20120216

detach_kernel_driverしまくってやればset_configurationが上手くいく



久々に真面目な話。
現在進行中の作業を公にすれば途中で投げ出すこともなかろうと。
それと、作業中にリファレンスが少なくてうがぁぁぁぁ!!となったので、このログが誰かの参考になれば幸い。


ここ最近、新しい実験システムの構築に取り組んでおります。
”出来るだけ安く”を目標にUbuntu+Pythonで作ろうとしているのですが、データ取り込み・A/Dコンバータ操作でハマり気味。
因みに現在はWindows XP+MATLABで実験しています。
MATLABなんて大体の研究室にあるんじゃないの?なんて考えていますが、今後それのない研究室にも移ることの出来るように、先にフリーのプログラミング環境であるPythonの勉強をしておこうかと。
それと趣味。
まあいくら金をかけたくなくてもPCだったり、アンプだったり、モニタだったり、今詰まってるA/Dコンバータだったりは必要なわけですが。
そもそも、今後移る先が電気生理の研究室では無い可能性もありますが。
そんな時でも、どんな時でも、出来る事は多いに越したことはあるまい。


さて本題。
開発環境はUbuntu 11.10 64bit。
使用するA/DコンバータはMeasurement Computing USB-1608FS
USB接続のこいつには公式のUbuntu(というかLinux)用ドライバが存在しないので、PythonからUSBを操作するPyUSBを用いて

import usb
USB1608FS = usb.core.find(idVendor = 0x09db, idProduct = 0x007d)
USB1608FS.set_configuration()

なんてやるとまずはPermission Deniedになりましたので、/etc/udev/rules.d/に中身が以下の60-mcc-usb1608fs.rulesなるファイルを作ってやりました。

BUS=="usb", SYSFS{idVendor}=="09db", SYSFS{idProduct}=="007d", MODE="0666"

Measurement Computing社(SYSFS{idVendor}=="09db")のUSB規格(BUS=="usb")のUSB-1608FS(SYSFS{idProduct}=="007d")が接続されたら、そいつの読み書きを許可(MODE="0666")しますよ、ということらしいです。
この会社の装置用の、Linux向けドライバを作ってるところ(ココ)を参考、というか必要部分だけをわざわざ抜き出しただけなのであまり理解出来ておりません。
まあでも一応こういうサイトは読みました。
SYSFS{idVendor}=="09db", SYSFS{idProduct}=="007d"だけで装置は一意に定まるのでBUS=="usb"は不要な気はしますが試していません。

さて、このファイルを作ったらTerminalで

/sbin/udevadm control --reload-rules

をやって、rulesファイルを読み込ませてやって、再度

import usb
USB1608FS = usb.core.find(idVendor = 0x09db, idProduct = 0x007d)
USB1608FS.set_configuration()

で今度は

USBError: Resource busy

と言われ、数日ハマってしまいました。
ググッてみるとdetach_kernel_driver()すればいいということは分かったのですが、引数がよく分からない。
interfaceってそれなんぞや?
とりあえず適当に0を入れてみたら

USB1608FS.detach_kernel_driver(0)

回りはしたのですが、それでも依然Resource Busy。
set_configuration()と同じ引数(装置依存のbConfigurationValueなる値、USB-1608FSの場合は1だが、指定しなければ内部で適当な値を見繕ってくれる)を入れて回してもResource Busy。

じゃあ色々な値を引数に取り得るので、片っ端からdetachしてやろうじゃないかと。

for i in range(100):
    if USB1608FS.is_kernel_driver_active(i):
        USB1608FS.detach_kernel_driver(i)

0-99の引数でdetach。
この値のレンジに特別意味はありません。
if USB1608FS.is_kernel_driver_active(i):で元々detachされてる数字は除外。
これでResource Busyにならなくなりました!
因みに、どの引数でdetachされるのかを見るためにprint iをつけてみると

0
1
2
3
4
5
6

が出力されましたので、forループはrange(7)で良さ気?
そもそも、この中のどの値のせいでResource Busyだったのかは調べていません。
たぶんどれか一つでいいのでしょうね〜

さて、これで早速記録可能か!?と喜びも束の間、なかなか先に進めずにまたもや数日ハマっているのが現在の状況です…
うがぁぁぁぁ!!

20120214

ヤツは来ない2012冬

今朝メールがあって、やっぱり来ないんだそうな。
む〜ん残念。
まあ掃除を急ぐ必要が無くなって助かったか。

ヤツが来る2012冬

ここ数年、夏に遊びに来ていた高校時代の友人が今日来るそうな。
まあ連絡自体は先週末に受けていたのですが。

で、自分はといえばここ数週間少しずつやっていた掃除を、ヤツの来阪に間に合わせて終わらせようかと思いましたが、無理でした。
しかし、とりあえず、自分がこっちに来てから手付かずだった(つまりかれこれ5年程そのままだった)浴室の天井のカビは処理しておきました。
もう本当、気持ちいい感じ。
浴室の白成分が高くなりました。
他の部分は…ヤツが来るまでに出来る限り…

ところでヤツは寝床はどうするつもりなんでしょう?
毎年夏に来て、マットレスだけはあると思ってるでしょうけれども、実は最近寝袋買ったんですよね、趣味で。
そのことをヤツは知らないはず。
ヤツも寝袋を持ってきたりしたら面白いのだが…