お世話になります。
kukoと申します。
RX65NのRIIC0で通信中に、ノイズによってアービトレーションロストを検出するのですが、
このとき通信の終了処理として、ストップコンディションを実行して、終了したいのですが、
ストップコンディション要求をしても実行してくれません。
どのような手続きを行えば、ストップコンディションを実行してくれるのか、
ご教授いただきく、宜しくお願い致します。
RIIC0のドライバは、COnfig_RIIC0のver.1.4.0をベースとしています。
アービトレーションロスト検出時の各レジスタの状態は以下になります。
void r_Config_RIIC0_error_interrupt(void){ if ((1U == RIIC0.ICIER.BIT.ALIE) && (1U == RIIC0.ICSR2.BIT.AL)) {
//ここでブレークした際の、各レジスタの状態となります。
以上、宜しくお願い致します。
kukoさん
バスリセットをしてみてはいかがですか。
kukoさん、こんにちは。NoMaYと申します。バスリセットという操作が出来て、それにより解決しましたでしょうか?(実は、私ではお役に立てない、とは思っているのですけれども、どういう状況なのか気になりましたので。)
IKUZO様
kukoです。
アドバイスありがとうございます。
お返事が遅くなり申し訳ありません。
まだ試せてはいないのですが、バスリセットとは、RIIC0.ICCR1.IICRSTビットを1にする操作のことでしょうか?
ご教授のほど、宜しくお願い致します。
NoMaY様
まだ試せていない状況です。
別CPUの話なので、該当しないかもしれませんが IICRST をしてもストップコンディションはでませんでした。
IICで使っているポートを無理やり汎用IOにして、ポートをパタパタさせて、
ストップコンディションを出したことがあります。それでバス開放されます。
この中から見てください
/////////////////////////////////////////////////////////////////////////RIIC0の初期化 disp/////////////////////////////////////////////////////////////////////////SDA0 P13 44//SCL0 P12 45BOOL RIIC0_init(void){ SYS_PROTECT_OFF MSTP(RIIC0)=0; SYS_PROTECT_ON
//I/Oポート機能 PORT1.PMR.BIT.B2=0; //P12初期化 SCL1 PORT1.PMR.BIT.B3=0; //P13初期化 SDA1
MPC_PROTECT_OFF MPC.P12PFS.BYTE=0x0F; //P12 SCL1 MPC.P13PFS.BYTE=0x0F; //P13 SDA1 MPC_PROTECT_ON
PORT1.PDR.BIT.B2=1; //P12 SCL1->W PORT1.PDR.BIT.B3=0; //P13 SDA1->R
PORT1.PMR.BIT.B2=1; //P12 SCL1->peripheral. PORT1.PMR.BIT.B3=1; //P13 SDA1->peripheral.
RIIC0.ICCR1.BIT.ICE=0;//SCLn、SDAn端子非駆動状態 RIIC0.ICCR1.BIT.IICRST=1;//RIICリセット RIIC0.ICCR1.BIT.ICE=1;//内部リセット
RIIC0.ICSER.BIT.SAR0E=1;//スレーブアドレスレジスタ0有効 RIIC0.ICSER.BIT.SAR1E=0;//スレーブアドレスレジスタ1無効 RIIC0.ICSER.BIT.SAR2E=0;//スレーブアドレスレジスタ2無効 RIIC0.ICSER.BIT.GCAE=1;//ジェネラルコールアドレス有効 RIIC0.ICSER.BIT.DIDE=0;//デバイスIDアドレス検出無効 RIIC0.ICSER.BIT.HOAE=0;//ホストアドレス検出は無効
RIIC0.ICMR1.BIT.BC=0;//9ビットカウンタ RIIC0.ICMR1.BIT.BCWP=1;//BCライトプロテクト RIIC0.ICMR1.BIT.CKS=2;//PCLK/1クロック RIIC0.ICMR1.BIT.MTWP=0;//ICCR2.MST,TRSビット書き込み禁止
RIIC0.ICBRL.BIT.BRL=0x1F;//SCLクロックのLow幅の値 RIIC0.ICBRH.BIT.BRH=0x1F;//CLクロックのHigh幅の値
RIIC0.ICMR2.BIT.TMOS=0;//ロングモードタイムアウト検出時間 RIIC0.ICMR2.BIT.TMOL=0;//SCLnラインがLowでLカウント禁止 RIIC0.ICMR2.BIT.TMOH=0;//SCLnラインがHighでHカウント禁止 RIIC0.ICMR2.BIT.TMWE=0;//カウンタへの書き込み禁止 RIIC0.ICMR2.BIT.SDDL=0;//SDA出力遅延なし RIIC0.ICMR2.BIT.DLCS=0;//SDA出力遅延カウンタのクロックソースは内部基準クロック
RIIC0.ICMR3.BIT.NF=0;//フィルタは1段 RIIC0.ICMR3.BIT.ACKBR=0;//R アクノリッジビットに“0”を受信 RIIC0.ICMR3.BIT.ACKBT=0;//W アクノリッジビットに“0”を送出 RIIC0.ICMR3.BIT.ACKWP=1;//ACKBTビットへの書き込み許可 RIIC0.ICMR3.BIT.RDRFS=0;//8クロック目の立ち下がりでSCLnラインをLowにホールドしない RIIC0.ICMR3.BIT.WAIT=0;//9クロック目と1クロック目の間をLowにホールドしない RIIC0.ICMR3.BIT.SMBS=0;//I2C バス選択
RIIC0.ICFER.BIT.TMOE=0;//タイムアウト検出機能無効 RIIC0.ICFER.BIT.MALE=1;//マスタアービトレーションロスト検出許可 RIIC0.ICFER.BIT.NALE=0;//NACK送信アービトレーションロスト検出禁止 RIIC0.ICFER.BIT.SALE=0;//スレーブアービトレーションロスト検出禁止 RIIC0.ICFER.BIT.NACKE=1;//NACK受信時転送を中断する(転送中断許可) RIIC0.ICFER.BIT.NFE=1;//デジタルノイズフィルタ回路を使用 RIIC0.ICFER.BIT.SCLE=1;//SCL同期回路有効 RIIC0.ICFER.BIT.FMPE=0;//SCLn端子/SDAn端子にfm+用スロープ制御回路を使用しない
RIIC0.ICIER.BIT.TMOIE=0;//タイムアウト割り込み RIIC0.ICIER.BIT.ALIE=0;//アービトレーションロスト割り込み RIIC0.ICIER.BIT.STIE=0;//スタートコンディション検出割り込み RIIC0.ICIER.BIT.SPIE=0;//ストップコンディション検出割り込み RIIC0.ICIER.BIT.NAKIE=0;//NACK受信割り込み RIIC0.ICIER.BIT.RIE=0;//受信データフル割り込み RIIC0.ICIER.BIT.TEIE=0;//送信終了割り込み RIIC0.ICIER.BIT.TIE=0;//送信データエンプティ割り込み RIIC0.ICCR1.BIT.IICRST=0;//RIICリセット解除 return TRUE;}/////////////////////////////////////////////////////////////////////////RIIC0の初期化 disp///////////////////////////////////////////////////////////////////////
kukoさん、こんにちは。NoMaYです。私は、ほんの2ヶ月前に初めてI2Cの実際に動くプログラム(といっても初心者プログラム)を作っただけの経験しかないですが、kukoさんの状況というのは、マルチマスタで使っているわけでは無いのだけれども(RX65Nがシングルマスタで他はスレーブデバイスが1つ?)、最初の相談文にあったように、ノイズによりアービトレーションロストが検出されてしまったので、ストップコンディションを発行してスレーブとの通信をいったん終了したい(そうしないとスレーブが通信の続きを待ち続けてしまう)、という状況ですか?(実際にマルチマスタ接続であって、本当のアービトレーションロストが発生したら、次に自分がマスタになるまでは何も送信出来ないものである、そんなような気がしたからです。)--------自分の経験はここまでですが、、、(しかもRIICは使っていないです、、、)TB-RX65N/RX130/RX231+CSplus sample programjapan.renesasrulz.com/cafe_rene/f/002-2095199602/6870/tb-rx65n-rx130-rx231-csplus-sample-program/36990#36990
kukoさん、こんにちは。NoMaYです。RX65Nのハードウェアマニュアルと睨めっこしているのですが、アービトレーションロストが発生したら(とりあえずマスタアービトレーションロストだと仮定します)スレーブモードに遷移して受信待ちになるようですね。なので、この場合、マスタモードに遷移して送信待ちの状態に切り替える必要はあるのではないかと思うのです。フラグで書けば以下です。その上で、ストップコンディションの発行を要求するとどうなりますでしょうか?
/* マスタ送信中にマスタアービトレーションロストが検出された⇒スレーブモードで受信モードに遷移している */RIIC0.ICCR2.MST = 1; /* マスタモードへ復帰 */RIIC0.ICCR2.TRS = 1; /* 送信モードへ復帰 *//* I2Cバス占有状態(ICCR2.BBSY == 1)であればストップコンディションを発行出来るのではないか? */RIIC0.ICCR2.SP = 1; /* ストップコンディションの発行を要求 *//* 果たしてストップコンディションを発行出来るか??? */
[追記]引き続きハードウェアマニュアルと睨めっこしていたのですが、ストップコンディションの発行に必要な条件は、MST == 1 かつ BBSY == 1 のようですね。TRSは切り替えなくても良いのかも知れません。
「ノイズなどによって、マスタ・デバイスが出したつもりの無いデータがバス上に出たりした場合にもアービトレーション・ロストが発生します。 このような場合、I2Cモジュールは、即座に通信を中断し、バスを開放する」ということなので
RIIC0.ICCR1.BIT.IICRST=1;//RIICリセット
ですかね
ついでに
RIIC0.ICCR1.BIT.ICE=1;//内部リセット
?
チョコです。
例によって、RXは使ったことはありませんが、RXがノイズでアービトレーション負けを検出して通信から退避した状態だけであれば、RX側の対応(RIICのリセット)で対策できるかもしれません。しかし、問題は通信の場合には相手(この場合にはスレーブ)があり、スレーブがSDAラインをLowに引いている状態ではRX側は何もできません。ストップコンディションも発行できません。この場合には、SCL信号にダミー・クロックを出力してスレーブがSDA信号を引っ張るのをやめさせる必要があります。