While working on another project, I noticed that the hardware design in the BSP for the MiniZed has the pinout of the Arduino GPIO header specified in the Vivado constraints file (.xdc) but it doesn't actually have them connected to anything in the hardware block design. I decided it would make a good standalone tutorial of how to enable the digital IO on the Arduino shield header as I haven't seen a ton of other specific resources for it.
(Side Note: I am using Vivado/Vitis/PetaLinux 2019.2 for this project. I noticed while in the middle of this project that the Avnet Github repositories have updated quite a bit for version 2020.1, particularly for the MiniZed. So the exact steps for the Vitis aspect of this project and which files to upload to the MiniZed will be slightly different if you are using version Vivado/Vitis/PetaLinux 2020.1 or newer.)
I am starting with the Vivado and PetaLinux projects that I created from the MiniZed BSP in my last MiniZed project here. The first thing that needs to be done, is the updates to the hardware in Vivado.
To modify MiniZed based hardware design, open the Vivado project in the PetaLinux project directory generated by the BSP under the <project path>/hardware/MINIZED directory.
Since the EMIO GPIO of the Zynq are already being used for the bluetooth's I/O, add an AXI GPIO to the block diagram. Before running the connection automation option that appears, double-click on the new AXI GPIO block to reconfigure its settings.
Configure the GPIO block to have a single channel 14 bits wide connected to a custom endpoint. Click 'Ok' to save and close the configuration window then run the connection automation from the green banner at the top of the block design. Again, be sure that the GPIO connection option is set to 'Custom'.
Rename the port to indicate these lines will be connected to the Arduino header:
Validate and save the block design (there may be a critical warning about a clock line, but that can be ignored). Right-click on the block design in the Sources window and select the option to 'Create HDL Wrapper...' and the sub-option to allow Vivado to manage it. This will update the top level HDL to include the new external GPIO port.
Modify the minized_petalinux.xdc file to switch the Adruino data lines to match the bus output from the AXI GPIO block.
Save the constraints file then rerun synthesis, implementation, and generate a new bitstream. Once the bitstream has been generated, export the hardware design. There is already an existing hardware XSA in the local project directory (<path to PetaLinux project created with BSP>/hardware/MINIZED_2019_2/), so before exporting the new hardware XSA to it, I created a new folder in the project directory titled 'old_hw' and moved MINIZED.xsa to there. To export the new hardware design, select File > Export > Export Hardware... and be sure to check the box to include the bitstream. You'll see MINIZED_wrapper.xsa now appear in the local project directory.
In a new terminal window, source the PetaLinux environment settings and change directories into thePetaLinux project created with the BSP.
source <PetaLinux installation path>/2019.2/settings.sh
cd ./minized/minized_emmc_enhanced_2019_2/
Import the new hardware design into the existing PetaLinux project.
petalinux-config --get-hw-description ./hardware/MINIZED_2019_2/
Once the hardware configuration editor appears, you can exit it without making any changes. Select the option to save the new settings when prompted, then build the PetaLinux project.
petalinux-build
A new boot binary image (BOOT.BIN) needs to be created for the MiniZed to contain the new bitstream since we added new hardware to the design in Vivado. This can be done in the Vitis GUI by creating a new platform project and first stage bootloader application. In this instance, I find it to be a bit more straight forward to just create my own boot.bif using a text editor and the Xilinx software commandline tool (XSCT) to create the FSBL application stand alone, and then the bootgen tool to compile the new BOOT.BIN
In a new terminal window, source the Vitis environment settings script:
source <Vitis installation path>/2019.2/settings64.sh
Create a directory for the FSBL application project.
cd ./minized/minized_emmc_enhanced_2019_2/
mkdir -p ./fsbl_project/
Launch the Xilinx software commandline tool (XSCT):
xsct
Then use the HSI commands to create the Zynq first stage bootloader bare-metal application for the MiniZed. Learn more about HSI and how it's utilized in Vitis here.
Start by opening the hardware design for the MiniZed in the current XSCT instance.
xsct% hsi open_hw_design ./minized/minized_emmc_enhanced_2019_2/hardware/MINIZED_2019_2/MINIZED_wrapper.xsa
Verify the hardware was opened successfully with the current_hw_design command, the name of the hardware will be echoed back in the terminal similar to below:
xsct% hsi current_hw_design
MINIZED_wrapper
Create the bare-metal application for the FSBL using the HSI generate_app command:
xsct% hsi generate_app -dir ./minized/minized_emmc_enhanced_2019_2/fsbl_project/ -hw MINIZED_wrapper -sw fsbl -proc ps7_cortexa9_0 -os standalone -app zynq_fsbl -compile
Terminate and exit XSCT by pressing Ctrl+C twice in succession then use your text editor of choice to create a new boot info file (boot.bif) for the MiniZed.
nano boot.bif
Add the following text:
image : {
[bootloader] fsbl_project/executable.elf
images/linux/minized_petalinux_wrapper.bit
images/linux/u-boot.elf
}
The executable.elf is the new FSBL for the ARM core of the Zynq in the MiniZed just created in the last step using XSCT.
Finally, use the bootgen tool to create the new boot binary file for the MiniZed.
bootgen -image boot.bif -o i BOOT.BIN -w on
Once the boot binary has been successfully generated, copy the new kernel image (image.ub) and boot binary file (BOOT.BIN) to the eMMC of the MiniZed. I chose to use an FTP client again to upload the files to the MiniZed via its Wi-Fi connection.
From the MiniZed's command line, program the new boot binary to its QSPI flash memory and reboot.
root@MiniZed:~# flashcp /run/media/mmcblk1p1/BOOT.BIN /dev/mtd0
root@MiniZed:~# reboot
To test that the GPIOs were working properly, I hooked up LEDs to each of the I/O on its Arduino header and manually toggled each line from the command line (the GPIO based showed up as 999 for me, but it may be different for you so double-check using the get-gpio-offests application).
root@minized-emmc-enhanced-2019-2:~# cd /sys/class/gpio/
root@minized-emmc-enhanced-2019-2:/sys/class/gpio# echo 999 > ./export
root@minized-emmc-enhanced-2019-2:/sys/class/gpio# echo 1000 > ./export
root@minized-emmc-enhanced-2019-2:/sys/class/gpio# echo 1001 > ./export
root@minized-emmc-enhanced-2019-2:/sys/class/gpio# echo 1002 > ./export
root@minized-emmc-enhanced-2019-2:/sys/class/gpio# echo 1003 > ./export
root@minized-emmc-enhanced-2019-2:/sys/class/gpio# echo 1004 > ./export
root@minized-emmc-enhanced-2019-2:/sys/class/gpio# echo 1005 > ./export
root@minized-emmc-enhanced-2019-2:/sys/class/gpio# echo 1006 > ./export
root@minized-emmc-enhanced-2019-2:/sys/class/gpio# echo 1007 > ./export
root@minized-emmc-enhanced-2019-2:/sys/class/gpio# echo 1008 > ./export
root@minized-emmc-enhanced-2019-2:/sys/class/gpio# echo 1009 > ./export
root@minized-emmc-enhanced-2019-2:/sys/class/gpio# echo 1010 > ./export
root@minized-emmc-enhanced-2019-2:/sys/class/gpio# echo 1011 > ./export
root@minized-emmc-enhanced-2019-2:/sys/class/gpio# echo 1012 > ./export
root@minized-emmc-enhanced-2019-2:/sys/class/gpio# echo high > ./gpio999/direction
root@minized-emmc-enhanced-2019-2:/sys/class/gpio# echo high > ./gpio1000/direction
root@minized-emmc-enhanced-2019-2:/sys/class/gpio# echo high > ./gpio1001/direction
root@minized-emmc-enhanced-2019-2:/sys/class/gpio# echo high > ./gpio1002/direction
root@minized-emmc-enhanced-2019-2:/sys/class/gpio# echo high > ./gpio1003/direction
root@minized-emmc-enhanced-2019-2:/sys/class/gpio# echo high > ./gpio1004/direction
root@minized-emmc-enhanced-2019-2:/sys/class/gpio# echo high > ./gpio1005/direction
root@minized-emmc-enhanced-2019-2:/sys/class/gpio# echo high > ./gpio1006/direction
root@minized-emmc-enhanced-2019-2:/sys/class/gpio# echo high > ./gpio1007/direction
root@minized-emmc-enhanced-2019-2:/sys/class/gpio# echo high > ./gpio1008/direction
root@minized-emmc-enhanced-2019-2:/sys/class/gpio# echo high > ./gpio1009/direction
root@minized-emmc-enhanced-2019-2:/sys/class/gpio# echo high > ./gpio1010/direction
root@minized-emmc-enhanced-2019-2:/sys/class/gpio# echo high > ./gpio1011/direction
root@minized-emmc-enhanced-2019-2:/sys/class/gpio# echo high > ./gpio1012/direction
I tested the reference voltage rails with my DMM on the Arduino header both with and without the AUX power USB connected and they read out at the proper voltages. The MiniZed was also able to drive all 14 of the LEDs with the AUX power USB plugged in as well.
Comments