2008-10
神無月。†
- もうヨタ言やトンデモねたを書くのは止そう。現実化すると困ることばかりだ。
日記
- リサ・ランドールの「ワープする宇宙―5次元時空の謎を解く」(Warped Passages)を1日数ページづつ読んでいる。
- 誤解されないように書いておくと、これはトンデモ本ではなくて、真面目な物理の(一般向け)解説書だ。--ちょっと古い(2年くらい前の本だ)けどね。
- 20世紀の頭くらいから現在(LHC)までの素粒子物理学の歴史のおさらいのような感じ。(あくまで一般向け、だけど内容は濃い)
- 前半は読んでいると猛烈に眠気を催してすぐに寝てしまっていた。
- いまようやく半分まで読んで、すこしだけ面白くなってきたところ。(結構ページ数あるんだ。)
TORCHWOOD†
- 実は以前NHKなどで放映されていたBBCのドラマ、「DOCTOR WHO」の大ファンだったわけだが、
- DOCTOR WHOからスピンオフした(派生の)作品がBBCやBBC AMERICAで放映されているらしい。
- この作品もかなり興味がある。見てみたい。
- BBCのBigBangホームページになぜかTorchWood:LostSoulsというのがあって、雰囲気がDOCTOR WHOにとても似ていたので、TorchWoodのことを知ったというわけ。
- TorchWoodというのは、ビクトリア女王が設立したエイリアンと戦う組織(Men In Blackみたいな奴)のことで、DOCTOR WHOでも何回か出てきているのでおなじみかと思う。
- よくみると、DOCTOR WHOの文字を並べ替えるとTORCHWOODになる(アナグラム)という話はGoogle先生から教わった。
- 日本でも放映しないかな。無理っぽいけれど。
Glibの実装を見る†
- GarrayとかGByteArrayのコンテナ構造を見ると
struct GArray { gchar *data; guint len; };
とか、
struct GByteArray { guint8 *data; guint len; };
になっていて至極シンプルである。
- にもかかわらず、STLの<VECTOR>のようなコンテナを実現しているので 何故だろうと思って、glib2のソースをapt-getして見ていたら
struct _GRealArray { guint8 *data; guint len; guint alloc; guint elt_size; guint zero_terminated : 1; guint clear : 1; };
こうなっていた。
- ライブラリを使う人には最初の2要素しか見せない。
- 残りの要素はprivateということらしい。
- やっぱりそういうことだったんだよなぁ・・・。
どう考えても *dataとlenだけでは管理しきれない。
- 注意しないといけないことは、自分の構造体の中にGArrayやGByteArray の実体を含めるような書き方をしてはいけない、ということだ。
- 実体はGRealArrayなので、サイズが異なり、メモリー破壊を起こす。
- というかC++のnewのように、GArrayのインスタンスを受け取るように
しなければいけない。
GArray *a = g_array_sized_new( ... );
- まあ、そゆこと。
- 要素の追加に関しては、allocされた領域が十分残っているならば
data[len++] = add_data;
のような感じに追加されるし、残っていないなら<VECTOR>と同じように 領域全体を拡張されたメモリーブロックにコピーしたのちに同じことが 行われる。
USBaspのisp.cについて†
- ATmega88のマニュアルPDFに目を通しているが疑問点が1つある。
- というのは、SPIのクロックに関しての記述だ。
- mega88のSPIはハードウェアクロックであり、分周比を3ビットで指定 出来る。
- fclk/2〜fclk/128まで(7種類)だ。
- なぜか知らないがfclk/64がダブっているので8種類はない。
- では、-d<delay>のdelayが6〜255のときはどうするか?これが謎だった。
方法1
- マスターなのにスレーブにして、クロックは別のポートから引っ張ってくる方法。
- これだと、MISOとMOSIが逆転する。tiny2313のような感じ。
- 配線が増える。
- だけじゃなくて、低速モードのときにMISOとMOSIを反転させる外部回路が必要。
方法2
- ハードウェアSPIの機能を全部捨てて、SCK,MOSI,MISOの全部を単なる独立した I/Oポートとしてセットアップし、完全ソフトウェアSPIで行く。
- まだtiny2313のやりかたのほうがマシと思われるが、USIではないのでそうするしかなさそうだ。
- USBaspでは、後者の方法が取られていた。_hw()の関数と_sw()の関数を関数ポインタで切り替えていた。
HIDaspはほぼ日刊?†
- 手持ち基板を少し改造して、USBのD+、D−の接続をジャンパー切り替えにした。
- 旧回路での焼きこみチェックを行ってみた。
- やっぱり買ってきたばかりのtiny2313では、10回に3回くらい接続を認識しない。
- RESETシーケンスを悪あがきしたバージョンがあったので、それに差し替えて、接続性に関してはOKか。
- ATmega88を'-d0'で書くと、ベリファイエラーする。何故?
- 無意識のうちに水晶を12MHz化していたのを忘れていた。
- d0だと、SCKが3MHzになるが、これは 12MHz でマージン0になるようだ。読み出しだけはうまく行くことがある。
- d1だと、数回の書き込み実行は成功した。
今後の作業予定†
mega88
- とりあえずHW ISPの機能くらいは入れておく。
- SW ISPの機能まで入れると、おそらく関数ポインタを導入することになる(それがAVRでは一番効率がいい)ので 、まんまUSBaspのパクリになってしまい、面白くない。
- なので、とりあえずd0〜d5までにしておく。
- せっかくRAMが1Kあるので、4000サンプルくらいの高速サンプルをやってみる。
- 但し、サンプル中はUSB応答が出来ないので、USBが切り離される可能性がある。
- アナログスコープを作ってみる(予定)
tiny2313
- アナログ比較器でA/Dとか考えてみる。
HIDaspをさらに高速化するのであれば・・・†
- 高速化改良その4 でやりかけていた、インターリーブなisp処理を実装すると効果があると思う。
その場合の方針としては、
- '-d0'のループアンロールをやめて、'-d1'を最速とする('-d0'は'-d1'と同じにする)
- これは、'-d0'を使える場面が18MHz以上と、出番が少ないから、
- そして、アンロールはメモリーを食いすぎるので。
- HIDをやめて、libusb経由でドライブする(と、USBasp同様に8バイトパケット送信の間の空き時間にisp出来る)
- 内部の処理的には殆どUSBaspと同等になってしまうが、コマンド仕様はHIDaspとほぼ同じ。
そうすると、USBaspと同等の速度で'-d2'か'-d3'の書き込みが出来るような気がする(気のせい?)
技術的には出来そうな気がするんだけれど、それはもうHIDaspと呼ぶものではなく、USBasp2313とでも呼ぶ代物であるので、実装するつもりは毛頭ない。
- 単に2kに入れる練習にはなるよ。そりゃ。暇つぶしにはね。
- でも、暇な人がいるかもしれないので、(USBasp2313)種だけは蒔いておこう。
- テストアーカイブ:hidspx-test-0925a.zip
avr-size --mcu=attiny2313 main.elf text data bss dec hex filename 1930 2 54 1986 7c2 main.elf
- 注意:manufacture,productsが1文字になっていて、さらにdelay()ループも取り去っているので修正が必要。
- この実装からHIDを外して、普通のコントロール転送にしたほうがUSBaspそっくりになる。
- メモリー的にはぎりぎり境界線か?
- ちなみに、本物のUSBaspのサイズはこれくらいある。
avr-size main.bin text data bss dec hex filename 3540 2 65 3607 e17 main.bin
- HIDデバイスだと何故駄目なのかはまだ追求していないんだけど、予想ではHIDリクエストは優先順位が低いので、帯域制限が掛かっているのか、それともパケットのスケジュール上の優先度が低くて後回しにされるのか・・・。
- 一応、HIDパケットの優先度が低い件については、要調査かな。
- そういえば、瓶詰堂さんが書かれていた、HIDなのにlibusb経由でドライブする方法ってあるのかな。
- そもそもWindowsでは、device.infにlibusb0.sysって書いておかないとlibusbが捌いてくれないような気もしている 。
参考書はこのあたりかな?
謎な結果。†
一応、HIDパケットの優先度が低い件については、要調査かな。
- HID Report送信の遅延評価
- つまり、まだ改良の芽はあるわけだ。
そこで2択なんだけど
- UHCI(intelホスト)に限定するなら、HIDでインターリーブ方式のisp書き込みを採用するとベスト。(転送4.8kB/秒でUSBaspと同等)
- OHCI(AMD,SiS,NECホスト)なら、現行バージョンが今のところベスト。
但し、それぞれファームの書き方が変わるので、両方開発するのは大変だ。
- そのまえに、(高々)LowSpeedなのにそこまで速度を追求する意味あるのかな?と自問自答。
- tiny2313に焼いている限りだと、どっちでも充分。
実はもうひとつ。†
- 面白いことが分かってしまった。
- OHCIで、遅延を少し入れただけなのに妙に遅くなっている件を調べていたら、あることに気づいた。
- OHCIはUSBバス帯域を余らせないで使い尽くす傾向がある。
- ということは、AVR側に多大なCPU負荷を与えている可能性が高い。
- 遊んでいる暇を与えないのだ。
- USBパケットが流れてくる間中、INT1ハンドラ内で、割り込み禁止モードのサンプリングルーチンがCPU時間を食いまくっている。
- で、間髪入れずにまた次のパケットが来る。
- ということは、isp転送中は頻繁に、しかもかなりの間転送中断されている可能性がある。
- 試しに、isp転送を行っている間割り込み禁止にすると恐ろしく処理が速くなった。
ところが話はそううまくはいかない。データは化け化けになるので、なにか対策が要るのだろう。
LowSpeed ソフトUSBは奥が深いのぉ・・・
- ハードウェアUSBプロトコルエンジン積んだマイコンより1024倍くらい面白いぞ。
- なんだったら、自分でUSBドライバ書いてみ。
AVRUSB:flow controlを入れてみた。†
usbDisableAllRequests(); usbEnableAllRequests();
- これをispの前後に挟むことで、USB割り込みが来にくいようにすれば速くなるのではないか。
- 試してみた。
- やや速くなった気がする(ただし効果はOHCIに限定)
- というか転送限界に一歩近づいた?
と思ったら、AMDだと速いけれどSiSだとちょっと遅くて実はあんまり変わらない。
- やっぱり、FLOW_CONTROLあり、なしでの比較実験が必要?
- ここ1月くらいで2048に縮める技をいろいろ会得できたのでCDCデバイスを2048に入れようかな〜
- と思っている。
- recursionの田村さんが作成されたCDC2313は9600が 限界らしいけれど、38400にしたいなぁ・・・
- 自分の作ったAVR_termは19200はOKで38400だと文字落ちするので、落ちない38400がちょっと だけ欲しかったりする。
- FT232RLとかを貼り付けるハンダ技術があるなら、(FT232のほうが遥かに速いので)その必要すらないわけだけど・・・。
usbRS2313†
- 意外とあっさりできちゃいました。
- USBのD+、D−を (D,3,2)に変更し、INT1 -> INT0 に戻して、H8/tinyのUSB接続基板(AVR)
のファームを更新したところ、あっさりとH8のモニタに接続できました。
- 変更方法はusbconfig.hの (D,4,3)を定義しているところと、一番後ろのINT1の部分コメントアウトだけです。
- ボーレートは19200ですが、なんか安定動作しているようです。
- 所要メモリーは、某プロでだいぶ鍛えられたので、いきなり圧縮済。
avr-objcopy -j .text -j .data -O ihex main.elf main.hex avr-size main.elf text data bss dec hex filename 1912 10 99 2021 7e5 main.elf
- 速度38400での評価はまた後日。
ボーレート変更を実装†
- どうもPROGMEMに対するアクセスはマクロで書くと肥大化する。
- いんちきくさいアセンブラで書いてみたところ。
avr-objcopy -j .text -j .data -O ihex main.elf main.hex avr-size main.elf text data bss dec hex filename 1992 10 107 2109 83d main.elf
- あまりメモリーがないです。(残り46バイト)
- フロー制御等はまだ未実装。
- 特に送信バッファ溢れはちゃんと実装しないと。(未実装)
- とりあえず57600でも使えている(接続先はH8モニタ)のでまあいいか。
- H8モニタのHELPメッセージが改行しない(LFのみ)というつまらんBUGを自分で発見。わろた。
char melp_message[]= " .....\n" " .....\n" " .....\n";
- これがAVR_termでは改行表示になる。何故?
MIDIボーレートも実装。†
- USBでのフローコントロールが難しいので、送信バッファフルを別の方法で処理。
- いよいよメモリーがない
avr-objcopy -j .text -j .data -O ihex main.elf main.hex avr-size main.elf text data bss dec hex filename 2030 2 114 2146 862 main.elf
BUSY LEDも実装。†
avr-objcopy -j .text -j .data -O ihex main.elf main.hex avr-size main.elf text data bss dec hex filename 2010 2 106 2118 846 main.elf
- あつらえたようなサイズだな(ROM=2048 RAM=128)
ATtiny2313の良いところ。†
- 安い。
- 石は100円、水晶は50円、あとはCRなのでせいぜい100円以内。
- Xtalの負荷容量とかツェナーDiとか、無くても動くよ。もちろんあったほうがよい。
- USBケーブルは、壊れたマウスのしっぽを切って使えばタダ。コネクタ無しで基板にじか半田付け。
- 使い慣れたので、ICコネクタさえ使わなくなった。じか半田付け。
- コード、データの詰め込みパズルが楽しめる。
- 2048に達したら潔く諦めがつく。
- だらだらと機能追加の必要がない。
充分安価な「電子ブロック」だ。
- いや「電子ブロック」以上の優れたプログラミングToyだ。
usbRS2313 改良†
- ボーレートを任意整数で取れるように変更。
avr-objcopy -j .text -j .data -O ihex main.elf main.hex avr-size main.elf text data bss dec hex filename 1984 2 106 2092 82c main.elf
- PROGMEM table[] に対するテーブル引きをやめて、計算式を実行するようにした。
- 若干精度が落ちる。しかたない。
- 16bit演算を24bit演算にすれば改善できるが・・・20命令くらい増えるだろう。
- でも48000bpsとかも可能になった。
- H8/tinyのほうも任意整数ボーレートが出来るので、変なボーレートで接続して遊べる。
- 時間があればMIDIあたりも試せる。(もうMIDI機器は死滅済み?)
次のテーマはPS2キーボードを予定。†
(プレステ2のLinuxに付いて来たやたらスペースバーの長い106のことじゃあないよ)
- 突っ込む人いないけど念のため
- PS2キーボードは9600ボー程度の半二重シリアルっぽいやつ。
- なんだけど各ビット同期のためのクロック信号は自分で出すというやつ。
- AVR-USBが動作していると、その信号サンプルのタイミングが取れない(ポーリング、割り込みともに難しい)
- ので、AVR−USB抜きで制作して、シリアルに流す。
- シリアルは今日作った奴に繋いでPCから見る。
単にPS2−>シリアル変換を作るというようなテーマだが、応用としては
- AVRの入力スイッチとして、小さなタクトスイッチを基板につけたりするけれど、
- 押しにくいしキー数足らないし、キースキャンルーチン書くの面倒。
- なので、PS2フルキーでも繋ぐと、押しやすくなるゾウー。
- 最近ちっちゃいキーボードも売ってるし(USBタイプが多いけどあえてPS2)
- ELECOMとかのテンキーも同じプロトコルなので使える。
あと、ずっと放置していたAppleADB用の古いメカニカルキーボードをPS2に変換してパソコンで使いたいとか
- (それはPS2キーボードのふりをするファームになるので上とは逆だが)
- まあ、そういった野望。
- おそらく予定は予定のまま、永遠に予定かもしれない。
USBよりずっと楽です。
布団圧縮袋†
avr-objcopy -j .text -j .data -O ihex main.elf main.hex avr-size main.elf text data bss dec hex filename 1954 2 106 2062 80e main.elf
じゃあないけど、順調に縮んでいます。
- プチプチを潰す気分。
- シリアルNoを外すと1932まで縮むんだけど、そのファームを繋ぐと、自分のWindowsが必ずRESETされる。
- もう3回くらい問答無用RESETを食らって、CHKDSKが終わるまでずっと待っていた。
- おそろしいUSB平気になってしまった。(これはこれで何かネタ装置が作れそう)
- てっきり電源をショートさせたかとヒヤヒヤ。
- それを試すならシリアルNoの文字列と長さの#define をコメントアウトするだけでいい。
- もしかしてディスクリプタの内容も弄らないといけないっていうオチかな。
今週の標語
- tiny2313はプチプチじゃあありません
プチプチに興じていたので油断した。†
- 例のUSBシリアル変換器(付のH8/tiny)を人のパソコンに繋いでみた。
- 認識しないじゃん。
- なんで?
- どうやらCDCはinfファイルがいるらしい。
- HIDは要らなかったのにね。
- がっかりだ。
- AVR−USBでいろいろ実験していたので、obdevのCDC用VID,PIDはすでに登録されていて、自分のPCでだけ、ドライバー要らずで動くと勘違い。
いろいろ試してみたところ、以下の事実が判明†
- infファイルはavrdoper.infがそのまま使える。
- 注意点は、avedoper-vista.infを同じディレクトリにいれないでインストールすること。
- WinXPなのに何故かvistaのほう(brusbser.sys)を要求され、そんなファイルないよということになる。
- UHCI(i815)で試すと、38400では文字落ちする。19200が限界。
- ぜんぜんだめじゃあ。
結局のところ、UHCIではいくら頑張っても19200止まり
- OHCIでは57600くらいまでぎりぎりセーフっぽい。
- バルクのエンドポイントからの読み込みは普通に8kB/S行くはずなんだけど。8x8=64kBPS
- 可能性としては、他のトラフィックが割り込むことで、4kB/S(32kBPS)程度に落ちている。
- ますますUHCIだめ。どうしてくれよう。
- AVR-CDC.2008.08.25/のCDC-mega.pdfを読む限りでは、UHCIで57600キープ、NECのチップだと115200がOKの場合もあるようだ。
抜粋
b.p.s | HalfDuplex(interrupt) | FullDuplex(interrupt) | HalfDuplex(polling) | FullDuplex(polling) |
115200 | ○ | × | × | × |
57600 | ○ | ○ | × | × |
38400 | ○ | ○ | ○ | × |
19200 | ○ | ○ | ○ | ○ |
すでに決着済なのか・・・。
HIDaspxにinterrupt_in ENDPOINTがない件。†
瓶詰堂さんの日記にこう書かれてありました。
BSDにも対応したいところだけど, irukaさんに高速化していただいたものは, USBのエンドポイントが足りないせいでuhidドライバに蹴られます. それでも,HIDを名乗っているのでugenからもアクセスできません.どうしましょう. Macでも何やら怒られてますが,libusbからは見えるようです….
- HIDにはinterrupt_in ENDPOINTは必須なのでしょうか。
- 他のリファレンスプロジェクトでも、
#define USB_CFG_HAVE_INTRIN_ENDPOINT 1
にしているものが多いです。 - 1にしてみたら、100バイト以上溢れかえります。困りました。
- なにか方策はないものでしょうか・・・。
HIDspx-osx.tar.gzについて†
- 瓶詰堂さんは偉大です。
- osx版と言いながら、普通にLinuxでそのままコンパイル出来ます
- (要:libusb-devel)VineLinux 4.2では以下のようにしてライブラリを取得
# apt-get install libusb-devel
- (要:libusb-devel)VineLinux 4.2では以下のようにしてライブラリを取得
- hidasp.cのソースはHIDaspx版でした。
- これを試すためにわざわざLinuxを別マシンにセットアップして、ビルドまで来たところです。
まだ、HIDASPの認識までは来ていません。---別のPCにHIDASPを挿していました。
- root権限にしないとmanufacture stringが取得できないようです。
結論
- 瓶詰堂さんが公開されているmacos用のavrspxは、Linuxでそのままコンパイル出来、そのまま動作します。
- ターゲットのファームは千秋ゼミ版hidspx-1012.zipでOKです。
- ATmega88に書き込みを行うことが出来ました。
- 瓶詰堂さんは偉大です。
ありがとうございました。