This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

  • Resolved

MSP430: F5528 USCI SPI TxとRx、DMA転送時 Txの方が早く転送される

Prodigy 150 points

Replies: 4

Views: 2398

MSP430F5528で、USCI_A0 SPIとDMA Ch0、 Ch1を使用し、DMA転送だけでSPI Rxレジスタから規定サイズ受信するようにしたいため、受信するためにTxレジスタへDMA Ch0からダミーデータ(0xFF)を受信サイズと同じサイズ送信させています。送信&受信をしている途中で、RxレジスタからDMA Ch1が変数配列にデータを転送する前にDMA Ch0がTxレジスタへデータを転送してTxの方が早く動くことがあり、最終的に同じサイズで同時にスタートしたDMA Ch0とCh1の転送が、Tx側のDMA Ch0の方が転送完了してRx側のDMA Ch1が数バイト転送足りない状態でDMAが転送未完了になります。

SPI RxレジスタのデータをDMA転送してからTxレジスタへDMA転送し、Rxのデータを受信漏れがなく受け取りたいのですが、何か方法がありますでしょうか?

以下、SPIとDMAの設定部分ソースコードです。

DMA_initParam initParam0 = {0}; 

uint32_t readbytes_num = ubSize;

//受信IFGクリア
USCI_A_SPI_clearInterrupt(USCI_A0_BASE,
USCI_A_SPI_RECEIVE_INTERRUPT);

//DMA0設定
initParam0.channelSelect = DMA_CHANNEL_0;
initParam0.transferModeSelect = DMA_TRANSFER_SINGLE;
initParam0.transferSize = 2048;
initParam0.triggerSourceSelect = DMA_TRIGGERSOURCE_17; //USCI A0 SPI TX
initParam0.transferUnitSelect = DMA_SIZE_SRCBYTE_DSTBYTE;
initParam0.triggerTypeSelect = DMA_TRIGGER_RISINGEDGE;
DMA_init(&initParam0);

DMA_disableTransfers(DMA_CHANNEL_0);

//DMA 1設定
initParam0.channelSelect = DMA_CHANNEL_1;
initParam0.transferModeSelect = DMA_TRANSFER_SINGLE;
initParam0.transferSize = 2048;
initParam0.triggerSourceSelect = DMA_TRIGGERSOURCE_16; //USCI A0 SPI RX
initParam0.transferUnitSelect = DMA_SIZE_SRCBYTE_DSTBYTE;
initParam0.triggerTypeSelect = DMA_TRIGGER_RISINGEDGE;
DMA_init(&initParam0);

DMA_disableTransfers(DMA_CHANNEL_1);

//TX
DMA_setSrcAddress(DMA_CHANNEL_0,
(uint32_t)kaguc_Nand_Rd_Txdummyarray,     //ダミー送信用const配列
DMA_DIRECTION_INCREMENT);

DMA_setDstAddress(DMA_CHANNEL_0,
USCI_A_SPI_getTransmitBufferAddressForDMA(USCI_A0_BASE),
DMA_DIRECTION_UNCHANGED);

//RX
DMA_setSrcAddress(DMA_CHANNEL_1,
USCI_A_SPI_getReceiveBufferAddressForDMA(USCI_A0_BASE),
DMA_DIRECTION_UNCHANGED);

DMA_setDstAddress(DMA_CHANNEL_1,
(uint32_t)ubBuffer,                                                  //受信格納変数配列
DMA_DIRECTION_INCREMENT);

DMA_clearInterrupt(DMA_CHANNEL_0);
DMA_clearInterrupt(DMA_CHANNEL_1);

//Enable DMA1 Rx側から有効化
DMA_enableTransfers(DMA_CHANNEL_1);
//Enable DMA0
DMA_enableTransfers(DMA_CHANNEL_0);

  • F5528 SPI

    1 SPIの特性

    ・ まずmasterかslaveかで、送受信の様相が全く異なります。
    ・ 下記から、MSP430SPI概要と留意点.pdf を見ていただけますか。
      e2e.ti.com/.../469471

    2 masterとして考えると

    ・ TXを書くと同時にCLKが出ますので、最初にRX設定してenableにしておきます。

    ・ 1-2 送信・受信 の図2に有るように、クロックの両サイド・エッジでTXとRXが動きます。
      RXが遅れることは有りません。 SPIのHWとISRはTXとRXがほぼ同時に動いています。

    ・ RXのsizeが小さい=取りこぼしている理由は、まずアプリケーションのタイミング・動作遅れの
      可能��が高いです。
      LPM0を使い、CPU・MCLKをmax、SPIの送信速度をminにして動作するか確認してみてください。

    ・ 1-2 送信・受信に書いた、SIMOを自分のSOMIに折り返して試験ができます。
      12345と送信して、受信取りこぼすか、他の原因が有るのか、切り分けできます。


    3 master-slave間の送受信

    ・ 2-2 クロックと2-3 pull-up(/down)に留意してください。

    Kazuo Yamauchi

  • In reply to trout:

    ご回答ありがとうございます。
    PDF資料とコメントを確認いたしました。
    F5528のSPIはマスター側で使用しています。スレーブ側の制御はCSのHi-Loでスリープとアクティブ制御しています。
    コメント2のCPU・MCLKとSPIのクロック速度に差をつける確認はやっていなかったので、確認いたします。
    ただ、可能な限りSPIをCPUと同じ高速で動かしたいので、できればCPU・MCLK=SPIクロックで動かしたいです。

    あと、1つDMA設定でお聞きしたいのですが、下記フォーラム記事
     e2e.ti.com/.../258278
    で、DMAの優先度ラウンドロビンを無効にしないとTxとRxのDMA転送順番に影響が出るようなことが書かれているように見えたのですが、これも影響しますでしょうか?
  • In reply to user3933138:

    F5528 SPI & DMA

    相手は、memoryデバイスでしょうか。

    1 >CPU・MCLK=SPIクロックで動かしたいです。

    ・ これは、DMAを使っても原理的に不可能です。 max:MCLK/4
      UGの 11.1 Direct Memory Access (DMA) Introduction
      • Requires only two MCLK clock cycles per transfer
    ・ 他の命令実行にもバスを使いますから、余裕がないとバス獲得で衝突したら
      受信漏れます。

    ・ MCLK=25MHzにして、SPIの通信速度を少しずつ上げて安定通信できる
      ところを見つけた方が良いです。

    2 高周波の通信

    ・ 信号路の信号なまり、ノイズが影響します。
    ・ スレーブ側とタイミング確認が必須です。

    ・ e2e情報:SPIのDMAは送信・受信と動くので影響ないと思います。
      他のDMAとぶつかり時間余裕がないならトラブルになるかもしれませんが、
      本来スループットに余裕がない・・システム設計の問題かと思います。

    Kazuo Yamauchi

  • In reply to trout:

    回答ありがとうございます。SPI&DMAでMCLK/4上限(24MHz/4=6MHz)で、再度SPI通信速度を検討しなおそうと思います。

This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.