Program Listing for File special.h
↰ Return to documentation for file (include/libcaer/events/special.h
)
#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_ */