Well - I finally managed to do it!

I have created a basic project based on the lessons from the training.



Through Avnet, Xilinx and Element14, a training program to learn about the Zynq 7000 platform which is System On Chip combining an FPGA with an ARM processor. This comes to the students as complete development board packed with goodies like a wireless chip from MuRata (BT/BTLE/WIFI), 8GB Flash memory, onboard RAM, USB to JTAG (JTAG programmable over USB), Arduino-style headers (3.3V compatible only), Microphone, Bi-Color LED, and two additional expansion ports.


See all blog posts for this training here.


What did I do?

My project was supposed to be a line follower, but I had to limit the scope to just the sensor array as I talked about in the previous blog post. I spent a number of days trying to run with external hardware using an ADC to read the line sensor array; but for the life of me, I couldn't get the I2C bus to work. I continually got compiling errors in SDK relating to an interrupt library:


fatal error: xintc.h: No such file or directory


I wasn't able to find any example code that I could start with as a base.


My project ended up being an Timer Interrupt library based in the FPGA fabric. It generates an interrupt every "N" clock cycles; and I mapped it to the 48 MHz clock. This interrupt then feeds into the interrupt concatenator as interrupt #0. This still is relative to what I had wanted to do, but much much farther away from where I wanted to be.


I used the IP Library to find new IP and import into my hardware design. I then exported the hardware and made a new workspace & BSP in the SDK utility. I started with some base code in the SDK and got it working with my new hardware to run things. So I'm using both the PS + PL. I had to re-map the interrupt which was used in the base program to the one generated from Vivado.




This project uses the PWM LED dimmer as a base code for the PS side of things; but modified. When the FPGA Fixed Interval Timer ("FIT") generates an interrupt, it is captured in the PS running my code. We keep count of the number of interrupts and use that to run the PWM signal back out to the real world.


Here is the functional part of the ISR that does it:


void PWMIsr(void *InstancePtr)
count += 1; // add one to the counter
brightness = (count % 10)* 110000; // count modulus 10, multiplied by 110000 to normalize with the clock
xil_printf("\033[2K I have been interrupted %u times! Setting brightness to %u \r", count, brightness);
Xil_Out32(PWM_BASE_ADDRESS, brightness);//write value to PWM controller back in the PL


This code is still related to the project I wanted to do. I spent hours trying to create the part of the line follower which reads a wheel encoder and provides feedback about the speed of the robot before I settled on this as a start. Since this has a consistent time-based interrupt, I could use it to periodically check a counter to calculate the frequency of pulses; which correlate to speed. The output of this would then feed into a PID loop to adjust the PWM signal going out to the wheel motor based on the speed delta.


I can say that this has been very tough challenge as I don't have any background with FPGAs. Although this project is hardly earth shattering in terms of complexity, but it does demonstrate that the training has actually given a total beginner enough knowledge to perform some basic tasks. As stated above, this does make use of both the PS + PL, and both Vivado and the SDK were required to make all of this work. I had to find & import IP on my own, re-wire the block diagram, export a valid bitstream; then import to SDK and write [well, ok, 'modify'] a corresponding program. I have gotten much better at navigating the interfaces now that I'm doing it on my own. I decided that I like the automatic build when you save a file in SDK. One other nice thing as stated in a previous blog was the System Debugger lets you edit code and upload right from the deugger; which made it much faster and easier to develop. I thought at first that this would be annoying; but when running the debugger I can edit code right there, hit save (which generates a new build) then restart the deubgger immediately. I'm really curious what shortcuts are available on this platform to speed up hardware debugging because using the FPGA side to alleviate pressure on the ARM processor would be amazing and key to the line follower that I would like to build with this.


I found myself numerous times falling into some of the traps that the training warned about - importing code incorrectly, leaving a space in the Application Project Name (see cryptic error message below), and many other things. I would start getting cryptic errors and after an hour or so of troubleshooting, I would realize my mistake.


Error message from invalid application project name. This doesn't show up until one tries to run the debugger.

wrong # args: should be "dow ?options? file ?address?"


As with the Smart Range Hood design challenge, my sympathetic wife hung in there watching our two kids while I hid away in the workshop on this project, so I owe a big thanks to her.


See the video here to watch it in action! (sorry about the background noise with my 3D Printer running)




What did I learn from this? What are the take-aways?

Well... as far as the actual training documents, they are very well written. As long as someone can follow them, they can complete the lessons. There are training videos which are pretty dry and the presenter can be seen reading the prompter which was pretty distracting; but otherwise were very good. Looking back, I think I would have preferred having the SW (SDK) lessons first, then introduce the Hardware lessons and Vivado. The reason is that, especially for someone new to all of this, things can get overwhelming. As we modify the hardware in Vivado, there are quite a few steps required to get it running on the actual board - Synthesize, generate Bitstream, Export. Open SDK, Import hardware and generate Board Support Package. Create a new application (even it it is an empty 'do nothing' app), THEN we can program the FPGA, Then we have to run the application.


With this board, The FPGA (PL) can't run without at least a generic PS program. If we had done the software training first, then at least I would have been more comfortable with the SDK before I get in a start with the FPGA stuff. But then again, part of the focus of this training was around using an FPGA, so doing training in that order does seem a little backwards, and also means we couldn't write FPGA programs until the second half.


A huge thanks to Xilinx, Avnet, and Element14 for sponsoring this contest! I plan to continue to develop more with the MiniZed and really let it flex its muscles.


- James O'Gorman