アドレス部の先頭1bitが送信されない(I2C)

CPU : R5F52315AxFP
ツール : CS+forCC Ver8.02

現象 : アドレス部の先頭1bitが送信されない

内容 :
・コード生成を使用してI2Cバスインタフェースを、マスタで生成

・R_RIIC0_Master_Send()を使用して、「0x58(アドレス)」「0x00(データ)」を送信
    
    #define    I2C_E2P_ADDRESS                0x58
    ge2p_Write_Buffer[0] = 0x00;
    R_RIIC0_Master_Send(I2C_E2P_ADDRESS, ge2p_Write_Buffer, 1u);
    
・オシロスコープで波形(scope_0.png)を見る。(上側がSCL、下側がSDA)
・本来は9bit(8bit+ack)のハズが、8bitしかSCLが出ていない。
・SDAを見ると、アドレス部の先頭1bitが送信されず、1bitシフトされた形になっている

質問内容:
先頭の1bitが出力されないまま処理が進んでいる、もしくは、出力が出来なかったと思われるので、
コード生成で作成された「r_cg_riic_user.c」の修正が必要なのでしょうか?
その場合は、どの部分の修正が必要なのかを教えて頂けませんでしょうか?

  • その時の波形画像です。

  • コード生成で作成された、「r_cg_riic_user.c」の「r_riic0_transmit_interrupt()」を見てみると、
    RIIC0.ICDRT = (uint8_t)(g_riic0_slave_address << 1U);
    と書かれており、意図的に1bitシフトされてました。

    これを、
    RIIC0.ICDRT = (uint8_t)(g_riic0_slave_address);
    に修正したら解決しましたが、何故1bitシフトするように書かれていたのか不明です。

    この修正でよろしかったのでしょうか?
    何か他に影響がないか不安です。
  • miesuqe2さん
    ビット0はマスタ送信の場合は0で、残りの上位7ビットがアドレスになるためではないですか。

  • チョコです。
    世の中では,スレーブアドレスは7bitであらわすことが多いようです。
    ここも,g_riic0_slave_addressのデータが7bitで,その後ろにR/Wビットを付加して
    8bitにしてから送信するようにしているものと考えられます。
    ここらは,日ごろRL78を使っているので,少し混乱するところではありますが。

    >この修正でよろしかったのでしょうか?
    おそらく問題があると思います。
    基本的に,I2C_E2P_ADDRESSを0x58ではなく,0x2CにしておくのがRXでの正しい
    修正です。
  • 返信ありがとうございます。
    E2Pのアドレスは波形を見るために仮で、実際は「0xA0」を使ってます。
    (BR24G04-3を使用で、マニュアルもアドレスは0xA0です。)

    リード時の送信をそのまま実行すると先頭bitが送信されずにACKが送られない現状がありましたが、
    変更後は、正常に「0xA0」が送信されACKも正常となりました。

    この変更後、E2PROMや温湿度センサなど全I2C機器の通信がすべて正常となったので、結果的には正しかったようです。

    コード生成ではMSBとLSBの設定がなく、MSB固定だったのでその影響かもしれません。
  • miesuge2さん、こんにちは。NoMaYです。

    チョコさんも書かれていますが、アドレスの定義としては、7bitで表す流儀と8bitで表す流儀が混在してしまっています。電子工作で有名なのは、Arduinoは7bit流儀、Mbedは8bit流儀、です。ですので、今回の場合、アドレスが0xA0ということであれば(0xA0>>1)を指定することになると思います。今回の状況から察するに、BR24G04-3のマニュアルでアドレスが0xA0となっていたということであれば、BR24G04-3のマニュアルは8bit流儀だった、ということだろうと思うのです。

    I2Cのスレーブアドレス - 滴了庵日録
    lipoyang.hatenablog.com/entry/20150713/p2

    I2Cのスレーブアドレスは7bit表記の場合と8bit表記の場合があって紛らわしい。
    7bit派: Arduino, PSoC, Linux, .NET MF
    8bit派: mbed, CS+

    (なお、上の8bit派のCS+はRL78コード生成のことだと思います。CS+でもRXコード生成は7bit派ということになりますね。)

    Arduino 日本語リファレンス - musashinodenpa
    www.musashinodenpa.com/arduino/ref/index.php?f=1&pos=341

    I2Cアドレスには7ビットと8ビットのバージョンがあります。7ビットでデバイスを特定し、8番目のビットで書き込みか読み出しかを指定します。Wireライブラリは常に7ビットのアドレスを使用します。8ビットのアドレスを使うサンプルコードやデータシートがあったら、最下位のビットを(1ビットの右シフトで)落とし、0から127の範囲へ変更することになるでしょう。

  • miesuqe2さんチョコさんがご指摘のように
    RIIC0.ICDRT = (uint8_t)(g_riic0_slave_address << 1U);
    のソースコードは変更せずにアドレスを
    0xA0(1010 0000 )ではなく0x50(0101 0000)で指定されては。
  • I2Cの仕様書によるとアドレスは7ビット(Fast,Fast+ではオプションで10ビット)とされています。また、送信単位は8ビットとされています。

    なので、アドレスは7ビットで表し、MSB詰めで残りの1ビットはR/Wに割り当てられています。
    A6 A5 A4 A3 A2 A1 A0 R/W で8ビットです。

    関数 R_RIIC0_Master_Send はデータを送信するルーチンなので R/Wは常にWを表す’0’になるためにアドレスをビットシフトしているのでしょう。