Too much hassle: directly controlling the 8 LED bank from PS
Zedboard has 8 red LEDs, as you can see in the schematic:I want to toggle the pins above to control the LEDs from SW. I already described how to modify the Zynq processor's pin assignment in Vivado when I controlled an SPI device on Linux. After using up 4 pins for SPI, I still have a few MIO pins assigned to GPIO, as you can see in the screenshot of Vivado's PS customization window's "Peripheral I/O Pins" tab below (pins 50 and 51, not shown due to lack of space are also assigned to GPIO MIO):
But don't be fooled: these GPIO MIO pins are NOT connected to the above LEDs, according to the IO constraint (zed_system_constr.xdc) if your Vivado project setup is derived from "Ubuntu on Zedboard" reference design, as I've done in a previous blog entry. LD0, for example, is connected to gpio_bd[19] in the constraint:
set_property -dict {PACKAGE_PIN T22 IOSTANDARD LVCMOS33} [get_ports gpio_bd[19]]; ## LD0
gpio_bd[19] is one of the pins in the GPIO_O EMIO bus in the snapshot of the Zynq PS7 ports below.
I want to connect LD0 to FIXED_IO_mio[0] and LD1 to FIXED_IO_mio[7] (the name is what the auto-generated system_top.v calls the MIO bus above; FIXED_IO_mio[7:8] can only output according to the Zynq TRM, but that's OK for me).
So I changed the constraints for LD0, LD1, LD2:
set_property -dict {PACKAGE_PIN T22 IOSTANDARD LVCMOS33} [get_ports FIXED_IO_mio[0]] ; ## LD0
set_property -dict {PACKAGE_PIN T21 IOSTANDARD LVCMOS33} [get_ports FIXED_IO_mio[7]] ; ## LD1
set_property -dict {PACKAGE_PIN U22 IOSTANDARD LVCMOS33} [get_ports FIXED_IO_mio[9]] ; ## LD2
But this does NOT synthesize!
CRITICAL WARNING: [Vivado 12-1411] Cannot set LOC property of ports, Illegal to place instance i_system_wrapper/system_i/sys_ps7/inst/genblk13[0].MIO_BIBUF on site T22. The location site type does not match the instance type. [/mnt/work/Dorking/Zynq/ZedSPI/projects/common/zed/zed_system_constr.xdc:74]
Resolution: Verify the location constraints for differential ports are correctly specified in your constraints. The Site type should be of form: IO_LxxP for P-side, and IO_LxxN for N-side (Neg Diff Pair)
The warning is incomprehensible, but I get the feeling that these 7 LEDs cannot driven from MIO.
But there is already 1 LED wired to the PS
According to the schematic, this SHOULD be drivable from MIO7, which is IO pin D5Furthermore, Xilinx made it easy to learn how to control this GPIO from software. In the BSP information window (system.mss under the BSP project), each of the peripherals the BSP suports are listed when I double-click on system.mss, as you can see below:
When I double-click "Import Examples" for the ps7_gpio, xsdk asks whether you want the polled or interrupt example. For the purpose of blinking an LED, the polled example is fine, and I got the project shown in the bottom of the picture. This example wants to shake MIO10, so I just have to change the OUTPUT_PIN in the code below to 7:
#include "xparameters.h"
#include "xgpiops.h"
...
u32 Data;
volatile int Delay;
u32 LedLoop;
/*
* Set the direction for the pin to be output and
* Enable the Output enable for the LED Pin.
*/
XGpioPs_SetDirectionPin(&Gpio, OUTPUT_PIN, 1);
XGpioPs_SetOutputEnablePin(&Gpio, OUTPUT_PIN, 1);
/*
* Set the GPIO output to be low.
*/
XGpioPs_WritePin(&Gpio, OUTPUT_PIN, 0x0);
for (LedLoop = 0; LedLoop < LED_MAX_BLINK; LedLoop ++) {
#ifndef __SIM__
/*
* Wait a small amount of time so the LED is visible.
*/
for (Delay = 0; Delay < LED_DELAY; Delay++);
#endif
/*
* Set the GPIO Output to High.
*/
XGpioPs_WritePin(&Gpio, OUTPUT_PIN, 0x1);
for (Delay = 0; Delay < LED_DELAY; Delay++);
XGpioPs_WritePin(&Gpio, OUTPUT_PIN, 0x0);
for (Delay = 0; Delay < LED_DELAY; Delay++);
}
When I right click on this project --> Debug As --> Launch on Hardware (System Debugger), xsdk compiles the program, downloads it to CPU0 of the target, and stops at main(). It was easy to verify that the green LED to the right of the OLED panel on the Zedboard blinked the expected number of times!