お世話になっております。
CPU:RX113
使用する機能:RSPI
RX113をマスターとし、デバイスとなるFRAMメモリのデバイスIDを読み出すことを考えています。
送出するコマンドは、8ビットの0x9F
このコマンドを送出すると、デバイスより32ビットのデータが返ってくることになっています。
● 現在の設定
コマンド数1、転送フレーム数1
ビット長:8ビット
この設定で、次のコードを実行しますと、図に示しましたように、最後の8ビット( Product ID ( 2nd Byte ) )が欠落してしまいます。
( メモリメーカーが示している、Manufacturer ID,Continuation code,Product ID(1st Byte)までは正しく返されています )
//// FRAM デバイスID 読み込み//
Y_RSPI0_Start(); PORT5.PODR.BIT.B3 = 0; // チップセレクト -> FRAM
while(RSPI0.SPSR.BIT.SPTEF == 0); // RDID コマンド送信 ( 送信バイト数:1、データ:0x9F ) RSPI0.SPDR.WORD.H = 0x009F; // データの送信 while(RSPI0.SPSR.BIT.IDLNF == 1); // 送信完了待ち
RSPI0.SPDR.WORD.H = 0x0000; // ID受信用ダミー(1) while(RSPI0.SPSR.BIT.IDLNF == 1); // 送信完了待ち
RSPI0.SPDR.WORD.H = 0x0000; // ID受信用ダミー(2) while(RSPI0.SPSR.BIT.IDLNF == 1); // 送信完了待ち
RSPI0.SPDR.WORD.H = 0x0000; // ID受信用ダミー(3) while(RSPI0.SPSR.BIT.IDLNF == 1); // 送信完了待ち
RSPI0.SPDR.WORD.H = 0x0000; // ID受信用ダミー(4) <--- この行の送信分が欠けてしまう。 while(RSPI0.SPSR.BIT.IDLNF == 1); // 送信完了待ち
while(RSPI0.SPSR.BIT.SPRF == 0); // 受信バッファフルの確認 (1)
FRAM_DEVICE_ID1 = RSPI0.SPDR.WORD.H; // while(RSPI0.SPSR.BIT.SPRF == 0); // 受信バッファフルの確認 (1) FRAM_DEVICE_ID2 = RSPI0.SPDR.WORD.H;
PORT5.PODR.BIT.B3 = 1; // チップセレクト 解除
Y_RSPI0_Stop();
上記コードを実行した時の、波形
転送フレームが1であるから最後の8ビットが欠けてしまったのであろうと、フレーム数を2にしたら、今度は先頭の8ビットしかデータが返ってきませんでした。
そもそもフレームの理解ができていないのですが、今回のように、送信8ビット、受信32ビットを実行するにはどのようにしたらよいのでしょうか。
ハードウェアマニュアルを読みましたが、正直なところよくわかりませんでした。
大変お手数をおかけしますが、ご教示願います。
※ 一連の質問で未だ受信データの取り込みは解決できておりませんが、先にSPIバスにデータが現れることを確認することを先に進めております。
LEONです。 まず、Y_RSPI0_Start()、Y_RSPI0_Stop()内のRSPIレジスタ設定値をご開示願います。
> 送信8ビット、受信32ビットを実行するにはどのようにしたらよいのでしょうか。
FRAMのコマンド送信時は、8Bit送信のみを行い、送信後、32Bit、全二重同期に 設定を切り替えてはいかがでしょうか。 以下に手順を考えてみました。 Y_RSPI0_Start()後 //-- FRAMのコマンド送信時 --// // 8Bit、送信のみの設定 SPSR.IDLNF== 1は待ち // 0:RSPIがアイドル状態 SPCR.SPE = 0 // 0:RSPI機能無効 SPCR.TXMD =1 // 1:送信動作のみのシリアル通信 SPDCR←0x00 // SPLW=0:ワードアクセス、SPSF=00:1フレーム // SPRDDT=0:SPDRは受信バッファリード SPCMD0←0x0400 // SPB=0100:8Bit、LSBF=0:MSBファースト // 他のBitは必要に応じて調整してください SPCR.SPE = 1 // 1:RSPI機能有効 チップセレクト // RDID コマンド送信 while(RSPI0.SPSR.BIT.SPTEF == 0); RSPI0.SPDR.WORD.H = 0x009F; // RDID(0x9F)コマンド送信 //-- FRAMからのデバイスID(4Byte)を受信時 --// // 32Bit、全二重同期式シリアル通信の設定 SPSR.IDLNF== 1は待ち // 0:RSPIがアイドル状態 SPCR.SPE = 0 // 0:RSPI機能無効 SPCR.TXMD =0 // 0:全二重同期式シリアル通信 SPDCR←0x20 // SPLW=1:ロングワードアクセス、SPSF=00:1フレーム // SPRDDT=0:SPDRは受信バッファリード SPCMD0←0x0200 // SPB=0010:32Bit、LSBF=0:MSBファースト // 他のBitは必要に応じて調整してください SPCR.SPE = 1 // 1:RSPI機能有効 // 32ビットのID受信用ダミー送信 while(RSPI0.SPSR.BIT.SPTEF == 0); RSPI0.SPDR.LONG = 0x00000000; // ダミー送信 //-- デバイスID(4Byte)のリード --// while(RSPI0.SPSR.BIT.SPRF == 0); // 受信バッファフルの確認 FRAM_DEVICE_ID = RSPI0.SPDR.LONG; チップセレクト 解除 SPCR.SPE = 0 // 0:RSPI機能無効 設定切り替え部は、関数化すると良いでしょう。 検証できないので、誤りがある場合はご容赦ください。
おっと、ポーリングの場合 IDLNFチェックの前に(時におまじない的な)SPSR空読みを入れるんだった。 上のポーリング方式は、処理が終わるまで他タスクが実行できないので、割り込み方式をお勧めします。まずは、ポーリング方式のRSPI制御がうまく動作してから、その後どうするか考えましょう。
LEON様
早速試してみましたが、コマンドを送信したところで止まってしまいますね。
挙動としては、受信の命令を飛ばしてチップセレクトがOFFになっているようです。
試したコードは次の通りです。
Y_RSPI0_Start();
/* FRAM デバイスID読み込みのための 送信モード切替 */ RSPI0.SPCR.BIT.SPE = 0; // 機能無効 RSPI0.SPCR.BIT.TXMD = 1; // 送信のみ RSPI0.SPDCR.BYTE = 0x00; // ワードアクセス、1フレーム、受信バッファリード RSPI0.SPCMD0.WORD = 0x0400; // 8ビット、MSBファースト・・・ RSPI0.SPCR.BIT.SPE = 1; // 機能有効
PORT5.PODR.BIT.B3 = 0; // チップセレクト -> FRAM
while(RSPI0.SPSR.BIT.SPTEF == 0); // RDID コマンド送信 ( 送信バイト数:1、データ:0x9F ) RSPI0.SPDR.WORD.H = 0x009F; // データの送信 dummy = RSPI0.SPSR.BYTE; while(RSPI0.SPSR.BIT.IDLNF == 1); // 送信完了待ち
/* FRAM から32bitデータ受信のための 送信モード切替 */ RSPI0.SPCR.BIT.SPE = 0; // 機能無効 RSPI0.SPCR.BIT.TXMD = 0; // 全二重 RSPI0.SPDCR.BYTE = 0x20; // ロングワードアクセス、1フレーム、受信バッファリード RSPI0.SPCMD0.WORD = 0x0200; // 32ビット、MSBファースト・・・ RSPI0.SPCR.BIT.SPE = 1; // 機能有効
while(RSPI0.SPSR.BIT.SPTEF == 0); RSPI0.SPDR.LONG = 0x00000000; // ダミー送信
while(RSPI0.SPSR.BIT.SPRF == 0); // 受信バッファフルの確認 (1) FRAM_DEVICE_ID = RSPI0.SPDR.LONG;
コード開示、ありがとうございます。 ■R_RSPI0_Create() マクロが不明ですが、値は名前から推測しました。特に設定値に問題は無さそうです。 割り込みは使わないとのことなので、IPR(RSPI0,SPTI0) の設定は不要ぐらい。 ■Y_RSPI0_Start() ・SPCR2.SPIIE =0 は割り込み未使用とのことなので、なくても良い。 ・Y_RSPI0_Start()内の SPSRライトは余分では。 ・基本、SPCR.SPE =0 後、設定、SPCR.SPE =1 としましょう。 SPCR.SPE =1 の状態において....の注意がマニュアルにはいろいろ記述されてます。 ■Y_RSPI0_Stop() ・SPCR2.SPIIE =0 は割り込み未使用とのことなので、なくても良い。 フレームについては、1135、1136ページに示すとおりで、今回は1フレームのみ(設定1-1)で案内ですが、
Higetakaさんが案内するシーケンスを2つのフレーム(8bit, 32bit)も適切と思います。
SPTEFチェック、IDLNFチェックの前にSPSR空読みを入れててもだめですか。 (1127ページ。SPI動作ですが、クロック同期式も同じ) 表32.8 1項に示す症状っぽく、後の書込データが欠落し(送信されずに)チップセレクト解除まで処理が進んでいるようなんですが。 ダミーデータ送信直前の状態は、エミュレータで調べるとどうなってましたかね。
シーケンスとフレーム、一気に理解されたようで良かったですね。なら、話が早いです。 SPSR空読み、表32.8 1項、気をつけてね。
Higetakaさん、的確なヒント。ありがとうございました。
LEON様、Higetaka様
ありがとうございました。
ビット数とフレーム数について理解ができ、スレーブデバイスからのレスポンスも正しいデータが返ってきました。
図1 CMD0:8ビット、フレーム数:1
図2 CMD0:8ビット、CMD1:32ビット、フレーム数:2
後はレスポンスデータの取り込みだけなんだけど…なぜか相変わらずFF…
● 今回のフレーム操作で気がついた事。
設定したフレーム数の分(例:2フレームならば2つ)データがSPDRに入らなければ、マイコンは転送の実行を行わないということです。