SH7286のSSU(SPI)にお詳しい方、教えて下さい。

SH7286はよく使いましたが、SSU機能を使うことになり、この機能を使うのは今回が初めてです。
送信は希望通りに信号パルス(SSCK,SSO)が出ます。
受信は、マニュアルによれば、「SSER の RE を 1 にセットし、SSRDR をダミーリードすることにより受信動作を開始します。」と書かれています。
そこで、先ず送信にして読み出しアドレスを書き込み、受信に切り替え(RE=1)、ダミーリードしてもSSCKパルスが出ません。
色々と条件を変えて、何度も試していますが、まだ一度もSSCKパルスが出ません。
マスタモードですので、相手方もSSCKに同期して、信号を送ってくると思いますが、どうしたらSSCKパルスが出せるのでしょうか?
通信モードはSCSが他の端子とかち合うので、クロック同期式を使い、別のIOポートからSCSを操作しています。
よろしくお願いいたします。

Parents
  • orientalさん

    こんにちは、

    クロック同期式とのことですが、クロック同期式モードを使用しているということでしょうか?

    マニュアルから、クロック同期式モード、マスターデバイスに設定の場合、RE=1に設定するとダミーリードしなくてもクロックは出力されます。

    クロックが出力されない件ですが、SSSR の ORER が 1 にセットされていませんか?

    確認してみて下さい。

  • SAさん、関心を持って下さりありがとうございます。何かの設定が間違っていると思いますが…。何か気付かれましたら、教えて下さるようお願いします。

  • orientalさん

    前回の書き込みと多少内容が重複しますが、送信から受信に切り替えるときどの様にしてますか?

    TE=0に設定して、受信開始前に、SSSR の ORER とRDRFが0となっているか確認してから、RE=1としてますか?

    ご確認願います。

    クロックが出力されていない状況で関係ないかもしれませんが、以下の様なFAQがありました。ご注意願います。

    japan.renesas.com/.../MPUMCU_SH_385J.jsp

  • Former Member
    Former Member in reply to SA

    クロックが全く出ないとの事なので、

     ・ポートがSSUモードになっていない

     ・SSUMS、MSS、BIDRなどの初期設定に間違いがある

     ・RE=1(またはTE=1)の後にダミーリード(データライト)していない

    あたりが考え付きます。

    まずはハードウェアマニュアルの初期設定フローを確認して、抜けやミスが無いか確認してみてください。

    恐らくは何かの設定ミスなので、レジスタ設定を書き出すか、初期設定+送信部のソースを貼って頂けると問題が発見しやすいと思います。

  • SAさん、ありがとうございます。教えて頂いたURLは役に立ちそうです。SCSがフラッシュメモリー書き込み装置の使用している端子とかち合うので、クロック同期式にしましたが、SSUモードにして、SCSだけを別のポートからマニュアルで操作するのも可能でしょうか? 当方でもう一度、よく確認して、結果をご報告いたします。

  • つくしさん、ありがとうございます。冷静にもう一度見直します。どうしても分からない時は、つたないソースを掲示しますので、よろしくお願いします。

  • 対象デバイスとは、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 )

    {

    EndSSU();

    return false;

    }

    SSU.SSSR.BIT.TEND = 0; //TENDを0にクリア

    //TENDが0であることを確認

    waitTEND(false);

    EndSSU();

    return true;

    }

    //しかし下記だとCS以外は何も出力されません。

    bool ReadPress1(unsigned char regAddr, unsigned char *readData )

    {

    PA.DR.BIT.B23 = 0; //CS => LOW

    SSU.SSER.BYTE = 0xC0; //送受信動作が可能

    // SSSRをリードしてTDREが1であることを確認した後、

    if ( waitTDRE() == false )

    {

    EndSSU();

    return false;

    }

    //SSTDRに送信データをライトします。

    SSU.SSTDR0 = regAddr ; //RW=1,MS=0, 1000 1111

    if ( waitTDRE() == false )

    {

    EndSSU();

    return false;

    }

    SSU.SSRDR0 = 0; //ダミーライト

    //読み出し開始

    *readData = SSU.SSRDR0 ; //SSRDRをダミーリード

    if ( waitRDRF() == false )

    {

    EndSSU();

    return false;

    }

    *readData = SSU.SSRDR0 ; //データをリード

    // データ送信を終了するには、TENDが1であることを確認

    if ( waitTEND(true) == false )

    {

    EndSSU();

    return false;

    }

    SSU.SSSR.BIT.TEND = 0; //TENDを0にクリア

    //TENDが0であることを確認

    waitTEND(false);

    EndSSU();

    return true;

    }

    //

    void EndSSU()

    {

    SSU.SSSR.BIT.TEND = 0; //TENDを0にクリア

    SSU.SSER.BYTE = 0; //送受信停止

    PA.DR.BIT.B23 = 1; //CS => HIGH

    }

  • orientalさん

    こんにちは、

    この処理は、クロック送信を行った後、クロック送受信を行っていませんか?

    その場合、一旦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 )

    {

    PA.DR.BIT.B23 = 0; //CS => LOW

    //フラグクリアが必要 !!!

    status = SSU.SSSR.BYTE;

    SSU.SSSR.BYTE = 0;

    SSU.SSER.BYTE = 0x80; //送信動作が可能

    // SSSRをリードしてTDREが1であることを確認した後、

    if ( waitTDRE() == false )

    {

    EndSSU();

    return false;

    }

    //SSTDRに送信データをライトします。

    SSU.SSTDR0 = regAddr ; //RW=1,MS=0

    // データ送信を終了するには、TENDが1であることを確認

    if ( waitTEND(true) == false )

    {

    EndSSU();

    return false;

    }

    SSU.SSSR.BIT.TEND = 0; //TENDを0にクリア

    //TENDが0であることを確認

    if ( waitTEND(false) == false )

    {

    EndSSU();

    return false;

    }

    //一度SSERのTE、REを0にクリアすることが必要 !!!

    SSU.SSER.BYTE = 0;

    delay(10); //これを入れないとクロックが出ない。!!!

    SSU.SSER.BYTE = 0x40; //受信動作が可能

    //読み出し開始

    char dummy = SSU.SSRDR0 ; //SSRDRをダミーリード

    if ( waitRDRF() == false )

    {

    EndSSU();

    return false;

    }

    *readData = SSU.SSRDR0 ; //データをリード

    EndSSU();

    return true;

    }

    void EndSSU()

    {

    delay(20); //1ビット期間経過

    SSU.SSER.BYTE = 0; //送受信停止

    PA.DR.BIT.B23 = 1; //CS => HIGH

    }

  • orientalさん

    こんにちは、

    上手く行って良かったですね。

    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; //送受信動作が可能

    //下記だとクロックが出ません

    SSU.SSER.BYTE = 0; //一度SSERのTE、REを0にクリアすることが必要!

    char dummy = SSU.SSER.BYTE;

    SSU.SSER.BYTE = 0x40; //送受信動作が可能

    //ソフトウェアリセットをするとクロックが出ます

    //ソフトウェアリセット

    //本ビットを 1 にセットすると SSU 内部シーケンサを強制的にリセットします。

    //本ビットは自動的にクリアされ、SSSR の ORER、TEND、TDRE、RDRF、CE の各ビット

    //および、SSER の TE、RE ビットが初期化されます。

    //その他の SSU 内部レジスタ値は保持されます。

    SSU.SSCRL.BIT.SRES = 1; //1:ソフトウェアリセット

    SSU.SSER.BYTE = 0x40; //送受信動作が可能

    色々と教えて下さり、大変にありがとうございました。

