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