起動直後にr_Config_RIIC0_error_interrupt()が永遠に呼ばれる (RX231/CS+ )

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

コード生成で生成したConfig_RIIC0を使用し開発を進めているのですが以下の現象が発生しておりご教授いただけますと幸いです。

 

【発生現象】

R_Config_RIIC0_Start()コール後に、r_Config_RIIC0_error_interrupt()が永遠に呼ばれる

 

r_Config_RIIC0_error_interrupt()を確認した所、どのif/else ifにも入らず、下記のelseに入っております。

                :

else
{
 /* Do nothing */
}

 

【備考】

コード生成のバグがあるようで下記のコードは削除しましたが、そもそもその条件成立しておりません。

https://www.renesas.com/jp/ja/doc/toolnews/jpn/2019/r20ts0462jj0100-cstnno.pdf

 

  • bunbun様、鈴木と申します。
    お使いのツールはスマートコンフィグレータと思われます。そのためコード生成の不具合は該当いたしません。ツール名とツールのバージョンを教えてください。
    またAPIマニュアルに記載のI2Cサンプルは動作するでしょうか(下記219ページ)
    www.renesas.com/.../r20ut4360jj0103-scapirx.pdf
    以上、よろしくお願いします。
  • 鈴木様
    御世話になっております。
    ご教授有難うございます。

    ●環境は以下です。
    CS+ for CC: V8.03.00
    スマートコンフィグレータ: V1.02.07.01
    Config_RIIC0: 1.8.0


    >またAPIマニュアルに記載のI2Cサンプルは動作するでしょうか(下記219ページ)

    正常動作せず、以下に入ります。
    SCL/SDA波形をみる限りスタートコンディション発行後、SDAがすぐに立ち上がり、クロックすらでておりません。

    r_Config_RIIC0_error_interrupt()
    {
    :
    else if ((1U == RIIC0.ICIER.BIT.NAKIE) && (1U == RIIC0.ICSR2.BIT.NACKF))
    {
    if (_0D_IIC_MASTER_TRANSMIT == g_riic0_mode_flag)          ★★この条件が成立
    {
    RIIC0.ICSR2.BIT.STOP = 0U;                    
    RIIC0.ICCR2.BIT.SP = 1U;
    while (1U != RIIC0.ICSR2.BIT.STOP)
    {
    nop();
    }
    RIIC0.ICSR2.BIT.NACKF = 0U;
    RIIC0.ICSR2.BIT.STOP = 0U;
    }


    取り急ぎ、失礼いたします。
  • その後の状況ですが
    そもそも「Config_RIIC0」「接続しているSlaveDevice」「移植したSlaveDeviceのデバイスドライバー」と3つの新規要素が絡んでおり、何が悪いか切り分けができていなかった為、下記を実施しました。

    SlaveDeviceとしてArduinoを接続(SlaveDevice側のF/Wは自由にカスタマイズが可能)し
    RX231(マスター)とArduino(スレーブ)を接続し、CS+でデバッグした所、SCL/SDA波形も確認できましたが
    新たな現象がみられました。

    下記のコードを実施した際に、0x03を送信された際のSDA波形が0001 1101(0x1D)になります。
    但しr_Config_RIIC0_transmit_interrupt()内にBreakを貼り、1Byteずつ止めるとSDA波形は0x08, 0x02, 0x03と順次送信されました。


    ●実施したコード
    /*----- I2C -----*/
    R_Config_RIIC0_Start();

    MD_STATUS status;
    uint8_t snd_dt[2] = {0x02, 0x03};

    if((status = R_Config_RIIC0_Master_Send(0x08, snd_dt, 2)) != MD_OK)
    {
    printf("[ERROR ] VL53L0X::writeReg() 0x%x\n", status);
    }


    Q1:
    R_Config_RIIC0_Master_Send()の仕様は、第一引数=スレーブアドレス、第二引数=送信データバッファポインタ(0x02=レジスタアドレス、0x03=データ)、第三引数=第二引数のレングス?の認識であっていますでしょうか?また使用方法に問題はないでしょうか?

    Q2:
    RL78でI2Cを使えるようにした時ですが、R_IICA0_Master_Send()を直接ではなくr_IIC_put_data()が存在したのですが
    RX231ではR_Config_RIIC0_Master_Send()直接で問題ないでしょうか?
  • bunbunさん、こんにちは。NoMaYです。

    > 下記のコードを実施した際に、0x03を送信された際のSDA波形が0001 1101(0x1D)になります。
    > 但しr_Config_RIIC0_transmit_interrupt()内にBreakを貼り、1Byteずつ止めるとSDA波形は0x08, 0x02, 0x03と順次送信されました。

    提示されていたコードはスタック上に送信データの配列を確保していますが、送信完了待ちを、R_Config_RIIC0_Master_Send()を実行した関数から抜けた後で、やっていたりしないですか?

  • NoMaYさん
    いつも大変お世話になっております。


    >信完了待ちを、R_Config_RIIC0_Master_Send()を実行した関数から抜けた後で、やっていたりしないですか?

    (R_Config_RIIC0_Master_Send()は1回コール(上記データは1回だけ送信)するだけのテストコードで実施しており)
    送信完了待ちは特にしておりませんが、コード生成で生成された下記、送信完了割り込みが実施されていることは確認しております。
    尚、送信データを他のデータに変えてみても、送信バッファの2Byte目のデータのBit4,Bit3は常に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();
    }
    }
    }
  • bunbunさん、こんにちは。NoMaYです。

    うまく意図が伝わらなかったと思われますので、言い方を変えてみます。

    R_Config_RIIC0_Start();

    MD_STATUS status;
    uint8_t snd_dt[2] = {0x02, 0x03};

    if((status = R_Config_RIIC0_Master_Send(0x08, snd_dt, 2)) != MD_OK)
    {
        printf("[ERROR ] VL53L0X::writeReg() 0x%x\n", status);
    }

    の後は、すぐ

    while(1) ;

    とか

    for(;;) ;

    のような無限ループでしょうか?

  • NoMaYさん、こんにちは。

    R_Config_RIIC0_Master_Send()実施後は、無限ループなどはしておらず、I2C以外の他の処理に入ってしまいます。

    後程、試してみます。
    ご教授有難うございます。

    以上、取り急ぎ失礼致します。
  • bunbun様、鈴木と申します。情報ありがとうございます。

    Q1 -> 引数の認識は問題ありません。アドレスはスマートコンフィグレータで後からR/Wフラグを付加するので、そのままのアドレスを指定します。

    Q2 -> はい、R_Config_RIIC0_Master_Send()をお使いください。

    R_Config_RIIC0_Master_Sendは割り込みで処理されますので、関数を呼んだ後に時間待ちが必要です。(あるいは割り込みハンドラで送信完了を待つ)

    アドレスがあっていれば送信されますので、波形を見てご確認ください。

    SWが押下されたら送信するプログラムで試してみましたが、送信できました。

    volatile uint8_t gSw1;

    volatile uint8_t gData[2] = { 0x2, 0x3 };

    void main(void)

    {

       gSw1 = 0;

       R_Config_ICU_IRQ1_Start();

     R_Config_RIIC0_Start();

     while (1)

     {

        if ( gSw1 == 1 )

      {

                  R_Config_RIIC0_Master_Send( 0x40, gData, 2);

         gSw1 = 0;

      }

     }

    }

  • 鈴木様
    ご教授有難うございます。

    上記の通り「0x03」を送信した際にゴミがのるようなのですが
    volatileは試しておりません(非同期で変化するような変数ではないので不要の認識でした)が
    逆にconstを付与して試しましたがやはりゴミがのります。

    またr_Config_RIIC0_transmit_interrupt()の★gp_riic0_tx_addressが指すアドレスおよびデータをみましたが
    そこは問題ありませんでした。

    2Byte目にゴミがのるような要因は他に考えられるのでしょうか?


    static void r_Config_RIIC0_transmit_interrupt(void)
    {
          :
    else if (_05_IIC_MASTER_SENDS_DATA == g_riic0_state)
    {
    if (0U < g_riic0_tx_count)
    {
    RIIC0.ICDRT = *gp_riic0_tx_address;             ★
    gp_riic0_tx_address++;

          :
  • bunbun様、それはACKではないでしょうか?(スレーブから受け取ったという信号)
    ACKがないと、マスター側は2byte目を送信しないと思います。