« 2012年2月 | トップページ | 2012年4月 »

2012.03.28

RX-MEGAからAndroidをいじくる

Interface誌付録のRX62Nボード用の豪華拡張基板『RX-MEGA』から、AndroidをADB経由でいじくることができるようになりました。

ADBというのはAndroidのUSBデバッグモードで、ほぼすべて(たしかバージョン1.6以降)のAndroid機が対応しています。LinuxのシェルのようなものがUSB越しに使えたり、アプリケーションの通信ができたりします。

似たようなのにADKというのがあります。これはUSBアクセサリモードというやつで、Android 2.3.4以降で対応となっているので、ざっくり言って昨年の夏以降の携帯電話が対応しているかな・・と思います。

ちょっと古い携帯だとADKは使えないので、ADBでいろいろやろうと思います。

Rxmegaandroid

さて、RX-MEGAは、付録基板FRK-RX62Nを拡張するボードです。FRK-RX62NにはRX62Nがのっていて、このRX62NはUSBホストとしてコンフィギュレーションすることができます。

また、RX-MEGAにはレガシーなRS232Cポートがあります。このRS232Cポート経由で、Androidのデバッグコンソール「ADB」を叩けるようにしてしまう、というプログラムを用意しました。

それが、こちらのプログラムです。
「adbtest.mot」をダウンロード

このプログラムはRX-MEGA上で動作します。まだちょっとUSBのプルダウンとかその辺の制御がうまくいっていないみたいで、接続や切断を検出するところに難がありますが、だいたいうまくいくでしょう。(究極のRX62Nボードのほうでは完璧だったのに)
付録基板は、1つのUSBポートを、ホストにもファンクションにもする回路構成だから、結構面倒なのかもしれませんね。

このプログラムを動作させると、RX62NのUSB0をホストモードにして、SCI0をRS232Cにします。TeraTermを立ち上げて、RS232C経由でADBシェルを叩いて、Androidに対してlsや、pm、amといったコマンドを発行できます。
下の図はpm -lコマンドを発行して、携帯内にインストールされているアプリケーションのリストを得ているところです。
Rxmegaadbshell

ちなみに、シェルの上から
$ am start -a android.intent.action.VIEW http://www.tokudenkairo.co.jp/
とやると、ブラウザが開いて上記のページが開かれます。

pmコマンドを使えば、任意のアプリをインストールしたりアンインストールすることだってできてしまいます。ファイル転送もプロトコルを解読したので、そのうち実装します。このツールがあればいろいろ面白いことができそうですが、携帯電話とUSBをつなぐだけで、こういうことができてしまうのですから、ある意味危険です。

パソコンにADBを入れる場合と違って、このツールの何がいいのかと考えてみると、
パソコンにADBを入れる方法だと、携帯電話が変わるたびにUSBのVIDとPIDが変わるから、デバイスドライバを要求されるけど、このツールなら「Androidデバッグシェル→RS232C変換器」として動作するのでデバイスドライバ不要。他の組み込み機器から、Androidを操作するためのブリッジとしても使える
というわけです。

なお、RX-MEGAをお使いで、このRX-ADBブリッジのソースをご希望のお客様がいらっしゃいましたら、ご連絡ください。USBホストのソースと、ADBブリッジのソースも含めて提供します。


昨年の夏に販売を開始し、ご好評いただいていたRX-MEGAは、あと2台で完売します。
在庫限りで終了し、終息品となる予定です。再生産の予定は全くありません。

RX-MEGAご希望のお客様は、特電オンラインショップへお急ぎください。

| | コメント (0)

2012.03.27

SATA接続のHDDやSSDをデータロガーとして使うための実験

SATA接続のHDDやSSDをデータロガーとして使うための実験を行いました。

EXPARTAN-6TというFPGA評価ボードにSATAのHDDやSSDをつなぎ、特電SATAコアを入れました。FPGAの中でデータを作り出し、WRITE DMA EXT(s)コマンドとデータを送るだけなので、パソコンの性能やOSの都合に左右されず、ドライブの真の実力を測定できると思っています。

Satalogexperiment

FPGAの中で32bitのカウントアップする数値を作って、これをDMAライトモードで、ひたすらHDDに書き込みます。その際のセクタ番号(LBA48アドレス)をEXPARTAN-6TのGPIOから出力します。そして、MITOUJTAGを使ってGPIOの端子の様子をバウンダリスキャンで見ました。

まずは、SUAMSUNG製の500GBのHDD。セクタ番号のbit15がトグルする(つまり65536セクタを書き込む)のにかかった時間は約240msです。1セクタ=512バイトなので、33554432Bytes/0.25ms = 約134MB/secとなります。
Satalogsamsung500gb

次にHITACHI GSTの500GBのHDDです。これもほぼ同じ速度で、約134MB/secとなりました。
Sataloghgst500gb

次はSSDです。OCZ社の60GBのもの。
32MBの書き込みに380msもかかっているので、83MB/secしか出ていない計算になります。
Satalogocz60gb

次はSilicon Power社のE20と書かれた32GBのもの。
32MBの書き込みに660msかかっているので、50MB/secとなります。
Satalogsp32gb

