Program Listing for File imu6.h

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

#ifndef LIBCAER_EVENTS_IMU6_H_
#define LIBCAER_EVENTS_IMU6_H_

#include "common.h"

#ifdef __cplusplus
extern "C" {
#endif

PACKED_STRUCT(struct caer_imu6_event {
    uint32_t info;
    int32_t timestamp;
    float accel_x;
    float accel_y;
    float accel_z;
    float gyro_x;
    float gyro_y;
    float gyro_z;
    float temp;
});

typedef struct caer_imu6_event *caerIMU6Event;
typedef const struct caer_imu6_event *caerIMU6EventConst;

PACKED_STRUCT(struct caer_imu6_event_packet {
    struct caer_event_packet_header packetHeader;
    struct caer_imu6_event events[];
});

typedef struct caer_imu6_event_packet *caerIMU6EventPacket;
typedef const struct caer_imu6_event_packet *caerIMU6EventPacketConst;

static inline caerIMU6EventPacket caerIMU6EventPacketAllocate(
    int32_t eventCapacity, int16_t eventSource, int32_t tsOverflow) {
    return ((caerIMU6EventPacket) caerEventPacketAllocate(eventCapacity, eventSource, tsOverflow, IMU6_EVENT,
        sizeof(struct caer_imu6_event), offsetof(struct caer_imu6_event, timestamp)));
}

static inline caerIMU6EventPacket caerIMU6EventPacketFromPacketHeader(caerEventPacketHeader header) {
    if (caerEventPacketHeaderGetEventType(header) != IMU6_EVENT) {
        return (NULL);
    }

    return ((caerIMU6EventPacket) header);
}

static inline caerIMU6EventPacketConst caerIMU6EventPacketFromPacketHeaderConst(caerEventPacketHeaderConst header) {
    if (caerEventPacketHeaderGetEventType(header) != IMU6_EVENT) {
        return (NULL);
    }

    return ((caerIMU6EventPacketConst) header);
}

static inline caerIMU6Event caerIMU6EventPacketGetEvent(caerIMU6EventPacket packet, int32_t n) {
    // Check that we're not out of bounds.
    if (n < 0 || n >= caerEventPacketHeaderGetEventCapacity(&packet->packetHeader)) {
        caerLogEHO(CAER_LOG_CRITICAL, "IMU6 Event",
            "Called caerIMU6EventPacketGetEvent() 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 caerIMU6EventConst caerIMU6EventPacketGetEventConst(caerIMU6EventPacketConst packet, int32_t n) {
    // Check that we're not out of bounds.
    if (n < 0 || n >= caerEventPacketHeaderGetEventCapacity(&packet->packetHeader)) {
        caerLogEHO(CAER_LOG_CRITICAL, "IMU6 Event",
            "Called caerIMU6EventPacketGetEventConst() 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 caerIMU6EventGetTimestamp(caerIMU6EventConst event) {
    return (I32T(le32toh(U32T(event->timestamp))));
}

static inline int64_t caerIMU6EventGetTimestamp64(caerIMU6EventConst event, caerIMU6EventPacketConst packet) {
    return (I64T((U64T(caerEventPacketHeaderGetEventTSOverflow(&packet->packetHeader)) << TS_OVERFLOW_SHIFT)
                 | U64T(caerIMU6EventGetTimestamp(event))));
}

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

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

static inline bool caerIMU6EventIsValid(caerIMU6EventConst event) {
    return (GET_NUMBITS32(event->info, VALID_MARK_SHIFT, VALID_MARK_MASK));
}

static inline void caerIMU6EventValidate(caerIMU6Event event, caerIMU6EventPacket packet) {
    if (!caerIMU6EventIsValid(event)) {
        SET_NUMBITS32(event->info, 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, "IMU6 Event", "Called caerIMU6EventValidate() on already valid event.");
    }
}

static inline void caerIMU6EventInvalidate(caerIMU6Event event, caerIMU6EventPacket packet) {
    if (caerIMU6EventIsValid(event)) {
        CLEAR_NUMBITS32(event->info, 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, "IMU6 Event", "Called caerIMU6EventInvalidate() on already invalid event.");
    }
}

static inline float caerIMU6EventGetAccelX(caerIMU6EventConst event) {
    return (leflttoh(event->accel_x));
}

static inline void caerIMU6EventSetAccelX(caerIMU6Event event, float accelX) {
    event->accel_x = htoleflt(accelX);
}

static inline float caerIMU6EventGetAccelY(caerIMU6EventConst event) {
    return (leflttoh(event->accel_y));
}

static inline void caerIMU6EventSetAccelY(caerIMU6Event event, float accelY) {
    event->accel_y = htoleflt(accelY);
}

static inline float caerIMU6EventGetAccelZ(caerIMU6EventConst event) {
    return (leflttoh(event->accel_z));
}

static inline void caerIMU6EventSetAccelZ(caerIMU6Event event, float accelZ) {
    event->accel_z = htoleflt(accelZ);
}

static inline float caerIMU6EventGetGyroX(caerIMU6EventConst event) {
    return (leflttoh(event->gyro_x));
}

static inline void caerIMU6EventSetGyroX(caerIMU6Event event, float gyroX) {
    event->gyro_x = htoleflt(gyroX);
}

static inline float caerIMU6EventGetGyroY(caerIMU6EventConst event) {
    return (leflttoh(event->gyro_y));
}

static inline void caerIMU6EventSetGyroY(caerIMU6Event event, float gyroY) {
    event->gyro_y = htoleflt(gyroY);
}

static inline float caerIMU6EventGetGyroZ(caerIMU6EventConst event) {
    return (leflttoh(event->gyro_z));
}

static inline void caerIMU6EventSetGyroZ(caerIMU6Event event, float gyroZ) {
    event->gyro_z = htoleflt(gyroZ);
}

static inline float caerIMU6EventGetTemp(caerIMU6EventConst event) {
    return (leflttoh(event->temp));
}

static inline void caerIMU6EventSetTemp(caerIMU6Event event, float temp) {
    event->temp = htoleflt(temp);
}

#define CAER_IMU6_ITERATOR_ALL_START(IMU6_PACKET)                                                     \
    for (int32_t caerIMU6IteratorCounter = 0;                                                         \
         caerIMU6IteratorCounter < caerEventPacketHeaderGetEventNumber(&(IMU6_PACKET)->packetHeader); \
         caerIMU6IteratorCounter++) {                                                                 \
        caerIMU6Event caerIMU6IteratorElement = caerIMU6EventPacketGetEvent(IMU6_PACKET, caerIMU6IteratorCounter);

#define CAER_IMU6_CONST_ITERATOR_ALL_START(IMU6_PACKET)                                               \
    for (int32_t caerIMU6IteratorCounter = 0;                                                         \
         caerIMU6IteratorCounter < caerEventPacketHeaderGetEventNumber(&(IMU6_PACKET)->packetHeader); \
         caerIMU6IteratorCounter++) {                                                                 \
        caerIMU6EventConst caerIMU6IteratorElement                                                    \
            = caerIMU6EventPacketGetEventConst(IMU6_PACKET, caerIMU6IteratorCounter);

#define CAER_IMU6_ITERATOR_ALL_END }

#define CAER_IMU6_ITERATOR_VALID_START(IMU6_PACKET)                                                                \
    for (int32_t caerIMU6IteratorCounter = 0;                                                                      \
         caerIMU6IteratorCounter < caerEventPacketHeaderGetEventNumber(&(IMU6_PACKET)->packetHeader);              \
         caerIMU6IteratorCounter++) {                                                                              \
        caerIMU6Event caerIMU6IteratorElement = caerIMU6EventPacketGetEvent(IMU6_PACKET, caerIMU6IteratorCounter); \
        if (!caerIMU6EventIsValid(caerIMU6IteratorElement)) {                                                      \
            continue;                                                                                              \
        } // Skip invalid IMU6 events.

#define CAER_IMU6_CONST_ITERATOR_VALID_START(IMU6_PACKET)                                             \
    for (int32_t caerIMU6IteratorCounter = 0;                                                         \
         caerIMU6IteratorCounter < caerEventPacketHeaderGetEventNumber(&(IMU6_PACKET)->packetHeader); \
         caerIMU6IteratorCounter++) {                                                                 \
        caerIMU6EventConst caerIMU6IteratorElement                                                    \
            = caerIMU6EventPacketGetEventConst(IMU6_PACKET, caerIMU6IteratorCounter);                 \
        if (!caerIMU6EventIsValid(caerIMU6IteratorElement)) {                                         \
            continue;                                                                                 \
        } // Skip invalid IMU6 events.

#define CAER_IMU6_ITERATOR_VALID_END }

#define CAER_IMU6_REVERSE_ITERATOR_ALL_START(IMU6_PACKET)                                                         \
    for (int32_t caerIMU6IteratorCounter = caerEventPacketHeaderGetEventNumber(&(IMU6_PACKET)->packetHeader) - 1; \
         caerIMU6IteratorCounter >= 0; caerIMU6IteratorCounter--) {                                               \
        caerIMU6Event caerIMU6IteratorElement = caerIMU6EventPacketGetEvent(IMU6_PACKET, caerIMU6IteratorCounter);
#define CAER_IMU6_CONST_REVERSE_ITERATOR_ALL_START(IMU6_PACKET)                                                   \
    for (int32_t caerIMU6IteratorCounter = caerEventPacketHeaderGetEventNumber(&(IMU6_PACKET)->packetHeader) - 1; \
         caerIMU6IteratorCounter >= 0; caerIMU6IteratorCounter--) {                                               \
        caerIMU6EventConst caerIMU6IteratorElement                                                                \
            = caerIMU6EventPacketGetEventConst(IMU6_PACKET, caerIMU6IteratorCounter);

#define CAER_IMU6_REVERSE_ITERATOR_ALL_END }

#define CAER_IMU6_REVERSE_ITERATOR_VALID_START(IMU6_PACKET)                                                        \
    for (int32_t caerIMU6IteratorCounter = caerEventPacketHeaderGetEventNumber(&(IMU6_PACKET)->packetHeader) - 1;  \
         caerIMU6IteratorCounter >= 0; caerIMU6IteratorCounter--) {                                                \
        caerIMU6Event caerIMU6IteratorElement = caerIMU6EventPacketGetEvent(IMU6_PACKET, caerIMU6IteratorCounter); \
        if (!caerIMU6EventIsValid(caerIMU6IteratorElement)) {                                                      \
            continue;                                                                                              \
        } // Skip invalid IMU6 events.

#define CAER_IMU6_CONST_REVERSE_ITERATOR_VALID_START(IMU6_PACKET)                                                 \
    for (int32_t caerIMU6IteratorCounter = caerEventPacketHeaderGetEventNumber(&(IMU6_PACKET)->packetHeader) - 1; \
         caerIMU6IteratorCounter >= 0; caerIMU6IteratorCounter--) {                                               \
        caerIMU6EventConst caerIMU6IteratorElement                                                                \
            = caerIMU6EventPacketGetEventConst(IMU6_PACKET, caerIMU6IteratorCounter);                             \
        if (!caerIMU6EventIsValid(caerIMU6IteratorElement)) {                                                     \
            continue;                                                                                             \
        } // Skip invalid IMU6 events.

#define CAER_IMU6_REVERSE_ITERATOR_VALID_END }

#ifdef __cplusplus
}
#endif

#endif /* LIBCAER_EVENTS_IMU6_H_ */