SPI 核软件调试记录
1.首先说说int SpiFlashWaitForFlashReady(void)这一函数,基本上其它函数在执行的时候,都会事先执行一次此函数。
因为此函数的作用主要是用来等待,所以整个语句在一个循环里面。第一步是检测spi flash 的状态,若spi flash 已经完成了上一次传送,
状态为XST_SUCCESS,否则,函数直接返回XST_FAILURE 即not ready。检测ReadBuffer[1]中的值 若果为0,则break循环,函数返回XST_SUCCESS
代码内容如下:
/*****************************************************************************/
/**
*
* This function waits till the Numonyx serial Flash is ready to accept next
* command.
*
* @param None
*
* @return XST_SUCCESS if successful else XST_FAILURE.
*
* @note This function reads the status register of the Buffer and waits
*. till the WIP bit of the status register becomes 0.
*
******************************************************************************/
int SpiFlashWaitForFlashReady(void)
{
int Status;
u8 StatusReg; while() { /*
* Get the Status Register. The status register content is
* stored at the second byte pointed by the ReadBuffer.
*/
Status = SpiFlashGetStatus(&Spi);
if(Status != XST_SUCCESS) {
return XST_FAILURE;
} /*
* Check if the flash is ready to accept the next command.
* If so break.
*/
StatusReg = ReadBuffer[];
if((StatusReg & FLASH_SR_IS_READY_MASK) == ) {
break;
}
} return XST_SUCCESS;
}
2.函数SpiFlashGetStatus先写入一个命令COMMAND_STATUSREG_READ,然后用XSpi_Transfer函数将命令传入spi芯片中。
当传送过程完成后,退出循环返回XST_SUCCESS 成功的状态,若传送没有完成,则一直执行:while(TransferInProgress);
/*****************************************************************************/
/**
*
* This function reads the Status register of the Numonyx Flash.
*
* @param SpiPtr is a pointer to the instance of the Spi device.
*
* @return XST_SUCCESS if successful else XST_FAILURE.
*
* @note The status register content is stored at the second byte
* pointed by the ReadBuffer.
*
******************************************************************************/
int SpiFlashGetStatus(XSpi *SpiPtr)
{
int Status; /*
* Prepare the Write Buffer.
*/
WriteBuffer[BYTE1] = COMMAND_STATUSREG_READ; /*
* Initiate the Transfer.
*/
TransferInProgress = TRUE;
Status = XSpi_Transfer(SpiPtr, WriteBuffer, ReadBuffer,
STATUS_READ_BYTES);
if(Status != XST_SUCCESS) {
return XST_FAILURE;
} /*
* Wait till the Transfer is complete and check if there are any errors
* in the transaction..
*/
while(TransferInProgress);
if(ErrorCount != ) {
ErrorCount = ;
return XST_FAILURE;
} return XST_SUCCESS;
}
3. SpiFlashWriteEnable函数
首先检测spi flash 是否ready , 然后写入写使能命令:COMMAND_WRITE_ENABLE 到WriteBuffer中,最后通过XSPi_Transfer函数将命令发出。
/*****************************************************************************/
/**
*
* This function enables writes to the Numonyx Serial Flash memory.
*
* @param SpiPtr is a pointer to the instance of the Spi device.
*
* @return XST_SUCCESS if successful else XST_FAILURE.
*
* @note None
*
******************************************************************************/
int SpiFlashWriteEnable(XSpi *SpiPtr)
{
int Status; /*
* Wait while the Flash is busy.
*/
Status = SpiFlashWaitForFlashReady();
if(Status != XST_SUCCESS) {
return XST_FAILURE;
} /*
* Prepare the WriteBuffer.
*/
WriteBuffer[BYTE1] = COMMAND_WRITE_ENABLE; /*
* Initiate the Transfer.
*/
TransferInProgress = TRUE;
Status = XSpi_Transfer(SpiPtr, WriteBuffer, NULL,
WRITE_ENABLE_BYTES);
if(Status != XST_SUCCESS) {
return XST_FAILURE;
} /*
* Wait till the Transfer is complete and check if there are any errors
* in the transaction..
*/
while(TransferInProgress);
if(ErrorCount != ) {
ErrorCount = ;
return XST_FAILURE;
} return XST_SUCCESS;
}
4.SpiFlashSectorErase函数,依旧是先检测spi flash 是否ready. 然后就是将要写的内容存入writebuffer中,主要命令和地址信息。
/*****************************************************************************/
/**
*
* This function erases the contents of the specified Sector in the Numonyx
* Serial Flash device.
*
* @param SpiPtr is a pointer to the instance of the Spi device.
* @param Addr is the address within a sector of the Buffer, which is to
* be erased.
*
* @return XST_SUCCESS if successful else XST_FAILURE.
*
* @note The erased bytes will be read back as 0xFF.
*
******************************************************************************/
int SpiFlashSectorErase(XSpi *SpiPtr, u32 Addr)
{
int Status; /*
* Wait while the Flash is busy.
*/
Status = SpiFlashWaitForFlashReady();
if(Status != XST_SUCCESS) {
return XST_FAILURE;
} /*
* Prepare the WriteBuffer.
*/
WriteBuffer[BYTE1] = COMMAND_SECTOR_ERASE;
WriteBuffer[BYTE2] = (u8) (Addr >> );
WriteBuffer[BYTE3] = (u8) (Addr >> );
WriteBuffer[BYTE4] = (u8) (Addr); /*
* Initiate the Transfer.
*/
TransferInProgress = TRUE;
Status = XSpi_Transfer(SpiPtr, WriteBuffer, NULL,
SECTOR_ERASE_BYTES);
if(Status != XST_SUCCESS) {
return XST_FAILURE;
} /*
* Wait till the Transfer is complete and check if there are any errors
* in the transaction..
*/
while(TransferInProgress);
if(ErrorCount != ) {
ErrorCount = ;
return XST_FAILURE;
} return XST_SUCCESS;
}
5.SpiFlashWrite函数,依旧是检测是否ready,然后写入地址和命令,接下来就是用一个for循环 把将要写入的数据一个一个存入writeBuffer中,然后通过Xspi_Transfer函数
一起发送出去。
/*****************************************************************************/
/**
*
* This function writes the data to the specified locations in the Numonyx Serial
* Flash memory.
*
* @param SpiPtr is a pointer to the instance of the Spi device.
* @param Addr is the address in the Buffer, where to write the data.
* @param ByteCount is the number of bytes to be written.
*
* @return XST_SUCCESS if successful else XST_FAILURE.
*
* @note None
*
******************************************************************************/
int SpiFlashWrite(XSpi *SpiPtr, u32 Addr, u32 ByteCount, u8 WriteCmd)
{
u32 Index;
int Status; /*
* Wait while the Flash is busy.
*/
Status = SpiFlashWaitForFlashReady();
if(Status != XST_SUCCESS) {
return XST_FAILURE;
} /*
* Prepare the WriteBuffer.
*/
WriteBuffer[BYTE1] = WriteCmd;
WriteBuffer[BYTE2] = (u8) (Addr >> );
WriteBuffer[BYTE3] = (u8) (Addr >> );
WriteBuffer[BYTE4] = (u8) Addr; /*
* Fill in the TEST data that is to be written into the Numonyx Serial
* Flash device.
*/
for(Index = ; Index < ByteCount + READ_WRITE_EXTRA_BYTES; Index++) {
WriteBuffer[Index] = (u8)((Index - ) + TestByte);
} /*
* Initiate the Transfer.
*/
TransferInProgress = TRUE;
Status = XSpi_Transfer(SpiPtr, WriteBuffer, NULL,
(ByteCount + READ_WRITE_EXTRA_BYTES));
if(Status != XST_SUCCESS) {
return XST_FAILURE;
} /*
* Wait till the Transfer is complete and check if there are any errors
* in the transaction.
*/
while(TransferInProgress);
if(ErrorCount != ) {
ErrorCount = ;
return XST_FAILURE;
} return XST_SUCCESS;
}
6.SpiFlashRead 函数,先检测spi flash 是否ready,然后将readcmd命令和读地址存入writeBuffer, 接下来就是先判断read函数接收的是那种命令,根据接收的命令来
处理ByteCount的值,最后就是用transfer函数将要写入的命令发给spi flash, 然后将读到的数据存入readbuffer中。
/*****************************************************************************/
/**
*
* This function reads the data from the Numonyx Serial Flash Memory
*
* @param SpiPtr is a pointer to the instance of the Spi device.
* @param Addr is the starting address in the Flash Memory from which the
* data is to be read.
* @param ByteCount is the number of bytes to be read.
*
* @return XST_SUCCESS if successful else XST_FAILURE.
*
* @note None
*
******************************************************************************/
int SpiFlashRead(XSpi *SpiPtr, u32 Addr, u32 ByteCount, u8 ReadCmd)
{
int Status; /*
* Wait while the Flash is busy.
*/
Status = SpiFlashWaitForFlashReady();
if(Status != XST_SUCCESS) {
return XST_FAILURE;
} /*
* Prepare the WriteBuffer.
*/
WriteBuffer[BYTE1] = ReadCmd;
WriteBuffer[BYTE2] = (u8) (Addr >> );
WriteBuffer[BYTE3] = (u8) (Addr >> );
WriteBuffer[BYTE4] = (u8) Addr; if (ReadCmd == COMMAND_DUAL_READ) {
ByteCount += DUAL_READ_DUMMY_BYTES;
} else if (ReadCmd == COMMAND_DUAL_IO_READ) {
ByteCount += DUAL_READ_DUMMY_BYTES;
} else if (ReadCmd == COMMAND_QUAD_IO_READ) {
ByteCount += QUAD_IO_READ_DUMMY_BYTES;
} else if (ReadCmd==COMMAND_QUAD_READ) {
ByteCount += QUAD_READ_DUMMY_BYTES;
} /*
* Initiate the Transfer.
*/
TransferInProgress = TRUE;
Status = XSpi_Transfer( SpiPtr, WriteBuffer, ReadBuffer,
(ByteCount + READ_WRITE_EXTRA_BYTES));
if(Status != XST_SUCCESS) {
return XST_FAILURE;
} /*
* Wait till the Transfer is complete and check if there are any errors
* in the transaction.
*/
while(TransferInProgress);
if(ErrorCount != ) {
ErrorCount = ;
return XST_FAILURE;
} return XST_SUCCESS;
}