Categories

[SpiROSE] Driver protocol and renderer test

Driver protocol

This week I have made a lot of changes in the driver controller code. This module controls all 30 drivers, so it has to send the data, sclk (shift register clock), gclk (displayed clock) and lat commands. To test it we have a PCB with 8 columns of led (7 columns with only one led, and a last column with 16 leds), this simulates what a driver will have to drive : 8 columns of 16 leds, with multiplexing. We have connected a driver to this PCB, and use the DE1-SoC card we have at school as our FPGA. On those cards the FPGA is a cyclone 5, not a cyclone 3 as we plan to use, however the driver controller code is device agnostic so it is not a problem.

The module driver controller is supposed to receive data from another module, called framebuffer, which read the images in the FPGA ram. Thus for the test I wrote a simple framebuffer emulator which send data directly, without reading any ram.

The driver controller is a state machine, it can send a new configuration to the drivers, dump this configuration for debug purposes, do a Led Open Detection, or be in stream mode where it sends data and commands to actually display something. This last state has to be in sync with the framebuffer, thus the framebuffer sends a signal to the driver controller when it starts sending data from a new slice. When the driver controller goes from any state to the stream state, it has to wait for this signal. This signal will also be used by the multiplexing module.

The drivers have a lot of timing requirements, after each lat command sclk or gclk needs to be paused to give time to the driver to latch his buffers, and the data and lat needs to change severals ns before and sclk rising and falling edges. Therefor I added a second clock, two times faster (66 MHz), and used it to generate two clocks at 33MHz, in phase quadrature. One is used to clock the state machine, the other is used to generate sclk and gclk. This means that the lat and data edges will occurs a quarter cycle before or after the sclk/gclk edges, which is enough to respect the timing requirements.

In stream mode, gclk has to be input as a segment of length 2^n. During a segment we have to send all the new data to the 16 leds, and input the right lat commands to latch the buffers. The final command has to be input precisely at the last gclk cycle of the segment. In poker mode we send only 9 bit by leds, which takes 9*48 = 432 sclk cycles. The closest power of two is 512, thus we have 512-432=80 cycles of blanking to put somewhere. It was first decided to do all the blanking at the beginning of a segment, and then stream all the data. However as stated before, we need to pause sclk after each WRTGS command, which are sent every 48 cycles. Fortunately one cycle is enough, thus we have 8 blanking cycles not occurring at the beginning of a segment. So now we have 72 cycles of blanking, then one cycle of blanking every 48 cycles.

This means that the frame buffer has to take into account those blanking cycles. Just skipping one shift all the data, resulting in a weird color mix.

Demo

To test all this I wrote two simple demo. One simply lights all the leds in the same color (red, blue or green). The second one lights the led with the following pattern:

A button allow to shift the pattern, resulting in a nice Christmas animation.

You can notice that the colors don’t have the same luminosity. Fortunately this can be control with the driver configuration: each color has a 512 steps brightness control. What it still unclear to me is if the driver simply diminish the power sent to a color, or divide the same amount into the three colors. The current measures we have made seems to suggest the later, as the global amount of power doesn’t change when reducing the green intensity for instance.

Renderer test

The renderer allows us to voxelize an opengl scene. It is still a proof of concept and will soon be turn into a library. To test it, I wrote an sh script that does the following steps:

  • Start the renderer with default configuration to see if there is no error and that the shaders load properly
  • Take a screenshot of the rendering with imagemagick, and check that something is actually displayed by checking the color of the central pixel
  • Start the renderer with a simple sphere, take a screenshot and compare it (with imagemagick) to a reference image to detect any changes
  • Start the renderer in xor and non-xor mode, and compare two screenshot taken at the same time

[AmpeRose] And yet another problem… Experts… A word…

Hello,

So, in previous posts, we’ve shown you the results of simulating Switches, initial calibration, automatic calibration sub-system, etc. In addition, we’ve talked about some problems and how we’ve approached them and shared the results with you. However, we are still having a little problem, let’s see what’s happening… The origin of the problem is the DUT itself, to be more precise, it’s the decoupling capacitors that are bothering us. Yesterday, we showed you (In this post) that  a decoupling capacitor must be used by the DUT to ensure that we do not have a big voltage drop in case of a very fast transition between current ranges. This guarantees that the DUT will always be powered up.

Now, we’re getting closer to the problem.

Problem Statement

A negative current is being fed to AmpeRose by the decoupling capacitors during fast current transitions, therefore delaying the stabilisation of the op amp output.

