cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Bystander25
Visitor
Visitor
467 Views
Registered: ‎05-02-2021

Mapping XC7Z010 pins to XGpioPs function pin input

Question

How do I map package numbers like BANK34_R18 to pin numbers that I can input to XGpioPs functions? 

Background 

I'm working with an evaluation board and am following a tutorial in which the Zynq 7 processing system is configured in Vivado and then the following code is launched on hardware from the SDK. 

 

#include "xgpiops.h"
#include "sleep.h"

int main()
{
	static XGpioPs psGpioInstancePtr;
	XGpioPs_Config* GpioConfigPtr;
	int xStatus;

    GpioConfigPtr = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);
	if(GpioConfigPtr == NULL)
		return XST_FAILURE;

	xStatus = XGpioPs_CfgInitialize(&psGpioInstancePtr,GpioConfigPtr, GpioConfigPtr->BaseAddr);
	if(XST_SUCCESS != xStatus)
		print(" PS GPIO INIT FAILED \n\r");
	 XGpioPs_SetDirectionPin(&psGpioInstancePtr, 54,1);
     XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, 54,1);

	 while(1)
	 {
		XGpioPs_WritePin(&psGpioInstancePtr, 54, 1);
		usleep(200000);
		XGpioPs_WritePin(&psGpioInstancePtr, 54, 0);
		usleep(200000);

	 }
    return 0;
}

 

 

This is a simple LED blinker that connects to the LED via package pin D19 of the XC7Z010 evaluation board. My question is where is the conversion table showing that pin 54 is connected to the package pin D19? Sectional 14.1.2 of the Zynq 7000 technical reference manual informs me of the following groups.  

• Bank2: 32-bit bank controlling EMIO signals[31:0]
• Bank3: 32-bit bank controlling EMIO signals[63:32]

So I know that pin 54 is a valid EMIO pin. But this does not show the correspondence between package pin assignment (which follow the format alphabetic + number) and these numerical groupings shown in the above bullet list. I found the package pinout the Xilinx documentation UG865 which shows lower level pin names. I have attached a screenshot below of the package pinout from this document. I see that pin D19 is an empty white circle and so IO_LXXY_# is apparently its "name". I assume this information is used for register-level assignments.

But when using a high-level function like XGpioPs_WritePin which takes a pin number as one of its inputs how am I supposed to know that the pin number for some arbitrary package name? For example, if I wanted to program EMIO package pin BANK34_R18 to generate a square wave how would I find the correct pin number to input to XGpioPs_WritePin?

Thank you

xc7z010 pinout.PNG

 

0 Kudos
9 Replies
Bystander25
Visitor
Visitor
458 Views
Registered: ‎05-02-2021

Update: 

The .XDC file contains these pin assignments. Particularly these two lines.

 

 

set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_0_0_tri_io[0]}]
set_property PACKAGE_PIN D19 [get_ports {GPIO_0_0_tri_io[0]}]

 

 

But I'm wondering where in the documentation can I find GPIO_0_0_tri_io[##] referenced? Searching the technical reference manual doesn't turn anything up so I'm still not sure how to find the index number of this variable (GPIO_0_0_tri_io) for an arbitrary package pin like R18. Does anyone have any ideas on where documentation like this is? 

0 Kudos
derekm_
Voyager
Voyager
436 Views
Registered: ‎01-16-2019

You've gone way down a completely unnecessary rabbit hole, such that it is hard to know exactly what you are trying to do. It will be easier to help if you tell us the evaluation board, the tutorial you are following, and the GPIO pin you are trying to use.

0 Kudos
derekm_
Voyager
Voyager
436 Views
Registered: ‎01-16-2019

[post deleted by derekm_: bad info!]

0 Kudos
Bystander25
Visitor
Visitor
325 Views
Registered: ‎05-02-2021

That's good to know it certainly felt like a rabbit hole. I purchased the QMTech third party development board which is the first listed on this page. Here's a link to the tutorial. I'm working through project 2 EMIO Led in the tutorial. And here's a link to the Vivado project zip folder I'm following along with. Since reading a bit more through the technical reference manual, the thought occurred that 

 

