Beispiel #1
0
static bool
pressure_create_channels(struct iio_double_data *mdata, int device_id)
{
    struct sol_iio_channel_config channel_config = SOL_IIO_CHANNEL_CONFIG_INIT;

    mdata->iio_base.device = sol_iio_open(device_id, &mdata->iio_base.config);
    SOL_NULL_CHECK(mdata->iio_base.device, false);

#define ADD_CHANNEL(_val) \
    if (!mdata->iio_base.use_device_default_scale) \
        channel_config.scale = mdata->scale; \
    if (!mdata->iio_base.use_device_default_offset) \
        channel_config.offset = mdata->offset; \
    mdata->channel_ ## _val = sol_iio_add_channel(mdata->iio_base.device, "in_pressure", &channel_config); \
    SOL_NULL_CHECK_GOTO(mdata->channel_ ## _val, error);

    ADD_CHANNEL(val);

#undef ADD_CHANNEL

    sol_iio_device_start_buffer(mdata->iio_base.device);

    return true;

error:
    SOL_WRN("Could not create iio/pressure node. Failed to open IIO device %d",
        device_id);

    sol_iio_close(mdata->iio_base.device);
    return false;
}
Beispiel #2
0
static void
iio_direction_vector_reader_cb(void *data, struct sol_iio_device *device)
{
    static const char *errmsg = "Could not read channel buffer values";
    struct sol_flow_node *node = data;
    struct iio_direction_vector_data *mdata = sol_flow_node_get_private_data(node);
    struct sol_direction_vector out = {
        .min = mdata->iio_base.out_range.min,
        .max = mdata->iio_base.out_range.max
    };
    int r;
    struct iio_node_type *type;

    type = (struct iio_node_type *)sol_flow_node_get_type(node);

    r = sol_iio_read_channel_value(mdata->channel_x, &out.x);
    SOL_INT_CHECK_GOTO(r, < 0, error);

    r = sol_iio_read_channel_value(mdata->channel_y, &out.y);
    SOL_INT_CHECK_GOTO(r, < 0, error);

    r = sol_iio_read_channel_value(mdata->channel_z, &out.z);
    SOL_INT_CHECK_GOTO(r, < 0, error);

    sol_flow_send_direction_vector_packet(node, type->out_port, &out);

    return;

error:
    sol_flow_send_error_packet_str(node, EIO, errmsg);
    SOL_WRN("%s", errmsg);
}

static void
iio_double_reader_cb(void *data, struct sol_iio_device *device)
{
    static const char *errmsg = "Could not read channel buffer values";
    struct sol_flow_node *node = data;
    struct iio_double_data *mdata = sol_flow_node_get_private_data(node);
    struct sol_drange out = {
        .min = mdata->iio_base.out_range.min,
        .max = mdata->iio_base.out_range.max,
        .step = mdata->iio_base.out_range.step
    };

    int r;
    struct iio_node_type *type;

    type = (struct iio_node_type *)sol_flow_node_get_type(node);

    r = sol_iio_read_channel_value(mdata->channel_val, &out.val);
    SOL_INT_CHECK_GOTO(r, < 0, error);

    sol_flow_send_drange_value_packet(node, type->out_port, out.val);

    return;

error:
    sol_flow_send_error_packet_str(node, EIO, errmsg);
    SOL_WRN("%s", errmsg);
}

static void
iio_color_reader_cb(void *data, struct sol_iio_device *device)
{
    static const char *errmsg = "Could not read channel buffer values";
    struct sol_flow_node *node = data;
    struct iio_color_data *mdata = sol_flow_node_get_private_data(node);
    struct sol_rgb out = {
        .red_max = mdata->iio_base.out_range.max,
        .green_max = mdata->iio_base.out_range.max,
        .blue_max = mdata->iio_base.out_range.max
    };
    double tmp;
    int r;
    struct iio_node_type *type;

    type = (struct iio_node_type *)sol_flow_node_get_type(node);

    r = sol_iio_read_channel_value(mdata->channel_red, &tmp);
    if (r < 0 || tmp < 0 || tmp > UINT32_MAX) goto error;
    out.red = tmp;

    r = sol_iio_read_channel_value(mdata->channel_green, &tmp);
    if (r < 0 || tmp < 0 || tmp > UINT32_MAX) goto error;
    out.green = tmp;

    r = sol_iio_read_channel_value(mdata->channel_blue, &tmp);
    if (r < 0 || tmp < 0 || tmp > UINT32_MAX) goto error;
    out.blue = tmp;

    sol_flow_send_rgb_packet(node, type->out_port, &out);

    return;

error:
    sol_flow_send_error_packet_str(node, EIO, errmsg);
    SOL_WRN("%s", errmsg);
}

static bool
gyroscope_create_channels(struct iio_direction_vector_data *mdata, int device_id)
{
    struct sol_iio_channel_config channel_config = SOL_IIO_CHANNEL_CONFIG_INIT;

    mdata->iio_base.device = sol_iio_open(device_id, &mdata->iio_base.config);
    SOL_NULL_CHECK(mdata->iio_base.device, false);

#define ADD_CHANNEL(_axis) \
    if (!mdata->iio_base.use_device_default_scale) \
        channel_config.scale = mdata->scale._axis; \
    if (!mdata->iio_base.use_device_default_offset) \
        channel_config.offset = mdata->offset._axis; \
    mdata->channel_ ## _axis = sol_iio_add_channel(mdata->iio_base.device, "in_anglvel_" # _axis, &channel_config); \
    SOL_NULL_CHECK_GOTO(mdata->channel_ ## _axis, error);

    ADD_CHANNEL(x);
    ADD_CHANNEL(y);
    ADD_CHANNEL(z);

#undef ADD_CHANNEL

    sol_iio_device_start_buffer(mdata->iio_base.device);

    return true;

error:
    SOL_WRN("Could not create iio/gyroscope node. Failed to open IIO device %d",
        device_id);
    sol_iio_close(mdata->iio_base.device);
    return false;
}

static int
gyroscope_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options)
{
    struct iio_direction_vector_data *mdata = data;
    const struct sol_flow_node_type_iio_gyroscope_options *opts;
    int device_id;
    struct iio_node_type *type;

    type = (struct iio_node_type *)sol_flow_node_get_type(node);

    SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_IIO_GYROSCOPE_OPTIONS_API_VERSION,
        -EINVAL);
    opts = (const struct sol_flow_node_type_iio_gyroscope_options *)options;

    mdata->iio_base.buffer_enabled = opts->buffer_size > -1;

    SOL_SET_API_VERSION(mdata->iio_base.config.api_version = SOL_IIO_CONFIG_API_VERSION; )

    if (opts->iio_trigger_name) {
        mdata->iio_base.config.trigger_name = strdup(opts->iio_trigger_name);
        SOL_NULL_CHECK(mdata->iio_base.config.trigger_name, -ENOMEM);
    }

    mdata->iio_base.config.buffer_size = opts->buffer_size;
    mdata->iio_base.config.sampling_frequency = opts->sampling_frequency;

    if (mdata->iio_base.buffer_enabled) {
        mdata->iio_base.config.sol_iio_reader_cb = type->reader_cb;
        mdata->iio_base.config.data = node;
    }
    mdata->iio_base.use_device_default_scale = opts->use_device_default_scale;
    mdata->iio_base.use_device_default_offset = opts->use_device_default_offset;
    mdata->scale = opts->scale;
    mdata->offset = opts->offset;
    mdata->iio_base.out_range = opts->out_range;

    device_id = sol_iio_address_device(opts->iio_device);
    if (device_id < 0) {
        SOL_WRN("Could not create iio/gyroscope node. Failed to open IIO device %s",
            opts->iio_device);
        goto err;
    }

    if (!gyroscope_create_channels(mdata, device_id))
        goto err;

    return 0;

err:
    free((char *)mdata->iio_base.config.trigger_name);
    return -EINVAL;
}