Remember that we’re sampling each 10 us. That being said, a lot of samples would need to be discarded (~ 70) before voltage stabilization.

What do we want?

We want to block the current flowing from the decoupling capacitor of the DUT, easy, let’s use a diode.

Not that easy! In fact, an ideal diode would have definitely solved our problem(?), because it allows the current to flow in one direction only and does not consume any voltage (drop voltage = 0). However, such a diode does not exist… 🙁

Different solutions

Constructors (Linear tech, Maxim,…) provide different near-ideal diode solutions. However, the drop voltage is still huge, and therefore not suitable for our needs.

Well, I hope I made the problem clear… If you have any questions or clarification requests, we’re here to answer… And, it goes without saying… We’re open for any and all suggestions.

Thank you.

[SpiROSE] LED Panel, end of place and route

Nothing really interesting for me this week, except place, route, place again, route again, etc.

The LED panel is pretty hard to route because of the constraints we have on it. Here are some stats about it:

  • There are 1920 LEDs, 15 drivers, 4 buffers, and 2 multiplexers inside a panel.
  • The top of the panel must have placeholders of approx. 10x10mm regularly to fix it using brackets, these placeholders will also be used as wires for electrical power input.
  • There will be 5 micro-blocks (a micro-block is a vertical set of 8×48 LEDs, with two drivers on top, one on bottom)

For fun, I looked at the stats from XPedition Layout, and saw there are approximately 12000 vias.

I would never have done everything by hand, it would have been too much repetitive work to check manually after. Hopefully mentor gives some utilities to help us copying blocks, here are the main ones I tried.

Hierarchical design and Instantiation

There are two main ways to design a circuit : by describing it explicitly, using pages to separate functions when possible (and appropriate), or abstracting parts of the schematic by defining new symbols representing a whole function.

The last method comes when the schematic is starting to get so big that it becomes difficult to read the schematics all at once. It is kinda similar to functions in procedural programming languages like C/C++. Another big advantage is the capacity of the symbols to be used more than once, making it easy to reuse a whole block.

This is where hierarchical designs can come in our design: designing a symbol as a whole micro-block makes the schematic approximately 5x smaller, with a guarantee that the micro-blocks will be wired in the exact same way. Finally, instantiating 5 micro-blocks let me place 5 big “components” already wired inside the PCB, and not manually placing and routing the 384 LEDs of the micro-block individually 🙂

Unfortunately, this systems works fine if it is conceived hierarchically from the beginning. If already placed and routed a micro-block, and putting it inside a symbol broke the link between the schematic and the PCB, breaking my place/route I already made…

Clusters and Circuit reuse

Another way of doing it is by using clusters. Cluster (Type 152 as described in the mentor’s documentation) is a type (physically represented by an integer) you can add in a device property. It acts as a group function: put some parts into the same cluster and they will be recognized as ‘equivalent’ parts. Here is how I’ve done this (UB0 is the reference micro-block, already placed/routed, I want to duplicate it and name the duplicated version UB1):

  • Set every LED’s cluster property in UB0 to a different number quickly by selecting the LEDs only (be careful not selecting special symbols like intrapage connector, power symbol, etc.) and using the ‘place text’ in ‘Type 152 – Cluster’ mode with options ‘auto-increment’.
  • Same for all the other devices like IC, resistors, capacitors, etc.
  • At this point there should be one element inside each cluster.
  • Copy paste (including net names) the whole UB0 schematic, and without unselecting it, replace text ‘UB0*’ to ‘UB1*’ with option ‘selected text only’ (I suppose all the different nets start with ‘UB0’, adapt as needed)
  • The schematic is ready!

Now for PCB:

  • Package, forward annotate.
  • Select (in select mode) UB0 parts, nets, vias, etc.
  • Now you have two options: direct paste (using clipboard) or save the selected circuit for future reuse.
  • If you activate licence for ‘Circuit Reuse’, you can save it (inside the ‘Edit’ menu).
  • Otherwise, just right-click and ‘Copy’. From there you should have a pin map assigner window where you can adjust your paste settings (if it does not show, just hit ‘F2’).
  • Oce it’s done, you can paste, and it’s done!

The problem with this being that there is no verification of integrity between the micro-blocks (if you rip/shortcut a wire somewhere in the schematic on one micro-block, you may not be notified).

This is what I applied because it is easier to use when you already have an existing design.

 

Next week, the last part will be added and the bottom part of the panel will be routed, finally!

 

