wiki:epics/bbb/debian/thermometer/ft260

Version 5 (modified by michkawa, 7 years ago) (diff)

--

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ではジャンパで接続されている。
なるべく余計な接続をしない状態で実験したかったのでEEPROMなしの状態にジャンパを設定する。

デバイスを接続すると、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つ認識されているが、FT260のアプリケーションノートの6ページ目1.2 FT260 HID Interfaces and Endpointsをみると、I2CとUARTがそれぞれ別のHIDとして認識されるようだ。
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デバイスのテストをした時のドキュメントを参考にしてみる。
まずは、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()

うまくいかない、、、
色々見ていったところ、取得するデータによって使用する関数が違うらしい。
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,OUTPUTwrite,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にアクセスできることが確認できた。
次にI2C上のスレーブデバイスにアクセス。

接続しているI2Cデバイスは、ADT7410を基板化した、秋月電子 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]がデータ。
取得するデータ数は4byteだけど、6byteデータが出てくる。多分、HIDヘッダも含めて4byte単位でデータが出てくるのだろう。

ADT7410のデータシートから、[13, 88]が温度データ、次の[128]がStatus、[0]がConfigurationとなっているようだ。
Configurationの7bit目が1なら16bit,0なら13bitデータになる。
13bit時のデータは[15:3]が有効なデータなので、計算式は、

ADC_DEC = ((HSB<<8) | LSB)>>3

Positive_Temp[℃] = ADC_DEC /16.0
Negative_Temp[℃] = (ADC_DEC - 8192)/16

となるらしい。
この計算式に当てはめると、LSB=88,HSB=13の場合、26.6875[℃]となる。

今回は16bitで使いたいので、Configration Registorの7bit目を1にする必要がある。
どうやるか試行錯誤して、I2Cプロトコルにおける設定(書き込み)は、書き込みアドレスの後ろに設定データを付けて送ればいいことを思い出した。

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になっていることがわかる。
16bit時の計算式は、

ADC_DEC = ((HSB<<8) | LSB)

Positive_Temp[℃] = ADC_DEC /128
Negative_Temp[℃] = (ADC_DEC - 65536)/128

となる。計算式に当てはめると、LSB=75,HSB=13の場合、26.5859375[℃]となる。

これで、FT260をつかったI2Cデバイスの制御に必要なコマンドは全て使い方が分かったので、IOC化することができそうである。

複数デバイス接続

FT260開発ボードをUSBハブで複数繋いでみると、当たり前だが普通に認識して/dev/hidraw*が生成される。
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のような表示が入る。(詳細な属性名は不明)
データシートを見ると、I2C接続した外付けEEPROMに書き込むと、表示されるようになるらしい。
実験の初めにEEPROMを外して実験していたが、接続しなおしてから、シリアル番号を書き込んでみる。
設定の変更はI2Cコマンドでできるようだが、FT_ProgというユティリティをFTDIが用意してくれているので、今回はそれを使う。

USB String Descriptors -> Serial Number EnabledAuto Generate Serial Noにチェックを入れて、メインメニューのDEVICES -> Programを選択すると、

のダイアログボックスでProgramすれば自動的にシリアル番号が生成されてEEPROMに書き込まれる。
書き込み実行後に再度デバイス情報を見てみると、今度はATTRS{serial}==が設定されている。

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"
     :

Attachments (2)

Download all attachments as: .zip