diff --git a/DSView/pv/dialogs/waitingdialog.cpp b/DSView/pv/dialogs/waitingdialog.cpp index b4bcdb264cb81759002c904ff21855232ad914e6..f4144ec50a24f3dcd50cf7973dffc448a32e7e74 100755 --- a/DSView/pv/dialogs/waitingdialog.cpp +++ b/DSView/pv/dialogs/waitingdialog.cpp @@ -170,8 +170,34 @@ void WaitingDialog::changeText() { tips->setText(tr("Waiting")); index = 0; + GVariant* gvar; + bool comb_comp_en = false; + bool zero_fgain = false; - GVariant* gvar = _dev_inst->get_config(NULL, NULL, _key); + gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_PROBE_COMB_COMP_EN); + if (gvar != NULL) { + comb_comp_en = g_variant_get_boolean(gvar); + g_variant_unref(gvar); + if (comb_comp_en) { + gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_ZERO_COMB_FGAIN); + if (gvar != NULL) { + zero_fgain = g_variant_get_boolean(gvar); + g_variant_unref(gvar); + if (zero_fgain) { + boost::shared_ptr<view::DsoSignal> dsoSig; + BOOST_FOREACH(const boost::shared_ptr<view::Signal> s, _session.get_signals()) + { + if ((dsoSig = dynamic_pointer_cast<view::DsoSignal>(s))) + dsoSig->set_enable(dsoSig->get_index() == 0); + } + boost::this_thread::sleep(boost::posix_time::millisec(100)); + _dev_inst->set_config(NULL, NULL, SR_CONF_ZERO_COMB, g_variant_new_boolean(true)); + } + } + } + } + + gvar = _dev_inst->get_config(NULL, NULL, _key); if (gvar != NULL) { bool zero = g_variant_get_boolean(gvar); g_variant_unref(gvar); diff --git a/DSView/pv/sigsession.cpp b/DSView/pv/sigsession.cpp index dc28e0055c2375834d98db234033125e75b5750d..3debb650a1ee199eeb2ee17b191f9344f98a7fb3 100755 --- a/DSView/pv/sigsession.cpp +++ b/DSView/pv/sigsession.cpp @@ -505,7 +505,7 @@ bool SigSession::get_capture_status(bool &triggered, int &progress) { uint64_t sample_limits = cur_samplelimits(); sr_status status; - if (sr_status_get(_dev_inst->dev_inst(), &status, true, SR_STATUS_TRIG_BEGIN, SR_STATUS_TRIG_END) == SR_OK){ + if (sr_status_get(_dev_inst->dev_inst(), &status, true) == SR_OK){ triggered = status.trig_hit & 0x01; uint64_t captured_cnt = status.trig_hit >> 2; captured_cnt = ((uint64_t)status.captured_cnt0 + diff --git a/DSView/pv/storesession.cpp b/DSView/pv/storesession.cpp index 377dfef2a268bd37776c60308988ae7760ecc649..40958fdc2a998d0f48531bb099869cd910573783 100755 --- a/DSView/pv/storesession.cpp +++ b/DSView/pv/storesession.cpp @@ -460,7 +460,7 @@ QString StoreSession::meta_gen(boost::shared_ptr<data::Snapshot> snapshot) fprintf(meta, " vFactor%d = %" PRIu64 "\n", probecnt, probe->vfactor); fprintf(meta, " vOffset%d = %d\n", probecnt, probe->hw_offset); fprintf(meta, " vTrig%d = %d\n", probecnt, probe->trig_value); - if (sr_status_get(sdi, &status, false, 0, 0) == SR_OK) { + if (sr_status_get(sdi, &status, false) == SR_OK) { if (probe->index == 0) { fprintf(meta, " period%d = %" PRIu32 "\n", probecnt, status.ch0_cyc_tlen); fprintf(meta, " pcnt%d = %" PRIu32 "\n", probecnt, status.ch0_cyc_cnt); diff --git a/DSView/pv/toolbars/samplingbar.cpp b/DSView/pv/toolbars/samplingbar.cpp index 908464c578e71cccccdb6794a4dddfb3c5067427..bf60dbf7ab056f110a10c826e1333a473eb9bcc8 100755 --- a/DSView/pv/toolbars/samplingbar.cpp +++ b/DSView/pv/toolbars/samplingbar.cpp @@ -804,7 +804,7 @@ void SamplingBar::commit_settings() g_variant_new_uint64(sample_rate)); if (dev_inst->dev_inst()->mode != DSO) { const uint64_t sample_count = ((uint64_t)ceil(sample_duration / SR_SEC(1) * - sample_rate) + 1023ULL) & ~1023ULL; + sample_rate) + SAMPLES_ALIGN) & ~SAMPLES_ALIGN; if (sample_count != dev_inst->get_sample_limit()) dev_inst->set_config(NULL, NULL, SR_CONF_LIMIT_SAMPLES, diff --git a/DSView/pv/view/dsosignal.cpp b/DSView/pv/view/dsosignal.cpp index 801c370b1305e45ed2e60e3c05f0832de6465df1..7999855bffd216ed5c864004a75823bbd026c7c7 100755 --- a/DSView/pv/view/dsosignal.cpp +++ b/DSView/pv/view/dsosignal.cpp @@ -892,7 +892,7 @@ void DsoSignal::paint_mid(QPainter &p, int left, int right, QColor fore, QColor } sr_status status; - if (sr_status_get(_dev_inst->dev_inst(), &status, false, 0, 0) == SR_OK) { + if (sr_status_get(_dev_inst->dev_inst(), &status, false) == SR_OK) { _mValid = true; if (status.measure_valid) { _min = (index == 0) ? status.ch0_min : status.ch1_min; diff --git a/DSView/res/DSCopeU2B100.bin b/DSView/res/DSCopeU2B100.bin new file mode 100644 index 0000000000000000000000000000000000000000..25c3df7f80a415e3d0541741dc99eb03e87ed136 Binary files /dev/null and b/DSView/res/DSCopeU2B100.bin differ diff --git a/DSView/res/DSCopeU3P100.bin b/DSView/res/DSCopeU3P100.bin new file mode 100644 index 0000000000000000000000000000000000000000..b24ab5c9403ac0c300b91c2f9c857400d3aea906 Binary files /dev/null and b/DSView/res/DSCopeU3P100.bin differ diff --git a/DSView/res/DSLogic33.bin b/DSView/res/DSLogic33.bin index ea7b87a3067b5be2b3db4cf2985794accae23695..84d6a76ec36d5a6d62f11b431f7e47b2f38d8e19 100755 Binary files a/DSView/res/DSLogic33.bin and b/DSView/res/DSLogic33.bin differ diff --git a/DSView/res/DSLogic50.bin b/DSView/res/DSLogic50.bin index b4d8cf723117a3b6e548a0046dfb2c131b73b387..c1a80894c66e60f8b71d0941f7f8d4e7ebd87a57 100755 Binary files a/DSView/res/DSLogic50.bin and b/DSView/res/DSLogic50.bin differ diff --git a/DSView/res/DSLogicBasic.bin b/DSView/res/DSLogicBasic.bin index d232d1402de1b17b57c1493d35baa86f95309a2e..b52cb5889788b25f3eedc33bb86a1c9349631fe2 100755 Binary files a/DSView/res/DSLogicBasic.bin and b/DSView/res/DSLogicBasic.bin differ diff --git a/DSView/res/DSLogicPlus.bin b/DSView/res/DSLogicPlus.bin index 0c420e70a22688f381bab119f7b3dfa4a671697b..1235ed369aa7b604d3adb75178e190082854d35e 100755 Binary files a/DSView/res/DSLogicPlus.bin and b/DSView/res/DSLogicPlus.bin differ diff --git a/DSView/res/DSLogicPro.bin b/DSView/res/DSLogicPro.bin index 7b2a18d18edaef68456e25806fbfc30cf63c9b3a..ac1336a7c263e6e02fd21f929c8ba2391838ffe6 100755 Binary files a/DSView/res/DSLogicPro.bin and b/DSView/res/DSLogicPro.bin differ diff --git a/DSView/res/DSLogicU2Basic.bin b/DSView/res/DSLogicU2Basic.bin index b04ed19d89c171a72707ba23c8e4ce3ea05f973d..4f412821fdcfaae842d364d1046ea45b06806b56 100755 Binary files a/DSView/res/DSLogicU2Basic.bin and b/DSView/res/DSLogicU2Basic.bin differ diff --git a/DSView/res/DSLogicU3Pro16.bin b/DSView/res/DSLogicU3Pro16.bin new file mode 100644 index 0000000000000000000000000000000000000000..ef5fbbe6d57300bb70407948fc1e157f5b67775d Binary files /dev/null and b/DSView/res/DSLogicU3Pro16.bin differ diff --git a/DSView/res/DSLogicU3Pro32.bin b/DSView/res/DSLogicU3Pro32.bin new file mode 100644 index 0000000000000000000000000000000000000000..5cfb432cfd0aa4f982bb2bf4d72816ef1c880c3a Binary files /dev/null and b/DSView/res/DSLogicU3Pro32.bin differ diff --git a/libsigrok4DSL/hardware/DSL/command.h b/libsigrok4DSL/hardware/DSL/command.h index bebad27c913c17755ba3f42e168f992afe804459..bc3205316989aa610f6fc65936ac029731cf4a01 100755 --- a/libsigrok4DSL/hardware/DSL/command.h +++ b/libsigrok4DSL/hardware/DSL/command.h @@ -137,6 +137,14 @@ struct cmd_zero_info { uint8_t trans0; uint8_t trans1; uint8_t comb_comp; + uint8_t fgain0_code; + uint8_t fgain1_code; + uint8_t fgain2_code; + uint8_t fgain3_code; + uint8_t comb_fgain0_code; + uint8_t comb_fgain1_code; + uint8_t comb_fgain2_code; + uint8_t comb_fgain3_code; }; struct cmd_vga_info { diff --git a/libsigrok4DSL/hardware/DSL/dscope.c b/libsigrok4DSL/hardware/DSL/dscope.c index 868808edd8ded028f23afbda46340af9d53e2f6b..81174156867d4063c84e42d9aa98c77a13c4a1bd 100755 --- a/libsigrok4DSL/hardware/DSL/dscope.c +++ b/libsigrok4DSL/hardware/DSL/dscope.c @@ -159,6 +159,9 @@ static struct DSL_context *DSCope_dev_new(const struct DSL_profile *prof) devc->trigger_hpos = 0x0; devc->trigger_hrate = 0; devc->zero = FALSE; + devc->zero_branch = FALSE; + devc->zero_comb_fgain = FALSE; + devc->zero_comb = FALSE; devc->tune = FALSE; devc->data_lock = FALSE; devc->cali = FALSE; @@ -195,6 +198,7 @@ static GSList *scan(GSList *options) libusb_device **devlist; int devcnt, ret, i, j; const char *conn; + enum libusb_speed usb_speed; drvc = di->priv; @@ -236,10 +240,16 @@ static GSList *scan(GSList *options) continue; } + usb_speed = libusb_get_device_speed( devlist[i]); + if ((usb_speed != LIBUSB_SPEED_HIGH) && + (usb_speed != LIBUSB_SPEED_SUPER)) + continue; + prof = NULL; for (j = 0; supported_DSCope[j].vid; j++) { if (des.idVendor == supported_DSCope[j].vid && - des.idProduct == supported_DSCope[j].pid) { + des.idProduct == supported_DSCope[j].pid && + usb_speed == supported_DSCope[j].usb_speed) { prof = &supported_DSCope[j]; } } @@ -343,8 +353,9 @@ static uint64_t dso_offset(const struct sr_dev_inst *sdi, const struct sr_channe struct DSL_context *devc = sdi->priv; const double offset_mid = (1 << (ch->bits - 1)); const double offset_max = ((1 << ch->bits) - 1.0); - const uint64_t offset = devc->zero ? ch->zero_offset : ch->hw_offset; - double comb_off = 2.0 / (pow(10, 24.0*ch->comb_comp/20/4096) - 1); + const uint64_t offset = devc->zero ? ch->zero_offset : ch->offset; + double comb_off = (devc->profile->dev_caps.feature_caps & CAPS_FEATURE_HMCAD1511) ? 0.57 / (pow(10, 24.0*ch->comb_comp/20/4096) - 1) : + 2.0 / (pow(10, 24.0*ch->comb_comp/20/4096) - 1); // const double comb_compensate = ((devc->profile->dev_caps.feature_caps & CAPS_FEATURE_HMCAD1511) && // (dsl_en_ch_num(sdi) == 1))? (offset - offset_mid) / comb_off : 0; const double comb_compensate = ((ch->comb_comp != 0) && (dsl_en_ch_num(sdi) == 1)) ? (offset - offset_mid) / comb_off : 0; @@ -385,9 +396,8 @@ static uint64_t dso_cmd_gen(const struct sr_dev_inst *sdi, struct sr_channel* ch switch (id) { case SR_CONF_PROBE_EN: case SR_CONF_PROBE_COUPLING: - if (devc->zero || sdi->mode == ANALOG || dsl_en_ch_num(sdi) == 2) { + if (sdi->mode == ANALOG || dsl_en_ch_num(sdi) == 2) { cmd += 0x0E00; - //cmd += 0x000; } else if (dsl_en_ch_num(sdi) == 1) { if (((ch->index == 0) && ch->enabled) || ((ch->index == 1) && !ch->enabled)) cmd += 0x1600; @@ -418,7 +428,6 @@ static uint64_t dso_cmd_gen(const struct sr_dev_inst *sdi, struct sr_channel* ch case SR_CONF_PROBE_OFFSET: cmd += 0x10; cmd += ch->index << ch_bit; - ch->hw_offset = ch->offset; offset = dso_offset(sdi, ch); cmd += (offset << 8); break; @@ -429,7 +438,7 @@ static uint64_t dso_cmd_gen(const struct sr_dev_inst *sdi, struct sr_channel* ch break; case SR_CONF_HORIZ_TRIGGERPOS: cmd += 0x20; - cmd += devc->trigger_hpos << 8; + cmd += ((uint64_t)devc->trigger_hpos << 8); break; case SR_CONF_TRIGGER_SLOPE: cmd += 0x28; @@ -539,6 +548,8 @@ static gboolean dso_load_eep(struct sr_dev_inst *sdi, struct sr_channel *probe, zero_info.zero_addr = dst_addr; if (devc->profile->dev_caps.feature_caps & CAPS_FEATURE_SEEP) real_zero_addr = zero_info.zero_addr; + else if (devc->profile->dev_caps.feature_caps & CAPS_FEATURE_FLASH) + real_zero_addr = probe->index * DSO_ZERO_PAGE; else real_zero_addr = (zero_big_addr << 8) + zero_info.zero_addr; if ((ret = dsl_rd_nvm(sdi, (unsigned char *)&zero_info, real_zero_addr, sizeof(struct cmd_zero_info))) != SR_OK) { @@ -555,6 +566,16 @@ static gboolean dso_load_eep(struct sr_dev_inst *sdi, struct sr_channel *probe, probe->comb_diff_bom = *(preoff_ptr + 2*i + 1); probe->vpos_trans = *(preoff_ptr + 2*i + 2) + (*(preoff_ptr + 2*i + 3) << 8); probe->comb_comp = *(preoff_ptr + 2*i + 4); + probe->digi_fgain = *(preoff_ptr + 2*i + 5) + (*(preoff_ptr + 2*i + 6) << 8); + probe->cali_fgain0 = dsl_adc_code2fgain(*(preoff_ptr + 2*i + 7)); + probe->cali_fgain1 = dsl_adc_code2fgain(*(preoff_ptr + 2*i + 8)); + probe->cali_fgain2 = dsl_adc_code2fgain(*(preoff_ptr + 2*i + 9)); + probe->cali_fgain3 = dsl_adc_code2fgain(*(preoff_ptr + 2*i + 10)); + probe->cali_comb_fgain0 = dsl_adc_code2fgain(*(preoff_ptr + 2*i + 11)); + probe->cali_comb_fgain1 = dsl_adc_code2fgain(*(preoff_ptr + 2*i + 12)); + probe->cali_comb_fgain2 = dsl_adc_code2fgain(*(preoff_ptr + 2*i + 13)); + probe->cali_comb_fgain3 = dsl_adc_code2fgain(*(preoff_ptr + 2*i + 14)); + if (!fpga_done) { const double slope = (probe->comb_diff_bom - probe->comb_diff_top)/(2.0*255.0); for (i = 0; i < 256; i++) { @@ -575,6 +596,8 @@ static gboolean dso_load_eep(struct sr_dev_inst *sdi, struct sr_channel *probe, vga_info.vga_addr = dst_addr + sizeof(struct cmd_zero_info); if (devc ->profile->dev_caps.feature_caps & CAPS_FEATURE_SEEP) real_zero_addr = vga_info.vga_addr; + else if (devc->profile->dev_caps.feature_caps & CAPS_FEATURE_FLASH) + real_zero_addr = probe->index * DSO_ZERO_PAGE + 1; else real_zero_addr = (zero_big_addr << 8) + vga_info.vga_addr; if ((ret = dsl_rd_nvm(sdi, (unsigned char *)&vga_info, real_zero_addr, sizeof(struct cmd_vga_info))) != SR_OK) { @@ -594,6 +617,396 @@ static gboolean dso_load_eep(struct sr_dev_inst *sdi, struct sr_channel *probe, return TRUE; } +static int dso_zero(const struct sr_dev_inst *sdi, gboolean reset) +{ + struct DSL_context *devc = sdi->priv; + GSList *l; + int ret = SR_OK; + struct sr_usb_dev_inst *usb; + struct libusb_device_handle *hdl; + struct ctl_wr_cmd wr_cmd; + + static uint64_t vdiv_back[2] = {0, 0}; + struct sr_channel *probe0 = NULL, *probe1 = NULL; + uint16_t offset_top; + if (devc->profile->dev_caps.feature_caps & CAPS_FEATURE_HMCAD1511) + offset_top = 15; + else + offset_top = 20; + const uint16_t offset_bom = ((1 << channel_modes[devc->ch_mode].unit_bits) - 1) - offset_top; + const uint16_t offset_mid = (1 << (channel_modes[devc->ch_mode].unit_bits - 1)); + const uint16_t max_trans = ((1 << 10) - 1); + + #ifdef _WIN32 + const int zero_interval = (devc->profile->usb_speed == LIBUSB_SPEED_SUPER) ? 10 : 4; + #else + const int zero_interval = 50; + #endif + const double margin_pass = 0.3; + int end_cnt = 0; + const int branch_done_cnt = (devc->profile->usb_speed == LIBUSB_SPEED_SUPER) ? 10 : 2; + static gboolean warm_done = FALSE; + static gboolean trans_fix_done = FALSE; + static gboolean mid_zero_done = FALSE; + static double margin[2]; + //static double offset[2]; + double acc_mean = 0; + double acc_mean0 = 0; + double acc_mean1 = 0; + double acc_skew[8]; + double acc_max_skew; + + if (reset) { + warm_done = FALSE; + trans_fix_done = FALSE; + mid_zero_done = FALSE; + vdiv_back[0] = 0; + vdiv_back[1] = 0; + return SR_OK; + } + if (!devc->mstatus_valid) + return SR_ERR_ARG; + + usb = sdi->conn; + hdl = usb->devhdl; + for(l = sdi->channels; l; l = l->next) { + struct sr_channel *probe = (struct sr_channel *)l->data; + if (probe->index == 0) + probe0 = probe; + if (probe->index == 1) + probe1 = probe; + if (vdiv_back[probe->index] == 0) + vdiv_back[probe->index] = probe->vdiv; + } + + if (!trans_fix_done && devc->zero_stage == 0) { + ret = SR_OK; + if (!warm_done) { + if (devc->zero_pcnt == 0*zero_interval) { + for(l = sdi->channels; l; l = l->next) { + struct sr_channel *probe = (struct sr_channel *)l->data; + for (int i = 0; (probe->vga_ptr+i)->key; i++) + probe->vdiv = (probe->vga_ptr+i)->key; + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_PROBE_VDIV)); + probe->zero_offset = offset_mid; + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_PROBE_OFFSET)); + } + } + if (!(devc->profile->dev_caps.feature_caps & CAPS_FEATURE_HMCAD1511) || + (devc->zero_pcnt == 1*zero_interval)) { + warm_done = TRUE; + devc->zero_pcnt = 0*zero_interval-1; + } + } else if (!(devc->profile->dev_caps.feature_caps & CAPS_FEATURE_PREOFF)) { + if (devc->zero_pcnt == 0*zero_interval) { + for(l = sdi->channels; l; l = l->next) { + struct sr_channel *probe = (struct sr_channel *)l->data; + probe->zero_offset = offset_bom; + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_PROBE_OFFSET)); + } + } + if (devc->zero_pcnt == 1*zero_interval) { + margin[0] = (devc->mstatus.ch0_acc_mean * 1.0 / devc->limit_samples); + margin[1] = (devc->mstatus.ch1_acc_mean * 1.0 / devc->limit_samples); +// if (margin[0] >= value_max || margin[1] >= value_max) +// ret = SR_ERR; + } + if (devc->zero_pcnt == 1*zero_interval+1) { + for(l = sdi->channels; l; l = l->next) { + struct sr_channel *probe = (struct sr_channel *)l->data; + probe->zero_offset = offset_top; + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_PROBE_OFFSET)); + } + } + if (devc->zero_pcnt == 2*zero_interval) { + double top0 = (devc->mstatus.ch0_acc_mean * 1.0 / devc->limit_samples); + double top1 = (devc->mstatus.ch1_acc_mean * 1.0 / devc->limit_samples); +// if (top0 <= value_min || top1 <= value_min) { +// ret = SR_ERR; + //} else { + margin[0] -= top0; + margin[1] -= top1; + for(l = sdi->channels; l; l = l->next) { + struct sr_channel *probe = (struct sr_channel *)l->data; + margin[probe->index] -= (offset_bom - offset_top); + if (fabs(margin[probe->index]) > margin_pass) { + margin[probe->index] = margin[probe->index] > 0 ? ceil(margin[probe->index]) : floor(margin[probe->index]); + probe->vpos_trans = min(probe->vpos_trans - margin[probe->index], max_trans); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe0, SR_CONF_PROBE_OFFSET)); + } else { + margin[probe->index] = 0; + } + } + trans_fix_done = (margin[0] == 0) && (margin[1] == 0); + devc->zero_pcnt = trans_fix_done ? 0*zero_interval : 0*zero_interval-1; + //} + } + } else { + trans_fix_done = TRUE; + } + + if (!trans_fix_done && ret == SR_OK) + devc->zero_pcnt++; + } else if (!mid_zero_done) { + if (devc->zero_pcnt == 0) { + for(l = sdi->channels; l; l = l->next) { + struct sr_channel *probe = (struct sr_channel *)l->data; + probe->vdiv = (probe->vga_ptr+devc->zero_stage)->key; + if (probe->vdiv == 0) { + probe->vdiv = (probe->vga_ptr+devc->zero_stage-1)->key; + mid_zero_done = TRUE; + break; + } + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_PROBE_VDIV)); + probe->zero_offset = offset_mid; + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_PROBE_OFFSET)); + // must after offset setting + probe->vdiv = vdiv_back[probe->index]; + } + } + + if (devc->zero_pcnt == zero_interval) { + margin[0] = offset_mid - (devc->mstatus.ch0_acc_mean * 1.0 / devc->limit_samples); + margin[1] = offset_mid - (devc->mstatus.ch1_acc_mean * 1.0 / devc->limit_samples); + if (fabs(margin[0]) < margin_pass && fabs(margin[1]) < margin_pass) { + devc->zero_stage++; + } else { + if (devc->profile->dev_caps.feature_caps & CAPS_FEATURE_PREOFF) { + for(l = sdi->channels; l; l = l->next) { + struct sr_channel *probe = (struct sr_channel *)l->data; + double trans_coarse = ((probe->vga_ptr+devc->zero_stage)->key < 500) ? (probe->vpos_trans >> 8)/DSCOPE_TRANS_CMULTI : (probe->vpos_trans >> 8); + double trans_fine = ((probe->vga_ptr+devc->zero_stage)->key < 500) ? (probe->vpos_trans & 0x00ff) / 1000.0 : (probe->vpos_trans & 0x00ff) / DSCOPE_TRANS_FMULTI; + + double voltage_margin = margin[probe->index] * (probe->vga_ptr+devc->zero_stage)->key * 10 / 255.0; + uint16_t last_preoff = (probe->vga_ptr+devc->zero_stage)->preoff; + int preoff_coarse = floor(voltage_margin / trans_coarse + 0.5); + int preoff_fine = floor(-(voltage_margin - preoff_coarse*trans_coarse)/trans_fine + 0.5); + preoff_coarse = (last_preoff >> 10) + preoff_coarse; + preoff_fine = (last_preoff&0x03ff) + preoff_fine; + (probe->vga_ptr+devc->zero_stage)->preoff = (preoff_coarse << 10) + preoff_fine; + } + } else { + for(l = sdi->channels; l; l = l->next) { + struct sr_channel *probe = (struct sr_channel *)l->data; + (probe->vga_ptr+devc->zero_stage)->preoff += margin[probe->index] > 0 ? ceil(margin[probe->index]) : floor(margin[probe->index]); + } + } + } + devc->zero_pcnt = 0; + } else if (!mid_zero_done) { + devc->zero_pcnt++; + } + } else { + ret = SR_OK; + end_cnt = 0*zero_interval + 1; + if (devc->profile->dev_caps.feature_caps & CAPS_FEATURE_HMCAD1511) { + if (!devc->zero_comb_fgain) { + if (devc->zero_pcnt == 0*zero_interval+1) { + devc->zero_branch = TRUE; + + probe0->zero_offset = offset_bom; + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe0, SR_CONF_PROBE_OFFSET)); + probe1->zero_offset = offset_bom; + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe1, SR_CONF_PROBE_OFFSET)); + + dsl_probe_cali_fgain(devc, probe0, 1, FALSE, TRUE); + dsl_probe_cali_fgain(devc, probe1, 1, FALSE, TRUE); + dsl_config_adc_fgain(sdi, 0, probe0->cali_fgain0, probe0->cali_fgain1); + dsl_config_adc_fgain(sdi, 1, probe0->cali_fgain2, probe0->cali_fgain3); + dsl_config_adc_fgain(sdi, 2, probe1->cali_fgain0, probe1->cali_fgain1); + dsl_config_adc_fgain(sdi, 3, probe1->cali_fgain2, probe1->cali_fgain3); + acc_mean0 = 0; + acc_mean1 = 0; + } else if (devc->zero_pcnt == branch_done_cnt*zero_interval) { + acc_mean0 = (devc->mstatus.ch0_acc_mean + devc->mstatus.ch0_acc_mean_p1 + + devc->mstatus.ch0_acc_mean_p2 + devc->mstatus.ch0_acc_mean_p3) / 4.0; + acc_mean1 = (devc->mstatus.ch1_acc_mean + devc->mstatus.ch1_acc_mean_p1 + + devc->mstatus.ch1_acc_mean_p2 + devc->mstatus.ch1_acc_mean_p3) / 4.0; + + acc_skew[0] = devc->mstatus.ch0_acc_mean / acc_mean0 - 1; + acc_skew[1] = devc->mstatus.ch0_acc_mean_p1 / acc_mean0 - 1; + acc_skew[2] = devc->mstatus.ch0_acc_mean_p2 / acc_mean0 - 1; + acc_skew[3] = devc->mstatus.ch0_acc_mean_p3 / acc_mean0 - 1; + acc_skew[4] = devc->mstatus.ch1_acc_mean / acc_mean1 - 1; + acc_skew[5] = devc->mstatus.ch1_acc_mean_p1 / acc_mean1 - 1; + acc_skew[6] = devc->mstatus.ch1_acc_mean_p2 / acc_mean1 - 1; + acc_skew[7] = devc->mstatus.ch1_acc_mean_p3 / acc_mean1 - 1; + acc_max_skew = fabs(acc_skew[0]); + for (int i=1; i <8; i++) + acc_max_skew = max(acc_max_skew, fabs(acc_skew[i])); + if ((acc_max_skew > MAX_ACC_VARIANCE) && (dsl_probe_fgain_inrange(probe0, FALSE, acc_skew) || + dsl_probe_fgain_inrange(probe1, FALSE, acc_skew))) { + devc->zero_pcnt = 0*zero_interval+1; + + dsl_probe_cali_fgain(devc, probe0, acc_mean0, FALSE, FALSE); + dsl_probe_cali_fgain(devc, probe1, acc_mean1, FALSE, FALSE); + + dsl_config_adc_fgain(sdi, 0, probe0->cali_fgain0, probe0->cali_fgain1); + dsl_config_adc_fgain(sdi, 1, probe0->cali_fgain2, probe0->cali_fgain3); + dsl_config_adc_fgain(sdi, 2, probe1->cali_fgain0, probe1->cali_fgain1); + dsl_config_adc_fgain(sdi, 3, probe1->cali_fgain2, probe1->cali_fgain3); + } else { + if (acc_max_skew <= MAX_ACC_VARIANCE) { + devc->zero_comb_fgain = TRUE; + devc->zero_pcnt = 0*zero_interval; + } else { + devc->zero_pcnt = 0*zero_interval; + dsl_skew_fpga_fgain(sdi, FALSE, acc_skew); + } + } + } + } + if (devc->zero_comb_fgain) { + if (devc->zero_pcnt == 0*zero_interval+1) { + probe0->zero_offset = offset_bom; + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe0, SR_CONF_PROBE_OFFSET)); + probe1->zero_offset = offset_bom; + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe1, SR_CONF_PROBE_OFFSET)); + + acc_mean = 0; + devc->zero_comb = FALSE; + dsl_probe_cali_fgain(devc, probe0, 1, TRUE, TRUE); + dsl_probe_cali_fgain(devc, probe1, 1, TRUE, TRUE); + dsl_config_adc_fgain(sdi, 0, probe0->cali_comb_fgain0, probe0->cali_comb_fgain1); + dsl_config_adc_fgain(sdi, 1, probe0->cali_comb_fgain2, probe0->cali_comb_fgain3); + dsl_config_adc_fgain(sdi, 2, probe1->cali_comb_fgain0, probe1->cali_comb_fgain1); + dsl_config_adc_fgain(sdi, 3, probe1->cali_comb_fgain2, probe1->cali_comb_fgain3); + } else if (devc->zero_pcnt == 1*zero_interval) { + if (!devc->zero_comb) + devc->zero_pcnt = 0*zero_interval+1; + } else if (devc->zero_pcnt == branch_done_cnt*zero_interval) { + acc_mean = (devc->mstatus.ch0_acc_mean + devc->mstatus.ch0_acc_mean_p1 + + devc->mstatus.ch0_acc_mean_p2 + devc->mstatus.ch0_acc_mean_p3 + + devc->mstatus.ch1_acc_mean + devc->mstatus.ch1_acc_mean_p1 + + devc->mstatus.ch1_acc_mean_p2 + devc->mstatus.ch1_acc_mean_p3) / 8.0; + + acc_skew[0] = devc->mstatus.ch0_acc_mean / acc_mean - 1; + acc_skew[1] = devc->mstatus.ch0_acc_mean_p1 / acc_mean - 1; + acc_skew[2] = devc->mstatus.ch0_acc_mean_p2 / acc_mean - 1; + acc_skew[3] = devc->mstatus.ch0_acc_mean_p3 / acc_mean - 1; + acc_skew[4] = devc->mstatus.ch1_acc_mean / acc_mean - 1; + acc_skew[5] = devc->mstatus.ch1_acc_mean_p1 / acc_mean - 1; + acc_skew[6] = devc->mstatus.ch1_acc_mean_p2 / acc_mean - 1; + acc_skew[7] = devc->mstatus.ch1_acc_mean_p3 / acc_mean - 1; + acc_max_skew = fabs(acc_skew[0]); + for (int i=1; i <8; i++) + acc_max_skew = max(acc_max_skew, fabs(acc_skew[i])); + if ((acc_max_skew > MAX_ACC_VARIANCE) && (dsl_probe_fgain_inrange(probe0, TRUE, acc_skew) || + dsl_probe_fgain_inrange(probe1, TRUE, acc_skew))) { + devc->zero_pcnt = 0*zero_interval+1; + + dsl_probe_cali_fgain(devc, probe0, acc_mean, TRUE, FALSE); + dsl_probe_cali_fgain(devc, probe1, acc_mean, TRUE, FALSE); + + dsl_config_adc_fgain(sdi, 0, probe0->cali_comb_fgain0, probe0->cali_comb_fgain1); + dsl_config_adc_fgain(sdi, 1, probe0->cali_comb_fgain2, probe0->cali_comb_fgain3); + dsl_config_adc_fgain(sdi, 2, probe1->cali_comb_fgain0, probe1->cali_comb_fgain1); + dsl_config_adc_fgain(sdi, 3, probe1->cali_comb_fgain2, probe1->cali_comb_fgain3); + } else { + if (acc_max_skew <= MAX_ACC_VARIANCE) { + devc->zero_comb_fgain = FALSE; + devc->zero_branch = FALSE; + } else { + devc->zero_pcnt = 0*zero_interval; + dsl_skew_fpga_fgain(sdi, TRUE, acc_skew); + } + } + } + } + end_cnt = branch_done_cnt*zero_interval + 1; + } else { + if (devc->zero_pcnt == 0*zero_interval+1) { + ret = dsl_wr_reg(sdi, COMB_ADDR+6, 0b1101); + wr_cmd.header.dest = DSL_CTL_DSO_EN1; + wr_cmd.data[0] = (uint8_t)~bmCH_CH1; + wr_cmd.header.size = 1; + ret = command_ctl_wr(hdl, wr_cmd); + + probe0->zero_offset = offset_top; + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe0, SR_CONF_PROBE_OFFSET)); + } else if (devc->zero_pcnt == 1*zero_interval) { + probe0->comb_diff_top = ((devc->mstatus.ch0_acc_mean * 2.0 - devc->mstatus.ch1_acc_mean * 2.0) / devc->limit_samples); + probe0->zero_offset = offset_bom; + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe0, SR_CONF_PROBE_OFFSET)); + } else if (devc->zero_pcnt == 2*zero_interval) { + probe0->comb_diff_bom = ((devc->mstatus.ch0_acc_mean * 2.0 - devc->mstatus.ch1_acc_mean * 2.0) / devc->limit_samples); + } + + if (devc->zero_pcnt == 2*zero_interval+1) { + ret = dsl_wr_reg(sdi, COMB_ADDR+6, 0b1110); + wr_cmd.header.dest = DSL_CTL_DSO_EN1; + wr_cmd.data[0] = bmCH_CH1; + wr_cmd.header.size = 1; + ret = command_ctl_wr(hdl, wr_cmd); + wr_cmd.header.dest = DSL_CTL_DSO_EN0; + wr_cmd.data[0] = (uint8_t)~bmCH_CH0; + wr_cmd.header.size = 1; + ret = command_ctl_wr(hdl, wr_cmd); + + probe1->zero_offset = offset_top; + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe1, SR_CONF_PROBE_OFFSET)); + } else if (devc->zero_pcnt == 3*zero_interval) { + probe1->comb_diff_top = ((devc->mstatus.ch1_acc_mean * 2.0 - devc->mstatus.ch0_acc_mean * 2.0) / devc->limit_samples); + probe1->zero_offset = offset_bom; + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe1, SR_CONF_PROBE_OFFSET)); + } else if (devc->zero_pcnt == 4*zero_interval) { + probe1->comb_diff_bom = ((devc->mstatus.ch1_acc_mean * 2.0 - devc->mstatus.ch0_acc_mean * 2.0) / devc->limit_samples); + } + + end_cnt = 4*zero_interval+1; + } + + if (ret == SR_OK) + devc->zero_pcnt++; + + if (devc->zero_pcnt == end_cnt) { + for(l = sdi->channels; l; l = l->next) { + struct sr_channel *probe = (struct sr_channel *)l->data; + probe->vdiv = vdiv_back[probe->index]; + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_PROBE_VDIV)); + + // vgain tunning + if (devc->profile->dev_caps.feature_caps & CAPS_FEATURE_AUTO_VGAIN) { + if (probe->vga_ptr != NULL) { + for (uint16_t i = 0; devc->profile->dev_caps.vdivs[i]; i++) { + for (uint16_t j = 0; j < ARRAY_SIZE(vga_defaults); j++) { + if (vga_defaults[j].id == devc->profile->dev_caps.vga_id && + vga_defaults[j].key == devc->profile->dev_caps.vdivs[i]) { + const int64_t vgain_delta = probe->vpos_trans > devc->profile->dev_caps.default_pwmtrans ? + ((int64_t)(probe->vpos_trans - devc->profile->dev_caps.default_pwmtrans) << 8) : + (((int64_t)(probe->vpos_trans - devc->profile->dev_caps.default_pwmtrans) << 7) & 0xFFFFFF00); + (probe->vga_ptr+i)->vgain = vga_defaults[j].vgain + vgain_delta; + break; + } + } + } + } + } + } + + ret = dsl_wr_reg(sdi, COMB_ADDR+6, 0b0011); + wr_cmd.header.dest = DSL_CTL_DSO_EN0; + wr_cmd.data[0] = bmCH_CH0; + wr_cmd.header.size = 1; + ret = command_ctl_wr(hdl, wr_cmd); + wr_cmd.header.dest = DSL_CTL_DSO_EN1; + wr_cmd.data[0] = bmCH_CH1; + wr_cmd.header.size = 1; + ret = command_ctl_wr(hdl, wr_cmd); + + devc->zero = FALSE; + warm_done = FALSE; + trans_fix_done = FALSE; + mid_zero_done = FALSE; + vdiv_back[0] = 0; + vdiv_back[1] = 0; + dso_init(sdi); + } + } + + return ret; +} + static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, const struct sr_channel *ch, const struct sr_channel_group *cg) @@ -651,9 +1064,9 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, *data = g_variant_new_uint64(dso_vga(ch)>>8); break; case SR_CONF_PROBE_COMB_COMP_EN: - if (!sdi || !ch) + if (!sdi) return SR_ERR; - *data = g_variant_new_boolean(devc->profile->dev_caps.feature_caps & CAPS_FEATURE_HMCAD1511); + *data = g_variant_new_boolean((devc->profile->dev_caps.feature_caps & CAPS_FEATURE_HMCAD1511) != 0); break; case SR_CONF_PROBE_COMB_COMP: if (!sdi || !ch) @@ -1065,6 +1478,8 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, } } } + } else { + dso_zero(sdi, TRUE); } } else if (id == SR_CONF_ZERO_DEFAULT) { unsigned int i, j; @@ -1072,6 +1487,15 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, struct sr_channel *probe = (struct sr_channel *)l->data; probe->vpos_trans = devc->profile->dev_caps.default_pwmtrans; probe->comb_comp = devc->profile->dev_caps.default_comb_comp; + probe->digi_fgain = 0; + probe->cali_fgain0 = 1; + probe->cali_fgain1 = 1; + probe->cali_fgain2 = 1; + probe->cali_fgain3 = 1; + probe->cali_comb_fgain0 = 1; + probe->cali_comb_fgain1 = 1; + probe->cali_comb_fgain2 = 1; + probe->cali_comb_fgain3 = 1; if (probe->vga_ptr != NULL) { for (i = 0; devc->profile->dev_caps.vdivs[i]; i++) { for (j = 0; j < ARRAY_SIZE(vga_defaults); j++) { @@ -1120,6 +1544,16 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, *(preoff_ptr+2*i+2) = (probe->vpos_trans&0x00FF); *(preoff_ptr+2*i+3) = (probe->vpos_trans>>8); *(preoff_ptr+2*i+4) = probe->comb_comp; + *(preoff_ptr+2*i+5) = (probe->digi_fgain&0x00FF); + *(preoff_ptr+2*i+6) = (probe->digi_fgain>>8); + *(preoff_ptr+2*i+7) = dsl_adc_fgain2code(probe->cali_fgain0); + *(preoff_ptr+2*i+8) = dsl_adc_fgain2code(probe->cali_fgain1); + *(preoff_ptr+2*i+9) = dsl_adc_fgain2code(probe->cali_fgain2); + *(preoff_ptr+2*i+10) = dsl_adc_fgain2code(probe->cali_fgain3); + *(preoff_ptr+2*i+11) = dsl_adc_fgain2code(probe->cali_comb_fgain0); + *(preoff_ptr+2*i+12) = dsl_adc_fgain2code(probe->cali_comb_fgain1); + *(preoff_ptr+2*i+13) = dsl_adc_fgain2code(probe->cali_comb_fgain2); + *(preoff_ptr+2*i+14) = dsl_adc_fgain2code(probe->cali_comb_fgain3); vga_info.vga_addr = zero_info.zero_addr + sizeof(struct cmd_zero_info); uint16_t *vgain_ptr = &vga_info.vga0; @@ -1130,6 +1564,8 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, if (ret == SR_OK) { if (devc->profile->dev_caps.feature_caps & CAPS_FEATURE_SEEP) real_zero_addr = zero_info.zero_addr; + else if (devc->profile->dev_caps.feature_caps & CAPS_FEATURE_FLASH) + real_zero_addr = probe->index * DSO_ZERO_PAGE; else real_zero_addr = (zero_big_addr << 8) + zero_info.zero_addr; ret = dsl_wr_nvm(sdi, (unsigned char *)&zero_info, real_zero_addr, sizeof(struct cmd_zero_info)); @@ -1137,6 +1573,8 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, if (ret == SR_OK) { if (devc->profile->dev_caps.feature_caps & CAPS_FEATURE_SEEP) real_zero_addr = vga_info.vga_addr; + else if (devc->profile->dev_caps.feature_caps & CAPS_FEATURE_FLASH) + real_zero_addr = probe->index * DSO_ZERO_PAGE + 1; else real_zero_addr = (zero_big_addr << 8) + vga_info.vga_addr; ret = dsl_wr_nvm(sdi, (unsigned char *)&vga_info, real_zero_addr, sizeof(struct cmd_vga_info)); @@ -1260,269 +1698,6 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi, return SR_OK; } -static int dso_zero(const struct sr_dev_inst *sdi) -{ - struct DSL_context *devc = sdi->priv; - GSList *l; - int ret; - struct sr_usb_dev_inst *usb; - struct libusb_device_handle *hdl; - struct ctl_wr_cmd wr_cmd; - - static uint64_t vdiv_back[2]; - struct sr_channel *probe0 = NULL, *probe1 = NULL; - const uint16_t offset_top = 20; - const uint16_t offset_bom = ((1 << channel_modes[devc->ch_mode].unit_bits) - 1) - offset_top; - const uint16_t offset_mid = (1 << (channel_modes[devc->ch_mode].unit_bits - 1)); - const uint16_t max_trans = ((1 << 10) - 1); - const uint8_t value_min = 0; - const uint8_t value_max = (1 << channel_modes[devc->ch_mode].unit_bits) - 1; - - const int zero_interval = 10; - const double margin_pass = 0.3; - int end_cnt = 0; - static gboolean trans_fix_done = FALSE; - static gboolean mid_zero_done = FALSE; - static double margin[2]; - //static double offset[2]; - - usb = sdi->conn; - hdl = usb->devhdl; - for(l = sdi->channels; l; l = l->next) { - struct sr_channel *probe = (struct sr_channel *)l->data; - if (probe->index == 0) - probe0 = probe; - if (probe->index == 1) - probe1 = probe; - vdiv_back[probe->index] = probe->vdiv; - } - - if (!trans_fix_done && devc->zero_stage == 0) { - ret = SR_OK; - if (!(devc->profile->dev_caps.feature_caps & CAPS_FEATURE_PREOFF)) { - if (devc->zero_pcnt == 0*zero_interval) { - for(l = sdi->channels; l; l = l->next) { - struct sr_channel *probe = (struct sr_channel *)l->data; - probe->zero_offset = offset_bom; - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_PROBE_OFFSET)); - } - } - if (devc->zero_pcnt == 1*zero_interval) { - margin[0] = (devc->mstatus.ch0_acc_mean * 1.0 / devc->limit_samples); - margin[1] = (devc->mstatus.ch1_acc_mean * 1.0 / devc->limit_samples); - if (margin[0] >= value_max || margin[1] >= value_max) - ret = SR_ERR; - } - if (devc->zero_pcnt == 1*zero_interval+1) { - for(l = sdi->channels; l; l = l->next) { - struct sr_channel *probe = (struct sr_channel *)l->data; - probe->zero_offset = offset_top; - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_PROBE_OFFSET)); - } - } - if (devc->zero_pcnt == 2*zero_interval) { - double top0 = (devc->mstatus.ch0_acc_mean * 1.0 / devc->limit_samples); - double top1 = (devc->mstatus.ch1_acc_mean * 1.0 / devc->limit_samples); - if (top0 <= value_min || top1 <= value_min) { - ret = SR_ERR; - } else { - margin[0] -= top0; - margin[1] -= top1; - for(l = sdi->channels; l; l = l->next) { - struct sr_channel *probe = (struct sr_channel *)l->data; - margin[probe->index] -= (offset_bom - offset_top); - if (fabs(margin[probe->index]) > margin_pass) { - margin[probe->index] = margin[probe->index] > 0 ? ceil(margin[probe->index]) : floor(margin[probe->index]); - probe->vpos_trans = min(probe->vpos_trans - margin[probe->index], max_trans); - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe0, SR_CONF_PROBE_OFFSET)); - } else { - margin[probe->index] = 0; - } - } - trans_fix_done = (margin[0] == 0) && (margin[1] == 0); - devc->zero_pcnt = trans_fix_done ? 0*zero_interval : 0*zero_interval-1; - } - } - } else { - trans_fix_done = TRUE; - } - - if (!trans_fix_done && ret == SR_OK) - devc->zero_pcnt++; - } else if (!mid_zero_done) { - if (devc->zero_pcnt == 0) { - for(l = sdi->channels; l; l = l->next) { - struct sr_channel *probe = (struct sr_channel *)l->data; - probe->vdiv = (probe->vga_ptr+devc->zero_stage)->key; - if (probe->vdiv == 0) { - probe->vdiv = vdiv_back[probe->index]; - mid_zero_done = TRUE; - break; - } - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_PROBE_VDIV)); - probe->zero_offset = offset_mid; - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_PROBE_OFFSET)); - // must after offset setting - probe->vdiv = vdiv_back[probe->index]; - } - } - - if (devc->zero_pcnt == zero_interval) { - margin[0] = offset_mid - (devc->mstatus.ch0_acc_mean * 1.0 / devc->limit_samples); - margin[1] = offset_mid - (devc->mstatus.ch1_acc_mean * 1.0 / devc->limit_samples); - if (fabs(margin[0]) < margin_pass && fabs(margin[1]) < margin_pass) { - devc->zero_stage++; - } else { - if (devc->profile->dev_caps.feature_caps & CAPS_FEATURE_PREOFF) { - for(l = sdi->channels; l; l = l->next) { - struct sr_channel *probe = (struct sr_channel *)l->data; - double trans_coarse = ((probe->vga_ptr+devc->zero_stage)->key < 500) ? (probe->vpos_trans >> 8)/DSCOPE_TRANS_CMULTI : (probe->vpos_trans >> 8); - double trans_fine = ((probe->vga_ptr+devc->zero_stage)->key < 500) ? (probe->vpos_trans & 0x00ff) / 1000.0 : (probe->vpos_trans & 0x00ff) / DSCOPE_TRANS_FMULTI; - - double voltage_margin = margin[probe->index] * (probe->vga_ptr+devc->zero_stage)->key * 10 / 255.0; - uint16_t last_preoff = (probe->vga_ptr+devc->zero_stage)->preoff; - int preoff_coarse = floor(voltage_margin / trans_coarse + 0.5); - int preoff_fine = floor(-(voltage_margin - preoff_coarse*trans_coarse)/trans_fine + 0.5); - preoff_coarse = (last_preoff >> 10) + preoff_coarse; - preoff_fine = (last_preoff&0x03ff) + preoff_fine; - (probe->vga_ptr+devc->zero_stage)->preoff = (preoff_coarse << 10) + preoff_fine; - } - } else { - for(l = sdi->channels; l; l = l->next) { - struct sr_channel *probe = (struct sr_channel *)l->data; - (probe->vga_ptr+devc->zero_stage)->preoff += margin[probe->index] > 0 ? ceil(margin[probe->index]) : floor(margin[probe->index]); - } - } - } - devc->zero_pcnt = 0; - } else if (!mid_zero_done) { - devc->zero_pcnt++; - } - } else { - ret = SR_OK; - end_cnt = 0*zero_interval + 1; - if (devc->profile->dev_caps.feature_caps & CAPS_FEATURE_HMCAD1511) { -// if (devc->zero_pcnt == 0*zero_interval+1) { -// for(l = sdi->channels; l; l = l->next) { -// struct sr_channel *probe = (struct sr_channel *)l->data; -// probe->zero_offset = offset_bom; -// ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_PROBE_OFFSET)); -// } -// } -// if (devc->zero_pcnt == 1*zero_interval) { -// offset[0] = (devc->mstatus.ch0_acc_mean * 1.0 / devc->limit_samples); -// offset[1] = (devc->mstatus.ch1_acc_mean * 1.0 / devc->limit_samples); -// if (margin[0] >= value_max || margin[1] >= value_max) -// ret = SR_ERR; -// } -// if (devc->zero_pcnt == 1*zero_interval+1) { -// dsl_config_adc(sdi, adc_single_ch0); -// probe0->enabled = TRUE; -// probe1->enabled = FALSE; - -// probe0->zero_offset = offset_bom; -// ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe0, SR_CONF_PROBE_OFFSET)); -// } -// if (devc->zero_pcnt == 2*zero_interval) { -// margin[0] = offset[0] - (devc->mstatus.ch0_acc_mean * 1.0 / devc->limit_samples); -// if (fabs(margin[0]) > margin_pass) { -// probe0->comb_comp -= margin[0] > 0 ? ceil(margin[0]) : floor(margin[0]); -// ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe0, SR_CONF_PROBE_OFFSET)); -// devc->zero_pcnt = 1*zero_interval+1; -// } -// } -// if (devc->zero_pcnt == 2*zero_interval+1) { -// dsl_config_adc(sdi, adc_single_ch3); -// probe0->enabled = FALSE; -// probe1->enabled = TRUE; - -// probe1->zero_offset = offset_bom; -// ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe1, SR_CONF_PROBE_OFFSET)); -// } -// if (devc->zero_pcnt == 3*zero_interval) { -// margin[1] = offset[1] - (devc->mstatus.ch1_acc_mean * 1.0 / devc->limit_samples); -// if (fabs(margin[1]) > margin_pass) { -// probe1->comb_comp -= margin[1] > 0 ? ceil(margin[1]) : floor(margin[1]); -// ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe1, SR_CONF_PROBE_OFFSET)); -// devc->zero_pcnt = 2*zero_interval+1; -// } -// } -// end_cnt = 3*zero_interval + 1; - } else { - if (devc->zero_pcnt == 0*zero_interval+1) { - ret = dsl_wr_reg(sdi, COMB_ADDR+6, 0b1101); - wr_cmd.header.dest = DSL_CTL_DSO_EN1; - wr_cmd.data[0] = (uint8_t)~bmCH_CH1; - wr_cmd.header.size = 1; - ret = command_ctl_wr(hdl, wr_cmd); - - probe0->zero_offset = offset_top; - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe0, SR_CONF_PROBE_OFFSET)); - } else if (devc->zero_pcnt == 1*zero_interval) { - probe0->comb_diff_top = ((devc->mstatus.ch0_acc_mean * 2.0 - devc->mstatus.ch1_acc_mean * 2.0) / devc->limit_samples); - probe0->zero_offset = offset_bom; - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe0, SR_CONF_PROBE_OFFSET)); - } else if (devc->zero_pcnt == 2*zero_interval) { - probe0->comb_diff_bom = ((devc->mstatus.ch0_acc_mean * 2.0 - devc->mstatus.ch1_acc_mean * 2.0) / devc->limit_samples); - } - - if (devc->zero_pcnt == 2*zero_interval+1) { - ret = dsl_wr_reg(sdi, COMB_ADDR+6, 0b1110); - wr_cmd.header.dest = DSL_CTL_DSO_EN1; - wr_cmd.data[0] = bmCH_CH1; - wr_cmd.header.size = 1; - ret = command_ctl_wr(hdl, wr_cmd); - wr_cmd.header.dest = DSL_CTL_DSO_EN0; - wr_cmd.data[0] = (uint8_t)~bmCH_CH0; - wr_cmd.header.size = 1; - ret = command_ctl_wr(hdl, wr_cmd); - - probe1->zero_offset = offset_top; - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe1, SR_CONF_PROBE_OFFSET)); - } else if (devc->zero_pcnt == 3*zero_interval) { - probe1->comb_diff_top = ((devc->mstatus.ch1_acc_mean * 2.0 - devc->mstatus.ch0_acc_mean * 2.0) / devc->limit_samples); - probe1->zero_offset = offset_bom; - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe1, SR_CONF_PROBE_OFFSET)); - } else if (devc->zero_pcnt == 4*zero_interval) { - probe1->comb_diff_bom = ((devc->mstatus.ch1_acc_mean * 2.0 - devc->mstatus.ch0_acc_mean * 2.0) / devc->limit_samples); - } - - end_cnt = 4*zero_interval+1; - } - - if (ret == SR_OK) - devc->zero_pcnt++; - - if (devc->zero_pcnt == end_cnt) { - for(l = sdi->channels; l; l = l->next) { - struct sr_channel *probe = (struct sr_channel *)l->data; - probe->vdiv = vdiv_back[probe->index]; -// if (!(devc->profile->dev_caps.feature_caps & CAPS_FEATURE_HMCAD1511)) -// probe->comb_comp = ((1 << channel_modes[devc->ch_mode].unit_bits) - 1) * 0.7 * 2 / -// min(abs(probe->comb_diff_top), abs(probe->comb_diff_bom)); - - } - - ret = dsl_wr_reg(sdi, COMB_ADDR+6, 0b0011); - wr_cmd.header.dest = DSL_CTL_DSO_EN0; - wr_cmd.data[0] = bmCH_CH0; - wr_cmd.header.size = 1; - ret = command_ctl_wr(hdl, wr_cmd); - wr_cmd.header.dest = DSL_CTL_DSO_EN1; - wr_cmd.data[0] = bmCH_CH1; - wr_cmd.header.size = 1; - ret = command_ctl_wr(hdl, wr_cmd); - - devc->zero = FALSE; - trans_fix_done = FALSE; - mid_zero_done = FALSE; - dso_init(sdi); - } - } - - return ret; -} - static int dso_tune(const struct sr_dev_inst *sdi) { struct DSL_context *devc = sdi->priv; @@ -1631,6 +1806,7 @@ static int dev_open(struct sr_dev_inst *sdi) static int dev_close(struct sr_dev_inst *sdi) { int ret; + dso_zero(sdi, TRUE); ret = dsl_dev_close(sdi); return ret; } @@ -1667,23 +1843,45 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi) struct timeval tv; struct drv_context *drvc; struct DSL_context *devc; + struct ctl_rd_cmd rd_cmd; + struct sr_usb_dev_inst *usb; + int ret; (void)fd; (void)revents; drvc = di->priv; devc = sdi->priv; + usb = sdi->conn; tv.tv_sec = tv.tv_usec = 0; libusb_handle_events_timeout_completed(drvc->sr_ctx->libusb_ctx, &tv, &completed); + if (devc->trf_completed) + devc->empty_poll_count = 0; + else + devc->empty_poll_count++; + if (devc->zero && devc->trf_completed) { - dso_zero(sdi); + dso_zero(sdi, FALSE); } if (devc->tune && devc->trf_completed) { dso_tune(sdi); } + // progress check + if ((devc->empty_poll_count > MAX_EMPTY_POLL) && (devc->status == DSL_START)) { + devc->mstatus.captured_cnt0 = 0; + rd_cmd.header.dest = DSL_CTL_I2C_STATUS; + rd_cmd.header.offset = 0; + rd_cmd.header.size = 4; + rd_cmd.data = (unsigned char*)&devc->mstatus; + if ((ret = command_ctl_rd(usb->devhdl, rd_cmd)) != SR_OK) + sr_err("Failed to get progress infos."); + + devc->empty_poll_count = 0; + } + if (devc->status == DSL_FINISH) { remove_sources(devc); } @@ -1716,12 +1914,18 @@ static int dev_acquisition_start(struct sr_dev_inst *sdi, void *cb_data) devc->cb_data = sdi; devc->num_samples = 0; devc->empty_transfer_count = 0; + devc->empty_poll_count = 0; devc->status = DSL_INIT; devc->num_transfers = 0; devc->submitted_transfers = 0; - devc->actual_samples = (devc->limit_samples + 1023ULL) & ~1023ULL; + devc->actual_samples = (devc->limit_samples + SAMPLES_ALIGN) & ~SAMPLES_ALIGN; devc->abort = FALSE; devc->mstatus_valid = FALSE; + devc->mstatus.captured_cnt0 = 0; + devc->mstatus.captured_cnt1 = 0; + devc->mstatus.captured_cnt2 = 0; + devc->mstatus.captured_cnt3 = 0; + devc->mstatus.trig_hit = 0; devc->overflow = FALSE; devc->instant_tail_bytes = dsl_header_size(devc); @@ -1745,19 +1949,27 @@ static int dev_acquisition_start(struct sr_dev_inst *sdi, void *cb_data) if (devc->profile->dev_caps.feature_caps & CAPS_FEATURE_HMCAD1511) { if (dsl_en_ch_num(sdi) == 2) { dsl_config_adc(sdi, adc_dual_ch03); + for (l = sdi->channels; l; l = l->next) { + struct sr_channel *probe = (struct sr_channel *)l->data; + dsl_config_adc_fgain(sdi, probe->index*2 + 0, probe->cali_fgain0, probe->cali_fgain1); + dsl_config_adc_fgain(sdi, probe->index*2 + 1, probe->cali_fgain2, probe->cali_fgain3); + } } else if (dsl_en_ch_num(sdi) == 1) { for (l = sdi->channels; l; l = l->next) { struct sr_channel *probe = (struct sr_channel *)l->data; if (probe->enabled && probe->index == 0) { dsl_config_adc(sdi, adc_single_ch0); - break; } else if (probe->enabled && probe->index == 1) { dsl_config_adc(sdi, adc_single_ch3); - break; } } + for (l = sdi->channels; l; l = l->next) { + struct sr_channel *probe = (struct sr_channel *)l->data; + dsl_config_adc_fgain(sdi, probe->index*2 + 0, probe->cali_comb_fgain0, probe->cali_comb_fgain1); + dsl_config_adc_fgain(sdi, probe->index*2 + 1, probe->cali_comb_fgain2, probe->cali_comb_fgain3); + } } - //dsl_config_adc(sdi, adc_power_up); + dsl_config_fpga_fgain(sdi); } if ((ret = dsl_fpga_arm(sdi)) != SR_OK) { sr_err("%s: Arm FPGA failed!", __func__); @@ -1771,12 +1983,14 @@ static int dev_acquisition_start(struct sr_dev_inst *sdi, void *cb_data) return ret; } devc->zero_stage = 0; + devc->zero_comb_fgain = FALSE; + devc->zero_branch = FALSE; } /* * settings must be updated before acquisition */ - if (sdi->mode == DSO) { + if (sdi->mode != LOGIC) { devc->trigger_hpos = devc->trigger_hrate * dsl_en_ch_num(sdi) * devc->limit_samples / 200.0; ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, NULL, SR_CONF_HORIZ_TRIGGERPOS)); if (ret != SR_OK) @@ -1790,6 +2004,7 @@ static int dev_acquisition_start(struct sr_dev_inst *sdi, void *cb_data) ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_PROBE_OFFSET)); if (ret != SR_OK) sr_err("%s: Set OFFSET of channel %d command failed!", __func__, probe->index); + probe->hw_offset = probe->offset; } } @@ -1839,9 +2054,9 @@ static int dev_acquisition_stop(const struct sr_dev_inst *sdi, void *cb_data) return ret; } -static int dev_status_get(const struct sr_dev_inst *sdi, struct sr_status *status, gboolean prg, int begin, int end) +static int dev_status_get(const struct sr_dev_inst *sdi, struct sr_status *status, gboolean prg) { - int ret = dsl_dev_status_get(sdi, status, prg, begin, end); + int ret = dsl_dev_status_get(sdi, status, prg); return ret; } diff --git a/libsigrok4DSL/hardware/DSL/dsl.c b/libsigrok4DSL/hardware/DSL/dsl.c index 40010a9c96454f249acf52fee72cb862779528e8..9e5628c9b2566e5a1e89e3097b70d759213edcb3 100755 --- a/libsigrok4DSL/hardware/DSL/dsl.c +++ b/libsigrok4DSL/hardware/DSL/dsl.c @@ -86,12 +86,20 @@ SR_PRIV void dsl_probe_init(struct sr_dev_inst *sdi) probe->bits = channel_modes[devc->ch_mode].unit_bits; probe->vdiv = 1000; probe->vfactor = 1; + probe->cali_fgain0 = 1; + probe->cali_fgain1 = 1; + probe->cali_fgain2 = 1; + probe->cali_fgain3 = 1; + probe->cali_comb_fgain0 = 1; + probe->cali_comb_fgain1 = 1; + probe->cali_comb_fgain2 = 1; + probe->cali_comb_fgain3 = 1; probe->offset = (1 << (probe->bits - 1)); - probe->hw_offset = (1 << (probe->bits - 1)); probe->coupling = SR_DC_COUPLING; probe->trig_value = (1 << (probe->bits - 1)); probe->vpos_trans = devc->profile->dev_caps.default_pwmtrans; probe->comb_comp = devc->profile->dev_caps.default_comb_comp; + probe->digi_fgain = 0; probe->map_default = TRUE; probe->map_unit = probeMapUnits[0]; @@ -421,7 +429,7 @@ SR_PRIV uint64_t dsl_channel_depth(const struct sr_dev_inst *sdi) { struct DSL_context *devc = sdi->priv; int ch_num = dsl_en_ch_num(sdi); - return devc->profile->dev_caps.hw_depth / (ch_num ? ch_num : 1); + return (devc->profile->dev_caps.hw_depth / (ch_num ? ch_num : 1)) & ~SAMPLES_ALIGN; } SR_PRIV int dsl_wr_reg(const struct sr_dev_inst *sdi, uint8_t addr, uint8_t value) @@ -675,6 +683,282 @@ SR_PRIV int dsl_config_adc(const struct sr_dev_inst *sdi, const struct DSL_adc_c return SR_OK; } +SR_PRIV double dsl_adc_code2fgain(uint8_t code) +{ + double xcode = code & 0x40 ? -(~code & 0x3F) : code & 0x3F; + return (1 + xcode / (1 << 13)); +} + +SR_PRIV uint8_t dsl_adc_fgain2code(double gain) +{ + int xratio = (gain - 1) * (1 << 13); + uint8_t code = xratio > 63 ? 63 : + xratio > 0 ? xratio : + xratio < -63 ? 64 : ~(-xratio) & 0x7F; + return code; +} + +SR_PRIV int dsl_config_adc_fgain(const struct sr_dev_inst *sdi, uint8_t branch, double gain0, double gain1) +{ + dsl_wr_reg(sdi, ADCC_ADDR, 0x00); + dsl_wr_reg(sdi, ADCC_ADDR, dsl_adc_fgain2code(gain0)); + dsl_wr_reg(sdi, ADCC_ADDR, dsl_adc_fgain2code(gain1)); + dsl_wr_reg(sdi, ADCC_ADDR, 0x34 + branch); + + return SR_OK; +} + +SR_PRIV int dsl_config_fpga_fgain(const struct sr_dev_inst *sdi) +{ + GSList *l; + int ret = SR_OK; + + for (l = sdi->channels; l; l = l->next) { + struct sr_channel *probe = (struct sr_channel *)l->data; + if (probe->index == 0) { + ret = dsl_wr_reg(sdi, ADCC_ADDR+3, (probe->digi_fgain & 0x00FF)); + ret = dsl_wr_reg(sdi, ADCC_ADDR+4, (probe->digi_fgain >> 8)); + } else if (probe->index == 1) { + ret = dsl_wr_reg(sdi, ADCC_ADDR+5, (probe->digi_fgain & 0x00FF)); + ret = dsl_wr_reg(sdi, ADCC_ADDR+6, (probe->digi_fgain >>8)); + } + } + + return ret; +} + +SR_PRIV int dsl_skew_fpga_fgain(const struct sr_dev_inst *sdi, gboolean comb, double skew[]) +{ + uint8_t fgain_up = 0; + uint8_t fgain_dn = 0; + GSList *l; + gboolean tmp; + int ret; + + for (int i = 0; i <= 7; i++) { + tmp = (-skew[i] > 1.6*MAX_ACC_VARIANCE); + fgain_up += (tmp << i); + } + + if (comb) { + for (l = sdi->channels; l; l = l->next) { + struct sr_channel *probe = (struct sr_channel *)l->data; + if (probe->index == 0) { + probe->digi_fgain |= (probe->digi_fgain & 0xFF00) + fgain_up; + fgain_up = (probe->digi_fgain & 0x00FF); + break; + } + } + ret = dsl_wr_reg(sdi, ADCC_ADDR+3, fgain_up); + } else { + for (l = sdi->channels; l; l = l->next) { + struct sr_channel *probe = (struct sr_channel *)l->data; + if (probe->index == 0) { + probe->digi_fgain |= (fgain_up << 8) + (probe->digi_fgain & 0x00FF); + fgain_up = (probe->digi_fgain>>8); + break; + } + } + ret = dsl_wr_reg(sdi, ADCC_ADDR+4, fgain_up); + } + + for (int i = 0; i <= 7; i++) { + tmp = (skew[i] > 1.6*MAX_ACC_VARIANCE); + fgain_dn += (tmp << i); + } + + if (comb) { + for (l = sdi->channels; l; l = l->next) { + struct sr_channel *probe = (struct sr_channel *)l->data; + if (probe->index == 1) { + probe->digi_fgain |= (probe->digi_fgain & 0xFF00) + fgain_dn; + fgain_dn = (probe->digi_fgain & 0x00FF); + break; + } + } + ret = dsl_wr_reg(sdi, ADCC_ADDR+5, fgain_dn); + } else { + for (l = sdi->channels; l; l = l->next) { + struct sr_channel *probe = (struct sr_channel *)l->data; + if (probe->index == 1) { + probe->digi_fgain |= (fgain_dn << 8) + (probe->digi_fgain & 0x00FF); + fgain_dn = (probe->digi_fgain>>8); + break; + } + } + ret = dsl_wr_reg(sdi, ADCC_ADDR+6, fgain_dn); + } + + return ret; +} + +SR_PRIV int dsl_probe_cali_fgain(struct DSL_context *devc, struct sr_channel *probe, double mean, gboolean comb, gboolean reset) +{ + const double UPGAIN = 1.0077; + const double DNGAIN = 0.9923; + const double MDGAIN = 1; + const double ignore_ratio = 2.0; + const double ratio = 2.0; + double drift; + if (reset) { + if (comb) { + probe->cali_comb_fgain0 = MDGAIN; + probe->cali_comb_fgain1 = MDGAIN; + probe->cali_comb_fgain2 = MDGAIN; + probe->cali_comb_fgain3 = MDGAIN; + } else { + probe->cali_fgain0 = MDGAIN; + probe->cali_fgain1 = MDGAIN; + probe->cali_fgain2 = MDGAIN; + probe->cali_fgain3 = MDGAIN; + } + } else { + if (comb) { + /* + * not consist with hmcad1511 datasheet + * + * byte order | acc_mean | single channel branch (datasheet) + * 0 ch0_acc_mean 1 (0->cali_comb_fgain0) + * 1 ch1_acc_mean 6 (1->cali_comb_fgain1) + * 2 ch0_acc_mean_p1 2 (0->cali_comb_fgain1) + * 3 ch1_acc_mean_p1 5 (1->cali_comb_fgain0) + * 4 ch0_acc_mean_p2 8 (1->cali_comb_fgain3) + * 5 ch1_acc_mean_p2 3 (0->cali_comb_fgain2) + * 6 ch0_acc_mean_p3 7 (1->cali_comb_fgain2) + * 7 ch1_acc_mean_p3 4 (0->cali_comb_fgain3) + */ + if (probe->index == 0) { + drift = (devc->mstatus.ch0_acc_mean / mean - 1) / ratio; + if (fabs(drift) > MAX_ACC_VARIANCE / ignore_ratio) + probe->cali_comb_fgain0 /= (1 + drift); + drift = (devc->mstatus.ch0_acc_mean_p1 / mean - 1) / ratio; + if (fabs(drift) > MAX_ACC_VARIANCE / ignore_ratio) + probe->cali_comb_fgain1 /= (1 + drift); + drift = (devc->mstatus.ch1_acc_mean_p2 / mean - 1) / ratio; + if (fabs(drift) > MAX_ACC_VARIANCE / ignore_ratio) + probe->cali_comb_fgain2 /= (1 + drift); + drift = (devc->mstatus.ch1_acc_mean_p3 / mean - 1) / ratio; + if (fabs(drift) > MAX_ACC_VARIANCE / ignore_ratio) + probe->cali_comb_fgain3 /= (1 + drift); + } else { + drift = (devc->mstatus.ch1_acc_mean_p1 / mean - 1) / ratio; + if (fabs(drift) > MAX_ACC_VARIANCE / ignore_ratio) + probe->cali_comb_fgain0 /= (1 + drift); + drift = (devc->mstatus.ch1_acc_mean / mean - 1) / ratio; + if (fabs(drift) > MAX_ACC_VARIANCE / ignore_ratio) + probe->cali_comb_fgain1 /= (1 + drift); + drift = (devc->mstatus.ch0_acc_mean_p3 / mean - 1) / ratio; + if (fabs(drift) > MAX_ACC_VARIANCE / ignore_ratio) + probe->cali_comb_fgain2 /= (1 + drift); + drift = (devc->mstatus.ch0_acc_mean_p2 / mean - 1) / ratio; + if (fabs(drift) > MAX_ACC_VARIANCE / ignore_ratio) + probe->cali_comb_fgain3 /= (1 + drift); + } + + probe->cali_comb_fgain0 = max(min(probe->cali_comb_fgain0, UPGAIN), DNGAIN); + probe->cali_comb_fgain1 = max(min(probe->cali_comb_fgain1, UPGAIN), DNGAIN); + probe->cali_comb_fgain2 = max(min(probe->cali_comb_fgain2, UPGAIN), DNGAIN); + probe->cali_comb_fgain3 = max(min(probe->cali_comb_fgain3, UPGAIN), DNGAIN); + } else { + /* + * byte order | acc_mean | dual channel branch + * 0 ch0_acc_mean 1 (0->cali_fgain0) + * 1 ch0_acc_mean_p1 3 (0->cali_fgain2) + * 2 ch0_acc_mean_p2 2 (0->cali_fgain1) + * 3 ch0_acc_mean_p3 4 (0->cali_fgain3) + * 4 ch1_acc_mean 5 (1->cali_fgain0) + * 5 ch1_acc_mean_p1 7 (1->cali_fgain2) + * 6 ch1_acc_mean_p2 6 (1->cali_fgain1) + * 7 ch1_acc_mean_p3 8 (1->cali_fgain3) + */ + if (probe->index == 0) { + drift = (devc->mstatus.ch0_acc_mean / mean - 1) / ratio; + if (fabs(drift) > MAX_ACC_VARIANCE / ignore_ratio) + probe->cali_fgain0 /= (1 + drift); + drift = (devc->mstatus.ch0_acc_mean_p2 / mean - 1) / ratio; + if (fabs(drift) > MAX_ACC_VARIANCE / ignore_ratio) + probe->cali_fgain1 /= (1 + drift); + drift = (devc->mstatus.ch0_acc_mean_p1 / mean - 1) / ratio; + if (fabs(drift) > MAX_ACC_VARIANCE / ignore_ratio) + probe->cali_fgain2 /= (1 + drift); + drift = (devc->mstatus.ch0_acc_mean_p3 / mean - 1) / ratio; + if (fabs(drift) > MAX_ACC_VARIANCE / ignore_ratio) + probe->cali_fgain3 /= (1 + drift); + } else { + drift = (devc->mstatus.ch1_acc_mean / mean - 1) / ratio; + if (fabs(drift) > MAX_ACC_VARIANCE / ignore_ratio) + probe->cali_fgain0 /= (1 + drift); + drift = (devc->mstatus.ch1_acc_mean_p2 / mean - 1) / ratio; + if (fabs(drift) > MAX_ACC_VARIANCE / ignore_ratio) + probe->cali_fgain1 /= (1 + drift); + drift = (devc->mstatus.ch1_acc_mean_p1 / mean - 1) / ratio; + if (fabs(drift) > MAX_ACC_VARIANCE / ignore_ratio) + probe->cali_fgain2 /= (1 + drift); + drift = (devc->mstatus.ch1_acc_mean_p3 / mean - 1) / ratio; + if (fabs(drift) > MAX_ACC_VARIANCE / ignore_ratio) + probe->cali_fgain3 /= (1 + drift); + } + + probe->cali_fgain0 = max(min(probe->cali_fgain0, UPGAIN), DNGAIN); + probe->cali_fgain1 = max(min(probe->cali_fgain1, UPGAIN), DNGAIN); + probe->cali_fgain2 = max(min(probe->cali_fgain2, UPGAIN), DNGAIN); + probe->cali_fgain3 = max(min(probe->cali_fgain3, UPGAIN), DNGAIN); + } + } + + return SR_OK; +} + +SR_PRIV gboolean dsl_probe_fgain_inrange(struct sr_channel *probe, gboolean comb, double skew[]) +{ + const double UPGAIN = 1.0077; + const double DNGAIN = 0.9923; + + if (comb) { + if (probe->index == 0) { + if (fabs(skew[0]) > MAX_ACC_VARIANCE && probe->cali_comb_fgain0 > DNGAIN && probe->cali_comb_fgain0 < UPGAIN) + return TRUE; + if (fabs(skew[1]) > MAX_ACC_VARIANCE && probe->cali_comb_fgain1 > DNGAIN && probe->cali_comb_fgain1 < UPGAIN) + return TRUE; + if (fabs(skew[6]) > MAX_ACC_VARIANCE && probe->cali_comb_fgain2 > DNGAIN && probe->cali_comb_fgain2 < UPGAIN) + return TRUE; + if (fabs(skew[7]) > MAX_ACC_VARIANCE && probe->cali_comb_fgain3 > DNGAIN && probe->cali_comb_fgain3 < UPGAIN) + return TRUE; + } else { + if (fabs(skew[5]) > MAX_ACC_VARIANCE && probe->cali_comb_fgain0 > DNGAIN && probe->cali_comb_fgain0 < UPGAIN) + return TRUE; + if (fabs(skew[4]) > MAX_ACC_VARIANCE && probe->cali_comb_fgain1 > DNGAIN && probe->cali_comb_fgain1 < UPGAIN) + return TRUE; + if (fabs(skew[3]) > MAX_ACC_VARIANCE && probe->cali_comb_fgain2 > DNGAIN && probe->cali_comb_fgain2 < UPGAIN) + return TRUE; + if (fabs(skew[2]) > MAX_ACC_VARIANCE && probe->cali_comb_fgain3 > DNGAIN && probe->cali_comb_fgain3 < UPGAIN) + return TRUE; + } + } else { + if (probe->index == 0) { + if (fabs(skew[0]) > MAX_ACC_VARIANCE && probe->cali_fgain0 > DNGAIN && probe->cali_fgain0 < UPGAIN) + return TRUE; + if (fabs(skew[2]) > MAX_ACC_VARIANCE && probe->cali_fgain1 > DNGAIN && probe->cali_fgain1 < UPGAIN) + return TRUE; + if (fabs(skew[1]) > MAX_ACC_VARIANCE && probe->cali_fgain2 > DNGAIN && probe->cali_fgain2 < UPGAIN) + return TRUE; + if (fabs(skew[3]) > MAX_ACC_VARIANCE && probe->cali_fgain3 > DNGAIN && probe->cali_fgain3 < UPGAIN) + return TRUE; + } else { + if (fabs(skew[4]) > MAX_ACC_VARIANCE && probe->cali_fgain0 > DNGAIN && probe->cali_fgain0 < UPGAIN) + return TRUE; + if (fabs(skew[6]) > MAX_ACC_VARIANCE && probe->cali_fgain1 > DNGAIN && probe->cali_fgain1 < UPGAIN) + return TRUE; + if (fabs(skew[5]) > MAX_ACC_VARIANCE && probe->cali_fgain2 > DNGAIN && probe->cali_fgain2 < UPGAIN) + return TRUE; + if (fabs(skew[7]) > MAX_ACC_VARIANCE && probe->cali_fgain3 > DNGAIN && probe->cali_fgain3 < UPGAIN) + return TRUE; + } + } + + return FALSE; +} + SR_PRIV int dsl_rd_probe(const struct sr_dev_inst *sdi, unsigned char *ctx, uint16_t addr, uint8_t len) { struct sr_usb_dev_inst *usb; @@ -802,6 +1086,13 @@ SR_PRIV int dsl_fpga_arm(const struct sr_dev_inst *sdi) setting.ch_en_h += probe->enabled << (probe->index - 16); } + // digital fgain + for (l = sdi->channels; l; l = l->next) { + struct sr_channel *probe = (struct sr_channel *)l->data; + setting.fgain = probe->digi_fgain; + break; + } + // trigger advanced configuration if (trigger->trigger_mode == SIMPLE_TRIGGER) { qutr_trig = !(devc->profile->dev_caps.feature_caps & CAPS_FEATURE_USB30) && (setting.mode & (1 << QUAR_MODE_BIT)); @@ -1156,7 +1447,7 @@ SR_PRIV int dsl_config_get(int id, GVariant **data, const struct sr_dev_inst *sd case SR_CONF_USB30_SUPPORT: if (!sdi) return SR_ERR; - *data = g_variant_new_boolean(devc->profile->dev_caps.feature_caps & CAPS_FEATURE_USB30); + *data = g_variant_new_boolean((devc->profile->dev_caps.feature_caps & CAPS_FEATURE_USB30) != 0); break; case SR_CONF_LIMIT_SAMPLES: if (!sdi) @@ -1171,7 +1462,10 @@ SR_PRIV int dsl_config_get(int id, GVariant **data, const struct sr_dev_inst *sd case SR_CONF_RLE_SUPPORT: if (!sdi) return SR_ERR; - *data = g_variant_new_boolean(devc->rle_support); + if ((devc->test_mode != SR_TEST_NONE)) + *data = g_variant_new_boolean(FALSE); + else + *data = g_variant_new_boolean(devc->rle_support); break; case SR_CONF_CLOCK_TYPE: if (!sdi) @@ -1280,7 +1574,7 @@ SR_PRIV int dsl_config_get(int id, GVariant **data, const struct sr_dev_inst *sd case SR_CONF_HAVE_ZERO: if (!sdi) return SR_ERR; - *data = g_variant_new_boolean(devc->profile->dev_caps.feature_caps & CAPS_FEATURE_ZERO); + *data = g_variant_new_boolean((devc->profile->dev_caps.feature_caps & CAPS_FEATURE_ZERO) != 0); break; case SR_CONF_ZERO: if (!sdi) @@ -1290,6 +1584,11 @@ SR_PRIV int dsl_config_get(int id, GVariant **data, const struct sr_dev_inst *sd else *data = g_variant_new_boolean(FALSE); break; + case SR_CONF_ZERO_COMB_FGAIN: + if (!sdi) + return SR_ERR; + *data = g_variant_new_boolean(devc->zero_comb_fgain); + break; case SR_CONF_ROLL: if (!sdi) return SR_ERR; @@ -1362,6 +1661,8 @@ SR_PRIV int dsl_config_set(int id, GVariant *data, struct sr_dev_inst *sdi, if (id == SR_CONF_LANGUAGE) { devc->language = g_variant_get_int16(data); + } else if (id == SR_CONF_ZERO_COMB) { + devc->zero_comb = g_variant_get_boolean(data); } else if (id == SR_CONF_PROBE_MAP_DEFAULT) { ch->map_default = g_variant_get_boolean(data); if (ch->map_default) { @@ -1579,24 +1880,14 @@ SR_PRIV int dsl_dev_acquisition_stop(const struct sr_dev_inst *sdi, void *cb_dat return SR_OK; } -SR_PRIV int dsl_dev_status_get(const struct sr_dev_inst *sdi, struct sr_status *status, gboolean prg, int begin, int end) +SR_PRIV int dsl_dev_status_get(const struct sr_dev_inst *sdi, struct sr_status *status, gboolean prg) { int ret = SR_ERR; - struct ctl_rd_cmd rd_cmd; if (sdi) { struct DSL_context *devc; - struct sr_usb_dev_inst *usb; - devc = sdi->priv; - usb = sdi->conn; - if (prg && (devc->status == DSL_START)) { - rd_cmd.header.dest = DSL_CTL_I2C_STATUS; - rd_cmd.header.offset = begin; - rd_cmd.header.size = end - begin + 1; - rd_cmd.data = (unsigned char*)status; - ret = command_ctl_rd(usb->devhdl, rd_cmd); - } else if (devc->mstatus_valid) { + if (prg || devc->mstatus_valid) { *status = devc->mstatus; ret = SR_OK; } @@ -1630,7 +1921,7 @@ static unsigned int to_bytes_per_ms(struct DSL_context *devc) if (devc->cur_samplerate > SR_MHZ(100)) return SR_MHZ(100) / 1000.0 * dsl_en_ch_num(sdi); else - return ceil(devc->cur_samplerate / 1000.0 * dsl_en_ch_num(sdi)); + return ceil(max(devc->cur_samplerate, channel_modes[devc->ch_mode].hw_min_samplerate) / 1000.0 * dsl_en_ch_num(sdi)); } } @@ -1638,7 +1929,7 @@ SR_PRIV int dsl_header_size(const struct DSL_context *devc) { int size; - if (devc->profile->usb_speed == LIBUSB_SPEED_SUPER) + if (devc->profile->dev_caps.feature_caps & CAPS_FEATURE_USB30) size = SR_KB(1); else size = SR_B(512); @@ -1660,7 +1951,11 @@ static size_t get_buffer_size(const struct sr_dev_inst *sdi) } else { s = (devc->stream) ? get_single_buffer_time(devc) * to_bytes_per_ms(devc) : 1024*1024; } - return (s + 511ULL) & ~511ULL; + + if (devc->profile->usb_speed == LIBUSB_SPEED_SUPER) + return (s + 1023ULL) & ~1023ULL; + else + return (s + 511ULL) & ~511ULL; } static unsigned int get_number_of_transfers(const struct sr_dev_inst *sdi) @@ -1673,7 +1968,8 @@ static unsigned int get_number_of_transfers(const struct sr_dev_inst *sdi) /* Total buffer size should be able to hold about 100ms of data. */ n = (devc->stream) ? ceil(get_total_buffer_time(devc) * 1.0f * to_bytes_per_ms(devc) / get_buffer_size(sdi)) : 1; #else - n = (devc->stream) ? ceil(get_total_buffer_time(devc) * 1.0f * to_bytes_per_ms(devc) / get_buffer_size(sdi)) : 4; + n = (devc->stream) ? ceil(get_total_buffer_time(devc) * 1.0f * to_bytes_per_ms(devc) / get_buffer_size(sdi)) : + (devc->profile->usb_speed == LIBUSB_SPEED_SUPER) ? 16 : 4; #endif if (n > NUM_SIMUL_TRANSFERS) @@ -1695,7 +1991,7 @@ SR_PRIV unsigned int dsl_get_timeout(const struct sr_dev_inst *sdi) if (devc->stream) return timeout + timeout / 4; /* Leave a headroom of 25% percent. */ else - return 1000; + return 20; } static void finish_acquisition(struct DSL_context *devc) @@ -1756,6 +2052,7 @@ static void get_measure(const struct sr_dev_inst *sdi, uint8_t *buf, uint32_t of { uint64_t u64_tmp; struct DSL_context *devc = sdi->priv; + GSList *l; devc->mstatus.pkt_id = *((const uint16_t*)buf + offset); devc->mstatus.vlen = *((const uint32_t*)buf + offset/2 + 2/2) & 0x0fffffff; @@ -1779,8 +2076,11 @@ static void get_measure(const struct sr_dev_inst *sdi, uint8_t *buf, uint32_t of devc->mstatus.ch0_low_level = *((const uint8_t*)buf + offset*2 + 43*2+1); devc->mstatus.ch0_cyc_rlen = *((const uint32_t*)buf + offset/2 + 44/2); devc->mstatus.ch0_cyc_flen = *((const uint32_t*)buf + offset/2 + 46/2); - devc->mstatus.ch0_acc_square = *((const uint64_t*)buf + offset/4 + 48/4); + devc->mstatus.ch0_acc_square = *((const uint64_t*)buf + offset/4 + 48/4) & 0x0000FFFFFFFFFFFF; devc->mstatus.ch0_acc_mean = *((const uint32_t*)buf + offset/2 + 52/2); + devc->mstatus.ch0_acc_mean_p1 = *((const uint32_t*)buf + offset/2 + 54/2); + devc->mstatus.ch0_acc_mean_p2 = *((const uint32_t*)buf + offset/2 + 56/2); + devc->mstatus.ch0_acc_mean_p3 = *((const uint32_t*)buf + offset/2 + 58/2); devc->mstatus.ch1_max = *((const uint8_t*)buf + offset*2 + 65*2); devc->mstatus.ch1_min = *((const uint8_t*)buf + offset*2 + 65*2+1); @@ -1794,16 +2094,46 @@ static void get_measure(const struct sr_dev_inst *sdi, uint8_t *buf, uint32_t of devc->mstatus.ch1_low_level = *((const uint8_t*)buf + offset*2 + 75*2+1); devc->mstatus.ch1_cyc_rlen = *((const uint32_t*)buf + offset/2 + 76/2); devc->mstatus.ch1_cyc_flen = *((const uint32_t*)buf + offset/2 + 78/2); - devc->mstatus.ch1_acc_square = *((const uint64_t*)buf + offset/4 + 80/4); + devc->mstatus.ch1_acc_square = *((const uint64_t*)buf + offset/4 + 80/4) & 0x0000FFFFFFFFFFFF; devc->mstatus.ch1_acc_mean = *((const uint32_t*)buf + offset/2 + 84/2); + devc->mstatus.ch1_acc_mean_p1 = *((const uint32_t*)buf + offset/2 + 86/2); + devc->mstatus.ch1_acc_mean_p2 = *((const uint32_t*)buf + offset/2 + 88/2); + devc->mstatus.ch1_acc_mean_p3 = *((const uint32_t*)buf + offset/2 + 90/2); + + if (!devc->zero_branch) { + devc->mstatus.ch0_acc_mean += devc->mstatus.ch0_acc_mean_p1; + devc->mstatus.ch0_acc_mean += devc->mstatus.ch0_acc_mean_p2; + devc->mstatus.ch0_acc_mean += devc->mstatus.ch0_acc_mean_p3; + + devc->mstatus.ch1_acc_mean += devc->mstatus.ch1_acc_mean_p1; + devc->mstatus.ch1_acc_mean += devc->mstatus.ch1_acc_mean_p2; + devc->mstatus.ch1_acc_mean += devc->mstatus.ch1_acc_mean_p3; + + if (1 == dsl_en_ch_num(sdi)) { + u64_tmp = devc->mstatus.ch0_acc_square + devc->mstatus.ch1_acc_square; + devc->mstatus.ch0_acc_square = u64_tmp; + devc->mstatus.ch1_acc_square = u64_tmp; + u64_tmp = devc->mstatus.ch0_acc_mean + devc->mstatus.ch1_acc_mean; + devc->mstatus.ch0_acc_mean = u64_tmp; + devc->mstatus.ch1_acc_mean = u64_tmp; + } + } + + devc->mstatus_valid = FALSE; + const uint32_t divider = devc->zero ? 0x1 : (uint32_t)ceil(channel_modes[devc->ch_mode].max_samplerate * 1.0 / devc->cur_samplerate / dsl_en_ch_num(sdi)); + if (devc->instant) { + devc->mstatus_valid = (devc->mstatus.pkt_id == DSO_PKTID); + } else if (devc->mstatus.pkt_id == DSO_PKTID && + devc->mstatus.sample_divider == divider && + devc->mstatus.vlen != 0) { + devc->mstatus_valid = TRUE; + } - if (1 == dsl_en_ch_num(sdi)) { - u64_tmp = devc->mstatus.ch0_acc_square + devc->mstatus.ch1_acc_square; - devc->mstatus.ch0_acc_square = u64_tmp; - devc->mstatus.ch1_acc_square = u64_tmp; - u64_tmp = devc->mstatus.ch0_acc_mean + devc->mstatus.ch1_acc_mean; - devc->mstatus.ch0_acc_mean = u64_tmp; - devc->mstatus.ch0_acc_mean = u64_tmp; + if (devc->mstatus_valid) { + for (l = sdi->channels; l; l = l->next) { + struct sr_channel *probe = (struct sr_channel *)l->data; + probe->hw_offset = *((const uint8_t*)buf + offset*2 + (51 + 32*probe->index)*2); + } } } @@ -1856,16 +2186,13 @@ static void receive_transfer(struct libusb_transfer *transfer) get_measure(sdi, cur_buf, offset); } else { devc->mstatus.vlen = get_buffer_size(sdi) / channel_modes[devc->ch_mode].num; + devc->mstatus.trig_offset = 0; + devc->mstatus.sample_divider_tog = FALSE; + devc->mstatus_valid = TRUE; } - const uint32_t divider = devc->zero ? 0x1 : (uint32_t)ceil(channel_modes[devc->ch_mode].max_samplerate * 1.0 / devc->cur_samplerate / dsl_en_ch_num(sdi)); - if ((devc->mstatus.pkt_id == DSO_PKTID && - devc->mstatus.sample_divider == divider && - devc->mstatus.vlen != 0 && - devc->mstatus.vlen <= (uint32_t)(transfer->actual_length - dsl_header_size(devc)) / 2) || - devc->instant) { + if (devc->mstatus_valid) { devc->roll = (devc->mstatus.stream_mode != 0); - devc->mstatus_valid = devc->instant ? FALSE : TRUE; packet.type = SR_DF_DSO; packet.payload = &dso; dso.probes = sdi->channels; @@ -1876,11 +2203,11 @@ static void receive_transfer(struct libusb_transfer *transfer) dso.mqflags = SR_MQFLAG_AC; dso.samplerate_tog = (devc->mstatus.sample_divider_tog != 0); dso.trig_flag = (devc->mstatus.trig_flag != 0); - dso.data = cur_buf; + dso.trig_ch = devc->mstatus.trig_ch; + dso.data = cur_buf + (devc->zero ? 0 : 2*devc->mstatus.trig_offset); } else { packet.type = SR_DF_DSO; packet.status = SR_PKT_DATA_ERROR; - devc->mstatus_valid = FALSE; } } else if (sdi->mode == ANALOG) { packet.type = SR_DF_ANALOG; @@ -1902,14 +2229,8 @@ static void receive_transfer(struct libusb_transfer *transfer) logic.length = min(logic.length, remain_length); /* send data to session bus */ - if (!devc->overflow) { - if (packet.status == SR_PKT_OK) - sr_session_send(sdi, &packet); - } else { - packet.type = SR_DF_OVERFLOW; - packet.payload = NULL; + if (packet.status == SR_PKT_OK) sr_session_send(sdi, &packet); - } } devc->num_samples += cur_sample_count; @@ -1925,8 +2246,6 @@ static void receive_transfer(struct libusb_transfer *transfer) if (over_bytes >= devc->instant_tail_bytes) { const uint32_t offset = (transfer->actual_length - over_bytes) / 2; get_measure(sdi, cur_buf, offset); - if (devc->mstatus.pkt_id == DSO_PKTID) - devc->mstatus_valid = TRUE; devc->status = DSL_STOP; } else { @@ -1968,7 +2287,7 @@ static void receive_header(struct libusb_transfer *transfer) devc->stream || remain_cnt < devc->limit_samples) { if (sdi->mode == LOGIC && (!devc->stream || (devc->status == DSL_ABORT))) { - devc->actual_samples = devc->limit_samples - remain_cnt; + devc->actual_samples = (devc->limit_samples - remain_cnt) & ~SAMPLES_ALIGN; devc->actual_bytes = devc->actual_samples / DSLOGIC_ATOMIC_SAMPLES * dsl_en_ch_num(sdi) * DSLOGIC_ATOMIC_SIZE; devc->actual_samples = devc->actual_bytes / dsl_en_ch_num(sdi) * 8; } diff --git a/libsigrok4DSL/hardware/DSL/dsl.h b/libsigrok4DSL/hardware/DSL/dsl.h index 2376784217e132186d1ed9ac729bdede50ad81ef..a30e7a94c18acc56266cf0512d9cd8b121477df5 100755 --- a/libsigrok4DSL/hardware/DSL/dsl.h +++ b/libsigrok4DSL/hardware/DSL/dsl.h @@ -54,6 +54,7 @@ #define USB_CONFIGURATION 1 #define NUM_TRIGGER_STAGES 16 #define NUM_SIMUL_TRANSFERS 64 +#define MAX_EMPTY_POLL 16 #define DSL_REQUIRED_VERSION_MAJOR 2 #define DSL_REQUIRED_VERSION_MINOR 0 @@ -132,6 +133,11 @@ #define TRIG_CHECKID 0x55555555 #define DSO_PKTID 0xa500 +/* + * zero configuration + */ +#define DSO_ZERO_PAGE 8 +#define MAX_ACC_VARIANCE 0.0005 /* * for DSCope device * trans: x << 8 + y @@ -341,14 +347,14 @@ static const struct DSL_vga vga_defaults[] = { {3, 1000, 0x57200, 45, 1024-920-45}, {3, 2000, 0x2DD00, 45, 1024-920-45}, - {4, 10, 0x1C6C00, 45, 1024-945-45}, - {4, 20, 0x19E000, 45, 1024-945-45}, - {4, 50, 0x16A800, 45, 1024-945-45}, - {4, 100, 0x142800, 45, 1024-945-45}, - {4, 200, 0xC7F00, 45, 1024-945-45}, - {4, 500, 0x94000, 45, 1024-945-45}, - {4, 1000, 0x6CF00, 45, 1024-945-45}, - {4, 2000, 0x44F00, 45, 1024-945-45}, + {4, 10, 0x1C6C00, 60, 1024-900-60}, + {4, 20, 0x19E000, 60, 1024-900-60}, + {4, 50, 0x16A800, 60, 1024-900-60}, + {4, 100, 0x142800, 60, 1024-900-60}, + {4, 200, 0xC7F00, 60, 1024-900-60}, + {4, 500, 0x94000, 60, 1024-900-60}, + {4, 1000, 0x6CF00, 60, 1024-900-60}, + {4, 2000, 0x44F00, 60, 1024-900-60}, {0, 0, 0, 0, 0} }; @@ -358,19 +364,36 @@ enum CHANNEL_ID { DSL_STREAM25x12, DSL_STREAM50x6, DSL_STREAM100x3, - DSL_STREAM100x16, - DSL_STREAM125x16, + + DSL_STREAM20x16_3DN2, + DSL_STREAM25x12_3DN2, + DSL_STREAM50x6_3DN2, + DSL_STREAM100x3_3DN2, + + DSL_STREAM10x32_32_3DN2, + DSL_STREAM20x16_32_3DN2, + DSL_STREAM25x12_32_3DN2, + DSL_STREAM50x6_32_3DN2, + DSL_STREAM100x3_32_3DN2, + + DSL_STREAM50x32, + DSL_STREAM100x30, DSL_STREAM250x12, + DSL_STREAM125x16_16, + DSL_STREAM250x12_16, DSL_STREAM500x6, DSL_STREAM1000x3, DSL_BUFFER100x16, DSL_BUFFER200x8, DSL_BUFFER400x4, + + DSL_BUFFER250x32, DSL_BUFFER500x16, DSL_BUFFER1000x8, DSL_ANALOG10x2, + DSL_ANALOG10x2_500, DSL_DSO200x2, DSL_DSO1000x2, @@ -403,15 +426,40 @@ static const struct DSL_channels channel_modes[] = { SR_KHZ(10), SR_MHZ(100), 1, "Use 6 Channels (Max 50MHz)", "使用6个通é“(æœ€å¤§é‡‡æ ·çŽ‡ 50MHz)"}, {DSL_STREAM100x3, LOGIC, SR_CHANNEL_LOGIC, TRUE, 16, 3, 1, SR_KHZ(10), SR_MHZ(100), SR_KHZ(10), SR_MHZ(100), 1, "Use 3 Channels (Max 100MHz)", "使用3个通é“(æœ€å¤§é‡‡æ ·çŽ‡ 100MHz)"}, - {DSL_STREAM100x16, LOGIC, SR_CHANNEL_LOGIC, TRUE, 16, 16, 1, SR_KHZ(10), SR_MHZ(100), - SR_KHZ(10), SR_MHZ(500), 5, "Use 16 Channels (Max 100MHz)", "使用16个通é“(æœ€å¤§é‡‡æ ·çŽ‡ 100MHz)"}, - {DSL_STREAM125x16, LOGIC, SR_CHANNEL_LOGIC, TRUE, 16, 16, 1, SR_KHZ(10), SR_MHZ(125), + + {DSL_STREAM20x16_3DN2, LOGIC, SR_CHANNEL_LOGIC, TRUE, 16, 16, 1, SR_KHZ(10), SR_MHZ(20), + SR_KHZ(10), SR_MHZ(500), 5, "Use 16 Channels (Max 20MHz)", "使用16个通é“(æœ€å¤§é‡‡æ ·çŽ‡ 20MHz)"}, + {DSL_STREAM25x12_3DN2, LOGIC, SR_CHANNEL_LOGIC, TRUE, 16, 12, 1, SR_KHZ(10), SR_MHZ(25), + SR_KHZ(10), SR_MHZ(500), 5, "Use 12 Channels (Max 25MHz)", "使用12个通é“(æœ€å¤§é‡‡æ ·çŽ‡ 25MHz)"}, + {DSL_STREAM50x6_3DN2, LOGIC, SR_CHANNEL_LOGIC, TRUE, 16, 6, 1, SR_KHZ(10), SR_MHZ(50), + SR_KHZ(10), SR_MHZ(500), 5, "Use 6 Channels (Max 50MHz)", "使用6个通é“(æœ€å¤§é‡‡æ ·çŽ‡ 50MHz)"}, + {DSL_STREAM100x3_3DN2, LOGIC, SR_CHANNEL_LOGIC, TRUE, 16, 3, 1, SR_KHZ(10), SR_MHZ(100), + SR_KHZ(10), SR_MHZ(500), 5, "Use 3 Channels (Max 100MHz)", "使用3个通é“(æœ€å¤§é‡‡æ ·çŽ‡ 100MHz)"}, + + {DSL_STREAM10x32_32_3DN2, LOGIC, SR_CHANNEL_LOGIC, TRUE, 32, 32, 1, SR_KHZ(10), SR_MHZ(10), + SR_KHZ(10), SR_MHZ(500), 5, "Use 32 Channels (Max 10MHz)", "使用32个通é“(æœ€å¤§é‡‡æ ·çŽ‡ 10MHz)"}, + {DSL_STREAM20x16_32_3DN2, LOGIC, SR_CHANNEL_LOGIC, TRUE, 32, 16, 1, SR_KHZ(10), SR_MHZ(20), + SR_KHZ(10), SR_MHZ(500), 5, "Use 16 Channels (Max 20MHz)", "使用16个通é“(æœ€å¤§é‡‡æ ·çŽ‡ 20MHz)"}, + {DSL_STREAM25x12_32_3DN2, LOGIC, SR_CHANNEL_LOGIC, TRUE, 32, 12, 1, SR_KHZ(10), SR_MHZ(25), + SR_KHZ(10), SR_MHZ(500), 5, "Use 12 Channels (Max 25MHz)", "使用12个通é“(æœ€å¤§é‡‡æ ·çŽ‡ 25MHz)"}, + {DSL_STREAM50x6_32_3DN2, LOGIC, SR_CHANNEL_LOGIC, TRUE, 32, 6, 1, SR_KHZ(10), SR_MHZ(50), + SR_KHZ(10), SR_MHZ(500), 5, "Use 6 Channels (Max 50MHz)", "使用6个通é“(æœ€å¤§é‡‡æ ·çŽ‡ 50MHz)"}, + {DSL_STREAM100x3_32_3DN2, LOGIC, SR_CHANNEL_LOGIC, TRUE, 32, 3, 1, SR_KHZ(10), SR_MHZ(100), + SR_KHZ(10), SR_MHZ(500), 5, "Use 3 Channels (Max 100MHz)", "使用3个通é“(æœ€å¤§é‡‡æ ·çŽ‡ 100MHz)"}, + + {DSL_STREAM50x32, LOGIC, SR_CHANNEL_LOGIC, TRUE, 32, 32, 1, SR_KHZ(10), SR_MHZ(50), + SR_KHZ(10), SR_MHZ(500), 5, "Use 32 Channels (Max 50MHz)", "使用32个通é“(æœ€å¤§é‡‡æ ·çŽ‡ 50MHz)"}, + {DSL_STREAM100x30, LOGIC, SR_CHANNEL_LOGIC, TRUE, 32, 30, 1, SR_KHZ(10), SR_MHZ(100), + SR_KHZ(10), SR_MHZ(500), 5, "Use 30 Channels (Max 100MHz)", "使用30个通é“(æœ€å¤§é‡‡æ ·çŽ‡ 100MHz)"}, + {DSL_STREAM250x12, LOGIC, SR_CHANNEL_LOGIC, TRUE, 32, 12, 1, SR_KHZ(10), SR_MHZ(250), + SR_KHZ(10), SR_MHZ(500), 5, "Use 12 Channels (Max 250MHz)", "使用12个通é“(æœ€å¤§é‡‡æ ·çŽ‡ 250MHz)"}, + {DSL_STREAM125x16_16, LOGIC, SR_CHANNEL_LOGIC, TRUE, 16, 16, 1, SR_KHZ(10), SR_MHZ(125), SR_KHZ(10), SR_MHZ(500), 5, "Use 16 Channels (Max 125MHz)", "使用16个通é“(æœ€å¤§é‡‡æ ·çŽ‡ 125MHz)"}, - {DSL_STREAM250x12, LOGIC, SR_CHANNEL_LOGIC, TRUE, 16, 12, 1, SR_KHZ(10), SR_MHZ(250), + {DSL_STREAM250x12_16, LOGIC, SR_CHANNEL_LOGIC, TRUE, 16, 12, 1, SR_KHZ(10), SR_MHZ(250), SR_KHZ(10), SR_MHZ(500), 5, "Use 12 Channels (Max 250MHz)", "使用12个通é“(æœ€å¤§é‡‡æ ·çŽ‡ 250MHz)"}, {DSL_STREAM500x6, LOGIC, SR_CHANNEL_LOGIC, TRUE, 16, 6, 1, SR_KHZ(10), SR_MHZ(500), SR_KHZ(10), SR_MHZ(500), 5, "Use 6 Channels (Max 500MHz)", "使用6个通é“(æœ€å¤§é‡‡æ ·çŽ‡ 500MHz)"}, - {DSL_STREAM1000x3, LOGIC, SR_CHANNEL_LOGIC, TRUE, 16, 3, 1, SR_KHZ(10), SR_GHZ(1), + {DSL_STREAM1000x3, LOGIC, SR_CHANNEL_LOGIC, TRUE, 8, 3, 1, SR_KHZ(10), SR_GHZ(1), SR_KHZ(10), SR_MHZ(500), 5, "Use 3 Channels (Max 1GHz)", "使用3个通é“(æœ€å¤§é‡‡æ ·çŽ‡ 1GHz)"}, // LA Buffer @@ -421,6 +469,9 @@ static const struct DSL_channels channel_modes[] = { SR_KHZ(10), SR_MHZ(100), 1, "Use Channels 0~7 (Max 200MHz)", "ä½¿ç”¨é€šé“ 0~7 (æœ€å¤§é‡‡æ ·çŽ‡ 200MHz)"}, {DSL_BUFFER400x4, LOGIC, SR_CHANNEL_LOGIC, FALSE, 4, 4, 1, SR_KHZ(10), SR_MHZ(400), SR_KHZ(10), SR_MHZ(100), 1, "Use Channels 0~3 (Max 400MHz)", "ä½¿ç”¨é€šé“ 0~3 (æœ€å¤§é‡‡æ ·çŽ‡ 400MHz)"}, + + {DSL_BUFFER250x32, LOGIC, SR_CHANNEL_LOGIC, FALSE, 32, 32, 1, SR_KHZ(10), SR_MHZ(250), + SR_KHZ(10), SR_MHZ(500), 5, "Use Channels 0~31 (Max 250MHz)", "ä½¿ç”¨é€šé“ 0~31 (æœ€å¤§é‡‡æ ·çŽ‡ 250MHz)"}, {DSL_BUFFER500x16, LOGIC, SR_CHANNEL_LOGIC, FALSE, 16, 16, 1, SR_KHZ(10), SR_MHZ(500), SR_KHZ(10), SR_MHZ(500), 5, "Use Channels 0~15 (Max 500MHz)", "ä½¿ç”¨é€šé“ 0~15 (æœ€å¤§é‡‡æ ·çŽ‡ 500MHz)"}, {DSL_BUFFER1000x8, LOGIC, SR_CHANNEL_LOGIC, FALSE, 8, 8, 1, SR_KHZ(10), SR_GHZ(1), @@ -429,12 +480,14 @@ static const struct DSL_channels channel_modes[] = { // DAQ {DSL_ANALOG10x2, ANALOG, SR_CHANNEL_ANALOG, TRUE, 2, 2, 8, SR_HZ(10), SR_MHZ(10), SR_KHZ(10), SR_MHZ(100), 1, "Use Channels 0~1 (Max 10MHz)", "ä½¿ç”¨é€šé“ 0~1 (æœ€å¤§é‡‡æ ·çŽ‡ 10MHz)"}, + {DSL_ANALOG10x2_500, ANALOG, SR_CHANNEL_ANALOG, TRUE, 2, 2, 8, SR_HZ(10), SR_MHZ(10), + SR_KHZ(10), SR_MHZ(500), 1, "Use Channels 0~1 (Max 10MHz)", "ä½¿ç”¨é€šé“ 0~1 (æœ€å¤§é‡‡æ ·çŽ‡ 10MHz)"}, // OSC {DSL_DSO200x2, DSO, SR_CHANNEL_DSO, FALSE, 2, 2, 8, SR_KHZ(10), SR_MHZ(200), SR_KHZ(10), SR_MHZ(100), 1, "Use Channels 0~1 (Max 200MHz)", "ä½¿ç”¨é€šé“ 0~1 (æœ€å¤§é‡‡æ ·çŽ‡ 200MHz)"}, {DSL_DSO1000x2, DSO, SR_CHANNEL_DSO, FALSE, 2, 2, 8, SR_KHZ(10), SR_GHZ(1), - SR_KHZ(10), SR_MHZ(100), 1, "Use Channels 0~1 (Max 1GHz)", "ä½¿ç”¨é€šé“ 0~1 (æœ€å¤§é‡‡æ ·çŽ‡ 1GHz)"} + SR_KHZ(10), SR_MHZ(500), 1, "Use Channels 0~1 (Max 1GHz)", "ä½¿ç”¨é€šé“ 0~1 (æœ€å¤§é‡‡æ ·çŽ‡ 1GHz)"} }; static const struct DSL_profile supported_DSLogic[] = { @@ -578,6 +631,114 @@ static const struct DSL_profile supported_DSLogic[] = { SR_MHZ(400)} }, + {0x2A0E, 0x002A, LIBUSB_SPEED_HIGH, "DreamSourceLab", "DSLogic U3Pro16", NULL, + "DSLogicU3Pro16.fw", + "DSLogicU3Pro16.bin", + "DSLogicU3Pro16.bin", + {CAPS_MODE_LOGIC, + CAPS_FEATURE_VTH | CAPS_FEATURE_BUF | CAPS_FEATURE_USB30 | CAPS_FEATURE_ADF4360, + (1 << DSL_STREAM20x16_3DN2) | (1 << DSL_STREAM25x12_3DN2) | (1 << DSL_STREAM50x6_3DN2) | (1 << DSL_STREAM100x3_3DN2) | + (1 << DSL_BUFFER500x16) | (1 << DSL_BUFFER1000x8), + 16, + SR_GB(2), + 0, + DSL_BUFFER500x16, + 0, + samplerates1000, + 0, + DSL_STREAM20x16_3DN2, + SR_MHZ(1), + SR_Mn(1), + 0, + 0, + 0, + 0, + 0, + SR_MHZ(500), + SR_GHZ(1)} + }, + + {0x2A0E, 0x002A, LIBUSB_SPEED_SUPER, "DreamSourceLab", "DSLogic U3Pro16", NULL, + "DSLogicU3Pro16.fw", + "DSLogicU3Pro16.bin", + "DSLogicU3Pro16.bin", + {CAPS_MODE_LOGIC, + CAPS_FEATURE_VTH | CAPS_FEATURE_BUF | CAPS_FEATURE_USB30 | CAPS_FEATURE_ADF4360, + (1 << DSL_STREAM125x16_16) | (1 << DSL_STREAM250x12_16) | (1 << DSL_STREAM500x6) | (1 << DSL_STREAM1000x3) | + (1 << DSL_BUFFER500x16) | (1 << DSL_BUFFER1000x8), + 16, + SR_GB(2), + 0, + DSL_BUFFER500x16, + 0, + samplerates1000, + 0, + DSL_STREAM125x16_16, + SR_MHZ(1), + SR_Mn(1), + 0, + 0, + 0, + 0, + 0, + SR_MHZ(500), + SR_GHZ(1)} + }, + + {0x2A0E, 0x002C, LIBUSB_SPEED_HIGH, "DreamSourceLab", "DSLogic U3Pro32", NULL, + "DSLogicU3Pro32.fw", + "DSLogicU3Pro32.bin", + "DSLogicU3Pro32.bin", + {CAPS_MODE_LOGIC, + CAPS_FEATURE_VTH | CAPS_FEATURE_BUF | CAPS_FEATURE_USB30 | CAPS_FEATURE_ADF4360 | CAPS_FEATURE_LA_CH32, + (1 << DSL_STREAM10x32_32_3DN2) | (1 << DSL_STREAM20x16_32_3DN2) | (1 << DSL_STREAM25x12_32_3DN2) | (1 << DSL_STREAM50x6_32_3DN2) | (1 << DSL_STREAM100x3_32_3DN2) | + (1 << DSL_BUFFER500x16) | (1 << DSL_BUFFER1000x8), + 32, + SR_GB(2), + 0, + DSL_BUFFER250x32, + 0, + samplerates1000, + 0, + DSL_STREAM10x32_32_3DN2, + SR_MHZ(1), + SR_Mn(1), + 0, + 0, + 0, + 0, + 0, + SR_MHZ(500), + SR_GHZ(1)} + }, + + {0x2A0E, 0x002C, LIBUSB_SPEED_SUPER, "DreamSourceLab", "DSLogic U3Pro32", NULL, + "DSLogicU3Pro32.fw", + "DSLogicU3Pro32.bin", + "DSLogicU3Pro32.bin", + {CAPS_MODE_LOGIC, + CAPS_FEATURE_VTH | CAPS_FEATURE_BUF | CAPS_FEATURE_USB30 | CAPS_FEATURE_ADF4360 | CAPS_FEATURE_LA_CH32, + (1 << DSL_STREAM50x32) | (1 << DSL_STREAM100x30) | (1 << DSL_STREAM250x12) | (1 << DSL_STREAM500x6) | (1 << DSL_STREAM1000x3) | + (1 << DSL_BUFFER250x32) | (1 << DSL_BUFFER500x16) | (1 << DSL_BUFFER1000x8), + 32, + SR_GB(2), + 0, + DSL_BUFFER250x32, + 0, + samplerates1000, + 0, + DSL_STREAM50x32, + SR_MHZ(1), + SR_Mn(1), + 0, + 0, + 0, + 0, + 0, + SR_MHZ(500), + SR_GHZ(1)} + }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}} }; @@ -753,7 +914,7 @@ static const struct DSL_profile supported_DSCope[] = { "DSCopeU2B20.bin", "DSCopeU2B20.bin", {CAPS_MODE_ANALOG | CAPS_MODE_DSO, - CAPS_FEATURE_ZERO, + CAPS_FEATURE_ZERO | CAPS_FEATURE_AUTO_VGAIN, (1 << DSL_ANALOG10x2) | (1 << DSL_DSO200x2), 2, @@ -766,8 +927,8 @@ static const struct DSL_profile supported_DSCope[] = { DSL_DSO200x2, SR_MHZ(100), SR_Kn(10), - 945, - 1024-945, + 930, + 1024-930, 10, 245, 22, @@ -780,7 +941,7 @@ static const struct DSL_profile supported_DSCope[] = { "DSCopeU2P20.bin", "DSCopeU2P20.bin", {CAPS_MODE_ANALOG | CAPS_MODE_DSO, - CAPS_FEATURE_ZERO | CAPS_FEATURE_BUF | CAPS_FEATURE_POGOPIN, + CAPS_FEATURE_ZERO | CAPS_FEATURE_BUF | CAPS_FEATURE_POGOPIN | CAPS_FEATURE_AUTO_VGAIN, (1 << DSL_ANALOG10x2) | (1 << DSL_DSO200x2), 2, @@ -793,8 +954,8 @@ static const struct DSL_profile supported_DSCope[] = { DSL_DSO200x2, SR_MHZ(100), SR_Mn(1), - 945, - 1024-945, + 930, + 1024-930, 10, 245, 22, @@ -802,6 +963,86 @@ static const struct DSL_profile supported_DSCope[] = { SR_HZ(0)} }, + {0x2A0E, 0x0028, LIBUSB_SPEED_HIGH, "DreamSourceLab", "DSCope U2B100", NULL, + "DSCopeU2B100.fw", + "DSCopeU2B100.bin", + "DSCopeU2B100.bin", + {CAPS_MODE_ANALOG | CAPS_MODE_DSO, + CAPS_FEATURE_ZERO | CAPS_FEATURE_HMCAD1511 | CAPS_FEATURE_20M, + (1 << DSL_ANALOG10x2_500) | + (1 << DSL_DSO1000x2), + 2, + SR_KB(256), + SR_Kn(20), + 0, + vdivs10to2000, + samplerates1000, + 4, + DSL_DSO1000x2, + SR_MHZ(500), + SR_Kn(10), + 850, + 1024-850, + 10, + 245, + 80, + SR_HZ(0), + SR_HZ(0)} + }, + + {0x2A0E, 0x002B, LIBUSB_SPEED_HIGH, "DreamSourceLab", "DSCope U3P100", NULL, + "DSCopeU3P100.fw", + "DSCopeU3P100.bin", + "DSCopeU3P100.bin", + {CAPS_MODE_ANALOG | CAPS_MODE_DSO, + CAPS_FEATURE_ZERO | CAPS_FEATURE_FLASH | CAPS_FEATURE_USB30 | CAPS_FEATURE_HMCAD1511 | CAPS_FEATURE_20M, + (1 << DSL_ANALOG10x2_500) | + (1 << DSL_DSO1000x2), + 2, + SR_GB(2), + SR_Mn(2), + 0, + vdivs10to2000, + samplerates1000, + 4, + DSL_DSO1000x2, + SR_MHZ(500), + SR_Mn(1), + 900, + 1024-900, + 10, + 245, + 60, + SR_HZ(0), + SR_HZ(0)} + }, + + {0x2A0E, 0x002B, LIBUSB_SPEED_SUPER, "DreamSourceLab", "DSCope U3P100", NULL, + "DSCopeU3P100.fw", + "DSCopeU3P100.bin", + "DSCopeU3P100.bin", + {CAPS_MODE_ANALOG | CAPS_MODE_DSO, + CAPS_FEATURE_ZERO | CAPS_FEATURE_FLASH | CAPS_FEATURE_USB30 | CAPS_FEATURE_HMCAD1511 | CAPS_FEATURE_20M, + (1 << DSL_ANALOG10x2_500) | + (1 << DSL_DSO1000x2), + 2, + SR_GB(2), + SR_Mn(2), + 0, + vdivs10to2000, + samplerates1000, + 4, + DSL_DSO1000x2, + SR_MHZ(500), + SR_Mn(1), + 900, + 1024-900, + 10, + 245, + 60, + SR_HZ(0), + SR_HZ(0)} + }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}} }; @@ -880,6 +1121,9 @@ struct DSL_context { int16_t tune_index; int zero_stage; int zero_pcnt; + gboolean zero_branch; + gboolean zero_comb_fgain; + gboolean zero_comb; int tune_stage; int tune_pcnt; struct sr_channel *tune_probe; @@ -908,6 +1152,7 @@ struct DSL_context { gboolean abort; gboolean overflow; int bw_limit; + int empty_poll_count; int language; }; @@ -1085,6 +1330,13 @@ SR_PRIV int dsl_rd_nvm(const struct sr_dev_inst *sdi, unsigned char *ctx, uint16 SR_PRIV int dsl_rd_probe(const struct sr_dev_inst *sdi, unsigned char *ctx, uint16_t addr, uint8_t len); SR_PRIV int dsl_config_adc(const struct sr_dev_inst *sdi, const struct DSL_adc_config *config); +SR_PRIV double dsl_adc_code2fgain(uint8_t code); +SR_PRIV uint8_t dsl_adc_fgain2code(double gain); +SR_PRIV int dsl_config_adc_fgain(const struct sr_dev_inst *sdi, uint8_t branch, double gain0, double gain1); +SR_PRIV int dsl_config_fpga_fgain(const struct sr_dev_inst *sdi); +SR_PRIV int dsl_skew_fpga_fgain(const struct sr_dev_inst *sdi, gboolean comb, double skew[]); +SR_PRIV int dsl_probe_cali_fgain(struct DSL_context *devc, struct sr_channel *probe, double mean, gboolean comb, gboolean reset); +SR_PRIV gboolean dsl_probe_fgain_inrange(struct sr_channel *probe, gboolean comb, double skew[]); SR_PRIV int dsl_fpga_arm(const struct sr_dev_inst *sdi); SR_PRIV int dsl_fpga_config(struct libusb_device_handle *hdl, const char *filename); @@ -1101,7 +1353,7 @@ SR_PRIV int dsl_config_list(int key, GVariant **data, const struct sr_dev_inst * SR_PRIV int dsl_dev_open(struct sr_dev_driver *di, struct sr_dev_inst *sdi, gboolean *fpga_done); SR_PRIV int dsl_dev_close(struct sr_dev_inst *sdi); SR_PRIV int dsl_dev_acquisition_stop(const struct sr_dev_inst *sdi, void *cb_data); -SR_PRIV int dsl_dev_status_get(const struct sr_dev_inst *sdi, struct sr_status *status, gboolean prg, int begin, int end); +SR_PRIV int dsl_dev_status_get(const struct sr_dev_inst *sdi, struct sr_status *status, gboolean prg); SR_PRIV unsigned int dsl_get_timeout(const struct sr_dev_inst *sdi); SR_PRIV int dsl_start_transfers(const struct sr_dev_inst *sdi); diff --git a/libsigrok4DSL/hardware/DSL/dslogic.c b/libsigrok4DSL/hardware/DSL/dslogic.c index f174cfd989f42afb7d05d6d71f6fac5a260557dc..443c8052ff5950df409af42d7e3089dc8720a743 100755 --- a/libsigrok4DSL/hardware/DSL/dslogic.c +++ b/libsigrok4DSL/hardware/DSL/dslogic.c @@ -228,6 +228,9 @@ static struct DSL_context *DSLogic_dev_new(const struct DSL_profile *prof) devc->trigger_hrate = 0; devc->trigger_holdoff = 0; devc->zero = FALSE; + devc->zero_branch = FALSE; + devc->zero_comb_fgain = FALSE; + devc->zero_comb = FALSE; devc->status = DSL_FINISH; devc->mstatus_valid = FALSE; @@ -932,7 +935,7 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, dsl_adjust_samplerate(devc); if (devc->op_mode == OP_INTEST) { devc->cur_samplerate = devc->stream ? channel_modes[devc->ch_mode].max_samplerate / 10 : - channel_modes[devc->ch_mode].max_samplerate; + SR_MHZ(100); devc->limit_samples = devc->stream ? devc->cur_samplerate * 3 : devc->profile->dev_caps.hw_depth / dsl_en_ch_num(sdi); } @@ -1042,10 +1045,6 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, ch->offset = g_variant_get_uint16(data); sr_dbg("%s: setting OFFSET of channel %d to %d", __func__, ch->index, ch->offset); - } else if (id == SR_CONF_PROBE_HW_OFFSET) { - ch->hw_offset = g_variant_get_uint16(data); - sr_dbg("%s: setting OFFSET of channel %d to %d", __func__, - ch->index, ch->offset); } else if (id == SR_CONF_TRIGGER_SOURCE) { devc->trigger_source = g_variant_get_byte(data); if (sdi->mode == DSO) { @@ -1119,12 +1118,12 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi, for (i = 0; i < ARRAY_SIZE(channel_modes); i++) { if (channel_modes[i].stream == devc->stream && devc->profile->dev_caps.channels & (1 << i)) { + if (devc->test_mode != SR_TEST_NONE && devc->profile->dev_caps.intest_channel != channel_modes[i].id) + continue; if (devc->language == LANGUAGE_CN) g_variant_builder_add(&gvb, "s", channel_modes[i].descr_cn); else g_variant_builder_add(&gvb, "s", channel_modes[i].descr); - if (devc->test_mode != SR_TEST_NONE) - break; } } *data = g_variant_builder_end(&gvb); @@ -1197,6 +1196,17 @@ static void remove_sources(struct DSL_context *devc) g_free(devc->usbfd); } +static void report_overflow(struct DSL_context *devc) +{ + struct sr_datafeed_packet packet; + struct sr_dev_inst *sdi = devc->cb_data; + + packet.status = SR_PKT_OK; + packet.type = SR_DF_OVERFLOW; + packet.payload = NULL; + sr_session_send(sdi, &packet); +} + static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi) { int completed = 0; @@ -1218,16 +1228,44 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi) tv.tv_sec = tv.tv_usec = 0; libusb_handle_events_timeout_completed(drvc->sr_ctx->libusb_ctx, &tv, &completed); - // overflow check - if (devc->stream && devc->trf_completed) { - rd_cmd.header.dest = DSL_CTL_HW_STATUS; - rd_cmd.header.size = 1; - hw_info = 0; - rd_cmd.data = &hw_info; + if (devc->trf_completed) + devc->empty_poll_count = 0; + else + devc->empty_poll_count++; + + // -- + // progress check + // must before overflow check (1ch@10K) + // -- + if ((devc->empty_poll_count > MAX_EMPTY_POLL) && (devc->status == DSL_START)) { + devc->mstatus.captured_cnt0 = 0; + rd_cmd.header.dest = DSL_CTL_I2C_STATUS; + rd_cmd.header.offset = 0; + rd_cmd.header.size = 4; + rd_cmd.data = (unsigned char*)&devc->mstatus; if ((ret = command_ctl_rd(usb->devhdl, rd_cmd)) != SR_OK) - sr_err("Failed to get hardware infos."); - else - devc->overflow = (hw_info & bmSYS_OVERFLOW) != 0; + sr_err("Failed to get progress infos."); + + devc->empty_poll_count = 0; + } + + // overflow check + if (devc->stream) { + if (devc->empty_poll_count > MAX_EMPTY_POLL) { + rd_cmd.header.dest = DSL_CTL_HW_STATUS; + rd_cmd.header.size = 1; + hw_info = 0; + rd_cmd.data = &hw_info; + if ((ret = command_ctl_rd(usb->devhdl, rd_cmd)) != SR_OK) + sr_err("Failed to get hardware infos."); + else + devc->overflow = (hw_info & bmSYS_OVERFLOW) != 0; + + if (devc->overflow) + report_overflow(devc); + + devc->empty_poll_count = 0; + } } if (devc->status == DSL_FINISH) { @@ -1263,13 +1301,19 @@ static int dev_acquisition_start(struct sr_dev_inst *sdi, void *cb_data) devc->num_samples = 0; devc->num_bytes = 0; devc->empty_transfer_count = 0; + devc->empty_poll_count = 0; devc->status = DSL_INIT; devc->num_transfers = 0; devc->submitted_transfers = 0; - devc->actual_samples = (devc->limit_samples + 1023ULL) & ~1023ULL; + devc->actual_samples = (devc->limit_samples + SAMPLES_ALIGN) & ~SAMPLES_ALIGN; devc->actual_bytes = devc->actual_samples / DSLOGIC_ATOMIC_SAMPLES * dsl_en_ch_num(sdi) * DSLOGIC_ATOMIC_SIZE; devc->abort = FALSE; devc->mstatus_valid = FALSE; + devc->mstatus.captured_cnt0 = 0; + devc->mstatus.captured_cnt1 = 0; + devc->mstatus.captured_cnt2 = 0; + devc->mstatus.captured_cnt3 = 0; + devc->mstatus.trig_hit = 0; devc->overflow = FALSE; /* Configures devc->trigger_* and devc->sample_wide */ @@ -1346,9 +1390,9 @@ static int dev_acquisition_stop(const struct sr_dev_inst *sdi, void *cb_data) return ret; } -static int dev_status_get(const struct sr_dev_inst *sdi, struct sr_status *status, gboolean prg, int begin, int end) +static int dev_status_get(const struct sr_dev_inst *sdi, struct sr_status *status, gboolean prg) { - int ret = dsl_dev_status_get(sdi, status, prg, begin, end); + int ret = dsl_dev_status_get(sdi, status, prg); return ret; } diff --git a/libsigrok4DSL/hardware/demo/demo.c b/libsigrok4DSL/hardware/demo/demo.c index ce1550db5833254597a553d75469b230adcc555a..5539d5fb64126c2cc5a68b317d8d3fafe18b5802 100755 --- a/libsigrok4DSL/hardware/demo/demo.c +++ b/libsigrok4DSL/hardware/demo/demo.c @@ -1074,11 +1074,10 @@ static int hw_dev_acquisition_stop(const struct sr_dev_inst *sdi, void *cb_data) return SR_OK; } -static int hw_dev_status_get(const struct sr_dev_inst *sdi, struct sr_status *status, gboolean prg, int begin, int end) +static int hw_dev_status_get(const struct sr_dev_inst *sdi, struct sr_status *status, gboolean prg) { (void)prg; - (void)begin; - (void)end; + if (sdi) { struct demo_context *const devc = sdi->priv; *status = devc->mstatus; diff --git a/libsigrok4DSL/hwdriver.c b/libsigrok4DSL/hwdriver.c index 2d921dc1e32a2c7a9990d5893f2913367672a631..6af67d91c443f47ea5ce80004e9967d950507e3f 100755 --- a/libsigrok4DSL/hwdriver.c +++ b/libsigrok4DSL/hwdriver.c @@ -425,8 +425,7 @@ SR_API const struct sr_config_info *sr_config_info_get(int key) * as an indication that it's not applicable. */ SR_API int sr_status_get(const struct sr_dev_inst *sdi, - struct sr_status *status, - gboolean prg, int begin, int end) + struct sr_status *status, gboolean prg) { int ret; @@ -435,7 +434,7 @@ SR_API int sr_status_get(const struct sr_dev_inst *sdi, else if (!sdi->driver->dev_status_get) ret = SR_ERR_ARG; else - ret = sdi->driver->dev_status_get(sdi, status, prg, begin, end); + ret = sdi->driver->dev_status_get(sdi, status, prg); return ret; } diff --git a/libsigrok4DSL/libsigrok.h b/libsigrok4DSL/libsigrok.h index b6e181011b743df22dc3f06f0d01b6568aaaa862..77d01ebe41151c578a5c3800b97240fd6b8b6c3f 100755 --- a/libsigrok4DSL/libsigrok.h +++ b/libsigrok4DSL/libsigrok.h @@ -126,6 +126,8 @@ enum { #define DS_CONF_DSO_VDIVS 10 #define DS_MAX_TRIG_PERCENT 90 + +#define SAMPLES_ALIGN 1023ULL /* * Oscilloscope */ @@ -647,6 +649,16 @@ struct sr_channel { int8_t comb_diff_top; int8_t comb_diff_bom; int8_t comb_comp; + uint16_t digi_fgain; + + double cali_fgain0; + double cali_fgain1; + double cali_fgain2; + double cali_fgain3; + double cali_comb_fgain0; + double cali_comb_fgain1; + double cali_comb_fgain2; + double cali_comb_fgain3; gboolean map_default; const char *map_unit; @@ -680,17 +692,6 @@ struct sr_config_info { char *description; }; -enum { - SR_STATUS_TRIG_BEGIN = 0, - SR_STATUS_TRIG_END = 4, - SR_STATUS_CH0_BEGIN = 5, - SR_STATUS_CH0_END = 14, - SR_STATUS_CH1_BEGIN = 15, - SR_STATUS_CH1_END = 24, - SR_STATUS_ZERO_BEGIN = 128, - SR_STATUS_ZERO_END = 135, -}; - struct sr_status { uint8_t trig_hit; uint8_t captured_cnt3; @@ -722,6 +723,9 @@ struct sr_status { uint32_t ch0_cyc_flen; uint64_t ch0_acc_square; uint32_t ch0_acc_mean; + uint32_t ch0_acc_mean_p1; + uint32_t ch0_acc_mean_p2; + uint32_t ch0_acc_mean_p3; uint8_t ch1_max; uint8_t ch1_min; @@ -737,6 +741,9 @@ struct sr_status { uint32_t ch1_cyc_flen; uint64_t ch1_acc_square; uint32_t ch1_acc_mean; + uint32_t ch1_acc_mean_p1; + uint32_t ch1_acc_mean_p2; + uint32_t ch1_acc_mean_p3; }; enum { @@ -877,6 +884,8 @@ enum { SR_CONF_ZERO_SET, SR_CONF_ZERO_LOAD, SR_CONF_ZERO_DEFAULT, + SR_CONF_ZERO_COMB_FGAIN, + SR_CONF_ZERO_COMB, SR_CONF_VOCM, SR_CONF_CALI, @@ -1199,8 +1208,7 @@ struct sr_dev_driver { int (*dev_open) (struct sr_dev_inst *sdi); int (*dev_close) (struct sr_dev_inst *sdi); int (*dev_status_get) (const struct sr_dev_inst *sdi, - struct sr_status *status, - gboolean prg, int begin, int end); + struct sr_status *status, gboolean prg); int (*dev_acquisition_start) (struct sr_dev_inst *sdi, void *cb_data); int (*dev_acquisition_stop) (const struct sr_dev_inst *sdi, diff --git a/libsigrok4DSL/proto.h b/libsigrok4DSL/proto.h index 84ffaae20ea56a110e3e99dab2b7e4fc00d327c7..aeac6b8108c4a31e212c63365bca24b86bba3e4c 100755 --- a/libsigrok4DSL/proto.h +++ b/libsigrok4DSL/proto.h @@ -78,7 +78,7 @@ SR_API int sr_config_list(const struct sr_dev_driver *driver, int key, GVariant **data); SR_API const struct sr_config_info *sr_config_info_get(int key); SR_API const struct sr_config_info *sr_config_info_name_get(const char *optname); -SR_API int sr_status_get(const struct sr_dev_inst *sdi, struct sr_status *status, gboolean prg, int begin, int end); +SR_API int sr_status_get(const struct sr_dev_inst *sdi, struct sr_status *status, gboolean prg); SR_API struct sr_config *sr_config_new(int key, GVariant *data); SR_API void sr_config_free(struct sr_config *src); diff --git a/libsigrok4DSL/session_driver.c b/libsigrok4DSL/session_driver.c index ce4281e58f92223bdbbf146c65e6b49979314f6c..aca809bee6be670595f5964fe91aa49750649d02 100755 --- a/libsigrok4DSL/session_driver.c +++ b/libsigrok4DSL/session_driver.c @@ -867,11 +867,9 @@ static int config_list(int key, GVariant **data, return SR_OK; } -static int dev_status_get(const struct sr_dev_inst *sdi, struct sr_status *status, gboolean prg, int begin, int end) +static int dev_status_get(const struct sr_dev_inst *sdi, struct sr_status *status, gboolean prg) { (void)prg; - (void)begin; - (void)end; struct session_vdev *vdev;