[AmpeROSE] Current generation for the initial calibration

Hello,

As you saw in a previous post, we are going to do some measurements on the AmpeROSE to do an initial calibration, to correct eventual imprecisions. To do that we need to be able to put a current that we know and control precisely. In order to achieve our goal, we decided to use a current mirror, the one we are going to use was built by Analog Devices and has the reference ADL5315. The following figure shows you how we will use it.

Since it is a current mirror there is some current being copied from somewhere to somewhere. Here it is the current flowing through INPT that is copied to IOUT. Then this current is injected in our measurement system : MIR+ and MIR- are connected to the shunts.

To generate a current on INPT, we used a resistor to force the current which depends on the voltage on the INPT pin. So, we also need to control the voltage on this pin. That is simple here because we have the same voltage on INPT and VSET, so we only need to force one voltage on the VSET pin to have the same on INPT. Then we know the voltage and the resistor so we can deduce the current. In our application, we want to have some precise current, so we chose the current and then we compute and apply the voltage  we need of VSET.  As you can see, we have 2 resistors, so depending the current we need to generate, we use one or both (which is almost equivalent as saying the other here).

To control the voltage on VSET, we are using a voltage divider. This voltage divider is built upon a digital potentiometer. So, we can use it to vary  the VSET voltage to generate multiple values of currents.

Here are the equations that allow us to know how to generate a current :

  • VSET= Rpot /(Rpot + 100K)
  • Iout=Iin= VSET/Rinpt

According to these equation these are the values of current we can generate : from 100nA to 500nA and from 500uA to 2.5mA.

[AmpeROSE] A Tale of Two Calibration Methods

Hello everyone

In the past two weeks, I was involved mainly in simulating the measurement circuit using LTSpice. In previous posts, problems related with switching and amplifying were discussed. In this post, I am going to share the results of the simulation of the calibration method we are going to use.

Brief Recap

In a previous post we discussed the 3 options we had regarding the calibration. Back then, we were considering 4 measurement intervals. Due to the problem with the parasitic capacitance of switches, we decided to use 3 measurement intervals. This will simplify the calibration circuitry because we have to drive only 2 switches.

The basic idea of the calibration logic is the following:

  • If the measured voltage is too small (smaller than a reference OFF voltage) we have to use a shunt resistor with a bigger value and thus turn off the corresponding switch.
  • If the measured voltage is too high (Higher than a reference ON voltage) we have to use a shunt resistor with a smaller value (to avoid high burden voltages) and thus turn on the corresponding switch.

To implement the following logic, 2 methods were considered, simulated and will be discussed in the following

RS Latches

The first circuit we used was based on RS Latches. SW1 is the switch connected to the smallest resistor while SW2 is connected to the resistor of the medium interval.

Then we applied a sine wave at the input of the comparators. Note that in this simulation our goal was to test the logic and thus driving switches will have no impact on the input wave. This was done later when we put the circuit together.

The results of the SPICE simulation are the following

The logic works exactly as needed : When the signal is below OFF reference voltage both switches must be turned off (Note that we are using PMOS transistors). When the signal is above ON reference voltage both switches must be turned on.

However this circuit has a major disadvantage. Since we are using latches, once a switch is turned on/off, the circuit has no time to stabilize the measurements (Switching time – Amplifying …). This will cause the second switch to turn on/off immediately. This is problematic especially for values in the second interval: We will never have stable measurements because we are switching on and off all the time.

Shift Registers

Our second option was using the 74HC194 shift register. We can use this register to implement our calibration state machine. The main advantage of this switch is that time can be controlled using the clock.

We simulated the following circuit

The results – presented in the following picture – are exactly as expected

We were considering using the 74HC194 circuit in our final design because we can easily control the time between switching.

However the major drawback of this circuit is that it does not follow the comparators output instantly. In the worst case scenario, we had a voltage higher than the ON reference voltage right after the clock edge. The burden voltage will increase significantly before we can change the measurement interval.

Going back to RS Latches

We actually have to be able to follow any exceeding fast enough and thus RS latch must be used. However we have to insert a delay in order to give the circuit the time needed to react to these changes.

A simple way to do that is to use RC delay followed by a buffer. The use of a simple buffer will give however a higher delay when SW1 passes from High to Low than when it passes from Low to High. We can then use a comparator with VDD/2. Another method is to use a single component proposed by linear tech LTC6994-2. Note that if we used a simple 74 buffer it would be better to use a RC delay however with the introduction of a comparator, RC has no advantages over the use of a simple single component. That’s why we are going with LTC6994-2.

