68534
SPRESENSE SDK を使用したI2C通信が上手く行かずに困ってます。

**■環境**  
PC：Ubuntu 18.04.4 LTS  
SDK：v2.0.0  
IDE：v1.2.0

**■やりたいこと**  
Adafruitの出しているハプティックドライバを用いてモーターの制御をしようとしております。  
<https://www.marutsu.co.jp/pc/i/574336/>

ハプティックドライバの初期化のために、ハプティックドライバのレジスタをI2C経由で弄る必要があるのですが、上手く行きません。

**■やったこと**  
Spresense SDKでの開発→5.8.7ドライバ開発者のためのガイドライン  
<https://developer.sony.com/develop/spresense/docs/sdk_developer_guide_ja.html#_sensor_control_unit>  
を見ながら作業しています。

特に、下記の様な記述があることと、SPRESESEメイン・拡張ボード共に、I2C0というSCUに直接繋がっているI2Cしか使用できないことから、SCU
driverを使っています。

> SCU に直接つながっている SPI と I2C バスは、SCU
> とセンサードライバが同時にアクセスが発生すると衝突が発生し、誤作動の原因になります。デバイドライバ開発者は、提供される API
> を通じてのみ、デバイスにアクセスするようにしてください。

気になるのは、seq_open()やscu_i2ctransfer()などの返り値から成功したかどうかの判定ができるようですが、無効値を入力しても成功の返り値が返ってきます。

■質問  
長くなりましたが、質問したいことは2点です。

  1. 今回やりたいことの、モーターを動かすためにSCUを使用するのは、正しいやり方なのでしょうか。i2c_masterの様なnuttxで用意されたライブラリを使用するべきなのでしょうか。
  2. SCUドライバを無効値で使用しても成功判定されるのはなぜでしょうか。

その他、誤り等ございましたらご教授のほどよろしくお願いいたします。

また、非常に汚い状態ですが、ソースを載せておきます。

```

    int ret;
    FAR struct seq_s *ada_seq;
    uint16_t inst[2];
    
    void init_vibration()
    {
        printf("AutoCalib start\n");
    
        ada_seq = seq_open(SEQ_TYPE_NORMAL, SCU_BUS_I2C0);
        if (!ada_seq)
        {
            printf("ada_seq : NULL error\n");
            return -ENOENT;
        }
        else
        {
            printf("openSequence\n");
            //printf("ada_seq:%d\n", ada_seq);
        }
    
        seq_setaddress(ada_seq, ADAFRUT_ADDRESS);
        ret = write_adafruit(0, ADAFRUT_ADDRESS, DRV2605_REG_STATUS, 0x00);
        ret = write_adafruit(0, ADAFRUT_ADDRESS, DRV2605_REG_RTPIN, 0x00);
        ret = write_adafruit(0, ADAFRUT_ADDRESS, DRV2605_REG_WAVESEQ1, 1);
        ret = write_adafruit(0, ADAFRUT_ADDRESS, DRV2605_REG_WAVESEQ2, 0x00);
        ret = write_adafruit(0, ADAFRUT_ADDRESS, DRV2605_REG_OVERDRIVE, 0x00);
        ret = write_adafruit(0, ADAFRUT_ADDRESS, DRV2605_REG_SUSTAINPOS, 0x00);
        ret = write_adafruit(0, ADAFRUT_ADDRESS, DRV2605_REG_SUSTAINNEG, 0x00);
        ret = write_adafruit(0, ADAFRUT_ADDRESS, DRV2605_REG_BREAK, 0x00);
        ret = write_adafruit(0, ADAFRUT_ADDRESS, DRV2605_REG_AUDIOMAX, 0x64);
    
        printf("setup completed\n");
    }
    }
    
    int write_adafruit(int port, int addr, int reg, int instruc)
    {
        inst[0] = SCU_INST_SEND(reg);
        inst[1] = SCU_INST_SEND(instruc) | SCU_INST_LAST;
    
        ret = scu_i2ctransfer(port, addr, inst, 2, NULL, 0);
        if (ret == 0)
        {
            printf("tarnsferok\n");
        }
        else
        {
            printf("failed. %d\n", ret);
            printf("%d\n", errno);
            return ret;
        }
    }
    
```
CC BY-SA 4.0
2020-06-14T06:54:20.390
67644
2020-07-13T01:26:59.740
2020-06-14T10:26:08.580
3060
40647
question
spresense i2c
SPRESENSE SDK によるI2C通信がうまくいかない
こんにちは。

SCUドライバはややこしそうなので、I2Cを使ってデバイスを制御する、ということであれば、  
SCUを使わずにI2Cを利用するのはいかがでしょうか。

SDK v2.0.1のコンフィグに、feature/i2ctoolというものがあります。  
これはnshのコマンドでI2Cを操作するサンプル（？）のようです。

コードは、spresense/sdk/apps/system/i2c  
にあるようなので、これを参考に、I2Cのバスの利用方法を確認して、  
所望のデバイスを制御されるのがよいかと思いました。
CC BY-SA 4.0
2020-07-13T01:26:59.740
68534
2020-07-13T01:26:59.740
34651
67644
answer