DTCを用いたRSPI通信時の割り込みについて

皆様

毎度お世話になっております。

 

RX71Mマイコンを使用して、DTCによりRSPIから32bitのデータを連続送受信することを試みています。

現時点でDTCが正常に起動して、実際に通信も起きていることが確認できたのですが、

CPUへの割り込みが2回発生してしまう問題があります。

DTCはFITモジュールを使用しており、CPU割り込みはDTCの全転送終了後に1度発生する設定にしてあります。

 

DTCの転送回数を2回や4回などに変更しても、同じようにCPU割り込みは2回発生しています。

 

通信の流れは以下のようにしています。

 

①RSPI0の割り込みを無効化

②DTC起動要因の設定(FITモジュールのR_DTC_Create, R_DTC_Control関数)

③RSPI0の割り込みを有効化

④RSPI.SPDR.LONGレジスタに最初の32bitデータを書き込み

 

④に関しては、現時点では送信バッファエンプティ割り込みを発生させるために、最初のデータはプログラムから手動で書き込んでいます。

 

割り込みのタイミングに関しては、

最初の一回は④で書き込んだデータの転送終了時、2回目はDTCの全転送終了時に発生しているようです。

 

自分の希望としては、最初の一回目の割り込みは発生しないようにして、2回目の割り込みだけを発生させるようにしたいのですが、

そのような方法はあるのでしょうか?

 

よろしくお願いいたします。

 

開発環境:CS+ for CC V7.00.00

