AXI Quad SPI read / write Flash for remote upgrade

catalogue

brief introduction

AXI Quad SPI IP settings

  Register description

General commands supported by AXI Quad SPI

Read flash id

Read flash data

Erase sector

Write flash data

matters needing attention

brief introduction

        This paper briefly introduces the use of xilinx 7 Series AXI quad spi IP core, which is mainly used for reading and writing flash for boot (n25q128 as an example) for online upgrade. This article will omit many details, mainly because I don't understand it very well. Secondly, many details can be found in other blogs. So far, I have only tried to use the axi lite interface to configure registers, read id, read data, erase sectors and write data to flash. Later, you will learn how to partition flash, do upgrade backup, and add quad read-write commands for different flash to improve the speed.

        Serial flash usually refers to spi flash, including standard, dual and quad. The operation of flash is to send command, send address (optional) and write / read data (optional). The difference between various modes mainly lies in the distribution of transmission data on the data line. I will not clear it here, but skip it for the time being.     

AXI Quad SPI IP settings

          Manual pg153 introduces the register meaning of the IP. In Chapter 5, Example Programming Sequence introduces the register writing sequence of several flash operation modes. In IP configuration, XIP (eXecute In Place) is executed in the chip, which means that the application program can run directly in flash memory, that is, it provides a memory map operation interface for the CPU to directly access the address, just like accessing memory, rather than sending the cmd command of flash. Therefore, a controller is integrated in flash to convert the read address command into various read timings. Note that XIP can only read flash. I don't need to check here. If performance Mode is checked, the AXI4 interface can support burst, which is not required at present. The IP is configured in quad mode. There is only one slave device. The device type is mixed. It supports commands common to winbond, micron, spansion and macronix. If you check micro, you can support the special command of micro. Otherwise, if you send its special command, the IPISR status register will report command error. FIFO depth is only available in 16 and 256 options. When the STARTUP primitive is checked, the clk of SPI will output the clock from the CCLK pin dedicated to FPGA.

          The clock frequencies of axi lite and SPI are described in the manual. spi_clk is twice that of flash clk, and this frequency is also constrained by flash devices. STARTUP_IO not connected, SPI_ After IO output, it can be led out to the inout pin with IOBUF, or you can write three state control, SPI_IO0_ Output high resistance at t = 1.

 

  Register description

        The register is described in the second chapter Register Space of pg153. The main registers are as follows.  

        The operating principle of the IP is to configure SPI as master, configure phase / polarity, reset fifo and prohibit transmission; Then write the command and data to SPI_ In DTR register, enable device chip selection, enable transmission, turn off chip selection and turn off transmission; From SPI_ Read data from DRR (optional). In addition, you can configure interrupts, select which interrupts are enabled, and then turn on the global interrupt enable. After transmission, query IPISR to know whether there is an error in the current transmission.

        40h: reset register, write 0xa to reset the whole IP, and reset automatically.

        60h: control register, which controls the working mode of SPI.

        64h: status register to check whether fifo is empty or full, which is used to judge whether the transmission ends.

        68h: send fifo and write data into it. If it is full, it will be overwritten. So don't fill it up.

        6ch: receive fifo. If it is full, subsequent data will be automatically discarded.

        70h: for chip selection, writing 0 means that the cs of the 0 device is pulled down. After the chip selection of a device is completed, write a useless device and pull up the cs.

        74h: send the number of data in fifo. For example, a value of 5 indicates that there are 6 data to be sent.

        78h: receive the number of data in fifo. For example, a value of 5 indicates that there are 6 data in it that have not been read.

General commands supported by AXI Quad SPI

        Check the flash manual and send it. Most flash should support these commands. Especially 02/06/9f/d8, which is also the command I have successfully applied at present.

Read flash id

        There is no difference between reading flash id and ordinary reading operations. First configure SPI and prohibit sending, that is, send read cmd (9f), and then write several dummy (false and meaningless data) to exchange data, enable film selection, enable sending, close film selection, prohibit sending and read data. The corresponding manual is described below.

