ADSP-21488 Master SPI

ADSP-21488 master SPI driver ADS7868

  • 在使用ADSP-21488的SPI主模式讀取ADS7868芯片的數據時,一開始的讀模塊的驅動函數在讀取數據前沒有先寫一下數據導致折騰好長時間SPI讀取數據的功能不成功,因爲我的產品只用三根線CS、MOSI、SCLK沒有使用寫的數據線,所以在啓動SPI 通訊時主機沒有線發個寫的操作再去讀數據,導致SPI的時鐘信號起不來。

連接圖

在這裏插入圖片描述

讀數據的代碼

/**
  * @brief  ReadByteFromSPI(int *pbyByte, const int msb_lsb)
  * @param
       Reads one byte from the spi port.  This may or may not cause a sclk or send
       event.  If there is something waiting in the spi RX buffer, this will not
       cause an sclk shift from the spi
  * @retval NO_ERR
  */
ERROR_CODE ReadByteFromSPI(int *pbyByte, const int msb_lsb)
{
	int nTimeOut = 1000;

    if( NO_ERR != Wait_For_SPIF() )
	{
		return POLL_TIMEOUT;
	}
	// don't read until there is something to read.
	// as a master mode needs to send data to slave first then read the datas
	*pTXSPIB = 0x0000;

	while( !(RXS & *pSPISTATB) )
	{
		if( nTimeOut-- < 0 )
		{
			return POLL_TIMEOUT;
		}
	}
	*pbyByte = *pRXSPIB & 0x0FF0;
	*pbyByte >>= 4;    /*Low four bits is garbage data*/

	return NO_ERR;

}
  • 程序中倘若不寫*pTXSPIB = 0x0000即主機不發寫命令則SPI總線的時鐘無法啓動,這樣也將無法使用讀命令去讀取從機BUFF中的數據。

主機SPI的配置

  • ADSP-21488配置主機SPI的詳細資料有很多,官方的芯片手冊相應的SPI部分寫的很清楚,這裏講述一下在配置SPI的SPI_CS線的兩種方式。
  1. 用戶在操作SPI時手動控制SPI_CS的選擇和釋放,這種方式用戶在讀取數據時要先手動選擇SPI_CS信號然後讀取數據再釋放數據,如下程序所示,調用Assert_SPI_CS(void)Clear_SPI_CS(void)來完成SPI_CS信號的使能和釋放,ReadADC(int *pBuffer)裏可以看到具體的應用;
  2. 由主機自動控制SPI_CS的使能和釋放,這種方式下只要配置好SPIFLGB_EN爲使能並且物理鏈路到對應的CS引腳,配置完之後,在操作SPI總線時,主機會自動控制SPI_CS的使能和釋放,即在發送讀命令時,自動把SPI_CS拉低使能等數據讀完了在自動把SPI_CS拉高釋放,這就不需要使用Assert_SPI_CS(void)Clear_SPI_CS(void)這兩函數來手動操作SPI_CS了,ReadADC(int *pBuffer)裏可以看到具體的應用。
void Clear_SPI_CS(void);
void Assert_SPI_CS(void);
/* Exported constants --------------------------------------------------------*/

void Assert_SPI_CS(void)
{
    //Then control the level of flag 4
	sysreg_bit_clr( sysreg_FLAGS, FLG4 );  //logic low
}

void Clear_SPI_CS(void)
{
    //Then control the level of flag 4
	sysreg_bit_set( sysreg_FLAGS, FLG4 );  //Logic high
}
/**
  * @brief  SPI init function
     DPI PINs:
		DPI_P06 --> SPI_DS (Master mode)
		DPI_P10 <-- SPI_CLK
		DPI_P09 --> SPI_MISO
		SPI_MOSI unused!
  * @retval None
  */
ERROR_CODE SetupSPIforADC(void)
{
	SRU2(SPIB_CLK_O,DPI_PB10_I);
	SRU2(HIGH,DPI_PBEN10_I);
    //SRU2(SPIB_CLK_PBEN_O, DPI_PBEN10_I);

    SRU2(DPI_PB09_O, SPIB_MISO_I);     /*Connect DPI PB9 to MISO*/
    SRU2(LOW, DPI_PBEN09_I);     /*set DPI PB09 input*/
    //SRU(SPIB_MISO_PBEN_O, DPI_PBEN09_I);
#if SPIFLGB_EN
    // for the ADC pins to act as chip select
    SRU2(SPIB_FLG0_O, DPI_PB06_I);     /*Connect SPI_FLG0  DS to DPI PB06.*/
    SRU2(SPIB_FLG0_PBEN_O, DPI_PBEN06_I);
    //SRU2(HIGH, DPI_PBEN06_I);     /*set DPI PB06 output*/
	*pSPIFLGB = 0xF81;
#else
	// for the flag pins to act as chip select
	SRU2(FLAG4_O, DPI_PB06_I);
	SRU2(HIGH, DPI_PBEN06_I);

	//First set flag 4 as an output
	sysreg_bit_set( sysreg_FLAGS, FLG4O );    //asm("bit set flags FLG4O;");
	sysreg_bit_set( sysreg_FLAGS, FLG4 );    //Logic high
#endif

    *pSPIDMACB = 0;
	*pSPIBAUDB = BAUD_RATE_DIVISOR;
	*pSPICTLB = (SPIEN|SPIMS|SENDZ|TIMOD1|WL16|MSBF);
    return NO_ERR;
}
/**
  * @brief  ReadBuffer
  * @PURPOSE (1 Byte)
 		Returns the 16-bit value of the Buffer
  * @OUTPUTS  	second read byte ,
        		       first 4 read bit is garbage.
			      Core sends the command
  * @retval None
  */

ERROR_CODE ReadADC(int *pBuffer)
{
	// clear the TX or RX buffer
	*pSPICTLB |= (RXFLSH | TXFLSH);
	asm("nop;");
	asm("nop;");
	asm("nop;");
    // enable TX and RX buffer
	*pSPICTLB &= ((~RXFLSH) & (~TXFLSH));

#if SPIFLGB_EN
	// This is a dummy read which pulls in the
	// SO data clocked in from the write.
	if( NO_ERR != ReadByteFromSPI(pBuffer, MSBF) )
	{
		return POLL_TIMEOUT;
	}
#else
	Assert_SPI_CS();
	// This is a dummy read which pulls in the
	// SO data clocked in from the write.
	if( NO_ERR != ReadByteFromSPI(pBuffer, MSBF) )
	{
		Clear_SPI_CS();
		return POLL_TIMEOUT;
	}
	Clear_SPI_CS();
#endif

	return NO_ERR;

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章