[SpiROSE] FPGA synchronization architecture

Synchronization signals

The engine may not have cycle accurate speed, the rgb logic will not send data at exactly 33MHz… there are various synchronization issue to tackle. Thus we need some sync signals.
In order to have the simplest and less error prone code, the modules will all rely on a few sync signals, each one output by the relevant module so that the other ones don’t need to worry about his inner working. The framebuffer buffer for instance shouldn’t have to know how the driver controller works, it just needs to know when to send data to it.

The synchronisation signals are the following:

Signal name Output by Used by Role
hall_sensor_trigger hall effect sensor Indicates that we have made half a turn
position_sync hall effect sensor framebuffer, driver controller Indicates that the position has changed
rgb_enable SPI rgb logic Command sent by the SBC to start everything
stream_ready rgb logic framebuffer, driver controller Indicates that enough slices are stored in ram to begin sending data to the driver
driver_ready driver controller framebuffer Indicates that the drivers are ready to receive data (they are configured and we are not in a blanking cycle)
column_ready driver controller multiplexer Indicates that the drivers have latch the data for a column

Modules’ states

The modules will follow those steps:

  1. At reset, the driver controller send the default configuration to the drivers. driver_ready and column_ready will be low so the framebuffer is waiting and the multiplexer doesn’t turn on anything. The rgb_logic waits for rgb_enable to start writing in the ram.
  2. The SPI module receives an rgb_enable command, so it drives the signal high. rgb_logic starts to read the incoming rgb stream, and monitor vsync to ctach the beggining of an image. Then it starts writing in the ram. When enough slices have been written it drives stream_ready high.
  3. The framebuffer and driver controller modules will do nothing before the stream_ready signal. When they receive the stream_ready signal they start a two state behaviour: send data, wait for next slice. In send data state framebuffer listen to the driver_ready signal to send data to the driver controller, driver controller send data to the drivers with the protocol describe in previous posts. When a column has been sent the driver controller drives column ready high for one cycle.
  4. When the multiplexer module receives column_ready it turns on one column only for less than 10µs (so we don’t burn the led when overdriving), then turn it off and wait for the next column_ready assert.
  5. When the whole slice has been displayed (i.e. 8 columns), the frembuffer and driver controller enter wait for next slice state, where they wait for position_sync signal.
  6. The position_sync signal triggers the change from the wait for next slice state to the send data state (go back to step 4)

This is sum up in the following figure:


There is an issue if position_sync changes when we are in the send data state. This can occurs when:

  • There are too many slices, so the time required to send the data exceeds the lenght of a slice
  • The motor was too fast, so the hall_sensor_trigger happens too soon

The first issue can be fixed by using fewer slices, but this means a lower resolution.
The second one is unlikely to happen, as the engine speed is steady.

In case one or the other happens, we handle it this way:

  • Continue to send data for the current column
  • Then reset the relevant counters/signals and start sending the next slice normally

Thus we just finish to send our column before moving to the slice n+1, so in the worst case we lose 7 columns out of 8 in slice n. The slice n+1 is displayed normally but slighlty delayed, worst case by 512 cycles. So if wait for next slice state last for more than 512 cycles the delay is gone when we reach slice n+2, otherwise we end up being in the same situation as before.

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>