trykmkmの備忘録

自称組み込みエンジニアのブログ

Raspberry PiでFT232Hのi2cデバイス制御(7)

 今回は、libftdiを直接使用したFT232Hのi2cデバイス制御プログラムを作成しようと思います。

 プログラムは、Ori Idanさんが公開している、FT4232用ライト・リードコマンドを流用します。この記事ではライトを作成したいと思います。

 

 ラズパイの状態は、(5)の作業を終えた状態です。(厳密にいえばAdafruitのライブラリを使用しないので⑫まででOK)

 試験基板を挿入し、カレントディレクトリはホームディレクトリ(/home/pi)の状態から始めます。(OSは(3)、試験基板は(4)を参照)

 

 下記に手順を記載します。 

 ①まず、libftdiのパッケージをインストール(※1)するため

  コマンド sudo apt-get install libftdi-dev -y を入力します。

 

 ②下記コマンドを入力して、ソースコード一式をラズパイにダウンロードます。

  すでにmaster.zipというファイルがある場合は、上記コマンド入力前に、リネームか削除しておきましょう。

 

 ③ファイルを解凍します。unzip master.zip

 

 ④解凍したフォルダ内部に移動します。 cd ftdi-i2c-master 

 

 ⑤プログラムをFT4232から FT232H 用にするため、i2csend.の183行目の0x6011を0x6014にします。

 

 ⑥デバッグモードを有効にするため、i2csend.cの38行目を debug = 1 に書き換えます。 送信したデータがターミナルに表示できます。

 

 ⑦関数メインを下記コードに書き換えます。書き換える理由は、不要なオプション削除と、既存コードがデバイスアドレスを1bitシフトしたデータとそのままのデータを送る処理になっているからです。そのため、元のコードを修正しています。

int main(int argc, char *argv[]) {
    int i, a;
    char *s, *serial;
    int b = 0;
    int flag = 1;

    if(argc < 2) {
        printf("i2csend: Send data over i2c bus using ftdi FT232H port 0 I2C\n");
        return 1;
     }

    for(a = 1; a < argc; a++) {
        for(a = 1; a < argc; a++) {
            s = argv[a];
            if(*s == '-') { // This is a command line option 
                s++;
                a++;
                if(*s == 'c')
                    chan = 0;
               else if(*s == 'g')
                    gpio = 0;
               else {
                    printf("Unknown option -%c\n", *s);
                    exit(1);
              }
          }
         else
            break;
     }
    InitializeI2C(chan, gpio);
    HighSpeedSetI2CStart();

    for(i = a ; i < argc; i++) {
       // Acutaly send bytes
       s = argv[i];
       b = 0;
       if(*s == '0')
           s++;
       if(*s == 'x')
           s++;

        while(*s) {
            if(!isxdigit(*s)) {
                printf("%c Invalid hex value: %s\n", *s, argv[i]);
                break;
             }
            b *= 16;
            *s = toupper(*s);
            if(*s >= 'A')
                b += (*s - 'A' + 10);
            else
                b += (*s - '0');
                s++;
        }

        if(flag){
            flag = 0;
            b = b << 1; // R/W bit should be 0
        }

        if(debug)
            printf("Sending %02X\n", b);
        b = SendByteAndCheckACK((unsigned char)b);
        if(debug) {
            if(b)
               printf("Received ACK\n");
            else
               printf("Error reading ACK\n");
        }
  }
    HighSpeedSetI2CStop();
    ftdi_write_data(&ftdic, OutputBuffer, dwNumBytesToSend);
    dwNumBytesToSend = 0;

    ftdi_usb_close(&ftdic);
    ftdi_deinit(&ftdic);

    return 0;
}

 

 ⑧コマンド make を入力

  これで、コマンド i2csend ができました。

  使い方は、下記コマンドを入力します。

 sudo ./i2csend デバイスアドレス レジスタアドレス データ ・・・

   デバイスアドレス、レジスタアドレス、データは16進数形式で入力します。

  例として、DRV8830の出力端子を1V正転にするときの入力を示します。

f:id:trykmkm:20171204022928p:plain

 

 今回は、ここまでです。次回は、i2cgetを確認する予定です。

 

 ------------------------------------------------------------------------------------

 ※前回までのセットアップで、libftdiを使用できる環境が構築済と思っていたんですが、何か足りなかったぽいです。この作業をしないで、後述のmakeを実施すると下記のようなエラーが出ます。

f:id:trykmkm:20171120223419p:plain

 Perhaps you should add the directory containing `libftdi.pc'で検索したところ、下記のページに引っ掛かりました。

Compilation dependencies · Issue #1 · matthiasbock/flashrom-ice40 · GitHub

上記ページによれば、aptgetでlibftdiをインストールすればよさそうです。

すでにソースからコンパイルしてインストールしたのに、大丈夫でしょうか?

pythonに異常がでたら、OSセットアップからやり直しましょうか(汗)

ソースコードからインストールするのと、apt-getでインストールするのは何が違うのか・・・。自身への課題としておきましょう。