2009年5月 3日 (日)

HDDインジケーター

ゴールデンウィークである。
本日付けの記事は、4月上旬の出来事を思い出しながら書いている。で、やっとここからゴールデンウィークの出来事を書く。今までのは全部前振り。

何か、電子工作的な事をしたい。仕事ではC#だのASP.netだの使っていたので、是非とも連休にはAVRでアセンブリを書きたい!半田付けしてチープな回路を作りたい!
で、思いついたのが新調したPCのHDDインジケータ。ケースにはHDD用のLEDが付いているのだが、1個のLEDをチカチカさせるんじゃなく、複数のLED連続してチカチカさせたい。HDDのロードゲージ見たいのを作ろうと思う。

作るものはこうだ。
Tiny2313のPB0~PB7にLEDを8こ繋ぎ、フォトカプラを介してマザーボードのHDD_LEDのピンヘッダをPD6に繋ぐ。タイマ割り込みでPD6を定周期で監視して、LEDの点灯制御を行う。HDDのアクセスが連続して検出される場合、それに応じて複数のLEDを点灯させる。

幸い、部品は手持ちのストックで賄えそうだ。
早速、AVR Studioを立ち上げファームを書く。シミュレータで動作を確認、うまく動きそうだ。今回は思いつきで始めたので、手順を深く考えていない。思いつきでガンガン作業を進めることにする。

取り敢えず、次はPCケースの前面パネルを分解して、LEDの配置を考える。

2009050307  

 

 

 

 

 

 

 

 

 

 

 

 
ファンがむき出しの状態のケースも、サイバーな感じで何かカッコいいかもと思いつつ、パネルのLED配置を決める。

2009050308

 

 

 

 

 

 

 

吸気用の穴にLEDを突っ込んで見たら、ぴったりのサイズだったので、裏側からホットボンドで止めてみた。

2009050309  

 

 

 

 

 

 

LEDにフラットケーブルを半田付けし、熱収縮チューブで処理する。めんどくさ。
ユニバーサル基盤にTiny2313を配置、適時配線する。回路が単純なので、回路図も配線図も書いていない。

2009050310 

 

 

 

 

 

 

電源はマザーボードで未使用のUSB用ピンヘッダから頂戴する。これをケースに固定する。

2009050311  

 

 

 

 

 

 

この状態で動作チェック。おお!ちゃんと動いてる。実際の動作をみてLEDの点灯タイミングを修正する。

2009050312  

 

 

 

 

 

 

 

 

 

 

 

 
ここまで、まる1日かけて完成。
LEDが流れる様に点灯する。ギャラクティカのサイロンみたいでカッコいい。

回路図,ドキュメント類は書いていないが、ソースを見たい人はこちら

回路図描きました。

| | コメント (0) | トラックバック (0)

2008年8月17日 (日)

USB応用

パフォーマンス・インジケーター その4

お盆も終わった。
会社も今週は夏休みである。が、会社のイントラネット上にある
出勤簿を見ると、何かみんな出勤になってる。
おっかしいなぁ~?

まあ、日本の零細企業の下層技術者の待遇なんてそんなもんか。

で、ペンディング状態になっていたAVRでCPUゲージであるが、
細部のすり合わせと、おざなりではあるがドキュメントを書いて
完結とする。
これを作成する事で、色々と調べたり理解したりした事も多いが、
後日まとめたいと思う。
Piavr06_2  

 

 

 

 

 

 

 
ダウンロード 

  次もUSBデバイスを作る。つもり・・・である。

| | コメント (3) | トラックバック (0)

2008年7月28日 (月)

USB応用

パフォーマンス・インジケーター その2

驚いた事にまたヤフオクにBeBoxが出品されている!
幻のマシンだと思っていたのに、そんなにタマ数があるのかい?
当然、先週とは別の方が出品されているのだが、あるところにあ
るもんだ。ただ、スタート価格が6万円なんでやはり手が出ない。
2週連続で指を銜えるはめになるとは思わなかった。

BeBoxほしいな~。

さて、AVRでCPUゲージであるが、土日を利用してファームと
デバイスドライバを書いてみた。

AVRのプログラムとなるファームは、昨年作ったUSBCOMIOを
流用し、LED制御を組み込んで見た。肝となるのが、4つのI/O
ピンを使用して10個のLEDを制御する所だが、これはMicrochip社
にあるアプリケーションノートTB023を参考にしている。ダイナミック
点灯させて、見かけ上同時に複数のLEDが灯っているようにしてみた。

