.. _program_listing_file_include_libcaer_events_special.h: Program Listing for File special.h ================================== |exhale_lsh| :ref:`Return to documentation for file ` (``include/libcaer/events/special.h``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #ifndef LIBCAER_EVENTS_SPECIAL_H_ #define LIBCAER_EVENTS_SPECIAL_H_ #include "common.h" #ifdef __cplusplus extern "C" { #endif #define SPECIAL_TYPE_SHIFT 1 #define SPECIAL_TYPE_MASK 0x0000007F #define SPECIAL_DATA_SHIFT 8 #define SPECIAL_DATA_MASK 0x00FFFFFF enum caer_special_event_types { TIMESTAMP_WRAP = 0, TIMESTAMP_RESET = 1, EXTERNAL_INPUT_RISING_EDGE = 2, EXTERNAL_INPUT_FALLING_EDGE = 3, EXTERNAL_INPUT_PULSE = 4, DVS_ROW_ONLY = 5, EXTERNAL_INPUT1_RISING_EDGE = 6, EXTERNAL_INPUT1_FALLING_EDGE = 7, EXTERNAL_INPUT1_PULSE = 8, EXTERNAL_INPUT2_RISING_EDGE = 9, EXTERNAL_INPUT2_FALLING_EDGE = 10, EXTERNAL_INPUT2_PULSE = 11, EXTERNAL_GENERATOR_RISING_EDGE = 12, EXTERNAL_GENERATOR_FALLING_EDGE = 13, APS_FRAME_START = 14, APS_FRAME_END = 15, APS_EXPOSURE_START = 16, APS_EXPOSURE_END = 17, EVENT_READOUT_START = 18, }; PACKED_STRUCT(struct caer_special_event { uint32_t data; int32_t timestamp; }); typedef struct caer_special_event *caerSpecialEvent; typedef const struct caer_special_event *caerSpecialEventConst; PACKED_STRUCT(struct caer_special_event_packet { struct caer_event_packet_header packetHeader; struct caer_special_event events[]; }); typedef struct caer_special_event_packet *caerSpecialEventPacket; typedef const struct caer_special_event_packet *caerSpecialEventPacketConst; static inline caerSpecialEventPacket caerSpecialEventPacketAllocate( int32_t eventCapacity, int16_t eventSource, int32_t tsOverflow) { return ((caerSpecialEventPacket) caerEventPacketAllocate(eventCapacity, eventSource, tsOverflow, SPECIAL_EVENT, sizeof(struct caer_special_event), offsetof(struct caer_special_event, timestamp))); } static inline caerSpecialEventPacket caerSpecialEventPacketFromPacketHeader(caerEventPacketHeader header) { if (caerEventPacketHeaderGetEventType(header) != SPECIAL_EVENT) { return (NULL); } return ((caerSpecialEventPacket) header); } static inline caerSpecialEventPacketConst caerSpecialEventPacketFromPacketHeaderConst( caerEventPacketHeaderConst header) { if (caerEventPacketHeaderGetEventType(header) != SPECIAL_EVENT) { return (NULL); } return ((caerSpecialEventPacketConst) header); } static inline caerSpecialEvent caerSpecialEventPacketGetEvent(caerSpecialEventPacket packet, int32_t n) { // Check that we're not out of bounds. if (n < 0 || n >= caerEventPacketHeaderGetEventCapacity(&packet->packetHeader)) { caerLogEHO(CAER_LOG_CRITICAL, "Special Event", "Called caerSpecialEventPacketGetEvent() with invalid event offset %" PRIi32 ", while maximum allowed value is %" PRIi32 ".", n, caerEventPacketHeaderGetEventCapacity(&packet->packetHeader) - 1); return (NULL); } // Return a pointer to the specified event. return (packet->events + n); } static inline caerSpecialEventConst caerSpecialEventPacketGetEventConst(caerSpecialEventPacketConst packet, int32_t n) { // Check that we're not out of bounds. if (n < 0 || n >= caerEventPacketHeaderGetEventCapacity(&packet->packetHeader)) { caerLogEHO(CAER_LOG_CRITICAL, "Special Event", "Called caerSpecialEventPacketGetEventConst() with invalid event offset %" PRIi32 ", while maximum allowed value is %" PRIi32 ".", n, caerEventPacketHeaderGetEventCapacity(&packet->packetHeader) - 1); return (NULL); } // Return a pointer to the specified event. return (packet->events + n); } static inline int32_t caerSpecialEventGetTimestamp(caerSpecialEventConst event) { return (I32T(le32toh(U32T(event->timestamp)))); } static inline int64_t caerSpecialEventGetTimestamp64(caerSpecialEventConst event, caerSpecialEventPacketConst packet) { return (I64T((U64T(caerEventPacketHeaderGetEventTSOverflow(&packet->packetHeader)) << TS_OVERFLOW_SHIFT) | U64T(caerSpecialEventGetTimestamp(event)))); } static inline void caerSpecialEventSetTimestamp(caerSpecialEvent event, int32_t timestamp) { if (timestamp < 0) { // Negative means using the 31st bit! caerLogEHO(CAER_LOG_CRITICAL, "Special Event", "Called caerSpecialEventSetTimestamp() with negative value!"); return; } event->timestamp = I32T(htole32(U32T(timestamp))); } static inline bool caerSpecialEventIsValid(caerSpecialEventConst event) { return (GET_NUMBITS32(event->data, VALID_MARK_SHIFT, VALID_MARK_MASK)); } static inline void caerSpecialEventValidate(caerSpecialEvent event, caerSpecialEventPacket packet) { if (!caerSpecialEventIsValid(event)) { SET_NUMBITS32(event->data, VALID_MARK_SHIFT, VALID_MARK_MASK, 1); // Also increase number of events and valid events. // Only call this on (still) invalid events! caerEventPacketHeaderSetEventNumber( &packet->packetHeader, caerEventPacketHeaderGetEventNumber(&packet->packetHeader) + 1); caerEventPacketHeaderSetEventValid( &packet->packetHeader, caerEventPacketHeaderGetEventValid(&packet->packetHeader) + 1); } else { caerLogEHO(CAER_LOG_CRITICAL, "Special Event", "Called caerSpecialEventValidate() on already valid event."); } } static inline void caerSpecialEventInvalidate(caerSpecialEvent event, caerSpecialEventPacket packet) { if (caerSpecialEventIsValid(event)) { CLEAR_NUMBITS32(event->data, VALID_MARK_SHIFT, VALID_MARK_MASK); // Also decrease number of valid events. Number of total events doesn't change. // Only call this on valid events! caerEventPacketHeaderSetEventValid( &packet->packetHeader, caerEventPacketHeaderGetEventValid(&packet->packetHeader) - 1); } else { caerLogEHO(CAER_LOG_CRITICAL, "Special Event", "Called caerSpecialEventInvalidate() on already invalid event."); } } static inline uint8_t caerSpecialEventGetType(caerSpecialEventConst event) { return U8T(GET_NUMBITS32(event->data, SPECIAL_TYPE_SHIFT, SPECIAL_TYPE_MASK)); } static inline void caerSpecialEventSetType(caerSpecialEvent event, uint8_t type) { CLEAR_NUMBITS32(event->data, SPECIAL_TYPE_SHIFT, SPECIAL_TYPE_MASK); SET_NUMBITS32(event->data, SPECIAL_TYPE_SHIFT, SPECIAL_TYPE_MASK, type); } static inline uint32_t caerSpecialEventGetData(caerSpecialEventConst event) { return U32T(GET_NUMBITS32(event->data, SPECIAL_DATA_SHIFT, SPECIAL_DATA_MASK)); } static inline void caerSpecialEventSetData(caerSpecialEvent event, uint32_t data) { CLEAR_NUMBITS32(event->data, SPECIAL_DATA_SHIFT, SPECIAL_DATA_MASK); SET_NUMBITS32(event->data, SPECIAL_DATA_SHIFT, SPECIAL_DATA_MASK, data); } #define CAER_SPECIAL_ITERATOR_ALL_START(SPECIAL_PACKET) \ for (int32_t caerSpecialIteratorCounter = 0; \ caerSpecialIteratorCounter < caerEventPacketHeaderGetEventNumber(&(SPECIAL_PACKET)->packetHeader); \ caerSpecialIteratorCounter++) { \ caerSpecialEvent caerSpecialIteratorElement \ = caerSpecialEventPacketGetEvent(SPECIAL_PACKET, caerSpecialIteratorCounter); #define CAER_SPECIAL_CONST_ITERATOR_ALL_START(SPECIAL_PACKET) \ for (int32_t caerSpecialIteratorCounter = 0; \ caerSpecialIteratorCounter < caerEventPacketHeaderGetEventNumber(&(SPECIAL_PACKET)->packetHeader); \ caerSpecialIteratorCounter++) { \ caerSpecialEventConst caerSpecialIteratorElement \ = caerSpecialEventPacketGetEventConst(SPECIAL_PACKET, caerSpecialIteratorCounter); #define CAER_SPECIAL_ITERATOR_ALL_END } #define CAER_SPECIAL_ITERATOR_VALID_START(SPECIAL_PACKET) \ for (int32_t caerSpecialIteratorCounter = 0; \ caerSpecialIteratorCounter < caerEventPacketHeaderGetEventNumber(&(SPECIAL_PACKET)->packetHeader); \ caerSpecialIteratorCounter++) { \ caerSpecialEvent caerSpecialIteratorElement \ = caerSpecialEventPacketGetEvent(SPECIAL_PACKET, caerSpecialIteratorCounter); \ if (!caerSpecialEventIsValid(caerSpecialIteratorElement)) { \ continue; \ } // Skip invalid special events. #define CAER_SPECIAL_CONST_ITERATOR_VALID_START(SPECIAL_PACKET) \ for (int32_t caerSpecialIteratorCounter = 0; \ caerSpecialIteratorCounter < caerEventPacketHeaderGetEventNumber(&(SPECIAL_PACKET)->packetHeader); \ caerSpecialIteratorCounter++) { \ caerSpecialEventConst caerSpecialIteratorElement \ = caerSpecialEventPacketGetEventConst(SPECIAL_PACKET, caerSpecialIteratorCounter); \ if (!caerSpecialEventIsValid(caerSpecialIteratorElement)) { \ continue; \ } // Skip invalid special events. #define CAER_SPECIAL_ITERATOR_VALID_END } #define CAER_SPECIAL_REVERSE_ITERATOR_ALL_START(SPECIAL_PACKET) \ for (int32_t caerSpecialIteratorCounter \ = caerEventPacketHeaderGetEventNumber(&(SPECIAL_PACKET)->packetHeader) - 1; \ caerSpecialIteratorCounter >= 0; caerSpecialIteratorCounter--) { \ caerSpecialEvent caerSpecialIteratorElement \ = caerSpecialEventPacketGetEvent(SPECIAL_PACKET, caerSpecialIteratorCounter); #define CAER_SPECIAL_CONST_REVERSE_ITERATOR_ALL_START(SPECIAL_PACKET) \ for (int32_t caerSpecialIteratorCounter \ = caerEventPacketHeaderGetEventNumber(&(SPECIAL_PACKET)->packetHeader) - 1; \ caerSpecialIteratorCounter >= 0; caerSpecialIteratorCounter--) { \ caerSpecialEventConst caerSpecialIteratorElement \ = caerSpecialEventPacketGetEventConst(SPECIAL_PACKET, caerSpecialIteratorCounter); #define CAER_SPECIAL_REVERSE_ITERATOR_ALL_END } #define CAER_SPECIAL_REVERSE_ITERATOR_VALID_START(SPECIAL_PACKET) \ for (int32_t caerSpecialIteratorCounter \ = caerEventPacketHeaderGetEventNumber(&(SPECIAL_PACKET)->packetHeader) - 1; \ caerSpecialIteratorCounter >= 0; caerSpecialIteratorCounter--) { \ caerSpecialEvent caerSpecialIteratorElement \ = caerSpecialEventPacketGetEvent(SPECIAL_PACKET, caerSpecialIteratorCounter); \ if (!caerSpecialEventIsValid(caerSpecialIteratorElement)) { \ continue; \ } // Skip invalid special events. #define CAER_SPECIAL_CONST_REVERSE_ITERATOR_VALID_START(SPECIAL_PACKET) \ for (int32_t caerSpecialIteratorCounter \ = caerEventPacketHeaderGetEventNumber(&(SPECIAL_PACKET)->packetHeader) - 1; \ caerSpecialIteratorCounter >= 0; caerSpecialIteratorCounter--) { \ caerSpecialEventConst caerSpecialIteratorElement \ = caerSpecialEventPacketGetEventConst(SPECIAL_PACKET, caerSpecialIteratorCounter); \ if (!caerSpecialEventIsValid(caerSpecialIteratorElement)) { \ continue; \ } // Skip invalid special events. #define CAER_SPECIAL_REVERSE_ITERATOR_VALID_END } static inline caerSpecialEvent caerSpecialEventPacketFindEventByType(caerSpecialEventPacket packet, uint8_t type) { CAER_SPECIAL_ITERATOR_ALL_START(packet) if (caerSpecialEventGetType(caerSpecialIteratorElement) == type) { // Found it, return it. return (caerSpecialIteratorElement); } CAER_SPECIAL_ITERATOR_ALL_END // Found nothing, return nothing. return (NULL); } static inline caerSpecialEventConst caerSpecialEventPacketFindEventByTypeConst( caerSpecialEventPacketConst packet, uint8_t type) { CAER_SPECIAL_CONST_ITERATOR_ALL_START(packet) if (caerSpecialEventGetType(caerSpecialIteratorElement) == type) { // Found it, return it. return (caerSpecialIteratorElement); } CAER_SPECIAL_ITERATOR_ALL_END // Found nothing, return nothing. return (NULL); } static inline caerSpecialEvent caerSpecialEventPacketFindValidEventByType(caerSpecialEventPacket packet, uint8_t type) { CAER_SPECIAL_ITERATOR_VALID_START(packet) if (caerSpecialEventGetType(caerSpecialIteratorElement) == type) { // Found it, return it. return (caerSpecialIteratorElement); } CAER_SPECIAL_ITERATOR_VALID_END // Found nothing, return nothing. return (NULL); } static inline caerSpecialEventConst caerSpecialEventPacketFindValidEventByTypeConst( caerSpecialEventPacketConst packet, uint8_t type) { CAER_SPECIAL_CONST_ITERATOR_VALID_START(packet) if (caerSpecialEventGetType(caerSpecialIteratorElement) == type) { // Found it, return it. return (caerSpecialIteratorElement); } CAER_SPECIAL_ITERATOR_VALID_END // Found nothing, return nothing. return (NULL); } #ifdef __cplusplus } #endif #endif /* LIBCAER_EVENTS_SPECIAL_H_ */