= [http://www.ftdichip.com/Products/ICs/FT260.html FTDI FT260]で実験 = FT260をBBBに繋いで使い方の実験してみる。 == パッケージインストール == 始めにpythonで実験するために、hidapi周りのパッケージをインストールする。 {{{ root@beaglebone:~# apt-get install libhidapi-libusb0 libudev-dev libusb root@beaglebone:~# pip install --trusted-host pypi.python.org Cython hidapi }}} == デバイスの接続 == 開発ボードにはI2C接続のEEPROMが搭載されていて、defaultではジャンパで接続されている。[[br]] なるべく余計な接続をしない状態で実験したかったのでEEPROMなしの状態にジャンパを設定する。[[br]] デバイスを接続すると、{{{musb-hdrc musb-hdrc.1.auto: Babble}}}というメッセージが大量に出力されるが、一応認識されて繋がりはするようだ。 {{{ [ 6891.320644] musb-hdrc: 28/31 max ep, 16384/16384 memory [ 6891.659553] musb-hdrc musb-hdrc.1.auto: Babble [ 6891.664416] musb-hdrc musb-hdrc.1.auto: Babble [ 6891.668943] musb-hdrc: setup fifo_mode 4 [ 6891.668996] musb-hdrc: 28/31 max ep, 16384/16384 memory [ 6892.066437] usb 1-1: new full-speed USB device number 27 using musb-hdrc [ 6892.199679] usb 1-1: New USB device found, idVendor=0403, idProduct=6030 [ 6892.199741] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [ 6892.199773] usb 1-1: Product: FT260 [ 6892.199803] usb 1-1: Manufacturer: FTDI [ 6902.262497] hid-generic 0003:0403:6030.0005: usb_submit_urb(ctrl) failed: -1 [ 6902.276074] hid-generic 0003:0403:6030.0005: timeout initializing reports [ 6902.284785] hid-generic 0003:0403:6030.0005: hidraw0: USB HID v1.11 Device [FTDI FT260] on usb-musb-hdrc.1.auto-1/input0 [ 6912.310492] hid-generic 0003:0403:6030.0006: usb_submit_urb(ctrl) failed: -1 [ 6912.322341] hid-generic 0003:0403:6030.0006: timeout initializing reports [ 6912.330402] hid-generic 0003:0403:6030.0006: hidraw1: USB HID v1.11 Device [FTDI FT260] on usb-musb-hdrc.1.auto-1/input1 }}} HIDデバイスが2つ認識されているが、[http://www.ftdichip.com/Support/Documents/ProgramGuides/AN_394_User_Guide_for_FT260.pdf FT260のアプリケーションノート]の6ページ目{{{1.2 FT260 HID Interfaces and Endpoints}}}をみると、I2CとUARTがそれぞれ別のHIDとして認識されるようだ。[[br]] {{{hidraw0}}}がI2C、{{{hidraw1}}}がUARTらしい。 ジャンパを設定し直して、I2Cのみにしてみると、 {{{ [ 7774.216655] musb-hdrc: 28/31 max ep, 16384/16384 memory [ 7774.555547] musb-hdrc musb-hdrc.1.auto: Babble [ 7774.560500] musb-hdrc musb-hdrc.1.auto: Babble [ 7774.565029] musb-hdrc: setup fifo_mode 4 [ 7774.565083] musb-hdrc: 28/31 max ep, 16384/16384 memory [ 7774.962288] usb 1-1: new full-speed USB device number 31 using musb-hdrc [ 7775.093398] usb 1-1: New USB device found, idVendor=0403, idProduct=6030 [ 7775.093436] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [ 7775.093452] usb 1-1: Product: FT260 [ 7775.093467] usb 1-1: Manufacturer: FTDI [ 7785.130492] hid-generic 0003:0403:6030.0007: usb_submit_urb(ctrl) failed: -1 [ 7785.144095] hid-generic 0003:0403:6030.0007: timeout initializing reports [ 7785.153751] hid-generic 0003:0403:6030.0007: hidraw0: USB HID v1.11 Device [FTDI FT260] on usb-musb-hdrc.1.auto-1/input0 }}} となり、I2Cのみになるので、これで実験することにする。 == pythonでのテスト == 以前、帯名さんがHIDデバイスのテストをした時のドキュメントを参考にしてみる。[[br]] まずは、FT260の設定を取得してみる。 {{{ oot@beaglebone:~# ipython --nosep Python 2.7.9 (default, Aug 13 2016, 17:56:53) Type "copyright", "credits" or "license" for more information. IPython 2.3.0 -- An enhanced Interactive Python. ? -> Introduction and overview of IPython's features. %quickref -> Quick reference. help -> Python's own help system. object? -> Details about 'object', use 'object??' for extra details. In [1]: import hid In [2]: h = hid.device() In [3]: In [3]: h.open(0x0403, 0x6030) In [4]: h.set_nonblocking(1) Out[4]: 0 In [5]: h.write([0xA1] + [0]*63) Out[5]: 64 In [6]: h.read(64) Out[6]: [] In [7]: h.write([0xA0] + [0]*63) Out[7]: 64 In [8]: h.write([0xA0] + [0]*63) Out[8]: 64 In [9]: h.read(64) Out[9]: [] In [10]: h.write([0xA0] + [0]*11) Out[10]: -1 In [11]: h.write([0xA0] + [0]*63) Out[11]: -1 In [12]: h.read(64) Out[12]: [] In [13]: h.read(64) Out[13]: [] In [14]: h.write([0xA0] + [0]*63) Out[14]: -1 In [15]: h.write([0xC0] + [0]*63) Out[15]: -1 In [16]: h.close() }}} うまくいかない、、、[[br]] 色々見ていったところ、取得するデータによって使用する関数が違うらしい。[[br]] [http://www.ftdichip.com/Support/Documents/ProgramGuides/AN_394_User_Guide_for_FT260.pdf FT260のアプリケーションノート]を見てみると、15ページの{{{4.3 FT260 Report ID List}}}には、 || Report ID || Type || description || || 0xA0 || Feature || Chip code || || 0xA1 || Feature || System Setting || || 0xB0 || Feature || GPIO || || 0xB1 || Input || Interrupt Status (from UART interface) || || 0xC0 || Feature || I2C Status || || 0xC2 || Output || I2C Read Request || || 0xD0 ~ 0xDE || Input, Output|| I2C Report || || 0xE0 || Feature || UART Status || || 0xE2 || Feature || UART RI and DCD Status || || 0xF0 ~0xFE ||Input, Output || UART Report || と書いてあり、{{{Feature}}}へのアクセスは{{{send_feature_report, get_feature_report}}}で行い、{{{INPUT,OUTPUT}}}は{{{write,read}}}で行うらしい。 {{{ root@beaglebone:~# ipython --nosep Python 2.7.9 (default, Aug 13 2016, 17:56:53) Type "copyright", "credits" or "license" for more information. IPython 2.3.0 -- An enhanced Interactive Python. ? -> Introduction and overview of IPython's features. %quickref -> Quick reference. help -> Python's own help system. object? -> Details about 'object', use 'object??' for extra details. In [1]: import hid In [2]: h = hid.device() In [3]: h.open(0x0403, 0x6030) In [4]: h.get_feature_report(0xA0,13) Out[4]: [160, 2, 96, 2, 0, 2, 96, 1, 0, 1, 1, 3, 0] In [5]: h.get_feature_report(0xA1,64) Out[5]: [161, 1, 2, 0, 1, 1, 0, 0, 1, 3, 6, 1, 1, 12, 1, 0, 0, 0, 0, 0, 172, 0, 188, 0, 204] }}} これでやっと、FT260にアクセスできることが確認できた。[[br]] 次にI2C上のスレーブデバイスにアクセス。[[br]] 接続しているI2Cデバイスは、[http://www.analog.com/jp/products/analog-to-digital-converters/integrated-special-purpose-converters/digital-temperature-sensors/adt7410.html#product-overview ADT7410]を基板化した、[http://akizukidenshi.com/catalog/g/gM-06675/ 秋月電子 ADT7410使用 高精度・高分解能 I2C・16Bit 温度センサモジュール]。 FT260開発ボードの3.3V電源と、IO0,IO1を接続した。 {{{ FT260 <-> ADT7410 3.3V (JP6-1) VDD IO0 (JP6-11) SCL IO1 (JP6-10) SDA GND GND }}} 温度センサのI2Cアドレスは0x48としておく。 {{{ In [1]: import hid In [2]: h = hid.device() In [3]: h.open(0x0403, 0x6030) In [4]: h.set_nonblocking(1) Out[4]: 0 In [5]: h.write([0xC2, 0x48, 0x06, 0x04, 0x00]) Out[5]: 5 In [6]: h.read(64) Out[6]: [208, 4, 13, 88, 128, 0, 50, 0] }}} 先頭2byteはFT260のHIDコマンドヘッダなので、{{{[13, 88, 128, 0, 50, 0]}}}がデータ。[[br]] 取得するデータ数は4byteだけど、6byteデータが出てくる。多分、HIDヘッダも含めて4byte単位でデータが出てくるのだろう。[[br]] ADT7410のデータシートから、{{{[13, 88]}}}が温度データ、次の{{{[128]}}}がStatus、{{{[0]}}}がConfigurationとなっているようだ。[[br]] Configurationの7bit目が1なら16bit,0なら13bitデータになる。[[br]] 13bit時のデータは[15:3]が有効なデータなので、計算式は、 {{{ ADC_DEC = ((HSB<<8) | LSB)>>3 Positive_Temp[℃] = ADC_DEC /16.0 Negative_Temp[℃] = (ADC_DEC - 8192)/16 }}} となるらしい。[[br]] この計算式に当てはめると、{{{LSB=88,HSB=13}}}の場合、{{{26.6875[℃]}}}となる。[[br]] 今回は16bitで使いたいので、Configration Registorの7bit目を1にする必要がある。[[br]] どうやるか試行錯誤して、I2Cプロトコルにおける設定(書き込み)は、書き込みアドレスの後ろに設定データを付けて送ればいいことを思い出した。[[br]] {{{ In [25]: h.write([0xD0, 0x48, 0x06, 0x02, 0x03,0x80,0x00,0x00]) Out[25]: 8 In [26]: h.write([0xC2, 0x48, 0x06, 0x04, 0x00]) Out[26]: 5 In [27]: h.read(64) Out[27]: [208, 4, 13, 75, 128, 128, 0, 0] }}} レジスタ設定後にデータを読み出すと、Configuration Registorが128(0x80)となっていて、16bitになっていることがわかる。[[br]] 16bit時の計算式は、 {{{ ADC_DEC = ((HSB<<8) | LSB) Positive_Temp[℃] = ADC_DEC /128 Negative_Temp[℃] = (ADC_DEC - 65536)/128 }}} となる。計算式に当てはめると、{{{LSB=75,HSB=13}}}の場合、{{{26.5859375[℃]}}}となる。[[br]] これで、FT260をつかったI2Cデバイスの制御に必要なコマンドは全て使い方が分かったので、IOC化することができそうである。 == 複数デバイス接続 == FT260開発ボードをUSBハブで複数繋いでみると、当たり前だが普通に認識して/dev/hidraw*が生成される。[[br]] FT232RやFT230Xには、デフォルトでチップ毎にシリアル番号が設定されていて、それを使えばデバイス名の固定が可能だが、FT260にはそれがない。 {{{ debian@beaglebone:~$ udevadm info -a -p $(udevadm info -q path -n /dev/hidraw0) : looking at parent device '/devices/platform/ocp/47400000.usb/47401c00.usb/musb-hdrc.1.auto/usb1/1-1/1-1.2': KERNELS=="1-1.2" SUBSYSTEMS=="usb" DRIVERS=="usb" ATTRS{authorized}=="1" ATTRS{avoid_reset_quirk}=="0" ATTRS{bConfigurationValue}=="1" ATTRS{bDeviceClass}=="00" ATTRS{bDeviceProtocol}=="00" ATTRS{bDeviceSubClass}=="00" ATTRS{bMaxPacketSize0}=="64" ATTRS{bMaxPower}=="100mA" ATTRS{bNumConfigurations}=="1" ATTRS{bNumInterfaces}==" 1" ATTRS{bcdDevice}=="2200" ATTRS{bmAttributes}=="a0" ATTRS{busnum}=="1" ATTRS{configuration}=="" ATTRS{devnum}=="118" ATTRS{devpath}=="1.2" ATTRS{idProduct}=="6030" ATTRS{idVendor}=="0403" ATTRS{ltm_capable}=="no" ATTRS{manufacturer}=="FTDI" ATTRS{maxchild}=="0" ATTRS{product}=="FT260" ATTRS{quirks}=="0x0" ATTRS{removable}=="unknown" ATTRS{speed}=="12" ATTRS{urbnum}=="16" ATTRS{version}==" 2.00" : }}} FT232R等の他のチップでは、{{{ATTRS{SerialNumber}==xxxx}}}のような表示が入る。(詳細な属性名は不明)[[br]] データシートを見ると、I2C接続した外付けEEPROMに書き込むと、表示されるようになるらしい。[[br]] 実験の初めにEEPROMを外して実験していたが、接続しなおしてから、シリアル番号を書き込んでみる。[[br]] 設定の変更はI2Cコマンドでできるようだが、[http://www.ftdichip.com/Support/Utilities.htm#FT_Prog FT_Prog]というユティリティをFTDIが用意してくれているので、今回はそれを使う。[[br]] [[Image(FT_Prog.png,300)]] {{{USB String Descriptors -> Serial Number Enabled}}}と{{{Auto Generate Serial No}}}にチェックを入れて、メインメニューの{{{DEVICES -> Program}}}を選択すると、 [[Image(FT_Prog_Write.png)]] のダイアログボックスで{{{Program}}}すれば自動的にシリアル番号が生成されてEEPROMに書き込まれる。[[br]] '''ここでの注意点は、プログラムのデフォルトのままだとvendoridが0403から0803に書き変わってしまうので、書き込み前にチェックすること。'''[[br]] 書き込み実行後に再度デバイス情報を見てみると、今度は{{{ATTRS{serial}==}}}が設定されている。[[br]] {{{ debian@beaglebone:~$ udevadm info -a -p $(udevadm info -q path -n /dev/hidraw0) : looking at parent device '/devices/platform/ocp/47400000.usb/47401c00.usb/musb-hdrc.1.auto/usb1/1-1/1-1.1': KERNELS=="1-1.1" SUBSYSTEMS=="usb" DRIVERS=="usb" ATTRS{authorized}=="1" ATTRS{avoid_reset_quirk}=="0" ATTRS{bConfigurationValue}=="1" ATTRS{bDeviceClass}=="00" ATTRS{bDeviceProtocol}=="00" ATTRS{bDeviceSubClass}=="00" ATTRS{bMaxPacketSize0}=="64" ATTRS{bMaxPower}=="128mA" ATTRS{bNumConfigurations}=="1" ATTRS{bNumInterfaces}==" 1" ATTRS{bcdDevice}=="2200" ATTRS{bmAttributes}=="a0" ATTRS{busnum}=="1" ATTRS{configuration}=="" ATTRS{devnum}=="124" ATTRS{devpath}=="1.1" ATTRS{idProduct}=="6030" ATTRS{idVendor}=="0403" ATTRS{ltm_capable}=="no" ATTRS{manufacturer}=="FTDI" ATTRS{maxchild}=="0" ATTRS{product}=="FT260" ATTRS{quirks}=="0x0" ATTRS{removable}=="unknown" ATTRS{serial}=="FT27KQDF" ATTRS{speed}=="12" ATTRS{urbnum}=="18" ATTRS{version}==" 2.00" : }}} デバイスを再接続後、pythonでアクセスしてみる。 {{{ root@beaglebone:~# ipython --nosep In [1]: import hid In [2]: h = hid.device() In [3]: h.open(0x0403, 0x6030, "FT27KQDF") --------------------------------------------------------------------------- TypeError Traceback (most recent call last) in () ----> 1 h.open(0x0403, 0x6030, "FT27KQDF") TypeError: Argument 'serial_number' has incorrect type (expected unicode, got str) In [4]: h.open(0x0403, 0x6030, u"FT27KQDF") }}} シリアル番号をunicodeで設定したら、オープンできたので、大丈夫そう。[[br]] == IOC == 接続方法と使用するコマンドがわかったので、IOCを作成する。[[br]] 作成するレコードは、ADT7410のADCを16bitに設定するコマンドと、温度を取得するコマンドのみ。[[br]] 以前作った、[wiki:/epics/bbb/debian/USBHID/USB_SP4T drvAsynUSBHID]を使って、コマンドを実装。[[br]] ここで気付いたのだが、drvAsynUSBHIDはInput,Outputを使った制御には使えるが、USBHIDデバイス自体を制御するFeatureコマンドには対応していない。[[br]] 今回もFeatureコマンドを使わなくても目的は達成できたが、今後Featureコマンドが必須の制御をする場合には、何らかの解決策を考える必要がありそう。[[br]] === 使用コマンド(FT260) === 今回使用するFT260上のコマンドは、 * I2C Write Request(0xD0~0xDE) * I2C Read Request(0xC2) * I2C Input Report(0xD0~0xDE) のみである。I2C Input ReportはReadで返ってくるフォーマットの定義なので、I2C Write RequestとI2C Read Requestだけを実装する。 === protocol ファイル === 今回作成したプロトコルファイルがこれ。 {{{ TERMINATOR=""; LockTimeout = 500; ReplyTimeout = 100; ReadTimeout = 100; WriteTimeout = 100; MaxInput=8; wr_4 = 0xD0; rd = 0xC2; flg = 0x06; len = 0x04; ##################### # $1:I2C slave device addr ##################### # Set ADT7410 ADC Resolution(16bit) setADCRes { out $wr_4 $1 $flg 0x02 0x03 0x80 0x00 0x00; } # Read ADT7410 templature value getTempReg { out $rd $1 $flg $len 0x00; in $wr_4 $len "%2r" "%*4r"; } }}} I2Cデバイスのアドレスをdbファイルから設定できるようにして、温度レジスタを読み込んでCALCで計算するようにした。[[br]] === DBファイル === {{{ record(bo, "$(user):ADT7410:init") { field(DESC, "Set ADT7410 ADC 16bit") field(DTYP, "stream") field(OUT, "@FT260_ADT7410.proto setADCRes($(i2caddr)) $(dev)") } record(longin, "$(user):temp:reg") { field(DESC, "Get temperature raw registor") field(DTYP, "stream") field(INP, "@FT260_ADT7410.proto getTempReg($(i2caddr)) $(dev)") field(SCAN, "$(scan)") field(FLNK, "$(user):temp") } record(calc, "$(user):temp") { field(DESC, "Get temperature") field(INPA, "$(user):temp:reg") field(CALC, "(A&0x8000)=0x8000?(A-65536)/128:A/128") field(PREC, "5") field(EGU, "degC") } }}} == 問題発生 == しばらく動かして値をcamonitorしていると、あるタイミングで止まってしまう。[[br]] camonitorだけではわからず、IOCのasynログを出力してみると、温度レジスタのLSBに0x00が入った時以降、データが出力されなくなっていることが判明した。[[br]] {{{ 2017/09/07 07:20:18.514 HID1 write 5 ツH \302H\006\004\000 c2 48 06 04 00 2017/09/07 07:20:18.517 HID1 write(raw) 65 ツH \302H\006\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 c2 48 06 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2017/09/07 07:20:18.544 HID1: wrote 5 bytes to 403:6030:FT27KQDF, return asynSuccess 2017/09/07 07:20:18.545 HID1 addr -1 queueRequest priority 0 from lockHolder 2017/09/07 07:20:18.546 HID1 schedule queueRequest timeout 2017/09/07 07:20:18.548 asynManager::portThread port=HID1 callback 2017/09/07 07:20:18.549 HID1: read 8 bytes from 403:6030:FT27KQDF, return asynSuccess 2017/09/07 07:20:18.551 HID1 read(raw) 8 ミ \320\004\016\n\200\200\000\000 d0 04 0e 0a 80 80 00 00 2017/09/07 07:20:19.500 HID1 addr -1 queueRequest priority 0 not lockHolder 2017/09/07 07:20:19.501 HID1 schedule queueRequest timeout 2017/09/07 07:20:19.502 asynManager::portThread port=HID1 callback 2017/09/07 07:20:19.503 HID1 addr -1 queueRequest priority 0 not lockHolder 2017/09/07 07:20:19.505 HID1 schedule queueRequest timeout 2017/09/07 07:20:19.506 asynManager::portThread port=HID1 callback 2017/09/07 07:20:19.506 HID1: read 0 bytes from 403:6030:FT27KQDF, return asynSuccess 2017/09/07 07:20:19.507 HID1 read(raw) 0 2017/09/07 07:20:19.508 HID1 write 5 ツH \302H\006\004\000 c2 48 06 04 00 2017/09/07 07:20:19.510 HID1 write(raw) 65 ツH \302H\006\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 c2 48 06 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2017/09/07 07:20:19.527 HID1: wrote 5 bytes to 403:6030:FT27KQDF, return asynSuccess 2017/09/07 07:20:19.529 HID1 addr -1 queueRequest priority 0 from lockHolder 2017/09/07 07:20:19.529 HID1 schedule queueRequest timeout 2017/09/07 07:20:19.529 asynManager::portThread port=HID1 callback 2017/09/07 07:20:19.530 HID1: read 8 bytes from 403:6030:FT27KQDF, return asynSuccess 2017/09/07 07:20:19.531 HID1 read(raw) 8 ミ \320\004\016\000\200\200\000\000 d0 04 0e 00 80 80 00 00 2017/09/07 07:20:20.501 HID1 addr -1 queueRequest priority 0 not lockHolder 2017/09/07 07:20:20.503 HID1 schedule queueRequest timeout 2017/09/07 07:20:20.505 asynManager::portThread port=HID1 callback 2017/09/07 07:20:20.506 HID1 addr -1 queueRequest priority 0 not lockHolder 2017/09/07 07:20:20.507 HID1 schedule queueRequest timeout 2017/09/07 07:20:20.508 asynManager::portThread port=HID1 callback 2017/09/07 07:20:20.509 HID1: read 0 bytes from 403:6030:FT27KQDF, return asynSuccess 2017/09/07 07:20:20.511 HID1 read(raw) 0 2017/09/07 07:20:20.511 HID1 write 5 ツH \302H\006\004\000 c2 48 06 04 00 2017/09/07 07:20:20.513 HID1 write(raw) 65 ツH \302H\006\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 c2 48 06 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2017/09/07 07:20:20.529 HID1: wrote 5 bytes to 403:6030:FT27KQDF, return asynSuccess 2017/09/07 07:20:20.530 HID1 addr -1 queueRequest priority 0 from lockHolder 2017/09/07 07:20:20.531 HID1 schedule queueRequest timeout 2017/09/07 07:20:20.531 asynManager::portThread port=HID1 callback 2017/09/07 07:20:22.535 HID1: read 0 bytes from 403:6030:FT27KQDF, return asynSuccess 2017/09/07 07:20:22.535 HID1 read(raw) 0 2017/09/07 07:20:24.538 HID1: read 0 bytes from 403:6030:FT27KQDF, return asynSuccess 2017/09/07 07:20:24.538 HID1 read(raw) 0 2017/09/07 07:20:26.541 HID1: read 0 bytes from 403:6030:FT27KQDF, return asynSuccess 2017/09/07 07:20:26.541 HID1 read(raw) 0 }}} この状態になると、IOCを止めるだけではダメで、USBコネクタを挿抜して再認識させないと復活しない。[[br]] 始めは、HIDAPIの方の問題かと考え、pythonでテストプログラムを書いて実行してみたが、LSBが0x00になっても止まることはなかった。[[br]] その時のスクリプトがこれ。[[br]] {{{ import hid import time import logging h = hid.device() h.open(0x0403, 0x6030, u"FT27KQDF") h.set_nonblocking(1) logging.basicConfig(format='[%(asctime)s]: %(message)s', level=logging.DEBUG) h.write([0xD0, 0x48, 0x06, 0x02, 0x03,0x80,0x00,0x00]) while True: try: wr = h.write([0xC2, 0x48, 0x06, 0x04, 0x00]) logging.debug("[W]" + str(wr)) rd = h.read(64) logging.debug("[R]" + str(rd)) time.sleep(1) except: break h.close() }}} 実行結果がこれ。 {{{ [2017-09-11 09:46:04,155]: [R][208, 4, 12, 253, 128, 128, 0, 0] [2017-09-11 09:46:05,161]: [W]5 [2017-09-11 09:46:05,163]: [R][208, 4, 13, 2, 128, 128, 0, 0] [2017-09-11 09:46:06,169]: [W]5 [2017-09-11 09:46:06,171]: [R][208, 4, 13, 1, 128, 128, 0, 0] [2017-09-11 09:46:07,177]: [W]5 [2017-09-11 09:46:07,179]: [R][208, 4, 13, 0, 128, 128, 0, 0] [2017-09-11 09:46:08,185]: [W]5 [2017-09-11 09:46:08,187]: [R][208, 4, 12, 253, 128, 128, 0, 0] [2017-09-11 09:46:09,193]: [W]5 [2017-09-11 09:46:09,195]: [R][208, 4, 13, 0, 128, 128, 0, 0] [2017-09-11 09:46:10,199]: [W]5 [2017-09-11 09:46:10,202]: [R][208, 4, 13, 0, 128, 128, 0, 0] [2017-09-11 09:46:11,207]: [W]5 [2017-09-11 09:46:11,209]: [R][208, 4, 13, 4, 128, 128, 0, 0] [2017-09-11 09:46:12,215]: [W]5 [2017-09-11 09:46:12,217]: [R][208, 4, 13, 5, 128, 128, 0, 0] }}} pythonでは問題なく取り込めてる。[[br]] IOCが止まるのは、asynかstreamdeviceのどちらかの問題の可能性が高いが、詳細は追っていないので現時点では原因は不明。[[br]]