static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, struct sr_channel *ch, const struct sr_channel_group *cg) { uint16_t i, j; int ret; const char *stropt; struct sr_channel *probe; uint64_t tmp_u64; (void) cg; struct dev_context *const devc = sdi->priv; if (sdi->status != SR_ST_ACTIVE) return SR_ERR_DEV_CLOSED; if (id == SR_CONF_SAMPLERATE) { devc->cur_samplerate = g_variant_get_uint64(data); devc->samples_counter = 0; devc->pre_index = 0; sr_dbg("%s: setting samplerate to %" PRIu64, __func__, devc->cur_samplerate); ret = SR_OK; } else if (id == SR_CONF_LIMIT_SAMPLES) { devc->limit_msec = 0; devc->limit_samples = g_variant_get_uint64(data); devc->limit_samples_show = devc->limit_samples; if (sdi->mode == DSO && en_ch_num(sdi) == 1) { devc->limit_samples /= 2; } sr_dbg("%s: setting limit_samples to %" PRIu64, __func__, devc->limit_samples); ret = SR_OK; } else if (id == SR_CONF_LIMIT_MSEC) { devc->limit_msec = g_variant_get_uint64(data); devc->limit_samples = 0; devc->limit_samples_show = devc->limit_samples; sr_dbg("%s: setting limit_msec to %" PRIu64, __func__, devc->limit_msec); ret = SR_OK; } else if (id == SR_CONF_DEVICE_MODE) { sdi->mode = g_variant_get_int16(data); ret = SR_OK; if (sdi->mode == LOGIC) { sr_dev_probes_free(sdi); for (i = 0; probe_names[i]; i++) { if (!(probe = sr_channel_new(i, SR_CHANNEL_LOGIC, TRUE, probe_names[i]))) ret = SR_ERR; else sdi->channels = g_slist_append(sdi->channels, probe); } devc->cur_samplerate = SR_MHZ(1); devc->limit_samples = SR_MB(1); devc->limit_samples_show = devc->limit_samples; } else if (sdi->mode == DSO) { sr_dev_probes_free(sdi); for (i = 0; i < DEMO_MAX_DSO_PROBES_NUM; i++) { if (!(probe = sr_channel_new(i, SR_CHANNEL_DSO, TRUE, probe_names[i]))) ret = SR_ERR; else { probe->vdiv = 1000; probe->vfactor = 1; probe->coupling = SR_AC_COUPLING; probe->trig_value = 0x80; probe->vpos = (probe->index == 0 ? 0.5 : -0.5)*probe->vdiv; sdi->channels = g_slist_append(sdi->channels, probe); probe->ms_show = TRUE; for (j = DSO_MS_BEGIN; j < DSO_MS_END; j++) probe->ms_en[j] = default_ms_en[j]; } } devc->cur_samplerate = DEMO_MAX_DSO_SAMPLERATE / DEMO_MAX_DSO_PROBES_NUM; devc->limit_samples = DEMO_MAX_DSO_DEPTH / DEMO_MAX_DSO_PROBES_NUM; devc->limit_samples_show = devc->limit_samples; } else if (sdi->mode == ANALOG) { sr_dev_probes_free(sdi); for (i = 0; i < DS_MAX_ANALOG_PROBES_NUM; i++) { if (!(probe = sr_channel_new(i, SR_CHANNEL_ANALOG, TRUE, probe_names[i]))) ret = SR_ERR; else sdi->channels = g_slist_append(sdi->channels, probe); } devc->cur_samplerate = SR_HZ(100); devc->limit_samples = SR_KB(1); devc->limit_samples_show = devc->limit_samples; } else { ret = SR_ERR; } sr_dbg("%s: setting mode to %d", __func__, sdi->mode); }else if (id == SR_CONF_PATTERN_MODE) { stropt = g_variant_get_string(data, NULL); ret = SR_OK; if (!strcmp(stropt, pattern_strings[PATTERN_SINE])) { devc->sample_generator = PATTERN_SINE; } else if (!strcmp(stropt, pattern_strings[PATTERN_SQUARE])) { devc->sample_generator = PATTERN_SQUARE; } else if (!strcmp(stropt, pattern_strings[PATTERN_TRIANGLE])) { devc->sample_generator = PATTERN_TRIANGLE; } else if (!strcmp(stropt, pattern_strings[PATTERN_SAWTOOTH])) { devc->sample_generator = PATTERN_SAWTOOTH; } else if (!strcmp(stropt, pattern_strings[PATTERN_RANDOM])) { devc->sample_generator = PATTERN_RANDOM; } else { ret = SR_ERR; } sr_dbg("%s: setting pattern to %d", __func__, devc->sample_generator); } else if (id == SR_CONF_MAX_HEIGHT) { stropt = g_variant_get_string(data, NULL); ret = SR_OK; for (i = 0; i < ARRAY_SIZE(maxHeights); i++) { if (!strcmp(stropt, maxHeights[i])) { devc->max_height = i; break; } } sr_dbg("%s: setting Signal Max Height to %d", __func__, devc->max_height); } else if (id == SR_CONF_INSTANT) { devc->instant = g_variant_get_boolean(data); sr_dbg("%s: setting INSTANT mode to %d", __func__, devc->instant); ret = SR_OK; } else if (id == SR_CONF_HORIZ_TRIGGERPOS) { ret = SR_OK; } else if (id == SR_CONF_TRIGGER_HOLDOFF) { ret = SR_OK; } else if (id == SR_CONF_TRIGGER_MARGIN) { ret = SR_OK; } else if (id == SR_CONF_EN_CH) { ch->enabled = g_variant_get_boolean(data); sr_dbg("%s: setting ENABLE of channel %d to %d", __func__, ch->index, ch->enabled); ret = SR_OK; } else if (id == SR_CONF_DATALOCK) { devc->data_lock = g_variant_get_boolean(data); sr_dbg("%s: setting data lock to %d", __func__, devc->data_lock); ret = SR_OK; } else if (id == SR_CONF_VDIV) { tmp_u64 = g_variant_get_uint64(data); ch->vpos = (tmp_u64 * 1.0 / ch->vdiv) * ch->vpos; ch->vdiv = tmp_u64; sr_dbg("%s: setting VDIV of channel %d to %" PRIu64, __func__, ch->index, ch->vdiv); ret = SR_OK; } else if (id == SR_CONF_FACTOR) { ch->vfactor = g_variant_get_uint64(data); sr_dbg("%s: setting FACTOR of channel %d to %" PRIu64, __func__, ch->index, ch->vfactor); ret = SR_OK; } else if (id == SR_CONF_VPOS) { //ch->vpos = g_variant_get_double(data); sr_dbg("%s: setting VPOS of channel %d to %lf", __func__, ch->index, ch->vpos); ret = SR_OK; } else if (id == SR_CONF_TIMEBASE) { devc->timebase = g_variant_get_uint64(data); sr_dbg("%s: setting TIMEBASE to %" PRIu64, __func__, devc->timebase); ret = SR_OK; } else if (id == SR_CONF_COUPLING) { ch->coupling = g_variant_get_byte(data); sr_dbg("%s: setting AC COUPLING of channel %d to %d", __func__, ch->index, ch->coupling); ret = SR_OK; } else if (id == SR_CONF_TRIGGER_SOURCE) { devc->trigger_source = g_variant_get_byte(data); sr_dbg("%s: setting Trigger Source to %d", __func__, devc->trigger_source); ret = SR_OK; } else if (id == SR_CONF_TRIGGER_SLOPE) { devc->trigger_slope = g_variant_get_byte(data); sr_dbg("%s: setting Trigger Slope to %d", __func__, devc->trigger_slope); ret = SR_OK; } else if (id == SR_CONF_TRIGGER_VALUE) { ch->trig_value = g_variant_get_byte(data); sr_dbg("%s: setting channel %d Trigger Value to %d", __func__, ch->index, ch->trig_value); ret = SR_OK; } else { ret = SR_ERR_NA; } return ret; }
static void samples_generator(uint16_t *buf, uint64_t size, const struct sr_dev_inst *sdi, struct dev_context *devc) { uint64_t i, pre0_i, pre1_i; GSList *l; struct sr_channel *probe; int offset; unsigned int start_rand; const uint64_t span = DEMO_MAX_DSO_SAMPLERATE / devc->cur_samplerate; const uint64_t len = ARRAY_SIZE(sinx) - 1; const int *pre_buf; uint16_t tmp_u16 = 0; unsigned int ch_num = en_ch_num(sdi) ? en_ch_num(sdi) : 1; switch (devc->sample_generator) { case PATTERN_SINE: /* Sine */ pre_buf = sinx; break; case PATTERN_SQUARE: pre_buf = sqrx; break; case PATTERN_TRIANGLE: pre_buf = trix; break; case PATTERN_SAWTOOTH: pre_buf = sawx; break; case PATTERN_RANDOM: pre_buf = ranx; break; default: pre_buf = sinx; break; } if (devc->samples_counter == devc->limit_samples && size != devc->limit_samples) { for (i = 0; i < devc->limit_samples; i++) *(buf + i) = *(buf + ((i + size)%devc->limit_samples)); } else if (sdi->mode == LOGIC) { for (i = 0; i < size; i++) { //index = (i/10/g_slist_length(sdi->channels)+start_rand)%len; //*(buf + i) = (uint16_t)(((const_dc+pre_buf[index]) << 8) + (const_dc+pre_buf[index])); tmp_u16 = 0; if (i < ch_num*4) *(buf + i) = tmp_u16; else if (i % 4 == 0) { start_rand = rand() % (ch_num * 4); if (start_rand == (i/4 % ch_num)) tmp_u16 = 0xffff; *(buf + i) = tmp_u16 ? ~*(buf + i - ch_num*4) : *(buf + i - ch_num*4); } else { *(buf + i) = *(buf + i - 1); } } } else if (sdi->mode == ANALOG) { for (i = 0; i < size; i++) { if (rand() % (devc->limit_samples / 100) == 0) *(buf + i) = 0x4000 + rand() % 0x8000; else if (rand() % (devc->limit_samples / 1000) == 0) *(buf + i) = 0x7000 + rand() % 0x2000; else *(buf + i) = 0x8000; } } else { if (devc->pre_index == 0) { devc->mstatus.ch0_max = 0; devc->mstatus.ch0_min = 255; devc->mstatus.ch1_max = 0; devc->mstatus.ch1_min = 255; devc->mstatus.ch0_period = 0; devc->mstatus.ch0_pcnt = 1; devc->mstatus.ch1_period = 0; devc->mstatus.ch1_pcnt = 1; } memset(buf+devc->pre_index, 0, size*sizeof(uint16_t)); for (l = sdi->channels; l; l = l->next) { start_rand = devc->pre_index == 0 ? rand()%len : 0; probe = (struct sr_channel *)l->data; offset = ceil((0.5 - (probe->vpos/probe->vdiv/10.0)) * 255); //offset = 128; pre0_i = devc->pre_index; pre1_i = devc->pre_index; for (i = devc->pre_index; i < devc->pre_index + size; i++) { if (probe->coupling == SR_DC_COUPLING) { *(buf + i) += (uint8_t)(offset + (1000.0/probe->vdiv) * (pre_buf[(i*span+start_rand)%len] - const_dc)) << (probe->index * 8); } else if (probe->coupling == SR_AC_COUPLING) { *(buf + i) += (uint8_t)(offset + (1000.0/probe->vdiv) * pre_buf[(i*span+start_rand)%len]) << (probe->index * 8); } else { *(buf + i) += offset << (probe->index * 8); } if (probe->index == 0) { devc->mstatus.ch0_max = MAX(devc->mstatus.ch0_max, (*(buf + i) & 0x00ff)); devc->mstatus.ch0_min = MIN(devc->mstatus.ch0_min, (*(buf + i) & 0x00ff)); if (i > devc->pre_index && pre_buf[(i*span+start_rand)%len] < 0 && pre_buf[((i-1)*span+start_rand)%len] > 0) { devc->mstatus.ch0_period = 2*(i - pre0_i)*pow(10, 8)/DEMO_MAX_DSO_SAMPLERATE; pre0_i = i; } } else { devc->mstatus.ch1_max = MAX(devc->mstatus.ch1_max, ((*(buf + i) & 0xff00) >> 8)); devc->mstatus.ch1_min = MIN(devc->mstatus.ch1_min, ((*(buf + i) & 0xff00) >> 8)); if (i > devc->pre_index && pre_buf[(i*span+start_rand)%len] < 0 && pre_buf[((i-1)*span+start_rand)%len] > 0) { devc->mstatus.ch1_period = 2*(i - pre1_i)*pow(10, 8)/DEMO_MAX_DSO_SAMPLERATE; pre1_i = i; } } } } for (l = sdi->channels; l; l = l->next) { probe = (struct sr_channel *)l->data; if (!probe->enabled) { devc->mstatus.ch1_max = MAX(devc->mstatus.ch0_max, devc->mstatus.ch1_max); devc->mstatus.ch1_min = MIN(devc->mstatus.ch0_min, devc->mstatus.ch1_min); devc->mstatus.ch0_max = MAX(devc->mstatus.ch0_max, devc->mstatus.ch1_max); devc->mstatus.ch0_min = MIN(devc->mstatus.ch0_min, devc->mstatus.ch1_min); break; } } } }