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 | 161 | size_t EVT2_state_size(void) { | |
| 15 | 161 | 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 | 472 | 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 | 472 | const uint32_t *restrict current = input_buffer->begin; | |
| 38 | 472 | const uint32_t *restrict end = input_buffer->end; | |
| 39 | |||
| 40 | // Event output buffers | ||
| 41 | 472 | size_t n_events_read = event_buffer->size; | |
| 42 | 472 | const size_t events_capacity = event_buffer->capacity; | |
| 43 | |||
| 44 | 472 | timestamp_t* restrict out_ts = event_buffer->t; | |
| 45 | 472 | uint16_t* restrict out_x = event_buffer->x; | |
| 46 | 472 | uint16_t* restrict out_y = event_buffer->y; | |
| 47 | 472 | uint8_t* restrict out_p = event_buffer->p; | |
| 48 | |||
| 49 | // Trigger output buffers | ||
| 50 | 472 | timestamp_t* restrict trigger_ts = trigger_buffer->t; | |
| 51 | 472 | uint8_t* restrict trigger_id = trigger_buffer->id; | |
| 52 | 472 | uint8_t* restrict trigger_p = trigger_buffer->p; | |
| 53 | |||
| 54 | 472 | size_t n_triggers_read = trigger_buffer->size; | |
| 55 | 472 | const size_t triggers_capacity = trigger_buffer->capacity; | |
| 56 | |||
| 57 | // State variables | ||
| 58 | 472 | uint64_t last_ts_high = state->last_ts_high; | |
| 59 | 472 | uint64_t ts_high_high = state->ts_high_high; | |
| 60 | |||
| 61 | 472 | parse_status_t status = EVUTILS_PARSE_OK; | |
| 62 | |||
| 63 | 472 | while( | |
| 64 | 272414199 | current < end && | |
| 65 | 544828142 | n_events_read < events_capacity && | |
| 66 | n_triggers_read < triggers_capacity | ||
| 67 | ) { | ||
| 68 | |||
| 69 | 272413835 | uint32_t packet_type = (*current & 0xF0000000) >> 28; | |
| 70 | 272413835 | uint32_t packet_data = *current & 0x0FFFFFFF; | |
| 71 | 272413835 | uint8_t value = 0, channel = 0; | |
| 72 | |||
| 73 | // printf("%01lx %08lx\n", packet_type, packet_data); | ||
| 74 | 272413835 | switch(packet_type){ | |
| 75 | 265619134 | case EVT2_CD_OFF: | |
| 76 | case EVT2_CD_ON: | ||
| 77 | // Bits 27..22 are the least significant bits of the timestamp | ||
| 78 | 265619134 | 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 | 265619134 | out_x[n_events_read] = (packet_data >> 11) & 0x7FF; | |
| 82 | // Bits 10..0 are the y coordinate | ||
| 83 | 265619134 | out_y[n_events_read] = packet_data & 0x7FF; | |
| 84 | |||
| 85 | 265619134 | out_p[n_events_read] = !!packet_type; | |
| 86 | 265619134 | n_events_read++; | |
| 87 | 265619134 | break; | |
| 88 | 6129808 | 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 | 6129808 | uint64_t new_ts_high = (uint64_t)packet_data << 6; | |
| 93 | 6129808 | if (new_ts_high < last_ts_high) { | |
| 94 | 759 | ts_high_high += EVT2_TS_WRAP; | |
| 95 | } | ||
| 96 | 6129808 | last_ts_high = new_ts_high; | |
| 97 | } | ||
| 98 | 6129808 | break; | |
| 99 | 1609 | case EVT2_EXT_TRIGGER: | |
| 100 | // Bits 11..8 carry the trigger channel id, bit 0 the edge value. | ||
| 101 | 1609 | channel = (packet_data >> 8) & 0x0F; | |
| 102 | 1609 | value = packet_data & 0x01; | |
| 103 | |||
| 104 | 1609 | trigger_ts[n_triggers_read] = ts_high_high | last_ts_high | ((packet_data >> 22) & 0x3F); | |
| 105 | 1609 | trigger_id[n_triggers_read] = channel; | |
| 106 | 1609 | trigger_p[n_triggers_read] = value; | |
| 107 | 1609 | n_triggers_read++; | |
| 108 | 1609 | break; | |
| 109 | 663284 | case EVT2_OTHERS: | |
| 110 | case EVT2_CONTINUED: | ||
| 111 | default: | ||
| 112 | 663284 | break; | |
| 113 | } | ||
| 114 | 272413835 | current++; | |
| 115 | } | ||
| 116 | 472 | event_buffer->size = n_events_read; | |
| 117 | 472 | trigger_buffer->size = n_triggers_read; | |
| 118 | 472 | state->last_ts_high = last_ts_high; | |
| 119 | 472 | state->ts_high_high = ts_high_high; | |
| 120 | |||
| 121 | /* Report why parsing stopped: output space exhausted vs input drained. */ | ||
| 122 | 472 | if (n_events_read >= events_capacity || n_triggers_read >= triggers_capacity) { | |
| 123 | 364 | status = EVUTILS_PARSE_OUTPUT_FULL; | |
| 124 | } | ||
| 125 | |||
| 126 | 472 | return (parser_result_t){ | |
| 127 | .current = (const void *)current, | ||
| 128 | .status = status | ||
| 129 | }; | ||
| 130 | } | ||
| 131 | |||
| 132 | |||
| 133 |