初めてお世話になります。axonteraです。
RL78/G13を7つ使って、マスタ1、スレーブ6のCSI通信を行おうとしていますが、うまくいっていません。【症状】・マスタから送信したデータが1バイト遅れてマスタの受信データになる・スレーブ側はオーバーランエラーが出て送受信できていない【条件】・マスタ、スレーブともコード生成を使用・通信条件(CSI00):シングル転送モード、8ビット、MSB、タイミングタイプ1、312500bps、割り込み優先度レベル2・マスタでCS後、100usのディレイ後に送受信開始(R_CSI_Send_Receive実行)・スレーブ側はCSを検知してすぐに送信バッファ(配列変数)にデータ格納し、続いてR_CSI_Send_Receive実行
現在はスレーブを1つにして、他の5つのスレーブはR_CSI_Createを実行せず、P10とP12をNchオープンドレインに設定したところ、SI00(マスタ)が0固定になってしまいました。そこで上記5つのスレーブでPM1 = 0x02、P1 = 0x05を追記して出力を1にしてみましたが、今度は立ち上がりの鈍い波形になり、マスタのマイコンが熱くなって(60℃くらい)しまいました。その鈍い波形もやはり当初の1バイト遅れデータのように見えます。
何か思い当たるアドバイスがあればお願いいたします。
チョコです。
具体的にどのような設定にしているかがよく読み取れません。
>他の5つのスレーブはR_CSI_Createを実行せず、P10とP12をNchオープンドレインに設定
これは、N-chオープンドレイン出力に設定したということでしょうか。全てのスレーブのCSI00の端子が接続されているならば、スレーブがSCKに出力すること自体が問題です。また、CSで選択されていないのにSO00に出力することが間違いです。
>今度は立ち上がりの鈍い波形になり、マスタのマイコンが熱くなって(60℃くらい)しまいました。
CSIの出力はCMOS出力です。マスタがSCKにハイを出力しても、スレーブがローにひっぱている(または、逆の組み合わせ)ので、出力同士がショートして、熱くなっているのではないですか。
CSで、選択されていないスレーブはCSIを停止して、SOはHi-Z(つまりは入力モード)にしてください。CSで選択されたスレーブはCSの立下りを検出したらSOを出る奥に設定してCSIの動作をスタートさせてください。
また、どのように接続しているのかを確認する必要もあります。そのうえでどのように制御しているかを確認する必要があります。
RL78/G13で適当なアプリケーションノートがないので、「RL78/G10 シリアル・アレイ・ユニット(CSIマスタ通信) CC-RL」(R01AN3076)のアプリケーションノートを参考にしてみてください。なお、RL78/G10はROMが小さいので、プログラムはアセンブラだったはずです。
詳しい情報が分かれば、きちんとしてコメントができると思います。出来れば、回路図とプロジェクトをzipで固めて添付してください。
以上
早速のご回答ありがとうございます。そしてわかりにくくてすみません。
昨日実験をやり直した内容をまとめます。・スレーブ6個のうち5個をリセット状態にした・コード生成のポート(スレーブ)、CSI00(スレーブ、マスタ)を以下のように設定 これでスレーブにおけるxSCK00、SI00は入力、SO00はNchオープンドレインになっているという認識です。・SO00(スレーブ基準)のプルアップ抵抗を100KΩ → 1KΩに変更
これらの変更で、マスタマイコンが熱くなるのとSO00(スレーブ基準)波形の立ち上がりが鈍いのは解消できました。ただ、まだスレーブでオーバーランが発生します。(スレーブのr_csi00_interrupt()の頭に"SIR00 = 1"と書いて、強引にエラーを消して動作確認しています。)回路図とプロジェクトをまるまる公開は難しいので、回路図で関係していそうな部分の切り抜きと、プログラムの関係していそうな部分を抜き出します。(zip添付はよくわかりませんでした)バスのプルアップは100KΩ(SI00のみ1KΩ)です。--- マスタ側プログラム ---(この前にTxBuf[]には18個のデータを格納済み。R_CSI_Startも実行済み)
CSmoni5 = 0; // デバッグのためスレーブ5だけ
Delay_us(100); // サブマイコンの準備待ち 100usstatus = R_CSI00_Send_Receive(&com0.TxBuf[0], 18, &com0.RxBuf[0]); check_TxComp_CSI00(); // r_csi00_callback_sendend()待ち check_RxComp_CSI00(); // r_csi00_callback_receiveend()待ちCSmoni5 = 1;
--- スレーブ側プログラム ---if(!CSmoni) { R_CSI00_Start(); SetSendDataCSI00(); // TxBuf[]にデータ格納 memset( &com0.RxBuf[0], 0, 18 ); // 受信バッファクリア status = R_CSI00_Send_Receive(&com0.TxBuf[0], 18, &com0.RxBuf[0]); check_TxComp_CSI00(); // r_csi00_callback_sendend()待ち check_RxComp_CSI00(); // r_csi00_callback_receiveend()待ち}アプリケーションノートもこれから見てみます。よろしくお願いいたします。
回路を眺めたところ、マスタのCS信号出力にN-chオープンドレインのP60とP61を使っているようですが、プルアップ抵抗が100kΩというのは、大きすぎです。
それと、スレーブが準備できる前にマスタが通信を開始することはないでしょうか。
R_CSI00_Send_Receiveの引数に、「&com0.TxBuf[0]」や「 &com0.RxBuf[0]」の表現がありますが、com0は構造体で定義しているのでしょうか。
スレーブはCSをポーリングで待っているようですが、応答時間は100μsで大丈夫でしょうか。
チョコさん、ご確認ありがとうございます。
スレーブの準備ができる前にマスタのクロックが来ないように100usのディレイを設定しました。それを確認するために、念のためディレイを150usにして、スレーブのR_CSI_Send_Receive()の直前に空きピンをハイにし、同関数後にローにした時の波形を以下に示します。(緑が空きピンP21、ピンクがxSCK00です)
--- プログラム(スレーブ) ---P2_bit.no1 = 1; status = R_CSI00_Send_Receive(&com0.TxBuf[0], 18, &com0.RxBuf[0]);P2_bit.no1 = 0;
これを見ると同関数の呼び出し後にxSCK00が始まっているように見えます。この時も問題は解決していません。
あ、ご推察の通りcom0はCSI00の構造体です。
CSのプルアップ抵抗については残りのスレーブを復活させたときに検討しますが、今回生かしているスレーブ5はP20を使っているので1usくらいで遷移しているようです。
よろしくお願いいたします。
>まだスレーブでオーバーランが発生します。
割り込み禁止期間があるのではないでしょうか。
明日は忙しいので、明後日にでもテスト用のプロジェクトを作成してみようと思います。
コード生成されたINTCSIの割り込み処理を眺めたところ、マスタもスレーブも同じ処理のようでした。一方、RL78/G10シリアル・アレイ・ユニット(CSIスレーブ通信) CC-RL(R01AN3077JJ0110)を参照していたのですが、以下のように1バイトの通信ごとにBUSY信号でハンドシェイクしています。
スレーブがセンサやEEPROM等のように、ハードウェアで通信処理を行っている場合にはコード生成の処理でもいいのですが、スレーブがMCUのようにソフトで処理している場合には、スレーブでの処理がマスタに間に合わないことが考えられます。これが、今回の問題の原因ではないかと思われます。
ハンドシェイク処理を追加するのは大変なので、マスタ側の割り込み処理の通信起動を遅延させることを考えてみます。該当する部分を赤で囲んでいます。
この処理の前(88行目)に遅延処理を追加してください。ソフトウェアタイマでもいいですから、1~10μs程度のループを入れてみてください。これで、スレーブの処理時間が稼げるので、通信がうまくいく可能性があります。
なお、ここは、コード生成を行うと消されてしまうので、コード生成後は毎回追加してください。
これから環境を作って、試してみようと思います。
チョコさん、お忙しい中ありがとうございます。
マスタ側とはまた思いもよらないところ(@_@こちらで1,5,10usのディレイを試してみたところ、いずれも1バイトだけ受信したらあとはSI00(マスタ基準)がハイ固定になっています。(ピンク:SI00、緑:xSCK00)
取り急ぎご報告まで。これから解析してみます。
>・マスタから送信したデータが1バイト遅れてマスタの受信データになる
この理由が分かったような気がします。
スレーブが、マスタからの1バイト目を受信すると、シフトレジスタには受信データが入り、そのデータがSDRレジスタに転送されます。
この状態で、スレーブが新しいデータを書き込む(次の通信準備をする)と、次の通信ではスレーブが書き込んだデータがシフトレジスタに転送されてこのデータがマスタに送信されます。
もし、スレーブが新しいデータを書き込む前にマスタが次の通信を開始すると、シフトレジスタの値(つまりは、前回マスタが送信したデータ)が送信されます。
このため、「マスタから送信したデータが1バイト遅れてマスタの受信データになる」という現象になっている考えられます。
この対策としては、「マスタが次のデータを通信する前に、スレーブの準備ができるまで遅延を挿入する。」となります。このための確実な方法はRL78/G10のアプリケーションノート(R01AN2759JJ0201)にあるようなハンドシェイク信号を追加することです。回路を変更するのは大変ならば、前回紹介した「マスタ側でのソフトタイマでの遅延を追加する」ことです。これは、コード生成されたコードの修正が必要です。修正するたびに元に戻るので、面倒です。
そこで、マスタ側での通信データ数を1に設定して、必要な回数をループさせることが考えられます。そのループに遅延を入れれば、コード生成されたコードはいじる必要はなくなります。この方法を試してみてください。
入れ違いになったようです。
マスタに遅延を入れたら、1バイトで停止するとのことですが、SCKはマスタで送信データを書き込めば
次の通信が起動することで出力されるはずです。次のデータはきちんと書かれているかを念のために確認してください。
ところで遅延はソフトタイマですか、ハードのタイマでしょうか?
もし、ハードのタイマでの割り込み待ちならば、優先順位はINTCSIより高く設定して、INTCSI ではEI();は実行していますでしょうか?