Use EMIO and MIO directly to control GPIOs on zedboard is way more convenient than AXI GPIO, it won't need any IP. One drawback of this method is that when using the PS (programmable system) to control GPIOs directly, the signal should be sent pin by pin. So there will be little bit delays between each pin, while AXI GPIO can send all read or write signal together. However, pins that directly controlled by EMIO or MIO are dual-direction while the direction of AXI_GPIO are fixed when we created it, so it would be more convenient to control.
本章介绍用emio 和mio直接控制pmod, 不同于之前的axi gpio, 直接用ps来控制gpio的时候,每个端口需要一个个地读或写,端口与端口直接存在delay,axi gpio更像一个register, 可以同时对所有端口读或写. 不过用emio和mio直接控制的gpio是可读可写的双向端口,而axi gpio在创建的时候就已经设置了方向,要么读,要么写,所以前者更方便控制。
There three ways to drive GPIOs by PS on FPGA
(You can get rid of PS part and use bit-file only if you want to drive GPIO only by PL part)
1. PS ->MIO -> GPIOs (no need for constraints, pin_number[53:0] driven by PS)
2. PS ->EMIO -> PL->GPIOs (need constraints, pin_number[117: 54] driven by PL)
3. PS ->EMIO ->AXI Bus -> PL-> GPIOs (need constraints, pin_number[117: 54] driven by PL)
(This is the guide picture for WLAN installing)
Design:
Pmod JE is driven by MIO/ps while Pmod JA, JB, JC, JD are driven by EMIO, so we need to add constraints for JA, JB, JC, JD
1. Adding block design in vivado:
Remember to check "EMIO" in MIO configuration
Set the constraints for pins that controlled by EMIO(there is no need to write constraints for gpios that controlled by MIO, since MIO I/O are fixed)
Generate block wrapper -> generate bitstream.
2. Driving GPIOs in SDK
There is the template I created for my block design, you can uncomment different port setting to control the read/write of different pins:
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xgpiops.h"
#include "xparameters.h"
#define DELAY 10000000
#define TEST_CYCLE 8
int main()
{
XGpioPs gpioStruct;
XGpioPs_Config *gpioConfig;
s32 xStatus;
int i=0, count=0;
init_platform();
int pinNum = 54; //this is the number of first pin that controlled by EMIO !!!
u32 pin_out = 1; //1 output signal
u32 pin_in = 0; //0 input signal
// int read1[TEST_CYCLE];
int read2[TEST_CYCLE];
// int read3[TEST_CYCLE];
// int read4[TEST_CYCLE];
// int read5[TEST_CYCLE];
// int read6[TEST_CYCLE];
// int read7[TEST_CYCLE];
// int read8[TEST_CYCLE];
// int read9[TEST_CYCLE];
// int read_10[TEST_CYCLE];
// int read_11[TEST_CYCLE];
// int read_12[TEST_CYCLE];
// int read_13[TEST_CYCLE];
// int read_14[TEST_CYCLE];
// int read_15[TEST_CYCLE];
// int read_16[TEST_CYCLE];
// int read_17[TEST_CYCLE];
// int read_18[TEST_CYCLE];
// int read_19[TEST_CYCLE];
// int read_20[TEST_CYCLE];
int input0[]={0,1,0,1,0,1,0,1};// int input1[]={0,1,0,1,0,1,0,1};
// int input2[]={0,1,0,1,0,1,0,1};
// int input3[]={0,1,0,1,0,1,0,1};
// int input4[]={0,1,0,1,0,1,0,1};
// int input5[]={0,1,0,1,0,1,0,1};
// int input6[]={0,1,0,1,0,1,0,1};
// int input7[]={0,1,0,1,0,1,0,1};
// int input8[]={0,1,0,1,0,1,0,1};
// int input9[]={0,1,0,1,0,1,0,1};
// int input_10[]={0,1,0,1,0,1,0,1};
// int input_11[]={0,1,0,1,0,1,0,1};
// int input_12[]={0,1,0,1,0,1,0,1};
// int input_13[]={0,1,0,1,0,