+ for (i = 0; i < num_samples; i++) {
+ t = (double) i / (double) sample_rate;
+ ag->pattern_data[i] = ANALOG_AMPLITUDE *
+ sin(2 * M_PI * frequency * t);
+ }
+
+ ag->num_samples = num_samples;
+ break;
+
+ case PATTERN_TRIANGLE:
+ frequency = (double) sample_rate / ANALOG_SAMPLES_PER_PERIOD;
+
+ while (num_samples % ANALOG_SAMPLES_PER_PERIOD != 0)
+ num_samples--;
+
+ for (i = 0; i < num_samples; i++) {
+ t = (double) i / (double) sample_rate;
+ ag->pattern_data[i] = (2 * ANALOG_AMPLITUDE / M_PI) *
+ asin(sin(2 * M_PI * frequency * t));
+ }
+
+ ag->num_samples = num_samples;
+ break;
+
+ case PATTERN_SAWTOOTH:
+ frequency = (double) sample_rate / ANALOG_SAMPLES_PER_PERIOD;
+
+ while (num_samples % ANALOG_SAMPLES_PER_PERIOD != 0)
+ num_samples--;
+
+ for (i = 0; i < num_samples; i++) {
+ t = (double) i / (double) sample_rate;
+ ag->pattern_data[i] = 2 * ANALOG_AMPLITUDE *
+ ((t * frequency) - floor(0.5f + t * frequency));
+ }
+
+ ag->num_samples = num_samples;
+ break;
+ }
+}
+
+static GSList *scan(GSList *options)
+{
+ struct drv_context *drvc;
+ struct dev_context *devc;
+ struct sr_dev_inst *sdi;
+ struct sr_channel *ch;
+ struct sr_channel_group *cg;
+ struct sr_config *src;
+ struct analog_gen *ag;
+ GSList *devices, *l;
+ int num_logic_channels, num_analog_channels, pattern, i;
+ char channel_name[16];
+
+ drvc = di->priv;
+
+ num_logic_channels = DEFAULT_NUM_LOGIC_CHANNELS;
+ num_analog_channels = DEFAULT_NUM_ANALOG_CHANNELS;
+ for (l = options; l; l = l->next) {
+ src = l->data;
+ switch (src->key) {
+ case SR_CONF_NUM_LOGIC_CHANNELS:
+ num_logic_channels = g_variant_get_int32(src->data);
+ break;
+ case SR_CONF_NUM_ANALOG_CHANNELS:
+ num_analog_channels = g_variant_get_int32(src->data);
+ break;
+ }
+ }
+
+ devices = NULL;
+ sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, "Demo device", NULL, NULL);
+ if (!sdi) {
+ sr_err("Device instance creation failed.");
+ return NULL;
+ }
+ sdi->driver = di;
+
+ if (!(devc = g_try_malloc(sizeof(struct dev_context)))) {
+ sr_err("Device context malloc failed.");
+ return NULL;
+ }
+ devc->cur_samplerate = SR_KHZ(200);
+ devc->limit_samples = 0;
+ devc->limit_msec = 0;
+ devc->step = 0;
+ devc->num_logic_channels = num_logic_channels;
+ devc->logic_unitsize = (devc->num_logic_channels + 7) / 8;
+ devc->logic_pattern = PATTERN_SIGROK;
+ devc->num_analog_channels = num_analog_channels;
+ devc->analog_channel_groups = NULL;
+
+ /* Logic channels, all in one channel group. */
+ if (!(cg = g_try_malloc(sizeof(struct sr_channel_group))))
+ return NULL;
+ cg->name = g_strdup("Logic");
+ cg->channels = NULL;
+ cg->priv = NULL;
+ for (i = 0; i < num_logic_channels; i++) {
+ sprintf(channel_name, "D%d", i);
+ if (!(ch = sr_channel_new(i, SR_CHANNEL_LOGIC, TRUE, channel_name)))
+ return NULL;
+ sdi->channels = g_slist_append(sdi->channels, ch);
+ cg->channels = g_slist_append(cg->channels, ch);
+ }
+ sdi->channel_groups = g_slist_append(NULL, cg);
+
+ /* Analog channels, channel groups and pattern generators. */
+
+ pattern = 0;
+ for (i = 0; i < num_analog_channels; i++) {
+ sprintf(channel_name, "A%d", i);
+ if (!(ch = sr_channel_new(i + num_logic_channels,
+ SR_CHANNEL_ANALOG, TRUE, channel_name)))
+ return NULL;
+ sdi->channels = g_slist_append(sdi->channels, ch);
+
+ /* Every analog channel gets its own channel group. */
+ if (!(cg = g_try_malloc(sizeof(struct sr_channel_group))))
+ return NULL;
+ cg->name = g_strdup(channel_name);
+ cg->channels = g_slist_append(NULL, ch);
+
+ /* Every channel group gets a generator struct. */
+ if (!(ag = g_try_malloc(sizeof(struct analog_gen))))
+ return NULL;
+ ag->packet.channels = cg->channels;
+ ag->packet.mq = 0;
+ ag->packet.mqflags = 0;
+ ag->packet.unit = SR_UNIT_VOLT;
+ ag->packet.data = ag->pattern_data;
+ ag->pattern = pattern;
+ cg->priv = ag;
+
+ sdi->channel_groups = g_slist_append(sdi->channel_groups, cg);
+ devc->analog_channel_groups = g_slist_append(devc->analog_channel_groups, cg);
+
+ if (++pattern == ARRAY_SIZE(analog_pattern_str))
+ pattern = 0;
+ }
+
+ sdi->priv = devc;
+ devices = g_slist_append(devices, sdi);
+ drvc->instances = g_slist_append(drvc->instances, sdi);
+
+ return devices;
+}