26 #define CHAN_ACC_RAW_X 4 
   27 #define CHAN_ACC_RAW_Y 5 
   28 #define CHAN_ACC_RAW_Z 6 
   29 #define CHAN_ACC_CAL_X 7 
   30 #define CHAN_ACC_CAL_Y 8 
   31 #define CHAN_ACC_CAL_Z 9 
   32 #define CHAN_G_RAW_X   10 
   33 #define CHAN_G_RAW_Y   11 
   34 #define CHAN_G_RAW_Z   12 
   35 #define CHAN_G_CAL_X   13 
   36 #define CHAN_G_CAL_Y   14 
   37 #define CHAN_G_CAL_Z   15 
   38 #define CHAN_G_ALIGN_X 16 
   39 #define CHAN_G_ALIGN_Y 17 
   40 #define CHAN_G_ALIGN_Z 18 
   41 #define CHAN_OMEGA_X   19 
   42 #define CHAN_OMEGA_Y   20 
   43 #define CHAN_OMEGA_Z   21 
   47 #define CHAN_ACC_LIN_X 25 
   48 #define CHAN_ACC_LIN_Y 26 
   49 #define CHAN_ACC_LIN_Z 27 
   50 #define CHAN_ALTITUDE  28 
   63     if (lpmsInfo->
handle < 0) {
 
   85     uint8_t rateData[4] = {
 
   88         (lpmsInfo->
pollFreq & 0xFF0000) >> 16,
 
   89         (lpmsInfo->
pollFreq & 0xFF000000) >> 24,
 
   93                             .length = 
sizeof(uint32_t),
 
  101     const uint32_t outputs =
 
  106     uint8_t outputData[4] = {(outputs & 0xFF), (outputs & 0xFF00) >> 8,
 
  107                              (outputs & 0xFF0000) >> 16, (outputs & 0xFF000000) >> 24};
 
  111                                    .length = 
sizeof(uint32_t),
 
  139     if (m == NULL) { 
return false; }
 
  167     uint8_t *buf = calloc(
LPMS_BUFF, 
sizeof(uint8_t));
 
  170     uint32_t outputs = 0;
 
  171     bool unitMismatch = 
false;
 
  172     unsigned int pendingCount = 0;
 
  173     unsigned int missingCount = 0;
 
  178             perror(
"lpms_message calloc");
 
  191             if ((m->
id != lpmsInfo->
unitID) && !unitMismatch) {
 
  194                     "[LPMS:%s] Unexpected unit ID (got 0x%02x, expected 0x%02x)",
 
  200                             ((uint32_t)m->
data[2] << 16) +
 
  201                             ((uint32_t)m->
data[3] << 24);
 
  204                          "[LPMS:%s] Output configuration received for unit 0x%02x",
 
  208                          "[LPMS:%s] Unit 0x%02x: Sensor model: %-24s", args->
tag,
 
  211                 int sl = asprintf(&lm, 
"LPMS Unit 0x%02x: Sensor model: %-24s",
 
  219                               "[LPMS:%s] Error pushing message to queue",
 
  227                          "[LPMS:%s] Unit 0x%02x: Serial number: %-24s", args->
tag,
 
  230                 int sl = asprintf(&lm, 
"LPMS Unit 0x%02x: Serial number: %-24s",
 
  238                               "[LPMS:%s] Error pushing message to queue",
 
  246                          "[LPMS:%s] Unit 0x%02x: Firmware version: %-24s",
 
  249                 int sl = asprintf(&lm, 
"LPMS Unit 0x%02x: Firmware version: %-24s",
 
  257                               "[LPMS:%s] Error pushing message to queue",
 
  264                 uint32_t rate = m->
data[0] + ((uint32_t)m->
data[1] << 8) +
 
  265                                 ((uint32_t)m->
data[2] << 16) +
 
  266                                 ((uint32_t)m->
data[3] << 24);
 
  268                          "[LPMS:%s] Unit 0x%02x: Message rate %dHz", args->
tag,
 
  273                     if ((pendingCount++ % 100) == 0) {
 
  276                             "[LPMS:%s] No output configuration received - skipping messages (%d skipped so far)",
 
  277                             args->
tag, pendingCount);
 
  279                                  "[LPMS:%s] Repeating GET_OUTPUTS request",
 
  297                             "[LPMS:%s] Error pushing message to queue",
 
  307                                 "[LPMS:%s] Unit 0x%02x: Timestamp invalid",
 
  328                     if (missingCount == 0) {
 
  331                             "[LPMS:%s] Unit 0x%02x: Some data missing in update",
 
  371                                          CHAN_OMEGA_X, d.
omega[0]);
 
  373                                          CHAN_OMEGA_Y, d.
omega[1]);
 
  375                                          CHAN_OMEGA_Z, d.
omega[2]);
 
  393                         "[LPMS:%s] Unable to allocate and/or queue all messages (%d)",
 
  402                          "[LPSM:%s] Unhandled message type: 0x%02x [%02d bytes]",
 
  427     if (lpmsInfo->
handle >= 0) { 
 
  454         .
portName = NULL, .baudRate = 921600, .handle = -1, .unitID = 1, .pollFreq = 10};
 
  474         log_error(args->
pstate, 
"[LPMS:%s] Error pushing channel name to queue",
 
  540         log_error(lta->
pstate, 
"[LPMS:%s] Unable to allocate memory for device parameters",
 
  560         int sn = strtol(t->
value, NULL, 0);
 
  563                       lta->
tag, strerror(errno));
 
  580                     "[LPMS:%s] Unexpected Source ID number (0x%02x)- this may cause analysis problems",
 
  586         log_warning(lta->
pstate, 
"[LPMS:%s] Source number not provided - 0x%02x assigned",
 
  611         if ((lpmsInfo->
unitID <= 0) || (lpmsInfo->
unitID > 255)) {
 
  613                       "[LPMS:%s] Unit ID specified (%d not in range 1-255)", lta->
tag,
 
  626                       "[LPMS:%s] Error parsing minimum poll frequency: %s", lta->
tag,
 
  643                     "[LPMS:%s] Invalid minimum poll frequency (%d is not greater than zero)",
 
bool lpms_readMessage_buf(int handle, lpms_message *out, uint8_t buf[LPMS_BUFF], size_t *index, size_t *hw)
Read data from handle, and parse message if able.
 
bool lpms_send_command(const int handle, lpms_message *m)
Write command defined by structure to handle.
 
#define LPMS_BUFF
Default serial buffer allocation size.
 
int lpms_openConnection(const char *device, const int baud)
Open connection to an LPMS serial device.
 
bool lpms_send_stream_mode(const int handle)
Shortcut: Send LPMS_MSG_MODE_STREAM.
 
bool lpms_send_command_mode(const int handle)
Shortcut: Send LPMS_MSG_MODE_CMD.
 
bool lpms_checksum(const lpms_message *msg, uint16_t *csum)
Calculate checksum for LPMS message packet.
 
bool lpms_imu_set_gyro_aligned(const lpms_message *msg, lpms_data *d)
Extract gyro_aligned from lpms_message into lpms_data, if available.
 
bool lpms_imu_set_altitude(const lpms_message *msg, lpms_data *d)
Extract altitude from lpms_message into lpms_data, if available.
 
bool lpms_imu_set_euler_angles(const lpms_message *msg, lpms_data *d)
Extract euler_angles from lpms_message into lpms_data, if available.
 
bool lpms_imu_set_gyro_raw(const lpms_message *msg, lpms_data *d)
Extract gyro_raw from lpms_message into lpms_data, if available.
 
bool lpms_imu_set_accel_raw(const lpms_message *msg, lpms_data *d)
Extract accel_raw from lpms_message into lpms_data, if available.
 
bool lpms_imu_set_timestamp(const lpms_message *msg, lpms_data *d)
Extract timestamp from lpms_message into lpms_data, if available.
 
bool lpms_imu_set_accel_cal(const lpms_message *msg, lpms_data *d)
Extract accel_cal from lpms_message into lpms_data, if available.
 
bool lpms_imu_set_gyro_cal(const lpms_message *msg, lpms_data *d)
Extract gyro_cal from lpms_message into lpms_data, if available.
 
bool lpms_imu_set_accel_linear(const lpms_message *msg, lpms_data *d)
Extract accel_linear from lpms_message into lpms_data, if available.
 
bool lpms_imu_set_omega(const lpms_message *msg, lpms_data *d)
Extract omega from lpms_message into lpms_data, if available.
 
char * config_qstrdup(const char *c)
Duplicate string, stripping optional leading/trailing quote marks.
 
config_kv * config_get_key(const config_section *cs, const char *kn)
Find configugration key within specific section, by name.
 
void signalHandlersBlock(void)
Block signals that we have handlers for.
 
#define LPMS_IMU_EULER
euler[] will contain data
 
#define LPMS_IMU_ACCEL_LINEAR
accel_linear[] will contain data
 
#define LPMS_IMU_OMEGA
omega[] will contain data
 
#define LPMS_IMU_ACCEL_CAL
accel_cal[] will contain data
 
#define LPMS_IMU_GYRO_ALIGN
gyro_align[] will contain data
 
#define LPMS_IMU_ALTITUDE
altitude will contain data
 
#define LPMS_IMU_GYRO_CAL
gyro_cal[] will contain data
 
#define LPMS_IMU_GYRO_RAW
gyro_raw[] will contain data
 
#define LPMS_IMU_ACCEL_RAW
accel_raw[] will contain data
 
#define LPMS_MSG_SET_OUTPUTS
Configure fields included in IMUDATA messages.
 
#define LPMS_MSG_GET_OUTPUTS
Get fields configured for IMUDATA messages.
 
#define LPMS_MSG_GET_SERIALNUM
Get serial number as 24 character string.
 
#define LPMS_MSG_GET_FREQ
Get current streaming output rate.
 
#define LPMS_MSG_GET_IMUDATA
IMU data, as configured by LPMS_MSG_SET_OUTPUTS.
 
#define LPMS_MSG_GET_FIRMWAREVER
Get firmware version as 24 character string.
 
#define LPMS_MSG_GET_SENSORMODEL
Get hardware model as 24 character string.
 
#define LPMS_MSG_SET_FREQ
Set streaming output rate (Hz)
 
msg_t * msg_new_string(const uint8_t source, const uint8_t type, const size_t len, const char *str)
Create a new message with a single string embedded.
 
void msg_destroy(msg_t *msg)
Destroy a message.
 
msg_t * msg_new_string_array(const uint8_t source, const uint8_t type, const strarray *array)
Create a new message containing an array of strings.
 
msg_t * msg_new_timestamp(const uint8_t source, const uint8_t type, const uint32_t ts)
Create a timestamp message.
 
msg_t * msg_new_float(const uint8_t source, const uint8_t type, const float val)
Create new message with a single numeric value.
 
#define SLCHAN_TSTAMP
Source timestamp (milliseconds, arbitrary epoch)
 
#define SLCHAN_RAW
Raw device data (Not mandatory)
 
#define SLCHAN_LOG_INFO
Information messages.
 
#define SLCHAN_MAP
Channel name map (excludes log channels)
 
#define SLCHAN_NAME
Name of source device.
 
bool lpms_parseConfig(log_thread_args_t *lta, config_section *s)
Take a configuration section and parse parameters.
 
void * lpms_logging(void *ptargs)
Serial source main logging loop.
 
bool lpms_queue_message(msgqueue *Q, const uint8_t src, const uint8_t chan, const float val)
Helper function: Create and queue data messages, with error handling.
 
void * lpms_channels(void *ptargs)
Serial source channel map.
 
void * lpms_setup(void *ptargs)
Generic serial connection setup.
 
device_callbacks lpms_getCallbacks()
Fill out device callback functions for logging.
 
lpms_params lpms_getParams()
Fill out default MP source parameters.
 
void * lpms_shutdown(void *ptargs)
Serial source shutdown.
 
#define SLSOURCE_ADC
Generic analogue inputs.
 
atomic_bool shutdownFlag
Trigger clean software shutdown.
 
void log_info(const program_state *s, const int level, const char *format,...)
Output formatted information message at a given level.
 
void log_warning(const program_state *s, const char *format,...)
Output formatted warning message.
 
void log_error(const program_state *s, const char *format,...)
Output formatted error message.
 
bool queue_push(msgqueue *queue, msg_t *msg)
Add a message to the tail of the queue.
 
void sa_destroy(strarray *sa)
Destroy array and contents.
 
strarray * sa_new(int entries)
Allocate storage for a new array.
 
bool sa_create_entry(strarray *array, const int index, const size_t len, const char *src)
Create an string in a given position from a character array and length.
 
Represent a key=value pair.
 
char * value
Configuration item value.
 
Configuration file section.
 
Device specific function information.
 
device_fn startup
Called serially at startup, opens devices etc.
 
Logging thread information.
 
msgqueue * logQ
Main message queue. Pushed to by threads, consumed by main()
 
char * tag
Tag/source name for messages etc.
 
void * dParams
Device/Thread specific data.
 
program_state * pstate
Current program state, used for logging.
 
int returnCode
Thread return code (output)
 
float euler_angles[3]
Orientation as Euler roll angles [X].
 
float altitude
Altitude [m].
 
float gyro_aligned[3]
Calibrated and aligned gyroscope values [X/s].
 
float gyro_raw[3]
Raw gyroscope values [X/s].
 
float accel_linear[3]
Linear acceleration (only) [g].
 
uint32_t timestamp
Counted in 0.002s increments.
 
float accel_cal[3]
Calibrated accelerometer values [g].
 
float gyro_cal[3]
Calibrated gyroscope values [X/s].
 
float accel_raw[3]
Raw accelerometer values [g].
 
float omega[3]
Angular velocity [X/s].
 
uint32_t present
Bitmask indicating set/valid members.
 
uint16_t length
Length of data, in bytes.
 
uint16_t checksum
Sum of all preceding message bytes.
 
uint8_t * data
Pointer to data array.
 
uint16_t id
Source/Destination Sensor ID.
 
uint16_t command
Message type.
 
Serial device specific parameters.
 
int unitID
LPMS Sensor Address.
 
int pollFreq
Desired number of measurements per second.
 
int baudRate
Baud rate for operations (Default 921600)
 
int handle
Handle for currently opened device.
 
char * sourceName
User defined name for this source.
 
char * portName
Target port name.
 
uint8_t sourceNum
Source ID for messages.
 
Represent a simple FIFO message queue.