#define RL64S(x) read_i64le((const uint8_t *)(x))
/**
- * Read a 32 bits big endian float out of memory.
+ * Read a 32 bits big endian float out of memory (single precision).
* @param x a pointer to the input memory
* @return the corresponding float
*/
#define RBFL(x) read_fltbe((const uint8_t *)(x))
/**
- * Read a 32 bits little endian float out of memory.
+ * Read a 32 bits little endian float out of memory (single precision).
* @param x a pointer to the input memory
* @return the corresponding float
*/
}
#define RLFL(x) read_fltle((const uint8_t *)(x))
+/**
+ * Read a 64 bits little endian float out of memory (double precision).
+ * @param x a pointer to the input memory
+ * @return the corresponding floating point value
+ */
+static inline double read_dblle(const uint8_t *p)
+{
+ /*
+ * Implementor's note: Strictly speaking the "union" trick
+ * is not portable. But this phrase was found to work on the
+ * project's supported platforms, and serve well until a more
+ * appropriate phrase is found.
+ */
+ union { uint64_t u64; double flt; } u;
+ double f;
+
+ u.u64 = read_u64le(p);
+ f = u.flt;
+
+ return f;
+}
+#define RLDB(x) read_dblle((const uint8_t *)(x))
+
/**
* Write a 8 bits unsigned integer to memory.
* @param p a pointer to the output memory
}
#define WL32(p, x) write_u32le((uint8_t *)(p), (uint32_t)(x))
+/**
+ * Write a 64 bits unsigned integer to memory stored as little endian.
+ * @param p a pointer to the output memory
+ * @param x the input unsigned integer
+ */
+static inline void write_u64le(uint8_t *p, uint64_t x)
+{
+ p[0] = x & 0xff; x >>= 8;
+ p[1] = x & 0xff; x >>= 8;
+ p[2] = x & 0xff; x >>= 8;
+ p[3] = x & 0xff; x >>= 8;
+ p[4] = x & 0xff; x >>= 8;
+ p[5] = x & 0xff; x >>= 8;
+ p[6] = x & 0xff; x >>= 8;
+ p[7] = x & 0xff; x >>= 8;
+}
+#define WL64(p, x) write_u64le((uint8_t *)(p), (uint64_t)(x))
+
/**
* Write a 32 bits float to memory stored as big endian.
* @param p a pointer to the output memory
}
#define WLFL(p, x) write_fltle((uint8_t *)(p), float (x))
+/**
+ * Write a 64 bits float to memory stored as little endian.
+ * @param p a pointer to the output memory
+ * @param x the input floating point value
+ */
+static inline void write_dblle(uint8_t *p, double x)
+{
+ union { uint64_t u; double f; } u;
+ u.f = x;
+ write_u64le(p, u.u);
+}
+#define WLDB(p, x) write_dblle((uint8_t *)(p), float (x))
+
/* Endianess conversion helpers with read/write position increment. */
/**
return v;
}
+/**
+ * Read 32bit float from raw memory (little endian format), increment read position.
+ * @param[in, out] p Pointer into byte stream.
+ * @return Retrieved float value.
+ */
+static inline float read_fltle_inc(const uint8_t **p)
+{
+ float v;
+
+ if (!p || !*p)
+ return 0;
+ v = read_fltle(*p);
+ *p += sizeof(v);
+
+ return v;
+}
+
+/**
+ * Read 64bit float from raw memory (little endian format), increment read position.
+ * @param[in, out] p Pointer into byte stream.
+ * @return Retrieved float value.
+ */
+static inline double read_dblle_inc(const uint8_t **p)
+{
+ double v;
+
+ if (!p || !*p)
+ return 0;
+ v = read_dblle(*p);
+ *p += sizeof(v);
+
+ return v;
+}
+
/**
* Write unsigned 8bit integer to raw memory, increment write position.
* @param[in, out] p Pointer into byte stream.
*p += sizeof(x);
}
+/**
+ * Write unsigned 64bit little endian integer to raw memory, increment write position.
+ * @param[in, out] p Pointer into byte stream.
+ * @param[in] x Value to write.
+ */
+static inline void write_u64le_inc(uint8_t **p, uint64_t x)
+{
+ if (!p || !*p)
+ return;
+ write_u64le(*p, x);
+ *p += sizeof(x);
+}
+
+/**
+ * Write single precision little endian float to raw memory, increment write position.
+ * @param[in, out] p Pointer into byte stream.
+ * @param[in] x Value to write.
+ */
+static inline void write_fltle_inc(uint8_t **p, float x)
+{
+ if (!p || !*p)
+ return;
+ write_fltle(*p, x);
+ *p += sizeof(x);
+}
+
+/**
+ * Write double precision little endian float to raw memory, increment write position.
+ * @param[in, out] p Pointer into byte stream.
+ * @param[in] x Value to write.
+ */
+static inline void write_dblle_inc(uint8_t **p, double x)
+{
+ if (!p || !*p)
+ return;
+ write_dblle(*p, x);
+ *p += sizeof(x);
+}
+
/* Portability fixes for FreeBSD. */
#ifdef __FreeBSD__
#define LIBUSB_CLASS_APPLICATION 0xfe
const char *manufacturer, const char *product);
#endif
+/*--- binary_helpers.c ------------------------------------------------------*/
+
+/** Binary value type */
+enum binary_value_type {
+ BVT_UINT8 = 0,
+ BVT_BE_UINT8 = BVT_UINT8,
+ BVT_LE_UINT8 = BVT_UINT8,
+
+ BVT_BE_UINT16,
+ BVT_BE_UINT32,
+ BVT_BE_UINT64,
+ BVT_BE_FLOAT,
+
+ BVT_LE_UINT16,
+ BVT_LE_UINT32,
+ BVT_LE_UINT64,
+ BVT_LE_FLOAT,
+};
+
+/** Binary value specification */
+struct binary_value_spec {
+ /** Offset into binary blob */
+ size_t offset;
+ /** Data type to decode */
+ enum binary_value_type type;
+ /** Scale factor to get native units */
+ float scale;
+};
+
+/** Binary channel definition */
+struct binary_analog_channel {
+ /** Channel name */
+ const char *name;
+ /** Binary value in data stream */
+ struct binary_value_spec spec;
+ /** Significant digits */
+ int digits;
+ /** Measured quantity */
+ enum sr_mq mq;
+ /** Measured unit */
+ enum sr_unit unit;
+};
+
+/**
+ * Read extract a value from a binary blob.
+ *
+ * @param out Pointer to output buffer.
+ * @param spec Binary value specification
+ * @param data Pointer to binary blob
+ * @param length Size of binary blob
+ * @return SR_OK on success, SR_ERR_* error code on failure.
+ */
+SR_PRIV int bv_get_value(float *out, const struct binary_value_spec *spec, const void *data, size_t length);
+
+/**
+ * Send an analog channel packet based on a binary analog channel
+ * specification.
+ *
+ * @param sdi Device instance
+ * @param ch Sigrok channel
+ * @param spec Channel specification
+ * @param data Pointer to binary blob
+ * @param length Size of binary blob
+ * @return SR_OK on success, SR_ERR_* error code on failure.
+ */
+SR_PRIV int bv_send_analog_channel(const struct sr_dev_inst *sdi, struct sr_channel *ch,
+ const struct binary_analog_channel *spec, const void *data, size_t length);
+
+/*--- crc.c -----------------------------------------------------------------*/
+
+#define SR_CRC16_DEFAULT_INIT 0xffffU
+
+/**
+ * Calculate a CRC16 checksum using the 0x8005 polynomial.
+ *
+ * This CRC16 flavor is also known as CRC16-ANSI or CRC16-MODBUS.
+ *
+ * @param crc Initial value (typically 0xffff)
+ * @param buffer Input buffer
+ * @param len Buffer length
+ * @return Checksum
+ */
+SR_PRIV uint16_t sr_crc16(uint16_t crc, const uint8_t *buffer, int len);
/*--- modbus/modbus.c -------------------------------------------------------*/
uint64_t start_time;
};
-SR_PRIV int sr_sw_limits_config_get(struct sr_sw_limits *limits, uint32_t key,
+SR_PRIV int sr_sw_limits_config_get(const struct sr_sw_limits *limits, uint32_t key,
GVariant **data);
SR_PRIV int sr_sw_limits_config_set(struct sr_sw_limits *limits, uint32_t key,
GVariant *data);
uint64_t frames_read);
SR_PRIV void sr_sw_limits_init(struct sr_sw_limits *limits);
+/*--- feed_queue.h ----------------------------------------------------------*/
+
+struct feed_queue_logic;
+struct feed_queue_analog;
+
+SR_API struct feed_queue_logic *feed_queue_logic_alloc(
+ struct sr_dev_inst *sdi,
+ size_t sample_count, size_t unit_size);
+SR_API int feed_queue_logic_submit(struct feed_queue_logic *q,
+ const uint8_t *data, size_t count);
+SR_API int feed_queue_logic_flush(struct feed_queue_logic *q);
+SR_API void feed_queue_logic_free(struct feed_queue_logic *q);
+
+SR_API struct feed_queue_analog *feed_queue_analog_alloc(
+ struct sr_dev_inst *sdi,
+ size_t sample_count, int digits, struct sr_channel *ch);
+SR_API int feed_queue_analog_submit(struct feed_queue_analog *q,
+ float data, size_t count);
+SR_API int feed_queue_analog_flush(struct feed_queue_analog *q);
+SR_API void feed_queue_analog_free(struct feed_queue_analog *q);
+
#endif