web-dev-qa-db-ja.com

stm32f4でハードウェアNSS(SPI)を使用する方法

そのため、HALライブラリでハードウェアNSS信号を使用しようとしましたが、NSSピンを低レベルまたは高レベルにする機能が見つかりません。私もHALのドキュメントで答えを見つけようとしましたが、情報もありません。インターネットのすべての例には、ソフトウェアNSSのみが含まれています。どのようにハードウェアNSSを使用することになっていますか?

8
mkom

SPIマスターが有効で、SPIマスターが無効である場合、マスターが無効になっている限り、NSSはローに駆動されます。 STのSTM32L476を使用し、SPI1をポーリングするHALライブラリ(Cube/CubeMX)。送信前の初期化と送信後の非初期化では、NSSピンが設定されませんでしたが、時間がかかりました。

初期構造:

hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
hspi1.Init.CLKPhase = SPI_PHASE_2Edge;
hspi1.Init.NSS = SPI_NSS_HARD_OUTPUT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 7;
hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi1.Init.NSSPMode = SPI_NSS_Pulse_DISABLE;

送信シーケンス:

HAL_SPI_Init( &hspi1 );
HAL_SPI_TransmitReceive( &hspi1, btx, brx, l, 5 ); // timeout 5msec;
while( hspi1.State == HAL_SPI_STATE_BUSY );  // wait for xmission complete
HAL_SPI_DeInit( &hspi1 );

そこで、GPIOを使用して(initでSPI_NSS_SOFTを使用して)ピンを手動で設定することにしました。

HAL_GPIO_WritePin( NSS1_GPIO_Port, NSS1_Pin, GPIO_PIN_RESET ); // NSS1 low
HAL_SPI_TransmitReceive( &hspi1, btx, brx, l, 5 ); // timeout 5msec;
while( hspi1.State == HAL_SPI_STATE_BUSY );  // wait xmission complete
HAL_GPIO_WritePin( NSS1_GPIO_Port, NSS1_Pin, GPIO_PIN_SET ); // NSS1 high

十分な速度があり、他のタスクが待機していないため、ブロック送信(DMAまたは割り込み)を使用しませんでした。DMAセットアップは、送信のみに許容できないほど長い時間がかかることが判明しました20MHzで24バイト。ITは許容可能な代替手段です。

STM32L4xxマニュアルの第38.4.12/13章で確認できる限り、自動NSSは各バイト/ワード送信後に高くなるため、送信全体でNSSを低く保持する長いストリームには十分に使用できません。

7
peets

NSSピンを標準GPIOとして使用し、割り込みルーチンで駆動することができます。その部分はソフトウェアで実行する必要があります。最初にNssをLowにしてからフレームを送信します(HAL_SPI_Transmit)スレーブがすべてのフレームを取得したら、HAL_SPI_RxCpltCallbackを使用し、その割り込みでNssを高くします。

GPIOピンをスレーブのNssピンに接続することを忘れないでください。

2
B. Canturk

HiZの場合、NSSピンにはプルアップ抵抗が必要な場合があります[ドキュメントに記載されていません]

1
Cris

STM32チップのリファレンスマニュアルをご覧ください。それらがすべて同じかどうかはわかりませんが、私のもの(STM32WB55xx)によると、( STM32F )へのパブリックWebリンクを見つけることができました...

SPI NSSピン管理の機能説明(リンク先のSTM32F0文書についてはセクション28.5.5))を参照してください。ここでは、3つのモードについて説明しています。

  • ソフトウェアNSS管理(SPIx_CR1レジスタSSMビット= 1)。内部スレーブ選択情報は、レジスタSPIx_CR1のSSIビットによって内部で駆動されます。外部NSSピンは、アプリケーションで自由に使用できます。

  • ハードウェアNSS管理(SSMビット= 0)。これには、レジスタSPIx_CR1のSSOEビットに応じて2つの可能な構成があります。

    • NSS出力イネーブル(SSOE = 1)。 MCUがマスターの場合にのみ使用されます。 NSS信号は、SPIがマスターモード(SPE = 1)で有効になるとすぐにLowに駆動され、SPIが無効になるまで(SPE = 0 )NSSパルスモードがアクティブ化されている場合、連続通信間でパルスを生成できます。SPIは、このNSS設定のマルチマスター構成では機能しません
    • NSS出力の無効化(SSOE = 0)。 MCUがマスターの場合、これによりマルチマスター機能が可能になります。 NSSがLowにプルされると、SPIがマスターモードの障害状態になり、デバイスはスレーブモードで自動的に再構成されます。スレーブモードでは、NSSピンは標準の「チップセレクト」入力として機能し、スレーブNSSラインがローレベルのときに選択されます。

私のSoCのヘッダーを見ると、ソフトモードはSSM = 1(ソフトウェアNSS管理)です。ハード出力モードは、SSM = 0およびSSOE = 1(NSS出力有効)です。ハード入力モードはすべてゼロ(NSS出力無効)です。

ハード出力モードを使用している場合は、NSSパルスモード(リンク先のSTM32F0ドキュメントのセクション28.5.12)もご覧ください。これは、システムがほとんどの場合NSSを低くして、データフレーム間でNSSを高くパルスする方法を(タイミング図とともに)示しています。デバイスがNSS/CSを使用してデータフレームを同期する場合、これが役立つことがあります。または、デバイスが現在の操作を中止することによってNSSが高くなることに反応する場合、テキストがそれがバッファ間ではなく、転送するすべてのワード間でNSSをパルスするように見えるため、そうでない場合があります。

残念ながら、これは最も柔軟な実装のようには見えません。アプリケーションによっては、ソフトモードのままにして、GPIOを介してNSSピンを切り替えるだけの方が簡単な場合があります。

0
David C.