こんにちは。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.pdfRX63NのSCIcのTENDフラグの説明www.renesas.com/jp/ja/doc/products/mpumcu/doc/rx_family/r01uh0041jj0180_rx63n631.pdfRX65NのSCIgのTENDフラグの説明www.renesas.com/jp/ja/doc/products/mpumcu/doc/rx_family/r01uh0590jj0210-rx651.pdfRX65Nのレベル検出割り込みの説明 (上の説明内で参照するよう指示されている)RX65NのI/Oレジスタ書き込み時の注意事項の説明 (上の説明内で参照するよう指示されている)RX65NのSCIgの割り込みの説明 (ここにもTENDフラグと割り込みの話が書かれていることに気付いたので)[余談]RX65NのTBボードで調べるのに使用した端子(というかボードのスルーホール)の場所の写真
こんにちは。NoMaYです。RXマイコンには、汎用レジスタを介すことなく1命令でメモリ間転送を行う命令があり、コンパイラが生成するコードでも使用されているのですが、それが前の投稿の「演算」の代役を果たせるかどうか気になったので試してみました。結果、命令実行は先へ先へと進んで行き、代役を果たせませんでした。(なお、RX631とRX65Nとでは、NOP 1個ですが、RX65Nの方が先へ進んで行くという違いがありました。)プロジェクトのファイル一式 (先日のプログラムを改造、RX631のGR-CITRUSとRX65NのTBボード、CS+プロジェクト(rcpe同梱))issue_20190223.zip今回は以下のdummyという変数を使用 (以下のソースはRX631版、RX65N版のソースも同様)
void R_Config_SCI0_Serial_Send_Test_TEI(uint8_t * const tx_buf){ uint8_t data = tx_buf[0]; volatile uint8_t dummy; PORT2.PMR.BYTE |= 0x01U; /* 端子設定 @ PORT */ SCI0.SCR.BIT.TE = 1U; /* 送信許可 @ SCI */ clrpsw_i(); /* 割り込み禁止 @ CPU */ SCI0.SCR.BIT.TEIE = 1U; /* 送信終了割り込み許可(送信終了割り込み信号出力許可) @ SCI */ nop100(); /* 送信終了割り込み信号伝達待ち(取り敢えず NOP 100個) @ SCI → INTC */
RX631の場合NOP無し
/* 動作NG */ SCI0.TDR = data; /* 送信&送信終了フラグクリア @ SCI */ dummy = SCI0.SSR.BYTE; setpsw_i(); /* 割り込み許可 @ CPU */
MOV.B R1, 01H[R2] MOV.B 02H[R2], 03H[R0] SETPSW I
NOP 3個
/* 動作NG */ SCI0.TDR = data; /* 送信&送信終了フラグクリア @ SCI */ dummy = SCI0.SSR.BYTE; nop3(); // 参考情報:以前のダミーリード無しの場合ではNOP 6個だった setpsw_i(); /* 割り込み許可 @ CPU */
MOV.B R1, 01H[R2] MOV.B 02H[R2], 03H[R0] NOP NOP NOP SETPSW I
NOP 4個
/* 動作OK */ SCI0.TDR = data; /* 送信&送信終了フラグクリア @ SCI */ dummy = SCI0.SSR.BYTE; nop4(); // 参考情報:以前のダミーリード無しの場合ではNOP 7個だった setpsw_i(); /* 割り込み許可 @ CPU */
MOV.B R1, 01H[R2] MOV.B 02H[R2], 03H[R0] NOP NOP NOP NOP SETPSW I
RX65Nの場合NOP無し
/* 動作NG */ SCI6.TDR = data; /* 送信&送信終了フラグクリア @ SCI */ dummy = SCI6.SSR.BYTE; setpsw_i(); /* 割り込み許可 @ CPU */
/* 動作NG */ SCI6.TDR = data; /* 送信&送信終了フラグクリア @ SCI */ dummy = SCI6.SSR.BYTE; nop4(); // 参考情報:以前のダミーリード無しの場合ではNOP 6個だった setpsw_i(); /* 割り込み許可 @ CPU */
NOP 5個
/* 動作OK */ SCI6.TDR = data; /* 送信&送信終了フラグクリア @ SCI */ dummy = SCI6.SSR.BYTE; nop5(); // 参考情報:以前のダミーリード無しの場合ではNOP 7個だった setpsw_i(); /* 割り込み許可 @ CPU */
MOV.B R1, 01H[R2] MOV.B 02H[R2], 03H[R0] NOP NOP NOP NOP NOP SETPSW I