最後に某社の8GBのSSD。おそらく一番初期のころのSSDだと思われます。
なんと、32MBの書き込みに2.3秒かかっています。16MB/secくらいしか出ていない計算になります。
Satalog8gb

シーケンシャルアクセスならHDDの方が圧倒的に高速でした。以前試した時はOCZ社のSSDでも130MB/sくらい出せたと記憶しているのですが、何か使うコマンドを変えればもう少し早くなるのかもしれません。

書き込んだデータは、このような32bitのカウントアップするデータです。
Satalogdata

今回使ったHDDたちです。
Sataloghdds

シーケンシャルアクセスならSSDよりHDDのほうが高速でした。

| | コメント (0)

2012.03.25

RXマイコンのUSBホストライブラリを公開します

お待たせしました。
とっても簡単で便利な、RXマイコンのUSBホストライブラリを公開します。

Rxusbhost_mem

このライブラリを使うと、とても簡単にRXマイコンのUSBホストプログラムが作れます。
どのくらい簡単かというと・・・

初期化は、


if(tkusbh_init() != TKUSBH_OK) { // モジュールの初期化
printf("失敗!"); return 0;
}
if(tkusbh_connect(5000) != TKUSBH_OK) { // 接続されるまで待つ
printf("タイムアウト\n"); return 0;
}
でOKです。

エンドポイント1へデータを送信したくなったら、


tkusbh_bulk_write(1,buf,32,TIMEOUT_INFINITE);
とやれば32バイトのデータ送信されます。

エンドポイント2からデータを受信したくなったら、


tkusbh_bulk_read(2,buf,1024,100);
とやれば1024バイトのデータを受信しようとします。100msで反応がなければタイムアウトします。

ね、簡単でしょ?

特徴
・RTOSを前提としていないので、わかりやすく、直感的な関数を用意した。
・Windows版汎用USBドライバのようにカーネルモードとユーザモードを遷移しないので、INとOUTトランザクションを即座に発行でき、速い(かもしれない)。

           ま さ に U S B H O S T 自 由 自 在

というわけです。

詳しい関数の使い方は、こちらのページに用意しました。
http://rx.tokudenkairo.co.jp/reference/tkdnhal/usbh

次の図は、nahimon(RX用モニタプログラム)にUSBホストの機能を搭載したものです。差し込まれたUSBメモリのディスクリプタを読み込んで表示しています。
Rxusbhost

このUSBホストライブラリは、当面は究極のRX62Nボードをターゲットにしていますが、(現時点では)ソースコードも含めて一切合財をオープンにしています。

これは私がRX62Nのハードウェアマニュアルや、USBプロトコルアナライザの解析結果を読みながら、一から作り上げたものので、他所から持ってきたコードは一切含まれておりません。ライセンス的にもとてもクリーンです。

究極のRX62Nボードをご利用いただいているお客様は、このライブラリとソースコードを無償でダウンロードできますので、どうぞいろいろご覧になってみてください。
アーカイブを解凍していただいて、core/tkdnhal/の中のtkdnusbh.cとtkdnusbh.hがUSBホストのライブラリです。

楽しいUSB機器の製作にお役立てください。

| | コメント (0)

2012.03.23

BLOGANA機能の強化!Verilog対応も

大変お待たせいたしました!
MITOUJTAGに内蔵されているBlockRAMモードのJTAGロジアナ「BLOGANA」を大幅に強化しました。

BLOGANAというのは、XILINXのFPGAに内蔵されたBlockRAMに波形データを溜め込んで、それをJTAGで吸い出して表示する機能です。要するにChipScopeやSignalTapの簡易版みたいなものです。内蔵BlockRAMを使うので、数百MHzで動作します。(Spartan系なら最大200MHz弱、Virtex系ならその2倍くらい)

何が強化されたかというと、
① ターゲットボードの電源がONになってからスタートする機能
② Verilog対応
③ VHDLやVerilogのソースファイルを読み込んで、信号名やバス名を自動的に設定する機能
です。
順番に見ていきましょう。


まず、「① ターゲットボードの電源がONになってからスタートする機能」というのは、その名のとおり、ターゲットボードの電源がONするまで待機する機能です。
使い方は、通常のサンプリングと同じで、キャプチャスタートボタンを押すだけです。
待機中は「電源待機中」と表示されます。

Power_idle

この新機能では、Vrefの信号を見てターゲットボードの電源がOFFになっていると判断された場合には、キャプチャ開始せずに待ちます。ボードの電源がONになって、FPGAがコンフィギュレーションされてから、すぐにBLOGANAの動作を開始します。

何に使うかというと、電源がONした直後のFPGAの振る舞いを見たいときに使います。

この機能が必要になったのは、先日、PCI Expressの問題が起きてデバッグしなければならなくなったときでした。電源ON直後のリンク確立のやりとりの様子を見なければならないという課題がありました。

こういうときXILINXに慣れている方なら、ChipScopeを使おうとするかもしれません。でも、ボードの電源がOFFしていてFPGAが見えていないときに、果たしてChipScopeのキャプチャは開始できるでしょうか?
ボードの電源がONして、FPGAがコンフィギュレーションされてからスタートボタンを押したとしたら、そのときには既に時遅し。PCIeのリンク確立のやりとりが終わっているので、問題の部分が見れません。
このような問題を解決するため、MITOUJTAGは電源ON前からキャプチャを開始ボタンが押せるようにしたのです。


