📄 mrfi_spi.c
字号:
*/
static uint8_t spiRegAccess(uint8_t addrByte, uint8_t writeValue)
{
uint8_t readValue;
mrfiSpiIState_t s=0;
//MRFI_SPI_ASSERT( MRFI_SPI_IS_INITIALIZED() ); /* SPI is not initialized */
/* disable interrupts that use SPI */
MRFI_SPI_ENTER_CRITICAL_SECTION(s);
/* turn chip select "off" and then "on" to clear any current SPI access */
MRFI_SPI_TURN_CHIP_SELECT_OFF();
MRFI_SPI_TURN_CHIP_SELECT_ON();
while( GPIO_ReadInput(CSPIPort) & CSPISO );
/* send register address byte, the read/write bit is already configured */
// MRFI_SPI_WRITE_BYTE(addrByte);
// MRFI_SPI_WAIT_DONE();
while ( (LPC_SSP0->SR & (SSP_SR_TNF|SSP_SR_BSY)) != SSP_SR_TNF );
LPC_SSP0->DR = addrByte;
//while ( LPC_SSP0->SR & SSP_SR_BSY );
while ( (LPC_SSP0->SR & (SSP_SR_BSY|SSP_SR_RNE)) != SSP_SR_RNE );
mrfiRadioState = LPC_SSP0->DR;
//while ( LPC_SSP0->SR & SSP_SR_BSY );
/*
* Send the byte value to write. If this operation is a read, this value
* is not used and is just dummy data. Wait for SPI access to complete.
*/
while ( (LPC_SSP0->SR & (SSP_SR_TNF|SSP_SR_BSY)) != SSP_SR_TNF );
LPC_SSP0->DR = writeValue;
//while ( LPC_SSP0->SR & SSP_SR_BSY );
//MRFI_DELAY(5);
/*
* If this is a read operation, SPI data register now contains the register
* value which will be returned. For a read operation, it contains junk info
* that is not used.
*/
while ( (LPC_SSP0->SR & (SSP_SR_BSY|SSP_SR_RNE)) != SSP_SR_RNE );
readValue = LPC_SSP0->DR;
//while ( LPC_SSP0->SR & SSP_SR_BSY );
//MRFI_DELAY(20);
/* turn off chip select; enable interrupts that call SPI functions */
MRFI_SPI_TURN_CHIP_SELECT_OFF();
MRFI_SPI_EXIT_CRITICAL_SECTION(s);
/* return the register value */
return(readValue);
}
/**************************************************************************************************
* @fn mrfiSpiWriteTxFifo
*
* @brief Write data to radio transmit FIFO.
*
* @param pData - pointer for storing write data
* @param len - length of data in bytes
*
* @return none
**************************************************************************************************
*/
void mrfiSpiWriteTxFifo(uint8_t * pData, uint8_t len)
{
spiBurstFifoAccess(TXFIFO | BURST_BIT, pData, len);
}
/**************************************************************************************************
* @fn macSpiReadRxFifo
*
* @brief Read data from radio receive FIFO.
*
* @param pData - pointer for storing read data
* @param len - length of data in bytes
*
* @return none
**************************************************************************************************
*/
void mrfiSpiReadRxFifo(uint8_t * pData, uint8_t len)
{
spiBurstFifoAccess(RXFIFO | BURST_BIT | READ_BIT, pData, len);
}
/*=================================================================================================
* @fn spiBurstFifoAccess
*
* @brief Burst mode access used for reading or writing to radio FIFOs.
*
* For more efficient interrupt latency, this function does not keep interrupts
* disabled for its entire execution. It is designed to recover if an interrupt
* occurs that accesses SPI. See comments in code for further details.
*
* @param addrByte - first byte written to SPI, contains address and mode bits
* @param pData - pointer to data to read or write
* @param len - length of data in bytes
*
* @return none
*=================================================================================================
*/
static void spiBurstFifoAccess(uint8_t addrByte, uint8_t * pData, uint8_t len)
{
mrfiSpiIState_t s=0;
uint8_t i8Temp = 0;
//MRFI_SPI_ASSERT( MRFI_SPI_IS_INITIALIZED() ); /* SPI is not initialized */
MRFI_SPI_ASSERT(len != 0); /* zero length is not allowed */
MRFI_SPI_ASSERT(addrByte & BURST_BIT); /* only burst mode supported */
/* disable interrupts that use SPI */
MRFI_SPI_ENTER_CRITICAL_SECTION(s);
/* turn chip select "off" and then "on" to clear any current SPI access */
MRFI_SPI_TURN_CHIP_SELECT_OFF();
MRFI_SPI_TURN_CHIP_SELECT_ON();
//while ( (LPC_SSP0->SR & (SSP_SR_BSY|SSP_SR_RNE)) != SSP_SR_RNE );
//i8Temp = LPC_SSP0->DR;
/*-------------------------------------------------------------------------------
* Main loop. If the SPI access is interrupted, execution comes back to
* the start of this loop. Loop exits when nothing left to transfer.
*/
do
{
/* send FIFO access command byte, wait for SPI access to complete */
// MRFI_SPI_WRITE_BYTE(addrByte);
// MRFI_SPI_WAIT_DONE();
while ( (LPC_SSP0->SR & (SSP_SR_TNF|SSP_SR_BSY)) != SSP_SR_TNF );
LPC_SSP0->DR = addrByte;
//while ( LPC_SSP0->SR & SSP_SR_BSY );
//while ( (LPC_SSP0->SR & (SSP_SR_TNF|SSP_SR_BSY)) != SSP_SR_TNF );
//LPC_SSP0->DR = 0;//dumy
while ( (LPC_SSP0->SR & (SSP_SR_BSY|SSP_SR_RNE)) != SSP_SR_RNE );
mrfiRadioState = LPC_SSP0->DR;
/*-------------------------------------------------------------------------------
* Inner loop. This loop executes as long as the SPI access is not interrupted.
* Loop completes when nothing left to transfer.
*/
do
{
// MRFI_SPI_WRITE_BYTE(*pData);
while ( (LPC_SSP0->SR & (SSP_SR_TNF|SSP_SR_BSY)) != SSP_SR_TNF );
LPC_SSP0->DR = *pData;
//while ( LPC_SSP0->SR & SSP_SR_BSY );
/*-------------------------------------------------------------------------------
* Use idle time. Perform increment/decrement operations before pending on
* completion of SPI access.
*
* Decrement the length counter. Wait for SPI access to complete.
*/
len--;
//MRFI_SPI_WAIT_DONE();
/*-------------------------------------------------------------------------------
* SPI data register holds data just read. If this is a read operation,
* store the value into memory.
*/
if (addrByte & READ_BIT)
{
//*pData = MRFI_SPI_READ_BYTE();
while ( (LPC_SSP0->SR & (SSP_SR_BSY|SSP_SR_RNE)) != SSP_SR_RNE );
*pData = LPC_SSP0->DR;
//while ( LPC_SSP0->SR & SSP_SR_BSY );
}
else
{
while ( (LPC_SSP0->SR & (SSP_SR_BSY|SSP_SR_RNE)) != SSP_SR_RNE );
i8Temp = LPC_SSP0->DR;
}
/*-------------------------------------------------------------------------------
* At least one byte of data has transferred. Briefly enable (and then disable)
* interrupts that can call SPI functions. This provides a window for any timing
* critical interrupts that might be pending.
*
* To improve latency, take care of pointer increment within the interrupt
* enabled window.
*/
MRFI_SPI_EXIT_CRITICAL_SECTION(s);
pData++;
MRFI_SPI_ENTER_CRITICAL_SECTION(s);
/*-------------------------------------------------------------------------------
* If chip select is "off" the SPI access was interrupted (all SPI access
* functions leave chip select in the "off" state). In this case, turn
* back on chip select and break to the main loop. The main loop will
* pick up where the access was interrupted.
*/
if (MRFI_SPI_CHIP_SELECT_IS_OFF())
{
MRFI_SPI_TURN_CHIP_SELECT_ON();
break;
}
/*-------------------------------------------------------------------------------
*/
} while (len); /* inner loop */
} while (len); /* main loop */
/* turn off chip select; enable interrupts that call SPI functions */
MRFI_SPI_TURN_CHIP_SELECT_OFF();
MRFI_SPI_EXIT_CRITICAL_SECTION(s);
}
/**************************************************************************************************
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -