こんにちは
G10にてCS+のコード生成プラグインのR_IICA0_Slave_Sendを使用して送信をしようと思っています。
二つ目の引数に2を入れて送信したところ、受け側は0xXX 0xFFとなります。1バイト目は〇なのですが、
2バイト目が0xFFになります。どのようなことが考えられますか?
チョコです。
何か誤解があるようなので、少しコメントしておきます。
I2Cバスの仕様では、マスタが受信(スレーブ送信)を終了するときには、スレーブから受信した最後のデータに対してACK応答をしない(NACK応答をする)という規定があります。これは、I2Cバスのハード的な制約(信号がローに引かれた状態は、マスタといえどもハイにすることはできない)に対するもので、「受信を終了するからスレーブにそれ以上データを送るな…
具体的にどのようなタイミングで、どのようにデータを確認しているのでしょうか。
R_IICA0_Slave_Sendや対になったR_IICA0_Master_Receiveで通信が完了したことをどのようにして判断しているのでしょうか。
わたしは、基本的に、コード生成されたAPI関数は使えないと判断して、初期設定だけしか使っていません。(それ以外の部分は自前で作成しています。)コード生成されたコードの問題点として、昔から指摘しているのが、通信の完了をきちんとサポートすべきだということです。これは、他の通信でも共通している内容です。
具体的なプロジェクトを開示(zipで固めて添付)してもらえれば、チェックしてみますが。
以上
初期設定して自前で作る実力をつけたいです。
ところで、今回の相手はルネさんでないです。たぶんマスターとして動作しています。2バイトを読む感じです。
通信の完了が大切ということですが、RL78はひたすら送信です。
uint16_t tx_num=2; uint8_t tx_data[]={0}; tx_data[0]=0x20; tx_data[1]=0x40; f=0; R_IICA0_Slave_Send(tx_data,tx_num); R_IICA0_Set_WakeupOn();//r_iica0_callback~が発生したら終了か待機R_IICA0_Set_WakeupOff();
0x40が相手さんでは0xFFとなっています。相手が悪いという線も並行して考えています。
データが0xFFと言うのは、2バイト目でスレーブは通信を中止しているのではないかと疑っていました。
「uint8_t tx_data[]={0};」できちんと2バイト分のバッファは確保されていないのではないでしょうか。
ここは、
uint8_t tx_data[]={0x20,0x40};
としてみてはいかがでしょうか。
提示されたプログラムで、「R_IICA0_Set_WakeupOn()」とありますが、コード生成したINTIICA0の割り込みハンドラーではウェイクアップ機能には対応していません。また、このプログラムではSTOPモードを使っていないようなので、こんな処理は無意味です。
>//r_iica0_callback~が発生したら終了か待機
これは具体的にどのようにされているのでしょうか。callbackをきちんと処理されていない場合に問題が起こるのですが。具体的に言えば、送信完了のcallbackで終了フラグをセットして、そのフラグがセットされるのを提示されたプログラムが待つようにする必要があります。
>0x40が相手さんでは0xFFとなっています。相手が悪いという線も並行して考えています。
I2Cバスの波形は確認されないのでしょうか。波形を確認すると、どちらに問題があるかは切り分けられると思います。
ところで、スレーブの仕様としては、必ず2バイト送信するようになっているのでしょうか。マスタが1バイトで受信をやめることを許していますか。
助言ありがとうございます。手直ししました。
R_IICA0_Set_WakeupOn、WakeupOff(を外すと相手はアイドル状態とビジー状態に
なっているみたいです。波形を確認したいのですが、アナログオシロを使っているのですが
私の腕では見にくいです。
uint16_t tx_num=2; uint8_t tx_data[2]={0x20,0x40}; f=0; R_IICA0_Slave_Send(tx_data,tx_num); //ファーストモード ディジタルフィルターオン //R_IICA0_Set_WakeupOn(); while(f!=11){ //callback_slave_receiveendがあったら抜ける if(f==99){ //callback_slave_errorが発生したら NOP(); return; }else{ R_WDT_Restart(); } } //R_IICA0_Set_WakeupOff(); NOP();
>R_IICA0_Set_WakeupOn、WakeupOff(を外すと相手はアイドル状態とビジー状態に
>なっているみたいです。
それは、普通ではないのでしょうか?そもそも、wakeupはRL78のIICA0のスレーブで、STOPモードを使えるようにするための機能で、I2Cバスから先には関係ないはずです。
>波形を確認したいのですが、アナログオシロを使っているのですが
デジタルオシロだったらよかったのですが、アナログのオシロでは通信波形は難しいですね。スレーブ送信だと、2バイト目以降については、マスタはスレーブの状態(通信していない)が分からないですからSDA信号で確認したかったのですが。
>while(f!=11){ //callback_slave_receiveendがあったら抜ける
これだと、受信完了のcallbackではないですか?
もう一ヵ所気になりました。以下に示すのは、おそらく、マスタからのNACK応答だと思うのですが、これは正常終了するところですが、returnでいいのですか?
if(f==99){ //callback_slave_errorが発生したら NOP(); return;
コメントの間違いっぽいです。すみませんでした。
static void r_iica0_callback_slave_error(MD_STATUS flag){ f=99;}
static void r_iica0_callback_slave_receiveend(void){ f=1;}
static void r_iica0_callback_slave_sendend(void){ f=11;}
flag=2
なのでNACKでしょうか。
I2Cバスの仕様では、マスタが受信(スレーブ送信)を終了するときには、スレーブから受信した最後のデータに対してACK応答をしない(NACK応答をする)という規定があります。これは、I2Cバスのハード的な制約(信号がローに引かれた状態は、マスタといえどもハイにすることはできない)に対するもので、「受信を終了するからスレーブにそれ以上データを送るな」の意味を持っています。こうすることで、マスタはI2Cバスを制御できるようになり、次の処理(ストップコンディションの発行)を行えるようになります。
初心者は、「受信したデータがおかしいからNACK応答になった」とよく誤解しているようですが、それは間違いです。
と言うことで、スレーブでは「f=99」が正常な終わり方です。以前のコメントの最後で「スレーブの仕様としては、必ず2バイト送信するようになっているのでしょうか。マスタが1バイトで受信をやめることを許していますか。」と書いたのは、このようなI2Cバスの仕様に沿っているかを確認したかったからです。
なお、RL78/G10をI2Cバスのスレーブとして使用した例は、以下の所にあります。
かふぇルネの「Forums & Groups」をクリックして、
その飛び先のページの一番下の「サンプルプログラム等」をクリックした先にあります。
ここから行ってもいいのですが、RL78/G10をI2Cバスのスレーブとして使用した例は、接以下のURLで飛べます。
https://community-ja.renesas.com/cafe_rene/m/sample_program/283
ここにアップされているzipファイルをダウンロードするとプロジェクトと説明のpdfがあります。
RL78/G10のIICA0のスレーブプログラムの例で、出力としてのLED,読み出し用のA/D、読み書きの対象としてのRAMがサポートされています。ちなみにコード生成は初期設定だけで、IICA0の制御は、r_iica0_lib.cとして準備されています。
I2Cの勉強をするなら、「サンプルプログラム等」にかなりプログラムや解説を投稿していますので、参考になると思います。
リンク先ありがとうございます。