AT91SAM7X512のSPIペリフェラルは、書き込みを行うX時間(Xは変化します)で無効になりますSPI_TDR
。その結果、プロセッサはでTDRE
フラグをチェックするwhileループでハングしSPI_SR
ます。このwhileループはSPI_Write()
、ATMELが提供するソフトウェアパッケージ/ライブラリに属する関数にあります。問題は任意に発生します。すべてが正常に機能する場合もあれば、繰り返し試行しても失敗する場合もあります(試行=同じバイナリをMCUにダウンロードしてプログラムを実行する)。
構成は次のとおりです(書き込み順に定義)。
SPI_MR
:MSTR
= 1PS
= 0PCSDEC
= 0PCS
= 0111DLYBCS
= 0
SPI_CSR[3]
:CPOL
= 0NCPHA
= 1CSAAT
= 0BITS
= 0000SCBR
= 20DLYBS
= 0DLYBCT
= 0
SPI_CR
:SPIEN
= 1
構成を設定した後、コードはSPIENS
フラグをチェックすることにより、SPIが有効になっていることを確認します。
次のようにバイトの送信を実行します。
const short int dataSize = 5;
// Filling array with random data
unsigned char data[dataSize] = {0xA5, 0x34, 0x12, 0x00, 0xFF};
short int i = 0;
volatile unsigned short dummyRead;
SetCS3(); // NPCS3 == PIOA15
while(i-- < dataSize) {
mySPI_Write(data[i]);
while((AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
dummyRead = SPI_Read(); // SPI_Read() from Atmel's library
}
ClearCS3();
/**********************************/
void mySPI_Write(unsigned char data) {
while ((AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
AT91C_BASE_SPI0->SPI_TDR = data;
while ((AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_TDRE) == 0); // <-- This is where
// the processor hangs, because that the SPI peripheral is disabled
// (SPIENS equals 0), which makes TDRE equal to 0 forever.
}
質問:
- 書き込み時にSPIペリフェラルが無効になる原因は何
SPI_TDR
ですか? レジスタ
SPI_Write()
を読み取る行のコメントを解除する必要がありますか? つまり、次のコードの4行目:( 4行目は元々コメントとしてマークされています)SPI_RDR
void SPI_Write(AT91S_SPI *spi, unsigned int npcs, unsigned short data) { // Discard contents of RDR register //volatile unsigned int discard = spi->SPI_RDR; /* Send data */ while ((spi->SPI_SR & AT91C_SPI_TXEMPTY) == 0); spi->SPI_TDR = data | SPI_PCS(npcs); while ((spi->SPI_SR & AT91C_SPI_TDRE) == 0); }
5バイトのデータを送信する上記のコードに何か問題がありますか?
ご注意ください:
- NPCS行番号。3はGPIOライン(つまり、PIOモード)であり、SPIコントローラーによって制御されません。必要に応じてChipSelect#3(NPCS3)ピンをデ/アサートすることにより、コード内でこの行を自分で制御しています。私がそうしている理由は、SPIコントローラーにこのピンを制御させようとしたときに問題が発生したためです。
- 私はPDC/DMAコントローラーを使用せず、使用しないことを好みました。
SPIペリフェラルを2回リセットしませんでした。これは、リセットを実行した場合にのみエラッタが2回リセットするように指示しているためです。これは実行しません。正誤表の引用:
ソフトウェアリセット(SPI制御レジスタのSWRST)を実行すると、SPIが正しく動作しない場合があります(チップセレクトの前にクロックが有効になります)。
問題の修正/回避策
SPI制御レジスタフィールドのSWRST(ソフトウェアリセット)は次のようになります。正しく設定するために2回書き込まれます。レジスター(in )への書き込みの前に遅延を設定すると、コードが完全に機能し、通信が成功する場合があることに気付きました。
SPI_TDR
SPI_Write()
便利なリンク:
SPIを初期化し、5バイトの転送を実行する例は、高く評価されており、役に立ちます。