こんにちは。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です。以前の投稿で、RX631では動作しなかったプログラムと同等の以下のプログラムがRX65NのTBボードで何事も無く動作したのは、もしかすると、RX65Nでは送信終了割り込みがグループ割り込みになっているからかも知れない、と書いたのですが、それを確かめてみました。結果、やはりそういうことでした。プロジェクトのファイル一式 (先日のプログラムを改造、RX65NのTBボード、CS+プロジェクト)issue_20190220.zip以前の投稿でRX65Nでは何事も無く動作してしまったプログラム???
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 */
今回、グループ割り込みと送信終了割り込みを実験用に以下のように変更src/smc_gen/r_bsp/mcu/rx65n/mcu_interrupts.c (元々のグループ割り込みハンドラを削除)
#if 0 /* toriaezu */#pragma interrupt group_bl0_handler_isr(vect=VECT(ICU,GROUPBL0))void group_bl0_handler_isr (void){ if (1 == ICU.GRPBL0.BIT.IS1) { R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI0_ERI0, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR); } if (1 == ICU.GRPBL0.BIT.IS0) { R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI0_TEI0, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR); }途中省略 if (1 == ICU.GRPBL0.BIT.IS13) { R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI6_ERI6, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR); } if (1 == ICU.GRPBL0.BIT.IS12) { R_BSP_InterruptControl(BSP_INT_SRC_BL0_SCI6_TEI6, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR); }途中省略 if (1 == ICU.GRPBL0.BIT.IS29) { R_BSP_InterruptControl(BSP_INT_SRC_BL0_DOC_DOPCI, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR); } if (1 == ICU.GRPBL0.BIT.IS31) { R_BSP_InterruptControl(BSP_INT_SRC_BL0_PDC_PCERI, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR); } if (1 == ICU.GRPBL0.BIT.IS30) { R_BSP_InterruptControl(BSP_INT_SRC_BL0_PDC_PCFEI, BSP_INT_CMD_CALL_CALLBACK, FIT_NO_PTR); }}#endif
src/smc_gen/Config_SCI6/Config_SCI6_user.c (グループ割り込みハンドラを送信終了割り込み処理で代用)
#if 1 /* toriaezu */#pragma interrupt r_Config_SCI6_transmitend_interrupt(vect=VECT(ICU,GROUPBL0))#endifvoid r_Config_SCI6_transmitend_interrupt(void){ PORT3.PMR.BYTE &= 0xFBU; SCI6.SCR.BIT.TIE = 0U; SCI6.SCR.BIT.TE = 0U; SCI6.SCR.BIT.TEIE = 0U; r_Config_SCI6_callback_transmitend();}
結果、RX65NでもRX631と同じ以下のようになったNOP 0個 ⇒ 動作NG
/* 動作NG */ SCI6.TDR = data; /* 送信&送信終了フラグクリア @ SCI */ /**/ /* NOP 0個 ⇒ 送信前に偽の送信終了割り込み発生 ⇒ 動作NG */ setpsw_i(); /* 割り込み許可 @ CPU */
NOP 6個 ⇒ 動作NG
/* 動作NG */ SCI6.TDR = data; /* 送信&送信終了フラグクリア @ SCI */ nop6(); /* NOP 6個 ⇒ 送信前に偽の送信終了割り込み発生 ⇒ 動作NG */ setpsw_i(); /* 割り込み許可 @ CPU */
NOP 7個 ⇒ 動作OK
/* 動作OK */ SCI6.TDR = data; /* 送信&送信終了フラグクリア @ SCI */ nop7(); /* NOP 7個 ⇒ 送信前に偽の送信終了割り込み無し ⇒ 動作OK */ setpsw_i(); /* 割り込み許可 @ CPU */