スマート・コンフィグレータ SCIの割り込み

ルネサス 鈴木様 ならびに回答いただける方々 お願いいたします。

 

初めて投稿いたします。

ルネサススターターキットfor Rx231 を使用して機能を試しています。

CS+でコード生成(設計ツール)を使用して来たのですが、この度 スマート・コンフィグレータをインストールして使用しはじめました。

SCIの割り込みの部分ですが、一例として 受信 割り込みの自動生成コードをコピペすると

/***********************************************************************************************************************
* Function Name: r_Config_SCI0_receive_interrupt
* Description  : This function is RXI0 interrupt service routine
* Arguments    : None
* Return Value : None
***********************************************************************************************************************/

#if FAST_INTERRUPT_VECTOR == VECT_SCI0_RXI0
#pragma interrupt r_Config_SCI0_receive_interrupt(vect=VECT(SCI0,RXI0),fint)
#else
#pragma interrupt r_Config_SCI0_receive_interrupt(vect=VECT(SCI0,RXI0))
#endif
static void r_Config_SCI0_receive_interrupt(void)
{
    if (g_sci0_rx_length > g_sci0_rx_count)
    {
        *gp_sci0_rx_address = SCI0.RDR;
        gp_sci0_rx_address++;
        g_sci0_rx_count++;
    }

    if (g_sci0_rx_length <= g_sci0_rx_count)
    {
        /* All data received */
        SCI0.SCR.BIT.RIE = 0U;
        SCI0.SCR.BIT.RE = 0U;
        r_Config_SCI0_callback_receiveend();
    }
}

のようになっています。

①この生成コード(送信の部分も)の中は、ユーザーが追記できる部分がありませんが、

つまり、

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

のパートが含まれていませんが、割込みがおこった際にフラグを立てたりといった追加、独自の処理をしたい場合、どのようにコードを書くのが良いのでしょうか?

ユーザーがどのようにすることを想定しているのでしょうか?

 

②スマート・コンフィグレータの方には、それまで作成されなかった、

void R_Config_SCI0_Create_UserInit(void);

という関数が新たに加わっていますが、これはどういう点から追加されたのでしょうか?

こちらの関数は、中が空で、

void R_Config_SCI0_Create_UserInit(void)
{
    /* Start user code for user init. Do not edit comment generated here */
    /* End user code. Do not edit comment generated here */
}

のようになっているのが判りますが、①の部分を解決するためでしょうか?

