プログラミング

14/11/07 FTDI USB3.0互換性問題

好んでFTDIのICを使用するんだけど、ちょっとドハマリした事があったのでその時の覚書。

●現象
MPSSEモードでFT2232Hを制御するためlibMPSSE.dllを使うが、SPI_GetNumChannels()でチャネル数が取得できない、SPI_GetChannelInfo()でデバイスの情報が取得できない、SPI_OpenChannel()でオープンできない等、正常動作しなかった。
ちなみにFT232Hは問題なし。
動作環境はWindows7 Professional (64bit)。

試しにlibMPSSE.dllのAPIは使用せず、FTD2XX.dllのAPIであるFT_GetDeviceInfoList()を実行。
すると接続しているデバイスの情報を取得できたが、「Location ID」が"0"になっていた。
(0x00000331といった値になるハズ)

01_log
<図01>FT_GetDeviceInfoList()の取得結果

●解析
この「Location ID」が"0"になる現象について調べるとFTDI社による見解が公開されており(下記リンク先参照)、簡単に言うとWindows8以前のOSでUSB3.0のルートハブ系統に接続すると予期しない動作となるとの事で、本現象はTN152の「2.1.2 Location ID Retuned As 0」に該当する。

FTDIとしては、これはUSBホストベンダによる問題であり、USBデバイスの製造者が解決する問題ではない、として対策はしない方針のようです。
言い分も分かるけど、ちょっと困りますね。

・FTDI テクニカルノート「TN_152 USB3.0 Compatibility Issues Explained」
http://www.ftdichip.com/Support/Documents/TechnicalNotes/TN_152_USB_3.0_Compatibility_Issues_Explained.pdf

・TN_152のヒューマンデータによる和訳
http://www.hdl.co.jp/USB/FTDI/lt2/index.html

公開されているlibMPSSE.dllのソースコードから、SPI_GetNumChannels()でチャネル数が取得できない原因を調べていくと、ftdi_mid.cにてLocation IDを参照している箇所あり。
上記問題から、正しくチャネル数が検出できなかったようです。
ちなみにFT232Hの場合はLocation IDを参照していないため、初めから問題なかったようです。

02_source
<図02>「ftdi_mid.c」の該当箇所

●対策
FTDI テクニカルノートTN_152では、
・USB2.0のポートに接続する。
・Windows8以降のOSを使用する。
としているが、まだまだWindows7環境が多い事と、USBポートを限定させるのも使い勝手が悪いのでlibMPSSE.dllを修正してみました。
添付しますのでお使い下さい。
「libMPSSE.dll.zip」をダウンロード

<図02>の該当箇所を仮修正(if文をコメントアウト)しMinGWでコンパイル。
生成されたlibMPSSE.dllで動作検証を行い、SPI_GetNumChannels()でのチャネル数取得、SPI_GetChannelInfo()やSPI_OpenChannel()等で期待通りの動作をする事と、実際のデバイスからも信号出力される事を確認しました。

03_a0xaa
<図03>Ach SPI_DATA = 0xAA時の波形

04_a0x55
<図04>Ach SPI_DATA = 0x55時の波形

05_agpio
<図05>Ach GPIO(H→L→H)時の波形

Bch側も同様に動作しているので波形は省略。

●考察
今回行った仮修正の妥当性について。
修正対象となったftdi_mid.cのMid_CheckMPSSEAvailable()は、対象デバイスの中から利用可能なMPSSE数を取得する関数で(表1参照)。
FT232HやFT2232Hに関しては総チャネル数に対して利用可能なMPSSE数が同数のため、今回行ったコメントアウトによる修正でも問題ないと思います。
しかしFT2232D(またはC、L)やFT4232Hのように総チャネル数に対してMPSSE数が異なるデバイスを使用する際は別の対策を行う必要がありそうです。

                                                                                     
<表1>総チャネル数とMPSSE数
デバイス 総チャネル数 MPSSE数
FT232H 1 1
FT2232D/C/L 2 1
FT2232H 2 2
FT4232H 4 2

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

14/07/12 Xamarin テキストのデフォルトカラーを取得

Android向けのアプリ開発始めました。
環境はXamarinで、言語はC#。

VisualStudioのC#とは勝手が随分違っていて、まず最初に躓いたのがテキストのデフォルトカラーの取得方法。
無効文字を入力された時などのエラーを示すため一旦赤色に設定したあと、元のデフォルトカラーに戻す方法が分からない。
VisualStudio C#では、

	textBox.ForeColor = Color.Empty;

とすれば元の色に戻せる。
他にも、

	Color defaultColor = textBox.ForeColor;

としておいて、色を戻したい時にdefaultColorをセットする方法も考えられるが…、
Xamarin(というかAndroid?)だと、Color構造体にEmptyフィールドがないし、そもそもForeColorプロパティがない。
そこで時間をかけて調べた結果、以下の通りにしてみました。

	[Activity (Label = "サンプル", MainLauncher = true)]
	public class MainActivity : Activity
	{
		/// 

デフォルトのフォントカラーを保持

private Color defaultColor; #region OnCreateイベント ///

OnCreateイベント

/// Bundle. protected override void OnCreate (Bundle bundle) { base.OnCreate (bundle); // Set our view from the "main" layout resource SetContentView (Resource.Layout.Main); // テキストのデフォルトカラーを取得 defaultColor = new Color(editText.TextColors.DefaultColor); // テキストのカラーを変更(例えばエラーを示したい時とか) editText.SetTextColor(Color.Red); // そして、デフォルトのカラーに戻す editText.SetTextColor(defaultColor); } #endregion OnCreateイベント         }

もし、もっとスマートな方法がある、そもそも思想が間違っている、などのご意見がありましたらご指摘ください。

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

09/12/04 リッチテキストBoxの行間を詰める

VisualStudio2005 C#のお話です。

どうしてもリッチテキストBoxを使う必要が出てきたけど、リッチテキストBoxは行間が開いてしまうのがイヤ(しかも設定できない)。
おまけに、文字入力をするとデザイナ設定時に指定したフォントとは違うフォントに勝手に変わってしまうなど、もうダメダメでがっかり。
それでも使う必要があるので色々と調べてみてもAPIを駆使して解決する方法しか見つからなかった。
コレはコレであまり綺麗じゃないので、もっと調べていたら…
いい方法が見つかりました。
LanguageOptionプロパティを変えれば良さそうです。
調べてみた所、規定値は以下のようです。

 
richTextBox1.LanguageOption = RichTextBoxLanguageOptions.AutoFont |
                    RichTextBoxLanguageOptions.DualFont;
 

そこで、勝手にフォントが変わるのを防ぐには、

 
richTextBox1.LanguageOption -= RichTextBoxLanguageOptions.DualFont;
// または
richTextBox1.LanguageOption = RichTextBoxLanguageOptions.AutoFont;
 

勝手にフォントが変わるのを防いで、かつ行間を詰めるには、

 
richTextBox1.LanguageOption = RichTextBoxLanguageOptions.UIFonts;
 

これで良さそうです。
この方法で良い根拠は他で調べて頂くとして…
この1行をコンストラクタあたりに記述しておくだけで、見た目は普通のテキストBoxと同じになります。
APIを駆使する必要もないので簡単です。
ただ、スクロールは遅いけどね(^_^;)ゞ

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