static bool
magnet_create_channels(struct iio_direction_vector_data *mdata, int device_id)
{
    struct sol_iio_channel_config channel_config = SOL_IIO_CHANNEL_CONFIG_INIT;

    mdata->iio_base.device = sol_iio_open(device_id, &mdata->iio_base.config);
    SOL_NULL_CHECK(mdata->iio_base.device, false);

#define ADD_CHANNEL(_axis) \
    if (!mdata->iio_base.use_device_default_scale) \
        channel_config.scale = mdata->scale._axis; \
    if (!mdata->iio_base.use_device_default_offset) \
        channel_config.offset = mdata->offset._axis; \
    mdata->channel_ ## _axis = sol_iio_add_channel(mdata->iio_base.device, "in_magn_" # _axis, &channel_config); \
    SOL_NULL_CHECK_GOTO(mdata->channel_ ## _axis, error);

    ADD_CHANNEL(x);
    ADD_CHANNEL(y);
    ADD_CHANNEL(z);

#undef ADD_CHANNEL

    sol_iio_device_start_buffer(mdata->iio_base.device);

    return true;

error:
    SOL_WRN("Could not create iio/magnet node. Failed to open IIO device %d",
        device_id);
    sol_iio_close(mdata->iio_base.device);
    return false;
}

static int
magnet_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options)
{
    struct iio_direction_vector_data *mdata = data;
    const struct sol_flow_node_type_iio_magnetometer_options *opts;
    int device_id;
    struct iio_node_type *type;

    type = (struct iio_node_type *)sol_flow_node_get_type(node);

    SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_IIO_MAGNETOMETER_OPTIONS_API_VERSION,
        -EINVAL);
    opts = (const struct sol_flow_node_type_iio_magnetometer_options *)options;

    mdata->iio_base.buffer_enabled = opts->buffer_size > -1;

    SOL_SET_API_VERSION(mdata->iio_base.config.api_version = SOL_IIO_CONFIG_API_VERSION; )

    if (opts->iio_trigger_name) {
        mdata->iio_base.config.trigger_name = strdup(opts->iio_trigger_name);
        SOL_NULL_CHECK(mdata->iio_base.config.trigger_name, -ENOMEM);
    }

    mdata->iio_base.config.buffer_size = opts->buffer_size;
    mdata->iio_base.config.sampling_frequency = opts->sampling_frequency;
    if (mdata->iio_base.buffer_enabled) {
        mdata->iio_base.config.sol_iio_reader_cb = type->reader_cb;
        mdata->iio_base.config.data = node;
    }
    mdata->iio_base.use_device_default_scale = opts->use_device_default_scale;
    mdata->iio_base.use_device_default_offset = opts->use_device_default_offset;
    mdata->scale = opts->scale;
    mdata->offset = opts->offset;
    mdata->iio_base.out_range = opts->out_range;

    device_id = sol_iio_address_device(opts->iio_device);
    if (device_id < 0) {
        SOL_WRN("Could not create iio/magnet node. Failed to open IIO device %s",
            opts->iio_device);
        goto err;
    }

    if (!magnet_create_channels(mdata, device_id))
        goto err;

    return 0;

