felix-trickle

felix-trickle is a felix-star application that sends configuration data towards Front-End electronics. Like felix-toflx, the application receives messages from the network, encodes them into FromHost messages and transfers them to the corresponding Trickle DMA buffer.

Note

The trickle DMA buffer has one major difference from felix-toflx: it is a ring buffer, that the firmware will continuously read once the trickle configuration is written in it.

Trickle

The top-level class is Trickle, used to build two executables: felix-trickle that works with a FELIX card and felix-trickle2file that emulates the hardware. Trickle is templated to support both use cases. The template parameters are three: the configuration parameters, the type of FromHost DMA buffer (that interfaces with the FELIX driver or not) and the type of FELIX device (real or emulated). Trickle owns (by composition) devices, DMA buffers and writers. It is responsible for creating a TrickleManager instance for each FELIX device, and a Receiver for each buffer.

Note

The Receiver can only be unbuffered, and uses only the TCP network mode.

template<class Config, class Device, class Buffer>
class Trickle

Class used to forward trickle configuration to FE devices.

This template approach allows the same core logic to work with both real hardware and file-based emulation.

Template Parameters:
  • Config -- Configuration class that provides device IDs, DMA buffer sizes, and network settings (e.g. ConfigTrickle)

  • Device -- Represents a FELIX device (e.g. FlxDevice, FileDevice) that handles hardware communication

  • Buffer -- FromHost DMA buffer implementation (e.g. FlxFromHostBuffer, FileFromHostBuffer) for memory management

Public Functions

void start()

allocate all resources and start thread(s).

void stop()

stop transfers, join all created threads.

TrickleManager

TrickleManager is the class that implements the API that allows to receive a trickle configuration and write it into the DMA buffer. The most important thing to know is that the commands received from the client are all in JSON format.

template<class Buffer>
class TrickleManager

TrickleManager owns a network Receiver that runs the (event loop) thread. Messages are received from the network, encoded, and written into the FromHost buffer. The FromHost can be shared by more than one TrickleManager.

Template Parameters:

Buffer -- FlxFromHostBuffer or FileFromHostBuffer

Public Functions

TrickleManager(std::shared_ptr<Buffer> buffer, std::unique_ptr<Receiver> receiver)

TrickleManager contructor.

Parameters:
  • buffer -- shared pointer to Fromhost DMA buffer.

  • receiver -- pointer to network receiver.

FromHost Buffer

The buffer handling is managed by FromHost Buffer, which can be referenced in felix-toflx. The class has been enhanced with some methods for trickle configuration.

void FromHostBuffer::trickle_padding()

Adds padding to the trickle configuration.

The trickle configration total memory occupancy inside the DMA buffer must be a multiple of 4096 bytes. This function adds some padding to make it a multiple of 4096 bytes if necessary. The padding must also be correctly encoded in the Fromhost data format, but to ensure that the padding is discarded by the firmware I used e-link 0x30 which contains a valid link-ID but an invalid e-path (FLX-2562).

virtual void FlxFromHostBuffer::dma_start_circular_trickle_buffer() override

Starts a circular trickle DMA buffer.

The firmware will continuously read the configuration data up to the current write offset. The firmware will not check the write offset pointer as for the normal FromHost buffer, but it is used to tell the firmware the size of the trickle configuration when enabling the buffer

virtual void FlxFromHostBuffer::set_oneshot_trickle_buffer() override

Sets a trickle DMA buffer to one-shot.

The firmware reads the configuration data from the buffer once. This function will block until the firmware has finished reading the data, or until a timeout is reached. After the transfer, the write offset is reset to 0 and the buffer disbled.

virtual void FileFromHostBuffer::dma_start_circular_trickle_buffer() override

This function does not wraparound, it reads the trickle DMA buffer just one time.

Be careful since the behaviour might be unexpected. I start a circular buffer and in the function copy_trickle_buffer_to_file I only read it once. This is because the generated file is very large, and having it N times bigger would be problematic

Change this comment if this is no longer true

inline virtual void FileFromHostBuffer::set_oneshot_trickle_buffer() override

Mock funcion that emulates the behaviour of the real hardware.