こんにちはNAKAといいます。あんぽんたんです。
RL78F15で使ってたSPIデバイス(下記ごくふつーな感じ)をRX65N(GR-ROSE)で使おうと思った
のですが、複数バイト読み込みの1バイト目だけが読めません!!
無理やり読み込みを繰り返し、オシロで観測してますが、書き込みはできていて、デバイスから波形も
ちゃんと出ています。(一番下オシロ絵みたいな感じ)
何かアドバイス頂けたら嬉しいです!
使ったデバイスはこんな感じ
①まずRSPIを初期化して (割込みも使いません。)
//***********************************************************************// 関数名 : fn_Init_RSPI1(void)// 動作 : SPI1の初期化 // 引数 : // 作成 : NAKA 21.04.27// **********************************************************************void fn_Init_RSPI1(void){volatile unsigned char dummy;
MSTP(RSPI1) = 0; //モジュール「ストップ解除 RSPI1.SPCR.BIT.SPE = 0; //SPI動作停止
RSPI1.SPPCR.BYTE = 0x00; //0x00:MOSIの最後出力は保持? は0x20:MOSIの最後の出力は"L"? RSPI1.SPDCR.BYTE = 0x40; //バイトアクセス RSPI1.SPCMD0.WORD = 0x0400;//奇数エッジでデータサンプル、偶数エッジでデータ変化 8bit
RSPI1.SPDCR2.BYTE = 0x00;//スワップ無
/* Set RSPCKB pin */ MPC.PE5PFS.BYTE = 0x0D; PORTE.ODR1.BYTE &= 0xFB; PORTE.PMR.BYTE |= 0x20;
/* Set MOSIB pin */ MPC.PE6PFS.BYTE = 0x0D; PORTE.ODR1.BYTE &= 0xEF; PORTE.PMR.BYTE |= 0x40;
/* Set MISOB pin */ MPC.PE7PFS.BYTE = 0x0D; PORTE.ODR1.BYTE &= 0xBF; PORTE.PMR.BYTE |= 0x80;
RSPI1.SPCR.BIT.SPMS = 1; //★3線式クロック同期モード RSPI1.SPCR.BIT.MSTR = 1; //★マスターモード dummy = RSPI1.SPCR.BYTE; dummy = RSPI1.SPSR.BYTE; RSPI1.SPSR.BYTE = 0xA0; //エラ-クリア
RSPI1.SPCR.BIT.SPE = 1; //SPI動作開始 //ビットレート調整 RSPI1.SPBR = 3; //PCLK(60MHz) RSPI1.SPCMD0.BIT.BRDV = 0; //3_0 = 1/8 60Mhz/8= 7.5Mbps }
②受信関数/************************************************//* SPI1 1バイト受信 *//************************************************/unsigned char ReadSPI1(void){ RSPI1.SPDR.BYTE.HH = 0xFF ; //ダミー書き込み バイトアクセス while(RSPI1.SPSR.BIT.IDLNF){__nop();} //RSPIが転送状態 return (unsigned char)(RSPI1.SPDR.BYTE.HH);}
③SFR(特殊レジスタ)読み込み関数/*******************************************************************************// 関数名 : SFR_RD(unsigned short ADD, unsigned char LEN, unsigned char *RdDATA)// 動作 : CANコントローラSFRへの読み込み// 引数 : ADD→アドレス// : LEN→データ長// : RdDATA→データ// 戻り値 : 無し// 作成 : NAKA 21.04.27// ****************************************************************************/void SFR_RD(unsigned short ADD, unsigned char LEN, unsigned char *RdDATA){unsigned char i; FD_CS = 0; //CSをL 開始 WriteSPI1(0x30 | (ADD >> 8)); //WRITE コマンド+MSBアドレス WriteSPI1((unsigned char)(ADD & 0x00FF)); //LSBアドレス for(i=0;i<LEN;i++) { *RdDATA++ = ReadSPI1(); } FD_CS = 1; //CSをH 終了 }
SFR(特殊レジスタ)設定の設定のところで 0x0F,0x0F,0x3E,0x00を”C1NBTCFG ”レジスタ(アドレス)に書き込んでみますが
最初のバイトだけ読めない!!!!(T_T)
よろしくお願いいたします。
NAKAさん、こんにちは。NoMaYです。自分はRXスマートコンフィグレータ任せでレジスタ制御の詳細は分かりませんけれど、症状的に気になったのは、以下のようなコードを入れてオシロで波形を観測して、タイミングが想定通りか確認してみてはどうでしょうか?unsigned char ReadSPI1(void){ ここでポートの1つをhigh RSPI1.SPDR.BYTE.HH = 0xFF ; //ダミー書き込み バイトアクセス while(RSPI1.SPSR.BIT.IDLNF){__nop();} //RSPIが転送状態 ここでポートをLow return (unsigned char)(RSPI1.SPDR.BYTE.HH);}
NAKAさん、こんにちは。NoMaYです。それから、(自分はRXスマートコンフィグレータ任せでレジスタ制御の詳細は分かりませんけれども、) オシロの波形で気になるのは、アドレス2バイトを送信して最初の0x0Fが返って来るまでの間に、クロックが2バイト分出ているのですが、これの正体が分からないです。思うに、何か無理矢理なリードをする前の素朴な状態のコードで何が起きていたのだろうか、知りたいような気がします、、、ちなみに、ごく普通にSPIを使うのであれば、RSPIよりSCIでの簡易SPIをお勧めします。
NoMaYさま
ご無沙汰しています&いつもありがとうございます!GWに入ってしまい会社でオシロとか使えないので試せません。
>アドレス2バイトを送信して最初の0x0Fが返って来るまでの間に、クロックが2バイト分出ているのですが、これの正体が分からないです。
⇒すみません、この部分はいい加減です。オシロの画像がなく在宅で思い出しながら絵(波形)を書きました。伝えたかったのはREADコマンドとアドレスを送信すると、デバイスからはちゃんと値(0x0f,0x0f,0x3c,0x00)がMISO端子に出力されているということでした。
RL78で動作した波形も観測しましたが、同じような波形でした。ちょっとの違いはRL78はクロックとクロックのあいだの時間が短く、RXはちょっと長めなくらいでした RL78は|||||||| |||||||| |||||||| RX65Nは|||||||| ||||||||| |||||||| みたいな感じ。MOSI、MISOのタイミングは同じように見えました。
ハードも後輩がバラックで組立てるので、イマイチ信用できませんが(>_<)
実はずっとテレワークで「会社のPCに作ったハードを繋げておいたので、リモートでつなげて、通信部の動作確認してください」と後輩に頼まれたのですが動作しなかったため、2日前に出社したら、半田付け忘れを見つけました。そこを直しましたが、今回の現象でした。
P.S.
【かふぇるねについて質問があります】
久々に投稿したのですが、Loginのアイコンを押したのですが、Loding.....の状態になってしまい、何度か繰り返すうちに自分のアバターが出たので、投稿やCAN-FDの質問に回答したのですが、今日サイトをみたら投稿が表示されてませんでした。昨日のように何度か起動し、自分のアバターがでてきたら表示されてました。
NoMaYさまからは見れたのでしょうか?
自宅のパソコンやタブレットでは表示されませんでした。
どうなってるのでしょうか?
こんなメッセージがでました!!!
どうすればいいのでしょうか?
NAKAさん、こんにちは。NoMaYです。> GWに入ってしまい会社でオシロとか使えないので試せません。気になるのは、定番的な(?)、送信データレジスタにライトした直後にフラグを読んでも直後は状態が変化していないので一旦送信中(というか受信中というか)になるのを待ってから送信完了待ち(受信完了待ち)をしないといけない?、ということだったりするのかなぁ、という点ですね。そこをオシロで確認してはどうだろうか、ということでした。> 【かふぇるねについて質問があります】私の場合も調子は良くは無いです。(きっと、ブラウザをGoogle Chromeに変更すれば改善されるのだろうなぁ、と思いながら、(かなり古い)Fire Foxで、ログインしてます。) どうもものすごく頻繁にサーバーにアクセスしているようで、今何人このスレッドを見ているかとか、今リプライを書いている人がいるとか、そんな表示がリアルタイムで表示されるようになっているのですが、そのアクセス動作が不安定っぽくって、エラーが発生、エラーから回復、という旨の英文メッセージが割りと頻繁に交互に表示されますね。つまり、大抵は暫くすれば直ります。(でも、そのうち、またエラーになりますが、また暫くすれば直ります、、、の繰り返しです、、、)あと、Loading...中が続く場合、ブラウザのキャッシュのクリアしてみるのが、自分では良くやる行為ですね。(きっと何か自分の昔の経験からなのでしょうが、そんなクセがついてしまっている、という感じで、改めて思い返すと、それでうまくいったことが多かったのか少なかったのか、思い返せないというところだったり、、、)
NAKAさん、こんにちは。NoMaYです。> 定番的な(?)、送信データレジスタにライトした直後にフラグを読んでも直後は状態が変化していないので一旦送信中(というか受信中というか)になるのを待ってから送信完了待ち(受信完了待ち)をしないといけない?、ということだったりするのかなぁ、例が悪かったと思いました。もちろん、単純にそのものずばり的なものでは無い、と思います。他に、アドレスの送信が終了してアイドル状態になる前にダミーライトしてしまったとか?、も気になります。これも、その理由でこのような受信データになるだろうか?、というのは何とも言えないですけれども、、、
NoMaYさん
NAKAです。
ありがとうございます!!
とうとうGWで会社のPCや基板の電源を切られちゃったみたいで、VPNリモート接続ができなくなっちゃった!!
GW明け(5/10)までしばらく何もできません!(T_T;)
NoMaYさまからはLoginしなくてもみえるのかな? NAKAはどのPCからもLoginしないと表示されませんでした!
見えないとしたら、よくこの書き込みを見つけられましたね?
NAKAさん、こんにちは。NoMaYです。ああっ、私は古いFire FoxのRSSリーダー(もう今のFire Foxには無いらしい)で見ていましたので、そういう点には気を配っていなかったです。でも、今、Fire Foxのプライベートモードでかふぇルネのトップページを見たら、NAKAさんの書き込みはちゃんと見えていますよ。(ページ右上のアイコンが Join or sign in なのでログインしていない状態となっている筈です。)ただ、私も昔、ログインしていないと見えなかった、という経験があります。(その時の下書きの文を見ると、投稿者さんが最後にリプライした投稿が、ログインしていると見えるけれどもログインしていないと見えないですね、となってました。でも、今プライベートモードで確認すると、今は見えるようになっていました。) きっと何かが起きている(ことがある?)のは間違いないのだと思います。なんでしょうかね、、、[追記]そういえば、見えなかった時はブラウザはMicrosoft Edgeでした。それが関係しているのかなと思って今確認してみると、そちらのブラウザでも、今は見えるようになっていましたね。(ブラウザ依存というのでも無いらしいようです、、、) なお、そちらのブラウザでも、NAKAさんの書き込みはログインしてなくても見えました。
ReadSPI1() で、SPSRのIDLNF(アイドルフラグ)で待つのは、間接的に思えます。SPRF(受信バッファフル)を見た方が直接的かと。
そのためには、WriteSPI1()でダミー受信もしないとダメかもしれません。
過去に、RX621用にサンプルを書いたので、参考になると思います。かふぇルネ内で、SampleSPI1.zipで検索すると出てきます。
Higetakaさま
いつもお世話になってます、NAKAです。
そういえば、以前にもHigetakaさまにSPIだったかIICだったかの凡ミスを教えていただき助けていただきましたよね!毎回ありがとうございます。NAKAもSPRFで見ようとしてましたがWhileで止まっちゃうのでおかしいなぁと思っていたら
while(!RSPI1.SPSR.BIT.SPRF){__nop();}
!ビックリマーク忘れてました! ハハッ!(~_~;)
そんで ! つけてやったら 0x00が一つ余分に読まれちゃいます。(*_*;
Higetakaさまの「WriteSPI1()でダミー受信もしないとダメかもしれません。」とあったので
void SFR_RD(unsigned short ADD, unsigned char LEN, unsigned char *RdDATA){unsigned char i;
FD_CS = 0; //CSをL 開始 WriteSPI1(0x30 | (ADD >> 8)); //WRITE コマンド+MSBアドレス WriteSPI1((unsigned char)(ADD & 0x00FF)); //LSBアドレス
__nop(); __nop(); RXDD = ReadSPI1(); //★0510 空読み必要? for(i=0;i<LEN;i++) { //*RdDATA++ = ReadSPI1(); RXDD = ReadSPI1(); *RdDATA++ = RXDD; } FD_CS = 1; //CSをH 終了 }
と一つ空読みしてみたらよさげでした! なんでだろう?????(~_~;)
NAKAの県もコロナ緊急事態宣言がでて、在宅勤務のため、会社にいけないので、まだハード動作確認はできてません。
明後日、無理矢理出勤しよっと!
SPIでは、1バイトの書き込みと読み込みが同時に発生しています。
WriteSPI1した時に、受信バッファフルが成立しているので、読み出された0は、直前のWriteSPI1の結果です。
少量の送受信では、「1バイト書いたら、1バイト読んで返す」の繰り返しをするのが確実です。
なので、WriteSPI1, ReadSPI1と分けるのではなく、WriteReadSPI1とした方が使いやすいと思います。
今回のケースだと、私なら
WriteReadSPI1(cmd1); // 受信データは捨てる
WriteReadSPI1(cmd2);
data1 = WriteReadSPI1(0); // ダミーデータを書いて受信する
data2 = WriteReadSPI1(0);
...
というような感じにします。
ちなみにSampleSPI1.zipでは、バッファを渡して、一気に送受信する形式になっています。
すみませ~ん! お礼をわすれてました! 空読みして、CSをちゃんと通信が終りをフラグで確認してから”H”にしたら動きました。久々にかふぇルネにお邪魔してお礼を忘れていたことに気づきました!!(^^)/
後輩がGR-ROSEでRT-OSをやるみたい!いつもベタ書きしかしないNAKAに聞かれたらどうしよう!!
やさしく、たよりになる NoMaYさまに、聞いちゃおっかなぁ~
その節はよろしくお願いいたします。......優しくしてね!チュッ!