err:
    free((char *)mdata->iio_base.config.trigger_name);
    return -EINVAL;
}

static bool
temp_create_channels(struct iio_double_data *mdata, int device_id)
{
    struct sol_iio_channel_config channel_config = SOL_IIO_CHANNEL_CONFIG_INIT;

    mdata->iio_base.device = sol_iio_open(device_id, &mdata->iio_base.config);
    SOL_NULL_CHECK(mdata->iio_base.device, false);

#define ADD_CHANNEL(_val) \
    if (!mdata->iio_base.use_device_default_scale) \
        channel_config.scale = mdata->scale; \
    if (!mdata->iio_base.use_device_default_offset) \
        channel_config.offset = mdata->offset; \
    mdata->channel_ ## _val = sol_iio_add_channel(mdata->iio_base.device, "in_temp", &channel_config); \
    SOL_NULL_CHECK_GOTO(mdata->channel_ ## _val, error);

    ADD_CHANNEL(val);

#undef ADD_CHANNEL

    sol_iio_device_start_buffer(mdata->iio_base.device);

    return true;

error:
    SOL_WRN("Could not create iio/thermometer node. Failed to open"
        " IIO device %d", device_id);

    sol_iio_close(mdata->iio_base.device);
    return false;
}

static int
temperature_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options)
{
    struct iio_double_data *mdata = data;
    const struct sol_flow_node_type_iio_thermometer_options *opts;
    int device_id;
    struct iio_node_type *type;

    type = (struct iio_node_type *)sol_flow_node_get_type(node);

    SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_IIO_THERMOMETER_OPTIONS_API_VERSION,
        -EINVAL);
    opts = (const struct sol_flow_node_type_iio_thermometer_options *)options;

    mdata->iio_base.buffer_enabled = opts->buffer_size > -1;

    SOL_SET_API_VERSION(mdata->iio_base.config.api_version = SOL_IIO_CONFIG_API_VERSION; )

    if (opts->iio_trigger_name) {
        mdata->iio_base.config.trigger_name = strdup(opts->iio_trigger_name);
        SOL_NULL_CHECK(mdata->iio_base.config.trigger_name, -ENOMEM);
    }

    mdata->iio_base.config.buffer_size = opts->buffer_size;
    mdata->iio_base.config.sampling_frequency = opts->sampling_frequency;
    if (mdata->iio_base.buffer_enabled) {
        mdata->iio_base.config.sol_iio_reader_cb = type->reader_cb;
        mdata->iio_base.config.data = node;
    }
    mdata->iio_base.use_device_default_scale = opts->use_device_default_scale;
    mdata->iio_base.use_device_default_offset = opts->use_device_default_offset;
    mdata->scale = opts->scale;
    mdata->offset = opts->offset;
    mdata->iio_base.out_range = opts->out_range;

    device_id = sol_iio_address_device(opts->iio_device);
    if (device_id < 0) {
        SOL_WRN("Could not create iio/thermometer node. Failed to"
            " open IIO device %s", opts->iio_device);
        goto err;
    }

    if (!temp_create_channels(mdata, device_id))
        goto err;

    return 0;

