SCAMP-5c Vision System  1.0.0
An image sensor with a parallel processor on focal plane
Files
SPI Macros

these macros provide the SPI communication functionalities More...

Files

file  spi_macros.h
 

Detailed Description

these macros provide the SPI communication functionalities

Basic Concept

SCAMP-5c has a SPI interface working at 2.5 Mhz, which is a method of low-bandwith low-latency communication.

The SCAMP system work as a SPI slave with a FIFO buffer of 1024 bytes. Despite being a SPI slave, the SCAMP system controls the whole SPI interface because it is in charge of sending a hardware signal to the its master (the Odroid XU4) to start a SPI transfer. In each of the transfer, a constant number of bytes ('transfer size') is sent and received. If the FIFO has not enough bytes, zeros will be padded.

When data need to be sent from the SCAMP system to the Odroid XU4 (the 'upwards' communication), they need to be fit in to a packet. A packet is composed of two sections: the packet header and the packet payload. The packet header is a 8-byte data structure that contains the size of the payload. The payload is simply the actual data that need to be sent. On the Odroid XU4, a SPI hosting program is running to parse the incoming byte stream on SPI transfers into packets. A packet is enclosed and queued in memory when the enough bytes is receveived after the header. For details about the SPI Host, see http://jianingchen.github.io/scamp5c/arm_linux/.

When a transfer occurs, both upwards and downwards communciation (Odroid XU4 to SCAMP system) happens simultanously. The spi interface on the SCAMP system will store the first eight bytes of in the downwards byte stream into eight SPI input ports that can be read by the IPU.

SPI Upwards Communication

Send Standard Packet

A standard packet is a SPI packet with some format designated to send basic debug information to the host, such as frame readout or events.

The SPI Host can recognize standard packet and treat them differently, including a extra layer of translation. The SPI Host App is able to graphically display the data in standard packets.

For example, a simple camera using SPI:

#start
rpix(B,C)
ipu.inc_loop_counter
spi.wait_fifo_space(SPI_FIFO_SPACE_768)
spi.begin
spi.aout64(C)
spi.end
_jump(#start)

Send Packet with Arbitrary Data

If some data packet with highly customized data format is needed, one can compose a generic data packet by sending a header first (use spi_send_header) followed by the payload bytes.

The following code segment uses a generic data packet to send back 6 bytes of user data back to the host:

...
spi.begin
// header (payload size = 6)
spi.send_header(6)
// payload
spi.send_byte(0xAA)
spi.send_byte(0xBB)
spi.send_byte(100)
spi.send_byte(200)
spi.send_byte(s0)
spi.send_byte(s1)
spi.end
...

See also Example 13: SPI Communication for a complete example.

SPI Downwards Communication

When a transfer occurs, the first 8 bytes received at MOSI are stored in the SPI input ports. These value can be read using spi_port with a given input port number (SPI_RX_0 ~ SPI_RX_7).

Note: since SPI transfers are triggered by upwards communcation, there must be upwards communications inside the frame loop to enable downwards communication. It nothing in particular is needed to be sent from SCAMP-5 to the host, one can simply send the loop counter (use spi_send_loop_counter) just to ensure downwards communication is processed.

Extra care must also be taken if the program need to be initlized with data read from SPI input port. It is recommand that put a time delay after the first upwards communication before any downwards communication. For example:

...
ipu.reset_loop_counter
spi.reset
spi.set_transfer_size(600)// an upwards communication, triggering a transfer
ipu.delay_50us_x(250)// this time delay ensures that the last transfer is finished
#start
s0 = spi.port(SPI_RX_0)
...

Configure SPI Host App GUI

To create sliders in SPI Host App, one can add two more arguments in host_add_slider. The first added argument choose a name for the slider from a list of available options, the second argument control whether the value is latched.

When a slider is enabled for the host app, its value will be sent to the spi input port in order. Thus, first slider in the app is sent to SPI_RX_0 while the second one is SPI_RX_1.

Optimizing Transfer Size

By using spi_set_transfer_size, transfer size of the spi interface can be modified from the SCAMP-5 side. This can be used to optimize the spi communication for the running algorithm in particular.

To increase the bandwith for large packet, such as event scanning or frame readout, it is better to change the transfer size to be a little bigger than the packet size. By doing that, the number of gaps between multiple transfers can be reduced. For example, if the algorithm only transfer 300 events in each frame loop, it will be optimal that the transfer size is (300*2 + 16). For packet that are bigger than the maximum transfer size of 4096 bytes, one can use a value of which the integer times is just bigger than the packet size. For example, one can use 2800 as transfer size for spi_dout.

Since a packet will only be issued after a transfer is finished, it also helps to reduce the latency if the transfer size is not much bigger than the packet size. For example, if the algorithm only transfer a packet of size 16 bytes in each frame iteration, changing transfer size to be 16 or 20 can give a minimized latency.

For example:

ipu.reset_loop_counter
spi.reset
spi.set_transfer_size(640)// one transfer can send 640 bytes
ipu.delay_50us_x(250)
#start
ipu.wait_frame_trigger
rpix(B,C)
...
// check if fifo space is more than 640 bytes (the packet size is 616)
spi.get_fifo_space(s0)
_sub(s0,SPI_FIFO_SPACE_640)
_jump(c,#start)
// scan and send upto 300 events in R5
spi.begin
spi.scan_events(R5,300)// packet size: 616
spi.end
_jump(#start)