使用デバイス: RX71M_RSK

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

    こちらのRX65Nでは、私の先日の予想に基づいて割り込みを1回にする方法を考えて試したら出来ました。

    予想したカラクリは、以下の通りです。(転送データ数は3個です。)

    (1) RXスマートコンフィグレータのコードにてダミーの送信バッファエンプティ割り込みを発生させた → DTC転送開始
    (2) DTCは1個目のデータを転送元のRAMからリードしてSPDRへ転送 → 次の送信バッファエンプティ割り込み発生
    (3) DTCは2個目のデータを転送元のRAMからリードしてSPDRへ転送 → 次の送信バッファエンプティ割り込み発生
    (4) DTCは3個目のデータを転送元のRAMからリードしてSPDRへ転送 → DTC転送終了 しかし 次の送信バッファエンプティ割り込みは発生する!
    (5) DTC転送終了割り込み発生 (DTCの仕様としてDTC転送終了割り込みは送信バッファエンプティ割り込みとして発生)
    (6) そして(4)による次の送信バッファエンプティ割り込み発生 ただし DTC転送は終了しているので単なるCPU割り込みとして受け付けられる

    そこで、(5)に対して以下のようにしたら(6)の割り込みは発生しませんでした。

    (5-1) DTC転送終了割り込み処理内で、RSPIからの送信バッファエンプティ割り込みの送出を不許可にして、かつ、ICUに取り込まれて保留中の送信バッファエンプティ割り込みを取り消す(もしあれば)
    (5-2) ogawaさんに教えて頂いたハードウェアマニュアルの記載では最大2個の割り込みが保留される可能性があるが、送信バッファエンプティ割り込みに関しては、DTC転送終了割り込みとしての送信バッファエンプティ割り込みと本物の送信バッファエンプティ割り込みの計2個までとなる(と思う)ので、DTC転送終了割り込み処理内ではDTC転送終了割り込みとしての送信バッファエンプティ割り込みはCPU受付済みですので、保留されている可能性があるのは本物の送信バッファエンプティ割り込みの1個のみである(と思う)
    (5-3) 割り込みの取り消し操作に関しては別スレッド「RX65NのSCIgのTENDフラグの挙動を調べてみた(RX631のSCIcのTENDフラグの挙動も調べてみた)」にあるような点にも注意した

    具体的には、以下の赤文字箇所の処理を行いました。(なお、正直に言うと、投稿文を書き始めてみて、この内蔵周辺回路へのライトの並び(RSPI0.SPCR.BIT.SPTIE、IR(RSPI0,SPTI0)、RSPI0.SPCR2.BIT.SPIIE)ならば、Waitは2つとも無くても大丈夫なような気がして来ています、、、実際に無しにしても大丈夫でした、、、)

    src\smc_gen\Config_RSPI0\Config_RSPI0_user.c

    /******************************************************************************
    * Function Name: r_Config_RSPI0_callback_transmitend
    * Description  : This function is a callback function when RSPI0 finishes transmission
    * Arguments    : None
    * Return Value : None
    ******************************************************************************/

    static void r_Config_RSPI0_callback_transmitend(void)
    {
        /* Start user code for r_Config_RSPI0_callback_transmitend. Do not edit comment generated here */
        RSPI0_dtce_chk[RSPI0_txint_count] = ICU.DTCER[39].BIT.DTCE;
        RSPI0_dtc_cra_chk[RSPI0_txint_count] = (dtc_transferdata_vector39.cra_crb >> 16);
        RSPI0_txint_count++;

        /* Disable transmit interrupt */
        RSPI0.SPCR.BIT.SPTIE = 0U;

        /* Wait for a completion of write access to RSPI and (if exists) an arrival of last interrupt request to ICU */
        if ( RSPI0.SPCR.BIT.SPTIE != 0 ) /* Always false */
        {
            nop(); /* Never come here */
        }

        /* Clear transmit interrupt request (if exists) */
        IR(RSPI0,SPTI0) = 0U;

        /* Wait for a completion of write access to ICU and (if exists) a cancel of last interrupt request to CPU */
        if ( IR(RSPI0,SPTI0) != 0 ) /* Always false */
        {
            nop(); /* Never come here */
        }

        /* Enable idle interrupt */
        RSPI0.SPCR2.BIT.SPIIE = 1U;
        /* End user code. Do not edit comment generated here */
    }

    以下、参考までにプロジェクトのファイル一式を添付します。(なお、今回、送信をDTC転送するものの他に、比較用に、受信をDTC転送するもの、送受信共にDTC転送ではなく素朴に割り込みで行うもの、も一緒に含めました。ただ、今回、コード生成したソースの変更をStart user code ~ End user codeに全て押し込んだこともあって、少し分かり難くなってしまっていますが、、、)

    プロジェクトのファイル一式 (RX65N TBボード、CS+プロジェクト(rcpeファイル同梱))
    issue_20190307.zip
    RX65N_SCFG_RSPI_DTC_SEND_3 → 送信をDTC転送するものの
    RX65N_SCFG_RSPI_DTC_RECV_3 → 受信をDTC転送するものの
    RX65N_SCFG_RSPI_INT → 送受信共に割り込みで行うもの

    以下、結果を確認したTeraTermの画面コピーです。

    割り込みは1回のみ


    [追記]

    RXスマートコンフィグレータでコード生成したソースの話になってしまいますが、送受信共にDTC転送ではなく素朴に割り込みで行うもので、ループバック動作時の送信バッファエンプティ割り込みと受信バッファフル割り込みの回数をカウントしてみました。(添付したzipファイルのRX65N_SCFG_RSPI_INTプロジェクトではカウントしていませんでしたので、少しコードを追加してカウントしてみました。) 結果、送信と受信で割り込み回数は一致していませんでした。送信の方が1回多いのは最後のデータを送信した後の次の送信バッファエンプティ割り込みの分です。

    送受信共にDTC転送ではなく素朴に割り込みで行った時(RXスマートコンフィグレータでコード生成したソース)


    [追記その2]

    上の方で「この内蔵周辺回路へのライトの並び(RSPI0.SPCR.BIT.SPTIE、IR(RSPI0,SPTI0)、RSPI0.SPCR2.BIT.SPIIE)ならば、Waitは2つとも無くても大丈夫なような気がして来ています、、、実際に無しにしても大丈夫でした、、、」と書きましたが、自分自身でソースのコメントに「if exists」と書き込んでいるような箇所に対して、ちょっと試して大丈夫だった、というのは良くなかったですね。ちゃんと確認する手が無いかどうか、これから考えてみます。すみません。

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

    こちらのRX65Nでは、私の先日の予想に基づいて割り込みを1回にする方法を考えて試したら出来ました。

    予想したカラクリは、以下の通りです。(転送データ数は3個です。)

    (1) RXスマートコンフィグレータのコードにてダミーの送信バッファエンプティ割り込みを発生させた → DTC転送開始
    (2) DTCは1個目のデータを転送元のRAMからリードしてSPDRへ転送 → 次の送信バッファエンプティ割り込み発生
    (3) DTCは2個目のデータを転送元のRAMからリードしてSPDRへ転送 → 次の送信バッファエンプティ割り込み発生
    (4) DTCは3個目のデータを転送元のRAMからリードしてSPDRへ転送 → DTC転送終了 しかし 次の送信バッファエンプティ割り込みは発生する!
    (5) DTC転送終了割り込み発生 (DTCの仕様としてDTC転送終了割り込みは送信バッファエンプティ割り込みとして発生)
    (6) そして(4)による次の送信バッファエンプティ割り込み発生 ただし DTC転送は終了しているので単なるCPU割り込みとして受け付けられる

    そこで、(5)に対して以下のようにしたら(6)の割り込みは発生しませんでした。

    (5-1) DTC転送終了割り込み処理内で、RSPIからの送信バッファエンプティ割り込みの送出を不許可にして、かつ、ICUに取り込まれて保留中の送信バッファエンプティ割り込みを取り消す(もしあれば)
    (5-2) ogawaさんに教えて頂いたハードウェアマニュアルの記載では最大2個の割り込みが保留される可能性があるが、送信バッファエンプティ割り込みに関しては、DTC転送終了割り込みとしての送信バッファエンプティ割り込みと本物の送信バッファエンプティ割り込みの計2個までとなる(と思う)ので、DTC転送終了割り込み処理内ではDTC転送終了割り込みとしての送信バッファエンプティ割り込みはCPU受付済みですので、保留されている可能性があるのは本物の送信バッファエンプティ割り込みの1個のみである(と思う)
    (5-3) 割り込みの取り消し操作に関しては別スレッド「RX65NのSCIgのTENDフラグの挙動を調べてみた(RX631のSCIcのTENDフラグの挙動も調べてみた)」にあるような点にも注意した

    具体的には、以下の赤文字箇所の処理を行いました。(なお、正直に言うと、投稿文を書き始めてみて、この内蔵周辺回路へのライトの並び(RSPI0.SPCR.BIT.SPTIE、IR(RSPI0,SPTI0)、RSPI0.SPCR2.BIT.SPIIE)ならば、Waitは2つとも無くても大丈夫なような気がして来ています、、、実際に無しにしても大丈夫でした、、、)

    src\smc_gen\Config_RSPI0\Config_RSPI0_user.c

    /******************************************************************************
    * Function Name: r_Config_RSPI0_callback_transmitend
    * Description  : This function is a callback function when RSPI0 finishes transmission
    * Arguments    : None
    * Return Value : None
    ******************************************************************************/

    static void r_Config_RSPI0_callback_transmitend(void)
    {
        /* Start user code for r_Config_RSPI0_callback_transmitend. Do not edit comment generated here */
        RSPI0_dtce_chk[RSPI0_txint_count] = ICU.DTCER[39].BIT.DTCE;
        RSPI0_dtc_cra_chk[RSPI0_txint_count] = (dtc_transferdata_vector39.cra_crb >> 16);
        RSPI0_txint_count++;

        /* Disable transmit interrupt */
        RSPI0.SPCR.BIT.SPTIE = 0U;

        /* Wait for a completion of write access to RSPI and (if exists) an arrival of last interrupt request to ICU */
        if ( RSPI0.SPCR.BIT.SPTIE != 0 ) /* Always false */
        {
            nop(); /* Never come here */
        }

        /* Clear transmit interrupt request (if exists) */
        IR(RSPI0,SPTI0) = 0U;

        /* Wait for a completion of write access to ICU and (if exists) a cancel of last interrupt request to CPU */
        if ( IR(RSPI0,SPTI0) != 0 ) /* Always false */
        {
            nop(); /* Never come here */
        }

        /* Enable idle interrupt */
        RSPI0.SPCR2.BIT.SPIIE = 1U;
        /* End user code. Do not edit comment generated here */
    }

    以下、参考までにプロジェクトのファイル一式を添付します。(なお、今回、送信をDTC転送するものの他に、比較用に、受信をDTC転送するもの、送受信共にDTC転送ではなく素朴に割り込みで行うもの、も一緒に含めました。ただ、今回、コード生成したソースの変更をStart user code ~ End user codeに全て押し込んだこともあって、少し分かり難くなってしまっていますが、、、)

    プロジェクトのファイル一式 (RX65N TBボード、CS+プロジェクト(rcpeファイル同梱))
    issue_20190307.zip
    RX65N_SCFG_RSPI_DTC_SEND_3 → 送信をDTC転送するものの
    RX65N_SCFG_RSPI_DTC_RECV_3 → 受信をDTC転送するものの
    RX65N_SCFG_RSPI_INT → 送受信共に割り込みで行うもの

    以下、結果を確認したTeraTermの画面コピーです。

    割り込みは1回のみ


    [追記]

    RXスマートコンフィグレータでコード生成したソースの話になってしまいますが、送受信共にDTC転送ではなく素朴に割り込みで行うもので、ループバック動作時の送信バッファエンプティ割り込みと受信バッファフル割り込みの回数をカウントしてみました。(添付したzipファイルのRX65N_SCFG_RSPI_INTプロジェクトではカウントしていませんでしたので、少しコードを追加してカウントしてみました。) 結果、送信と受信で割り込み回数は一致していませんでした。送信の方が1回多いのは最後のデータを送信した後の次の送信バッファエンプティ割り込みの分です。

    送受信共にDTC転送ではなく素朴に割り込みで行った時(RXスマートコンフィグレータでコード生成したソース)


    [追記その2]

    上の方で「この内蔵周辺回路へのライトの並び(RSPI0.SPCR.BIT.SPTIE、IR(RSPI0,SPTI0)、RSPI0.SPCR2.BIT.SPIIE)ならば、Waitは2つとも無くても大丈夫なような気がして来ています、、、実際に無しにしても大丈夫でした、、、」と書きましたが、自分自身でソースのコメントに「if exists」と書き込んでいるような箇所に対して、ちょっと試して大丈夫だった、というのは良くなかったですね。ちゃんと確認する手が無いかどうか、これから考えてみます。すみません。

Children
No Data