Top Page [◀◀]  2   3   4   5   6   7   8   9   ... [▶▶Last Page

SCI通信の受信をDTCで受けてみるも転送先バッファにデータが格納されない

お世話になります。
DTCを使ってSCI受信を試みておりますが、思ったような動きにならず悩んでいます。
長文とはなりますが、ご助言をいただけると大変助かります。

<目的>
PC ⇒ RX111に対して、SCI通信(UART)にて数バイトのコマンドを送信し、
データ受信処理をDTCに置き換えてパフォーマンスを向上したい。
※但し、コマンドは可変です。

<環境>
 IDE:e2Studio(v7.3.0)
 マイコン      :RX111(64pin)
 通信用Clock   :24MHz
 通信ボーレート:750Kbbs
 コマンド      :テスト用のコマンドとして以下の8byteを送信する。(Teratermから発行)
                 ・0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08

<現状況>
一先ず"お試し"としてコマンドを発行した後にE1デバッガでブレークし、
転送先RAM領域上(transferbuf)にテストコマンドが格納されていることは確認しました。

◆DTCの初期設定
    DTC.DTCVBR = (void*)0xffffa000;  //ベクタベースアドレス設定
    DTC.DTCADMOD.BIT.SHORT = 0;      //フルアドレスモード
    DTC.DTCCR.BIT.RRS = 1;

    ICU.DTCER[VECT(SCI1,RXI1)].BIT.DTCE = 1; //SCI RXをDTC起動要因
   
    ・転送情報
    SCI_DTC[0].MRA = 0x00;//SAR固定、ノーマル転送、8bit
    SCI_DTC[0].MRB = 0x08;//転送先インクリメント
    SCI_DTC[0].SAR = (void*)&SCI1.RDR;
    SCI_DTC[0].DAR = &transferbuf;           ←★RAM上に確保した転送先バッファです
    SCI_DTC[0].CRA = 0x000a;//転送回数設定


そこで、次にコマンドが可変の場合に対応するため、
最初はSCI RXの割り込み処理でデータ長までを受信して、
そのデータ長分だけDTCを使って受信したいと考えました。

具体的にはテストコマンドの0x03をデータ長として、
残りの5byteをDTCで受け取る設定にしたつもりです。

====================================
main(){
   ※DTC初期設定
  
    DTC.DTCVBR = (void*)0xffffa000;  //ベクタベースアドレス設定
    DTC.DTCADMOD.BIT.SHORT = 0;      //フルアドレスモード
    DTC.DTCCR.BIT.RRS = 1;

    SCI_DTC[0].MRA = 0x00;
    SCI_DTC[0].MRB = 0x40;  ★★★★★DTCのデータ受信完了後にCPU割り込みを受ける目的で"お試しから変更しています。★★★★★
    SCI_DTC[0].SAR = (void*)&SCI1.RDR;

    while(1)
    {

    }
}

====================================
※SCI RX割り込み処理
char dtcboot = 0;  //dtcboot判定用
char recvCnt=0;
void Excep_SCI1_RXI1(void){
    sendbuf_rx1[recvCnt] = SCI1.RDR;
    recvCnt++;

    //データ長は3byte目に格納されている(※テストコマンドは0x03ですが残り5byteです)
    if(recvCnt>=3){
       if(0 == dtcboot){
            dtcboot = 1;
           
            ICU.DTCER[VECT(SCI1,RXI1)].BIT.DTCE = 1; //SCI1受信割り込みをDTCの起動要因に設定
            SCI_DTC[0].DAR = &transferbuf;
            SCI_DTC[0].CRA = 5;//転送回数設定(残り5byte)
            DTC.DTCST.BIT.DTCST= 1;
       }
       else{
            //転送回数が5回分終了したため
            dtcboot = 0;
            ICU.DTCER[VECT(SCI1,RXI1)].BIT.DTCE = 0; //SCI1受信割り込みをDTCの起動要因に設定
            DTC.DTCST.BIT.DTCST= 0;
       }
    }
}
====================================

<結果>
  SCI RX側の受信バッファは以下の通りとなっており、
  DTC転送完了後にCPU割り込みを受ける振る舞いの想定なので問題ないのですが、

  sendbuf_rx1[0] = 0x01
  sendbuf_rx1[1] = 0x02
  sendbuf_rx1[2] = 0x03  ★データ長
  sendbuf_rx1[3] = 0x08  ★最終データ

  問題は、DTC側で受信する転送先バッファに0x08しか格納されておらず、
  残りのデータが消えています。

  transferbuf[0] = 0x08

  どうも転送先のバッファアドレスがインクリメントされていないため、
  上書きされているように思えるのですが、E1デバッガで確認しても以下の値が書き込まれており
  問題が見受けられません。

  SCI_DTC[0].MRB = 0x40;//転送先インクリメント

  原因として何が考えられるでしょうか。

  • わわいです
    SCIの受信をDMAやらDTCで受けるのは筋が悪いです

    おそらく、DTCは最初の割り込みがかかった場合に、DTCのパラメータを読み込んで何バイト転送かの動作を決定しますが、割り込みがかかった状態下でパラメータ変更しても、その変更したパラメータを読むかどうかはわかりません。

    ということで、DTCを使用しないで、受信割り込みで駆動するのをおすすめします
  • わたさん、こんにちは。NoMaYです。

    MRB = 0x40 のままという設定はおかしくないですか?このビットはCHNS(DTCチェーン転送選択)ビットですよね? MRB = 0x08 (転送先アドレスアドレッシングモードビットのDM[1:0] = 10なので転送後DARインクリメント)から変更した意図は何ですか?(言い方を変えますと、「DTCのデータ受信完了後にCPU割り込みを受ける目的で"お試しから変更しています」の意味が分からないです。) ([追記] 昨夜はDTCチェーン転送選択ビットが立っていることに気を取られて見落としてしまいましたが、「DTCのデータ受信完了後にCPU割り込みを受ける目的」というのは、以下の画面コピーのDISEL(DTC割り込み選択)ビットのことですか?とはいえ、このビットだとしても、"お試し"での0のままで良いように思うのですが?それから、転送先アドレスアドレッシングモードビットのDM[1:0]もDM[1:0] = 10にして転送後DARインクリメントにする"お試し"での設定のままで良いように思うですが?)

    RX111 ハードウェアマニュアル
    www.renesas.com/jp/ja/doc/products/mpumcu/doc/rx_family/r01uh0365jj0130_rx111.pdf


    あと、添付されていたソースコードで気になったのですが、DTCSTビットとDTCEビットの初期化箇所が(私の感覚では&RXスマートコンフィグレータの生成コードと比べても)一般的な設定箇所とは異なるように思います。以下の赤文字箇所あたりで設定するのが一般的では無いかと思います。

        DTC.DTCVBR = (void*)0xffffa000;  //ベクタベースアドレス設定
        DTC.DTCADMOD.BIT.SHORT = 0;      //フルアドレスモード
        DTC.DTCCR.BIT.RRS = 1;
        DTC.DTCST.BIT.DTCST= 1;
                SCI_DTC[0].DAR = &transferbuf;
                SCI_DTC[0].CRA = 5;//転送回数設定(残り5byte)
                ICU.DTCER[VECT(SCI1,RXI1)].BIT.DTCE = 1; //SCI1受信割り込みをDTCの起動要因に設定

    また、以下の赤文字箇所のコードは不要だと思います。(DTCEビットは自動で降ります。DTCSTビットはDTCモジュール自体の動作を許可/禁止するビットですので、頻繁に上げ下げするものでは無いです。)

        if(recvCnt>=3){
            if(0 == dtcboot){
                dtcboot = 1;
                略
                DTC.DTCST.BIT.DTCST= 1;
            }
            else{
                略
                dtcboot = 0;
                ICU.DTCER[VECT(SCI1,RXI1)].BIT.DTCE = 0; //SCI1受信割り込みをDTCの起動要因に設定
                DTC.DTCST.BIT.DTCST= 0;
            }
        }

     

  • In reply to わわい:

    わわいさん

    長期休暇のため返信遅くなりました。
    本件、パフォーマンスアップを目的にDTCに挑戦している次第です。
    大幅な改善が確認できれば、現状の受信割り込み駆動からDTC受信に置き換えていきたいと考えております。
  • In reply to NoMaY:

    NoMaYさん

    長期休暇のため返信遅くなりました。

    いつも拙い質問に対し、
    丁寧なご回答をいただき誠にありがとうございます。

    ご指摘の通りレジスタ設定がいろいろと誤っておりました。
    (bit位置の見間違えなどお恥ずかしい限りです。)

    受信の方は以下のように設定することで
    意図した通りの振る舞いとすることができました。

    ◆初期設定
    DTC.DTCVBR = (void*)0xffffa000; //ベクタベースアドレス設定
    DTC.DTCADMOD.BIT.SHORT = 0; //フルアドレスモード
    DTC.DTCCR.BIT.RRS = 1;

    ICU.DTCER[VECT(SCI1,RXI1)].BIT.DTCE = 1; //SCI1受信割り込みをDTCの起動要因に設定

    //RX1側の設定
    SCI_DTC[0].MRA = 0x00;//SAR固定、ノーマル転送、8bit
    SCI_DTC[0].wk[0]=0;
    SCI_DTC[0].MRB = 0x08;//DTCデータ転送完了時にCPU割り込み発生、転送先インクリメント
    SCI_DTC[0].SAR = (void*)&SCI1.RDR;
    SCI_DTC[0].DAR = &recvbuf_rx1[0];
    SCI_DTC[0].CRA = E_HEADER_MAX;//転送回数設定をヘッダ情報の取得サイズ分で初期化

    //TX1側の設定
    SCI_DTC[1].MRA = 0x08;//SARインクリメント、ノーマル転送、8bit
    SCI_DTC[1].wk[0]=0;
    SCI_DTC[1].MRB = 0x00;//DTCデータ転送完了時にCPU割り込み発生,転送先アドレス固定
    SCI_DTC[1].SAR = &sendbuf_tx1[0];
    SCI_DTC[1].DAR = (void*)&SCI1.TDR;

    DTC.DTCST.BIT.DTCST= 1;

    ◆SCI RXI(割り込み)
    recvCnt_rx1buf++;
    if(1 == recvCnt_rx1buf){//ヘッダ受信時
    SCI_DTC[0].CRA = recvbuf_rx1[E_HEADER_PAYLOAD_LEN] + MSG_CRC_SIZE;//ペイロード長から残転送回数を設定
    ICU.DTCER[VECT(SCI1,RXI1)].BIT.DTCE = 1; //SCI1受信割り込みをDTCの起動要因に再設定(CPU割り込みが起こるたびに初期化される)
    DTC.DTCCR.BIT.RRS = 0;//転送情報を再読み込みするための情報
    }
    else{//全データ受信完了
    recvCnt_rx1buf = 0;
    SCI_DTC[0].CRA = E_HEADER_MAX;//ヘッダ情報の取得サイズに初期化
    SCI_DTC[0].DAR = &recvbuf_rx1[0];//受信バッファ位置を初期化
    ICU.DTCER[VECT(SCI1,RXI1)].BIT.DTCE = 1; //SCI1受信割り込みをDTCの起動要因に再設定(CPU割り込みが起こるたびに初期化されるため)
    DTC.DTCCR.BIT.RRS = 0;
    }


    但し、送信で意図しない振る舞いとなっており悩み中です。

    送信データ(7byte)を"sendbuf_tx1"に設定し、
    DTC転送を行っているのですが、以下の2点の問題が発生します。

    ○1点目○
    E1でブレークポイントを貼ると、SCI TXI送信(割り込み)が2回コールされます。
    送信側の設定は「SCI_DTC[1].MRB = 0x00;」としているため、
    SCI TXI送信(割り込み)は7byteの転送が完了した際の1回のみではないかと思っています。

    ○2点目○
    ブレークポイントを貼ると送信データはちゃんと意図した7byteが送信されるのですが、
    ブレークポイントを貼らない場合、6byteしか送信されず、またデータの末尾が0xFEとなります。
    "sendbuf_tx1"には意図通りの7byteが設定されているにも関わらず、
    なぜ、ブレークの設定次第で振る舞いが変わってしまうのでしょうか。
    #問題となるタイミングがある?


    ◆TX送信(転送)情報設定
    memcpy((void*)sendbuf_tx1, buffer, size);
    SCI_DTC[1].SAR = &sendbuf_tx1[0];
    SCI_DTC[1].CRA = size;★★★★7byteの送信データ★★★★★
    ICU.DTCER[VECT(SCI1,TXI1)].BIT.DTCE = 1; //SCI1送信割り込みをDTCの起動要因に設定
    DTC.DTCCR.BIT.RRS = 0;

    SCI1.SCR.BIT.TE = 1;
    SCI1.SCR.BIT.TIE = 1;

    ◆SCI TXI(割り込み)
    SCI1.SCR.BIT.TE = 0; ★ブレーク位置★ 上記問題点に記載の通りここにブレークを貼る貼らないで振る舞いが変わる。
    SCI1.SCR.BIT.TIE = 0;
    SCI1.SCR.BIT.TEIE = 1;

    ◆SCI TEIE(割り込み)
    SCI1.SCR.BIT.TE = 0;
    SCI1.SCR.BIT.TIE = 0;
    SCI1.SCR.BIT.TEIE = 0;
  • In reply to わた:

    色々試すうちに、
    7byteの送信データに対して、以下を+2 (9byte)にすると、

    SCI_DTC[1].CRA = size + 2;

    末尾に0xFEが付与されるものの、
    なぜか期待データの7byteが出力されるようになりました。
    ただし、相変わらず○1点目○の2回割り込み発生の件は現象変わらずですが。

    ◆結果
    0x01 0x05 0x02 0x01 0x01 0x9c 0x5c 0xfe

    ※+2する前は以下でした。
    0x01 0x05 0x02 0x01 0x01 0xfe

    ◆期待動作
    0x01 0x05 0x02 0x01 0x01 0x9c 0x5c

    継続して調査はしますが、
    ひとまずご報告までに。
  • In reply to わた:

    わわいです
    SCIの受信をDTCで駆動するとして、その受信中にノイズなどで受信文字が欠落することを考えてみましょう。
    その場合にどういう事が起こるのか、そういう場合のエラー検出をどう実装すればいいのかわかるでしょうか。
    また、そういうエラーに陥ったときに、どう回復させるのか、というのをよく考えておく必要があります。
  • DTCを使わずSCI単体でも、割り込み処理が思ったように出来ていますか?
  • In reply to わわい:

    わわいさん

    ご指摘ありがとうございます。
    ご指摘の件はタイムアウト検出やチェックサムチェック、
    またオーバーランなどのエラーなど考えうるものについて
    問題データの破棄、復帰処理を実装&動作確認済みです。
  • In reply to リカルド:

    リカルドさん

    はい、SCI単体では問題なく割り込み処理が実施されることを確認済です。
    (7byteのデータ送信であれば、TXI割り込みが7回コールされる)

    個人的には0xfeが出ていることが何かしら解析の糸口になるような気がするのですが、
    現状0xfeでgoogle先生に聞いてみても解決に至る有力な情報を得ることができておりません。
  • わたさん、こんにちは。NoMaYです。

    送信側の割り込み処理の全体が気になります。ソースが見たいかな(見ないと何とも)、と思います。予期しない送信割り込みの原因としては、とっさには、以下の3種類が思い浮かびます。実は、たぶん何かヒントが見つかるのでは、と思うスレッドが最近あったのですが、見てみてはどうでしょうか?と思います。(そのスレッド自体はSPIに関するものですが、話の内容はSCIでも同様だと思ってます。)

    追記:ひょっとして、SCI TXI(割り込み)とSCI TEIE(割り込み)のそれぞれ3行がすべてですか?

    予期しない送信割り込みの原因の可能性:

    (1) SCIのレジスタ設定順序によっては、送信割り込みを許可した途端に、ダミーの送信バッファエンプティ割り込みが発生する

    (2) 最後のデータが送信シフトレジスタに転送された時、送信割り込みが許可されたままになっていると、そのタイミングで(SCI自体には最後のデータだったのか分かりようもないので)次のデータを要求する送信バッファエンプティ割り込みが発生する

    (3) ICUの中に割り込み要求が保持されてしまっていた(SCIの場合は最大2個保持される可能性があるようです)
    [訂正]
    (3) SCIモジュールとICUモジュールの中に割り込み要求が保持されてしまっていた(SCIの場合は、ハードウェアマニュアルの記載から解釈すると、それぞれ1つずつ、計最大2個保持される可能性があるようです)

    何かヒントが見つかるのではないかと思うスレッド:

    DTCを用いたRSPI通信時の割り込みについて
    japan.renesasrulz.com/cafe_rene/f/002-2095199602/5669/dtc-rspi

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

    1バイト目の送信の起動はどうされていますか?以下のレジスタ設定順序だと、ハードウェアマニュアルでDTCの起動に使えますよと書かれているダミーの送信エンプティ割り込みが発生しない筈なので、気になっています。

    ◆TX送信(転送)情報設定
    memcpy((void*)sendbuf_tx1, buffer, size);
    SCI_DTC[1].SAR = &sendbuf_tx1[0];
    SCI_DTC[1].CRA = size;★★★★7byteの送信データ★★★★★
    ICU.DTCER[VECT(SCI1,TXI1)].BIT.DTCE = 1; //SCI1送信割り込みをDTCの起動要因に設定
    DTC.DTCCR.BIT.RRS = 0;

    SCI1.SCR.BIT.TE = 1;
    SCI1.SCR.BIT.TIE = 1;

    あと、以下のタイミングは送信バッファエンプティですので、ここでTE=0にして送信を止めてしまっては駄目なのではないでしょうか?

    ◆SCI TXI(割り込み)
    SCI1.SCR.BIT.TE = 0; ★ブレーク位置★ 上記問題点に記載の通りここにブレークを貼る貼らないで振る舞いが変わる。
    SCI1.SCR.BIT.TIE = 0;
    SCI1.SCR.BIT.TEIE = 1;

     

  • In reply to NoMaY:

    NoMaYさん

    先の投稿で2点質問させていただいておりましたが、
    2点とも解決致しましたのでご報告させていただきます。
    ・1点目:SCI TXI送信(割り込み)が2回コールされる
    ・2点目:7byteの送信データに対して6byteしか送信されず、
    またデータの末尾が0xFEとなる


    >DTCを用いたRSPI通信時の割り込みについて
    >japan.renesasrulz.com/cafe_rene/f/002-2095199602/5669/dtc-rspi

    まずは、ご紹介いただいた上記内を確認し、
    TE、TIEフラグの操作順番がハードウェア仕様書とは異なっておりましたので、
    以下のように処理を入れ替えるとTXI割り込みは期待動作の通り1回のみになりました。
    (尚、処理を入れ替える前はTXI割り込み内でTIEのフラグを設定した瞬間に
    送信エンプティのIRフラグがOnされておりました。これが原因のようです。)

    ◆TX送信(転送)情報設定
    SCI1.SCR.BIT.TE = 1;
    SCI1.SCR.BIT.TIE = 1;

    SCI1.SCR.BIT.TIE = 1;
    SCI1.SCR.BIT.TE = 1;

    ◆SCI TXI(割り込み)
    SCI1.SCR.BIT.TE = 0;
    SCI1.SCR.BIT.TIE = 0;

    SCI1.SCR.BIT.TIE = 0;
    SCI1.SCR.BIT.TE = 0;



    また、先程コメントいただいた以下の内容はまさにご指摘の通りで、
    "送信バッファエンプティですので、ここでTE=0にして送信を止めてしまっては駄目"

    TXI割り込み内のSCI1.SCR.BIT.TE=0の行を削除すると、
    2点目の問題も解決しました。
    (TIEのフラグ操作もなくなったので結果的に1点目の問題も発生しなくなりました)

    もう少し動作確認を行いますが、
    一先ずお礼をと思いまして。

    誠にありがとうございました。
    大変助かりました。

    以上です。

Top Page [◀◀]  2   3   4   5   6   7   8   9   ... [▶▶Last Page