GPIO_0_0_tri_io[0]

 

may refer to a register. Or it could have to do with my block diagram's pinout shown below. 

myBlockDiagram.PNG

which has the GPIO port labeled as GPIO_0_0. Which led me to investigate the GPIO setup in the processing system. 

MIOConfig.PNG

So the notion I have is to set EMIO width to be however pins I want to access in the banks (such as Bank35_K18 and Bank35_L14) and then assign these sequentially to output ports using the following assignments in the design constraints folder. 

 

set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_0_0_tri_io[0]}]
set_property PACKAGE_PIN K18 [get_ports {GPIO_0_0_tri_io[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_0_0_tri_io[1]}]
set_property PACKAGE_PIN L14 [get_ports {GPIO_0_0_tri_io[1]}]

 

But in the above case how can I tell which should be GPIO_0_0_tri_io[1] and which should be GPIO_0_0_tri_io[0]? In addition, after I make these connections how can they be accessed programmatically in C? How can I tell which pin is to be passed to functions like 

 

XGpioPs_WritePin(&psGpioInstancePtr, [pin number], 1)

 

?

My next thought is to just do this all via register access which is what I'm working on now. 

 

0 Kudos
Bystander25
Visitor
Visitor
322 Views
Registered: ‎05-02-2021

Thanks for your reply. My ambiguity rests then with the function of the IP integrator. When I open the IP integrator there doesn't seem to be a place to dictate that some package pin say R18 will be assigned to GPIO MIO. I do see options for enabling GPIO such as in the following screenshots attached to this reply. "peripheralIO.PNG" may hold the key. I see that pins can be selected from bank and pin numbers and the selected options are green. So what I'm wondering now is how can I decode Bank numbers into alphanumeric package pins. For example in the screenshot Bank 0 pin 10 is green but which package pin is this? 

Put another way, how do the green enabled pins (such as the EMIO block on the far right of the IP integrator Peripheral IO screen "EMIO_peripheral.PNG" which is apparently assigned to Ethernet) correspond to a function call such as XGpioPs_WritePin(&psGpioInstancePtr, 54, 0);?

 

MIOConfig.PNG
peripheralIO.PNG
EMIO_peripheral.PNG
0 Kudos
Bystander25
Visitor
Visitor
308 Views
Registered: ‎05-02-2021

Update:

I enabled a larger EMIO configuration from MIO peripherals and saw that the block diagram changed to what is shown in "MoreGPIOs.PNG". The name GPIO_0_0_tri_io is mentioned in the designs tab as shown in "designs.PNG". So that confirms my theory that editing the constraints file will allow access to more elements in the GPIO_0_0_tri_io bus. And that I can dictate which package pin goes to which element in GPIO_0_0_tri_io using the constraints file. That still leaves me unaware as to which element of GPIO_0_0_tri_io belows to a certain pin number in the C function XGpioPs_WritePin(&psGpioInstancePtr, 54, 1). Where did 54 come from? 

Thank you

designs.PNG
MoreGPIOs.PNG
0 Kudos
derekm_
Voyager
Voyager
280 Views
Registered: ‎01-16-2019

Okay, I see the problem now. That company is selling Zynq platforms without providing board files (unforgivable, imo), making it much harder to use the board.

I will try to give an answer, hopefully not too long-winded. You probably know the difference between MIO and EMIO by now: MIO are fixed in the processing system and must be shared between all the peripherals in the PS. There are only 54 pins, meaning you have to share them out appropriately. EMIO makes up for this lack of pins by allowing you to route many (but not all) peripherals to the programmable logic.

For GPIO, there are four banks in the PS. Banks 0 and 1 are MIO only, and comprise a maximum of 54 pins (i.e. you could use up all your MIO pins just for GPIO if you wanted, with pin numbering 0-53. Nobody does that, of course, but you could if you wanted). Banks 2 and 3 can be mapped to EMIO instead. So the EMIO pin numbering starts at 54 (i.e. Bank 2:bit 0 = 54, Bank 2:bit1 = 55, etc). Note that this pin numbering really just corresponds to software IDs though.

In your design I can see that you have one EMIO bit mapped to GPIO. So this is Bank2-bit0 = 54 (for software purposes). However, in Vivado you also need to map the EMIO pin to an FPGA pin. In the FPGA, the place to look for the pin name is in the top-level wrapper file, as shown below. The pin name is similar to the name in the block diagram in IP Integrator, but the top-level wrapper adds a buffer, hence the "tri_io" addition.

 

pin_mapping.png

 

In the XCF file, you then set the IOSTANDARD and pin location as you are doing. The EMIO pins are mapped as a bus, but as you are just using bit 0, the pin name is GPIO_0_0_tri_io[0].

 

set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_0_0_tri_io[0]}]
set_property PACKAGE_PIN D19 [get_ports {GPIO_0_0_tri_io[0]}]

 

 