Alert

Another issue we faced was the very fast transition between the lowest possible value (10n) and the highest possible value (300mA) of current. This will introduce a huge burden voltage for a very small amount of time (before the calibration circuit reacts). A decoupling capacitor must be used by the DUT to ensure that we do not have a big voltage drop. This capacitor must be small to not alter our measurements and thus we must guarantee that the drop lasts the minimum possible time.

To do that, we will add a logic that switch directly from the lowest interval to the highest one – without using the intermediate one – in case of a sudden exceeding of the maximal allowed drop voltage. This can be done by comparing the voltage seen by the DUT and the “DUT supply voltage – maximum burden voltage 100mV”.  The output of the comparator will reset both switches instantly. This will not eliminate the voltage drop instantly (as we hoped …) but it would certainly help reducing the time of that drop.

The final calibration circuit we are going to use will look something like

The final results combine the advantages of both circuits: Immediate response with a controlled delay as shown in the following figure

Next Week

In this week we also put last touches to the entire design (for example, we gave the microprocessor direct access to the calibration switches that may be used in the initial calibration or in emergency cases).

FINALLY I am done with LTSpice. Next week my main tasks are related to the PC software that will receive data from our device. I will implement the communication interface and the graph display.

Until next week 🙂

[AmpeRose] GUI Skeleton

Hello AmpeRose fans,

This post is a bit overdue… Well a lot overdue, I was supposed to write it last week :p

So, that week, in addition to working on the calibration schema, I created the class diagram for our graphic interface, which I ordered into three well wrapped levels:

  • Back-end
  • Data View
  • Graphic interface

BackEnd

The Back-end handles communications with AmpeRose, which includes

  • Reading Data sent by AmpeRose
  • Decoding data using a specific configuration (Translation)
  • Sending commands to AmpeRose
  • Performing special operations with the data (save to file, backup, send to database…)

N.B: Just yesterday, we decided that we might add another class that would handle error correction, using correction info sent forth by AmpeRose. (Benefits of being late :p)

 

DataView

The Data View does not handle the data per Se, but it handles how this data will be viewed.

For instance, it is here that we can choose to view the data as a simple continuous stream, or as lapses that obey to a certain trigger. It is also here that we can calculate the FFT of our data points, to allow the user to see the frequency spectrum of his device. The data container of the Data View will act as a moving window for the measurements, i.e. it will contain a fixed number of points (10^7 to 10^8), and as new data pours in, values will be replaced.

 

The graphic interface

This part of the pc software is what the user will see and use directly. It will view the data in a useful manner, and will allow for control over AmpeRose, as well as the other components of the software.

 

That’s all for tonight folks,

But stay tuned for the way more interesting post about the updates on our calibration circuit this week!

P.S: Some titles are links to images of the class diagrams.

[AmpeRose] Believe it or not, STM32CubeMX wasn’t able to find a solution at full speed clock, but guess what, I did it…

Good evening everyone,

This week, I worked on schematics, simulation and power supply.

I started by reviewing the configuration of the STM32F767 microprocessor that is going to be used in our project. I used the STM32CubeMX software to review the pin assignments, check for potential conflicts.

In addition, one of the important aspect of this software is the clock configuration. Manually configuring it wouldn’t be an easy task though.

However, it’s not always possible to find an automatic solution using this software because there are a lot of constraints to take into consideration, lucky me, that was the case.

Eventually, I managed to manually configure the clock at full speed (spoiler 216MHz 🙂 ) and respect all different constraints. Yes I did it and I hate STM32CubeMX for that :).

In terms of schematics, I also reviewed them:  finalized the configuration of the microprocessor, removed some the unused pull down resistors in the ethernet schema in order to use less components and simplify the routing.

To have an idea of our full consumption, thus designing the right decoupling capacitors, I compiled a list that specifies the consumption of each component. The list is not fully complete yet because there has been some changes in some components, so I will finalize it when we choose the appropriate components that suit our needs.

Also, during this week, I joined the team and did some simulations in order to try to minimize the full drop voltage that occurs during the 100ns that corresponds more or less to the op amp response time. After all, the solution was to design an suitable decoupling capacitor that will maintain the voltage across the DUT.

Stay stuned,

See you next week.

[ZeROSEro7] Schematics

This week I worked on schematics.