デバイスドライバは新規に書いて見た。USBCOMIOとは違い仮想
COMのフィルタが必要ないので、煩雑なI/Oコントロールが無い分
コンパクトに仕上がった。
にしても、カーネルモードプログラミングは驚きに満ちている。
単純なバグでタスクマネージャーからも終了できないプロセスを
作り出したり、時計が止まるほどのパーフェクトなハングアップを
作ったり、自由自在である。もちろんブルースクリーンも簡単に
引き出せる。

ほんとに単純なミスなんだけどなぁ。

解ってしまえばあっけないバグを修正しつつ、デバイスドライバ完成。
テストアプリケーションを書いて動作を確認。

Piavr03  

 

 

 

 

 

 

ちゃんと動作している見たい。
次はWindows上の常駐アプリケーションだ。

今回、昨年書いたUSBCOMIOのコードを久しぶりに読んだが
なんかコードが汚い、よくこんなもんを公開してたもんだと
思わず赤面!公開した事に後悔する。(オヤジギャグ)

| | コメント (0) | トラックバック (0)

2008年7月26日 (土)

USB応用

パフォーマンス・インジケーター その1

ヤフオクにて発見!
かつて憧れだったBeBoX!!
PPC603eをデュアルで搭載、正真正銘マルチメディアOS搭載。
ユーザーインターフェイスも筐体のデザインも、とってもイカす。
ずっとウォッチしてたんだが、最終的に価格は99,000円まで高騰。

流石に手が出ないなぁ~。

泣く泣く入札を見送る事に。中古コンピュータに10万円なんぞ払え
る訳が無い。何年か振りに、指をくわえて(オークションページの)
BeBoxを眺める事になった。
筐体の左右にLEDが並んでいて、チカチカと2つのCPUの稼働率を
表示している様がカッコいいんだよなぁ。と実物を見た事はないが、
BeBoxの代表的なギミックCPUゲージに思いを馳せる。

BeBoXは手に入らなかったが、このCPUゲージ電子工作の題材とし
ては、お手軽でいいかも知れない。WindowsマシンのCPUゲージを
AVRでもって作ってみようと思う。

Windowsマシンの場合CPU使用率はPDHと呼ばれるAPIで得られる
らしい。パフォーマンスモニタで表示されるヤツだ。PDHならCPU以外
にもディスクやメモリの使用量も得られる。
そこで、Windows上で動作する常駐アプリでCPU使用率を取得し、
AVRで作成したLED表示器を制御する。これらの装置間IFはUSBを
使う。作成するものは以下の通り。

  • AVRを使ったLED表示器。PCからの制御はUSBで行う。
  • Windowsで動作し、LED表示器を制御する常駐アプリケーション。
  • IFとしてUSBを使用するので、専用のデバイスドライバ。

LED表示器のファームウェアやWindowsのデバイスドライバは、
USBCOMIOを流用改造する。WindowsアプリケーションはMFCを
使ってお手軽に作ってみる事にする。それぞれの作業は大した
事はないが、AVRのファームはアセンブリ言語、デバイスドライバ
はC言語、WindowsアプリはC++言語という夢の言語コンボを味
わえる。

う~ん。

開発環境も、フレームワークもそれぞれバラバラ。
取り敢えずLED表示器のハードウェアから手を付ける事にする。

で、ちゃちゃっとレイアウトをでっち上げて、作ったのがこれ。

Piavrcircuit02

Piavr01 Piavr02

 

 

 

 

 

 

 
うぅっ!2箇所LEDの極性を間違えた。
幸いソフトで何となりそう。でも、美しくないなぁ。

| | コメント (4) | トラックバック (0)

2007年10月21日 (日)

USB入門

USBCOMIO

最初は日々色々な事を書き綴ろうと始めたブログだが、このブログなんか電子工作ブログになってしまった感がある。結果、その筋のネタがないと書き込むべき記事が無くて、更新する気が起きなくなる。

いかん。

で、昨年からだらだらと続けている"AVRでUSB"であるが、最近
http://hp.vector.co.jp/authors/VA000177/html/FrontPage.html
AVRUSBEasyLoggerというのを知る。

これが凄い!何が凄いかと言うと、内蔵CR発振源のクロックで動作するUSBファームを書き上げている。実際ロースピードのUSBパケット1つを拾うのに必要な精度を以前計算した事があるが、とてもCR発振源では必要精度を満足させる事は出来ない気がする。
実際セラロックを使ってUSBファームを書いて見たが、特定のハードウェアではうまく動作しなかった。大半のマシンでは動作するのが、PCIバスに挿したUSB拡張カードでは不安定で認識にしくじる事がある。やっぱりクリスタルは必須かと思っていたが、そこに、

