We are using the PIO core IP from Intel to implement debug registers accessible from the HPS to communicate easily with the FPGA. After testing that we could read and write such a register, I implemented a shell accessible in a Linux terminal inspired from ChibiOS.
I used those IPs to act as bypass registers in our FPGA modules. The implementation is still ongoing, but I currently have a shell command to test the correct soldering of the LEDs (by lighting all of them in a dim white).
The next step will be to complete all of our FPGA modules as well as their basic bypass register and test-benches (should be done by Monday).
I’ve been working on the HPS/FPGA communication, and how we will handle buffering.
I came up with this completed version of the architecture:
FPGA buffers will be fed by a DMA Controller. The DMAC will read data from RAM using the fpga2hps bus, and write to an AXI bus connected to all FPGA buffers.
On the HPS side, we will have a kernel module controlling the DMAC through the hps2fpga bus. It will be responsible of DMA transfer sequencing (between all buffers), and also the transfer timing.
The DMA source will be a pool of contiguous RAM buffers allocated by the driver.
Finally, the driver will expose a Linux char device. Through this device, a user-space app will be able to feed the buffers with data from various source (an SD card, a Wifi streaming).
If you think about it, each half frame-slice will need to be printed twice, for it to be seen from all points of view. Thus, the drawing flow looks like this (where each line is a half turn, and the two numbers represents the frame being drawn by each half of the panel) :
F(n, right) ; F(n+1, left)
F(n+1, left) ; F(n+1, right)
F(n+1, right); F(n+1, left)
F(n+1, left) ; F(n+2, right)
We can see that the first half always get data from the second half at previous round. Thus, if we swap buffers smartly across drivers, we can use half-a-turn buffers. This results in 3 buffers for 2 drivers storing (F(n), right), F(n+1, left), F(n+1, right)), where at each time, one buffer is useless and can be fed by the DMAC with the next correct half.
To start with simpler code, we will approximate to 1 buffer per driver (+33% data stored), with a full turn capacity. We will optimize only if needed, that is, if the throughput of the HPS -> FPGA is not sufficient to transfer that much data.
In RAM, we will have a double buffer. One where we write data for the next turn, and one with data that should be used during this turn.
I started writing the code for the FPGA module which will be feeding the LED drivers. It corresponds to the “LED Driver driver” from our FPGA architecture diagram. In order to have a functional system as soon as possible once we receive the PCB I am also building a test bench to test the module. So far I have assertions on the timing requirements (hold times, setup times, etc.), the validity of the output data and on the internal state machine coherence. I will first finish the test bench and then the module.
Concerning the timing requirements, there are 7 different LAT commands. The datasheet of the TLC5957 indicates the setup time before a rising edge of SCLK for 6 of them. However, there is a diagram of the application note of the driver (Figure 7 of SLVUAF0) suggesting that there is also a setup time to respect for the 7th command. Does anyone from spirose have additional information on that?
It’s been a long time since the last post. I’ve been busy finished the routing of our vertical PCB. We use 4 layers, layer 2 being a GND plane.
Here is the routing layer by layer, with explanations:
Since we’re done (modulo reviewing) with the PCB, we started thinking about the FPGA architecture.
We came up with an architecture based on 4 modules.
We will use the Altera On-chip Memory IP as our per-driver buffers. It is practical since it has an AXI-compatible interface that we can use to easily connect to the HPS.
A synchronizer module will be in charge of time-keeping in order to load and display data at the right time. It will also select which column to display.
The data provider will load data from the memory and pass them to the LED-driver driver.
Finally, the LED-driver driver is in charge of creating the SIN/LAT signals. It will both send data to the driver (as requested per the data provider), and display those data (as requested per the synchronizer)
We had a long discussion with a student from SpiROSE (last year’s project with a rotative LED panel). He told us the problem they faced with the motor and ESC (Electronic Speed Controller). They could not get a constant speed output from the motor because the ESC was overheating, causing a shutdown and a boot up. It was caused by the motor asking too much current. The motor was one the had on hand and not perfectly fitted to their use. It was rated at 2100 RPM per Volt. While turning at 1500 RPM the ESC pulled 5A on 12V from the power supply, the same 60W would go to the motor, but to rotate at 1500 RPM it only needed 0.7V so the output current from the ESC was closing in on the max output, which caused overheating.
Another problem was to convey the power through the axis. They had to scrub the anodising paint from the top of the motor to make a connexion to a ball bearing which was connected to the motor shaft. I would like if possible to stay away from passing to much power through the ball bearing as it can cause sparks and damage the balls. To replace this connection I am looking toward brush slip rings.
As we are proceeding with the schematics and the PCB placing, we are realizing that we will need more than a single PCB to make everything fit. We will then design an horizontal PCB, very much like SpiRose, though ours will be rectangular for budgetary reasons and it will only host our voltage regulators. The interface between the horizontal and vertical PCBs will be three big pads: GND, 3.3V and 5V. Hence, no signal integrity concerns (at least not at this interface). I placed our 12 to 5V converter on Xpedition Layout while conforming to the PCB layout guide of the module.
Furthermore, it appears that the PCB size of 190 by 190mm that we initially chose will be problematic for us to solder the LED automatically: the problem being the width of the PCB. I was going through the process of routing the LED drivers so that we could be stacking five of them on each side of the panel (according to our previous PCB layout idea), but that will have to be abandoned in order to make our PCB thinner. We will put 4 driver on each side and 2 above.
Last friday we had a class about signal integrity. As we learnt about all the problems we could have, I finally understood the use of all the bypass capacitors and some of the other esoteric symbols or annotation that are no longer a mystery (such as 0-ohm resistors or DNI annotations)
Thus, I had to update the schematic of the ULPI/USB subsystem of our project. You can see it below. Here are some important changes :
Disconnected the oscillator ENA pin : according to the datasheet, having the pin on high impedance does enable the oscillator.
Added USB power distribution switch, the TPS2051C that is needed not to break our USB device. It limits the current of our usb device to 500mA.
Added bypass capacitor to oscillator and power switch.
Updated power supply capacitors
Added 10K resistor for VBUS, connected to a 10uF capacitor that should be enough for our system. The USB 2.0 specification recommends a 120uF capacitor for hosts but we do not intend to hot-plug our USB device or have a cable between our device and our system.
Added names to everything.
Connected the RESETBn pin to our nRST.
As such, our ULPI/USB system should work. However, I have a doubt about whether or not I should add a resistor on the wire between the oscillator’s CLK and the USB3320C REFCLK. Our development kit has a resistor on its schematic, but the oscillator’s datasheet does not mention to put a resistor on the CLK output. If anybody has an idea about it, I’d be happy to hear it.
For the past days, I have been working on the schematics of our ULPI transceiver, the USB3320 and when my colleagues were working on other parts of the schematics, I had to focus on other stuff such as making our SOM work and improving our system architecture.
Making our Cyclone V SOM work was a breath of air compared to the schematic part. Following the Quick Start Guide of our development kit, I had to make sure the jumpers were setup correctly (and they were – not sure if it was the factory default or if Alexis did his magic before giving us the devkit) and configure the UART0 interface. Once everything was set and connected on /dev/ttyUSB0, I simply plugged in the devkit and it booted correctly.
As we would like to be able to use Wi-Fi USB dongles, we are currently adding host USB 2.0 support. Unfortunately, we must use the ULPI interface to communicate with our USB devices. Thus, we have to use a ULPI-USB transceiver.
ULPI works with a 60MHz clock and I am unsure for now if our FPGA can generate such an accurate reference. However, the USB3320 can work with a external oscillator and it has its own PLLs to generate a 60MHz clock from a 12MHz reference clock.
Below is a work in progress of the schematic of the USB3320 in our system. It also includes a Linear Voltage Regulator as the transceiver also needs a 1.8V DC supply.
What is definitely missing are the appropiate capacitors and resistors that I have not added everywhere yet.
I’ve almost completed the schematics of all the LED panels. Once done, I will start placing and routing it.
I tried routing a small number of LEDs to check the estimations I made in the previous post. I forgot to take the soldering pad into account, so I only managed to place a LED each 3.2mm.
Anyway, this distance is too small and we risk soldering issues. Based on the vertical distance between last year’s SPIROSE LEDs, we will put a LED each 3.4mm (1.2mm between each).
Based on this, the LED panel will take roughly 11cm x 14cm. Since the PCB is 19cm x 19cm, we have plenty of space for other components. I will try to fully route one LED panel and its drivers to check if it is possible.
For now, here is an idea of how I was hopping to do the routing:
Technically, all components (except for the power supply, which I haven’t checked) fit in. What I need to figure out is if routing is feasible,