err:
    free((char *)mdata->iio_base.config.trigger_name);
    return -EINVAL;

}
Beispiel #3
0
/*
  call-seq: track_get_audio_channel_map() -> array
    
    Returns an array n-channels in length
    Array contains Hashes in the form: {:assignment => :description} where :description is a symbol representing an audio channel description.  eg. :Left, :Right, :Mono
  
*/
static VALUE track_get_audio_channel_map(VALUE obj)
{
  AudioChannelLayout *layout = track_get_audio_channel_layout(obj);
  if (layout == NULL) return Qnil;
  
  VALUE channels = Qnil;
  UInt32 numChannels, x, highLayoutTag;
  VALUE channel;
  char message[256];
  AudioChannelLayoutTag layoutTag = layout->mChannelLayoutTag;
  
  if (layoutTag == kAudioChannelLayoutTag_UseChannelDescriptions) {
    // using the descriptions
    // not implemented
    numChannels = layout->mNumberChannelDescriptions;
    channels = rb_ary_new2(numChannels);
    
    // loop through all channels, adding assignment descriptions
    AudioChannelDescription desc;
    char *trackStr;
    for (x=0; x < numChannels; x++) {
      desc = layout->mChannelDescriptions[x];
      trackStr = track_str_for_AudioChannelLabel(desc.mChannelLabel);

      if (trackStr != NULL) {
        ADD_CHANNEL(channels, channel, trackStr);

      } else {
         // unsupported audio channel labels
         ADD_CHANNEL(channels, channel, "UnsupportedByRMov");
         sprintf(message, "ChannelLabel unsupported by rmov: %d", (int)desc.mChannelLabel);
         rb_hash_aset(channel, ID2SYM(rb_intern("message")), rb_str_new2(message));
      }
    }
    

  } else {
    numChannels = AudioChannelLayoutTag_GetNumberOfChannels(layoutTag);
    channels = rb_ary_new2(numChannels);

    if (layoutTag == kAudioChannelLayoutTag_UseChannelBitmap) {
      // use the bitmap approach
      // not implemented
      //rb_raise(eQuickTime, "Not Implemented: kAudioChannelLayoutTag_UseChannelBitmap in track_get_audio_channel_map");
      for (x=0; x < numChannels; x++) {
        ADD_CHANNEL(channels, channel, "UnsupportedByRMov");
        rb_hash_aset(channel, ID2SYM(rb_intern("message")), rb_str_new2("UseChannelBitmap unsupported by rmov"));
      }



    } else {
      // using a standard LayoutTag
      switch (layoutTag) {

        case kAudioChannelLayoutTag_Mono:
          ADD_CHANNEL(channels, channel, "Mono");
          break;
        
        case kAudioChannelLayoutTag_Stereo:
          ADD_CHANNEL(channels, channel, "Left");
          ADD_CHANNEL(channels, channel, "Right");
          break;
          
        case kAudioChannelLayoutTag_MatrixStereo:
          ADD_CHANNEL(channels, channel, "LeftTotal");
          ADD_CHANNEL(channels, channel, "RightTotal");
          break;
          
        case kAudioChannelLayoutTag_SMPTE_DTV:
          ADD_CHANNEL(channels, channel, "Left");
          ADD_CHANNEL(channels, channel, "Right");
          ADD_CHANNEL(channels, channel, "Center");
          ADD_CHANNEL(channels, channel, "LFEScreen");
          ADD_CHANNEL(channels, channel, "LeftSurround");
          ADD_CHANNEL(channels, channel, "RightSurround");
          ADD_CHANNEL(channels, channel, "LeftTotal");
          ADD_CHANNEL(channels, channel, "RightTotal");
          break;

        default:
          // unsupported channels
          highLayoutTag = (layoutTag & 0xff0000) >> 16;
          sprintf(message, "layoutTag unsupported by rmov: (%dL << 16) | %d", (int)highLayoutTag, (int)numChannels);
          for (x=0; x < numChannels; x++) {
            ADD_CHANNEL(channels, channel, "UnsupportedByRMov");
            rb_hash_aset(channel, ID2SYM(rb_intern("message")), rb_str_new2(message));
          }
          //rb_raise(eQuickTime, "Unsupported ChannelLayoutTag in track_get_audio_channel_map: %d", layoutTag);
          break;
      }

    }

  }
  
  free(layout);
  
  return channels;
}
Beispiel #4
0
static void
humidity_reader_cb(void *data, struct sol_iio_device *device)
{
    static const char *errmsg = "Could not read channel buffer values";
    struct sol_flow_node *node = data;
    struct humidity_data *mdata = sol_flow_node_get_private_data(node);
    struct sol_drange out = {
        .min = mdata->out_range.min,
        .max = mdata->out_range.max,
        .step = mdata->out_range.step
    };
    bool b;

    b = sol_iio_read_channel_value(mdata->channel_val, &out.val);
    if (!b) goto error;

    sol_flow_send_drange_value_packet(node,
        SOL_FLOW_NODE_TYPE_IIO_HUMIDITY_SENSOR__OUT__OUT, out.val);

    return;

error:
    sol_flow_send_error_packet_str(node, EIO, errmsg);
    SOL_WRN("%s", errmsg);
}

