RSPIのMISOA信号とSPDRより読み取った値が異なってしまいます。

お世話になっております。

RX113のRSPIで、富士通のFRAMをスレーブデバイスとして接続し、通信を行っております。

無事にFRAMにステータスリードのコマンドを送信して、下図の通りバス上では正しいレスポンス(0x10)が返ってきました。

しかし、読み取ったSPDRの値はなぜか(0xFF)という値でした。

  

送受信のソースは次の通りです。

//
// FRAM ステータスレジスタ 読み込み
//
  Y_RSPI0_Start();
  PORTC.PODR.BIT.B4 = 0;           // チップセレクト -> FRAM

  while(RSPI0.SPSR.BIT.SPTEF == 0);
  // RDSR コマンド送信 ( 送信バイト数:1、データ:0x05 )

  RSPI0.SPDR.WORD.H = 0x0005;       // データの送信
  while(RSPI0.SPSR.BIT.IDLNF == 1);     // 送信完了待ち
  RSPI0.SPDR.WORD.H = 0x0000;       //  レスポンス受信用のクロック送出
  while(RSPI0.SPSR.BIT.IDLNF == 1);     // 送信完了待ち


  while(RSPI0.SPSR.BIT.SPRF == 0);      // 受信バッファフルの確認
  FRAM_READ_STR = RSPI0.SPDR.WORD.H;

  PORTC.PODR.BIT.B4 = 1;           // チップセレクト 解除
  Y_RSPI0_Stop();

 

バス上の信号(0x10)が何故0xFFになるのか、何処に原因があるのかわかりません。

リードするタイミングでしょうか。お手数をおかけしますが、ご教示願います。

 

※ コードの作成では、過去スレッドのつくしさんの回答を参考にさせていただきました。

Parents
  • LEONです。
    RX113は使ったこと無いですが、
    ・SPDRに書き込んだ後、SPTEFのクリア
    ・SPDRからリードした後、SPRFのクリア
    が必要じゃないんでしょうか。
Reply
  • LEONです。
    RX113は使ったこと無いですが、
    ・SPDRに書き込んだ後、SPTEFのクリア
    ・SPDRからリードした後、SPRFのクリア
    が必要じゃないんでしょうか。
