This is an old revision of the document!
The following example describes in detail how a Digilent ZYBO Board containing a ARM Processor and a Xilinx FPGA is configured to be used with flink. The FPGA will contain a single channel PWM module and a single channel GPIO modul.
The FPGA is connected directly to the Processors AXI Bus.
In the end the block diagram should look like this:
If there is no operating system used on the Zybo flinklight can be used to get easyer access to the fpga design.
The first step after starting the SDK is to create a application project with “File→ New → Application Project”. Give the project a name and press Finish. Than add the flinklight sources to the project by right clicking on the src folder and choose new Folder. Press the Advanced button and check “Link to alternate location” than choose the flinklib folder out of the flinklight repository. Than press Finish. Next we add the newly added folder as include directory.To to that right click on the project and choose Properties. Than go to C/C++ General→ Paths and Symbols → Includes press Add and choose the flinklib folder from the Workspace.
Next we will have a look at the following example code:
#include <stdio.h> #include "platform.h" #include "xil_printf.h" #include <stdio.h> #include "platform.h" #include "xil_printf.h" #include "flinklib.h" #include "xilinx/flink_axi.h" flink_dev* dev; flink_subdev* info_subdev; flink_subdev* pwm_subdev; flink_subdev* gpio_subdev; int main(){ char description[28]; int error = 0; int i = 0; init_platform(); xil_printf("fLink Example\n\r"); set_axi_base_address(XPAR_INFODEVICE_0_S00_AXI_BASEADDR); dev = flink_open(&axi_bus_ops); u32 nr_of_subdevs = flink_get_nof_subdevices(dev); xil_printf("nr_of_subdevs= %x\n\r",nr_of_subdevs); info_subdev = flink_get_subdevice_by_unique_id(dev, 0); // info device error = flink_info_get_description(info_subdev, description); xil_printf("error= %x\n\r",error); for(i = 0; i<28;i++){ xil_printf("%x,",description[i]); } xil_printf("\n\r"); pwm_subdev = flink_get_subdevice_by_unique_id(dev, 2); // pwm device uint32_t baseclk = 0; flink_pwm_get_baseclock(pwm_subdev,&baseclk); flink_pwm_set_period(pwm_subdev, 0,baseclk); flink_pwm_set_hightime(pwm_subdev, 0,baseclk/2); gpio_subdev = flink_get_subdevice_by_unique_id(dev, 1); // out gpio device flink_dio_set_direction(gpio_subdev, 0, FLINK_OUTPUT); flink_dio_set_value(gpio_subdev, 0,1); cleanup_platform(); return 0; }
The first thing we do in the code which is not given from the helloworld example is to set the base address for the bus operations. To do that we use the set_axi_base_address(base_address) method. This Address is the info devices address which we configured in the block design memory map bevore.
The next step is to open the flinkdevice with the flink_open(&bus_ops) method. The bus_ops depends on how the fpga is connected to the processor. In our example the fpga is connected to the internal axi bus of the processor. Flink allready offers the bus_ops for this bustype so we can use them.
With the flink_get_nof_subdevices(dev) method we can check how many subdevices have been found. In our case this should return 3 (info, pwm, gpio)
To easy access the subdevices we need a reverence to them. There are different ways to get this reference. In our example we will use the flink_get_subdevice_by_unique_id(dev, id) method. In the block design we configured the unique ids of our three blocks. So with this ids we can get easy accesses to our subdevices for example to get access to the info device we will use the method with id=0 for the pwm we use id=2.
After we have a reference to a subdevice we can use the subdevice specific methods to interact with it. In our example we us three methods to configure the pwm output. First we get the base clock frequency with wich the pwm subdevice is connected. For that we us flink_pwm_get_baseclock(pwm_subdev,&baseclk). With this frequency we can than configure the pwm period and high time with the two following methods: flink_pwm_set_period(pwm_subdev, 0,baseclk), flink_pwm_set_hightime(pwm_subdev, 0,baseclk/2). In this example we set the period to baseclk which corresponds to 1sec. The hightime we set so baseclk/2 with will result in a pwm ratio of 50%
The same thing we can do with the gpio subdevice. There we only need two methods: with flink_dio_set_direction(gpio_subdev, 0, FLINK_OUTPUT) we set the direction of the gpio to output. Than we can use flink_dio_set_value(gpio_subdev, 0,1) to set it to a high state.
The Linux part works the same on all systems please checke this page.