Over the course of this series, we have used the API’s provided by the Board Support Package to interact with peripherals. These peripherals have been located in the Processing System (PS), Programmable Logic (PL) and externally on the board.
For some applications, however, we need more functionality than the simple control, read, and write functions provided by the BSP APIs.
This is where the Xilinx libraries also included in the BSP come into play. These libraries provide higher level functionality for a range of tasks, including:
- Open AMP — Used for Asymmetric Processing
- LightWeight IP — Provides a TCP/IP stack
- Xil Serial Flash — Provides functions to work with Serial Flash devices such as QSPI and SPI
- Xil Flash — Provides functions to work with Flash devices
- Xil PM — Power Management for the Zynq MPSoC
- Xil RSA — Provides functions for RSA and SHA algorithms
- Xil Key — Provides functions for key management
In this blog, we are going to look at how we can use the Xil Serial Flash library to interface with QSPI or SPI Flash devices on our board.
QSPI/SPI Flash is, of course, commonly used for storing the Zynq applications, as such we might want to access the Flash from our application to do in the field updates. Alternatively, we may also be using serial Flash for non volatile data storage. Regardless of reason, the Xil SF library makes it very easy to start working with these devices.
The first thing we need to do is create the hardware application in Vivado. For this example, I will be using the Arty Z7 which has a 128 Mega Bit QSPI device (S25FL128SAGMFI00) connected to the PS Multiplexed IO (MIO).
As such, our hardware design is going to be very simple, perhaps the simplest we have done. As everything is contained within the PS, all we need to do is implement the Zynq PS, ensure the PS is configured for the Arty Z7, build and export the design.
Once we have the design exported, in SDK we can create a new application and BSP. To use the Xil Serial Flash libraires, we need to do the following:
- Enable the XiliSF lib in the BSP.
- Configure the QSPI (SPI) interface using the normal QSPI (SPI) APIs provided with the BSP.
- Configure the XiliSF library, connecting it to the QSPI (SPI) instance.
- Use the XiliSF library to read the Flash device type, ensuring it aligns with the Flash device on the board.
- Create simple functions which use the XiliSF libraries to Erase, Read and Write the Flash.
The first step is to enable the XiliSF libraries in the BSP — we do this by updating the BSP settings. This will cause the BSP to regenerate and include the XiliSF libraries, and any others we enable.
After we have included the XiliSF library, the next step is to configure it with settings for the Flash device used and the method of interfacing, e.g. AXI SPI, PS SPI, or PS QSPI. We also do this within the Modify BSP Settings dialog.
Once completed, within the Xparameters.h file you will see the definitions for the Flash family and interface type.
We can now use the XiliSF library within our application. For this demonstration, I have created a simple application that erases a sector, then writes in one page of data before reading the data back out.
The library provides most of the low level functionality as would be expected providing functions which read, write, erase, and control the Flash device.
I should point out after the initialization of the library, I read the Flash device JEDEC register using the XIsf_GetDeviceInfo() command. To check the libraries, BSP, Vivado design and Board layout are correct as we know the device ID we are looking for.
The provision of these functions frees us from much of the heavy lifting of interfacing with the Flash device and demonstrates the benefit of using the library. As engineers all we need to do is worry about putting the data in the in the correct location.
The full code for this example is available on my GitHub, however the main code loop can be seen below.
When I put it all the code together on my development board and ran the application, I was able to erase, read, and write the Flash memory as I expected.
Before I sign off, I should mention that by default the XiliSF library uses a polled approach. If we wish to use an interrupt driven approach we should use the command after we have performed initialization.
- XIsf_SetTransferMode(&Isf, XISF_INTERRUPT_MODE)
The XiliSF library, therefore, gives us a wide range of easy to use functions. I am going to be using this library to enable in the field updates of a project very soon.
See My FPGA / SoC Projects: Adam Taylor on Hackster.io
Get the Code: ATaylorCEngFIET (Adam Taylor)
Access the MicroZed Chronicles Archives with over 250 articles on the Zynq / Zynq MpSoC updated weekly at MicroZed Chronicles.