SH7286はよく使いましたが、SSU機能を使うことになり、この機能を使うのは今回が初めてです。送信は希望通りに信号パルス(SSCK,SSO)が出ます。受信は、マニュアルによれば、「SSER の RE を 1 にセットし、SSRDR をダミーリードすることにより受信動作を開始します。」と書かれています。そこで、先ず送信にして読み出しアドレスを書き込み、受信に切り替え(RE=1)、ダミーリードしてもSSCKパルスが出ません。色々と条件を変えて、何度も試していますが、まだ一度もSSCKパルスが出ません。マスタモードですので、相手方もSSCKに同期して、信号を送ってくると思いますが、どうしたらSSCKパルスが出せるのでしょうか?通信モードはSCSが他の端子とかち合うので、クロック同期式を使い、別のIOポートからSCSを操作しています。よろしくお願いいたします。
orientalさん
こんにちは、
クロック同期式とのことですが、クロック同期式モードを使用しているということでしょうか?
マニュアルから、クロック同期式モード、マスターデバイスに設定の場合、RE=1に設定するとダミーリードしなくてもクロックは出力されます。
クロックが出力されない件ですが、SSSR の ORER が 1 にセットされていませんか?
確認してみて下さい。
SAさん、関心を持って下さりありがとうございます。何かの設定が間違っていると思いますが…。何か気付かれましたら、教えて下さるようお願いします。
前回の書き込みと多少内容が重複しますが、送信から受信に切り替えるときどの様にしてますか?
TE=0に設定して、受信開始前に、SSSR の ORER とRDRFが0となっているか確認してから、RE=1としてますか?
ご確認願います。
クロックが出力されていない状況で関係ないかもしれませんが、以下の様なFAQがありました。ご注意願います。
japan.renesas.com/.../MPUMCU_SH_385J.jsp
クロックが全く出ないとの事なので、
・ポートがSSUモードになっていない
・SSUMS、MSS、BIDRなどの初期設定に間違いがある
・RE=1(またはTE=1)の後にダミーリード(データライト)していない
あたりが考え付きます。
まずはハードウェアマニュアルの初期設定フローを確認して、抜けやミスが無いか確認してみてください。
恐らくは何かの設定ミスなので、レジスタ設定を書き出すか、初期設定+送信部のソースを貼って頂けると問題が発見しやすいと思います。
つくしさん、ありがとうございます。冷静にもう一度見直します。どうしても分からない時は、つたないソースを掲示しますので、よろしくお願いします。
対象デバイスとは、I2CでもI/Oポート操作でも、データが読み書き出来るのに、慣れ親しんだSHのSSUで出来ないのは残念なので、先輩諸氏のご指摘を頂きたく、SSUに関するコードを記載致しまので、よろしくお願いします。
----------------------
(hwsetup.cppのSSUに関する部分)
//STB.CR5.BIT._SSU = 0 ; //0:SSU は動作
STB.CR5.BYTE = 0x52 ; //0101 0010
PFC.PACRL1.BIT.PA3MD = 7 ; //PA3 111:SSI 入出力(SSU)
PFC.PACRL2.BIT.PA4MD = 7 ; //PA4 111:SSO 入出力(SSU)
PFC.PACRL2.BIT.PA5MD = 7 ; //PA5 111:SSCK 入出力(SSU)
PFC.PAIORH.BIT.B23 = 1; //PA23 output
PFC.PACRH2.BIT.PA23MD = 0; //PA23 000:PA23 入出力(ポート)
PA.DR.BIT.B23 = 1; //CS => HIGH
(初期に1回だけの呼び出し)
void InitSSU()
{
SSU.SSER.BYTE = 0; //SSERのTE、REを0にクリア
SSU.SSCRH.BIT.MSS = 1; //1:マスタモードを選択
SSU.SSMR.BIT.MLS = 1; //1:MSB ファースト
SSU.SSMR.BIT.CKS = 7; //111:Pφ/256 =>195KHz
}
(1秒ごとに呼び出される関数)
//下記だとSSCKもSSOも出力されます
bool ReadPress(unsigned char regAddr, unsigned char *readData )
PA.DR.BIT.B23 = 0; //CS => LOW
SSU.SSER.BYTE = 0x80; //送受信動作が可能
// SSSRをリードしてTDREが1であることを確認した後、
if ( waitTDRE() == false )
EndSSU();
return false;
//SSTDRに送信データをライトします。
SSU.SSTDR0 = regAddr ; //RW=1,MS=0, 1000 1111
// データ送信を終了するには、TENDが1であることを確認
if ( waitTEND(true) == false )
SSU.SSSR.BIT.TEND = 0; //TENDを0にクリア
//TENDが0であることを確認
waitTEND(false);
return true;
//しかし下記だとCS以外は何も出力されません。
bool ReadPress1(unsigned char regAddr, unsigned char *readData )
SSU.SSER.BYTE = 0xC0; //送受信動作が可能
SSU.SSRDR0 = 0; //ダミーライト
//読み出し開始
*readData = SSU.SSRDR0 ; //SSRDRをダミーリード
if ( waitRDRF() == false )
*readData = SSU.SSRDR0 ; //データをリード
//
void EndSSU()
SSU.SSER.BYTE = 0; //送受信停止
この処理は、クロック送信を行った後、クロック送受信を行っていませんか?
その場合、一旦TEとREを0クリアして下さい。
また、TEND、RDRF、ORERが0にクリアさていること確認して下さい。
その後、TEとREを1にセットして下さい。
マニュアルの18-33ページの(4) データ送受信の記載さてれいます。
ご確認下さい。
SAさん、ご指摘ありがとうございます。ご指摘の通りで、
1)受信に切り替える前に、SSERのTE、REをクリアしました。
2)SSSRのフラグもクリアしました。
3)SSERのTE、REをクリアした後に、すぐSSERを受信に切り替えても、SSCKクロックが出ないので
10マイクロ秒位経ってから受信に切り替えたら、SSCKクロックが出ました。
これで対象デバイスの内容が読み出せました。大変ありがとうございました。
一応、成功したコードを記載します。
bool ReadPress2(unsigned char regAddr, unsigned char *readData )
//フラグクリアが必要 !!!
status = SSU.SSSR.BYTE;
SSU.SSSR.BYTE = 0;
SSU.SSER.BYTE = 0x80; //送信動作が可能
SSU.SSTDR0 = regAddr ; //RW=1,MS=0
if ( waitTEND(false) == false )
//一度SSERのTE、REを0にクリアすることが必要 !!!
SSU.SSER.BYTE = 0;
delay(10); //これを入れないとクロックが出ない。!!!
SSU.SSER.BYTE = 0x40; //受信動作が可能
char dummy = SSU.SSRDR0 ; //SSRDRをダミーリード
delay(20); //1ビット期間経過
上手く行って良かったですね。
SSU.SSER.BYTE = 0のあとに10マイクロ秒くらい立ってから受信とありますが、
これは、プログラムが実行されてから実際のSSERレジスタがクリアされるまでのタイムラグと思います。
SSERをクリアしてから、SSERをダミーリードしてみて下さい。
ダミーリードすることで確実にSSERがクリアされてから次のプログラムが実行されるはずです。
その後で受信開始とするとクロックが出力されると思います。
よろしければ試してみて下さい。
SAさん、ご親切にありがとうございます。
装置を外してあったので、また準備して試しました。
SSERのダミーリードでは、当方の装置ではクロックが出ませんでした。
//下記だとクロックが出ます
SSU.SSER.BYTE = 0; //一度SSERのTE、REを0にクリアすることが必要!
delay(10); //これを入れないとクロックが出ない。
SSU.SSER.BYTE = 0x40; //送受信動作が可能
//下記だとクロックが出ません
char dummy = SSU.SSER.BYTE;
//ソフトウェアリセットをするとクロックが出ます
//ソフトウェアリセット
//本ビットを 1 にセットすると SSU 内部シーケンサを強制的にリセットします。
//本ビットは自動的にクリアされ、SSSR の ORER、TEND、TDRE、RDRF、CE の各ビット
//および、SSER の TE、RE ビットが初期化されます。
//その他の SSU 内部レジスタ値は保持されます。
SSU.SSCRL.BIT.SRES = 1; //1:ソフトウェアリセット
色々と教えて下さり、大変にありがとうございました。