RX231のコード生成を用いた簡易IIC通信について

電流・電圧測定デバイスであるINA233を用いて電圧値を測定し,測定値を簡易IIC通信でRX231に送るプログラムを作成しておりますが上手くいきません.

RX231シリーズ R5F52316ADFM 

ROM:256Kbyte RAM 32Kbyte  外部発振20MHzを使用しています.

コード生成はSCI12を簡易IICバスに設定し,生成しました.

void main(void)
{
    R_MAIN_UserInit();
    /* Start user code. Do not edit comment generated here */
   {
    uint8_t     adr         =0      ;//7bit address
 uint8_t     dir         =0      ;//0:Write 1:Read
 
 uint8_t  tx_buf[255] = {0};//send data
     uint8_t  rx_buf[255] = {0};//receive data
 
 while(1){
  adr = 0x41;
  dir = 0x00;
  adr = (adr<<1) | (dir & 0x00);
  tx_buf[0] = 0x88; //READ_VIN PMBusコード ina233
  tx_buf[1] = 0x89; //READ_IN PMBusコード ina233
    
  //PMBusコマンド ina233に送信
  R_SCI12_Create();
  R_SCI12_Start();
  R_SCI12_IIC_Master_Send(adr,&tx_buf[0],3);
  R_SCI12_Stop();
 
  adr = 0x41;
  dir = 0x01;
  adr = (adr<<1) | (dir & 0x00);
 
  //ina233からデータ取得
  R_SCI12_Start();
  R_SCI12_IIC_Master_Receive(adr,rx_buf,3);
  R_SCI12_Stop();
 }
   }
  
    /* End user code. Do not edit comment generated here */
}

CS+の設定等もよく分からないのでその辺りも教えていただけるとありがたいです.

初歩的な質問ですいませんが,よろしくお願いいたします.

//INA233のデータシート

