Attention: For security reasons,please choose a user name *different* from your login name.
Also make sure to choose a secure password and change it regularly.

Main Menu

TE0715 Multi-SPI

Started by benwefers, March 22, 2023, 08:30:47 PM

Previous topic - Next topic


Hi there!

Competent computer programmer here, but newbie with FPGA and Xilinx stuff. I have been tasked with updating an old version of some code for a TE0715-05-51I33-L board. Essentially all it did was run Petalinux with a command line program (written in C) that used three different SPI modules.

These were setup in Xilinx like so:

MISO: JB1.55(FMC_LA11_N)(H17), JM1.56, B13_L10_P(Y12)
CLK: JB1.56(FMC_LA4_N)(H11), JM1.55, B13_L9_P(AB13)
MOSI: JB1.58(FMC_LA4_P)(H10), JM1.57, B13_L9_N(AB14)
CS1: JB1.57(FMC_LA11_P)(H16), JM1.58, B13_L10_N(Y13)
CS2: JB1.60(FMC_CLK0_N)(H5), JM1.59, B13_L12_N(Y15)
CS3: JB1.59(FMC_LA12_N)(G16), JM1.60, B13_L23_P(V16)
CS4: JB1.62(?????) (???), JM1.61, B13_L12_P(Y14)


&spi1 {
  is-decoded-cs = <0>;
  num-cs = <3>;
  status = "okay";
  spidev@0x00 {
    compatible = "spidev";
    spi-max-frequency = <50000000>;
    reg = <0>;
  spidev@0x01 {
    compatible = "spidev";
    spi-max-frequency = <50000000>;
    reg = <1>;
  spidev@0x02 {
    compatible = "spidev";
    spi-max-frequency = <50000000>;
    reg = <2>;

... along with a number of other configurations. When this project was given to me, I was told that it is only possible to run 3 SPI channels this way, and that in order to add a fourth it would be necessary to do something different, like set a register containing the value of the CS (1 - 4) in the PL and use that to control the four chip select wires. I am still grinding my way through getting a functioning programming environment working, the previous person was using Vivado and Petalinux 2020.2 with this example project ( ) as the starting point.

My question then is, once I get my environment up and running, how should I go about this? Is it true that I cannot simply add a value for CS4 (and if so what value?) and similarly add a spidev@0x03? Any tips to help me tackle this is appreciated. Thanks!


So as an update, it seems the best approach for my original problem is just using GPIO to control the 4 chip selects. But now I have encountered a different problem.

I got a new board to test with and just to make sure the hardware was functioning correctly I flashed it over QSPI with an old Petalinux BOOT.bin that I have flashed on another board a dozen times. It flashed successfully, the Petalinux booted up just fine and everything worked as expected. I then attempted to flash it with a new version I created but immediately got an error "unrecognized JEDEC id bytes: 00, 00, 00". I then tried to flash it with the original version that I know works, but get the same error, though sometimes the numbers will change slightly.

Petalinux boots up fine still with the firmware I first flashed it with but it seems I have no way of changing it. With the other board I was able to reflash it over and over again with no issues, though that one was given to me so maybe something had been changed on it? Any ideas why this may be and how can I fix it?



by "i got a new board" you mean a new TE0715 module ? or carrier?
Are you using a custom carrier?
And do i understand correctly, that youre not able anymore to program the QSPI flash even with our latest reference design 2021.2 ? (But it worked once with the old Boot.bin?)



Hi Waldemar!

Sorry, I should have added more details. By new board yes I mean Trenz module, that I opened myself from a sealed Trenz static bag. The previous one I had been working on was handed to me (same module) already opened and programmed before. We are using a custom carrier that communicates through an FTDI, but again this carrier has worked well, and I did test on another carrier board to make sure mine wasn't faulty and got the same results.

And yes. I successfully flashed it once with the old BOOT.bin (which is basically just the 2020.2 reference design with SPI channels added), but now I can't flash it with anything else.

I just downloaded the prebuilt version of the 2021.2 reference and tried to flash that but got the same error. Perhaps I am doing something wrong?

Here are the steps I took:
- Launch Vivado
- Open Hardware Manager
- Autoconnect
- Right click on xc7z015_1 and select Add Configuration Memory Device
- Add s25fl256s-3.3v-qspi-x4-single
- Select BOOT.bin
- Select fsbl_flash.elf
- Set address range to Configuration File Only
- Program

Thanks again for your help and let me know if there's any other info I can provide.


Thanks for detailed description.

Instead of manually choosing the Flash device in the hardware manager, you can simply insert the command "TE::pr_program_flash -swapp u-boot" in the TCl console to automatically program the flash when using out reference design environment. (describe under the section Lauch -> QSPI boot mode here:

Unfortunately the person who works with these devices is on vacation atm, so i can just guess what might be the problem.

Did you try to program the latest firmware onto the CPLD? ->
Otherwise ... try to program the QSPI flash with the same vivado version with which the last successful flashing took place, in your case 2020.2 ( if not installed, Vivado Lab version is enough to program the qspi)

good luck :)


Thanks for the quick reply!

After running the TCL command I get the following output:

QuoteTE::pr_program_flash -swapp u-boot
Start Flash Programming
INFO: [Labtools 27-1435] Device xc7z015 (JTAG device index = 1) is not programmed (DONE status = 0).
WARNING: [Labtoolstcl 44-653] Creating new cfgmem for device xc7z015_1 will delete cfgmem object cfgmem_0 currently associated with it.
INFO: [Labtools 27-1435] Device xc7z015 (JTAG device index = 1) is not programmed (DONE status = 0).
WARNING: [Xicom 50-100] The current boot mode is QSPI.
Flash programming is not supported with the selected boot mode.If flash programming fails, configure device for JTAG boot mode and try again.
Problem in Initializing Hardware
Flash programming initialization failed.
ERROR: [Labtools 27-3161] Flash Programming Unsuccessful
ERROR: [TE_PR-108] Script (TE::VLAB::hw_program_flash) failed: ERROR: [Common 17-39] 'program_hw_cfgmem' failed due to earlier errors.
ERROR: (TE_PR-108) Script (TE::VLAB::hw_program_flash) failed: ERROR: [Common 17-39] 'program_hw_cfgmem' failed due to earlier errors.

I will go through the CPLD firmware update process and see if that helps.

As a side note, my coworker who previously worked on this left these as part of the setup instructions:

petalinux-package --boot --fsbl images/linux/zynq_fsbl.elf --fpga ../../prebuilt/hardware/04_15_1i_1gb/test_board_04_15_1i_1gb.bit --u-boot --add images/linux/boot.scr --offset 0x1fc0000 --kernel --offset 0x510000 --force
mkdir ../../bin
cp images/linux/BOOT.BIN ../../bin

Erase flash:
   Interrupt the boot process, then
   sf probe 0 10000000 0
   sf erase 0 0x02000000

Compile fsbl(first time only):
   In Tcl console TE::sw_run_vitis -all, this may give errors but we only care that it builds the file at prebuilt/software/04_15_1i_1gb/fsbl_flash.elf

Use the gui to flash it:
   Under Program and Debug, under Open hardware manager
   Click Open Target, autoconnect
   Right click s25fl256s-3.3v-qspi-x4-single and click program configuration memory device
   For Configuration file: prebuilt/boot_images/04_15_1i_1gb/u-boot/BOOT.BIN
   for Zynq FSBL: prebuilt/software/04_15_1i_1gb/fsbl_flash.elf
   Address Range: configuration file only
   Just check Program and uncheck everything else and hit OK
   Close server
   Power cycle board

I can't figure out where to execute the sf probe and sf erase commands. Perhaps those might be part of the solution?


Just a quick update.

Changing versions did not help. Got the same error flashing from Vivado 2020.2 Lab Edition.

It seems this person had a similar problem, though I'm not sure I understand the solution from this thread:


Hi, as you see in the error log after executing the swapp command, newer vivado versions will not allow programming when the module is started in QSPI Boot mode. With older versions of vivado this worked also in QSPi boot mode. You might try to install an old vivado lab version like 2017.2 and retry to program.

Or you might try to bring the TE0715 into JTAG or SD Boot mode(this is what John meant by sd boot mode here by pulling the JM1-32 Pin low, somewhere on your custom carrier.


Thanks again for your continued help.

I will look into trying out both of those suggestions. In the meantime, are you familiar with the sf probe and sf erase commands that both the other post and my coworker's instructions mention? It doesn't seem like they can be entered in the TCL console, and when I look online is a bit unclear if and where in Vitis they could be entered.


Sooooooo I got it to reprogram!

After interrupting the board boot process after a power cycle, and using sf probe and sf erase, I was able to flash it with Vivado 2020.2 (Vivado 2021.2 failed). Hopefully it's smooth sailing from here adding my gpio for the spi channels.

Thanks again for all your help


Im glad it worked!

The sf commands are more or less meant for the u-boot environment(the piece of software you interrupted, thats trys to start linux). There are many more like this e.g. md to showw memory content



So now I've run into another issue  :(

I am able to reprogram with my previously functioning BOOT.bin file with ease, however I can't seem to generate any of my own BOOT.bin files that run correctly, or even get the BOOT.bin from the prebuilt reference design to run right. I consistently get the attached output on the console after flashing.

The steps I am taking:
1. Open the extracted test_board folder from TE0715-test_board-vivado_2021.2-build_11_20220208131345 in a new terminal
2. Switch to dash
3. Run the setup_linux script (choose board 26)
4. Close Vivado when it opens
5. Open Vivado 2020.2 Lab Edition (because 2021.2 always fails, seems to be a known bug according to this page:
6. Right click xc7z015_1 and Add Configuration Memory Device
7. Select s25fl256s-3.3v-qspi-x4-single
8. Program device, setting Config to prebuilt/boot_images/04_15_1i_1gb/u-boot/BOOT.bin and ZYNQ to prebuilt/software/04_15_1i_1gb/fsbl_flash.elf
9. Select Configuration File Only, Erase, and Program

Program runs successfully, but then it doesn't seem to boot right.

Any ideas? Thanks again


Hi, according to this guide:
you also need to have image.ub and boot.scr located either on SD card or USB stick.

It looks like your colleague packed everything into one BOOT.bin within the petalinux environment.
There are many ways to do it ^^


Yes that's the sense I am getting. So then the default Trenz commands like TE:run-vitis -all and such won't work for my use case since it won't pack everything into a single BOOT.bin?

Back to the drawing board I guess


Well I figure thanks to our time differences I get one good post a day, so here it is.

I got all my boot and flash issues sorted out and squared away. Yippee!

Now I am on to the GPIO part of things. My goal is to be able to toggle JB1 pins 57, 59, 60, and 62 from inside the PetaLinux kernel. My understanding is that these correspond to package pins Y13, V16, Y15, Y14 respectively, based on the pinout from here:

I also have been playing around with the /sys/class/gpio interface; being able to set a pin high and low etc. However, I only see gpiochip906 there which corresponds to the zynq_gpio. I have no clue how I am supposed to determine which gpio number corresponds to what package pin, and therefor have no idea how to verify if those are actually toggling anything.

My main question for today then is, how do I toggle the pins? Is there any setup I need to do in Vivado first (in my testing I created an EGPIO with a width of 4 in the block design, made those external, and assigned them to my Package Pins in the I/O Ports tab of the implemented design, but that could totally be on the wrong track for all I know). Do I need to add anything to my device tree in PetaLinux?

Thanks again for your continued help, hopefully I will get this wrapped up soon :)


Well it seems I was already 99% of the way there. I discovered that everything I did was correct, just that the index of the EMIO GPIO pins I set are offset by 54. So to control the pins, I just have to do echo 960 > /sys/classes/gpio/export (because 906 + 54), and this lets me control the pin!