I improved USB Sniffer schematics because there were several mistakes. nRF52832 chip and its antenna route constraints were not respected, wire width were improved (bigger for VCC and with a 50 ohm impedance for antenna), several ground pad were no linked.

Moreover, I routed Stealth Drop board using what I learned from USB Sniffer routing.

I still have to make a basic Android app to send and receive WiFi data.

See you next week

[ZeROSEro7] First LoRa transmission

Last week I worked further on controlling the SX1276 from the nRF52. Once I could use the high level functions from Semtech, I tested it and checked if the registers were set as expected. To complete the implementation, I had to write the code to control the antenna switch, which is trvial on our schematic. I also had to link the handlers for the optional IRQ DIOs. Unfortunately, the SDK doesn’t support them being disconnected so I had to rewrite a small part of the SDK with a similar behavior but without the IRQs. It is possible to switch back to the previous code by defining a symbol for the preprocessor. This will reduce CPU execution time but is completly optionnal otherwise.

I had very few debuging options to finally transmit over LoRa. I knew my timing and SPI transfers were right, but the transmission wasn’t working. After further analysis of the SX12 datasheet and checking the state registers, I was able to make a first transmission !

Among other things, there was a very misleading naming for modes :

There was the continuous mode vs packet mode, which states wether the rx data goes in the fifo or to the DIO. I chose packet.

And the continuous mode as opposed to single-shot mode. In single-shot, the antenna only goes to rx mode for a few symbols of time so I couldn’t receive anything. So I had to choose this continuous mode.

Before I resolved this ambiguity, I ran into troubles because the receiver didn’t have the expected behavior and spent all his time in standby mode.

Aside from this, I helped reviewing the schematics and PCBs that Erwan and Vincent made.

 

For this week, I’ll try to finish the parrots on both LoRa and BLE to close those PSSCs in time. I’ll use the remaining time (if any) to help Erwan with the USB. Indeed, driving 2 USB bus in parallel will probably be a tough challenge and will require to dive into the drivers if we want to respect the timing constraints. I also hope that we will finish all our PCBs before next week.

[ZeROSEro7] Understand USB Keyboard

This week, I worked on Schematics, PCB and USB Keyboard.

Schematics

We finished first schematic version of each device. I updated some details on schematics before to begin all PCB.
I also added a spreadsheet of the STM32Fxx pin functions. Finally, I added a file in the wiki about the power supply of each component.

USB Keyboard

I started to work on the USB Keyboard Issue. The goal is to plug a PC to an STM32 (Olimex OTG1 port) and to plug the same STM32 (Olimex OTG2 port) to a USB Keyboard. The PC has to detect a keyboard without to see the STM32 between both. The STM32 has to get all USB Keyboard interaction as descriptors and interrupt to send it to the PC.

The first step would be to get USB Keyboard descriptors and show it on the RTT connection. However, I’m still working on this step.

I started to check the Olimex board connection to know jumper position and I updated the file board.h correctly.

USB protocol

I read documentations about the USB standard from the official website, some blogs as site OUAIBE de la BIDOUILLE and some forums. I got knowledge about how USB works. There are four types of communication : control, bulk, interrupt and isochronous. Note that Keyboard works with interrupt.

Each communication is constructed with different packet:

  • Token
Sync PID ADDR ENDP CRC5 EOP
8bits 2x4bits 7bits 4bits 5bits 3bits
  • Data
Sync PID DATA CRC16 EOP
8bits 2x4bits 1024bits 16bits 3bits
  • Handshake
Sync PID EOP
8bits 2x4bits 3bits
  • SOF (Start of Fram)
Sync PID FramNumber CRC5 EOP
8bits 2x4bits 5bits 3bits

Finally, there are four descriptors : devices, configuration, interface and endpoint descriptors. Each descriptors has field contain information about the device. The PID, VID, consumption, type of communication, etc.

USB on ChibiOS

My difficulties are to implement that on the STM32 and more specially with the OS we choose: ChibiOS.

I got back usbcfg from ChibiOS/testhal/STM32/STM32F4xx/USB_CDC_IAD/
This example uses two SerialUSBDriver SDU1 and SDU2 but not as a host.

I found another example at ChibiOS/community/testhal/STM32/STM32F4xx/USB_HOST/ which logically implement what we need. Nevertheless, the code is very hard to understand and is not possible to compile it. I try to debug the Makefile, but there are too many errors. I will continue to read ChibiOS documentation, code and forum to find a solution.

Next week

Next week, I will finished the spy talk PCB and continue to work on the USB Keyboard Issue.