The specific code is as follows. The number of dummy data can be controlled by yourself. Write several dummy data as much as you want to read.

  REG_W(pstDev, 0x80040, 0xa);       //Software Reset Register
  REG_W(pstDev, 0x80028, 0x00003fff);//Enable all interrupts
  REG_W(pstDev, 0x8001c, 0x80000000);//Turn on global interrupt enable
  REG_W(pstDev, 0x80060, 0x000001e6);//Reset tx rx fifo,
  REG_W(pstDev, 0x80060, 0x00000186);//Reset fifo
  REG_W(pstDev, 0x80068, 0x0000009f);//cmd = 9f, read flash id
  REG_W(pstDev, 0x80068, 0x00000000);//dummy
  REG_W(pstDev, 0x80068, 0x00000000);//dummy
  REG_W(pstDev, 0x80068, 0x00000000);//dummy
  REG_W(pstDev, 0x80068, 0x00000000);//dummy
  REG_W(pstDev, 0x80068, 0x00000000);//dummy
  REG_W(pstDev, 0x80068, 0x00000000);//dummy
  REG_W(pstDev, 0x80068, 0x00000000);//dummy
  REG_W(pstDev, 0x80068, 0x00000000);//dummy
  REG_W(pstDev, 0x80068, 0x00000000);//dummy
  REG_W(pstDev, 0x80068, 0x00000000);//dummy
  printf("Reg[0x%04X] : 0x%08X\n", 0x80074, REG_R(pstDev, 0x80074));
  REG_W(pstDev, 0x80070, 0x00000000);//Select 0 channel cs
  REG_W(pstDev, 0x80060, 0x00000086);//Enable the master and start sending data
  REG_W(pstDev, 0x80070, 0x00000001);//Select 0 channel cs to pull up
  REG_W(pstDev, 0x80060, 0x00000186);//Prohibit master spe
  printf("Reg[0x%04X] : 0x%08X\n", 0x80078, REG_R(pstDev, 0x80078));
  for(i=0;i<11;i++){
    printf("data = 0x%08X\n", REG_R(pstDev, 0x8006c));
  }
  printf("Reg[0x%04X] : 0x%08X\n", 0x80020, REG_R(pstDev, 0x80020));
  REG_W(pstDev, 0x80020, REG_R(pstDev, 0x80020));//clear

Read flash data

         The manual description is consistent with the id read above, except cmd = 03. It is not necessary to reset 0x40 and set interrupt every read. When reading data, the default 03 command needs a 3-byte addr. If a 4-byte address is required, the command will be a different cmd according to flash, but it must not be 03. Send the high address first. Note that the data read back is 4 + dummy data. That is, as long as a data is written to the DTR, a data will be received and written to the DRR. So the data read back will be FF XX XX... (real data). Note that the DRR fifo is only 256 deep. Do not read too much data.

  REG_W(pstDev, 0x80040, 0xa);       //Software Reset Register
  REG_W(pstDev, 0x80028, 0x00003fff);//Enable all interrupts
  REG_W(pstDev, 0x8001c, 0x80000000);//Turn on global interrupt enable
  REG_W(pstDev, 0x80060, 0x000001e6);//Reset tx rx fifo,
  REG_W(pstDev, 0x80060, 0x00000186);//Reset fifo
  REG_W(pstDev, 0x80068, 0x00000003);//cmd = 03, read flash data
  //write addr
  REG_W(pstDev, 0x80068, (nOffset>>16)&0xff);
  REG_W(pstDev, 0x80068, (nOffset>>8)&0xff);
  REG_W(pstDev, 0x80068, (nOffset&0xff));
  for(i=0;i<nCount;i++){
     REG_W(pstDev, 0x80068, 0);//dummy
  }
  REG_W(pstDev, 0x80070, 0x00000000);//Select 0 channel cs
  REG_W(pstDev, 0x80060, 0x00000086);//Enable the master and start sending data
  REG_W(pstDev, 0x80070, 0x00000001);//Select 0 channel cs to pull up
  REG_W(pstDev, 0x80060, 0x00000186);//Prohibit master spe
  for(i=0;i<nCount+4;i++){
    printf("data = 0x%08X\n", REG_R(pstDev, 0x8006c));
  }
  printf("Reg[0x%04X] : 0x%08X\n", 0x80020, REG_R(pstDev, 0x80020));
  REG_W(pstDev, 0x80020, REG_R(pstDev, 0x80020));//clear

Erase sector

        Each flash has its own sector and page write parameters. The d8 command erases one sector, but the size of the sector is different. For example, n25q128 manual describes:

          As you can see, there are 16777216 bytes in total, 256 sectors (64KB per sector) and 65536 pages (256 bytes per page). Therefore, executing the erase command once will erase 64KB of data, write the data as 0xFF, and write the data as 0 only. Note that each erase command and write data command must be preceded by a write enable command (06). If the erase command is followed by an address, 64KB of the address where the address is aligned will be erased.

  The test code is:

  REG_W(pstDev, 0x80040, 0xa);       //Software Reset Register
  REG_W(pstDev, 0x80060, 0x000001e6);//Reset tx rx fifo,
  REG_W(pstDev, 0x80060, 0x00000186);//Reset fifo
  REG_W(pstDev, 0x80068, 0x00000006);//cmd = 06, write enable
  REG_W(pstDev, 0x80070, 0x00000000);//Select 0 channel cs
  REG_W(pstDev, 0x80060, 0x00000086);//Enable the master and start sending data
  REG_W(pstDev, 0x80070, 0x00000001);//Select 0 channel cs to pull up
  REG_W(pstDev, 0x80060, 0x00000186);//Prohibit master spe
  REG_W(pstDev, 0x80060, 0x000001e6);//Reset tx rx fifo,
  REG_W(pstDev, 0x80060, 0x00000186);//Reset fifo
  REG_W(pstDev, 0x80068, 0x000000d8);//cmd = d8, erase sector.
  //write addr
  REG_W(pstDev, 0x80068, (nOffset>>16)&0xff);
  REG_W(pstDev, 0x80068, (nOffset>>8)&0xff);
  REG_W(pstDev, 0x80068, (nOffset&0xff));
  REG_W(pstDev, 0x80070, 0x00000000);//Select 0 channel cs
  REG_W(pstDev, 0x80060, 0x00000086);//Enable the master and start sending data
  REG_W(pstDev, 0x80070, 0x00000001);//Select 0 channel cs to pull up
  REG_W(pstDev, 0x80060, 0x00000186);//Prohibit master spe