static bool
humidity_create_channels(struct humidity_data *mdata, int device_id)
{
    struct sol_iio_channel_config channel_config = SOL_IIO_CHANNEL_CONFIG_INIT;

    mdata->device = sol_iio_open(device_id, &mdata->config);
    SOL_NULL_CHECK(mdata->device, false);

#define ADD_CHANNEL(_val) \
    if (!mdata->use_device_default_scale) \
        channel_config.scale = mdata->scale; \
    if (!mdata->use_device_default_offset) \
        channel_config.offset = mdata->offset; \
    mdata->channel_ ## _val = sol_iio_add_channel(mdata->device, "in_humidityrelative", &channel_config); \
    SOL_NULL_CHECK_GOTO(mdata->channel_ ## _val, error);

    ADD_CHANNEL(val);

#undef ADD_CHANNEL

    sol_iio_device_start_buffer(mdata->device);

    return true;

error:
    SOL_WRN("Could not create iio/humidity node. Failed to open IIO device %d",
        device_id);

    sol_iio_close(mdata->device);
    return false;
}

static int
humidity_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options)
{
    struct humidity_data *mdata = data;
    const struct sol_flow_node_type_iio_humidity_sensor_options *opts;
    int device_id;

    SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_IIO_HUMIDITY_SENSOR_OPTIONS_API_VERSION,
        -EINVAL);
    opts = (const struct sol_flow_node_type_iio_humidity_sensor_options *)options;

    mdata->buffer_enabled = opts->buffer_size > -1;

    SOL_SET_API_VERSION(mdata->config.api_version = SOL_IIO_CONFIG_API_VERSION; )

    if (opts->iio_trigger_name) {
        mdata->config.trigger_name = strdup(opts->iio_trigger_name);
        SOL_NULL_CHECK(mdata->config.trigger_name, -ENOMEM);
    }

    mdata->config.buffer_size = opts->buffer_size;
    mdata->config.sampling_frequency = opts->sampling_frequency;
    if (mdata->buffer_enabled) {
        mdata->config.sol_iio_reader_cb = humidity_reader_cb;
        mdata->config.data = node;
    }
    mdata->use_device_default_scale = opts->use_device_default_scale;
    mdata->use_device_default_offset = opts->use_device_default_offset;
    mdata->scale = opts->scale;
    mdata->offset = opts->offset;
    mdata->out_range = opts->out_range;

    device_id = sol_iio_address_device(opts->iio_device);
    if (device_id < 0) {
        SOL_WRN("Could not create iio/humidity node. Failed to open IIO device %s",
            opts->iio_device);
        goto err;
    }

    if (!humidity_create_channels(mdata, device_id))
        goto err;

    return 0;