次に、②Verilog対応ですが、Verilogユーザの皆様には、本当にお待たせして申し訳ございませんでした。BLOGANAが、Verilogのソースファイルを解読できるようになりました。


さて、BlockRAMタイプのロジアナでは見たい信号の名前が簡単にはわかりません。FPGAの外に出るI/Oピンではないので、UCFファイルやPADファイルに書かれているというわけでもありません。BlockRAMの何本目のデータ線につながっているという程度のことしかわかりません。
だから、BLOGANAモードが起動したときには、すべての端子に名前がついていません。

Blogana_1

これでは不便なので、MITOUJTAGでは、BLOGANAを埋め込んだVHDLソースを解読して、BLOGANAモジュールにつながっている信号名を読み込んで、信号名を自動的に設定する機能がありました。今回、この機能を強化して、バス化されている信号でも正しく設定されるようにしました

つまり、こういうソースを読み込むと、


BLOGANA_DIN( 7 downto 0) <= lnk_rd_data_d(7 downto 0) when (lnk_rd_dvalid = '0') else
 lnk_rd_data_d(23 downto 16) ;
BLOGANA_DIN(15 downto 8) <= lnk_rd_data_d(15 downto 8) when (lnk_rd_dvalid = '0') else
 lnk_rd_data_d(31 downto 24) ;
BLOGANA_DIN(23 downto 16) <= lnk_wr_data(7 downto 0);
BLOGANA_DIN(31 downto 24) <= lnk_wr_data(15 downto 8);
BLOGANA_DIN(35 downto 32) <= conv_std_logic_vector(rxtrn_state,4);
BLOGANA_DIN(39 downto 36) <= conv_std_logic_vector(txtrn_state,4);
BLOGANA_DIN(44 downto 40) <= lnk_state_i;
BLOGANA_DIN(45) <= lnk_wr_full;-- '1' when (rxtype = 1) else '0'; -- RegDH
BLOGANA_DIN(46) <= '1' when (transmode = TR_IDLE) else '0'; -- PIOSU
BLOGANA_DIN(47) <= '1' when (transmode = TR_PIOOUT) else '0'; -- DataFIS
BLOGANA_DIN(48) <= '1' when (txtrn_state >= 1) and (txtrn_state <= 7) else '0'; -- TxCmd
BLOGANA_DIN(49) <= rtfr_int;
BLOGANA_DIN(50) <= Reg_Bit_Int;
BLOGANA_DIN(51) <= Reg_Status(7);
BLOGANA_DIN(59 downto 52) <= rtfr_status;
BLOGANA_DIN(60) <= '1' when (recv_fis = RF_NONE) else '0';
・・・

下の図のように信号名が自動設定されます。
Blogana_2

こういう設定が、何も操作しなくても、ソースファイルを指定するだけで良くなりました。

今回の更新パッチは下記のURLからダウンロードできます。
http://www.tokudenkairo.co.jp/jtag/sp.html#beta
ここの「ロジアナ強化パッチ 2 平成24年3月23日」というものをダウンロードして、適用してください。

それでは快適なFPGA開発ライフを!


| | コメント (0)

2012.03.20

RX-Androidブリッジを公開します

RXマイコンからAndroidのADBを操作するブリッジのプログラムを公開します。

このプログラムを使うと、RXマイコンのUSBホストにつながったAndroid携帯のデバッグシェルをいろいろいじれます。
Endpointの番号とかは自動的に調べます。

Rxa3

プログラムはこちらです。
「tkusbhost.mot」をダウンロード

このプログラムは176ピンのRX62N専用です。(USB1を使っているため)
したがって、究極のRX62Nボードで動作します。
パソコン側のポートは、レガシーのシリアルインタフェース(SCI0)で動きます。
※PCとの接続をUSB仮想COMポートにするのはまだ。
※RaXinoや、RX-MEGAではまだ動きません(144ピンや100ピンのRX62NはUSBのポートが1つしかないため、まだ移植していない)

現在、lsや、ps、logcat、dfなどのコマンドが確認済みです。
いろいろできて面白いです。
どうぞお試しください。

| | コメント (0)

2012.03.19

Android携帯をRXマイコンから操作できた!

ついにできました。
RXマイコンのUSBホスト機能を作って、Android携帯にコマンドを送れました!

ADBのシェルを開いて、lsコマンドを送っています。

Rxa1

もう少しロバストに動くようになれば公開する予定です。

| | コメント (0)

2012.03.16

RXマイコンとAndroid携帯をつなぐ

RXマイコンのUSBホスト機能ができてきました。
といっても、ディスクリプタを解析して表示するだけなのですが。。

とりあえず、究極のRX62Nボードに、Android携帯をつないでみました。
Rx_android

AndroidのUSB接続モードがデフォルト(外部メモリ転送モード)のときに、デスクリプタを取得したところ、InterfaceClass=8なので、USBメモリになっています。

Rx_android1

AndroidのほうでUSB接続モードを「高速転送モード」に切り替えると、InterfaceClass=2になるので、通信クラスになります。

