RSPI 送信バッファSPTXをクリアしたい

お世話になります。

RX23W   RSPI スレーブモード で使用しています。

マスター側の クロックにのって データ送出されるのですが

なぜか 同じデータが2回送出されたりして、 そのあとデータ送出タイミングが 1個ずつ ずれたりします

SPDR レジスタ に書き込むタイミングと  送信バッファSPTXに書き込まれる タイミングが ずれていくためと思われます

どこかで 送信バッファSPTXをクリア して

  SPDR レジスタ に書き込む   ⇒ SPTXに書き込まれる    ⇒ 次のクロックで送出される

としたいのですが、

助言いただきたく どうぞよろしくお願いいたします。

  • こんにちは hirakuni45 です。

    まず、受信側で何とかしようとせずに、送信側に不具合があるなら、それを修正する事が先決なのでは?


    送信側の修正が何等かの理由で出来ないのでしょうか?

    その場合、ロジックアナライザを繋いで、クロックとデータの関係をキャプチャーするなどして、添付しないと、適切な助言が出来ないと思います。

    それで、頑張ったとしても、実りがあるとは思えませんが・・・


    他に、データ長が、送信側と受信側で違っているとか、クロックの位相と極性の関係が合っていないとか、パリティの有無とか、他の要因も色々考えられますので、それも確認が必要と思います。

  • >まず、受信側で何とかしようとせずに、送信側に不具合があるなら、それを修正する事が先決なのでは?

    確かに。。。

    シーケンスとして 、一連の送受信を考え直します。

    ありがとうございました。

  • atsuatsuさん、こんにちは。NoMaYです。

    もともと単にRSPIスレーブ送信の話では無かったのですか???

  • なぜか わからないのですが  起動後 、 1回目にSPDR レジスタに書き込んだデータが2回続けて送出されるされるという現象があり、(本来なら 次にセットしたデータが 送出してほしかった。)

    よって その後順次  SPDR レジスタにデータを書き込むのですが、 想定より1byteずれていく。

    SPDR レジスタに書き込んでも、 送信バッファが空にならないと 反映されないので、(たぶん。。)

    このようなことが 発生するのかと、 

    対策として どこかのタイミングで   送信バッファをクリアして SPDR レジスタに書き込んだデータを即反映できたらと思いました。

    送信側に不具合があるわけではありませんが 、  同じデータが2回続けて送出される理由もわからないままですし

    送信側との運用で うまいこといけたらと思っています

     

  • atsuatsuさん、こんにちは。NoMaYです。

    > 送信側に不具合があるわけではありませんが 、  同じデータが2回続けて送出される理由もわからないままですし送信側との運用で うまいこといけたらと思っています

    この `送信側` というのはSPIマスタのことですか?

  • atsuatsuさん、こんにちは。(hirakuni45さんも、こんにちは。) NoMaYです。

    > この `送信側` というのはSPIマスタのことですか?

    今回、RX23WがSPIスレーブなのですよね。SPIマスタは何ですか?ラズパイとかですか?

    [追記]

    すみません、↓これで、データ送出しているのは、RX23W側=SPIスレーブ側 ですよね?違うのかな?SPIマスタ側???

    > マスター側の クロックにのって データ送出されるのですがなぜか 同じデータが2回送出されたりして、

    その後、↓このようにも書いていることですし、↑でデータ送出しているのは、RX23W側=SPIスレーブ側 ですよね?

    > なぜか わからないのですが  起動後 、1回目にSPDR レジスタに書き込んだデータが2回続けて送出されるされるという現象があり、(本来なら 次にセットしたデータが 送出してほしかった。)

    [追記2]

    RXスマートコンフィグレータのSPI送受信の、CGコンポーネントもしくはFITモジュール、を使われていないのでしょうか?もし、使いたくない、ということであれば、ごめんなさい、他の人からのリプライを待って頂けないか、と思います。


  • RXスマートコンフィグレータ  コンポーネント 使用しています。

    RX23W側=SPIスレーブ、  別マイコン=SPIマスタ です。

    ↑でデータ送出しているのは、RX23W側=SPIスレーブ側 です。

    現象は とても分かりづらいと思います。伝えきれないです。

    スレーブ側の送信バッファをクリアをする方法があれば と思ったのです

    解決ではありませんが   マスタ側との運用で うまいこといけたらと思っています

    色々 ありがとうございました。

  • atsuatsuさん、こんにちは。NoMaYです。

    もう関わらないで欲しい、と言わんとしていると思しき状況で、リプライを続けるのは嫌がらせと同義とも思いますが、このスレッドを読んだ多くの人は、なぜ同じデータが2回続けて送出される原因を調べて不具合修正することをせずに、強制的に送信バッファ/送信シフトレジスタをクリアするという強引な対処法を取ろうとしているのだろう?と不思議に思っているだろうと思うのです。

    そして、同じデータが2回続けて送出されるのであれば、同じデータを2回SPDRレジスタに書いているのではないかな?ということです。スーパーループのコーディングがバグっていて、そうなっているのではないかな?という可能性です。

    RXスマートコンフィグレータのCGコンポーネントを使用している場合には、以下のAPI関数を呼んでいると思いますが、試しに以下のようなエラーチェックを入れるとどうなりますか?(ちなみに、ソースのコメントにも英語で書いてあるのですが、毎回、送信バッファ/送信シフトレジスタをクリアしている[訂正]クリアしてある状態から始まる、のでした。)

    MD_STATUS R_Config_RSPI0_Send_Receive(uint32_t * const tx_buf, uint16_t tx_num, uint32_t * const rx_buf)
    {
        MD_STATUS status = MD_OK;

        if (tx_num < 1U)
        {
            status = MD_ARGERROR;
        }
        else
        {
            static uint32_t last_tx_buf_0 = 0xffffffff;
            if(last_tx_buf_0 == tx_buf[0]) // あくまで調査用
            {
                nop(); // デバッグ時のブレークポイントの設定用
            }
            last_tx_buf_0 = tx_buf[0];
            if(1U == RSPI0.SPCR.BIT.SPE) // あくまで調査用
            {
                nop(); // デバッグ時のブレークポイントの設定用
            }

            /* Initialize the global counters */
            gp_rspi0_tx_address = tx_buf;
            g_rspi0_tx_count = tx_num;
            gp_rspi0_rx_address = rx_buf;
            g_rspi0_rx_length = tx_num;
            g_rspi0_rx_count = 0U;

            /* Clear SPE bit to ensure transmit buffer empty interrupt be generated
               when state of SPE bit changing from 0 to 1 is satisfied later        */
            if(1U == RSPI0.SPCR.BIT.SPE)
            {
                RSPI0.SPCR.BIT.SPE = 0U;
            }

            /* Enable transmit interrupt */
            RSPI0.SPCR.BIT.SPTIE = 1U;

            /* Enable receive interrupt */
            RSPI0.SPCR.BIT.SPRIE = 1U;

            /* Enable error interrupt */
            RSPI0.SPCR.BIT.SPEIE = 1U;

            /* Enable RSPI function */
            RSPI0.SPCR.BIT.SPE = 1U;
        }

        return (status);
    }

     
    [追記]

    なお、以下のスレッドはRSPIマスタの場合のものですが、RSPIは初学者さんには難しいと思います。もし、転送ビットが8の倍数であれば簡易SPIスレーブを試してみるの一案だと思います。

    RX231 でのコード生成を利用した、RSPIモジュールの利用方法について(データのアクセス単位で混乱しています)
    japan.renesasrulz.com/cafe_rene/f/forum5/5670/rx231-rspi/31588#31588

    [追記2]

    以下、RX23Wグループ ユーザーズマニュアル ハードウェア編からの引用です。

    R01UH0823JJ0100 Rev.1.00 Pages 1842 2019.07.31

    38.3.9.1 SPE ビットのクリアによる初期化
    SPCR.SPE ビットを“0” にしたとき、RSPI は以下に示す初期化を実施します。
    ・ 実行中のシリアル転送を中断
    ・ スレーブモードの場合、出力信号のドライブ停止(Hi-Z)
    ・ RSPI 内部ステートの初期化 ← 送信シフトレジスタのクリアを含む、と思うのだけれども。
    ・ RSPI 送信バッファを空にする(SPTEF フラグを“1” にする)