I2Cバスビジー状態になる時がある(RX231/CS+/Config_RIIC0)

いつもお世話になっております。

下記の現象についてご教授ください。

 

【発生現象】

スマートコンフィグレータで生成したConfig_RIIC0でマスターからの送受信をした際にかなり頻度で

送信時に★バスビジー状態となる現象が発生します。

尚、★時にICSR2のSTARTビットをみても0で、Step実行で実行する限りは発生しません。

 

MD_STATUS R_Config_RIIC0_Master_Send(uint16_t adr, uint8_t * const tx_buf, uint16_t tx_num)
{
        :

if (1U == RIIC0.ICCR2.BIT.BBSY)
{
   status = MD_ERROR1;                     ★

 

 

【発生環境】

・CS+

・スマートコンフィグレータ生成のConfig_RIIC0

・SCLは200kHz

・SDA/SCL波形をみる限りBBSYフラグ=1条件であるスタートコンディションおよびIICRST発生はみられません。

・割込要因はALI/STI/SPI/NAKI

※生成された割込ハンドラはr_Config_RIIC0_error_interrupt()/r_Config_RIIC0_transmit_interrupt()/r_Config_RIIC0_transmitend_interrupt()/r_Config_RIIC0_receive_interrupt()

 

【ご質問】

Q1:

waitで回避する事は可能ですが、どの関数にいれるべきか?(割込ハンドラにwaitなどいれたくないのが本音です)

頭を悩ませております。

 

Q2:

他に何をどうやって確認すればよいのか、お恥ずかしながらわかりません。

(http://japan.renesasrulz.com/cafe_rene/f/forum11/1425/r5f61644a-h8sx-iic-busy#pi4368=3

 は拝見しましたがノイズがのってる訳ではないので、同じ現象ではないように思えます)

  • 画像は現象発生時の『SCL/SDAの波形』『エラー該当コード』『RIIC0.ICSR2.STARTビット(が0であるエビデンスです)』

  • bunbunさん、こんにちは。NoMaYです。

    この場合、(私なら、) どれか空いているポートを使って、オシロの波形のどこで以下のif文の条件が成立してしまうのか、それを確認したいかな、と思います。

    if (1U == RIIC0.ICCR2.BIT.BBSY)
    {
       この位置で、どれかのポートを0出力→1出力に変化させ、オシロのSCL/SDAの波形と一緒に観測してみる
       status = MD_ERROR1;                     ★

     

  • NoMaYさん、こんにちは。
    いつもお世話になっております。

    現在、2CHオシロしかない為、3CHオシロが借用でき次第試してみます!!
    いつもいつもご教授ありがとうございます。
  • bunbunさん、こんにちは。NoMaYです。

    3CHがなかなか借用出来ないようであれば、2CHで、くだんのポート出力とSCLの2つでも何かしら分かるかもしれないです。あまり、先のことを書いても最初の状況からして既に想定外だったということもあるかとは思われますが、今、私の頭の中に浮かんでいることを書いておきます。

    (1) if文の条件が成立している箇所が、それこそ通信真っ最中の箇所だった場合
    ⇒ bunbunさんのプログラム内に待ち時間の見積もりを間違えた箇所があるのでは?という可能性が気になります

    (2) stop conditionが生成されたあたりで発生していた場合

    ⇒ (2-1) bunbunさんのプログラム内にぎりぎりで待ち時間の見積もりが足りてなかった箇所がある可能性
    ⇒ (2-1-1) 本来は「見積もる」という大まかな方法では無くてコールバック関数内で通信完了フラグを立ててそれを見て判断する

    (3) 上記の(2-1-1)の通信完了フラグを立ててそれを見て判断することをしていた場合

    ⇒  RX231のRIIC0のハードウェア&RXスマートコンフィグレータの生成コードのあるべき状況としては、通信完了のコールバック関数が呼ばれた時点で、既にBBSYは1→0に変化した後であるべきだと思われるが、そうなっているかどうか?

    (3-1) 通信完了のコールバック関数が呼ばれた時点で、まだBBSYは 1 のままである場合
    ⇒ RX231のRIIC0のハードウェアが誤判定している? or RXスマートコンフィグレータの生成コードに何か足りない?

    (3-2) 通信完了のコールバック関数が呼ばれた時点で、既にBBSYは1→0に変化した後である場合
    ⇒ う~ん、、、と考え込みます、、、

  • チョコです。

    RXは使ったことないので,波形についてだけコメントさせてもらいます。

    この波形は,正常な波形に見えます。最初の赤で囲んだところがスタート・コンディションです。

    その後,スレーブアドレス0b0101001(7bit)に0x89を書き込んでいます。2つ目の赤で囲んだ

    ところが通信方向を変更するためのリスタートで,その後スレーブアドレス0b0101001(7bit

    から読出しを行っています。

    読み出したデータは0x00で,それに対してマスタがNAK応答して通信を完了しています。

    最後に3つ目の赤で囲んだところがストップ・コンディションで,I2Cバスが解放されて

    いることが読み取れます。

    どう見ても,異常な波形には見えません。

     

  • NoMaYさん、こんにちは。

    ご教授有難うございます。

    >3CHがなかなか借用出来ないようであれば、2CHで、くだんのポート出力とSCLの2つでも何かしら分かるかもし>れないです。あまり、先のことを書いても最初の状況からして既に想定外だったということもあるかとは思わ>れますが、今、私の頭の中に浮かんでいることを書いておきます。

    借用できない場合も考慮して頂きありがとうございます。

    2CHでやっても意味ないかと思いましたが後程トライしてみます(案の定、当面3CHは使えそうもないので自前で購入しようかとおもってました。。)

    >(1) if文の条件が成立している箇所が、それこそ通信真っ最中の箇所だった場合

    >⇒ bunbunさんのプログラム内に待ち時間の見積もりを間違えた箇所があるのでは?という可能性が気になりま>す

    >(2) stop conditionが生成されたあたりで発生していた場合

    >⇒ (2-1) bunbunさんのプログラム内にぎりぎりで待ち時間の見積もりが足りてなかった箇所がある可能性

    スマートコンフィグレータで生成したI2C APIを使用している為、自分で待ち時間を設定、追加等はしておりません。

    >⇒ (2-1-1) 本来は「見積もる」という大まかな方法では無くてコールバック関数内で通信完了フラグを立ててそれを見て判断する

    自動生成されたコードでその辺が自己完結が一応されているコードとなっております。

    ④でnop()を4回ほどコールしてみましたが挙動はかわりませんでした。(4つでは足りないとは思いますが)

    R_Config_RIIC0_Master_Send()

    {

                                  :

           /* Issue a start condition */

           R_Config_RIIC0_IIC_StartCondition();                                                                                  ①

           /* Set flag for generating stop condition when transmission finishes */

           g_riic0_stop_generation = 1;

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    static void r_Config_RIIC0_transmitend_interrupt(void)

    {

       if (_06_IIC_MASTER_SENDS_END == g_riic0_state)

       {

           if (1U == g_riic0_stop_generation)

           {

               RIIC0.ICSR2.BIT.STOP = 0U;

               RIIC0.ICCR2.BIT.SP = 1U;                                                                                                          ②

               g_riic0_state = _07_IIC_MASTER_SENDS_STOP;

           }

           else

           {

               RIIC0.ICSR2.BIT.TEND = 0U;

               r_Config_RIIC0_callback_transmitend();               ③

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    static void r_Config_RIIC0_callback_transmitend(void)

    {

       /* Start user code for r_Config_RIIC0_callback_transmitend. Do not edit comment generated here */

       /* End user code. Do not edit comment generated here */          ④ 

    }

     

    >(3) 上記の(2-1-1)の通信完了フラグを立ててそれを見て判断することをしていた場合

    >⇒  RX231のRIIC0のハードウェア&RXスマートコンフィグレータの生成コードのあるべき状況としては、通信

    >完了のコールバック関数が呼ばれた時点で、既にBBSYは1→0に変化した後であるべきだと思われるが、そうな

    >っているかどうか?

     

    コールバック関数r_Config_RIIC0_callback_transmitend()内、上記を確認してみます。

     

    >(3-1) 通信完了のコールバック関数が呼ばれた時点で、まだBBSYは 1 のままである場合

    >⇒ RX231のRIIC0のハードウェアが誤判定している? or RXスマートコンフィグレータの生成コードに何か

    >足りない?

     

    RIIC0コンポーネントの設定は以下としております。

     

    >(3-2) 通信完了のコールバック関数が呼ばれた時点で、既にBBSYは1→0に変化した後である場合

    >⇒ う~ん、、、と考え込みます、、、

     

    いずれにしろ、上記を確認後、ご報告させて頂きます。

    色々、ありがとうございます。

  • チョコさん、いつもお世話になっております。

    ご教授有難うございます。
    I2C波形解析機能がないオシロをつかっているので1Bitずつ確認してみましたが正常だと思っており、

    NoMaYさんのご指南である実際にビジーと判定されてるときにI/OポートをHiにした所でトリガーをかけ
    その時のSCL/SDAを捕まえない事にはどうにも先に進めないような気がしておりました。。。。


    ただ8ないし9Bit以降も間髪いれずにクロックをだしているのでどこかにウェイトがあった方がよいのかと思っております。
  • bunbun様、鈴木と申します。
    かなりの頻度で送信した時にバスビジーとなるのでしょうか。
    そうであれば、I2Cに接続した対抗機の処理時間は考慮されているでしょうか
    EEPROM接続であればデバイスによっては、書き込みに最大5msかかることがデータシートに記載されています。書き込み中にデータを送ってもバスビジーが帰ってくることになります。
    対抗機に接続されているデバイスのデータシートを確認してみてください。
    以上、よろしくお願いします。
  • とりあえずの結果、ご報告です

     

    >>2CHでやっても意味ないかと思いましたが後程トライしてみます(案の定、当面3CHは使えそうもないので自前で購入しようかとおもってました。。)

    >>(3) 上記の(2-1-1)の通信完了フラグを立ててそれを見て判断することをしていた場合

    >>⇒  RX231のRIIC0のハードウェア&RXスマートコンフィグレータの生成コードのあるべき状況としては、通信

    >>完了のコールバック関数が呼ばれた時点で、既にBBSYは1→0に変化した後であるべきだと思われるが、そうな

    >>っているかどうか?

    >コールバック関数r_Config_RIIC0_callback_transmitend()内、上記を確認してみます。

     

    異常は特にみられませんがこの波形は次の送信データを送信する際の一発目のクロック(スタートコンディション)発行時なので、1つ前の送信終了があやしそうです。

    またコールバック関数r_Config_RIIC0_callback_transmitend()ではBBSYフラグはたっておりました。(STAR/STOPビットは0)

     

     

  • 鈴木様、いつもお世話になっております。

    >かなりの頻度で送信した時にバスビジーとなるのでしょうか。

    はい。
    またStep実行の際は発生しませんのでウェイトをおけばなおるとは思っております。


    >そうであれば、I2Cに接続した対抗機の処理時間は考慮されているでしょうか
    >対抗機に接続されているデバイスのデータシートを確認してみてください。

    1.3msとなっており、ぎりぎりか切ってる可能性があります。
    割込ハンドラ内でウェイトは極力したくないとおもっておりますが
    上位でウェイトをおけそうな箇所を模索してみます。

    ご教授ありがとうございます。