Device Desriptor:
  bLength            = 18
  bDescriptorType    = 1
  bcdUSB             = 0x200
  bDeviceClass       = 0x0
  bDeviceSubClass    = 0x0
  bDeviceProtocol    = 0x0
  bMaxPacketSize     = 64
  idVendor           = 0x04c5
  idProduct          = 0x12aa
  bcdDevice          = 0x0227
  iManufacture       = 1 ()
  iProduct           = 2 ()
  iSerialNumber      = 3 ()
  bNumConfigurations = 1
 
Configuration Desriptor:
  bLength             = 9
  bDescriptorType     = 2
  wTotalLength        = 58
  bConfigurationValue = 1
  iConfiguraion       = 0
  bmAttributes        = 0x80 (Bus powered)
  bMaxPower           = 250 (500mA)
  + Interface Desriptor:
      bLength             = 9
      bDescriptorType     = 4
      bInterfaceNumber    = 0
      bAlternateSetting   = 0
      bNumEndpoints       = 2
      bInterfaceClass     = 0x2
      bInterfaceSubClass  = 0xa
      bInterfaceProtocol  = 0x1
      iInterface          = 0
Unknown Descriptor
0000 05 24 00 10 01
Unknown Descriptor
0000 15 24 12 00 01 C2 29 9F CC D4 89 40 66 89 2B 10
0010 C3 41 DD 98 A9
      + Endpoint Desriptor: (EP1 IN)
          bLength             = 7
          bDescriptorType     = 5
          bEndpointAddress    = 129
          bmAttributes        = 0x2 BULK
          wMaxPacketSize      = 64
          bInterval           = 0
          bRefresh            = 0
          bSynchAddress       = 0
      + Endpoint Desriptor: (EP1 OUT)
          bLength             = 7
          bDescriptorType     = 5
          bEndpointAddress    = 1
          bmAttributes        = 0x2 BULK
          wMaxPacketSize      = 64
          bInterval           = 0
          bRefresh            = 0
          bSynchAddress       = 0
タイプ0x24という謎のディスクリプタが見えています。

AndroidのUSBデバッグモードをONにすると、USBメモリと、ベンダ定義クラス(FF)の2つのインタフェースが見えました。


Device Desriptor:
bLength = 18
bDescriptorType = 1
bcdUSB = 0x200
bDeviceClass = 0x0
bDeviceSubClass = 0x0
bDeviceProtocol = 0x0
bMaxPacketSize = 64
idVendor = 0x04c5
idProduct = 0x12a8
bcdDevice = 0x0227
iManufacture = 1 ()
iProduct = 2 ()
iSerialNumber = 3 ()
bNumConfigurations = 1
 
Configuration Desriptor:
bLength = 9
bDescriptorType = 2
wTotalLength = 55
bConfigurationValue = 1
iConfiguraion = 0
bmAttributes = 0x80 (Bus powered)
bMaxPower = 250 (500mA)
+ Interface Desriptor:
bLength = 9
bDescriptorType = 4
bInterfaceNumber = 0
bAlternateSetting = 0
bNumEndpoints = 2
bInterfaceClass = 0x8
bInterfaceSubClass = 0x6
bInterfaceProtocol = 0x50
iInterface = 5
+ Endpoint Desriptor: (EP2 IN)
bLength = 7
bDescriptorType = 5
bEndpointAddress = 130
bmAttributes = 0x2 BULK
wMaxPacketSize = 64
bInterval = 0
bRefresh = 0
bSynchAddress = 0
+ Endpoint Desriptor: (EP2 OUT)
bLength = 7
bDescriptorType = 5
bEndpointAddress = 2
bmAttributes = 0x2 BULK
wMaxPacketSize = 64
bInterval = 0
bRefresh = 0
bSynchAddress = 0
+ Interface Desriptor:
bLength = 9
bDescriptorType = 4
bInterfaceNumber = 1
bAlternateSetting = 0
bNumEndpoints = 2
bInterfaceClass = 0xff
bInterfaceSubClass = 0x42
bInterfaceProtocol = 0x1
iInterface = 0
+ Endpoint Desriptor: (EP3 IN)
bLength = 7
bDescriptorType = 5
bEndpointAddress = 131
bmAttributes = 0x2 BULK
wMaxPacketSize = 64
bInterval = 0
bRefresh = 0
bSynchAddress = 0
+ Endpoint Desriptor: (EP3 OUT)
bLength = 7
bDescriptorType = 5
bEndpointAddress = 3
bmAttributes = 0x2 BULK
wMaxPacketSize = 64
bInterval = 0
bRefresh = 0
bSynchAddress = 0

おおっ、複合デバイスってやつでしょう!

次はバルク転送ができるようにします。

| | コメント (0)

2012.03.15

EZ-USB FX3のGPIOを動かしてみる

FX3はソフトウェア開発環境すごく良くできていて、CypressのSDKにはRTOSがすでに組み込まれています。SDKにはGCCやEclipse、各種ライブラリがあらかじめ同梱されています。
ユーザがEZ-USB FX3用に作るプログラムはRTOSの1つのスレッドとして動かすべきんのようです。