「内蔵CR発振源!?」

である。早速ソースコードを読んで見る。

「なるほど!やられた。」

物凄い衝撃を受けた。脳天に特大の金たらいが落下したくらいの衝撃!正直妬ましいくらいのアイディア。

簡単に説明すると、私のシステムの場合20MHzのセラロックを発信源に使っている。この場合、ロースピード1.5MHzのパケットを送受信するには、1ビットを13.333・・・クロックのタイミングでサンプリングする必要がある。

Bitsamp1

 

 

 

ただし、AVRで少数を含む数値をカウント出来ないので、3ビットサンプリングする毎に13,13,14クロックでサンプリングすれば、小数部の誤差をカバー出来る。
この方法で、20MHzの発信源を使ったAVRでも1.5MHzで作動するパケットを送受信できるが、1パケット送受信する間サンプリングするタイミングがきちんと拾うビットの遷移期間に収まっている精度が発信源に求められる。セラロックでは非常に微妙だ。

そこにCR発信源である。どう考えても必要精度を満たしていない気がするし、実際満たしていない。で、EasyLoggerでは何をやっているかと言うと、NRZIのビット挿入を省いた8ビット分(つまり1バイト)をサンプリングするために、必要なクロックより少ないクロックでサンプリングするループを組む。必然的にサンプリングタイミングは前方にずれる事になる。
そこで、各ビットをサンプリングする際、ビットの遷移期間の前方境界直後とビットの中央部をサンプリングして、この値が異なればサンプリングタイミングを後ろにずらすという方法で同期を取っている。

Bitsamp2  

 

 

連続するビットが同じ値だと同期のずれを検出出来ないが、データはNRZIで符号化されていて、6ビット以上同じ値が続く事は無く、この方法は有効である。

「凄いわ。このコード」

このコードを読んで一気に発奮!同期補正を行うコードを組み込んで見る。
動作原理はこうだ。8ビット(1バイト)を1つのループで組み、各ビットを14,13,13,14,13,13,14クロックの周期でサンプリングする。これだと1バイトサンプリングする毎に0.333・・・クロック分サンプリングタイミングが後ろにずれる事になる。
そこで、1ビットサンプリングする際にビット中央部と後方境界を比較し同期を補正する。この方法で同期補正のついでに、0.333・・・のクロック誤差も補正する。

Bitsamp3  

 

 

この方法でファームを書いてテスト。

「おおぉ。認識する!」

今まで接続が不安定だったPCとでも、安定して通信できる。
気を良くしたので、一気にWindows側のドライバも書き上げて見る。
出来上がったのがこれ。

Avrusbcomio01 

 

 

 

 

 

  Avrusbcomio02  

 

 

 

 

 

 

 
AVR Tiny2313を使った汎用I/O。WindowsからはCOMポートとして見えるので、シリアル通信を行うアプリケーションからAVR Tiny2313のポートBを操作出来る。
senshuさんから紹介してもらったキットを参考にして、ブレッドボードに挿せるようにして見た。

Avrusbcomio03  

 

 

 

 

 

 

ブレッドボード上で実験。うまく動作しているようだ。
取り掛かってから約1年掛かったが、何とかAVRでUSBデバイスを作る事が出来た。
一応「車輪の再発明」完結。

AVR Tiny2313 USB 汎用 I/O:ダウンロード

| | コメント (21) | トラックバック (0)

2007年6月19日 (火)

USB入門

COMデバイス

ポチポチと Tiny2313 USB ファームの Windows ドライバを書いている。前回は(と言っても1月以上前になってしまったが)ほとんど「WindowsXPデバイスドライバプログラミング」のサンプル通りテストドライバを書いて見き動作を確認して見た。が、サンプル通りのコードを書いて見ても、今ひとつ WDM を自分の物にした気がしない。なので、1から自分で設計してみたい。

Usb04

 

 

 

 

 

 

 

 
作る物は Tiny2313 のBポートを USB を通して PC から入出力出する汎用 I/O みたいな物を作って見ようと思う。アプリケーションから WriteFile で出力した内容を Tiny2313のBポートに出力し、Bポートの内容を ReadFile で読み出す事が出来るシステム。
たったこれだけの事なのだが、実装を考えると意外とめんどくさい。まず、Write/Read するにはデバイスのハンドルを得る必要があり、ハンドルを得るにはデバイス名を指定して CreateFile を実行する必要がある。USB の様に同一デバイスが同時に接続される場合、デバイス名の重複やそれぞれの識別を考慮する必要がある。一般的には GUID を用いて、Windows側でデバイス名を作成し、アプリケーション側はこの GUID を用いてデバイス名に辿り着くコードを書く。