追加された目的を知りたいので、回答お願いいたします。

  • 菅原と申します。

    SCIの自動生成等について送信はいいとして受信は固定長受信なので使い物になりません。
    私は最初に出来上がったソースを参考にして、コードを書き直しています。

    受信毎にコールバックするか、リングバッファに入れてくれたらそのまま使えるのですが・・
  • Dazs様、ビーコン菅原様  スマートコンフィグレータサポート担当の鈴木です。
    受信は固定長のみサポートしています。割り込みハンドラの書き換えについてはコード生成を実行してしまうと消えてしまうので、再度書き換えが必要です。下記のような方法もご検討ください。
    ja-support.renesas.com/.../17797653

    xxx_Create_Userinitですが、コード生成ではオプションで出力していたのですが、デフォルトで出力するようにしています。使い方としては、周辺機能の初期化時にユーザーが設定したいコードを書いてください。初期化時のコード追加ですので、割り込みハンドラの書き換えには対応できません。

    以上、よろしくお願いします。
  • ビーコン菅原様 、ルネサス 鈴木様

    早々の回答いただけまして、誠にありがとうございます。
    固定長のみのサポートである事や、ナレッジベースでのコード生成時の書き換え対応の方法、良く判りました。参考にさせていただきます。
  • Dazsさん、こんにちは。NoMaYと申します。

    ① r_Config_SCI0_callback_receiveend()やr_Config_SCI0_callback_transmitend()の中にユーザ記述部がありますので、連続受信時や連続送信時の1バイト割り込み毎にユーザ記述動作をさせたい場合は対処出来ませんが、連続受信完了時や連続送信完了時にやれれば良いというものであれば、そこで対処出来ます。

    自分の書いたコード例として近いものでは、送信になってしまうのですが、以下のスレッドに投稿したものがあります。

    RX65NのSCIgのTENDフラグの挙動を調べてみた(RX631のSCIcのTENDフラグの挙動も調べてみた)
    issue_20190212.zip

    RX651 で RSPI + DTC による全二重クロック同期式通信
    issue_20190725.zip

    ② 私は、以下の2つの用途として使えば良いかな、と考えています。

    (1) スマートコンフィグレータの初期化ルーチンでは対処出来ない初期化を行いたい場合。
    例: ボーレートを動的に決められるようにしたい

    (2) スマートコンフィグレータの初期化ルーチンに不具合があって回避したい場合。
    例: 漏れていたレジスタ設定があったら此処に記述する

  • NoMay様

    ①2つのスレッド参照しました。
    遅延の事、グループ割り込みの事、転送データのビット幅を合わせる事など参考になりました。
    今後、通信関連で問題が発生した時には、これらの処理を確認するようにしたいと思います。
    ありがとうございます。

    ②も具体的に事例を書いていただきましてありがとうございます。

    (この通信関係以外の部分で、main.cのファイルで、質問があり、新たに投稿します。
    そちらもアドバイスをいただけますとうれしいです。)
  • 皆様
    こんにちは、ひろと申します。

    やはり固定長受信用のモジュールだったんですね。

    現在詳細設計中でテストはしていませんが、
    初めに、受信開始(R_Config_SCI?_Serial_Receive)を受信バイト数を1で呼び、
    受信コールバック関数(r_Config_SCI?_callback_receiveend)内で
    再度受信開始(R_Config_SCI?_Serial_Receive)を呼ぶことで
    実現しようと考えていました。

    生成される関数は、「スマート・コンフィグレータ ユーザーズマニュアル RX APIリファレンス編」(r20ut4360jj0100-scapirx.pdf)を見れば分かるのですが
    その関数をどう使うかが書かれていないのでソースファイルを見ながら想像しています。
    使い方が書かれた資料は無いのでしょうか?
  • ひろさん、こんにちは。NoMaYと申します。

    実装したことがある訳では無くて、漠然と思ったことなのですが、受信バイト長を例えば64バイト固定とし、64バイト受信完了で再度受信開始を呼ぶようにし、64バイトのリングバッファを管理するような感じのコードにしてみるのはどうでしょうか?

    受信済みデータ位置を指すポインタ変数は生成されたコードにありますので、そこに読み出し済みデータ位置を指すポインタ変数等を追加し、さらに以下のような関数を実装してみる、というのはどうでしょうか?

    ・ 受信済み(未読み出し)データ数を取得する関数
    ・ Nバイト分を読み出す関数

  • こんにちは。NoMaYです。

    裏技的な話ですが、RXスマートコンフィグレータのSCI設定で受信をDTCで行うという設定を選択すると、以下の通りのスッカラカンの受信割り込みルーチンが生成されます。この時、DTCコンポーネントを全く生成しない、もしくは、DTCコンポーネントでSCI受信割り込みを扱わない、ようにしておくと、このスッカラカンの受信割り込みルーチンが1バイト受信毎に呼ばれるようになる筈です。後は、ユーザ記述部で何だって書ける、のではないかなと先程気付きました。(裏技的な話ですが、、、)

    /******************************************************************************
    * Function Name: r_Config_SCI0_receive_interrupt
    * Description  : This function is RXI0 interrupt service routine
    * Arguments    : None
    * Return Value : None
    ******************************************************************************/

    #if FAST_INTERRUPT_VECTOR == VECT_SCI0_RXI0
    #pragma interrupt r_Config_SCI0_receive_interrupt(vect=VECT(SCI0,RXI0),fint)
    #else
    #pragma interrupt r_Config_SCI0_receive_interrupt(vect=VECT(SCI0,RXI0))
    #endif
    static void r_Config_SCI0_receive_interrupt(void)
    {
        r_Config_SCI0_callback_receiveend();
    } 
    /******************************************************************************
    * Function Name: r_Config_SCI0_callback_receiveend
    * Description  : This function is a callback function when SCI0 finishes reception
    * Arguments    : None
    * Return Value : None
    ******************************************************************************/

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

    [追記]

    RXスマートコンフィグレータのSCI設定で更に受信完了のコールバック無しにしたところ、以下のコードが生成されました。こちらの方が上のものより素朴ですね。(あくまで、裏技的な話ですが、、、)

    /******************************************************************************
    * Function Name: r_Config_SCI0_receive_interrupt
    * Description  : This function is RXI0 interrupt service routine
    * Arguments    : None
    * Return Value : None
    ******************************************************************************/

    #if FAST_INTERRUPT_VECTOR == VECT_SCI0_RXI0
    #pragma interrupt r_Config_SCI0_receive_interrupt(vect=VECT(SCI0,RXI0),fint)
    #else
    #pragma interrupt r_Config_SCI0_receive_interrupt(vect=VECT(SCI0,RXI0))
    #endif
    static void r_Config_SCI0_receive_interrupt(void)
    {
        /* Start user code for r_Config_SCI0_receive_interrupt. Do not edit comment generated here */
        /* End user code. Do not edit comment generated here */
    }

     

  • NoMay様

    これらの裏技的な部分は、色々と試さない事には判らない事なので、(自分ではそこまで気づく事はなかったと思いますので)ありがとうございます。
  • こんにちは。NoMaYです。#先日の投稿の自己フォローです。

    この際ですので、チョコさんが以前に投稿されたサンプルプログラムの『RL78コード生成へのリングバッファ追加』をRXスマートコンフィグレータでやって投稿しようかと思い、ゴソゴソやり始めてみて気付いたのですが、RL78コード生成機能ではフレームワークの枠内でもリングバッファを実装可能だった、のですね。ところが、RXスマートコンフィグレータのコード生成コンポーネントではフレームワークの枠内では実装出来ない、のですね。ようやくそのことが分かって来ました、、、

    RL78コード生成機能

    ・巧みにr_uartXX_callback_softwareoverrun()を使うことでリングバッファを実装可能である

    RXマートコンフィグレータのコード生成コンポーネント

    ・上記相当の例えばr_Config_SCIXX_callback_softwareoverrun()といったものが無くリングバッファを実装出来ない

    RXマートコンフィグレータでの対処案

    ・そのSCIチャンネルに関しては(参考としてソース生成させるのみで)全てを自前で実装する(ビーコン菅原さん案)
    ・Config_SCIXX_user.cをビルドから除外して代わりとなる自前のソースをプロジェクトに追加する(鈴木さん案)
    ・先日の自分の投稿の「SCI設定で受信をDTCで行うという設定を選択する」という裏技を使用する

    もしくは

    ・SCIに関してはコード生成コンポーネントを生成させるではなくFITモジュールを生成させる

    ちなみに、以前のチョコさんの投稿では、RL78コード生成機能で生成されたソースの割り込み処理に以下のコードを追加し、リングバッファの割り込み処理を実装されていました。(赤文字箇所が追加部分です。青文字箇所はr_uartXX_callback_softwareoverrun()関連の部分です。)

    /******************************************************************************
    * Function Name: r_uart0_interrupt_receive
    * Description  : This function is INTSR0 interrupt service routine.
    * Arguments    : None
    * Return Value : None
    ******************************************************************************/
    static void __near r_uart0_interrupt_receive(void)
    {
        volatile uint8_t rx_data;
        volatile uint8_t err_type;
        
        err_type = (uint8_t)(SSR01 & 0x0007U);
        SIR01 = (uint16_t)err_type;

        if (err_type != 0U)
        {
            r_uart0_callback_error(err_type);
        }
        
        rx_data = RXD0;

        if (g_uart0_rx_length > g_uart0_rx_count)
        {
            *gp_uart0_rx_address = rx_data;
            gp_uart0_rx_address++;
            g_uart0_rx_count++;

            if (g_uart0_rx_length == g_uart0_rx_count)
            {
                r_uart0_callback_receiveend();
            }
        }
        else
        {
            r_uart0_callback_softwareoverrun(rx_data);
        }
    }
    /******************************************************************************
    * Function Name: r_uart0_callback_softwareoverrun
    * Description  : This function is a callback function when UART0 receives an overflow data.
    * Arguments    : rx_data -
    *                    receive data
    * Return Value : None
    ******************************************************************************/
    static void r_uart0_callback_softwareoverrun(uint16_t rx_data)
    {
        /* Start user code. Do not edit comment generated here */
        /* 受信用リングバッファ制御 */

        uint8_t  setptr;

        if ( g_rx_dtno < 16 )
        {                           /* バッファに空きあり                       */
            setptr = ((g_rx_rdpt + g_rx_dtno) & 0x0F);  /* 書き込みポインタ     */
            g_rx_buff[setptr] = rx_data;    /* 受信データをバッファに格納       */
            g_rx_dtno++;
        }
        else
        {                           /* バッファがフル時の処理                   */
            g_rx_status = 0x80;             /* オーバフロー・フラグをセット     */
        }
        /* End user code. Do not edit comment generated here */
    }

    それから、鈴木さん案(リプライにあったFAQのこと)ですが、具体的には、一例として、以下の画面コピーのプロジェクトのようにすれば良い、ということだと思います。

    CS+の場合


    e2 studioの場合