Skip to How to use this repo to see how to get to the relevant files.
Quadcopter controller based on Altera Cyclone-V. The motivation of multi-processor system is fault tolerance, from sensor failures (the project gets data from up to 3 IMUs) to tolerance in processing errors (e.g. radio communication is handled by separate processor, such that main processor makes decisions when the signal is bad, without the need to handle UART communication and correction sum calculation).
This repo does not include 1.5 GB Quartus II project! Instead, this repo contains the hardware description files (VHDL) and software (C/C++) to teach how to deploy multi-processor system on Cyclone-V. Therefore, this repo is brief and well documented and should be of use to anyone that uses Cyclone-V (not just quadcopters/drones) to leverage the processing power of embedded platforms. Although, the Quartus II project, which is based on freerly available Golden Hardware Reference Design (GHRD) for Cyclone-V, can be shared via link, once contacted at [email protected].
For TL;DR, to navigate through this repo, use the diagram below and link to the files to get what you need. The code within the files is well documented (grey round boxes) and should be sufficient to understand the main aspects of the code together with documentation files (blue round boxes).
Quad_SoC_v1_0/src/main.cpp: main file with main loop running in ARM under Linux
- initialize FPGA components and then hand-off the control to Nios II co-processors
- handles 2-way communication with co-processors through FPGA components aux_radio_0_mem and aux_imu_0_mem
- sets co-processor control registers
- polls co-processor registers
- reads information processed by co-processors from memory
- performs high level data processing (navigation, PID control, etc)
API_Interconnect.hpp: object for mapping virtual address space provided by Linux, to hardware address space of FPGA components (hardware addresses are assigned in Qsys)
- software representation of L3 Interconnect -> HPS-to-FPGA Bridge (HPS is a master to this communication)
- good example of properly handling virtual address conversion to FPGA address space
- NOTE: FPGA-to-HPS (FPGA is master) is not utilized, since this is handled by interrupts, which are notoriously difficult to handle in Linux
hps_0.h: file containing physical address space of FPGA components
- generated by winfo2header utility from soc_system.sopcinfo
AUX_RADIO_constants.h: well documented memory map of FPGA component aux_radio_0_mem
GHRD/software/aux_radio_0/src/main.c: main loop running on Nios II co-processor aux_radio_0
AUX_IMU_constants.h: well documented memory map of FPGA component aux_imu_0_mem
GHRD/software/aux_imu_0/src/main.c: main loop running on Nios II co-processor aux_imu_0
API_PWM_module.hpp: object for controlling PWM FPGA component from Linux
API_UART_module.hpp: object for controlling UART FPGA component from Linux
API_I2C_module.cpp: object for controlling I2C FPGA component from Linux
MPU6050_DMP_arbiter.c: Nios II co-processor functions to handle the communication with MPU6050
QUADCOPTER_documentation.docx: the main file documenting the development of this project
Qsys.png: a screenshot of Qsys (System integration tool) depicting the connections of FPGA components
soc_system.html: auto-generated documentation for FPGA layout/Qsys view
HOW_TO_NiosII_boot_from_On-Chip_Ram.docx: documents how to make the Linux configure the FPGA (load the FPGA components) during boot (otherwise, the FPGA part of SoC needs to be loaded through USB Blaster II every single time after hard-reset)
HOW_TO_wishbone_interface.docx: documents how to go from Wishbone interface (generic interface for OpenCores FPGA components) to proprietary Avalon interface (Alteras HPS-to-FPGA Bridge interface)
- it is very useful, when one can generate a VHDL wrapper, that handles the translation of Wishbone to Avalon, since then one can create a trully integrated components using high-level tools like Qsys
- the VHDL wishbone-to-avalon wrapper for i2c FPGA component
checksum_testing.docx: guidline on how to calculate checksum for packets sent through Flysky iBus protocol
- the checksum calculation is implemented in C and can be found in aux_radio_0/src/main.c line 185
FS-iA10B_iBus_TX_data.txt: matching the hex-values to radio channel values ontained from UART communication from Flysky FS-iA10B
The repo is intended to run on Atlas-SoC board with Cyclone-V ARM-FPGA chip. Furthermore, there is a custom PCB of a Quad Support Board which holds Radio Flysky FS-iA10B and up to 4x Inertial Measurement Units MPU 6050. The hardware components are depicted below, so one can check whether, for instance, the newer version of the product has compatible pinout (especially the MPU 6050).
Custom PCB board that fits on top of the Atlas-SoC board. It provides a simple way to hold all components firmly in place, which was found very usefull when debugging the UART and I2C communication, since the issues with improper connections is eliminated.
NOTE: mind the pinout of the MPU 6050 board.
The pins for UART communication are highligted (UART TX (cyan) and RX (green))
Cyclone-V from Altera, or Zinq-7000 Xilinx (the only competitor at the moment), is a hybrid architecture integrating ARM core(s) and FPGA fabric coupled with Interconnect on single System-on-Chip (SoC) device. The internal architerure is depicted below.
The Quad SoC uses both the ARM and FPGA to implement multi-processor system.
- ARM
- executes high level functions provided the data from Nios II co-processors
- control software is running in Linux with underlying custom communication layer control software -> Linux -> FPGA -> Nios II co-processors and vice-versa
- FPGA
- aux radio
- Nios II co-processor responsible for handling communication with external radio transciever through UART
- aux imu
- Nios II co-processor responsible for managing and collecting data from up to 4 IMUs through I2C The content of FPGA, connections in FPGA fabric, GPIO connections and external components are shown below.
- aux radio
i2c_0: VHDL source code for i2c FPGA component (all credit goes to the author Richard Herveille)
wishbone-to-avalon wrapper: VHDL wrapper to translate Wishbone to Avalon interface
pwm_0: VHDL file of the PWM FPGA component
package_common.vhd: useful functions for VHDL programming, for instance binary operations require ceil_log2 function