err:
    free((char *)mdata->config.trigger_name);
    return -EINVAL;

}
Beispiel #5
0
static void
accelerate_reader_cb(void *data, struct sol_iio_device *device)
{
    static const char *errmsg = "Could not read channel buffer values";
    struct sol_flow_node *node = data;
    struct accelerate_data *mdata = sol_flow_node_get_private_data(node);
    struct sol_direction_vector out = {
        .min = mdata->out_range.min,
        .max = mdata->out_range.max
    };
    bool b;

    b = sol_iio_read_channel_value(mdata->channel_x, &out.x);
    if (!b) goto error;

    b = sol_iio_read_channel_value(mdata->channel_y, &out.y);
    if (!b) goto error;

    b = sol_iio_read_channel_value(mdata->channel_z, &out.z);
    if (!b) goto error;

    sol_flow_send_direction_vector_packet(node,
        SOL_FLOW_NODE_TYPE_IIO_ACCELEROMETER__OUT__OUT, &out);

    return;

error:
    sol_flow_send_error_packet_str(node, EIO, errmsg);
    SOL_WRN("%s", errmsg);
}

static bool
accelerate_create_channels(struct accelerate_data *mdata, int device_id)
{
    struct sol_iio_channel_config channel_config = SOL_IIO_CHANNEL_CONFIG_INIT;

    mdata->device = sol_iio_open(device_id, &mdata->config);
    SOL_NULL_CHECK(mdata->device, false);

#define ADD_CHANNEL(_axis) \
    if (!mdata->use_device_default_scale) \
        channel_config.scale = mdata->scale._axis; \
    if (!mdata->use_device_default_offset) \
        channel_config.offset = mdata->offset._axis; \
    mdata->channel_ ## _axis = sol_iio_add_channel(mdata->device, "in_accel_" # _axis, &channel_config); \
    SOL_NULL_CHECK_GOTO(mdata->channel_ ## _axis, error);

    ADD_CHANNEL(x);
    ADD_CHANNEL(y);
    ADD_CHANNEL(z);

#undef ADD_CHANNEL

    sol_iio_device_start_buffer(mdata->device);

    return true;

error:
    SOL_WRN("Could not create iio/accelerate node. Failed to open IIO device %d",
        device_id);
    sol_iio_close(mdata->device);
    return false;
}

static int
accelerate_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options)
{
    struct accelerate_data *mdata = data;
    const struct sol_flow_node_type_iio_accelerometer_options *opts;
    int device_id;

    SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_IIO_ACCELEROMETER_OPTIONS_API_VERSION,
        -EINVAL);
    opts = (const struct sol_flow_node_type_iio_accelerometer_options *)options;

    mdata->buffer_enabled = opts->buffer_size > -1;

    SOL_SET_API_VERSION(mdata->config.api_version = SOL_IIO_CONFIG_API_VERSION; )

    if (opts->iio_trigger_name) {
        mdata->config.trigger_name = strdup(opts->iio_trigger_name);
        SOL_NULL_CHECK(mdata->config.trigger_name, -ENOMEM);
    }

    mdata->config.buffer_size = opts->buffer_size;
    mdata->config.sampling_frequency = opts->sampling_frequency;
    if (mdata->buffer_enabled) {
        mdata->config.sol_iio_reader_cb = accelerate_reader_cb;
        mdata->config.data = node;
    }
    mdata->use_device_default_scale = opts->use_device_default_scale;
    mdata->use_device_default_offset = opts->use_device_default_offset;
    mdata->scale = opts->scale;
    mdata->offset = opts->offset;
    mdata->out_range = opts->out_range;

    device_id = sol_iio_address_device(opts->iio_device);
    if (device_id < 0) {
        SOL_WRN("Could not create iio/accelerate node. Failed to open IIO device %s",
            opts->iio_device);
        goto err;
    }

    if (!accelerate_create_channels(mdata, device_id))
        goto err;

    return 0;

