Continuing on from my last project covering how to write an embedded C application for the TE0711 SoM with TE0701 baseboard, the final step is programming the application to live in the non-volatile memory of the TE0711.
The TE0711 is equipped with a 32MByte Cypress S25FL256S external flash memory chip for its Artix FPGA to use. This is the only non-volatile memory on the board for storing applications and user data where it will remain between power cycles of the board.
As with almost anything in the FPGA/Vivado realm, there are usually several different ways to program an external flash memory chip. Usually I flash memory chips from Vitis, but with the particular board layout and Cypress (aka Spansion) chip the TE0711 has I found that generating the MCS in Vivado and using the Hardware Manager to program the flash was the only way I could get it to work.
Associate ELF in VivadoFirst things first, add the ELF file for the desired target application from Vitis as a design source in Vivado (Flow Navigator > Add Sources > Add or create design sources). I like to use it's relative path where it lives in the Vitis workspace so when I rebuild the application in Vitis, I don't have to manually replace the ELF file Vivado sees with the new one compiled in Vitis.
After the ELF file has been added to the Vivado project, it needs to be associated to the block design such that Vivado knows to use it when generating the next bitstream. Right-click on the block design from the Sources tab and select the Associate ELF Files... option.
By default, the associated ELF file in Vivado is the auto-generated MicroBlaze bootloop for both the actual design and simulation. By switching the associated ELF in the design sources to the target application from Vitis, the bitstream generated will cause the FPGA to execute the application upon boot up.
Generate New Bitstream with Associated ELFAfter adding and associating the target application's ELF file in Vivado synthesis and implementation will need to be reran, as well as a new bitstream needs to be generated.
Side Note: every time the application is built in Vitis after adding and associating the ELF file in Vivado, it will cause the bitstream to go out-of-dateonce the initial new synthesis and implementation are ran.
Once the new bitstream is generated, the MCS file that will be what actually lives in the external memory needs to be generated. This is what the Generate Memory Configuration File option is in the dialog box that appears after a bitstream is successfully generated. It can also be accessed anytime from the Tools menu option in Vivado.
Determining the Flash Memory's Part Number in VivadoThe TE0711 is equipped with 32MBytes of external flash memory by means of a Cypress S25FL256S chip. Based on the part number S25FL256S, there are two supported options for it in Vivado and Vitis: s25fl256sxxxxxx0-spi-x1_x2_x4 and s25fl256sxxxxxx1-spi-x1_x2_x4.
According to the TRM for the TE0711, all four of the SPI data lines to the Cypress S25FL256S chip are connected so all of the different bus widths are supported for flashing. However, I could not find any documentation that explained what the difference was between xxxxxx0 and xxxxxx1. UG908 documenting Vivado programming and debugging recognized the two options but still didn't state the difference as shown in the screen shot from Appendix E below:
After digging through Trenz's support forum, I found a post about the TE0710 SoM where a Trenz engineer confirmed that the appropriate Flash Type to select in Vitis was s25fl256sxxxxxx0-spi-x1_x2_x4.
I then spent some time inspecting the schematic for the TE0710 and comparing it to the schematic of the TE0711. This revealed that both the TE0710 and the TE0711 use the same part number Cypress S25FL256S chip (S25FL256SAGBHI20) and same circuit configuration, and confirmed my suspicion that s25fl256sxxxxxx0-spi-x1_x2_x4 is also the part number to use for the TE0711 in Vivado and Vitis for programming the flash.
In the dialog box that appears after selecting the Generate Memory Configuration File option, leave the format for the output file set to MCS as the Cypress S25FL256S chip on the TE0711 requires bitstreams to be converted to the.MCS file type for storage on it. Specify a desired filename with directory path in the Filename box for the resulting MCS file that. will be generated.
Given that the Cypress S25FL256S chip is supported in Vivado, select the Memory Part option, click the three dots to the right of the blank box for the Memory Part and select s25fl256sxxxxxx0-spi-x1_x2_x4 from the list.
As I mentioned before, all four of the SPI data lines to the Cypress S25FL256S chip are connected so all of the different bus widths are supported for flashing. The constraints file for the TE0711 specifies the bus width specifically as 4, thus the Interface option needs to be set to SPIx4.
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
Finally, since the bitstream now contains the ELF file for the desired application, it is the only file that needs to live in the flash memory. Check the box to Load bitstream files, leave the Start address at 00000000 and point to the bitstream file located in <Vivado project directory>/impl_1/. It is very important to use this particular bitstream file when programming flash like this from Vivado, as it is the actual bitstream Vivado has output with the desired ELF file associated with it that we did in previous steps.
Add Configuration Memory DeviceConnect the TE0711 + TE0701 to the host PC and launch the Hardware Manager in Vivado. Select the Auto Connect option to establish a connection to the TE0711.
Right-click on the xc7a35t_0 part under localhost in the Hardware window and select the Add Configuration Memory Device... option. Use the filters to navigate to and select the s25fl256sxxxxxx0-spi-x1_x2_x4 part from the list.
With the flash memory chip added added and now recognized by the Hardware Manager, right-click on it in the Hardware window and select the Program Configuration Memory Device... option.
For the Configuration file, point to the MCS generated in the previous steps at the directory path specified in the Filename box of the Write Memory Configuration File dialog window. A PROM file was also generated in that step and saved with the same filename at the specified location as well, point to this file for the PRM file.
At a minimum, check the options to Erase, Program, and Verify then click Apply and OK to finally program the TE0711.
The programming may take a few minutes.
Reboot & TestOnce the dialog box indicating that the flash memory was successfully programmed appears, close the Hardware Manager in Vivado and power cycle the TE0711 + TE0701.
Once booted back up, connect to the board using your terminal application of choice (I just used the serial terminal in Vitis since I usually always already have Vitis open).
I chose to add to the loop in the application the print out of "Hello TE0711" just so there would immediately be something in the console to see, while still maintaining the character echo function on the UART:
/*
* Just sits in this loop of echoing characters back to the terminal until
* ESC key is pressed.
*/
while(RecvChar != EscChar){
ReceivedCount = XUartLite_Recv(&UartLite, RecvChar, 1);
if (ReceivedCount != 0){
XUartLite_Send(&UartLite, RecvChar, 1);
} else {
xil_printf("Hello TE0711\n\r");
for(int i=0;i<3000000;i++){};
}
}
And that's it! The TE0711 is programmed and ready to go. As shown in the screenshots above, the periodic "Hello TE0711" is being printed to the console as well as echoing back the characters it receives. The buffer in the UART for this app is still set to the default lower size so there is a limit on the length of characters it can echo back at one time.
Comments