|
1 | 1 | # MVLC data format
|
2 | 2 |
|
| 3 | +All data is 32-bit oriented and written in little-endian. |
| 4 | + |
3 | 5 | ## Frame types
|
4 | 6 |
|
5 |
| -| Name | Value | Binary Value | |
6 |
| -| ----------------- | ----- | ------------ | |
7 |
| -| StackFrame | 0xF3 | 0b1111'0011 | |
8 |
| -| StackContinuation | 0xF9 | 0b1111'1001 | |
9 |
| -| BlockRead | 0xF5 | 0b1111'0101 | |
10 |
| -| StackError | 0xF7 | 0b1111'0111 | |
11 |
| -| SystemEvent | 0xFA | 0b1111'1010 | |
| 7 | +| Name | Value | Binary Value | |
| 8 | +| --------------------- | ----- | ------------ | |
| 9 | +| StackFrame | 0xF3 | 0b1111'0011 | |
| 10 | +| StackContinuation | 0xF9 | 0b1111'1001 | |
| 11 | +| BlockRead | 0xF5 | 0b1111'0101 | |
| 12 | +| StackError | 0xF7 | 0b1111'0111 | |
| 13 | +| SystemEvent | 0xFA | 0b1111'1010 | |
| 14 | +| SystemEvent2 (future) | 0xFB | 0b1111'1011 | |
| 15 | + |
| 16 | + |
| 17 | +* Frame header format (except for SystemEvent) |
| 18 | + |
| 19 | + `Type[7:0] Continue[0:0] ErrorFlags[2:0] StackNum[3:0] CtrlId[2:0] Length[12:0]` |
| 20 | + |
| 21 | + - `Type`: is one of the non-SystemEvent frame types. |
| 22 | + - `Continue`: If set the payload is continued in the following frame. |
| 23 | + - `ErrorFlags`: 3 bits: `2=SyntaxError`, `1=VME BusError`, `0=VME Timeout` |
| 24 | + - `StackNum`: 0 based index of the MVLC command stack that produced the frame. |
| 25 | + - `CtrlId`: The MVLC controller/crate ID set via the `0x1304 controller_id ` register. |
| 26 | + - `Length`: The number of 32-bit words following this header word. |
| 27 | + |
| 28 | +* SystemEvent format: |
| 29 | + |
| 30 | + `Type[7:0] Continue[0:0] CtrlId[2:0] Subtype[6:0] Length[12:0]` |
| 31 | + |
| 32 | + - Common fields are the same as for non-SystemEvent frames. |
| 33 | + - `Subtype`: specifies the type of data this SystemEvent frame is carrying. |
| 34 | + See the [table below](#system-event-subtypes) for details. |
| 35 | + |
| 36 | + SystemEvent frames are not generated by the MVLC. mvme and the mvlc-mini-daq |
| 37 | + inject these frames into the data stream. |
| 38 | + |
| 39 | +## Output Format |
| 40 | + |
| 41 | +Outgoing data is wrapped in a `0xF3 StackFrame` with the `StackNum` field set to |
| 42 | +the number of the command stack that produced the data. If the `Continue` flag |
| 43 | +is set the `0xF3 StackFrame` will be followed by one or more `0xF9 |
| 44 | +StackContinuation` frames. The `Continue` bit will be set for all but the last |
| 45 | +part in the chain. |
| 46 | + |
| 47 | +### Outer framing example: |
| 48 | +``` |
| 49 | +TODO: copy me from real data please! |
| 50 | +0xF3 |
| 51 | +0xF9 |
| 52 | +0XF9 |
| 53 | +``` |
12 | 54 |
|
13 |
| -## UDP format |
| 55 | +The format is 32-bit oriented. 16-bit VME reads are returned as masked-off |
| 56 | +32-bit values. Single value VME reads are directly written into the frame |
| 57 | +contents, VME block reads are wrapped in inner `0xF5 BlockRead` frames. These |
| 58 | +inner frames also make use of the `Continue` bit but do not have an extra |
| 59 | +continuation frame type. |
14 | 60 |
|
15 |
| -Two headers, afterwards payload containing the above framing format starts. Size is always a multiple of 32-bits. |
16 |
| -Max payload size of packets sent to the MVLC is |
17 | 61 |
|
18 |
| -**Header0**: `{ 0b00, chan[1:0], packet_number[11:0], ctrl_id[2:0], data_word_count[12:0] }` |
| 62 | +## UDP packet format |
| 63 | + |
| 64 | +Two 32-bit headers, afterwards payload containing the above framing format |
| 65 | +starts. The total packet size is always a multiple of 32-bits. |
| 66 | + |
| 67 | +**Header0**: `{ 0b00, packet_channel[1:0], packet_number[11:0], ctrl_id[2:0], data_word_count[12:0] }` |
19 | 68 |
|
20 | 69 | **Header1**: `{ udp_timestamp[18:0], next_header_pointer[12:0] }`
|
21 | 70 |
|
| 71 | +* `packet_channel`: |
| 72 | + - `0 = Command`: Low level command responses. |
| 73 | + - `1 = Stack`: Data from immediate stack executions and `0xF7` error notifications. |
| 74 | + - `2 = Data`: Readout data produced by command stacks routed to the data pipe. |
| 75 | + |
| 76 | + Each `packet_channel` carries its own `packet_number` sequence. |
| 77 | + |
| 78 | +* `packet_number`: Wrapping sequence number for packet loss detection. |
| 79 | + |
| 80 | +* `ctrl_id`: The MVLC controller/crate ID set via the `0x1304 controller_id` register. |
| 81 | + |
| 82 | +* `data_word_count`: Number of 32-bit words following the `Header1` word. |
| 83 | + |
| 84 | +* `udp_timestamp`: currently not used. |
| 85 | + |
| 86 | +* `next_header_pointer`: Offset from `Header1` to the first outer frame header |
| 87 | + (`0xF3, 0xF9`) in the packet. `0` is the first word in the payload. `0xffff` |
| 88 | + indicates that no frame header is present in the packet. |
| 89 | + |
| 90 | + This field can be used to safely resume parsing on a frame header after packet |
| 91 | + loss occured. |
| 92 | + |
| 93 | +Max incoming packet size accepted by the MVLC is 1472 bytes `(ETH MTU - |
| 94 | +IPv4_Header - UDP_header == 1500 - 20 - 8)`. Outgoing packets are limited to |
| 95 | +1500 bytes or 9000 bytes if jumbo frames are used. |
| 96 | + |
| 97 | +**Header0** starts with `0b00`. This prefix does not collide with any of the |
| 98 | +[frame headers](#frame-types), so it is possible to store mixed streams (USB and ETH) in a |
| 99 | +single listmode file. |
22 | 100 |
|
23 |
| -`udp_timestamp` is not used so far. |
| 101 | +## SystemEvent subtypes |
24 | 102 |
|
25 |
| -The fact that **Header0** starts with `0b00` which does not collide with any of |
26 |
| -the other frames means that it is possible to store mixed streams (USB and ETH) |
27 |
| -in a single listmode file. If the MVLC ctrl_id (aka crate_id) is correctly set, |
28 |
| -streams from multiple crates can be stored in the same file too. So a mixed |
29 |
| -multicrate listfile is possible without running into parsing ambiguities. |
| 103 | +| Name | Value | Description | |
| 104 | +| --------------- | ----- | ------------------------------------------------------------------- | |
| 105 | +| EndianMarker | 0x01 | Payload is set to `0x12345678`. | |
| 106 | +| BeginRun | 0x02 | Inserted at the start of a DAQ run. | |
| 107 | +| EndRun | 0x03 | Inserted at the end of a DAQ run. | |
| 108 | +| MVMEConfig | 0x10 | MVME configuration serialized to JSON. | |
| 109 | +| UnitTimetick | 0x11 | Software generated low-accuracy timestamp, written once per second. | |
| 110 | +| Pause | 0x12 | Inserted when the DAQ was paused by the user. | |
| 111 | +| Resume | 0x13 | Inserted when the DAQ was resumed by the user. | |
| 112 | +| MVLCCrateConfig | 0x14 | MVLC CrateConfig in serialized to YAML. | |
| 113 | +| StackErrors | 0x15 | `stackNum [3:0], frameFlags [3:0], stackLine [7:0], count [15:0]` | |
| 114 | +| UserMin | 0x20 | First user defined type. | |
| 115 | +| UserMax | 0x2F | Last user defiend type. | |
| 116 | +| EndOfFile | 0x77 | Written when a listfile is closed. | |
0 commit comments