📄 hw_spi.c
字号:
return;
}
/**************************************************************************
* 函数描述: 从SPI从设备读数据
* 入口参数: size -- 数据大小
* config -- SPI配置属性
* 出口参数: pdata -- 指向读出的数据
* 返回值: rxCount -- 读出的数据个数
***************************************************************************/
// SPI_RxCR 的count值范围0~65536,因此size类型为UINT16
// polling mode
UINT16 SPI_Read(UINT8 *pdata, UINT16 size, UINT8 config) // 每次读写都要将clock传入参数
{
UINT16 rxCount = 0;
/* Check if SPI controller is running */
if (IS_SPI_RUNNING())
return FALSE;
/* Set transfer data count */
WriteReg32(&pSPIReg->SPI_RxCR, size);
// make sure we have a receive buffer
if (spiRxBuffer.size)
{
// make sure we have data
if (spiRxBuffer.datalength < 1)
{
// no data
return 0;
}
/* Start SPI transfer */
SPI_START_TRANSFER();
while (spiRxBuffer.datalength)
{
// get byte from beginning of buffer
*pdata = bufferGetFromFront(&spiRxBuffer);
pdata++;
rxCount++;
}
}
else
{
// no buffer
return 0;
}
return rxCount;
}
/**************************************************************************
* 函数描述: 向SPI从设备写数据
* 入口参数: pdata -- 待写入的数据指针
* size -- 数据大小
* config -- SPI配置属性
* 出口参数: 无
* 返回值: 1 -- 写成功
* 0 -- 写失败
***************************************************************************/
// SPI_TxCR 的count值范围0~65536,因此size类型为UINT16
// interrupt mode
UINT16 SPI_Write(UINT8 *pdata, UINT16 size, UINT8 config) // 每次读写都要将clock传入参数
{
/* Check if SPI controller is running */
if (IS_SPI_RUNNING())
return 0;
/* Set transfer data count */
WriteReg32(&pSPIReg->SPI_TxCR, size);
SET_RECEIVE_COUNT(size); // only for loopback test
/* Write the first character into tx fifo */
if (size > 1)
{
spiSendBuffer(pdata, size);
/* Start SPI transfer */
SPI_START_TRANSFER();
}
else if (size == 1)
{
WriteReg32(&pSPIReg->SPI_TxR, pdata[0]);
/* Start SPI transfer */
SPI_START_TRANSFER();
}
else
{
return 0;
}
return 1;
}
int SPILoopFunctionTest()
{
int recvCount = 0;
cBuffer recvBuffer;
unsigned char rxData;
unsigned char *testBuffer = (unsigned char *)PATTERN_BUFFER_BASE;
//memset((char *)spiRxBufferSpace, 0, sizeof(spiRxBufferSpace));
//memset((char *)spiTxBufferSpace, 0, sizeof(spiTxBufferSpace));
// setup testing pattern
initSPITestPattern(testBuffer, PATTERN_BUFFER_SIZE);
#if 1 // buffer
// setup receive data buffer
memset((char *)RECEIVE_DATA_BASE, 0, RECEIVE_DATA_SIZE);
bufferInit(&recvBuffer, (unsigned char *)RECEIVE_DATA_BASE, PATTERN_BUFFER_SIZE);
#endif
SPI_Write(testBuffer, TESTING_DATA_SIZE, 1);
//SPI_Read(NULL,TESTING_DATA_SIZE, 1);
#if 1 // buffer
while (recvCount < TESTING_DATA_SIZE)
{
while (!spiReceiveBufferIsEmpty())
{
// get receive data from uart receive buffer
if (spiReceiveByte(&rxData))
{
// save data into receive buffer
bufferAddToEnd(&recvBuffer, rxData); //将读的数据保存到buffer结构成员buffer->dataptr中
recvCount++;
}
}
}
#endif
// check testing data
#if 1 // buffer
if (0 != memcmp((unsigned char *)RECEIVE_DATA_BASE, (unsigned char *)PATTERN_BUFFER_BASE, TESTING_DATA_SIZE))
#else
if (0 != memcmp(spiRxBufferSpace, (unsigned char *)PATTERN_BUFFER_BASE, TESTING_DATA_SIZE))
#endif
return FALSE;
return TRUE;
}
/**************************************************************************
* 函数描述: 初始化SPI
* 入口参数: 无
* 出口参数: 无
* 返回值: TRUE -- 初始化成功
* FALSE -- 初始化失败
***************************************************************************/
BOOL SPI_PowerOnInit(void)
{
// initialize the buffers
SPIInitBuffers();
// initialize SPI
SPIInitController();
Intr_RegISR(INTC_SPI, SPI_IntrHandler);
// enable SPI interrupt
SPI_INT_ENABLE(IE_RXCP | IE_OR | IE_RX | IE_TX);
Intr_Enable(INTC_SPI);
// initialize states
spiReadyTx = TRUE;
return TRUE;
}
BOOL SPI_PowerOffDeinit(void)
{
// disable SPI master
ClrRegBits32(&pSPIReg->SPI_FWCR, 0x1 << 10);
return TRUE;
}
int spiLoopBackTest(int autotest)
{
SPI_PowerOnInit();
// set SPI into internal loopback mode
SPI_LOOPBACK_EN();
// config FIFO
SPI_CLEAR_TX_FIFO();
SPI_CLEAR_RX_FIFO();
SPI_TX_FIFO_THRESH_4();
SPI_RX_FIFO_THRESH_4();
// config clock count
spiSetClockDelay(CLOCK_HALF, CLOCK_ZERO, CLOCK_ZERO);
// set read & write concurrently
SPI_CONCURRENT_EN();
SPI_SELECT_SLAVE(0);
if (TRUE != SPILoopFunctionTest())
{
// clear SPI loopback mode
SPI_LOOPBACK_DIS();
return FALSE;
}
// clear SPI loopback mode
SPI_LOOPBACK_DIS();
return TRUE;
}
#if 0
void SPI_Open(UINT32 ChipSelect, UINT32 DataLength, UINT32 FreqKHz,)
{
UINT32 divisor;
divisor = Pll_get_apb_freq() * 1000 / FreqKHz;
if (DataLength > 8)
gSpiDataAlign = 16;
else
gSpiDataAlign = 8;
// 复位 SPI 控制器
SPI_RESET();
// 设置 SPI master 模式
SPI_MASETR_EN();
// 选中 SPI slave 设备
SPI_SELECT_SLAVE(ChipSelect);
// 传输的字长单位 ( 4~16 bit )
SET_BIT_LENGTH(DataLength - 1);
// 设置SPI的时钟频率
SET_CLOCK_DIVISOR(divisor);
// 清除 SPI FIFO
SPI_CLEAR_TX_FIFO();
SPI_CLEAR_RX_FIFO();
// 设置 FIFO 中断触发门槛
SPI_TX_FIFO_THRESH_4();
SPI_RX_FIFO_THRESH_4();
}
BOOL SPI_Write(void* pdata, UINT16 size)
{
BOOL rc = FALSE;
UINT32 mask;
// Check buffer alignment
mask = (1 << gSpiDataAlign) - 1;
if (((UINT32)pdata & mask) != 0) goto cleanUp;
if (((UINT32)size & mask) != 0) goto cleanUp;
/* Check if SPI controller is running */
if (IS_SPI_RUNNING()) goto cleanUp;
/* Set transfer data count */
WriteReg32(&pSPIReg->SPI_TxCR, size);
while (size > 0)
{
switch (gSpiDataAlign)
{
case 0:
SPI_WRITE_DATA(*((UINT8*)pdata)++);
size -= sizeof(UINT8);
break;
case 1:
SPI_WRITE_DATA(*((UINT16*)pdata)++);
size -= sizeof(UINT16);
break;
default:
goto cleanUp;
}
/* Start SPI transfer */
SPI_START_TRANSFER();
while (!CHECK_TRANSMIT_FIFO(ReadReg32(&(pSPIReg->SPI_ISR))));
}
// Done
rc = TRUE;
cleanUp:
return rc;
}
void SPI_Close()
{
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -