博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

SPI 核软件调试记录

Posted on 2017-12-29 09:15  沉默改良者  阅读(1385)  评论(0编辑  收藏  举报

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 }