Write flash data

        Similar to erasing sectors, write enable, write command, write address, write data.

      Note that the write FIFO is only 256 bytes deep, although the page write is 256 bytes. Page write means that the write command is followed by so many data at most, and the redundant data is written repeatedly. So you can write 128 bytes from 0 and 128 bytes from 128.

The test code is as follows:

  REG_W(pstDev, 0x80040, 0xa);       //Software Reset Register
  REG_W(pstDev, 0x80060, 0x000001e6);//Reset tx rx fifo,
  REG_W(pstDev, 0x80060, 0x00000186);//Reset fifo
  REG_W(pstDev, 0x80068, 0x00000006);//cmd = 06, write enable
  REG_W(pstDev, 0x80070, 0x00000000);//Select 0 channel cs
  REG_W(pstDev, 0x80060, 0x00000086);//Enable the master and start sending data
  REG_W(pstDev, 0x80070, 0x00000001);//Select 0 channel cs to pull up
  REG_W(pstDev, 0x80060, 0x00000186);//Prohibit master spe
  REG_W(pstDev, 0x80060, 0x000001e6);//Reset tx rx fifo,
  REG_W(pstDev, 0x80060, 0x00000186);//Reset fifo
  REG_W(pstDev, 0x80068, 0x00000002);//CMD = write on 02 pages, 256 bytes per page
  //write addr
  REG_W(pstDev, 0x80068, (nOffset>>16)&0xff);
  REG_W(pstDev, 0x80068, (nOffset>>8)&0xff);
  REG_W(pstDev, 0x80068, (nOffset&0xff));
  for(i=0;i<128;i++){
     REG_W(pstDev, 0x80068, i);//Fixed write incremental data
  }
  REG_W(pstDev, 0x80070, 0x00000000);//Select 0 channel cs
  REG_W(pstDev, 0x80060, 0x00000086);//Enable the master and start sending data
  REG_W(pstDev, 0x80070, 0x00000001);//Select 0 channel cs to pull up
  REG_W(pstDev, 0x80060, 0x00000186);//Prohibit master spe

  Remote upgrade

        For the differences between mcs, bin, bit and hex files, you can see ug470   7 Series FPGAsConfiguration.       

          Simply put, it is a bit file. Bit is not in reverse order (the bit of each byte is in reverse order). It is a binary file. Bin file has no bit reverse order, binary file. MCS bit is in reverse order. It is an ASCII file with address and verification. For our upgrade, the bin file is OK. When the FPGA is upgraded, the data is read from 0 to the synchronization header aa 99 55 66, indicating that a valid configuration file begins. As shown below.

ffff ffff ffff ffff ffff ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
0000 00bb 1122 0044 ffff ffff ffff ffff
aa99 5566 2000 0000 3003 e001 0000 026b
3000 8001 0000 0012 2000 0000 3002 2001
0000 0000 3002 0001 0000 0000 3000 8001
0000 0000 2000 0000 3000 8001 0000 0007

        Therefore, for online upgrade, the simple design is to erase sectors according to the bin file size after obtaining the bin file. It takes time to erase each sector. It is also explained in the manual that an interval can be set between erase commands, and then write the bin file directly from 0. After writing, read out the verification.

        In the follow-up, we will study how to make a backup. When upgrading the write image, only the user image area is written. When it is found that the user image fails to start, it will automatically jump to the factory image to ensure that there is an online upgrade code in the factory image, so as to prevent the problem of having to return to the factory to use JTAG due to an upgrade failure.

matters needing attention

          If JTAG to AXI Master is used, JTAG can be used to send axi lite read / write commands.

         usage method:

                1. Add jtag to axi master ip in bd, connect axi lite port, and configure address;

                2. Compile the project and download it.

                3. First create the axi lite read / write operation, and then execute it in vivado tcl console. Just create it once.

create_hw_axi_txn reset_qspi         [get_hw_axis hw_axi_1] -address 0x00000040 -data 0x0000000a -type write -force
create_hw_axi_txn rd_txn_lite_read_60 [get_hw_axis hw_axi_1] -address 00000060 -type read -force
run_hw_axi rd_txn_lite_read_74

        My test is to connect the bypas interface of xdma to SPI IP. When accessing the register, you will find that the read and write data are changing. Increase the delay between operation registers and increase a certain time, such as 10us.

        If there is a need for online upgrade of commercial applications, especially pcie online upgrade, you can send me a private letter through CSDN.

Tags: FPGA SPI Flash Xilinx

Posted on Sat, 06 Nov 2021 03:25:01 -0400 by acemods