Reply
  • SAさん、ご親切にありがとうございます。

    装置を外してあったので、また準備して試しました。

    SSERのダミーリードでは、当方の装置ではクロックが出ませんでした。

    //下記だとクロックが出ます

    SSU.SSER.BYTE = 0; //一度SSERのTE、REを0にクリアすることが必要!

    delay(10); //これを入れないとクロックが出ない。

    SSU.SSER.BYTE = 0x40; //送受信動作が可能

    //下記だとクロックが出ません

    SSU.SSER.BYTE = 0; //一度SSERのTE、REを0にクリアすることが必要!

    char dummy = SSU.SSER.BYTE;

    SSU.SSER.BYTE = 0x40; //送受信動作が可能

    //ソフトウェアリセットをするとクロックが出ます

    //ソフトウェアリセット

    //本ビットを 1 にセットすると SSU 内部シーケンサを強制的にリセットします。

    //本ビットは自動的にクリアされ、SSSR の ORER、TEND、TDRE、RDRF、CE の各ビット

    //および、SSER の TE、RE ビットが初期化されます。

    //その他の SSU 内部レジスタ値は保持されます。

    SSU.SSCRL.BIT.SRES = 1; //1:ソフトウェアリセット

    SSU.SSER.BYTE = 0x40; //送受信動作が可能

    色々と教えて下さり、大変にありがとうございました。

Children
No Data