が、自分で書いてて何がなにやらよく解んない。

UUSBD や USBLIB などの汎用 USB デバイスドライバは、専用ライブラリを用意して、アプリケーション側でこのライブラリをリンクする事で、めんどくさそうなデバイス名の取得の問題を解決している。流石です。

が、もう少し簡単にデバイス名を取得できる方法を泥臭く考えて見る。
仮想COMデバイスである。かなりレガシーだし、アプリケーション側からどの COM?? なのか判別する方法はないが、GUID からデバイス名を生成するよりは簡単な気がする。

ということで、デバイスオブジェクトに COM ポートへのシンボリックリンクを張る方法を調べる。INF ファイルにデバイスをポートクラスとして記述する。この INF ファイルでデバイスをインストールするとレジストリのハードウェアキーに COM 名が作成されるので、この名前をこのデバイスオブジェクトの物理デバイスオブジェクトにリンクする。あとは、レジストリの

\HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOM

にデバイス名をキーとして、COM 名を登録すればいいらしい。

Usb05  

 

 

 

 

 

 

 
取り敢えず COM デバイスとして認識したようだ。
実際の Read/Write ルーチンはこれから書くよー。 

| | コメント (0) | トラックバック (0)

2007年5月 8日 (火)

USB入門

CRC16

AVR Tiny2313でUSBデバイスは出来ている。そこで、こいつを使う
ための Windows用デバイスドライバを書かないといけないのだが、
何分素人なんで、デバイスドライバプログラミングなんてやった事が
ない。

解説書として「WindowsXPデバイスドライバプログラミング[入門と
実践]浜田憲一郎著」を用意した。私の様な素人さんにも解りやす
いらしい。

毎度の事ながら、解説書を読む。
毎度の事ながら、

うぅ~っ、わかんね。

なので、
毎度の事ながら、解説書を何回も読む。
という「毎度の事」を繰り返し、何とか

うっすら分かって来ましたよーっ!

で、うっすらUSBデバイスドライバを書いて見る。何とか認識されて、
Tiny2313のソフトで書かれたエンドポイントに対し送信。

うっすら受信出来ましたよーっ!

とりあえずUSBの通信は成功したが、さすがにTiny2313のメモリ
容量/スペックではUSBを実装するだけで、リソースをの殆どを
使い切っていてるし、所詮ロースピードデバイス。機能もうっすら。

これで何が作れるか、うっすら考えてみよう。

話は変わるが、USBのCRC計算法をググったあげく、当ブログに辿り
着いてしまった、というお気の毒な方がいらっしゃっる様なので、
私の付け焼刃の知識を恥ずかしながら披露する。

"HERO'S Download"から"AVRusb.ZIP"をダウンロード出来る。
この中にUSBの詳しいドキュメントがある。
USBのCRC16を計算するには「ハードウェアCRC16計算回路」
("USBspcs.pdf"に載っている)をエミュレートする。

Cで書くとこんな感じ

WORD UsbCrc16( int count, unsigned char *data )
{
    int      i, j;
    WORD crc = 0xffff;

    for( i = 0; i < count; i++ )
    {
        for( j = 0; j < 8; j++ )
        {
            if( crc & 0x0001 )
                data[ i ] ^= 0x01;

            crc >>= 1;

            if( data[ i ] & 0x01 )
                crc ^=0xA001;

            data[ i ] >>= 1;
        }
    }
    crc ^=0xffff;
    return crc;
}

引数dataがデータの配列、countがデータ数で、戻り値が求めたCRC。

| | コメント (0) | トラックバック (0)

2007年4月23日 (月)

USB入門

USBデバイスを作る6

久々の記事だがやってる事は変わらない。多少人生観は変わった
気もするが、行いが進歩する程の事でもなかったらしい。

なので、昨年の続きをやる。

Mega88でUSBロースピードデバイスのファームをでっち上げて、
Windowsから認識させる事が出来た。何とか。
そこで、自作デバイスドライバをスクラッチビルドしようと思うの
だが、その前に、実験用基板を作って見た。

Mega88は別の物を作るのに使ってしまったので、格安Tiny2313を
使用した。電源はUSBバスから三端子レギュレータで降圧した3.3V
を使う。クロック源は20MHzのセラロック。あとデバッグ出力用に
ADM3202ANを付けた。
さっそく、Mega88のコードをTiny2313用にコンバート。

げっ、フラッシュメモリの残りが数10ワード!

USBのファームだけで、ほぼプログラムメモリ満載。
こんなファームでなにか面白い物がつくれるのだろうか?