Children
  • 先のレスで、私の他CPU処理では SPTEF、SPRF をクリアしてましたが、必須ではないかもしれません。早とちりですみません。

    ・オシロのMISOAデータは、MSBから展開されますから 0x10 ではなく 0x02 のようです。
     富士通FRAMの型番が不明ですが、MB85RQ4MLの場合ステータスレジスタは以下の通りでした。
      Bit1:WEL:ライトイネーブルラッチ
       1=書き込み可能。WRENコマンドでセット
       0=書き込み不可。WRDIコマンドでもリセット

    以下は、既知設定済みかもしれませんが、お確かめ下さい。
    ・CPU側シングルマスタ/FRAM側シングルスレーブの設定?
    ・SPDRのワードアクセスの送信データ/受信データはLSB詰め。
    ・SPCMD0.LSBF=0 0:MSBファースト
    ・SPCMD0.SPB=0100~0111: 8Bit長
  • LEON様
    お世話になっております。

    いえ、気になさらないでください。
    > ・オシロのMISOAデータは、MSBから展開されますから 0x10 ではなく 0x02 のようです。

    はい、その通りです。2進と16進をごっちゃに書いてしまいました。0x02が正解です。

    > 以下は、既知設定済みかもしれませんが、お確かめ下さい。
    > ・CPU側シングルマスタ/FRAM側シングルスレーブの設定?
    > ・SPDRのワードアクセスの送信データ/受信データはLSB詰め。
    > ・SPCMD0.LSBF=0 0:MSBファースト
    > ・SPCMD0.SPB=0100~0111: 8Bit長

    はい。 CPU側はシングルマスタの設定です。(MSTRビット)
    接続されるデバイス(今回はFRAM)には、シングルスレーブなどを設定する機能はありましたでしょうか。
    そこは意識していなかったです。
    SPDRのワードアクセスは、ワードです。
    送信データのSPDRへの書き込みはハードウェアマニュアルに書かれている通りにLSB詰めで書いています。
    送信データは、0x0006と書いています。
    MSBファーストであること、8ビット長であることも確認いたしました。
  • パールマン様
    こんにちは、追加で確認ですが、
    全二重同期式シリアル通信(SPCR.TXMD = 0)でしょうか?
    お教え願います。
  • 今回使用しているFRAMの型番は、MB85RS512Tという512K(64Kx8)ビットのメモリです。
    メモリセルへの書き込み/読み出しの評価のために、まずはWRENコマンドを送信したわけです。
    その後、ステータスレジスタを確認しようとしたら、バスの波形と読み出しのデータが違っていたと…(涙)
  • はい、その通りです。
  • LEONです。
    > .... まずはWRENコマンドを送信したわけです。...
    > その後、ステータスレジスタを確認しようとしたら....
    > .... 送信データは、0x0006と書いています。

    WREN(0x06)コマンドですよね。ステータスリードコマンド後であれば RDSR(0x05)か
    ダミーライトの 0x00 だと思うのですが。
    表32.8 1項に該当しませんか?
     発生条件:送信バッファフルの状態でSPDRレジスタを書き込み
     RSPI動作:送信バッファ内容を保持。書き込みデータ欠落
     エラー検出:なし

    IDLNFをチェックしてますが、SPTEFチェックではどうなんでしょう。


    チョコさんが示唆されてますように、要所にダミーリードを入れてみるとか。
    もちろん、SPTEF、SPRFのルールは守った上で。

     ・SPDR ← WREN    WREN(06)書き込み許可
     ・ ★ダミーリード

     ・SPDR ← RDSR    RDSR(05)ステータスリード
     ・ ★ダミーリード
     ・SPDR ← 0x00    ダミーライト
     ・データ ← SPDR   受信データをリード

     # ライト+ダミーリード。ダミーライト+リード
     # (なんだかダミーだらけ.... PPAP みたい。)
     # 策の案は検証できず、効果があるかどうかわかりません。


    > シングルスレーブ....
    RSPI構成で外部にFRAM1個のみの接続であれば、必然的にシングルスレーブになろうかと。
    複数のFRAM等接続のマルチスレーブの可能性もあったので、念のための確認でした。
  • LEON様

    お世話になっております。

    SPTEFに変えて試してみましたところ、さらに摩訶不思議な状態になってしまいました。

    それが下図です。

    なんと、3線式で、全ての処理を終えてからチップセレクトを1にしているはずなのに、コマンド(0x05)を送信したところで強制的にポートが1に変わり、受信用に出しているはずのクロックも出なくなるという状態になりました。コマンドを送出したあとの命令が全部無視された状態です。(?o?;)これって何??

    画像をよく観察すると、どうもSPIのバスラインを初期化しているように見えます。

    ソースは、次の通りです。

    試験用に入れた命令のコメントアウトがあちこちにあるため、読みにくいソースになってしまっていますが、ご容赦願います。

    スレーブに送出するコマンドと、受信用に送出するときに入れていたIDLNFをSPTEFに変更したところ、上図に示す波形になってしまいました。

     

    //
    // FRAM ステータスレジスタ 読み込み
    //

      Y_RSPI0_Start();
      PORTC.PODR.BIT.B4 = 0; // チップセレクト -> FRAM

      while(RSPI0.SPSR.BIT.SPTEF == 0);
      // RDSR コマンド送信 ( 送信バイト数:1、データ:0x05 )

      RSPI0.SPDR.WORD.H = 0x0005; // データの送信
      // dummy = RSPI0.SPSR.BYTE;
      while(RSPI0.SPSR.BIT.SPTEF == 0); // 送信完了待ち
      // while(RSPI0.SPSR.BIT.IDLNF == 1); // 送信完了待ち

      RSPI0.SPDR.WORD.H = 0x0000; // 受信用ダミー送出
      // dummy = RSPI0.SPSR.BYTE;
      while(RSPI0.SPSR.BIT.SPTEF == 0); // 送信完了待ち
      // while(RSPI0.SPSR.BIT.IDLNF == 1); // 送信完了待ち

      while(RSPI0.SPSR.BIT.SPRF == 0); // 受信バッファフルの確認
      // dummy = RSPI0.SPDR.WORD.H;

      // RSPI0.SPSR.BIT.SPTEF = 1; // 送信バッファエンプティフラグのクリア
      // dummy = RSPI0.SPSR.BYTE;
      // while(RSPI0.SPSR.BIT.SPRF == 0); // 受信バッファフルの確認

      FRAM_READ_STR = RSPI0.SPDR.WORD.H;
      // RSPI0.SPSR.BIT.SPRF = 1;

      PORTC.PODR.BIT.B4 = 1; // チップセレクト 解除
      PORTF.PODR.BIT.B7 = 0;

      Y_RSPI0_Stop();

  • LEONです。
    混乱を与えました。すみません。摩訶不思議な状態、今は分かりません。(?ェ?)
     # 表32.8 1項とか、SPFCのフレーム数に達成してないとか....が考えられます。
     # 私が使っていたCPUには IDLNF が無いです。

    こんなのありました。
    RSPIの全データ送信完了確認方法の追加
    www.renesas.com/.../tnrxa147aj.pdf
    赤書きの箇所
    「SPDRレジスタに最終デーを書いた後は、“ 1”になる前の IDLNFフラグで判定
    しないように、一度 SPSRレジスタの値を読み捨て、次に読出した SPSR.IDLNF
    フラグの値から全データ送信完了の確認に使用してください。」
    ハードウェアマニュアル 1127ページにも同様の記述があります。

    ↓こういうことのようです。★箇所
     SPTEF==0で待ち   1:送信バッファに有効なデータなし?
     SPDR ← 0x05    RDSR(05)ステータスリードコマンド
     SPSR空読み     ★
     SPSR.IDLNF==1で待ち 0:RSPIがアイドル状態 1:RSPIが転送状態
    //SPDR空読み
     SPDR ← 0x00    受信用ダミー送出
    //SPSR空読み     ★
    //SPSR.IDLNF==1で待ち
     SPRF==0で待ち    1:SPDRに有効な受信データあり
     リードデータ ← SPDR

    //箇所は場合によっては処理が必要かも。

    開示ソース中、該当箇所のSPSR空読みのコメントを外してみたらどうでしょう。

     # また外してる?  凹
  • LEON様

    お示しいただきました手順を含めていろいろ試してみましたが、全て駄目でした。
    受信データを読んだ結果は、どうやってもこうやっても「255」としか入っていないようです。

    一体どのタイミングを読んでいるのか(波形の前のほうなのか、後のほうなのか)、さっぱりわかりません。
    MISOAの配線がはずれているのか?とも考えましたが、それもないようです。
    ※ バスに正しい信号が出ていて、マイコンに入っていないとしたら、配線しか疑うところがない。

    困った。
  • >困った。

     RX113もRSPIも知らないけど、困っているようだから。
     「藁をも掴む」の藁回答です。

    ・通信速度を下げる。速い方が良いと言うので安易に速くすると、トラブルの元
    ・プルアップが必要な信号ではないか
    ・電源電圧と速度の依存性は無いか
    ・CPUの処理速度が速いと、ステータスが確定する前のステータスを読む事がある。
     内蔵のI/Oの場合はそんな事は少ないけど、マニュアルを良く読んでみて。
     リセット・コマンドを送ってから、何クロック待てなんて言うのも有ります。
     
    ・通信の場合、最初のデータはゴミの事が多い。受信だったら、ゴミデータを読んでデータが空になった後が正しいデータとか。
     送信側も受信側も、通信が確定するまでの最初の部分ではゴミなので注意する。
     ゴミと言うのは通信ラインもH/Lが確定していないから、ゴミをデータとして受け取るかも知れない。
     レジスタに入っている送受信データやステータスの内容も不定値で、信用できないと言うことです。