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

こんにちは。NoMaYです。

先日、「SCIのTENDフラグの注釈」というスレッドでRX210やRX63Nに搭載されているSCIcのTENDフラグ(送信終了フラグ)というのは、ハードウェアマニュアル上は、TDRレジスタ(送信データレジスタ)に書き込みした直後からフラグの値が変化する(前の状態が送信終了であれば直ちに1(送信終了)→0(送信中)になる)のでは無くて暫くしてから値が変化する、という挙動を示す(と受け取れる)ように書かれていることを知りました。更に、その後、「RZ/A2MのDMACについて教えてください」というスレッドでRZ/A2MやRX65Nに搭載されているSCIgのTENDフラグの挙動が気になって説明を読む機会があったのですが、その時、ハードウェアマニュアル上は、書かれている内容が変わっていることに気付きました。(ちなみに、同様にSCIgを搭載したRX64Mでも変わっていました。) そこには、以下の画面コピーのように、TENDフラグの変化タイミングに関することは書かれていなくてレベル検出割り込みの一般的な話(のページを参照して下さいとの話)が書かれていました。

もともと、先ほど挙げたスレッドの1つ目ではRX210の実際の挙動はハードウェアマニュアルの記載と違っているということ?(と受け取れる)ような話も出ていて、ちょっと腑に落ちないところもあったので、この際なので、RX65NのTBボードでRX65NのSCIgのTENDフラグの挙動を調べてみました。(なお、後ほどGR-CITRUSでRX631も調べてみようと思っています。)

調べてみたところ、RX65NのSCIgのTENDフラグでは、TDRレジスタに書き込みした直後からTENDフラグの値が変わるようになっていました。(マイコン内部の信号を観測することが出来ませんので、正確には、直後にTENDフラグを読み出すと値が変わるようになっていた、ということではありますが。)

プロジェクトファイル一式 (RX65NのTBボードのサンプルプログラムをCS+プロジェクトへ変換して流用)
issue_20190212.zip

結果:TDRレジスタ書き込み前が送信終了状態だった場合の画面コピー(TeraTermへ結果を送信した時の画面コピー)


TENDフラグ読み出し箇所のCソース(なおSSRレジスタのbit2がTENDフラグ)

        TEND_sampling[0] = SCI6.SSR.BYTE; ← 上の画面コピーの左側の赤枠
        SCI6.TDR = data;
        TEND_sampling[1] = SCI6.SSR.BYTE; ← 上の画面コピーの右側の赤枠
        TEND_sampling[2] = SCI6.SSR.BYTE;
        TEND_sampling[3] = SCI6.SSR.BYTE;
        TEND_sampling[4] = SCI6.SSR.BYTE;

TENDフラグ読み出し箇所のアセンブラコード(なおSSRレジスタのbit2がTENDフラグ)

        MOV.B 02H[R2], [R5]    ; TEND_sampling[0] = SCI6.SSR.BYTE; ← 上の画面コピーの左側の赤枠
        MOV.B R15, 01H[R2]     ; SCI6.TDR = data;
        MOV.B 02H[R2], 01H[R5] ; TEND_sampling[1] = SCI6.SSR.BYTE; ← 上の画面コピーの右側の赤枠
        MOV.B 02H[R2], 02H[R5] ; TEND_sampling[2] = SCI6.SSR.BYTE;
        MOV.B 02H[R2], 03H[R5] ; TEND_sampling[3] = SCI6.SSR.BYTE;
        MOV.B 02H[R2], 04H[R5] ; TEND_sampling[4] = SCI6.SSR.BYTE;

参考:TDRレジスタ書き込み前が送信中状態だった場合の画面コピー(つまり連続送信時の2バイト目の場合)


以下、ハードウェアマニュアルの画面コピーです。(赤枠は私によるものです。)

RX210のSCIcのTENDフラグの説明
www.renesas.com/jp/ja/doc/products/mpumcu/doc/rx_family/r01uh0037jj0150-rx210.pdf


RX63NのSCIcのTENDフラグの説明
www.renesas.com/jp/ja/doc/products/mpumcu/doc/rx_family/r01uh0041jj0180_rx63n631.pdf


RX65NのSCIgのTENDフラグの説明
www.renesas.com/jp/ja/doc/products/mpumcu/doc/rx_family/r01uh0590jj0210-rx651.pdf


RX65Nのレベル検出割り込みの説明 (上の説明内で参照するよう指示されている)


RX65NのI/Oレジスタ書き込み時の注意事項の説明 (上の説明内で参照するよう指示されている)


RX65NのSCIgの割り込みの説明 (ここにもTENDフラグと割り込みの話が書かれていることに気付いたので)


[余談]

RX65NのTBボードで調べるのに使用した端子(というかボードのスルーホール)の場所の写真