err:
    free((char *)mdata->config.trigger_name);
    return -EINVAL;
}
Beispiel #6
0
static void
color_reader_cb(void *data, struct sol_iio_device *device)
{
    static const char *errmsg = "Could not read channel buffer values";
    struct sol_flow_node *node = data;
    struct color_data *mdata = sol_flow_node_get_private_data(node);
    struct sol_rgb out = {
        .red_max = mdata->out_range.max,
        .green_max = mdata->out_range.max,
        .blue_max = mdata->out_range.max
    };
    double tmp;
    bool b;

    b = sol_iio_read_channel_value(mdata->channel_red, &tmp);
    if (!b || tmp < 0 || tmp > UINT32_MAX) goto error;
    out.red = tmp;

    b = sol_iio_read_channel_value(mdata->channel_green, &tmp);
    if (!b || tmp < 0 || tmp > UINT32_MAX) goto error;
    out.green = tmp;

    b = sol_iio_read_channel_value(mdata->channel_blue, &tmp);
    if (!b || tmp < 0 || tmp > UINT32_MAX) goto error;
    out.blue = tmp;

    sol_flow_send_rgb_packet(node,
        SOL_FLOW_NODE_TYPE_IIO_COLOR_SENSOR__OUT__OUT, &out);

    return;

error:
    sol_flow_send_error_packet_str(node, EIO, errmsg);
    SOL_WRN("%s", errmsg);
}

static bool
color_create_channels(struct color_data *mdata, int device_id)
{
    struct sol_iio_channel_config channel_config = SOL_IIO_CHANNEL_CONFIG_INIT;

    mdata->device = sol_iio_open(device_id, &mdata->config);
    SOL_NULL_CHECK(mdata->device, false);

#define ADD_CHANNEL(_axis) \
    if (!mdata->use_device_default_scale) \
        channel_config.scale = mdata->scale; \
    if (!mdata->use_device_default_offset) \
        channel_config.offset = mdata->offset; \
    mdata->channel_ ## _axis = sol_iio_add_channel(mdata->device, "in_intensity_" # _axis, &channel_config); \
    SOL_NULL_CHECK_GOTO(mdata->channel_ ## _axis, error);

    ADD_CHANNEL(red);
    ADD_CHANNEL(green);
    ADD_CHANNEL(blue);

#undef ADD_CHANNEL

    sol_iio_device_start_buffer(mdata->device);

    return true;

error:
    SOL_WRN("Could not create iio/color-sensor node. Failed to open IIO"
        " device %d", device_id);
    sol_iio_close(mdata->device);
    return false;
}

static int
color_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options)
{
    struct color_data *mdata = data;
    const struct sol_flow_node_type_iio_color_sensor_options *opts;
    int device_id;

    SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_IIO_COLOR_SENSOR_OPTIONS_API_VERSION,
        -EINVAL);
    opts = (const struct sol_flow_node_type_iio_color_sensor_options *)options;

    mdata->buffer_enabled = opts->buffer_size > -1;

    SOL_SET_API_VERSION(mdata->config.api_version = SOL_IIO_CONFIG_API_VERSION; )

    if (opts->iio_trigger_name) {
        mdata->config.trigger_name = strdup(opts->iio_trigger_name);
        SOL_NULL_CHECK(mdata->config.trigger_name, -ENOMEM);
    }

    mdata->config.buffer_size = opts->buffer_size;
    mdata->config.sampling_frequency = opts->sampling_frequency;
    if (mdata->buffer_enabled) {
        mdata->config.sol_iio_reader_cb = color_reader_cb;
        mdata->config.data = node;
    }
    mdata->use_device_default_scale = opts->use_device_default_scale;
    mdata->use_device_default_offset = opts->use_device_default_offset;
    mdata->scale = opts->scale;
    mdata->offset = opts->offset;
    mdata->out_range = opts->out_range;

    device_id = sol_iio_address_device(opts->iio_device);
    if (device_id < 0) {
        SOL_WRN("Could not create iio/color-sensor node. Failed to open"
            " IIO device %s", opts->iio_device);
        goto err;
    }

    if (!color_create_channels(mdata, device_id))
        goto err;

    return 0;

err:
    free((char *)mdata->config.trigger_name);
    return -EINVAL;
}