Bar
SpaceWire UK
Specialist providers of VHDL Intellectual Property & Design Services
BarBarBarBar
Tutorial
Missing Image!
Part 3 - Create & build Firmware & Software projects without using BSP then deploy on Zedboard

Introduction

This tutorial details the steps required to create Firmware with Vivado & Software with Vitis to allow access to the LEDs & Switches on the Zedboard via a GPIO module. The tutorial covers generation of Programmable Logic (PL) & Processor System (PS) for the Zynq-7000 SoC without the aid of a BSP. The reason for making it harder work by not using a BSP is simply that by using a BSP a lot of the information & steps involved become absent, luring an inexperience user into a false sense of security. It is better to get a fuller understanding of what one is doing early on as it removes knowledge gaps when developing for custom (non-evaluation) hardware. Deployment of the PL & PS images will be via JTAG and the resulting output provided via a UART upto the host PC.

Aims

The aims of this tutorial are as follows :-

    Part 1 - Project Setup

    1. Setup environment
    2. Create project area

    Part 2 - Firmware Development

    1. Launch Vivado
    2. Create project
    3. Create block design
    4. Add ZYNQ to block design
    5. Apply Zedboard presets to ZYNQ
    6. Re-customize ZYNQ
    7. Add AXI GPIO to block design
    8. Re-customize AXI GPIO
    9. Run connection automation
    10. Rename external ports
    11. Edit address map
    12. Validate block design
    13. Create HDL wrapper
    14. Create pin constraints
    15. Generate bitstream
    16. Export Hardware Platform

    Part 3 - Software Development

    1. Launch Vitis
    2. Create project
    3. Build platform
    4. Create new source file
    5. Build project

    Part 4 - Hardware Deployment

    1. Setup Zedboard hardware
    2. Launch MiniCom terminal emulator
    3. Deploy firmware & software on Zedboard
    4. Check everything is working as expected

    Part 5 - Revision Control

    1. Create repository & commit files

    Part 6 - Quickstart

    1. Obtain tutorial files from Bitbucket, create & build projects, deploy on Zedboard

    1. Setup environment

    Setup Xilinx design environment for the 2021.2 toolset.
    steve@Desktop:~$ xilinx
    Xilinx tools available tools at /opt/Xilinx :-
    1) 2021.2 - Vivado - SDK - Vitis - PetaLinux
    0) Exit
    Please select tools required or exit : 1

    Tools are as follows :-
    vivado @ /opt/Xilinx/Vivado/2021.2/bin/vivado
    vitis @ /opt/Xilinx/Vitis/2021.2/bin/vitis
    petalinux-build @ /opt/Xilinx/PetaLinux/2021.2/tool/tools/common/petalinux/bin/petalinux-build

    2. Create project area

    Create the project directory structure and change the present working directory (pwd) to be at its root.
    steve@Desktop:~$ create_project_structure.sh ~/projects/zedboard_leds_switches
    Creating project directory structure @ ~/projects/hello_world
    steve@Desktop:~$ cd ~/projects/zedboard_leds_switches

    3. Launch Vivado

    Launch Vivado quietly from a Terminal.
    steve@Desktop:~/projects/zedboard_leds_switches$ vivado -nojournal -nolog -notrace &

    4. Create project

    The Vivado start window will now appear. Create a project by clicking on Create Project within the Vivado 2021.2 window. Missing Image! Review the information the in the New Project : Create a New Vivado Project window and then click Next. Missing Image! In the New Project : Project Name window set Project Name to project, Project location to ~/projects/zedboard_leds_switches/fw/vivado & untick Create project subdirectory. Click Next to proceed. Missing Image! No additional source files are required for this project so in the New Project : Project Type window tick the Do not specify sources at this time check box and then click Next. Missing Image! In the Parts tab enter xc7z020clg484 inside the Search element, select the xc7z020clg484-1 part from the parts list and click Next to continue. Missing Image! Look over the project details in the New Project : New Project Summary window and then click Finish. Missing Image! The Vivado project window now appears.

    5. Create block design

    Create a block design by clicking on Create Block Design under the IP INTEGRATOR heading inside the Flow Navigator section. Missing Image! The Create Block Design dialog now appears. Change the Design name to system, set the Directory to ~/projects/zedboard_leds_switches/fw/src/diagram and then click OK. Missing Image! The Vivado project window now changes to reflect the addition of the Diagram pane. Expand the Diagram pane outside of the Vivado window by clicking on its Float icon Missing Image!. Missing Image!

    6. Add ZYNQ to block design

    Add IP to the block design by clicking on the Missing Image! button. Missing Image! Scroll down to the ZYNQ7 Processing System in the pop-up dialog and add this to the block design by double clicking on it. Missing Image! The ZYNQ7 Processing System IP is now added to the block design. Missing Image! Let Vivado automate some of the connections by clicking on Run Block Automation. Missing Image! Review the connections proposed in the Run Block Automation dialog (note the missing Apply Board Preset checkbox) and then click OK. Missing Image! Some of the connections are now made in the block design. Missing Image!

    7. Apply Zedboard presets to ZYNQ

    Having gone down the FPGA part selection route and not the board selection route leaves the ZYNQ7 Processing System configured using its default settings.

    The Zedboard settings applied by selecting the Apply Board Preset (if it were present) are as shown below. Note there are some very important settings that MUST be applied, to name a few, the Bank 1 voltage and the DDR configuration. These settings can be applied through the ZYNQ7 Processing System re-customization dialog but this time around the script below shall be used to configure the PS in exactly the same way as if the Zedboard presets were applied.

    zedboard_presets.tcl

    1. # Peripheral I/O Pins
    2. set_property -dict [list \
    3. CONFIG.PCW_PRESET_BANK1_VOLTAGE {LVCMOS 1.8V} \
    4. CONFIG.PCW_QSPI_PERIPHERAL_ENABLE {1} \
    5. CONFIG.PCW_QSPI_GRP_SINGLE_SS_ENABLE {1} \
    6. CONFIG.PCW_ENET0_PERIPHERAL_ENABLE {1} \
    7. CONFIG.PCW_ENET0_ENET0_IO {MIO 16 .. 27} \
    8. CONFIG.PCW_ENET0_GRP_MDIO_ENABLE {1} \
    9. CONFIG.PCW_ENET0_GRP_MDIO_IO {MIO 52 .. 53} \
    10. CONFIG.PCW_SD0_PERIPHERAL_ENABLE {1} \
    11. CONFIG.PCW_SD0_GRP_CD_ENABLE {1} \
    12. CONFIG.PCW_SD0_GRP_CD_IO {MIO 47} \
    13. CONFIG.PCW_SD0_GRP_WP_ENABLE {1} \
    14. CONFIG.PCW_SD0_GRP_WP_IO {MIO 46} \
    15. CONFIG.PCW_UART1_PERIPHERAL_ENABLE {1} \
    16. CONFIG.PCW_TTC0_PERIPHERAL_ENABLE {1} \
    17. CONFIG.PCW_USB0_PERIPHERAL_ENABLE {1} \
    18. CONFIG.PCW_GPIO_MIO_GPIO_ENABLE {1} \
    19. CONFIG.PCW_GPIO_MIO_GPIO_IO {MIO} \
    20. ] [get_bd_cells processing_system7_0]

    21. # MIO Configuration
    22. set_property -dict [list \
    23. CONFIG.PCW_MIO_0_PULLUP {disabled} \
    24. CONFIG.PCW_MIO_1_PULLUP {disabled} \
    25. CONFIG.PCW_MIO_1_SLEW {fast} \
    26. CONFIG.PCW_MIO_2_SLEW {fast} \
    27. CONFIG.PCW_MIO_3_SLEW {fast} \
    28. CONFIG.PCW_MIO_4_SLEW {fast} \
    29. CONFIG.PCW_MIO_5_SLEW {fast} \
    30. CONFIG.PCW_MIO_6_SLEW {fast} \
    31. CONFIG.PCW_MIO_8_SLEW {fast} \
    32. CONFIG.PCW_MIO_9_PULLUP {disabled} \
    33. CONFIG.PCW_MIO_10_PULLUP {disabled} \
    34. CONFIG.PCW_MIO_11_PULLUP {disabled} \
    35. CONFIG.PCW_MIO_12_PULLUP {disabled} \
    36. CONFIG.PCW_MIO_13_PULLUP {disabled} \
    37. CONFIG.PCW_MIO_14_PULLUP {disabled} \
    38. CONFIG.PCW_MIO_15_PULLUP {disabled} \
    39. CONFIG.PCW_MIO_16_PULLUP {disabled} \
    40. CONFIG.PCW_MIO_16_SLEW {fast} \
    41. CONFIG.PCW_MIO_17_PULLUP {disabled} \
    42. CONFIG.PCW_MIO_17_SLEW {fast} \
    43. CONFIG.PCW_MIO_18_PULLUP {disabled} \
    44. CONFIG.PCW_MIO_18_SLEW {fast} \
    45. CONFIG.PCW_MIO_19_PULLUP {disabled} \
    46. CONFIG.PCW_MIO_19_SLEW {fast} \
    47. CONFIG.PCW_MIO_20_PULLUP {disabled} \
    48. CONFIG.PCW_MIO_20_SLEW {fast} \
    49. CONFIG.PCW_MIO_21_PULLUP {disabled} \
    50. CONFIG.PCW_MIO_21_SLEW {fast} \
    51. CONFIG.PCW_MIO_22_PULLUP {disabled} \
    52. CONFIG.PCW_MIO_22_SLEW {fast} \
    53. CONFIG.PCW_MIO_23_PULLUP {disabled} \
    54. CONFIG.PCW_MIO_23_SLEW {fast} \
    55. CONFIG.PCW_MIO_24_PULLUP {disabled} \
    56. CONFIG.PCW_MIO_24_SLEW {fast} \
    57. CONFIG.PCW_MIO_25_PULLUP {disabled} \
    58. CONFIG.PCW_MIO_25_SLEW {fast} \
    59. CONFIG.PCW_MIO_26_PULLUP {disabled} \
    60. CONFIG.PCW_MIO_26_SLEW {fast} \
    61. CONFIG.PCW_MIO_27_PULLUP {disabled} \
    62. CONFIG.PCW_MIO_27_SLEW {fast} \
    63. CONFIG.PCW_MIO_28_PULLUP {disabled} \
    64. CONFIG.PCW_MIO_28_SLEW {fast} \
    65. CONFIG.PCW_MIO_29_PULLUP {disabled} \
    66. CONFIG.PCW_MIO_29_SLEW {fast} \
    67. CONFIG.PCW_MIO_30_PULLUP {disabled} \
    68. CONFIG.PCW_MIO_30_SLEW {fast} \
    69. CONFIG.PCW_MIO_31_PULLUP {disabled} \
    70. CONFIG.PCW_MIO_31_SLEW {fast} \
    71. CONFIG.PCW_MIO_32_PULLUP {disabled} \
    72. CONFIG.PCW_MIO_32_SLEW {fast} \
    73. CONFIG.PCW_MIO_33_PULLUP {disabled} \
    74. CONFIG.PCW_MIO_33_SLEW {fast} \
    75. CONFIG.PCW_MIO_34_PULLUP {disabled} \
    76. CONFIG.PCW_MIO_34_SLEW {fast} \
    77. CONFIG.PCW_MIO_35_PULLUP {disabled} \
    78. CONFIG.PCW_MIO_35_SLEW {fast} \
    79. CONFIG.PCW_MIO_36_PULLUP {disabled} \
    80. CONFIG.PCW_MIO_36_SLEW {fast} \
    81. CONFIG.PCW_MIO_37_PULLUP {disabled} \
    82. CONFIG.PCW_MIO_37_SLEW {fast} \
    83. CONFIG.PCW_MIO_38_PULLUP {disabled} \
    84. CONFIG.PCW_MIO_38_SLEW {fast} \
    85. CONFIG.PCW_MIO_39_PULLUP {disabled} \
    86. CONFIG.PCW_MIO_39_SLEW {fast} \
    87. CONFIG.PCW_MIO_40_PULLUP {disabled} \
    88. CONFIG.PCW_MIO_40_SLEW {fast} \
    89. CONFIG.PCW_MIO_41_PULLUP {disabled} \
    90. CONFIG.PCW_MIO_41_SLEW {fast} \
    91. CONFIG.PCW_MIO_42_PULLUP {disabled} \
    92. CONFIG.PCW_MIO_42_SLEW {fast} \
    93. CONFIG.PCW_MIO_43_PULLUP {disabled} \
    94. CONFIG.PCW_MIO_43_SLEW {fast} \
    95. CONFIG.PCW_MIO_44_PULLUP {disabled} \
    96. CONFIG.PCW_MIO_44_SLEW {fast} \
    97. CONFIG.PCW_MIO_45_PULLUP {disabled} \
    98. CONFIG.PCW_MIO_45_SLEW {fast} \
    99. CONFIG.PCW_MIO_46_PULLUP {disabled} \
    100. CONFIG.PCW_MIO_47_PULLUP {disabled} \
    101. CONFIG.PCW_MIO_48_PULLUP {disabled} \
    102. CONFIG.PCW_MIO_49_PULLUP {disabled} \
    103. CONFIG.PCW_MIO_50_PULLUP {disabled} \
    104. CONFIG.PCW_MIO_51_PULLUP {disabled} \
    105. CONFIG.PCW_MIO_52_PULLUP {disabled} \
    106. CONFIG.PCW_MIO_53_PULLUP {disabled} \
    107. ] [get_bd_cells processing_system7_0]

    108. # Clock Configuration
    109. set_property -dict [list \
    110. CONFIG.PCW_UIPARAM_DDR_FREQ_MHZ {533.333313} \
    111. CONFIG.PCW_APU_PERIPHERAL_FREQMHZ {666.666667} \
    112. CONFIG.PCW_SDIO_PERIPHERAL_FREQMHZ {50} \
    113. CONFIG.PCW_UART_PERIPHERAL_FREQMHZ {50} \
    114. CONFIG.PCW_FPGA0_PERIPHERAL_FREQMHZ {100} \
    115. CONFIG.PCW_FPGA1_PERIPHERAL_FREQMHZ {150} \
    116. CONFIG.PCW_EN_CLK1_PORT {0} \
    117. ] [get_bd_cells processing_system7_0]

    118. # DDR Configuration
    119. set_property -dict [list \
    120. CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_0 {0.025} \
    121. CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_1 {0.028} \
    122. CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_2 {0.001} \
    123. CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_3 {0.001} \
    124. CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY0 {0.41} \
    125. CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY1 {0.411} \
    126. CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY2 {0.341} \
    127. CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY3 {0.358} \
    128. CONFIG.PCW_UIPARAM_DDR_PARTNO {MT41J128M16 HA-15E} \
    129. CONFIG.PCW_UIPARAM_DDR_USE_INTERNAL_VREF {1} \
    130. ] [get_bd_cells processing_system7_0]

    Save the zedboard_presets.tcl script into ~/projects/common/fw/src/script and run the script from the Tcl Console using source ~/projects/common/fw/src/script/zedboard_presets.tcl. Missing Image! After execution of the script the ZYNQ7 Processing System should reflect the applied changes. Missing Image!

    8. Re-customize ZYNQ

    Double click on the ZYNQ7 Processing System module to begin re-customization.

    Remove the USB 0 connection from the ZYNQ7 Processing System as it is not required for this design. Click on MIO Configuration, expand I/O Peripherals and untick USB 0. Missing Image! Remove the Timer connection from the ZYNQ7 Processing System as it is not required for this design. Click on MIO Configuration, expand Application Processor Unit and untick Timer 0. Missing Image! Click OK to commit the changes.

    9. Add AXI GPIO to block design

    In the floating Diagram window click on the Add IP Missing Image! icon and select AXI GPIO from the menu. The diagram now shows two unconnected IP modules. Missing Image!

    10. Re-customize AXI GPIO

    Connections to both the LED's and Slide Switches on the ZedBoard are required for this design. Double click on the AXI GPIO module to begin re-customization. Missing Image! Under GPIO tick All Outputs, set the GPIO Width to 8 and set the Default Output Value to 0x00000018. Tick Enable Dual Channel, then under GPIO 2 tick All Inputs and set the GPIO Width to 8. Missing Image! Click OK to commit the changes.

    11. Run connection automation

    The Diagram now contains all the I/O connections required by the two IP modules but these are totally unconnected. Let Vivado automate the connections by clicking on Run Connection Automation. Missing Image! Review each connection by selected GPIO, GPIO2 & S_AXI respectively. Once reviewed tick All Automation to enable all the suggested connections and then click OK to commit the changes. Missing Image! The extra modules of Processor System Reset & AXI Interconnect are now added to the block design to make connecting up the ZYNQ7 Processing System & AXI GPIO possible. Resize the canvas to obtain a better view of the design and click on the Regenerate Layout Missing Image! icon to obtain a better layout. Missing Image!

    12. Rename external ports

    Rename the external ports that GPIO & GPIO2 are connected to so they have more meaningful names. Highlight gpio_rtl_0 and goto the Vivado cockpit window, in the External Interface Properties under BLOCK DESIGN change the Name field from gpio_rtl_0 to leds. Missing Image! Using the same process rename gpio_rtl_1 to switches. Missing Image! The block design should now reflect the changes. Missing Image!

    13. Edit address map

    Check the address map assignment inside the Address Editor under the BLOCK DESIGN section. The axi_gpio_0 module should have a Master Base Address of 0x4120_0000 and a Range of 64K, if not change them. Missing Image!

    14. Validate block design

    Verify the block design is error free by clicking on the Validate Design Missing Image! icon. All being well the Validation successful dialogue should now appear. Missing Image! Once validated return the floating Diagram pane back to Vivado by clicking on the Dock Missing Image! icon. Save the Diagram.

    15. Create HDL wrapper

    Create a top-level wrapper for the block design since block designs cannot be the top-level of a design. Right click on system.bd and select Create HDL Wrapper... from the menu. Missing Image! The Create HDL Wrapper dialog now appears. Select Let Vivado manage wrapper and auto-update and then click OK. Missing Image!

    16. Create pin constraints

    Using the zedboard_master_XDC_RevC_D_v3.xdc from ~/projects/common/fw/src/constraint as a reference constraints can be constructed for the design. Right click on Constraints under Sources within BLOCK DESIGN and select Add Sources... from the context menu. Missing Image! In the Add Sources dialogue select Add or create constraints and then click Next. Missing Image! In the Add Sources - Add or Create Constraints dialogue click on Create File. Missing Image! In the Create Constraints File dialogue set the File name to zedboard, set the File location to ~/projects/zedboard_leds_switches/fw/src/constraint and then click Next. Missing Image! In the Add Sources - Add or Create Constraints dialogue click on Finish. Missing Image! Double click on the newly created constraints zedboard.xdc within Sources » Constraints » constrs_1 to edit. Missing Image! Add the following to zedboard.xdc and save the file.

    zedboard.xdc

    1. # User LEDs - Bank 33
    2. set_property PACKAGE_PIN T22 [get_ports {leds_tri_o[0]}];  # "LD0"
    3. set_property PACKAGE_PIN T21 [get_ports {leds_tri_o[1]}];  # "LD1"
    4. set_property PACKAGE_PIN U22 [get_ports {leds_tri_o[2]}];  # "LD2"
    5. set_property PACKAGE_PIN U21 [get_ports {leds_tri_o[3]}];  # "LD3"
    6. set_property PACKAGE_PIN V22 [get_ports {leds_tri_o[4]}];  # "LD4"
    7. set_property PACKAGE_PIN W22 [get_ports {leds_tri_o[5]}];  # "LD5"
    8. set_property PACKAGE_PIN U19 [get_ports {leds_tri_o[6]}];  # "LD6"
    9. set_property PACKAGE_PIN U14 [get_ports {leds_tri_o[7]}];  # "LD7"


    10. # User DIP Switches - Bank 34 & 35
    11. set_property PACKAGE_PIN F22 [get_ports {switches_tri_i[0]}];  # "SW0"
    12. set_property PACKAGE_PIN G22 [get_ports {switches_tri_i[1]}];  # "SW1"
    13. set_property PACKAGE_PIN H22 [get_ports {switches_tri_i[2]}];  # "SW2"
    14. set_property PACKAGE_PIN F21 [get_ports {switches_tri_i[3]}];  # "SW3"
    15. set_property PACKAGE_PIN H19 [get_ports {switches_tri_i[4]}];  # "SW4"
    16. set_property PACKAGE_PIN H18 [get_ports {switches_tri_i[5]}];  # "SW5"
    17. set_property PACKAGE_PIN H17 [get_ports {switches_tri_i[6]}];  # "SW6"
    18. set_property PACKAGE_PIN M15 [get_ports {switches_tri_i[7]}];  # "SW7"


    19. # Banks
    20. set_property IOSTANDARD LVCMOS33 [get_ports -of_objects [get_iobanks 33]];
    21. set_property IOSTANDARD LVCMOS18 [get_ports -of_objects [get_iobanks 34]];
    22. set_property IOSTANDARD LVCMOS18 [get_ports -of_objects [get_iobanks 35]];

    17. Generate bitstream

    Generate the programmable logic bitstream by clicking on Generate Bitstream under the PROGRAM AND DEBUG heading inside the Flow Navigator section.

    18. Export Hardware Platform

    Export the hardware platform by selecting File » Export » Export Hardware... from the main menu. Include the bitstream in the exported hardware file and save as ~/projects/zedboard_leds_switches/fw/system_wrapper.xsa.

    19. Launch Vitis

    Launch Vitis from a Terminal.
    steve@Desktop:~/projects/zedboard_leds_switches$ vitis &
    In the Vitis IDE Launcher dialog set the Workspace to ~/projects/zedboard_leds_switches/sw/vitis and click Launch. Missing Image!

    20. Create project

    The Vitis IDE : Welcome window will now appear. Create a project by clicking on Create Application Project under the Project heading. Missing Image! The New Application : Project Create a New Project window will now appear. Review the information provided and then click Next. Missing Image! The New Application Project : Platform window will now appear. Select the exported hardware platform from Vivado by entering the Create a new platform form hardware (XSA) tab and setting the XSA File to ~/projects/zedboard_leds_switches/fw/system_wrapper.xsa. Click Next to continue. Missing Image! The New Application Project : Application Project Details window will now appear. Set the Application project name to zedboard_leds_switches and then click Next. Missing Image! The New Application Project : Domain window will now appear. The default settings as shown are fine for this project. Click Next to contune. Missing Image! The New Application Project : Templates window will now appear. Create an empty application by selecting Empty Application(C) from the Available Templates section. Click Finish to contune. Missing Image! The Vitis IDE cockpit window will now appear. This is the window where all the action happens. Missing Image!

    21. Build platform

    Build the platform by right clicking on system_wrapper inside the Explorer tab and selecting Build Project. Missing Image!

    22. Create new source file

    Create a new source file inside the zedboard_leds_switches application project. Right click on src then select New » File. Missing Image! In the Create New File dialog click Advanced, tick Link to a file in the file system, use Browse... to select ~/projects/zedboard_leds_switches/sw/src/c/zedboard_leds_switches.c and then click Finish. Missing Image! The new source file is automatically opened in the Vitis IDE for editing. Missing Image! Copy the code below into the newly created zedboard_leds_switches.c and save it by selecting File » Save from the main menu.

    zedboard_leds_switches.c

    1. //
    2. // File .......... zedboard_leds_switches.c
    3. // Author ........ Steve Haywood
    4. // Version ....... 1.0
    5. // Date .......... 15 January 2022
    6. // Description ...
    7. //   Very simple LEDs & Switches example design.
    8. //


    9. #include "xparameters.h"
    10. #include "xil_printf.h"
    11. #include "xgpio.h"


    12. #define CHANNEL_LEDS 1
    13. #define CHANNEL_SWITCHES 2


    14. // Print LSB 'bits' from 'number' in binary format
    15. void print_bin(u32 number, u8 bits)
    16. {
    17.   u32 mask = 1 << (bits - 1);
    18.   for(; mask; mask >>= 1)
    19.     xil_printf("%d", (number & mask) != 0);
    20. }


    21. int main()
    22. {
    23.   XGpio_Config *gpio_0_cfg;
    24.   XGpio gpio_0;
    25.   u32 gpio_0_data;

    26.   // Initialise GPIO
    27.   gpio_0_cfg = XGpio_LookupConfig(XPAR_AXI_GPIO_0_BASEADDR);
    28.   XGpio_CfgInitialize(&gpio_0, gpio_0_cfg, gpio_0_cfg->BaseAddress);

    29.   // Print header
    30.   print("LED & Switch Example\n\n\r");
    31.   print("Select required operation :-\n\r");
    32.   print("r - Read from switch register\n\r");
    33.   print("w - Write to LED register\n\r");
    34.   print("q - Quit application\n\r");

    35.   // Wait for user input & perform required operation
    36.   char8 key;
    37.   do
    38.   {
    39.     key = inbyte();

    40.     switch (key)
    41.     {
    42.       case 'r':
    43.         gpio_0_data = XGpio_DiscreteRead(&gpio_0, CHANNEL_SWITCHES);
    44.         xil_printf("Switch Register @ 0x%x = 0b", gpio_0_cfg->BaseAddress);
    45.         print_bin(gpio_0_data, 8);
    46.         print("\n\r");
    47.         break;

    48.       case 'w':
    49.         gpio_0_data = 0b00000001;
    50.         for (u8 i = 0; i <= 15; i++)
    51.         {
    52.           XGpio_DiscreteWrite(&gpio_0, CHANNEL_LEDS, gpio_0_data);
    53.           xil_printf("LED Register @ 0x%x = 0b", gpio_0_cfg->BaseAddress);
    54.           print_bin(gpio_0_data, 8);
    55.           print("\n\r");
    56.           usleep(100000);
    57.           if (i < 7)
    58.             gpio_0_data <<= 1;
    59.           else
    60.             gpio_0_data >>= 1;
    61.         }
    62.         break;
    63.     }
    64.   } while (key != 'q');

    65.   // Print footer
    66.   print("All done!\n\n\r");

    67.   // Exit application
    68.   return 0;
    69. }

    23. Build project

    Build the project by right clicking on zedboard_leds_switches under zedboard_leds_switches_system inside the Explorer tab and selecting Build Project. Missing Image!

    24. Setup Zedboard hardware

    Connect up the hardware as follows :-
    1. Xubuntu PC USB ⇄ Zedboard USB JTAG/Debug
    2. Xubuntu PC USB ⇄ Zedboard USB UART
    Missing Image! Set the boot mode jumpers on the Zedboard for JTAG. Missing Image! Power on the Zedboard.

    25. Launch MiniCom terminal emulator

    If not already running, open up a new terminal and launch the MiniCom terminal emulator.
    steve@Desktop:~$ minized

    Welcome to minicom 2.7.1

    OPTIONS: I18n
    Compiled on Dec 23 2019, 02:06:26.
    Port /dev/ttyACM0, 06:34:25

    Press CTRL-A Z for help on special keys

    26. Deploy firmware & software on Zedboard

    To program the PL & PS part of the Zynq-7000 FPGA right click on zedboard_leds_switches under zedboard_leds_switches_system inside the Explorer tab and select Run As » Launch on Hardware (Single Application Debug) from the menu. The blue done LED will illuminate once the Programmable Logic (PL) has been programmed, the two middle LED's will then illuminate and after this the software will run on the Processor System (PS). Missing Image! Quit Vitis.

    27. Check everything is working as expected

    All being well the following sequence of events should be observed.
    LED & Switch Example

    Select required operation :-
    r - Read from switch register
    w - Write to LED register
    q - Quit application
    Pressing the 'r' key reads the register linked to the eight slide switches. With switches 0, 1, 4 & 5 in the 'on' position and 2, 3, 6 & 7 in the 'off' position the register read will return the following.
    Switch Register @ 0x41200000 = 0b00110011
    Pressing the 'w' key lights the eight LED's in sequence from right to left and then left to right, displaying the values written to the register.
    LED Register @ 0x41200000 = 0b00000001
    LED Register @ 0x41200000 = 0b00000010
    LED Register @ 0x41200000 = 0b00000100
    LED Register @ 0x41200000 = 0b00001000
    LED Register @ 0x41200000 = 0b00010000
    LED Register @ 0x41200000 = 0b00100000
    LED Register @ 0x41200000 = 0b01000000
    LED Register @ 0x41200000 = 0b10000000
    LED Register @ 0x41200000 = 0b01000000
    LED Register @ 0x41200000 = 0b00100000
    LED Register @ 0x41200000 = 0b00010000
    LED Register @ 0x41200000 = 0b00001000
    LED Register @ 0x41200000 = 0b00000100
    LED Register @ 0x41200000 = 0b00000010
    LED Register @ 0x41200000 = 0b00000001
    LED Register @ 0x41200000 = 0b00000000
    Pressing the 'q' key exits the application by exiting the main function.

    When finish with the application power off the Zedboard.

    28. Create repository & commit files

    Create a fresh repository and commit only the minimum set of files required to recreate the Firmware & Software projects. Create an annotated tag and push the commit & tag up to the remote repository.
    steve@Desktop:~/projects/zedboard_leds_switches$ ssh -t git@192.168.2.20 'git init --bare zedboard_leds_switches.git'
    steve@Desktop:~/projects/zedboard_leds_switches$ git init
    steve@Desktop:~/projects/zedboard_leds_switches$ git add fw/src/constraint/zedboard.xdc
    steve@Desktop:~/projects/zedboard_leds_switches$ git add fw/src/diagram/system/system.bd
    steve@Desktop:~/projects/zedboard_leds_switches$ git add fw/system_wrapper.xsa
    steve@Desktop:~/projects/zedboard_leds_switches$ git add sw/src/c/zedboard_leds_switches.c
    steve@Desktop:~/projects/zedboard_leds_switches$ git commit -m "Basic Zedboard design consisting of a ZYNQ7 Processing System controlling & monitoring LEDs & DIP Switches via a GPIO."
    steve@Desktop:~/projects/zedboard_leds_switches$ git tag -a v1.0 -m "ZYNQ & GPIO"
    steve@Desktop:~/projects/zedboard_leds_switches$ git remote add origin git@192.168.2.20:zedboard_leds_switches.git
    steve@Desktop:~/projects/zedboard_leds_switches$ git push -u origin master

    29. Obtain tutorial files from Bitbucket, create & build projects, deploy on Zedboard

    The source files relating to this tutorial for both Firmware & Software can be obtained from Bitbucket.

    The instructions below assume that Part 1 - Installation of tools, setup of environment and creation of project area has been completed in full and that the environment has been setup as per 1. Setup environment. The root project area ~/projects should be present and contain the common project. The zedboard_leds_switches project should NOT be present. Adjust the commands below to suit if the above differs.

    Obtain firmware & software source, create & build Vivado project, export hardware, then create & build Vitis project.
    steve@Desktop:~$ cd ~/projects
    steve@Desktop:~/projects$ git clone -b v1.0 https://bitbucket.org/spacewire_firmware/zedboard_leds_switches
    steve@Desktop:~/projects$ cd zedboard_leds_switches
    steve@Desktop:~/projects/zedboard_leds_switches$ create_vivado_project.sh build
    steve@Desktop:~/projects/zedboard_leds_switches$ create_vitis_project.sh build
    With the projects now created & built perform the following steps :-
    1. Setup Zedboard hardware
    2. Launch MiniCom terminal emulator
    3. Deploy firware & software on Zedboard
    4. Check everything is working as expected