0704230001

| | コメント (0) | トラックバック (0)

2006年12月21日 (木)

USB入門

USBデバイスを作る5

Usb03

 

 

 

エニュメレーション成功。何とか、辛うじて。

AVRでUSBデバイスを作ろうとしてから2月、やっとPCから
USBデバイスとして認識させる事が出来た。
USBの場合電気的なインターフェイス/プロトコルを実装し
ても、その上層のUSBプロトコルを実装しない限りPCとの
通信は出来ない。

いやぁ、悩ませて貰いました。

ハマッた所

  標準デバイスリクエストのSET_ADDRESを受け取っ
  ても、すぐにアドレスを変更してはいけない。
            ↓
  その後に続くシェイクハンド用入力指示PIDを受信
  出来なくなる。

  CRCの計算はハードウェア計算回路をエミュレート
  する。
            ↓
  良く見ると一般的なCRC計算とちょっと違う。

  GET_DESCRIPTORの前に大量の入力指示PIDを受信
  しても驚かない。
            ↓
  それは、同じロースピードデバイスであるマウスや
  キーボードの為のもの。ちゃんと自アドレスに向け
  てのパケットか確認する。

  バッファが空いているからといって、むやみにデータ
  パケットを受信し、ACKを勝手に返してはいけない。
            ↓
  データパケットはシェイクハンドにも用いられるので、
  得られるはずのデータパケットを受け損なう可能性大。

ほかにも色々あったが、どれもきちんとUSBプロトコルを
理解していないのが一番の原因だった。

時間は掛かったがなんとか動いた。よかった。
やって見れば出来るもんだと、一人で勝手に感動。

しかしAVRって凄い。20MHzのセラロックと抵抗3本だけで、
USBデバイスが出来るかもしれない。しかも、リアルタイムに
データをNRZI変調して送信。受信側もNRZIから復号しながら
データを取り込む(挿入ビットの削除までは出来なかった)
事が出来だけのパワーを持っている。PICでは無理だ。

さて、USBデバイスとして認識させることは出来たが、これだ
けではPCと任意の通信はできない。PC上のドライバが必要
だ。なので、次はデバイスドライバーを書いてみようと思う。
が、デバイスドライバーを書いた経験は無い。いつもの事だ
が出来るかどうか分からないが、取り敢えずやってみよう。

| | コメント (2) | トラックバック (0)

2006年11月 1日 (水)

USB入門

USBデバイスを作る3

AVRでUSBホストからのパケットを受信する事が出来たので、
次は送信部のコードといきたいところだが、その前に少し下準備
をする。

USBでは受信したパケットの誤りを検出するためCRCが用いられ
る。そこで用意したパケットに添付すべく、CRCを計算する必要が
ある。また、実際のUSBの信号線には、NRZIという方法で符号化
したデータが流れている。これは、送受信器間で同期を失う事を
防ぐために0や1が連続して送信する事を抑制する働きをする。
なので、HEXデータ(Decimalで表記してもいいが・・・)をNRZIで符
号化する事も必要になる。

まず、CRC計算部だが、実の所このCRC計算法にしてもNZRIに
しても、今回USBを調べて始めて知り得たにわか知識なので、こ
れらの事を調べる事から始めなければいけない。

CRC計算ルーチンを書くにあたって計算法を調べてみた。幸い幾
つかの説明とサンプルコードを掲載しているサイトを見つける事が
できたので、早速コードを書いてみる。先日のパケット受信実験で
得られたデータパケットのCRCを実際に計算し、そのパケットに添
えられていたCRCを比較してみたが、値が一致しない。この事で2
晩程悩んだが、HEROさんの所の "AVRusb.ZIP" に含まれる資料
から "ハードウェアCRC16計算回路" を見て納得。計算方法が違って
いた。この回路をエミュレートする形で計算部を実装してみると、
うまく値が一致した。

次に、データをNRZI符号化するコードを考える。こちらはそんなに
難しくはないのだが、バイト単位のデータをビットの連続として捕ら
えなければならないので、実装がちょっとめんどくさい。また、1が
6ビット連続するデータを変換する場合1ビットの0を挿入するので、
変換後のデータは必ずしも8の倍数にならない。故に変換後の
データはバイト単位ではなくビット単位で管理する必要があり、
ここら辺の実装も幾らか煩雑になる気がする。これらを踏まえて実
際のコードを書く。

しかし、それなりに思い悩んだ末に書き上げたたコードなのに、
エディタ上で眺めてみると、思っていたほど高度に見えないのは
なんでだろう。

| | コメント (0) | トラックバック (0)

より以前の記事一覧