www.ti.com/.../ina233.pdf

  • fiReさん、こんにちは。NoMaYと申します。

    ソースコードはこれから見るところですが、どのようにうまくいかないのか、もう少し具体的に教えて頂けますか?ズバリ、rx_bufに期待したデータが入っていない、あたりでしょうか?

  • 返信ありがとうございます.

    //ina233からデータ取得
    R_SCI12_Start();
    R_SCI12_IIC_Master_Receive(adr,rx_buf,3);
    *R_SCI12_Stop();

    *のところにアクションイベントで変数にrx_buf[0],rx_buf[1],rx_buf[2]を登録しています.
    その値が0となっていてデータが入ってない状態となっています.
  • チョコです。
    RX231は使ったことはありませんが,RL78のコード生成の例から推測すると,「R_SCI12_IIC_Master_Receive」は単に受信を起動している(マスタ受信でスレーブ・アドレスを送信している)だけで,実際の受信処理は行われていないのではないかと思われます。
    SCI12の割り込み処理のコードを参照して,指定したデータ数の転送が完了したところで,何かコールバック処理をやっていると思うので,そこで通信完了フラグをセットして,そのフラグを確認するような通信待ちを行ってみてください。
  • fiRe様、鈴木と申します。
    チョコ様の指摘にあるように R_SCI12_IIC_Master_Send, R_SCI12_IIC_Master_Receiveは
    割り込みでそれぞれ送信完了、受信完了を受ける必要があります。
    割り込みで送信、受信を行うため、R_SCI12_Stop();を呼んでしまうと送信、受信処理は
    行われないうちに停止します。
    また、R_SCI12_Create();は、スタートアップで呼ばれるので不要です。
    下記のAPIマニュアルに使用例が掲載されていますのでご参照ください。
    www.renesas.com/.../r20ut4324jj0100-cgapirx.pdf
    以上、よろしくお願いします。
  • fiReさん、こんにちは。NoMaYです。

    少し脱線しますが、確認したいことがあります。今現在、RX231のソフトウェア開発で使われるツールはRXスマートコンフィグレータというものになるのですが、fiReさんが提示されているソースコードはコード生成機能とよばれる機能で生成されたソースになっています。頂いている文面から察するに、CS+を使うのは初めて?(RX231というより)RXマイコンを使うのも初めて?のように思われるのですが、どういう経緯で、RXスマートコンフィグレータを使わずにコード生成機能を使われているのですか?私がとっさに思い浮かべたのは、以下の理由かな?と思ったのですが、、、

    (1) スタータキット(Renesas Starter Kit for RX231)に同梱されていた(?)かなり古い(?)CS+を使用していてコード生成機能しか無かったので?

    製品ページURL
    www.renesas.com/jp/ja/products/software-tools/boards-and-kits/starter-kits/renesas-starter-kit-for-rx231.html

    ちなみにRenesas Starter Kit for RX231(B版: Trusted Secure IP搭載)もDVD内のCS+はかなり古いのだろうか、、、(独り言です、、、)
    www.renesas.com/jp/ja/products/software-tools/boards-and-kits/starter-kits/renesas-starter-kit-for-rx231b.html

    [訂正] すみません、そういえば、Renesas公式サンプルコードはe2 studio版しかありませんでした。
    (2) ターゲットボード(Target Board for RX231)向けRenesas公式サンプルコード(この機種だけコード生成機能を使用)をベースにしたので?

    サンプルコードダウンロードURL
    www.renesas.com/jp/ja/software/D6002186.html

    ちなみに、コード生成機能で生成されたものかRXスマートコンフィグレータで生成されたものかは、以下のようにAPI関数が若干異なりますので、区別が出来ます。

    コード生成機能で生成
    例) R_SCI12_IIC_Master_Send()

    RXスマートコンフィグレータで生成
    例) R_Config_SCI12_IIC_Master_Send()

  • 皆さん、返信ありがとうございます。
    送信完了、受信完了を受ける必要があるとのことでしたので
    以下のようにプログラムを書き換えました。
    しかしrx_buf[0] = 255,rx_buf[1] = 255という結果となり期待した数値は得られませんでした
    割り込みの書き方が違うのでしょうか?

    //PMBusコマンド ina233に送信
    R_SCI12_Start();
       //TDRレジスタがデータなしになるまで
    while(SCI12.SSR.BIT.TDRE == 0){
    R_SCI12_IIC_Master_Send(adr,&tx_buf[0],3);
    }
    R_SCI12_Stop();

    adr = 0x41;
    dir = 0x01;
    adr = (adr<<1) | (dir & 0x00);

    //ina233からデータ取得
    R_SCI12_Start();
       //RDRレジスタに有効なデータが書き込まれるまで
    while(SCI12.SSR.BIT.RDRF == 0){
    R_SCI12_IIC_Master_Receive(adr,rx_buf,3);
    }
    R_SCI12_Stop();

    NoMaY様、今回用いているrx231は大学の研究で使用しているものでスイッチやLED、電流電圧センサーが組み込まれた評価ボードとなっています。RENESASのHPから統合環境をインストールしてCS+を使っている状態です。RXスマートコンフィグレータの存在は知りませんでした、、
    あとお察しの通りrxマイコンもCS+も今回初めて使っています。
    こんな感じでよろしいでしょうか、、
  • チョコです。

    >while(SCI12.SSR.BIT.TDRE == 0){

    >R_SCI12_IIC_Master_Send(adr,&tx_buf[0],3);

    >}

    この処理は間違いです。最初に送信を一度起動して,送信完了を待ちます。

    R_SCI12_IIC_Master_Send(adr,&tx_buf[0],3);

    while(...){

    }

    同様に受信についても,最初にR_SCI12_IIC_Master_Receive(adr,rx_buf,3);

    で受信を起動してから,受信完了を待ちます。おそらくSSR.RDRFでは,1バイトでも受信したら抜けてしまうので,鈴木さんが提示した資料を参照してください。(送信についても同様。)

    細かなことですが,adr = (adr<<1) | (dir & 0x00);の右側の項は常に0なので,無意味です。というか,これ自体が不要では。

     

    以上

     

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

    以下のリプライを有難う御座いました。そうでしたか、ルネサスさんのウェブサイトからCS+をダウンロード/インストールしても、RXスマートコンフィグレータがインストールされなかったのですね。そうなると、ここ暫くは(こうやればインストール出来ますよとアドバイスが出来る状態に私がなるまでは(週末調べてみます))、コード生成機能で作業を進めるしかないですね。[追記] あっ、そういば、もう金曜日の夕方ですね、、、

    > RENESASのHPから統合環境をインストールしてCS+を使っている状態です。
    > RXスマートコンフィグレータの存在は知りませんでした、、
    > あとお察しの通りrxマイコンもCS+も今回初めて使っています。

    多数の別スレッド(RL78ですが)でチョコさんがコード例を提示されているのですが、ルネサスさんのコード生成機能やRXスマートコンフィグレータの通信系のAPI関数仕様は、初心者さんがちょっと使い始めようとする時点ではコツが分からず皆苦労されるようです。(コツといっても実に些細なことで、コードを提示してしまえば直ぐに分かることですが、文章で書くと分かり難い気もします、、、これから私の手元でコード生成機能でソースを生成させてみますので、暫くお待ちください、、、)

    それとは別に、相手側デバイスのデータシートを見ていて気になったのですが、チョコさんも指摘されているように、以下の処理は不要だと思われます。(これからソースを生成させて確認しますが。) つい最近の別スレッドでの話なのですが、RX版のコード生成機能のAPI関数に渡すスレーブのアドレスは7bitアドレスのようですので、以下でadr=0x41としたら、その下の2行は不要だと思われます。ちなみに、スレーブのアドレスが0x41ということは、相手側デバイスのA1端子=GND&A0端子=VSなのですよね?

    adr = 0x41;
    dir = 0x01;
    adr = (adr<<1) | (dir & 0x00);

    また、同じく、相手側デバイスのデータシートを見ていて気になったのですが、以下のようにPMBus Command Codeを複数指定することは出来ないのではないでしょうか?(データシートを斜め読みしている段階ですので、私が読み漏らしているかもしれませんが、、、)

    tx_buf[0] = 0x88; //READ_VIN PMBusコード ina233
    tx_buf[1] = 0x89; //READ_IN PMBusコード ina233

    [関連リンク]

    RX版のコード生成機能のAPI関数に渡すスレーブのアドレスは7bitアドレスである、という話があった、つい最近の別スレッドのURLです。

    アドレス部の先頭1bitが送信されない(I2C)
    japan.renesasrulz.com/cafe_rene/f/forum5/6157/1bit-i2c/34102#34102
     

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

    ごめんなさい。ソースを生成させて確認したところ、(RX版の)コード生成機能の簡易I2CのAPI関数に渡すスレーブのアドレスは8ビットのようでした。ですので、(少なくとも)簡易I2Cでは以下の処理が必要そうですね。(ただ、アンドする値は0x00ではなくて0x01の間違いですね。)

    Send時

    adr = 0x41;
    dir = 0x00;
    adr = (adr<<1) | (dir & 0x01);

    Receive時

    adr = 0x41;
    dir = 0x01;
    adr = (adr<<1) | (dir & 0x01);

    以下、確認した時のSendに関する資料です。(自分自身への備忘録としてでもあります。)

    RX230グループ、RX231グループ  ユーザーズマニュアル ハードウェア編の画面コピー
    www.renesas.com/jp/ja/search/keyword-search.html#genre=document&q=r01uh0496
    r01uh0496jj0120-rx231.pdf



    r_cg_sci.c

    void R_SCI12_IIC_Master_Send(uint8_t adr, uint8_t * const tx_buf, uint16_t tx_num)
    {
        if (1U > tx_num)
        {
            return;
        }

        gp_sci12_tx_address = tx_buf;
        g_sci12_tx_count = tx_num;
        g_sci12_slave_address = adr;
        g_sci12_iic_transmit_receive_flag = _80_SCI_IIC_TRANSMISSION;
        g_sci12_iic_cycle_flag = _80_SCI_IIC_START_CYCLE;

        /* Disable RXI and ERI interrupt requests */
        SCI12.SCR.BIT.RIE = 0U;

        /* Generate start condition */
        R_SCI12_IIC_StartCondition();
    }

    r_cg_sci_user.c

    static void r_sci12_transmitend_interrupt(void)
    {
        if (_80_SCI_IIC_START_CYCLE == g_sci12_iic_cycle_flag)
        {
            SCI12.SIMR3.BIT.IICSTIF = 0U;
            SCI12.SIMR3.BIT.IICSCLS = 0U;
            SCI12.SIMR3.BIT.IICSDAS = 0U;
            SCI12.TDR = g_sci12_slave_address;
        }
        else if (_00_SCI_IIC_STOP_CYCLE == g_sci12_iic_cycle_flag)
        {
            SCI12.SIMR3.BIT.IICSTIF = 0U;
            SCI12.SIMR3.BYTE |= _30_SCI_SSDA_HIGH_IMPEDANCE | _C0_SCI_SSCL_HIGH_IMPEDANCE;
            if (_80_SCI_IIC_TRANSMISSION == g_sci12_iic_transmit_receive_flag)
            {
                r_sci12_callback_transmitend();
            }
            if (_00_SCI_IIC_RECEPTION == g_sci12_iic_transmit_receive_flag)
            {
                r_sci12_callback_receiveend();
            }
        }
    }

     

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

    チョコさんが仰っていたこと(以下)をコードにしてr_cg_sci_user.cのユーザ記述部に書くと以下のようになります。これを使ってr_cg_main.cを以下のように書き換えたらどうなりますでしょうか?(参考用に当方で試しに書き換えたプロジェクトのファイル一式を添付します。ただ、過去のプロジェクトのファイルを流用したのでresetprg.cが最新版では無かったりするので、参考にするぐらいにして下さい。また、相手側デバイスを持ち合わせていません(実はI2C全般で持ち合わせていません)ので、動作は未確認です。すみません。)


    SCI12の割り込み処理のコードを参照して,指定したデータ数の転送が完了したところで,何かコールバック処理をやっていると思うので,そこで通信完了フラグをセットして,そのフラグを確認するような通信待ちを行ってみてください。


    プロジェクトのファイル一式
    issue_20200214.zip    293KB

    今回、送信完了/受信完了を待つ送信関数名/受信関数名の末尾に _UWT を付けてみました。(unlimited wait timeの意。また、先頭を R_ ではなくて U_ にしてあります。ちなみに、STM32CubeMXでは送信完了/受信完了を待たない関数の名前の末尾に _IT を付けるようでしたので、逆向きに(?)真似てみました。) なお、スレーブアドレスは7ビットアドレスを受け取るようにしました。

    cg_src/r_cg_sci_user.c

    /******************************************************************************
    Global variables and functions
    ******************************************************************************/
    extern uint8_t   g_sci12_iic_transmit_receive_flag;  /* SCI12 transmit receive flag for I2C */
    extern uint8_t   g_sci12_iic_cycle_flag;             /* SCI12 start stop flag for I2C */
    extern uint8_t   g_sci12_slave_address;              /* SCI12 target slave address */
    extern uint8_t * gp_sci12_tx_address;                /* SCI12 send buffer address */
    extern uint16_t  g_sci12_tx_count;                   /* SCI12 send data number */
    extern uint8_t * gp_sci12_rx_address;                /* SCI12 receive buffer address */
    extern uint16_t  g_sci12_rx_count;                   /* SCI12 receive data number */
    extern uint16_t  g_sci12_rx_length;                  /* SCI12 receive data length */
    /* Start user code for global. Do not edit comment generated here */
    volatile uint8_t g_sci12_tx_ready_flag;              /* SCI12 send end flag */
    volatile uint8_t g_sci12_rx_ready_flag;              /* SCI12 receive end flag */
    /* End user code. Do not edit comment generated here */
    static void r_sci12_callback_transmitend(void)
    {
        /* Start user code. Do not edit comment generated here */

        g_sci12_tx_ready_flag = 1;

        /* End user code. Do not edit comment generated here */
    }
    static void r_sci12_callback_receiveend(void)
    {
        /* Start user code. Do not edit comment generated here */

        g_sci12_rx_ready_flag = 1;

        /* End user code. Do not edit comment generated here */
    }
    /* Start user code for adding. Do not edit comment generated here */

    /******************************************************************************
    * Function Name: U_SCI12_IIC_Master_Send
    * Description  : This function sends IIC12 data to slave device. (unlimited wait time)
    * Arguments    : same as R_SCI12_IIC_Master_Send except for adr
    *                adr -
    *                    slave device '7-bit' address (Not '8-bit' address)
    * Return Value : same as R_SCI12_IIC_Master_Send
    ******************************************************************************/
    void U_SCI12_IIC_Master_Send_UWT(uint8_t adr, uint8_t * const tx_buf, uint16_t tx_num)
    {
        R_SCI12_IIC_Master_Send( (uint8_t)(adr << 1), tx_buf, tx_num );
        do{}while (g_sci12_tx_ready_flag != 1);
        g_sci12_tx_ready_flag = 0;
    }

    /******************************************************************************
    * Function Name: R_SCI12_IIC_Master_Receive
    * Description  : This function receives IIC12 data from slave device. (unlimited wait time)
    * Arguments    : same as R_SCI12_IIC_Master_Receive except for adr
    *                adr -
    *                    slave device '7-bit' address (Not '8-bit' address)
    * Return Value : same as R_SCI12_IIC_Master_Receive
    ******************************************************************************/
    void U_SCI12_IIC_Master_Receive_UWT(uint8_t adr, uint8_t * const rx_buf, uint16_t rx_num)
    {
        R_SCI12_IIC_Master_Send( (uint8_t)((adr << 1) | 1), rx_buf, rx_num );
        do{}while (g_sci12_rx_ready_flag != 1);
        g_sci12_rx_ready_flag = 0;

    }

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

    cg_src/r_cg_sci.h

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

    void U_SCI12_IIC_Master_Send_UWT(uint8_t adr, uint8_t * const tx_buf, uint16_t tx_num);
    void U_SCI12_IIC_Master_Receive_UWT(uint8_t adr, uint8_t * const rx_buf, uint16_t rx_num);

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

    cg_src/r_cg_main.c

    void main(void)
    {
        R_MAIN_UserInit();
        /* Start user code. Do not edit comment generated here */
        {
            uint8_t adr = 0;//7bit address

            uint8_t  tx_buf[255] = {0};//send data
            uint8_t  rx_buf[255] = {0};//receive data

            R_SCI12_Start();

            while(1)
            {
                adr = 0x41;
                tx_buf[0] = 0xE0; //TI_MFR_ID PMBusコード ina233

                //PMBusコマンド ina233に送信
                U_SCI12_IIC_Master_Send_UWT( adr, tx_buf, 1 );

                //ina233からデータ取得
                U_SCI12_IIC_Master_Receive_UWT( adr, rx_buf, 2 );

                //デバッグ時にブレークポイントやアクションイベントを設定する箇所
                //ここまで来たら rx_buf[0] = 'T', rx_buf[1] = 'I' となっている筈
                nop();
            }
        }
        /* End user code. Do not edit comment generated here */
    }

    以下、作成した時の資料です。(自分自身への備忘録としてでもあります。)

    INA233データシートの画面コピー
    www.ti.com/jp/lit/ds/symlink/ina233.pdf



    CS+のコード生成機能の設定画面




    CS+のコード生成機能のヘルプのSCIのAPIの使用例の画面コピー