2016年5月29日日曜日

ubuntuでlibftdiを使って12Mbit/sのシリアル通信をする方法


苦労したので共有します。

目的

boardrateに12000000を設定して、12MBit/s(約1MByte/s)の通信を行います。

手順

最も重要なのは、version1.0以上(自分は1.3を使用)のlibftdiを使うことです。

libusb ver1以上のインストール

ubuntuは14.04も16.04もapt-getではver1をインストールできません。
そのため、下記のファイルに従ってインストールを行います。

README.build

上記ファイルの内容を、備忘録も兼ねて展開します。

buildに使うツールをインストールします。
sudo apt-get install build-essential
sudo apt-get install git-core
sudo apt-get install cmake

libftdiの動作に必要な関連プロジェクトをインストールします。
sudo apt-get install libconfuse-dev
sudo apt-get install swig python-dev
sudo apt-get install libboost-all-dev

libftdiのコードを取得します。
mkdir ~/gitprojects
cd ~/gitprojects
git clone git://developer.intra2net.com/libftdi

buildとinstallを行います。
cd ~/gitprojests/libftdi
mkdir build
cd build
cmake  -DCMAKE_INSTALL_PREFIX="/usr" ../
make
sudo make install

動作確認します。
cd ~/gitprojects/libftdi/build/examples
./find_all_pp

ftdiのチップが付いている機器がPCに接続されていたら、認識されるはずです。
asuki@asuki-ThinkPad-S1-Yoga:~/gitprojects/libftdi/build/examples$ ./find_all_pp 
Found devices ( VID: 0x403, PID: 0x6010 )
------------------------------------------------
FTDI (0x1c918a0): , ,  (Open FAILED)

libftdiのインストールできたので、次はプログラムを作ります。

プログラムの作成

このプログラムは下記の目的で作成しています。

通信相手: FT2232HLのBポートに接続された機器
通信速度: 12Mbit/s
通信相手の動作: 送信したデータを返信する

serial_with_libftdi.cpp
#include <libftdi1/ftdi.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define TARGET_BAUDRATE   12000000 // 12Mbit/s
#define TARGET_VENDOR_ID  1027
#define TARGET_PRODUCT_ID 24592
#define TARGET_INTERFACE  INTERFACE_B

int main(void) {
  struct ftdi_context* ftdic;
  int result;

  // open ftdi a device
  ftdic = ftdi_new();
  ftdi_set_interface(ftdic, TARGET_INTERFACE);
  result = ftdi_usb_open(ftdic, TARGET_VENDOR_ID, TARGET_PRODUCT_ID);

  if ( result < 0 && result != -5 ) {
    fprintf(stderr, "unable to open ftdi device: %d (%s)\n", result, ftdi_get_error_string(ftdic));
    exit(-1);
  }

  result = ftdi_set_baudrate(ftdic, TARGET_BAUDRATE);
  if ( result != 0 ) {
    fprintf(stderr, "failed to set baudrate: %d (%s)\n", result, ftdi_get_error_string(ftdic));
    exit(-1);
  }
  printf("baudrate: %d\n", ftdic->baudrate);

  const char* command_chars = "abcd";
  unsigned char sending_data[1];
  unsigned char received_data[255];
  int received_data_length = 0;

  for ( int i=0; i<4 ) {


    // data send
    sending_data[0] = command_chars[i];
    ftdi_write_data(ftdic, sending_data, 1);
    printf("Send: %c\n", sending_data[0]);

    // data receive
    received_data_length = ftdi_read_data(ftdic, received_data, 254);
    received_data[received_data_length] = 0;
    printf("Received: %s\n", received_data);

    sleep(1);
  }

  ftdi_usb_close(ftdic);
  ftdi_free(ftdic);

  return 0;
}

ファイルの内容は変わるかもしれませんが、上記のファイルはgitで下記のurlにて管理しています。
https://github.com/asukiaaa/miniSpartan6-plus_usb_communication/blob/master/cpp/src/serial_with_libftdi.cpp

コンパイル

下記のようにlibftdi1のフラグ「`pkg-config --cflags --libs libftdi1`」を付けてコンパイルします。
g++ serial_with_libftdi.cpp -o serial_with_libftdi `pkg-config --cflags --libs libftdi1`

実行

ftdiのデバイスをPCに接続し、プログラムを実行します。
sudo ./serial_with_libftdi

うまくいけば通信できるはずです。

通信相手のFPGAのコードも含めて、ソースコードは下記のリポジトリで管理しています。
https://github.com/asukiaaa/miniSpartan6-plus_usb_communication

以上です。
何かのお役に立てば嬉しいです。

参考

http://penguin.tantin.jp/hard/libFTDI.html
https://www.intra2net.com/en/developer/libftdi/documentation/
https://github.com/legege/libftdi/blob/master/test/baudrate.cpp
https://github.com/legege/libftdi/blob/master/src/ftdi.h

0 件のコメント :