そんな大仏の手のひらのような環境の元で、FX3のGPIOの実力を試そうと、GPIOをカチカチしてみました。

APIマニュアルを読むと、CyU3PGpioSimpleSetValueという関数があるので、例えばGPIO(21)をH/Lしたい場合には、
CyU3PGpioSimpleSetValue(21,CyTrue);
CyU3PGpioSimpleSetValue(21,CyFalse);
とやればよいのだろうなと想像しました。

しかし、1bitの遷移で600nsくらいかかっています。200MHzで動作するCPUなのにこれじゃ遅すぎると思って、APIマニュアルやその他マニュアルを読んでも、メモリマップI/Oのどの番地を叩けばGPIOがアクセスできるのか、書いていません。(見つけられませんでした)

つまり、EZ-USB FX3のGPIOを操作するには、CyU3PGpioSimpleSetValueやCyU3PGpioSetValueといった既成のAPI関数を呼ばなければいけないようです。

それじゃつまらないので、objdumpしてCyU3PGpioSimpleSetValueの中がどうなっているのか調べてみました。


4000cab0 <CyU3PGpioSimpleSetValue>:
4000cab0: e1a03000 mov r3, r0
4000cab4: e59f0598 ldr r0, [pc, #1432] ; 4000d054 <CyU3PGpioComplexWaitForCompletion+0x104>
4000cab8: e5900000 ldr r0, [r0]
4000cabc: e3500000 cmp r0, #0
4000cac0: 1a000001 bne 4000cacc <CyU3PGpioSimpleSetValue+0x1c>
4000cac4: e3a00042 mov r0, #66 ; 0x42
4000cac8: e12fff1e bx lr
4000cacc: e353003d cmp r3, #61 ; 0x3d
4000cad0: da000001 ble 4000cadc <CyU3PGpioSimpleSetValue+0x2c>
4000cad4: e3a00040 mov r0, #64 ; 0x40
4000cad8: eafffffa b 4000cac8 <CyU3PGpioSimpleSetValue+0x18>
4000cadc: e59f0598 ldr r0, [pc, #1432] ; 4000d07c <CyU3PGpioComplexWaitForCompletion+0x12c>
4000cae0: e7900103 ldr r0, [r0, r3, lsl #2]
4000cae4: e3c02342 bic r2, r0, #134217729 ; 0x8000001
4000cae8: e3510000 cmp r1, #0
4000caec: 0a000000 beq 4000caf4 <CyU3PGpioSimpleSetValue+0x44>
4000caf0: e3822001 orr r2, r2, #1
4000caf4: e59f0580 ldr r0, [pc, #1408] ; 4000d07c <CyU3PGpioComplexWaitForCompletion+0x12c>
4000caf8: e7802103 str r2, [r0, r3, lsl #2]
4000cafc: e3a00000 mov r0, #0
4000cb00: eafffff0 b 4000cac8 <CyU3PGpioSimpleSetValue+0x18>

CyU3PGpioSimpleSetValueという関数は、呼び出されるとまず[CyU3PGpioComplexWaitForCompletion+0x104]番地の内容を調べます。この値が0でなければ、66という戻り値でリターンします。おそらくCY_U3P_ERROR_NOT_STARTEDというエラーの値なので、GPIOが起動しているかどうかがこの番地に書かれているのだと思われます。

それから、引数の値が61以下であることを確認し、そうなっていなければCY_U3P_ERROR_BAD_ARGUMENTエラーを返します。その後、NULLポインタチェックを行うなどしています。

ひととおりのエラーチェックが終わったら、4000d07c番地[CyU3PGpioComplexWaitForCompletion+0x12c]の内容を読んで、r3の内容を左に2ビットシフトしたものを足して、その番地の内容をr0に読み出し、ビットクリアやビットセットを行ったものを計算して、書き戻しています。

4000d07c番地には0xe0001100が書かれているので、つまり、
[0xe0001100 + 4*GPIO番号]番地が、GPIOのポートのアドレスだろうと推測されます。
そして、読んだ値を書き戻す際に、LSBにポートから出力する値をセットする。ただし、28bit目を0にしなければならない、ということではないかと思われます。

まぁ、このような感じでGPIOにアクセスするためのレジスタの番地はわかったのですが、CyU3PGpioSimpleSetValueをコールしてもそれほど速くはならないでしょう。CyU3PGpioSimpleSetValueは16~20ステップ程度で実行できるはずなのです。

マニュアルを斜め読みしたところでは、このCPUは19.2MHzの源発振からPLLで403.2MHzのクロックを作って、それを2分周したものをシステムクロックにするようです。200MHz動作のCPUならば10MHzくらいの速さでGPIOを操作できてもいいのですが、その速度には到底及びません。もしかするとCPUのクロックがもっと遅いか、GPIOのクロックがとても遅いのではないかと推測できます。

続きはまた明日

| | コメント (0)

2012.03.14

RXマイコンのUSBホスト

RXマイコンのUSBホストプログラムを作っています。

Rx_usbhost

いろいろなところにあるサンプルプログラムは皆、グローバル変数使いまくり&割り込み駆動なので、難解です。

例えば、コントロールトランザクションを行うとき、割り込みを使ったプログラムだと、
① Setupパケットが送信されるようレジスタをセットし、
送信完了で割り込みが起こるよう、割り込み許可フラグを立てる
グローバル変数に受信バッファのアドレスをセット
② 割り込みルーチンの中でフラグをたてるか、直接、INデータパケットを送る
  送信完了で割り込みが起こるよう、割り込み許可フラグを立てる
  受信FIFOから受信バッファへデータをコピー
③ 割り込みルーチンの中でフラグをたてるか、直接、OUTデータパケットを送る

最低限、上のような処理が行われるのですが、これらが1つの関数ではなく、細切れに起こります。
というのは、USBパケットが送受信される時間はCPUのクロックに対してとても長いので、送受信の終了をwhile文で待っていると時間が無駄になるという考えなのでしょう。

割り込みを使うと、待ち時間に他の処理ができるので、RTOSではいいかもしれません。
しかし、わかりにくいし、送受信バッファのアドレスを受け渡しするためにグローバル変数を使わなければなりません。

そこで、見通しが良くなるようにケーブル抜き差し以外の割り込みを使わないで動くよう、プログラムをゼロから作っています。
セットアップステージとか、データステージを遷移するたびにステートマシンが遷移する・・といったプログラム方式ではなく、普通に上から下へ流れるモデルです。

int usb_ctrl_transfer(unsigned short req,
	                         unsigned short val,
	                         unsigned short idx,
	                         unsigned short len,
	                         unsigned char *buf)
{
	enum {CTRL_NODATA,CTRL_READ,CTRL_WRITE} transtype;
	if(len == 0) transtype = CTRL_NODATA;
	else
	{
		if(req & 0x0080) transtype = CTRL_READ;
		else             transtype = CTRL_WRITE;
	}
	USB1.SOFCFG.BIT.TRNENSEL = 0; // LowSpeedなら1
	USB1.DCPMAXP.WORD = 64;
	// セットアップ・ステージ
	USB1.USBREQ.WORD = req;
	USB1.USBVAL      = val;
	USB1.USBINDX     = idx;
	USB1.USBLENG     = len;
	USB1.DCPCTR.BIT.PID = 0;   // NAK応答をセットしてから、
	USB1.DCPCTR.WORD = 0x4000; // SUREQを1にするとSetupパケットが送信される
	while(USB1.DCPCTR.WORD & 0x4000) ; // Setup送信中。待つ
	// データ・ステージ
	if(transtype == CTRL_READ) // IN転送を発行
	{
		USB1.DCPCTR.WORD     = 0x0080;     // SQSET(DATA1に切り替え) PID=NAK
		USB1.DCPCFG.BIT.DIR  = 0;          // データ受信方向に切り替える
		USB1.DCPCFG.BIT.SHTNAK = 1;        // 転送終了時にNAKに切り替える
		USB1.CFIFOSEL.WORD   = 0x0000;     // ISEL=0(バッファメモリ読み出し), CURPIPE=0
		USB1.CFIFOCTR.WORD   = 0x4000;     // CPU側バッファメモリクリア
		USB1.DCPCTR.BIT.PID  = 0x01;       // PID_BUF 受信開始(INトランザクション発行)
		while(USB1.DCPCTR.BIT.PID == 0x01) {} // 転送が終了してPID_BUF以外になるまで待つ
		if(USB1.DCPCTR.BIT.PID >= 2) return -1; // STALL応答
		len = tkusbh_read_cfifo(buf);
	}
	if(transtype == CTRL_WRITE) // OUT転送を発行
	{
		USB1.DCPCTR.BIT.PID = 0x00;    // PID_NAK
		USB1.DCPCTR.WORD     = 0x0080; // SQSET(DATA1に切り替え) PID=NAK
		USB1.DCPCFG.BIT.DIR  = 1;      // データ送信方向に切り替える
		tkusbh_write_cfifo(buf,len);
		USB1.DCPCTR.BIT.PID = 0x00;    // PID_NAK
		USB1.DCPCTR.BIT.PID = 0x01;    // PID_BUF 受信開始(OUTトランザクション発行)
	}
	// ステータス・ステージ
	if((transtype == CTRL_NODATA) || (transtype == CTRL_READ)) // OUT転送を発行
	{
		USB1.DCPCTR.BIT.PID = 0x00;    // PID_NAK
		USB1.DCPCTR.WORD     = 0x0080; // SQSET(DATA1に切り替え) PID=NAK
		USB1.DCPCFG.BIT.DIR  = 1;      // データ送信方向に切り替える
		tkusbh_write_cfifo(buf,0);
		USB1.DCPCTR.BIT.PID = 0x00;    // PID_NAK
		USB1.DCPCTR.BIT.PID = 0x01;    // PID_BUF 受信開始(OUTトランザクション発行)
	}
	if(transtype == CTRL_WRITE) // IN転送を発行
	{
		USB1.DCPCTR.WORD     = 0x0080; // SQSET(DATA1に切り替え) PID=NAK
		USB1.DCPCFG.BIT.DIR  = 0;      // データ受信方向に切り替える
		USB1.DCPCFG.BIT.SHTNAK = 1;        // 転送終了時にNAKに切り替える
		USB1.CFIFOSEL.WORD   = 0x0000; // ISEL=0(バッファメモリ読み出し), CURPIPE=0
		USB1.CFIFOCTR.WORD   = 0x4000; // CPU側バッファメモリクリア
		USB1.DCPCTR.BIT.PID  = 0x01;   // PID_BUF 受信開始(INトランザクション発行)
		while(USB1.DCPCTR.BIT.PID == 0x01) {} // 転送が終了してPID_BUF以外になるまで待つ
		if(USB1.DCPCTR.BIT.PID >= 2) return -1; // STALL応答
	}
	return len;
}

Setupトランザクションが送られる時間と、転送が終了してINトランザクションの結果のデータがFIFOに格納されるまでの時間をwhile文で待つことにしました。
すると、割り込みを使わずに1つの関数で書けるのです。

組み込み用途ですし、シングルタスクのプログラムならこれでもいいかな、と思います。

| | コメント (0)

2012.03.13

月刊特電技術Vol.1の発送完了!

昨日、月刊特電技術 Vol.1の発送を完了しました。

下の写真は初日の発送分(約250冊)の写真です。
Gekkan_send


郵便番号順に出していったので、秋田、岩手、北海道、東京、関東地方~中部地方、および大阪の方は10(土)~12(月)ごろに到着したかなと思います。
大阪の一部と、近畿地方、中国・四国、九州・沖縄、東北の方は13(火)か14(水)には届くと思います。

なお、香川県はうどん県に改名されたそうなので、
宛名の住所もうどん県と書かせていただきました。ご了承ください。

ふと気がついたのですが、郵便番号って東北から南西にかけて順番に振られているのではなくて、沖縄(〒90*番台)までいくと次はなぜか福井県(〒91*)、石川県(〒92*)、富山県(〒93*)、新潟県(〒94*、〒95*)、福島県(〒96*、〒97*)、宮城県(〒98*)、山形県(〒99*)と東北に戻ってくるのです。
郵便番号のスタートは秋田県は(〒01*)、岩手県は(〒02*)なので不思議です。
どういう由来なんでしょうね。

というわけで、今週の水曜日までにはエンドユーザの皆様のお手元に届くと思います。

なお、以下の方にはお送りしていません。
・商社様を経由して購入された方で、エンドユーザ様名がわからない方。
・社内の資材部や総務部などを経由して購入された方で、エンドユーザ様名がわからない方。
・製品の購入を代行した商社様のご担当者様と思われる方。
・その他、エンドユーザ様のご住所や部署名がわからなくて・氏名がわからない方。(大学生協付け、学科名などで購入している場合)
・引っ越しされて、転送不能となって郵便物が戻ってきた方。

エンドユーザなのに、月刊特電が届かないという方がいらっしゃいましたら、間違って古い住所に発送してしまったか、商社の担当者と間違えてしまって発送しなかった、などのことが考えられます。その際は、ご連絡ください。
http://www.tokudenkairo.co.jp/gekkan/index.html

| | コメント (1)

2012.03.12

EZ-USB FX3の評価ボード実装完了!

今日、実装屋さんからEZ-USB FX3ボードの実装が上がってきました。

6面付けで6枚作りました。
Fx3_board1

部品を取り付けるとこんな感じです。
Fx3_board3

Spartan-6ボードを重ねてみるといい感じ。
Fx3_board4

早速、PCに挿してみると、WestBridgeという謎のデバイスとして認識されました。
Fx3_dev1

Fx3_dev2

まあ、何か動いているようです。

しかし・・実験につかっているWindows7マシンは64bit版で、CypressのSDKには64bit版のドライバがない・・。
32bitのマシンで実験できるようにするため、PCIe-USB3ホストボードを買ってくることにします。

◆追記

PCIe-USB3ホストボードを買ってきました。
これをWindows7の32bitマシンに挿して、再挑戦。

EZ-USB FX3をPMODE[2:0]を"F11"に設定すると、USBブートモードで起動します。このときVID=1480、PID=0000で"WestBridge"というデバイスで見えるようです。

しかし、EZ-USB FX3 SDKにあるデバイスドライバ(C:\Program Files\Cypress\EZ-USB FX3 SDK\1.0\driver\bin\win7\x86)にはこの番号は登録されていないので、cyusb3.infを書き換えます。

;%VID_XXXX&PID_XXXX.DeviceDesc%=CyUsb3, USB\VID_XXXX&PID_XXXX
%VID_04B4&PID_00F3.DeviceDesc%=CyUsb3, USB\VID_04B4&PID_00F3
%VID_04B4&PID_4720.DeviceDesc%=CyUsb3, USB\VID_04B4&PID_4720
となっているところの次に、
%VID_1480&PID_0000.DeviceDesc%=CyUsb3, USB\VID_1480&PID_0000
を加えます。(計3箇所)

そして、最後のStringsセクションに
VID_1480&PID_0000.DeviceDesc="Cypress USB BootLoader"
を追加します。

これでデバイスドライバがインストールできるようになります。

Cypressのコントロールソフト(CyControl.exe)を起動させてみて、CyBootProgrammer.imgというのを転送してみました。

Fx3_dev3

EZ-USB FX3の中にあるCPUはARM9ですが、とくにUSB-JTAGを使わなくても動かせそうです。
明日からソフトを作って実験してみることにします。

| | コメント (1)

2012.03.08

「月刊特電技術」が刷り上ってきた

今日もうひとつ荷物が届きました。
月刊「特電技術」が刷り上ってきたのです。

フルカラーで6ページ、マット紙135kgの機関紙「月刊特電技術」です。

Gekkan_tokuden_pre

3月6日(火)の23:40にデータを入稿して、翌3月7日(水)の18:00ごろに印刷屋さんが自社トラックで直送してくれていたようです。翌日発送となっていたので、てっきり今日届くかと思っていたのですが、なんと昨日届いていたのです。
(ただ、受け取ったのは今日8日(木)でした。)

さて、今日の午後から発送を始めます。
明日か明後日ごろにはお客様の皆様のお手元に届くでしょう。

乱筆乱文ばかりの、拙作な冊子ではございますが、どうぞお楽しみください。

| | コメント (0)

EZ-USB FX3の評価基板が出来上がってきた

EZ-USB FX3の評価基板が出来上がってきました。
6枚面付けして作っています。
Np1052_x6

すでに実装業者さんのほうでも実装が開始されているはずです。
来週の水曜日くらいまでには実装が出来上がるのではないかなと思っています。

BGAのパターンはこんな感じ。0.1mmの設計ルールで作っています。
Ezusbfx3_pattern

初回ロットは6枚製造しました。
欲しい方いらっしゃいましたら、予約を承りますので、メールでご連絡ください。

| | コメント (2)

2012.03.06

月刊「特電技術」(非売品)を創刊

特電のお客様向けに、「月刊 特電技術」なる小冊子を刊行することにしました。

創刊号は、フルカラー印刷でA4サイズ豪華8ページ。下の図のような感じの誌面になります。(Web上では都合によりモノクロですが、印刷した紙のものはフルカラーです)
Gekkan_tokuden_1

さて、どういう思いでこの冊子を作ったかというと、特電製品のいろいろな使い方や、アプリケーション例、設計思想などを、消えてしまうWebの情報ではなく、紙として保存できる形でお客様に伝えたいと思ったからです。

だから、この冊子はよくある通販業者が送ってくるような「広告だけのダイレクトメール」には絶対にしないつもりです。
何かを設計するときに役に立つ技術情報を満載した小冊子として、お客様に喜んでいただけて、また保存していただけるような価値のあるものを目指しています。

広告だけの冊子は即ゴミ箱行きです。そうならないよう、月刊特電技術はできるだけ広告性を排除して、中立の技術情報を増やし、お客様に捨てられない冊子、喜んでいただける内容を目指しています。

創刊号の目次は、
 ・P1 ご挨拶
 ・P2 MITOUJTAGのアップデートに関して
 ・P3 AndroidのUSB通信の解析
 ・P4 RXマイコンにおけるUSBの使い方
 ・P5~P6 EZ-USB FX3ボード設計の技術情報
 ・P6~P7 P板で高密度プリント基板を造るためのノウハウ
 ・P8 お客様の声
となりました。
こういう冊子を創る作業は初めてだったものでいろいろと手間取りましたが、型が出来あがったので、次回からは少し楽になるのかなと期待しています。

Gekkan_tokuden_1a

この冊子の創刊号は、直近の約2年間の間に何らかの商品をお買い上げいただいた方に無料でお送りしようと思います。「○○以上の製品をお買い上げいただいた方のみ・・」とかの制限はつけずに、この約2年間に何でもいいから特電の商品を1つ以上お買い上げいただいた方に郵便でお送りしようと思います。

そのような送付先リストを作成していたら、エンドユーザ様が判明しただけで800人近くになりました。法人ユーザ様で、代理店を経由して購入されていて、かつユーザ登録をされていないため送り先がわからない方もたくさんいらっしゃいます。そういうわけで、念のため1000冊くらい作ることにしました。

本日(3月6日)、印刷業者に翌日コースで出稿したので、木曜日には出来上がって特電に届くはずです。その後、郵便で出すので、早ければ金曜日には皆様のお手元に届くことになるでしょう。お楽しみに。

次号は4月上旬の発行を予定しています。
創刊号はレイアウトやMicrosoft Wordの使い方などで、いろいろバタバタとしてしまったので、内容的に詰められていないところとかも多くあると思います。その反省をかねて、次の第2号では1つの記事に2ページくらいを割いて詳しく解説したり、内容を充実させる方向に力を入れたいと思います。

次号の内容は
 ・RXマイコンのDMAをつかってファンクションジェネレータを作る
 ・EZ-USB FX3動作レポート
 ・AndroidとUSB通信をする(続)
 ・FPGAにSATAのHDDをつないで大容量データロガーを作る
 ・Spartan-6のBSCANプリミティブの使い方
 ・Spartan-6のPLLの達人になる
といったことを予定しています。

毎月1回のペースはかなり速いですが頑張っていきたいと思います。
今までWebやブログに出していなかったネタはたくさんあるので、そういう情報を紙で提供していきたいと思います。

お楽しみに!

| | コメント (5)

« 2012年2月 | トップページ | 2012年4月 »