Parents
  • こんにちは。NoMaYです。

    RX210のハードウェアマニュアルでは、以下の画面コピーの通り、TDRレジスタにライトした後に、SSRレジスタをリードして、更にリード値で何らかの演算をせよ、との指示があります。今回、この演算の有無と送信終了割り込み要求取り消しタイミングとの関係を、今までと同じ手法で調べてみました。(この演算の役割は先日の投稿に書いた通りです。) 次は、ボーレートを変えたり、ICLKとPCLKの比を変えたり、等してみようと思っています。(その後、無茶なDMAの使い方をして、内蔵周辺回路バスを渋滞させて、挙動を調べてみることにトライしてみようかとも思っています。)

    プロジェクトのファイル一式 (先日のプログラムを改造、RX631のGR-CITRUSとRX65NのTBボード、CS+プロジェクト(rcpe同梱))
    issue_20190221.zip

    RX210のSCIcのTENDフラグの説明 (赤枠は私によるものです。)
    www.renesas.com/jp/ja/doc/products/mpumcu/doc/rx_family/r01uh0037jj0150-rx210.pdf


    今回は以下の少し変なインラインアセンブラ関数を使用(使い捨てるつもりで'_'という名前にしてあります)

    #pragma inline_asm _
    void _(uint32_t data)
    {
    }

    リードと演算有りの場合

        /* 動作OK */
        SCI0.TDR = data;            /* 送信&送信終了フラグクリア @ SCI */
        _(SCI0.SSR.BYTE & 0x04);
        setpsw_i();                 /* 割り込み許可 @ CPU */
        MOV.B R1, 01H[R2]
        MOVU.B 02H[R2], R1
        AND #04H, R1
        SETPSW I

    リードのみ(演算無し)の場合

        /* 動作NG */
        SCI0.TDR = data;            /* 送信&送信終了フラグクリア @ SCI */
        _(SCI0.SSR.BYTE);
        setpsw_i();                 /* 割り込み許可 @ CPU */
        MOV.B R1, 01H[R2]
        MOVU.B 02H[R2], R1
        SETPSW I

    リードのみ(演算無し)でNOP 5個の場合

        /* 動作NG */
        SCI0.TDR = data;            /* 送信&送信終了フラグクリア @ SCI */
        _(SCI0.SSR.BYTE);
        nop5();                     // 参考情報:以前のSSRリード無しの場合ではNOP 6個だった
        setpsw_i();                 /* 割り込み許可 @ CPU */
        MOV.B R1, 01H[R2]
        MOVU.B 02H[R2], R1
        NOP
        NOP
        NOP
        NOP
        NOP
        SETPSW I

    リードのみ(演算無し)でNOP 6個の場合

        /* 動作OK */
        SCI0.TDR = data;            /* 送信&送信終了フラグクリア @ SCI */
        _(SCI0.SSR.BYTE);
        nop6();                     // 参考情報:以前のSSRリード無しの場合ではNOP 7個だった
        setpsw_i();                 /* 割り込み許可 @ CPU */
        MOV.B R1, 01H[R2]
        MOVU.B 02H[R2], R1
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        SETPSW I

     

Reply
  • こんにちは。NoMaYです。

    RX210のハードウェアマニュアルでは、以下の画面コピーの通り、TDRレジスタにライトした後に、SSRレジスタをリードして、更にリード値で何らかの演算をせよ、との指示があります。今回、この演算の有無と送信終了割り込み要求取り消しタイミングとの関係を、今までと同じ手法で調べてみました。(この演算の役割は先日の投稿に書いた通りです。) 次は、ボーレートを変えたり、ICLKとPCLKの比を変えたり、等してみようと思っています。(その後、無茶なDMAの使い方をして、内蔵周辺回路バスを渋滞させて、挙動を調べてみることにトライしてみようかとも思っています。)

    プロジェクトのファイル一式 (先日のプログラムを改造、RX631のGR-CITRUSとRX65NのTBボード、CS+プロジェクト(rcpe同梱))
    issue_20190221.zip

    RX210のSCIcのTENDフラグの説明 (赤枠は私によるものです。)
    www.renesas.com/jp/ja/doc/products/mpumcu/doc/rx_family/r01uh0037jj0150-rx210.pdf


    今回は以下の少し変なインラインアセンブラ関数を使用(使い捨てるつもりで'_'という名前にしてあります)

    #pragma inline_asm _
    void _(uint32_t data)
    {
    }

    リードと演算有りの場合

        /* 動作OK */
        SCI0.TDR = data;            /* 送信&送信終了フラグクリア @ SCI */
        _(SCI0.SSR.BYTE & 0x04);
        setpsw_i();                 /* 割り込み許可 @ CPU */
        MOV.B R1, 01H[R2]
        MOVU.B 02H[R2], R1
        AND #04H, R1
        SETPSW I

    リードのみ(演算無し)の場合

        /* 動作NG */
        SCI0.TDR = data;            /* 送信&送信終了フラグクリア @ SCI */
        _(SCI0.SSR.BYTE);
        setpsw_i();                 /* 割り込み許可 @ CPU */
        MOV.B R1, 01H[R2]
        MOVU.B 02H[R2], R1
        SETPSW I

    リードのみ(演算無し)でNOP 5個の場合

        /* 動作NG */
        SCI0.TDR = data;            /* 送信&送信終了フラグクリア @ SCI */
        _(SCI0.SSR.BYTE);
        nop5();                     // 参考情報:以前のSSRリード無しの場合ではNOP 6個だった
        setpsw_i();                 /* 割り込み許可 @ CPU */
        MOV.B R1, 01H[R2]
        MOVU.B 02H[R2], R1
        NOP
        NOP
        NOP
        NOP
        NOP
        SETPSW I

    リードのみ(演算無し)でNOP 6個の場合

        /* 動作OK */
        SCI0.TDR = data;            /* 送信&送信終了フラグクリア @ SCI */
        _(SCI0.SSR.BYTE);
        nop6();                     // 参考情報:以前のSSRリード無しの場合ではNOP 7個だった
        setpsw_i();                 /* 割り込み許可 @ CPU */
        MOV.B R1, 01H[R2]
        MOVU.B 02H[R2], R1
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        SETPSW I

     

Children
No Data