+ /* Make sure the number of samples we put out is an integer
+ * multiple of our period size */
+ /* FIXME we actually need only one period. A ringbuffer would be
+ * usefull here.*/
+ 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] = 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_probe *probe;
+ struct sr_channel_group *cg;
+ struct sr_config *src;
+ struct analog_gen *ag;
+ GSList *devices, *l;
+ int num_logic_probes, num_analog_probes, pattern, i;
+ char probe_name[16];
+
+ drvc = di->priv;
+
+ num_logic_probes = DEFAULT_NUM_LOGIC_PROBES;
+ num_analog_probes = DEFAULT_NUM_ANALOG_PROBES;
+ for (l = options; l; l = l->next) {
+ src = l->data;
+ switch (src->key) {
+ case SR_CONF_NUM_LOGIC_PROBES:
+ num_logic_probes = g_variant_get_int32(src->data);
+ break;
+ case SR_CONF_NUM_ANALOG_PROBES:
+ num_analog_probes = 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_probes = num_logic_probes;
+ devc->logic_unitsize = (devc->num_logic_probes + 7) / 8;
+ devc->logic_pattern = PATTERN_SIGROK;
+ devc->num_analog_probes = num_analog_probes;
+ devc->analog_channel_groups = NULL;
+
+ /* Logic probes, 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_probes; i++) {
+ sprintf(probe_name, "D%d", i);
+ if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, probe_name)))
+ return NULL;
+ sdi->probes = g_slist_append(sdi->probes, probe);
+ cg->channels = g_slist_append(cg->channels, probe);
+ }
+ sdi->channel_groups = g_slist_append(NULL, cg);
+
+ /* Analog probes, channel groups and pattern generators. */
+
+ pattern = 0;
+ for (i = 0; i < num_analog_probes; i++) {
+ sprintf(probe_name, "A%d", i);
+ if (!(probe = sr_probe_new(i + num_logic_probes,
+ SR_PROBE_ANALOG, TRUE, probe_name)))
+ return NULL;
+ sdi->probes = g_slist_append(sdi->probes, probe);
+
+ /* Every analog probe gets its own channel group. */
+ if (!(cg = g_try_malloc(sizeof(struct sr_channel_group))))
+ return NULL;
+ cg->name = g_strdup(probe_name);
+ cg->channels = g_slist_append(NULL, probe);
+
+ /* Every channel group gets a generator struct. */
+ if (!(ag = g_try_malloc(sizeof(struct analog_gen))))
+ return NULL;
+ ag->packet.probes = 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;
+ }