こんにちは、ユキと申します。
RL78/G13のCSIで、バッファ空き割込みを使った連続送受信をマスタとして行うときのことについてご教授いただけないでしょうか。コンパイラはCC-RL、IDEはe2studioを使用しております。
現在、コード生成を使い、CSI21を以下のような設定で動作させようとしています。
転送モード:連続転送モードデータ長:8ビットデータ転送方向:MSBデータ送受信タイミング:タイプ4転送レート: クロック・モード:内部クロック(マスタ) ボー・レート:2000000bps通信完了割り込み優先順位:低コールバック機能設定:すべて有効
コード生成を実行した上で、自分のコードでR_CSI21_Send_Receive()を呼び出しているのですが、以下のような現象が起きています。
・1バイトのデータを送信した時は通信が成功する・2バイト以上のデータを送信するとオーバーランエラーが発生する・シングル転送モードを使った場合は、2バイト以上のデータを送信してもオーバーランエラーは発生しない
そして、r_cg_serial_user.cのr_csi21_interrupt()の、
if (g_csi21_tx_count > 0U) { if (g_csi21_tx_count != (g_csi21_send_length - 1U)) { *gp_csi21_rx_address = SIO21; gp_csi21_rx_address++; } SIO21 = *gp_csi21_tx_address; gp_csi21_tx_address++; g_csi21_tx_count--; }上記のコードを以下のように書き換えてみると、オーバーランエラーが発生しなくなりました。
if (g_csi21_tx_count > 0U)
{
if (g_csi21_tx_count != (g_csi21_send_length - 1U))
*gp_csi21_rx_address = SIO21;
gp_csi21_rx_address++;
}
SIO21 = *gp_csi21_tx_address;
gp_csi21_tx_address++;
g_csi21_tx_count--;
if (g_csi21_tx_count > 0U) { *gp_csi21_rx_address = SIO21; gp_csi21_rx_address++; SIO21 = *gp_csi21_tx_address; gp_csi21_tx_address++; g_csi21_tx_count--;}
期待通りの動作をするようになったものの、何故こうなるのか理解できておりません。上記はコード生成でできるコードなので、私の使い方が間違っている気がするのですが……
バッファオーバーランが起きる時、送信データの1バイト目を書き込んだ後の最初のバッファ空き割込みで、実際にはSDRにデータが存在するような動作をしているように見えます。
しかし、ハードウェアマニュアルを読むと、送信データの1バイト目を書き込んだ後の最初のバッファ空き割込みでは、データを受信していないし、バッファ空き割込みなのだからSDRは空いている。何もせずに2バイト目のデータをSDRに書き込んで良いというように読み取れました。
私の理解は正しいのでしょうか。そして、何故このような動作をするのでしょうか。ご助言をいただけると嬉しいです。
足りない情報がございましたら、おっしゃってください。
よろしくお願いいたします。
ユキさん、こんにちは。NoMaYと申します。チョコさんも、こんにちは。横から失礼します。ユキさんはコンパイラの最適化レベルを何に設定してコンパイルされていますか? ユキさんも書かれているように> 転送速度が2Mbpsですから、1バイト転送するのに掛かる時間は4usですよね。> CPUのクロックは高速オンチップオシレータクロックで低速メインモード、周波数は8MHzですが、ですので、1命令=1クロックとしても8命令/us × 4us = 32命令ですね。他方、チョコさんの場合は以下になりますね。> RL78/G12(24MHzの動作クロック)のCSI00をタイプ4に設定して,6Mbpsの転送速度で送信して正常に送信できています24命令/us × 1s/6Mbps × 8bit = 32命令両者同じで間に合っても良さそうですが、いかんせん32命令分しかありません。コンパイラの最適化レベルの違いで、間に合う/間に合わないが変わることもあり得そう、な気がしました。(割り込み発生時のスタックへのPUSHや復帰時のスタックからのPOPもありますので、実際は、もっと少ない命令しか実行することが出来ない、と思います。)また、32命令という少なさで処理が間に合う/間に合わないを試行錯誤する場合は、生成されたコードをアセンブラレベルで確認しながらやらないと、うまくいかないような気がします。(と言うか、もうアセンブラ記述しないと(インラインアセンブラでも可ですが)、コンパイラの生成コードが変わった時に動かなくなったりしないか、やっぱり気になってしまいます。)