evt2.c
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | |||
| 2 | #include "evutils/evt2.h" | ||
| 3 | |||
| 4 | typedef struct evt2_state_s { | ||
| 5 | uint64_t last_ts_high; /* current TIME_HIGH << 6 (bits 6..33) */ | ||
| 6 | uint64_t ts_high_high; /* accumulated overflow of the 28-bit field (34+) */ | ||
| 7 | } evt2_state_t; | ||
| 8 | |||
| 9 | /* The EVT2 TIME_HIGH field is 28 bits and carries time base bits 6..33, so it | ||
| 10 | * wraps at 2^34. Bump the overflow accumulator by 2^34 each time it wraps. */ | ||
| 11 | #define EVT2_TS_WRAP (1ULL << 34) | ||
| 12 | |||
| 13 | |||
| 14 | 120 | size_t EVT2_state_size(void) { | |
| 15 | 120 | return sizeof(evt2_state_t); | |
| 16 | } | ||
| 17 | |||
| 18 | |||
| 19 | enum EVT2_PacketType { | ||
| 20 | EVT2_CD_OFF = 0x0, | ||
| 21 | EVT2_CD_ON = 0x1, | ||
| 22 | EVT2_EVT_TIME_HIGH = 0x8, | ||
| 23 | EVT2_EXT_TRIGGER = 0xA, | ||
| 24 | EVT2_OTHERS = 0xE, | ||
| 25 | EVT2_CONTINUED = 0xF | ||
| 26 | }; | ||
| 27 | |||
| 28 | |||
| 29 | EVUTILS_TARGET_CLONES | ||
| 30 | 363 | parser_result_t EVT2_parse_chunk_soa( | |
| 31 | evt2_state_t *state, | ||
| 32 | const evt2_input_buffer_t *input_buffer, | ||
| 33 | event_buffer_soa_t *event_buffer, | ||
| 34 | trigger_buffer_soa_t *trigger_buffer) { | ||
| 35 | |||
| 36 | |||
| 37 | 363 | const uint32_t *restrict current = input_buffer->begin; | |
| 38 | 363 | const uint32_t *restrict end = input_buffer->end; | |
| 39 | |||
| 40 | // Event output buffers | ||
| 41 | 363 | size_t n_events_read = event_buffer->size; | |
| 42 | 363 | const size_t events_capacity = event_buffer->capacity; | |
| 43 | |||
| 44 | 363 | timestamp_t* restrict out_ts = event_buffer->t; | |
| 45 | 363 | uint16_t* restrict out_x = event_buffer->x; | |
| 46 | 363 | uint16_t* restrict out_y = event_buffer->y; | |
| 47 | 363 | uint8_t* restrict out_p = event_buffer->p; | |
| 48 | |||
| 49 | // Trigger output buffers | ||
| 50 | 363 | timestamp_t* restrict trigger_ts = trigger_buffer->t; | |
| 51 | 363 | uint8_t* restrict trigger_id = trigger_buffer->id; | |
| 52 | 363 | uint8_t* restrict trigger_p = trigger_buffer->p; | |
| 53 | |||
| 54 | 363 | size_t n_triggers_read = trigger_buffer->size; | |
| 55 | 363 | const size_t triggers_capacity = trigger_buffer->capacity; | |
| 56 | |||
| 57 | // State variables | ||
| 58 | 363 | uint64_t last_ts_high = state->last_ts_high; | |
| 59 | 363 | uint64_t ts_high_high = state->ts_high_high; | |
| 60 | |||
| 61 | 363 | parse_status_t status = EVUTILS_PARSE_OK; | |
| 62 | |||
| 63 | 363 | while( | |
| 64 | 335137256 | current < end && | |
| 65 | 670274271 | n_events_read < events_capacity && | |
| 66 | n_triggers_read < triggers_capacity | ||
| 67 | ) { | ||
| 68 | |||
| 69 | 335136954 | uint32_t packet_type = (*current & 0xF0000000) >> 28; | |
| 70 | 335136954 | uint32_t packet_data = *current & 0x0FFFFFFF; | |
| 71 | 335136954 | uint8_t value = 0, channel = 0; | |
| 72 | |||
| 73 | // printf("%01lx %08lx\n", packet_type, packet_data); | ||
| 74 | 335136954 | switch(packet_type){ | |
| 75 | 327671193 | case EVT2_CD_OFF: | |
| 76 | case EVT2_CD_ON: | ||
| 77 | // Bits 27..22 are the least significant bits of the timestamp | ||
| 78 | 327671193 | out_ts[n_events_read] = ts_high_high | last_ts_high | ((packet_data >> 22) & 0x3F); | |
| 79 | |||
| 80 | // Bits 21..11 are the x coordinate | ||
| 81 | 327671193 | out_x[n_events_read] = (packet_data >> 11) & 0x7FF; | |
| 82 | // Bits 10..0 are the y coordinate | ||
| 83 | 327671193 | out_y[n_events_read] = packet_data & 0x7FF; | |
| 84 | |||
| 85 | 327671193 | out_p[n_events_read] = !!packet_type; | |
| 86 | 327671193 | n_events_read++; | |
| 87 | 327671193 | break; | |
| 88 | 6593590 | case EVT2_EVT_TIME_HIGH: | |
| 89 | { | ||
| 90 | // Bits 27..0 are the most significant bits of the event time | ||
| 91 | // base (33..6). Track wraps of the 28-bit field. | ||
| 92 | 6593590 | uint64_t new_ts_high = (uint64_t)packet_data << 6; | |
| 93 | 6593590 | if (new_ts_high < last_ts_high) { | |
| 94 | 2 | ts_high_high += EVT2_TS_WRAP; | |
| 95 | } | ||
| 96 | 6593590 | last_ts_high = new_ts_high; | |
| 97 | } | ||
| 98 | 6593590 | break; | |
| 99 | 9 | case EVT2_EXT_TRIGGER: | |
| 100 | // Bits 11..8 carry the trigger channel id, bit 0 the edge value. | ||
| 101 | 9 | channel = (packet_data >> 8) & 0x0F; | |
| 102 | 9 | value = packet_data & 0x01; | |
| 103 | |||
| 104 | 9 | trigger_ts[n_triggers_read] = ts_high_high | last_ts_high | ((packet_data >> 22) & 0x3F); | |
| 105 | 9 | trigger_id[n_triggers_read] = channel; | |
| 106 | 9 | trigger_p[n_triggers_read] = value; | |
| 107 | 9 | n_triggers_read++; | |
| 108 | 9 | break; | |
| 109 | 872162 | case EVT2_OTHERS: | |
| 110 | case EVT2_CONTINUED: | ||
| 111 | default: | ||
| 112 | 872162 | break; | |
| 113 | } | ||
| 114 | 335136954 | current++; | |
| 115 | } | ||
| 116 | 363 | event_buffer->size = n_events_read; | |
| 117 | 363 | trigger_buffer->size = n_triggers_read; | |
| 118 | 363 | state->last_ts_high = last_ts_high; | |
| 119 | 363 | state->ts_high_high = ts_high_high; | |
| 120 | |||
| 121 | 363 | return (parser_result_t){ | |
| 122 | .current = (const void *)current, | ||
| 123 | .status = status | ||
| 124 | }; | ||
| 125 | } | ||
| 126 | |||
| 127 | |||
| 128 |