こんにちは。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です。RX210のハードウェアマニュアルもRX63Nのハードウェアマニュアルも、注意を喚起したかったのは、実は、RX65Nのハードウェアマニュアルが喚起しているレベル検出割り込みの注意事項だったのではなかろうか、という気がし始めていますので、そのレベル検出割り込みの注意事項の現象が実際にSCIgやSCIcで起きるかどうか、調べてみました。結果、RX65NのTBボードでは何事も無かったプログラムがRX631のGR-CITRUSでは確かに偽の送信終了割り込みを発生させる現象を起こしてしまうことが分かりました。(次はハードウェアマニュアル記載の回避手段を確認してみようかと思っています。)プロジェクトのファイル一式 (先日のプログラムを改造、RX631のGR-CITRUSとRX65NのTBボード、CS+プロジェクト)issue_20190217.zip 入れるlstファイルを間違えたので以下へ差し替えました 2019/02/18 1:00issue_20190217.zipRX65Nでは何事も無く動作したプログラム
PORT3.PMR.BYTE |= 0x04U; /* 端子設定 @ PORT */ SCI6.SCR.BIT.TE = 1U; /* 送信許可 @ SCI */ clrpsw_i(); /* 割り込み禁止 @ CPU */ SCI6.SCR.BIT.TEIE = 1U; /* 送信終了割り込み許可(送信終了割り込み信号出力許可) @ SCI */ nop100(); /* 送信終了割り込み信号伝達待ち(取り敢えず NOP 100個) @ SCI → INTC */ /* 動作OK */ SCI6.TDR = data; /* 送信&送信終了フラグクリア @ SCI */ setpsw_i(); /* 割り込み許可 @ CPU */
同等のプログラムでもRX631では偽の送信終了割り込みが発生してしまって動作しない
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 */ /* 動作NG */ SCI0.TDR = data; /* 送信&送信終了フラグクリア @ SCI */ setpsw_i(); /* 割り込み許可 @ CPU */
幾つかNOPを入れて確かめてみると、NOP 6個ではNGでしたがNOP 7個ではOKになりました。NOP 6個 ⇒ 動作NG (まだsetpsw_i()のタイミングが早いため偽の送信終了割り込みが発生する)
/* 動作NG */ SCI0.TDR = data; /* 送信&送信終了フラグクリア @ SCI */ nop6(); /* NOP 6個 ⇒ 送信前に偽の送信終了割り込み発生 ⇒ 動作NG */ setpsw_i(); /* 割り込み許可 @ CPU */
NOP 7個 ⇒ 動作OK (充分setpsw_i()のタイミングが遅いため偽の送信終了割り込みが発生しない)
/* 動作OK */ SCI0.TDR = data; /* 送信&送信終了フラグクリア @ SCI */ nop7(); /* NOP 7個 ⇒ 送信前に偽の送信終了割り込み無し ⇒ 動作OK */ setpsw_i(); /* 割り込み許可 @ CPU */
なお、添付したプロジェクトですが、動作OKの場合と動作NGの場合で、それぞれTeraTermの表示内容が以下の画面コピーのようになります。動作OKの場合動作NGの場合(何も表示されない)[追記]朝になって気付いたのですが、RX65NのTBボードでプログラムが何事も無く動作したのは、もしかすると、RX65Nでは送信終了割り込みがグループ割り込みになっているからかも知れません。つまり、setpsw_i()の後に実際は偽の送信終了割り込み要因でグループ割り込みが発生してしまっているけれども、グループ割り込み処理ルーチン内で要因判定しようとしている箇所が実行されるタイミングでは、その偽の送信終了割り込み要因は既に降りていて、送信終了割り込み処理ルーチンが実行されずに済んでいたのかも知れません。後で、調べてみます。
eLeMさん、こんにちは。NoMaYです。この7クロックというのは、内蔵周辺回路のレベル割り込み信号出力が、CPUが内蔵周辺回路にライトしたことで出力が変化して、それが割り込みコントローラを経由し、CPUに認識されるまでの(RX631に於いてのSCIのTENDでの)遅延です。ある端子へのポート出力を別の端子からのポート入力で読む場合は、また違う遅延のカラクリになってしまう筈です(あるいは遅延が無い可能性もあります)。きっと、事例ごとに確認するしかないのだろうな、という気がします。ですが、今回、ハードウェアマニュアルを読んでいて、RXマイコンにはバスアクセスの高速化手法として色々な事例に共通的に影響する以下のような手法が採用されているらしい、ということを認識するようになりました。(1) CPUが(少なくとも?)内蔵周辺回路バスでライトアクセスする際には1エントリのライトバッファが使われるらしい(1-A) CPUはライトバッファにアドレスとデータをラッチさせるところまでしかケアしない(1-B) CPUは、ラッチさせたら、さっさと次の命令実行に移ってしまう(1-C) ラッチされたアドレスとデータに従って、内蔵周辺回路バスが自立的にライトアクセスを開始→完了させる(2) CPUは内蔵周辺回路バス(に限らず?)でリードアクセスする際にはリードアクセスの完了を待たないらしい(2-A) CPUはリードすべきアドレスを内蔵周辺回路バスに引き渡すと、とりあえず次の命令実行に移ってしまう(2-B) 内蔵周辺回路バスは自立的にリードアクセスを開始→完了させるべく動作する(2-C) CPUは、演算等で本当にリードデータが必要になった時にリードアクセスが未完了だった時、ようやく命令実行に「待ち」が生じる(3) 上記の(1-C)も(2-B)も開始されないまま命令実行が先へ先へと進んでいくことがあるらしい(3-A) 上記の(1-C)と(2-B)の順序は維持される筈(?)(3-B) (1-C)が完結してから(2-B)が開始される筈(?)そして、これらに加えて、SCIのTENDの割り込みでは、信号が割り込みコントローラを通り抜ける時間も関係してくるだろうと思われます。他方、IOポートの場合は、上記の(3-B)により遅延は生じないかも知れません。
リカルドさん、こんにちは。NoMaYです。> ボーレイトにも関係するかも知れませんよ。ボーレイトを遅くしてテストしてみたらどうでしょう。あと、PCLKも関係するかも知れないような気がします。追々調べてみようかと思います。それと、ハードウェアマニュアル上は、命令実行と割り込み発生/割り込み要求取り消しのタイミングのズレの回避手段(命令実行が先に進まないように待たせる手段)は、前の投稿に書いた(2-C)ということになっていますので、それも調べてみようかと思います。(でも、あれっ、信号が割り込みコントローラを通り抜ける時間に関しては?という気がしなくもないですが、、、)