— DAQ user 2018/06/18 07:26
Clear separation of acquisition and data transfer: The firmware is not controlling the acquisition time, it just throws a BUSY when one TDC fifo is ALmost Full (25 over 32). The BUSYs are collected by the MDCC board that terminates the acquisition window when one busy is seen and do not restart a window until all BUSYs are low.
Data transmit per channel: Once the acquisition window is end, a BUSY is set per FEB until the data transfer is completed. It consists first to an Event packet containing the GTC (window count) and the Absolute BCID (readout time 200 ns steps). Then TDCs are scanned one by one , if not empty a channel packet is sent. Once all TDCs are browsed, BUSY is released and the FEB is in IDLE for the next window.
Trigger Mode: If the trigger mode is set, at data transfer stage, the trigger TDC (0) is first check, if the FIFO is empty, all FIFOs are cleared, BUSY is released and the FEB go back in IDLE state. It minimizes the dead time and only events with external trigger are transmitted.
Each new window is tagged with an event packet
|CAFEDADE (4 bytes)||GTC (3 bytes)||0||ABCID (5 bytes)||DADECAFE (4 bytes)|
Each channel is read separately if there is data. Since the counters are reset for each new window, the BCID can be calculated from the TDC time and 2 bytes are saved per channel. The channel number is kept to align data in words.
|Header (2 bytes words)|
|and then per line|
|channel (1 byte)||Coarse (4 bytes)||fine (1 byte)|
|Trailer (2 bytes word)|
Remaining bugs : From time to time (<1/min),an empty event header is sent with same GTC number , good ABCID and no channels, the event synchr is recovered on next event header. Since the DAQ is synchronised on GTC, no inefficiencies is seen. It might come from MDCC firmware
The data forwarded to the Event builder are grouped per event. It has similar structure to the previous one.
// 28 bytes header itemp=_event; // Readout event itemp=_gtc; // Window number used to synchronize packets ltemp=_abcid; // 8 bytes itemp=_event; // unused indeed itemp=_adr; // IPV4 address itemp=_channels.size(); // Number of lines // and then list of channels in 6 bytes structure
|channel||coarse (4 bytes 2.5 ns)||fine (2.5 ns/256)|
|e||8 7c 22 6||38|
|10||8 7c 23 95||9d|
|2||8 7c 21 ff||f4|