The goal is to use a Raspberry PI Zero (or 2W) with RealTime Linux Patches running modified version of BaseFlight for a flight computer. One of the issues was generating OneShot protocol to control the ESCs (motor controller) from BaseFlight. So, why not use an FPGA to generate OneShot signals instead of taking resources on the PI to generate the signals.
Buildroot was used to create a distribution with RealTime patched Linux kernel. (If you need more information on how to do that please let me know)
This project does not go into a detailed step by step process to create the Vivado project and using iverlog to validate the design. Please comment below what you would like more detail on and I will add it.
How to communicate to the FPGAThe PI has SPI, TTL serial, I2C, and USB. The protocol needs to be fast and simple, so, SPI was chosen as the physical transport. The next issue is how to send simple read and write commands to the FPGA and process them. Also, it would be great to have a way to add functions/peripherals.
FPGA Communication designTo keep it simple, lets use a hardware bus, which has a defined way to access different blocks of memory, for example:
- Address i.e. 32 bits: To access different registers or devices
- Data bus to read and write the registers
Wishbone is a simple bus that was selected for this design. AXI Lite could have been used, maybe next time. AXI is used in ARM processors and has detailed specification and has many examples.
Shown below is a basic diagram of the FPGA system:
FPGA Code and external libraries
The code is provided below.
The SPI interface is from here. The Wishbone library is from here. The MUX is generated by using a python script from the wishbone library.
The complexity is how the Wishbone library is used, it has two AXIS ports using, one transmit port and one receive port. Glue logic needed to be created to interface between the SPI interface and the wishbone AXIS interface.
Example controlling the LEDsOne simple way to test is not use a MUX and attach the LED peripheral directly the Wishbone library. This is shown below:
The constraints file supplied with the board is modified to to map the SPI pins, MISO, MOSI, CLK, and CLK. Also, the four LEDS are mapped along with the RGB LEDs.
Using the PI to test FPGAspidev0.1 which is the SPI0 MISO, SPI0 MOSI, SPI0 CLK and CE1 is connected to the FPGA.
Shown below is how to use terminal to send SPI byte sequence to read and write byte stream. Here is an example:
# printf '\xA2\x1\x2\x3\x0\x0\x4\x11\x22\x33\x44\0' | spi-pipe -m 0 -s 1000000 -d /dev/spidev0.1 | hexdump -C
00000000 44 44 a4 01 02 03 00 00 04 04 04 04 |DD..........|
0000000c
#
0xA2: is command byte for write
0x01020300 is the address to write to
0x0004 is the number of bytes to write
0x44332211 is the bytes to write (Notice the bytes are reversed)
To read:
# printf '\xA1\x1\x2\x3\x0\x0\x4\x0\x0\x0\x0\0\0' | spi-pipe -m 0 -s 100000 -d /dev/spidev0.1 | hexdump -C
00000000 04 04 a3 01 02 03 00 00 04 11 22 33 44 |.........."3D|
0000000d
#
What comes back is, 0x04, 0x04 are two bytes are trash. The next bytes are the reply:
0xA3 is reply to the read
0x01020300 is the address
0x00 0x04 is the length
0x44332211 is the data that was written
Unit testing using iverlogThere are several test benches, tb_pwmdecoder_wb.v for validating the pwm decoding should work with a 100Mhz clock. tb_spiwishbone.v sends SPI data to read and write registers.
ValidatingShown below is a logic analyzer trace showing a write command sequence. In the project there is a python script to set the LEDs via spidev. The SPI frequency is 3.2Mhz. On the PI download the ledTester.py and issue the following command.
# python ledTester.py
The script will write the command as fast as possible. From the trace the commands are sent at a rate of 2.6Khz.
Comments