RL78 CSI について

RL78/G13を使用しています。

CSIで別のデバイスと通信したいのですが、シミュレータで出力波形を見るとクロックは出力されるのにデータが出力されません。

CSIを使用する上でアドバイスを頂けないでしょうか。

CSIは、SAU0のCSI11を使用し、シングル転送モード、連続転送モード、どちらでも同じです。

また、関係あるかどうかわからないのですが、SAU0のUART0も有効にしてコード生成しています。

コード生成されたデータは、r_cg_serial_userの割り込み処理の最後にF_SPI_comフラグのクリアを追加しています。

サブルーチンコールは以下のように行っています。

   if ((SSR11 & 0x0040 ) == 0) {
        P14_bit.no0 = 0;
        g_tx_data[0] = 0x31;
        g_tx_data[1] = 0x00;
        data_length = 1;
        F_SPI_com = 1;
        result = R_CSI11_Send_Receive(&g_tx_data[0], data_length, &g_rx_data[0]);
        
        while (1U)
        {
            if ( F_SPI_com == 0 )
                break;
        }

よろしくお願いします。

Parents
  • チョコさま、ご回答ありがとうございます。
    ソースを確認しましたが、CSIを制御するレジスタを直接いじっているところはありません。(と思っています。)
    コード生成で生成されたコードは、前述の通りr_cg_serial_userの割り込み処理にフラグ処理を追加した程度で、R_CSI11_Create関数もそのまま使用しています。
    I/Oポートも、P3およびP5も定義されているようです。
    void R_CSI11_Create(void)
    {
    ST0 |= _0008_SAU_CH3_STOP_TRG_ON; /* disable CSI11 */
    CSIMK11 = 1U; /* disable INTCSI11 interrupt */
    CSIIF11 = 0U; /* clear INTCSI11 interrupt flag */
    /* Set INTCSI11 low priority */
    CSIPR111 = 1U;
    CSIPR011 = 1U;
    SIR03 = _0004_SAU_SIRMN_FECTMN | _0002_SAU_SIRMN_PECTMN | _0001_SAU_SIRMN_OVCTMN; /* clear error flag */
    SMR03 = _0020_SAU_SMRMN_INITIALVALUE | _0000_SAU_CLOCK_SELECT_CK00 | _0000_SAU_CLOCK_MODE_CKS |
    _0000_SAU_TRIGGER_SOFTWARE | _0000_SAU_MODE_CSI | _0000_SAU_TRANSFER_END;
    SCR03 = _C000_SAU_RECEPTION_TRANSMISSION | _0000_SAU_TIMING_1 | _0000_SAU_MSB | _0007_SAU_LENGTH_8;
    SDR03 = _CE00_CSI11_DIVISOR;
    SO0 |= _0800_SAU_CH3_CLOCK_OUTPUT_1; /* CSI11 clock initial level */
    SO0 &= ~_0008_SAU_CH3_DATA_OUTPUT_1; /* CSI11 SO initial level */
    SOE0 |= _0008_SAU_CH3_OUTPUT_ENABLE; /* enable CSI11 output */
    /* Set SI11 pin */
    PM5 |= 0x01U;
    /* Set SO11 pin */
    P5 |= 0x02U;
    PM5 &= 0xFDU;
    /* Set SCK11 pin */
    P3 |= 0x01U;
    PM3 &= 0xFEU;
    }

    呼び出す前のif分は、SSR11のエラーチェックをしているだけなので、レジスタはいじっていません。
    すみませんが、ほかに確認する点はございませんでしょうか。
    よろしくお願いします。
Reply
  • チョコさま、ご回答ありがとうございます。
    ソースを確認しましたが、CSIを制御するレジスタを直接いじっているところはありません。(と思っています。)
    コード生成で生成されたコードは、前述の通りr_cg_serial_userの割り込み処理にフラグ処理を追加した程度で、R_CSI11_Create関数もそのまま使用しています。
    I/Oポートも、P3およびP5も定義されているようです。
    void R_CSI11_Create(void)
    {
    ST0 |= _0008_SAU_CH3_STOP_TRG_ON; /* disable CSI11 */
    CSIMK11 = 1U; /* disable INTCSI11 interrupt */
    CSIIF11 = 0U; /* clear INTCSI11 interrupt flag */
    /* Set INTCSI11 low priority */
    CSIPR111 = 1U;
    CSIPR011 = 1U;
    SIR03 = _0004_SAU_SIRMN_FECTMN | _0002_SAU_SIRMN_PECTMN | _0001_SAU_SIRMN_OVCTMN; /* clear error flag */
    SMR03 = _0020_SAU_SMRMN_INITIALVALUE | _0000_SAU_CLOCK_SELECT_CK00 | _0000_SAU_CLOCK_MODE_CKS |
    _0000_SAU_TRIGGER_SOFTWARE | _0000_SAU_MODE_CSI | _0000_SAU_TRANSFER_END;
    SCR03 = _C000_SAU_RECEPTION_TRANSMISSION | _0000_SAU_TIMING_1 | _0000_SAU_MSB | _0007_SAU_LENGTH_8;
    SDR03 = _CE00_CSI11_DIVISOR;
    SO0 |= _0800_SAU_CH3_CLOCK_OUTPUT_1; /* CSI11 clock initial level */
    SO0 &= ~_0008_SAU_CH3_DATA_OUTPUT_1; /* CSI11 SO initial level */
    SOE0 |= _0008_SAU_CH3_OUTPUT_ENABLE; /* enable CSI11 output */
    /* Set SI11 pin */
    PM5 |= 0x01U;
    /* Set SO11 pin */
    P5 |= 0x02U;
    PM5 &= 0xFDU;
    /* Set SCK11 pin */
    P3 |= 0x01U;
    PM3 &= 0xFEU;
    }

    呼び出す前のif分は、SSR11のエラーチェックをしているだけなので、レジスタはいじっていません。
    すみませんが、ほかに確認する点はございませんでしょうか。
    よろしくお願いします。
Children
  • チョコです。
    if ((SSR11 & 0x0040 ) == 0) はTSFビットをチェックしているので,UART2かCSI21かIIC21が
    通信中でないかのチェックですが,何をチェックしているのでしょうか。
    コード生成を使ってなければ,データで使用している兼用ポートの設定がおかしいという
    ところです。兼用ポートの出力ラッチが1になっているかPMレジスタが0になっていかを
    確認してください。SO11はP51なので,まずはここの値を確認してください。
  • チョコです。

    CS+CC-RLの環境でRL78/G13の64pin版で確認してみましたが,ちゃんとSO11にも波形が出ています。

    参考で,画面キャプチャしてPDFを作成したので添付しておきます。

    コード生成でCSI11マスタ送受信.pdf

  • チョコさま、いろいろとありがとうございます。
    ソースを見直しても該当しそうなところが見つかりません。
    もともとSC11端子はデジタル出力、SI11,SO11端子はデジタル入力に設定し、SPI(CSI)は
    別の端子でソフトで実現しようと考えていました。
    マニュアル等をよく読むと、3線式で実現できそうだと考え設定を途中で変えていじっていた
    プログラムです。(3線式はIICのようにSIとSOが同一信号線と思い込んでいました。)
    もしや最初の端子の設定が影響しているのではと思い、新規プロジェクトを作成しました。
    うまく動いていませんが、状況が変わりましたらまたご報告します。
  • チョコです。

    >、SI11,SO11端子はデジタル入力に設定し

    これは明らかな間違いです。

    SI11は入力設定で構いませんが,SO11端子は出力に設定しないといけません。

    参考として,こちらで確認したプロジェクトを添付しておきます。

     

    RL78_CSI_TEST2.zip

  • チョコです。
    追加で説明します。
    SPI(特にマスタ)はCSI+ポート(CS信号出力用)だけで済みます。この場合のSI11信号は
    抵抗でプルアップしておくだけで,基本的にCSIの設定と変わりません。SO11,SCK11は
    共に出力で固定です。
    CSI11で送受信を開始する直前に対象とするスレーブのCS信号をローにします。その後に
    送受信を行い,完了したらCS信号をハイにするだけです。

    SO信号を入力にしておくのはスレーバ側の処理かと思います。(CSで選択されていない時
    には,出力しないようにするため。)
  • チョコさま、サンプルプログラム、ありがとうございます。
    頂いたプロジェクト、および新規に作成したプロジェクトでは、シミュレータで波形を確認できました。
    しかし、最初に作成したプロジェクト(ピン機能を途中でデジタルI/Oから未使用に変更したもの)
    では、うまくいきません。
    これからうまくいったプロジェクトをベースに、他のI/O処理を追加していってみようと思います。
    いろいろとお世話になりました。
    ありがとうございます。

    余談ですが、RL78のCSI(SPI)通信では、送信と同時に受信していますが、一般的なSPIデバイス
    はそうなのでしょうか。
    通信ですから、コマンドを送信した後で返信がくる(受信する)と思うのですが。
    今回接続を試みているのは加速度センサで、コマンドを送ってから返信を受信するものです。
  • チョコです。
    >余談ですが、RL78のCSI(SPI)通信では、送信と同時に受信していますが、一般的なSPIデバイス
    はそうなのでしょうか。
    双方向通信を行う場合には,インタフェースとしては送受信を同時に行う(全二重と呼んでいます)方が
    簡単ではないかと思います。
    ただし,インタフェースとしては全二重でも,上位のプロトコル(加速度センサ等の手順)に従って,
    コマンド等の送信時に受信したデータは無視し,データを受信する時にはダミーデータを送信する
    などで対応します。同時に送受信できるからと言って,送受信データを全て使用する必要はありま
    せん。
    全二重で使いたくない時には,送信と受信を適当に切り替えることで対応できますが,CSIの設定を
    切り替えるのは面倒ではないかと思います。
  • KDX200です。
    チョコさま、確かに送信と受信でCSI設定を切り替えるのは面倒ですね。
    とりあえず必要なバイト数だけ送受信して、必要なものだけを取り出せばいいわけですね。
    そういう使い方でいこうと思います。
    ありがとうございました。
    残った疑問は、途中で端子機能を変えるとCSI信号が出ないということですが。
  • チョコです。
    >残った疑問は、途中で端子機能を変えるとCSI信号が出ないということですが。
    以前にも書きましたように,SO11端子の兼用ポートは出力ラッチ1で出力に設定
    しておかないといけません。
    入力状態PMxx=1の状態で他のビットの操作をやってはいないでしょうか。
    ここらはハードウェア マニュアルの「4. 6 ポート機能使用時の注意事項」を参照
    してください。
  • KDX200です。
    うーん、プログラム中では、このSI11とSO11端子(を含むポート)はr_cg_port.cの中で、
    PM5 = _01_PMn0_NOT_USE | _02_PMn1_NOT_USE | _04_PMn2_MODE_INPUT | _08_PMn3_MODE_INPUT | _10_PMn4_MODE_INPUT |
    _20_PMn5_MODE_INPUT | _C0_PM5_DEFAULT;
    と、r_cg_aerial.cの中で、
    P5 |= 0x02U;
    これらは、コード生成で出力されらものです。
    それ以外のルーチンでは、
    key_inside = (P5 & 0xF8);
    inkey = (P5 & 0xF8);
    といった入力だけなんですけどねえ。
    この& 0xF8というビットマスクして取り込むことが問題なのでしょうかねえ。