Program Listing for File polarity.h

Return to documentation for file (include/libcaer/events/polarity.h)

#ifndef LIBCAER_EVENTS_POLARITY_H_
#define LIBCAER_EVENTS_POLARITY_H_

#include "common.h"

#ifdef __cplusplus
extern "C" {
#endif

#define POLARITY_SHIFT        1
#define POLARITY_MASK         0x00000001
#define POLARITY_Y_ADDR_SHIFT 2
#define POLARITY_Y_ADDR_MASK  0x00007FFF
#define POLARITY_X_ADDR_SHIFT 17
#define POLARITY_X_ADDR_MASK  0x00007FFF

PACKED_STRUCT(struct caer_polarity_event {
    uint32_t data;
    int32_t timestamp;
});

typedef struct caer_polarity_event *caerPolarityEvent;
typedef const struct caer_polarity_event *caerPolarityEventConst;

PACKED_STRUCT(struct caer_polarity_event_packet {
    struct caer_event_packet_header packetHeader;
    struct caer_polarity_event events[];
});

typedef struct caer_polarity_event_packet *caerPolarityEventPacket;
typedef const struct caer_polarity_event_packet *caerPolarityEventPacketConst;

static inline caerPolarityEventPacket caerPolarityEventPacketAllocate(
    int32_t eventCapacity, int16_t eventSource, int32_t tsOverflow) {
    return ((caerPolarityEventPacket) caerEventPacketAllocate(eventCapacity, eventSource, tsOverflow, POLARITY_EVENT,
        sizeof(struct caer_polarity_event), offsetof(struct caer_polarity_event, timestamp)));
}

static inline caerPolarityEventPacket caerPolarityEventPacketFromPacketHeader(caerEventPacketHeader header) {
    if (caerEventPacketHeaderGetEventType(header) != POLARITY_EVENT) {
        return (NULL);
    }

    return ((caerPolarityEventPacket) header);
}

static inline caerPolarityEventPacketConst caerPolarityEventPacketFromPacketHeaderConst(
    caerEventPacketHeaderConst header) {
    if (caerEventPacketHeaderGetEventType(header) != POLARITY_EVENT) {
        return (NULL);
    }

    return ((caerPolarityEventPacketConst) header);
}

static inline caerPolarityEvent caerPolarityEventPacketGetEvent(caerPolarityEventPacket packet, int32_t n) {
    // Check that we're not out of bounds.
    if (n < 0 || n >= caerEventPacketHeaderGetEventCapacity(&packet->packetHeader)) {
        caerLogEHO(CAER_LOG_CRITICAL, "Polarity Event",
            "Called caerPolarityEventPacketGetEvent() 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 caerPolarityEventConst caerPolarityEventPacketGetEventConst(
    caerPolarityEventPacketConst packet, int32_t n) {
    // Check that we're not out of bounds.
    if (n < 0 || n >= caerEventPacketHeaderGetEventCapacity(&packet->packetHeader)) {
        caerLogEHO(CAER_LOG_CRITICAL, "Polarity Event",
            "Called caerPolarityEventPacketGetEventConst() 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 caerPolarityEventGetTimestamp(caerPolarityEventConst event) {
    return (I32T(le32toh(U32T(event->timestamp))));
}

static inline int64_t caerPolarityEventGetTimestamp64(
    caerPolarityEventConst event, caerPolarityEventPacketConst packet) {
    return (I64T((U64T(caerEventPacketHeaderGetEventTSOverflow(&packet->packetHeader)) << TS_OVERFLOW_SHIFT)
                 | U64T(caerPolarityEventGetTimestamp(event))));
}

static inline void caerPolarityEventSetTimestamp(caerPolarityEvent event, int32_t timestamp) {
    if (timestamp < 0) {
        // Negative means using the 31st bit!
        caerLogEHO(CAER_LOG_CRITICAL, "Polarity Event", "Called caerPolarityEventSetTimestamp() with negative value!");
        return;
    }

    event->timestamp = I32T(htole32(U32T(timestamp)));
}

static inline bool caerPolarityEventIsValid(caerPolarityEventConst event) {
    return (GET_NUMBITS32(event->data, VALID_MARK_SHIFT, VALID_MARK_MASK));
}

static inline void caerPolarityEventValidate(caerPolarityEvent event, caerPolarityEventPacket packet) {
    if (!caerPolarityEventIsValid(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, "Polarity Event", "Called caerPolarityEventValidate() on already valid event.");
    }
}

static inline void caerPolarityEventInvalidate(caerPolarityEvent event, caerPolarityEventPacket packet) {
    if (caerPolarityEventIsValid(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, "Polarity Event", "Called caerPolarityEventInvalidate() on already invalid event.");
    }
}

static inline bool caerPolarityEventGetPolarity(caerPolarityEventConst event) {
    return (GET_NUMBITS32(event->data, POLARITY_SHIFT, POLARITY_MASK));
}

static inline void caerPolarityEventSetPolarity(caerPolarityEvent event, bool polarity) {
    CLEAR_NUMBITS32(event->data, POLARITY_SHIFT, POLARITY_MASK);
    SET_NUMBITS32(event->data, POLARITY_SHIFT, POLARITY_MASK, polarity);
}

static inline uint16_t caerPolarityEventGetY(caerPolarityEventConst event) {
    return U16T(GET_NUMBITS32(event->data, POLARITY_Y_ADDR_SHIFT, POLARITY_Y_ADDR_MASK));
}

static inline void caerPolarityEventSetY(caerPolarityEvent event, uint16_t yAddress) {
    CLEAR_NUMBITS32(event->data, POLARITY_Y_ADDR_SHIFT, POLARITY_Y_ADDR_MASK);
    SET_NUMBITS32(event->data, POLARITY_Y_ADDR_SHIFT, POLARITY_Y_ADDR_MASK, yAddress);
}

static inline uint16_t caerPolarityEventGetX(caerPolarityEventConst event) {
    return U16T(GET_NUMBITS32(event->data, POLARITY_X_ADDR_SHIFT, POLARITY_X_ADDR_MASK));
}

static inline void caerPolarityEventSetX(caerPolarityEvent event, uint16_t xAddress) {
    CLEAR_NUMBITS32(event->data, POLARITY_X_ADDR_SHIFT, POLARITY_X_ADDR_MASK);
    SET_NUMBITS32(event->data, POLARITY_X_ADDR_SHIFT, POLARITY_X_ADDR_MASK, xAddress);
}

#define CAER_POLARITY_ITERATOR_ALL_START(POLARITY_PACKET)                                                     \
    for (int32_t caerPolarityIteratorCounter = 0;                                                             \
         caerPolarityIteratorCounter < caerEventPacketHeaderGetEventNumber(&(POLARITY_PACKET)->packetHeader); \
         caerPolarityIteratorCounter++) {                                                                     \
        caerPolarityEvent caerPolarityIteratorElement                                                         \
            = caerPolarityEventPacketGetEvent(POLARITY_PACKET, caerPolarityIteratorCounter);

#define CAER_POLARITY_CONST_ITERATOR_ALL_START(POLARITY_PACKET)                                               \
    for (int32_t caerPolarityIteratorCounter = 0;                                                             \
         caerPolarityIteratorCounter < caerEventPacketHeaderGetEventNumber(&(POLARITY_PACKET)->packetHeader); \
         caerPolarityIteratorCounter++) {                                                                     \
        caerPolarityEventConst caerPolarityIteratorElement                                                    \
            = caerPolarityEventPacketGetEventConst(POLARITY_PACKET, caerPolarityIteratorCounter);

#define CAER_POLARITY_ITERATOR_ALL_END }

#define CAER_POLARITY_ITERATOR_VALID_START(POLARITY_PACKET)                                                   \
    for (int32_t caerPolarityIteratorCounter = 0;                                                             \
         caerPolarityIteratorCounter < caerEventPacketHeaderGetEventNumber(&(POLARITY_PACKET)->packetHeader); \
         caerPolarityIteratorCounter++) {                                                                     \
        caerPolarityEvent caerPolarityIteratorElement                                                         \
            = caerPolarityEventPacketGetEvent(POLARITY_PACKET, caerPolarityIteratorCounter);                  \
        if (!caerPolarityEventIsValid(caerPolarityIteratorElement)) {                                         \
            continue;                                                                                         \
        } // Skip invalid polarity events.

#define CAER_POLARITY_CONST_ITERATOR_VALID_START(POLARITY_PACKET)                                             \
    for (int32_t caerPolarityIteratorCounter = 0;                                                             \
         caerPolarityIteratorCounter < caerEventPacketHeaderGetEventNumber(&(POLARITY_PACKET)->packetHeader); \
         caerPolarityIteratorCounter++) {                                                                     \
        caerPolarityEventConst caerPolarityIteratorElement                                                    \
            = caerPolarityEventPacketGetEventConst(POLARITY_PACKET, caerPolarityIteratorCounter);             \
        if (!caerPolarityEventIsValid(caerPolarityIteratorElement)) {                                         \
            continue;                                                                                         \
        } // Skip invalid polarity events.

#define CAER_POLARITY_ITERATOR_VALID_END }

#define CAER_POLARITY_REVERSE_ITERATOR_ALL_START(POLARITY_PACKET)                     \
    for (int32_t caerPolarityIteratorCounter                                          \
         = caerEventPacketHeaderGetEventNumber(&(POLARITY_PACKET)->packetHeader) - 1; \
         caerPolarityIteratorCounter >= 0; caerPolarityIteratorCounter--) {           \
        caerPolarityEvent caerPolarityIteratorElement                                 \
            = caerPolarityEventPacketGetEvent(POLARITY_PACKET, caerPolarityIteratorCounter);

#define CAER_POLARITY_CONST_REVERSE_ITERATOR_ALL_START(POLARITY_PACKET)               \
    for (int32_t caerPolarityIteratorCounter                                          \
         = caerEventPacketHeaderGetEventNumber(&(POLARITY_PACKET)->packetHeader) - 1; \
         caerPolarityIteratorCounter >= 0; caerPolarityIteratorCounter--) {           \
        caerPolarityEventConst caerPolarityIteratorElement                            \
            = caerPolarityEventPacketGetEventConst(POLARITY_PACKET, caerPolarityIteratorCounter);

#define CAER_POLARITY_REVERSE_ITERATOR_ALL_END }

#define CAER_POLARITY_REVERSE_ITERATOR_VALID_START(POLARITY_PACKET)                          \
    for (int32_t caerPolarityIteratorCounter                                                 \
         = caerEventPacketHeaderGetEventNumber(&(POLARITY_PACKET)->packetHeader) - 1;        \
         caerPolarityIteratorCounter >= 0; caerPolarityIteratorCounter--) {                  \
        caerPolarityEvent caerPolarityIteratorElement                                        \
            = caerPolarityEventPacketGetEvent(POLARITY_PACKET, caerPolarityIteratorCounter); \
        if (!caerPolarityEventIsValid(caerPolarityIteratorElement)) {                        \
            continue;                                                                        \
        } // Skip invalid polarity events.

#define CAER_POLARITY_CONST_REVERSE_ITERATOR_VALID_START(POLARITY_PACKET)                         \
    for (int32_t caerPolarityIteratorCounter                                                      \
         = caerEventPacketHeaderGetEventNumber(&(POLARITY_PACKET)->packetHeader) - 1;             \
         caerPolarityIteratorCounter >= 0; caerPolarityIteratorCounter--) {                       \
        caerPolarityEventConst caerPolarityIteratorElement                                        \
            = caerPolarityEventPacketGetEventConst(POLARITY_PACKET, caerPolarityIteratorCounter); \
        if (!caerPolarityEventIsValid(caerPolarityIteratorElement)) {                             \
            continue;                                                                             \
        } // Skip invalid polarity events.

#define CAER_POLARITY_REVERSE_ITERATOR_VALID_END }

#ifdef __cplusplus
}
#endif

#endif /* LIBCAER_EVENTS_POLARITY_H_ */