You also need to check the schematic to see where pin D19 is connected to on the board, and connect up a scope or whatever. Then to drive the GPIO in SDK/Vitis, you use the software ID for the pin, which is 54.

 

XGpioPs_SetDirectionPin(&psGpioInstancePtr, 54, 1);
XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, 54, 1);

while(1)
{
  XGpioPs_WritePin(&psGpioInstancePtr, 54, 1);
  usleep(200000);
  XGpioPs_WritePin(&psGpioInstancePtr, 54, 0);
  usleep(200000);
}

 

 

That might get you there?

 

derekm_
Voyager
Voyager
272 Views
Registered: ‎01-16-2019

I see you are talking about BANK34_R18. This is what the schematic looks like (if I have the right file):

bank34_r18.png

The XCF entry should look like this:

 

set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_0_0_tri_io[0]}]
set_property PACKAGE_PIN R18 [get_ports {GPIO_0_0_tri_io[0]}]

 

 

Your other question re. enabling more EMIO GPIO pins... If you had 4 EMIO pins enabled, for example, the XCF might look like this:

 

 

set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_0_0_tri_io*}]
set_property PACKAGE_PIN R18 [get_ports {GPIO_0_0_tri_io[0]}] // SW = 54
set_property PACKAGE_PIN V17 [get_ports {GPIO_0_0_tri_io[1]}] // SW = 55
set_property PACKAGE_PIN W18 [get_ports {GPIO_0_0_tri_io[2]}] // SW = 56
set_property PACKAGE_PIN W19 [get_ports {GPIO_0_0_tri_io[3]}] // SW = 57

 

 

Bystander25
Visitor
Visitor
239 Views
Registered: ‎05-02-2021

Thanks a lot. These answers make a lot of sense. In addition to the info on this thread for EMIO pin usage and as a follow up for future readers, I was able to access MIO pins by first referencing the datasheet and finding the MIO output pin on a jumper. The output pin was MIO52 and the following C code was able to generate a square wave using only high level functions and no register level work. 

#include "sleep.h"
int main()
{
	static XGpioPs psGpioInstancePtr;
	XGpioPs_Config* GpioConfigPtr;
	int iPinNumber= 52;
	u32 uPinDirection = 0x1;
	int xStatus;

    GpioConfigPtr = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);
	if(GpioConfigPtr == NULL)
		return XST_FAILURE;

	xStatus = XGpioPs_CfgInitialize(&psGpioInstancePtr,GpioConfigPtr, GpioConfigPtr->BaseAddr);
	if(XST_SUCCESS != xStatus)
		print(" PS GPIO INIT FAILED \n\r");

     XGpioPs_SetDirectionPin(&psGpioInstancePtr, iPinNumber,uPinDirection);
	 XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, iPinNumber,1);

	while(1)
	{
		print("Write high to MIO52\n");
		XGpioPs_WritePin(&psGpioInstancePtr, 52, 1);
		usleep(2000000);
		print("Write low to MIO52\n");
		XGpioPs_WritePin(&psGpioInstancePtr, 52, 0);
		usleep(2000000);

	}
    return 0;
}

Search terms: QMTech, Bajie Board, XC7Z010, XGpioPs