diff --git a/DSView/pv/prop/binding/binding_deviceoptions.cpp b/DSView/pv/prop/binding/binding_deviceoptions.cpp
index 8c8d9e48041cdae9835c3e0f6b25e4d769dc53f0..ba5045d72038217cf8c58e2c4e697d3402426838 100644
--- a/DSView/pv/prop/binding/binding_deviceoptions.cpp
+++ b/DSView/pv/prop/binding/binding_deviceoptions.cpp
@@ -90,6 +90,7 @@ DeviceOptions::DeviceOptions(struct sr_dev_inst *sdi) :
         case SR_CONF_STREAM:
         case SR_CONF_TEST:
         case SR_CONF_STATUS:
+        case SR_CONF_FACTOR:
 			bind_enum(name, key, gvar_list);
 			break;
 
diff --git a/DSView/pv/sigsession.cpp b/DSView/pv/sigsession.cpp
index 559ed53c8b3bd4795e075a7cb1f7e3b9661de989..b122fbee0ff444c80e3ad732315a3e33669be551 100644
--- a/DSView/pv/sigsession.cpp
+++ b/DSView/pv/sigsession.cpp
@@ -60,18 +60,21 @@
 
 #include <boost/foreach.hpp>
 
-using boost::dynamic_pointer_cast;
-using boost::function;
-using boost::lock_guard;
-using boost::mutex;
-using boost::shared_ptr;
-using std::list;
-using std::map;
-using std::set;
-using std::string;
-using std::vector;
-using std::deque;
-using std::min;
+//using boost::dynamic_pointer_cast;
+//using boost::function;
+//using boost::lock_guard;
+//using boost::mutex;
+//using boost::shared_ptr;
+//using std::list;
+//using std::map;
+//using std::set;
+//using std::string;
+//using std::vector;
+//using std::deque;
+//using std::min;
+
+using namespace boost;
+using namespace std;
 
 namespace pv {
 
@@ -100,10 +103,6 @@ SigSession::SigSession(DeviceManager &device_manager) :
 SigSession::~SigSession()
 {
 	stop_capture();
-    if (_hotplug_handle) {
-        stop_hotplug_proc();
-        deregister_hotplug_callback();
-    }
 		       
     ds_trigger_destroy();
 
@@ -111,6 +110,11 @@ SigSession::~SigSession()
 
 	// TODO: This should not be necessary
 	_session = NULL;
+
+    if (_hotplug_handle) {
+        stop_hotplug_proc();
+        deregister_hotplug_callback();
+    }
 }
 
 boost::shared_ptr<device::DevInst> SigSession::get_device() const
@@ -118,7 +122,7 @@ boost::shared_ptr<device::DevInst> SigSession::get_device() const
     return _dev_inst;
 }
 
-void SigSession::set_device(shared_ptr<device::DevInst> dev_inst) throw(QString)
+void SigSession::set_device(boost::shared_ptr<device::DevInst> dev_inst) throw(QString)
 {
     using pv::device::Device;
 
@@ -154,13 +158,13 @@ void SigSession::set_file(const string &name) throw(QString)
     // Deslect the old device, because file type detection in File::create
     // destorys the old session inside libsigrok.
     try {
-        set_device(shared_ptr<device::DevInst>());
+        set_device(boost::shared_ptr<device::DevInst>());
     } catch(const QString e) {
         throw(e);
         return;
     }
     try {
-        set_device(shared_ptr<device::DevInst>(device::File::create(name)));
+        set_device(boost::shared_ptr<device::DevInst>(device::File::create(name)));
     } catch(const QString e) {
         throw(e);
         return;
@@ -342,8 +346,8 @@ void SigSession::export_file(const std::string &name, QWidget* parent, const std
 
 void SigSession::set_default_device(boost::function<void (const QString)> error_handler)
 {
-    shared_ptr<pv::device::DevInst> default_device;
-    const list< shared_ptr<device::DevInst> > &devices =
+    boost::shared_ptr<pv::device::DevInst> default_device;
+    const list<boost::shared_ptr<device::DevInst> > &devices =
         _device_manager.devices();
 
     if (!devices.empty()) {
@@ -351,7 +355,7 @@ void SigSession::set_default_device(boost::function<void (const QString)> error_
         default_device = devices.front();
 
         // Try and find the DreamSourceLab device and select that by default
-        BOOST_FOREACH (shared_ptr<pv::device::DevInst> dev, devices)
+        BOOST_FOREACH (boost::shared_ptr<pv::device::DevInst> dev, devices)
             if (dev->dev_inst() &&
                 strcmp(dev->dev_inst()->driver->name,
                 "demo") != 0) {
@@ -373,7 +377,7 @@ void SigSession::release_device(device::DevInst *dev_inst)
     assert(_dev_inst.get() == dev_inst);
 
     assert(_capture_state != Running);
-    _dev_inst = shared_ptr<device::DevInst>();
+    _dev_inst = boost::shared_ptr<device::DevInst>();
     //_dev_inst.reset();
 }
 
@@ -447,11 +451,11 @@ vector< boost::shared_ptr<view::GroupSignal> > SigSession::get_group_signals()
     return _group_traces;
 }
 
-set< shared_ptr<data::SignalData> > SigSession::get_data() const
+set< boost::shared_ptr<data::SignalData> > SigSession::get_data() const
 {
     lock_guard<mutex> lock(_signals_mutex);
-    set< shared_ptr<data::SignalData> > data;
-    BOOST_FOREACH(const shared_ptr<view::Signal> sig, _signals) {
+    set< boost::shared_ptr<data::SignalData> > data;
+    BOOST_FOREACH(const boost::shared_ptr<view::Signal> sig, _signals) {
         assert(sig);
         data.insert(sig->data());
     }
@@ -513,7 +517,7 @@ void SigSession::set_capture_state(capture_state state)
 	capture_state_changed(state);
 }
 
-void SigSession::sample_thread_proc(shared_ptr<device::DevInst> dev_inst,
+void SigSession::sample_thread_proc(boost::shared_ptr<device::DevInst> dev_inst,
                                     boost::function<void (const QString)> error_handler)
 {
     assert(dev_inst);
@@ -577,8 +581,8 @@ void SigSession::read_sample_rate(const sr_dev_inst *const sdi)
     }
 
     // Set the sample rate of all data
-    const set< shared_ptr<data::SignalData> > data_set = get_data();
-    BOOST_FOREACH(shared_ptr<data::SignalData> data, data_set) {
+    const set< boost::shared_ptr<data::SignalData> > data_set = get_data();
+    BOOST_FOREACH(boost::shared_ptr<data::SignalData> data, data_set) {
         assert(data);
         data->set_samplerate(sample_rate);
     }
@@ -737,13 +741,13 @@ void SigSession::init_signals()
                 break;
 
             case SR_CHANNEL_DSO:
-                signal = shared_ptr<view::Signal>(
+                signal = boost::shared_ptr<view::Signal>(
                     new view::DsoSignal(_dev_inst, _dso_data, probe));
                 break;
 
             case SR_CHANNEL_ANALOG:
                 if (probe->enabled)
-                    signal = shared_ptr<view::Signal>(
+                    signal = boost::shared_ptr<view::Signal>(
                         new view::AnalogSignal(_dev_inst, _analog_data, probe));
                 break;
             }
@@ -781,13 +785,13 @@ void SigSession::reload()
                 break;
 
             case SR_CHANNEL_DSO:
-                signal = shared_ptr<view::Signal>(
+                signal = boost::shared_ptr<view::Signal>(
                     new view::DsoSignal(_dev_inst,_dso_data, probe));
                 break;
 
             case SR_CHANNEL_ANALOG:
                 if (probe->enabled)
-                    signal = shared_ptr<view::Signal>(
+                    signal = boost::shared_ptr<view::Signal>(
                         new view::AnalogSignal(_dev_inst, _analog_data, probe));
                 break;
             }
@@ -879,7 +883,7 @@ void SigSession::feed_in_logic(const sr_datafeed_logic &logic)
         return;
     }
 
-    receive_data(logic.length/logic.unitsize);
+    emit receive_data(logic.length/logic.unitsize);
     data_received();
     //data_updated();
 }
@@ -1005,7 +1009,7 @@ void SigSession::data_feed_in(const struct sr_dev_inst *sdi,
             _cur_analog_snapshot.reset();
 		}
 #ifdef ENABLE_DECODE
-        for (vector< shared_ptr<view::DecodeTrace> >::iterator i =
+        for (vector< boost::shared_ptr<view::DecodeTrace> >::iterator i =
             _decode_traces.begin();
             i != _decode_traces.end();
             i++)
@@ -1138,7 +1142,7 @@ uint16_t SigSession::get_ch_num(int type)
     uint16_t dso_ch_num = 0;
     uint16_t analog_ch_num = 0;
     if (_dev_inst->dev_inst()) {
-        BOOST_FOREACH(const shared_ptr<view::Signal> s, _signals)
+        BOOST_FOREACH(const boost::shared_ptr<view::Signal> s, _signals)
         {
             assert(s);
             if (dynamic_pointer_cast<view::LogicSignal>(s) && s->enabled()) {
@@ -1174,15 +1178,15 @@ uint16_t SigSession::get_ch_num(int type)
 bool SigSession::add_decoder(srd_decoder *const dec)
 {
     bool ret = false;
-    map<const srd_channel*, shared_ptr<view::LogicSignal> > probes;
-    shared_ptr<data::DecoderStack> decoder_stack;
+    map<const srd_channel*, boost::shared_ptr<view::LogicSignal> > probes;
+    boost::shared_ptr<data::DecoderStack> decoder_stack;
 
     try
     {
         //lock_guard<mutex> lock(_signals_mutex);
 
         // Create the decoder
-        decoder_stack = shared_ptr<data::DecoderStack>(
+        decoder_stack = boost::shared_ptr<data::DecoderStack>(
             new data::DecoderStack(*this, dec));
 
         // Make a list of all the probes
@@ -1198,7 +1202,7 @@ bool SigSession::add_decoder(srd_decoder *const dec)
         decoder_stack->stack().front()->set_probes(probes);
 
         // Create the decode signal
-        shared_ptr<view::DecodeTrace> d(
+        boost::shared_ptr<view::DecodeTrace> d(
             new view::DecodeTrace(*this, decoder_stack,
                 _decode_traces.size()));
         if (d->create_popup()) {
@@ -1221,7 +1225,7 @@ bool SigSession::add_decoder(srd_decoder *const dec)
     return ret;
 }
 
-vector< shared_ptr<view::DecodeTrace> > SigSession::get_decode_signals() const
+vector< boost::shared_ptr<view::DecodeTrace> > SigSession::get_decode_signals() const
 {
     lock_guard<mutex> lock(_signals_mutex);
     return _decode_traces;
@@ -1229,7 +1233,7 @@ vector< shared_ptr<view::DecodeTrace> > SigSession::get_decode_signals() const
 
 void SigSession::remove_decode_signal(view::DecodeTrace *signal)
 {
-    for (vector< shared_ptr<view::DecodeTrace> >::iterator i =
+    for (vector< boost::shared_ptr<view::DecodeTrace> >::iterator i =
         _decode_traces.begin();
         i != _decode_traces.end();
         i++)
@@ -1244,7 +1248,7 @@ void SigSession::remove_decode_signal(view::DecodeTrace *signal)
 void SigSession::remove_decode_signal(int index)
 {
     int cur_index = 0;
-    for (vector< shared_ptr<view::DecodeTrace> >::iterator i =
+    for (vector< boost::shared_ptr<view::DecodeTrace> >::iterator i =
         _decode_traces.begin();
         i != _decode_traces.end();
         i++)
@@ -1262,7 +1266,7 @@ void SigSession::remove_decode_signal(int index)
 void SigSession::rst_decoder(int index)
 {
     int cur_index = 0;
-    for (vector< shared_ptr<view::DecodeTrace> >::iterator i =
+    for (vector< boost::shared_ptr<view::DecodeTrace> >::iterator i =
         _decode_traces.begin();
         i != _decode_traces.end();
         i++)
@@ -1283,7 +1287,7 @@ void SigSession::rst_decoder(int index)
 
 void SigSession::rst_decoder(view::DecodeTrace *signal)
 {
-    for (vector< shared_ptr<view::DecodeTrace> >::iterator i =
+    for (vector< boost::shared_ptr<view::DecodeTrace> >::iterator i =
         _decode_traces.begin();
         i != _decode_traces.end();
         i++)
diff --git a/DSView/pv/sigsession.h b/DSView/pv/sigsession.h
index b625b03de30db715f13316247d030784abe0fd3f..fd4069506c8b752522f67751e759864c39652b7b 100644
--- a/DSView/pv/sigsession.h
+++ b/DSView/pv/sigsession.h
@@ -35,6 +35,7 @@
 #include <set>
 #include <string>
 #include <vector>
+#include <stdint.h>
 
 #include <QObject>
 #include <QString>
diff --git a/DSView/pv/view/dsldial.cpp b/DSView/pv/view/dsldial.cpp
index 15574966f36054ce0e1234306a838fc1cac38d59..f19c75613b50067d8990f3dad8f20cd57345fcd8 100644
--- a/DSView/pv/view/dsldial.cpp
+++ b/DSView/pv/view/dsldial.cpp
@@ -5,12 +5,12 @@
 namespace pv {
 namespace view {
 
-dslDial::dslDial(const quint64 div, const quint64 step,
-                 const QVector<quint64> value, const QVector<QString> unit)
+dslDial::dslDial(const uint64_t div, const uint64_t step,
+                 const QVector<uint64_t> value, const QVector<QString> unit)
 {
     assert(div > 0);
     assert(step > 0);
-    assert((quint64)value.count() == div);
+    assert((uint64_t)value.count() == div);
     assert(unit.count() > 0);
 
     _div = div;
@@ -18,6 +18,7 @@ dslDial::dslDial(const quint64 div, const quint64 step,
     _value = value;
     _unit = unit;
     _sel = 0;
+    _factor = 1;
 }
 
 dslDial::~dslDial()
@@ -39,11 +40,11 @@ void dslDial::paint(QPainter &p, QRectF dialRect, QColor dialColor)
     p.save();
     p.translate(dialRect.center());
     p.rotate(45);
-    for (quint64 i = 0; i < _div; i++) {
+    for (uint64_t i = 0; i < _div; i++) {
         // draw major ticks
         p.drawLine(0, dialRect.width()/2+3, 0, dialRect.width()/2+8);
         // draw minor ticks
-        for (quint64 j = 0; (j < 5) && (i < _div - 1); j++) {
+        for (uint64_t j = 0; (j < 5) && (i < _div - 1); j++) {
             p.drawLine(0, dialRect.width()/2+3, 0, dialRect.width()/2+5);
             p.rotate(54.0/(_div-1));
         }
@@ -55,8 +56,8 @@ void dslDial::paint(QPainter &p, QRectF dialRect, QColor dialColor)
     p.drawLine(-3, 0, 0, dialRect.width()/2-3);
     p.restore();
     // draw value
-    quint64 displayValue = _value[_sel];
-    quint64 displayIndex = 0;
+    uint64_t displayValue = _value[_sel]*_factor;
+    uint64_t displayIndex = 0;
     while(displayValue / _step >= 1) {
         displayValue = displayValue / _step;
         displayIndex++;
@@ -67,14 +68,14 @@ void dslDial::paint(QPainter &p, QRectF dialRect, QColor dialColor)
 
 }
 
-void dslDial::set_sel(quint64 sel)
+void dslDial::set_sel(uint64_t sel)
 {
     assert(sel < _div);
 
     _sel = sel;
 }
 
-quint64 dslDial::get_sel()
+uint64_t dslDial::get_sel()
 {
     return _sel;
 }
@@ -95,16 +96,28 @@ bool dslDial::isMax()
         return false;
 }
 
-quint64 dslDial::get_value()
+uint64_t dslDial::get_value()
 {
     return _value[_sel];
 }
 
-bool dslDial::set_value(quint64 value)
+bool dslDial::set_value(uint64_t value)
 {
     assert(_value.contains(value));
     _sel = _value.indexOf(value, 0);
 }
 
+void dslDial::set_factor(uint64_t factor)
+{
+    if (_factor != factor) {
+        _factor = factor;
+    }
+}
+
+uint64_t dslDial::get_factor()
+{
+    return _factor;
+}
+
 } // namespace view
 } // namespace pv
diff --git a/DSView/pv/view/dsldial.h b/DSView/pv/view/dsldial.h
index a0034cf862556e689847fd35fb883aee76c77edc..35701959f5040c55e89e034f5e86013b1d273e42 100644
--- a/DSView/pv/view/dsldial.h
+++ b/DSView/pv/view/dsldial.h
@@ -10,8 +10,8 @@ namespace view {
 class dslDial
 {
 public:
-    dslDial(const quint64 div, const quint64 step,
-            const QVector<quint64> value, const QVector<QString> unit);
+    dslDial(const uint64_t div, const uint64_t step,
+            const QVector<uint64_t> value, const QVector<QString> unit);
     virtual ~dslDial();
 
 public:
@@ -23,23 +23,28 @@ public:
     void paint(QPainter &p, QRectF dialRect, QColor dialColor);
 
     // set/get current select
-    void set_sel(quint64 sel);
-    quint64 get_sel();
+    void set_sel(uint64_t sel);
+    uint64_t get_sel();
 
     // boundary detection
     bool isMin();
     bool isMax();
 
     // get current value
-    quint64 get_value();
-    bool set_value(quint64 value);
+    uint64_t get_value();
+    bool set_value(uint64_t value);
+
+    // set/get factor
+    void set_factor(uint64_t factor);
+    uint64_t get_factor();
 
 private:
-    quint64 _div;
-    quint64 _step;
-    QVector<quint64> _value;
+    uint64_t _div;
+    uint64_t _step;
+    QVector<uint64_t> _value;
     QVector<QString> _unit;
-    quint64 _sel;
+    uint64_t _sel;
+    uint64_t _factor;
 };
 
 } // namespace view
diff --git a/DSView/pv/view/dsosignal.cpp b/DSView/pv/view/dsosignal.cpp
index ed4b68ea509dbd8d8fb130ded49324a1c3058bd9..1a404916c2ce5a9dbb73b1e181e66616d9cc69e6 100644
--- a/DSView/pv/view/dsosignal.cpp
+++ b/DSView/pv/view/dsosignal.cpp
@@ -120,21 +120,26 @@ DsoSignal::DsoSignal(boost::shared_ptr<pv::device::DevInst> dev_inst,
     //_zeroPos(probe->index * 0.5 + 0.25)
     _trig_vpos(0.5),
     _zeroPos(0.5),
+    _zero_off(255/2.0),
     _autoV(false),
-    _autoH(false)
+    _autoH(false),
+    _hover_en(false),
+    _hover_index(0),
+    _hover_point(QPointF(0, 0)),
+    _hover_value(0)
 {
-    QVector<quint64> vValue;
+    QVector<uint64_t> vValue;
     QVector<QString> vUnit;
-    QVector<quint64> hValue;
+    QVector<uint64_t> hValue;
     QVector<QString> hUnit;
-    for(quint64 i = 0; i < vDialValueCount; i++)
+    for(uint64_t i = 0; i < vDialValueCount; i++)
         vValue.append(vDialValue[i]);
-    for(quint64 i = 0; i < vDialUnitCount; i++)
+    for(uint64_t i = 0; i < vDialUnitCount; i++)
         vUnit.append(vDialUnit[i]);
 
-    for(quint64 i = 0; i < hDialValueCount; i++)
+    for(uint64_t i = 0; i < hDialValueCount; i++)
         hValue.append(hDialValue[i]);
-    for(quint64 i = 0; i < hDialUnitCount; i++)
+    for(uint64_t i = 0; i < hDialUnitCount; i++)
         hUnit.append(hDialUnit[i]);
 
     _vDial = new dslDial(vDialValueCount, vDialValueStep, vValue, vUnit);
@@ -244,10 +249,15 @@ void DsoSignal::set_vDialActive(bool active)
 bool DsoSignal::go_vDialPre()
 {
     if (enabled() && !_vDial->isMin()) {
+        const double pre_vdiv = _vDial->get_value();
         _vDial->set_sel(_vDial->get_sel() - 1);
         _dev_inst->set_config(_probe, NULL, SR_CONF_VDIV,
                               g_variant_new_uint64(_vDial->get_value()));
+        if (_view->session().get_capture_state() == SigSession::Stopped)
+            _scale *= pre_vdiv/_vDial->get_value();
         update_zeroPos();
+        _view->set_need_update(true);
+        _view->update();
         return true;
     } else {
         _autoV = false;
@@ -258,10 +268,15 @@ bool DsoSignal::go_vDialPre()
 bool DsoSignal::go_vDialNext()
 {
     if (enabled() && !_vDial->isMax()) {
+        const double pre_vdiv = _vDial->get_value();
         _vDial->set_sel(_vDial->get_sel() + 1);
         _dev_inst->set_config(_probe, NULL, SR_CONF_VDIV,
                               g_variant_new_uint64(_vDial->get_value()));
+        if (_view->session().get_capture_state() == SigSession::Stopped)
+            _scale *= pre_vdiv/_vDial->get_value();
         update_zeroPos();
+        _view->set_need_update(true);
+        _view->update();
         return true;
     } else {
         _autoV = false;
@@ -482,6 +497,29 @@ void DsoSignal::set_zeroPos(int pos)
     }
 }
 
+void DsoSignal::set_factor(uint64_t factor)
+{
+    if (enabled()) {
+        GVariant* gvar;
+        uint64_t prefactor = 0;
+        gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_FACTOR);
+        if (gvar != NULL) {
+            prefactor = g_variant_get_uint64(gvar);
+            g_variant_unref(gvar);
+        } else {
+            qDebug() << "ERROR: config_get SR_CONF_FACTOR failed.";
+            return;
+        }
+        if (prefactor != factor) {
+            _dev_inst->set_config(_probe, NULL, SR_CONF_FACTOR,
+                                  g_variant_new_uint64(factor));
+            _vDial->set_factor(factor);
+            _view->set_need_update(true);
+            _view->update();
+        }
+    }
+}
+
 void DsoSignal::update_zeroPos()
 {
     if (strcmp(_dev_inst->dev_inst()->driver->name, "DSCope") == 0) {
@@ -505,7 +543,7 @@ void DsoSignal::paint_back(QPainter &p, int left, int right)
     assert(_view);
 
     int i, j;
-    const int height = _view->viewport()->height() - UpMargin - DownMargin;
+    const int height = get_view_rect().height();
     const int width = right - left;
 
     p.setPen(Qt::NoPen);
@@ -568,7 +606,7 @@ void DsoSignal::paint_mid(QPainter &p, int left, int right)
     assert(right >= left);
 
     if (enabled()) {
-        const int height = _view->viewport()->height() - UpMargin - DownMargin;
+        const int height = get_view_rect().height();
         const int width = right - left;
 
         const int y = get_zeroPos() + height * 0.5;
@@ -581,7 +619,8 @@ void DsoSignal::paint_mid(QPainter &p, int left, int right)
         if (snapshots.empty())
             return;
 
-        _scale = height * 1.0f / 256;
+        if (_view->session().get_capture_state() == SigSession::Running)
+            _scale = height * 1.0f / 256;
         const boost::shared_ptr<pv::data::DsoSnapshot> &snapshot =
             snapshots.front();
 
@@ -647,9 +686,19 @@ void DsoSignal::paint_fore(QPainter &p, int left, int right)
         p.setBrush(hover ? _colour.dark() : _colour);
         p.drawPolygon(points, countof(points));
 
+        // paint the trig voltage
+        int trigp = get_trig_vpos();
+        float t_vol = (_zeroPos - _trig_vpos) * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS;
+        QString t_vol_s = (_vDial->get_value() >= 500) ? QString::number(t_vol/1000.0f, 'f', 2)+"V" : QString::number(t_vol, 'f', 2)+"mV";
+        int vol_width = p.boundingRect(0, 0, INT_MAX, INT_MAX,
+                                       Qt::AlignLeft | Qt::AlignTop, t_vol_s).width();
+        const QRectF t_vol_rect = QRectF(right-vol_width, trigp-10, vol_width, 20);
+        p.setPen(Qt::white);
+        p.drawText(t_vol_rect, Qt::AlignRight | Qt::AlignVCenter, t_vol_s);
+
         // paint the _trig_vpos line
         p.setPen(QPen(_colour, 1, Qt::DotLine));
-        p.drawLine(left, get_trig_vpos(), right - label_rect.width()*1.5, get_trig_vpos());
+        p.drawLine(left, trigp, right - p.boundingRect(t_vol_rect, Qt::AlignLeft, t_vol_s).width(), trigp);
 
         // Paint the text
         p.setPen(Qt::white);
@@ -687,9 +736,10 @@ void DsoSignal::paint_trace(QPainter &p,
 
         float top = get_view_rect().top();
         float bottom = get_view_rect().bottom();
-        float zeroP = 0;
-        if (strcmp(_dev_inst->dev_inst()->driver->name, "DSLogic") == 0)
-            zeroP = (_zeroPos - 0.5) * get_view_rect().height();
+        float zeroP = _zeroPos * get_view_rect().height() + top;;
+        if (strcmp(_dev_inst->dev_inst()->driver->name, "DSCope") == 0 &&
+            _view->session().get_capture_state() == SigSession::Running)
+            _zero_off = _zeroPos * 255;
         float x = (start / samples_per_pixel - pixels_offset) + left;
         double  pixels_per_sample = 1.0/samples_per_pixel;
         uint8_t offset;
@@ -700,7 +750,7 @@ void DsoSignal::paint_trace(QPainter &p,
 
             //offset = samples[(sample - start)*num_channels];
             offset = samples[sample];
-            const float y = min(max(top, top + offset * _scale + zeroP), bottom);
+            const float y = min(max(top, zeroP + (offset - _zero_off) * _scale), bottom);
             *point++ = QPointF(x, y);
             x += pixels_per_sample;
             //*point++ = QPointF(x, top + offset);
@@ -738,9 +788,10 @@ void DsoSignal::paint_envelope(QPainter &p,
 	QRectF *rect = rects;
     float top = get_view_rect().top();
     float bottom = get_view_rect().bottom();
-    float zeroP = 0;
-    if (strcmp(_dev_inst->dev_inst()->driver->name, "DSLogic") == 0)
-        zeroP = (_zeroPos - 0.5) * get_view_rect().height();
+    float zeroP = _zeroPos * get_view_rect().height() + top;
+    if (strcmp(_dev_inst->dev_inst()->driver->name, "DSCope") == 0 &&
+        _view->session().get_capture_state() == SigSession::Running)
+        _zero_off = _zeroPos * 255;
     for(uint64_t sample = 0; sample < e.length-1; sample++) {
 		const float x = ((e.scale * sample + e.start) /
 			samples_per_pixel - pixels_offset) + left;
@@ -749,8 +800,8 @@ void DsoSignal::paint_envelope(QPainter &p,
 
 		// We overlap this sample with the next so that vertical
 		// gaps do not appear during steep rising or falling edges
-        const float b = min(max(top, (top + max(s->max, (s+1)->min) * _scale + zeroP)), bottom);
-        const float t = min(max(top, (top + min(s->min, (s+1)->max) * _scale + zeroP)), bottom);
+        const float b = min(max(top, ((max(s->max, (s+1)->min) - _zero_off) * _scale + zeroP)), bottom);
+        const float t = min(max(top, ((min(s->min, (s+1)->max) - _zero_off) * _scale + zeroP)), bottom);
 
 		float h = b - t;
 		if(h >= 0.0f && h <= 1.0f)
@@ -776,6 +827,9 @@ void DsoSignal::paint_type_options(QPainter &p, int right, bool hover, int actio
 {
     int y = get_y();
     const QRectF vDial_rect = get_rect("vDial", y, right);
+    const QRectF x1_rect = get_rect("x1", y, right);
+    const QRectF x10_rect = get_rect("x10", y, right);
+    const QRectF x100_rect = get_rect("x100", y, right);
     const QRectF hDial_rect = get_rect("hDial", y, right);
     const QRectF acdc_rect = get_rect("acdc", y, right);
     const QRectF chEn_rect = get_rect("chEn", y, right);
@@ -797,6 +851,31 @@ void DsoSignal::paint_type_options(QPainter &p, int right, bool hover, int actio
     p.setPen(Qt::white);
     p.drawText(acdc_rect, Qt::AlignCenter | Qt::AlignVCenter, (_acCoupling == SR_GND_COUPLING) ? "GND" :
                                                               (_acCoupling == SR_DC_COUPLING) ? "DC" : "AC");
+
+    // paint the probe factor selector
+    GVariant* gvar;
+    uint64_t factor;
+    gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_FACTOR);
+    if (gvar != NULL) {
+        factor = g_variant_get_uint64(gvar);
+        g_variant_unref(gvar);
+    } else {
+        qDebug() << "ERROR: config_get SR_CONF_FACTOR failed.";
+        return;
+    }
+
+    p.setPen(Qt::white);
+    p.setBrush((enabled() && (factor == 100)) ? ((hover && action == X100) ? _colour.darker() : _colour)  : ((hover && action == X100) ? _colour.darker() : dsDisable));
+    p.drawRect(x100_rect);
+    p.drawText(x100_rect, Qt::AlignLeft | Qt::AlignVCenter, "x100");
+
+    p.setBrush((enabled() && (factor == 10)) ? ((hover && action == X10) ? _colour.darker() : _colour)  : ((hover && action == X10) ? _colour.darker() : dsDisable));
+    p.drawRect(x10_rect);
+    p.drawText(x10_rect, Qt::AlignLeft | Qt::AlignVCenter, "x10");
+
+    p.setBrush((enabled() && (factor == 1)) ? ((hover && action == X1) ? _colour.darker() : _colour)  : ((hover && action == X1) ? _colour.darker() : dsDisable));
+    p.drawRect(x1_rect);
+    p.drawText(x1_rect, Qt::AlignLeft | Qt::AlignVCenter, "x1");
 }
 
 void DsoSignal::paint_measure(QPainter &p)
@@ -808,26 +887,26 @@ void DsoSignal::paint_measure(QPainter &p)
     if (sr_status_get(_dev_inst->dev_inst(), &status, st_begin, st_end) == SR_OK) {
         _max = (index == 0) ? status.ch0_max : status.ch1_max;
         _min = (index == 0) ? status.ch0_min : status.ch1_min;
-        const uint32_t period = (index == 0) ? status.ch0_period : status.ch1_period;
+        const uint64_t period = (index == 0) ? status.ch0_period : status.ch1_period;
         const uint32_t count  = (index == 0) ? status.ch0_pcnt : status.ch1_pcnt;
-        double value_max = ((0xff - _min - (1-_zeroPos)*0xff) * _vDial->get_value() * DS_CONF_DSO_VDIVS) / 0xff;
-        double value_min = ((0xff - _max - (1-_zeroPos)*0xff) * _vDial->get_value() * DS_CONF_DSO_VDIVS) / 0xff;
-        _period = (count == 0) ? period * 10 : period * 10.0f / count;
+        double value_max = (_zero_off - _min) * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height();
+        double value_min = (_zero_off - _max) * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height();
+        _period = (count == 0) ? period * 10.0 : period * 10.0 / count;
         const int channel_count = _view->session().get_ch_num(SR_CHANNEL_DSO);
         uint64_t sample_rate = _dev_inst->get_sample_rate();
-        _period = _period * 200 / (channel_count * sample_rate * 1.0 / SR_MHZ(1));
-        QString max_string = abs(value_max) > 1000 ? QString::number(value_max/1000.0) + "V" : QString::number(value_max) + "mV";
-        QString min_string = abs(value_min) > 1000 ? QString::number(value_min/1000.0) + "V" : QString::number(value_min) + "mV";
-        QString period_string = abs(_period) > 1000000000 ? QString::number(_period/1000000000) + "S" :
-                                abs(_period) > 1000000 ? QString::number(_period/1000000) + "mS" :
-                                abs(_period) > 1000 ? QString::number(_period/1000) + "uS" : QString::number(_period) + "nS";
-        QString freq_string = abs(_period) > 1000000 ? QString::number(1000000000/_period) + "Hz" :
-                              abs(_period) > 1000 ? QString::number(1000000/_period) + "kHz" : QString::number(1000/_period) + "MHz";
+        _period = _period * 200.0 / (channel_count * sample_rate * 1.0 / SR_MHZ(1));
+        QString max_string = abs(value_max) > 1000 ? QString::number(value_max/1000.0, 'f', 2) + "V" : QString::number(value_max, 'f', 2) + "mV";
+        QString min_string = abs(value_min) > 1000 ? QString::number(value_min/1000.0, 'f', 2) + "V" : QString::number(value_min, 'f', 2) + "mV";
+        QString period_string = abs(_period) > 1000000000 ? QString::number(_period/1000000000, 'f', 2) + "S" :
+                                abs(_period) > 1000000 ? QString::number(_period/1000000, 'f', 2) + "mS" :
+                                abs(_period) > 1000 ? QString::number(_period/1000, 'f', 2) + "uS" : QString::number(_period, 'f', 2) + "nS";
+        QString freq_string = abs(_period) > 1000000 ? QString::number(1000000000/_period, 'f', 2) + "Hz" :
+                              abs(_period) > 1000 ? QString::number(1000000/_period, 'f', 2) + "kHz" : QString::number(1000/_period, 'f', 2) + "MHz";
         p.setPen(_colour);
-        p.drawText(QRectF(0, 100*index + UpMargin, get_view_rect().width(), 20), Qt::AlignRight | Qt::AlignVCenter, "Max: "+max_string+"        ");
-        p.drawText(QRectF(0, 100*index + UpMargin + 20, get_view_rect().width(), 20), Qt::AlignRight | Qt::AlignVCenter, "Min: "+min_string+"        ");
-        p.drawText(QRectF(0, 100*index + UpMargin + 40, get_view_rect().width(), 20), Qt::AlignRight | Qt::AlignVCenter, "Period: "+period_string+"        ");
-        p.drawText(QRectF(0, 100*index + UpMargin + 60, get_view_rect().width(), 20), Qt::AlignRight | Qt::AlignVCenter, "Frequency: "+freq_string+"        ");
+        p.drawText(QRectF(0, 100*index + UpMargin, get_view_rect().width()*0.9, 20), Qt::AlignRight | Qt::AlignVCenter, "Max: "+max_string+"        ");
+        p.drawText(QRectF(0, 100*index + UpMargin + 20, get_view_rect().width()*0.9, 20), Qt::AlignRight | Qt::AlignVCenter, "Min: "+min_string+"        ");
+        p.drawText(QRectF(0, 100*index + UpMargin + 40, get_view_rect().width()*0.9, 20), Qt::AlignRight | Qt::AlignVCenter, "Period: "+period_string+"        ");
+        p.drawText(QRectF(0, 100*index + UpMargin + 60, get_view_rect().width()*0.9, 20), Qt::AlignRight | Qt::AlignVCenter, "Frequency: "+freq_string+"        ");
 
         if (_autoV) {
             const uint8_t vscale = abs(_max - _min);
@@ -880,5 +959,78 @@ void DsoSignal::auto_set()
     }
 }
 
+bool DsoSignal::measure(const QPointF &p)
+{
+    _hover_en = false;
+    if (!enabled())
+        return false;
+
+    const deque< boost::shared_ptr<pv::data::DsoSnapshot> > &snapshots =
+        _data->get_snapshots();
+    if (snapshots.empty())
+        return false;
+
+    const boost::shared_ptr<pv::data::DsoSnapshot> &snapshot =
+        snapshots.front();
+    if (snapshot->buf_null())
+        return false;
+
+    const double scale = _view->scale();
+    assert(scale > 0);
+    const double offset = _view->offset();
+    const double pixels_offset = offset / scale;
+    const double samplerate = _dev_inst->get_sample_rate();
+    const double samples_per_pixel = samplerate * scale;
+
+    _hover_index = floor((p.x() + pixels_offset) * samples_per_pixel+0.5);
+    if (_hover_index >= snapshot->get_sample_count())
+        return false;
+
+    uint64_t pre_index;
+    uint64_t nxt_index;
+    if (_hover_index > 0)
+        pre_index = _hover_index - 1;
+    else
+        pre_index = _hover_index;
+    if (_hover_index < snapshot->get_sample_count() - 1)
+        nxt_index = _hover_index + 1;
+    else
+        nxt_index = _hover_index;
+    const uint8_t pre_sample = *snapshot->get_samples(pre_index, pre_index, get_index());
+    const uint8_t cur_sample = *snapshot->get_samples(_hover_index, _hover_index, get_index());
+    const uint8_t nxt_sample = *snapshot->get_samples(nxt_index, nxt_index, get_index());
+
+    _hover_value = (_zero_off - cur_sample) * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height();
+
+    float top = get_view_rect().top();
+    float bottom = get_view_rect().bottom();
+    float zeroP = _zeroPos * get_view_rect().height() + top;
+    float pre_x = (pre_index / samples_per_pixel - pixels_offset);
+    const float pre_y = min(max(top, zeroP + (pre_sample - _zero_off)* _scale), bottom);
+    float x = (_hover_index / samples_per_pixel - pixels_offset);
+    const float y = min(max(top, zeroP + (cur_sample - _zero_off)* _scale), bottom);
+    float nxt_x = (nxt_index / samples_per_pixel - pixels_offset);
+    const float nxt_y = min(max(top, zeroP + (nxt_sample - _zero_off)* _scale), bottom);
+    const QRectF slope_rect = QRectF(QPointF(pre_x - 10, pre_y - 10), QPointF(nxt_x + 10, nxt_y + 10));
+    if (abs(y-p.y()) < 20 || slope_rect.contains(p)) {
+        _hover_point = QPointF(x, y);
+        _hover_en = true;
+        return true;
+    } else {
+        return false;
+    }
+}
+
+bool DsoSignal::get_hover(uint64_t &index, QPointF &p, double &value)
+{
+    if (_hover_en) {
+        index = _hover_index;
+        p = _hover_point;
+        value = _hover_value;
+        return true;
+    }
+    return false;
+}
+
 } // namespace view
 } // namespace pv
diff --git a/DSView/pv/view/dsosignal.h b/DSView/pv/view/dsosignal.h
index f030f973877ef428362afb276fc08469ea3846e4..58a671ba72c752f64f292f614a49699c47fa7182 100644
--- a/DSView/pv/view/dsosignal.h
+++ b/DSView/pv/view/dsosignal.h
@@ -45,8 +45,8 @@ private:
 	static const float EnvelopeThreshold;
 
     static const int HitCursorMargin = 3;
-    static const quint64 vDialValueCount = 8;
-    static const quint64 vDialValueStep = 1000;
+    static const uint64_t vDialValueCount = 8;
+    static const uint64_t vDialValueStep = 1000;
     static const uint64_t vDialUnitCount = 2;
     static const uint64_t hDialValueCount = 28;
     static const uint64_t hDialValueStep = 1000;
@@ -94,6 +94,13 @@ public:
     void set_acCoupling(uint8_t coupling);
     void set_trig_vpos(int pos);
     int get_trig_vpos() const;
+    void set_factor(uint64_t factor);
+
+    /**
+      *
+      */
+    bool measure(const QPointF &p);
+    bool get_hover(uint64_t &index, QPointF &p, double &value);
 
     /**
       * auto set the vertical and Horizontal scale
@@ -171,12 +178,18 @@ private:
 
     double _trig_vpos;
     double _zeroPos;
+    float _zero_off;
 
     uint8_t _max;
     uint8_t _min;
     double _period;
     bool _autoV;
     bool _autoH;
+
+    bool _hover_en;
+    uint64_t _hover_index;
+    QPointF _hover_point;
+    double _hover_value;
 };
 
 } // namespace view
diff --git a/DSView/pv/view/header.cpp b/DSView/pv/view/header.cpp
index d240bf0f27bb984e938b93cc7b6276c2c4d16946..5bcc9ae02d6fabf6a7e62677aac87e8e735c6548 100644
--- a/DSView/pv/view/header.cpp
+++ b/DSView/pv/view/header.cpp
@@ -282,6 +282,21 @@ void Header::mousePressEvent(QMouseEvent *event)
                 else
                     dsoSig->set_acCoupling((dsoSig->get_acCoupling()+1)%3);
             }
+        } else if (action == Trace::X1 && mTrace) {
+            boost::shared_ptr<view::DsoSignal> dsoSig;
+            if (dsoSig = dynamic_pointer_cast<view::DsoSignal>(mTrace)) {
+                dsoSig->set_factor(1);
+            }
+        } else if (action == Trace::X10 && mTrace) {
+            boost::shared_ptr<view::DsoSignal> dsoSig;
+            if (dsoSig = dynamic_pointer_cast<view::DsoSignal>(mTrace)) {
+                dsoSig->set_factor(10);
+            }
+        } else if (action == Trace::X100 && mTrace) {
+            boost::shared_ptr<view::DsoSignal> dsoSig;
+            if (dsoSig = dynamic_pointer_cast<view::DsoSignal>(mTrace)) {
+                dsoSig->set_factor(100);
+            }
         }
 
         if (~QApplication::keyboardModifiers() & Qt::ControlModifier) {
diff --git a/DSView/pv/view/trace.cpp b/DSView/pv/view/trace.cpp
index 515932d42e238e3c15bde0cf8e1b9be2d1c8d6f1..a6820b9dfdf9e80c94e8bfda19b27d39598ba9f5 100644
--- a/DSView/pv/view/trace.cpp
+++ b/DSView/pv/view/trace.cpp
@@ -300,6 +300,9 @@ int Trace::pt_in_rect(int y, int right, const QPoint &point)
     const QRectF edgeTrig = get_rect("edgeTrig", y, right);
     const QRectF label = get_rect("label", get_zeroPos(), right);
     const QRectF vDial = get_rect("vDial", y, right);
+    const QRectF x1 = get_rect("x1", y, right);
+    const QRectF x10 = get_rect("x10", y, right);
+    const QRectF x100 = get_rect("x100", y, right);
     const QRectF hDial = get_rect("hDial", y, right);
     const QRectF chEn = get_rect("chEn", y, right);
     const QRectF acdc = get_rect("acdc", y, right);
@@ -323,6 +326,12 @@ int Trace::pt_in_rect(int y, int right, const QPoint &point)
         return LABEL;
     else if (vDial.contains(point) && _type == DS_DSO && enabled())
         return VDIAL;
+    else if (x1.contains(point) && _type == DS_DSO && enabled())
+        return X1;
+    else if (x10.contains(point) && _type == DS_DSO && enabled())
+        return X10;
+    else if (x100.contains(point) && _type == DS_DSO && enabled())
+        return X100;
     else if (hDial.contains(point) && _type == DS_DSO && enabled())
         return HDIAL;
     else if (chEn.contains(point) && _type == DS_DSO)
@@ -400,6 +409,21 @@ QRectF Trace::get_rect(const char *s, int y, int right)
             get_leftWidth() + name_size.width() + SquareWidth*0.5 + Margin,
             y - SquareWidth * SquareNum,
             SquareWidth * (SquareNum-1), SquareWidth * (SquareNum-1));
+    else if (!strcmp(s, "x1"))
+        return QRectF(
+            get_leftWidth() + name_size.width() + SquareWidth*0.5 + Margin - 45,
+            y - SquareWidth - SquareWidth * (SquareNum-1) * 0.85,
+            SquareWidth * 1.75, SquareWidth);
+    else if (!strcmp(s, "x10"))
+        return QRectF(
+            get_leftWidth() + name_size.width() + SquareWidth*0.5 + Margin - 45,
+            y - SquareWidth - SquareWidth * (SquareNum-1) * 0.55,
+            SquareWidth * 1.75, SquareWidth);
+    else if (!strcmp(s, "x100"))
+        return QRectF(
+            get_leftWidth() + name_size.width() + SquareWidth*0.5 + Margin - 45,
+            y - SquareWidth - SquareWidth * (SquareNum-1) * 0.25,
+            SquareWidth * 1.75, SquareWidth);
     else if (!strcmp(s, "hDial"))
         return QRectF(
             get_leftWidth() + name_size.width() + SquareWidth*0.5 + Margin,
diff --git a/DSView/pv/view/trace.h b/DSView/pv/view/trace.h
index 597818dca259eaafe0900ab1fde2cd7fb48ebebe..8eaae6bc29229883dfb5998085ce46dca7a72412 100644
--- a/DSView/pv/view/trace.h
+++ b/DSView/pv/view/trace.h
@@ -66,6 +66,9 @@ public:
     static const int CHEN = 11;
     static const int ACDC = 12;
     static const int DSOTRIG = 13;
+    static const int X1 = 14;
+    static const int X10 = 15;
+    static const int X100 = 16;
 
     static const QColor dsBlue;
     static const QColor dsYellow;
diff --git a/DSView/pv/view/view.cpp b/DSView/pv/view/view.cpp
index 45e2afe9791e93c2176e0036f042eabe90bf9c33..4ae18dd912fb9315133455965fb83a9ec1e8c2cd 100644
--- a/DSView/pv/view/view.cpp
+++ b/DSView/pv/view/view.cpp
@@ -96,12 +96,10 @@ View::View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget
     setViewportMargins(headerWidth(), RulerHeight, 0, 0);
     setViewport(_viewport);
 
-	connect(&_session, SIGNAL(signals_changed()),
-		this, SLOT(signals_changed()));
-	connect(&_session, SIGNAL(data_updated()),
-		this, SLOT(data_updated()));
-    connect(&_session, SIGNAL(receive_data(quint64)),
-            this, SLOT(receive_data(quint64)));
+    connect(&_session, SIGNAL(signals_changed()),
+        this, SLOT(signals_changed()));
+    connect(&_session, SIGNAL(data_updated()),
+        this, SLOT(data_updated()));
     connect(&_session, SIGNAL(receive_trigger(quint64)),
             this, SLOT(set_trig_pos(quint64)));
 
@@ -550,7 +548,7 @@ bool View::viewportEvent(QEvent *e)
 int View::headerWidth()
 {
     int headerWidth;
-    int maxNameWidth = 0;
+    int maxNameWidth = 25;
     int maxLeftWidth = 0;
     int maxRightWidth = 0;
 
@@ -580,7 +578,11 @@ void View::resizeEvent(QResizeEvent*)
     if (_session.get_device()->dev_inst()->mode == DSO)
         _scale = _session.get_device()->get_time_base() * std::pow(10.0, -9.0) * DS_CONF_DSO_HDIVS / get_view_width();
 
-    _maxscale = _session.get_device()->get_sample_time() / (get_view_width() * MaxViewRate);
+    if (_session.get_device()->dev_inst()->mode != DSO)
+        _maxscale = _session.get_device()->get_sample_time() / (get_view_width() * MaxViewRate);
+    else
+        _maxscale = 1e9;
+
     _scale = min(_scale, _maxscale);
 
     signals_changed();
@@ -722,11 +724,6 @@ void View::set_cursor_middle(int index)
     set_scale_offset(_scale, (*i)->index() * 1.0 / _session.get_device()->get_sample_rate() - _scale * get_view_width() / 2);
 }
 
-void View::receive_data(quint64 length)
-{
-    _viewport->set_receive_len(length);
-}
-
 Viewport * View::get_viewport()
 {
     return _viewport;
diff --git a/DSView/pv/view/view.h b/DSView/pv/view/view.h
index 6d79b7b8ed9d190308703cf8908108fa39a70058..81bffcb27c5dff954523e0af83614bbe6e2bc92f 100644
--- a/DSView/pv/view/view.h
+++ b/DSView/pv/view/view.h
@@ -225,8 +225,6 @@ private slots:
 
     void header_updated();
 
-    void receive_data(quint64 length);
-
     void set_trig_pos(quint64 trig_pos);
 
 private:
diff --git a/DSView/pv/view/viewport.cpp b/DSView/pv/view/viewport.cpp
index 9cd58bdb5b131b7dd82272cc7428d4e9894d2d03..4ed6c3813aff3c7b78ab2e47fbc4457f8024115b 100644
--- a/DSView/pv/view/viewport.cpp
+++ b/DSView/pv/view/viewport.cpp
@@ -52,11 +52,14 @@ Viewport::Viewport(View &parent) :
     _total_receive_len(0),
     _zoom_rect_visible(false),
     _measure_shown(false),
+    _measure_type(LOGIC),
     _cur_sample(0),
     _nxt_sample(1),
     _cur_preX(0),
     _cur_aftX(1),
-    _cur_midY(0)
+    _cur_midY(0),
+    _hover_index(0),
+    _hover_hit(false)
 {
 	setMouseTracking(true);
 	setAutoFillBackground(true);
@@ -75,6 +78,9 @@ Viewport::Viewport(View &parent) :
         this, SLOT(on_traces_moved()));
     connect(&trigger_timer, SIGNAL(timeout()),
             this, SLOT(on_trigger_timer()));
+
+    connect(&_view.session(), &SigSession::receive_data,
+            this, &Viewport::set_receive_len);
 }
 
 int Viewport::get_total_height() const
@@ -214,7 +220,7 @@ void Viewport::paintProgress(QPainter &p)
 {
     using pv::view::Signal;
 
-    const quint64 _total_sample_len = _view.session().get_device()->get_sample_limit();
+    const uint64_t _total_sample_len = _view.session().get_device()->get_sample_limit();
     double progress = -(_total_receive_len * 1.0 / _total_sample_len * 360 * 16);
     int captured_progress = 0;
 
@@ -361,9 +367,6 @@ void Viewport::mousePressEvent(QMouseEvent *event)
             }
 
         }
-//        if (!_view.get_ruler()->get_grabbed_cursor()) {
-//            _zoom_rect_visible = true;
-//        }
 
         const vector< boost::shared_ptr<Signal> > sigs(_view.session().get_signals());
         BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) {
@@ -384,6 +387,7 @@ void Viewport::mouseMoveEvent(QMouseEvent *event)
 {
 	assert(event);
     _mouse_point = event->pos();
+    _hover_hit = false;
     if (event->buttons() & Qt::RightButton) {
         _zoom_rect = QRectF(_mouse_down_point, event->pos());
         _zoom_rect_visible = true;
@@ -437,6 +441,13 @@ void Viewport::mouseReleaseEvent(QMouseEvent *event)
     if(_drag_sig)
         _drag_sig.reset();
 
+
+    if (_hover_hit){
+        _view.add_cursor(view::Ruler::CursorColor[_view.get_cursorList().size() % 8], _hover_index);
+        _view.show_cursors(true);
+        _hover_hit = false;
+    }
+
     update();
 }
 
@@ -505,14 +516,17 @@ void Viewport::measure()
 {
    if (_view.session().get_capture_state() == SigSession::Running)
        return;
+   _measure_shown = false;
    const uint64_t sample_rate = _view.session().get_device()->get_sample_rate();
    const vector< boost::shared_ptr<Signal> > sigs(_view.session().get_signals());
    BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) {
        assert(s);
        boost::shared_ptr<view::LogicSignal> logicSig;
+       boost::shared_ptr<view::DsoSignal> dsoSig;
        if (logicSig = dynamic_pointer_cast<view::LogicSignal>(s)) {
            if (logicSig->measure(_view.hover_point(), _cur_sample, _nxt_sample, _thd_sample)) {
                _measure_shown = true;
+               _measure_type = LOGIC;
 
                _mm_width = _view.get_ruler()->format_real_time(_nxt_sample - _cur_sample, sample_rate);
                _mm_period = _thd_sample != 0 ? _view.get_ruler()->format_real_time(_thd_sample - _cur_sample, sample_rate) : "#####";
@@ -528,7 +542,7 @@ void Viewport::measure()
                _mm_duty = _thd_sample != 0 ? QString::number((_nxt_sample - _cur_sample) * 100.0 / (_thd_sample - _cur_sample), 'f', 2)+"%" :
                                              "#####";
                mouse_measure();
-               return;
+               break;
            } else {
                _mm_width = "#####";
                _mm_period = "#####";
@@ -536,66 +550,127 @@ void Viewport::measure()
                _mm_duty = "#####";
            }
            mouse_measure();
+       } else if (dsoSig = dynamic_pointer_cast<view::DsoSignal>(s)) {
+           if (_measure_en && dsoSig->measure(_view.hover_point())) {
+               _measure_shown = true;
+               _measure_type = DSO;
+           }
        }
     }
-
-    _measure_shown = false;
-    return;
 }
 
 void Viewport::paintMeasure(QPainter &p)
 {
-    p.setPen(QColor(17, 133, 209,  255));
-    p.drawLine(QLineF(_cur_preX, _cur_midY, _cur_aftX, _cur_midY));
-    p.drawLine(QLineF(_cur_preX, _cur_midY, _cur_preX + 2, _cur_midY - 2));
-    p.drawLine(QLineF(_cur_preX, _cur_midY, _cur_preX + 2, _cur_midY + 2));
-    p.drawLine(QLineF(_cur_aftX - 2, _cur_midY - 2, _cur_aftX, _cur_midY));
-    p.drawLine(QLineF(_cur_aftX - 2, _cur_midY + 2, _cur_aftX, _cur_midY));
-    if (_thd_sample != 0) {
-        p.drawLine(QLineF(_cur_aftX, _cur_midY, _cur_thdX, _cur_midY));
-        p.drawLine(QLineF(_cur_aftX, _cur_midY, _cur_aftX + 2, _cur_midY - 2));
-        p.drawLine(QLineF(_cur_aftX, _cur_midY, _cur_aftX + 2, _cur_midY + 2));
-        p.drawLine(QLineF(_cur_thdX - 2, _cur_midY - 2, _cur_thdX, _cur_midY));
-        p.drawLine(QLineF(_cur_thdX - 2, _cur_midY + 2, _cur_thdX, _cur_midY));
-    }
-
-    if (_measure_en) {
-        int typical_width = p.boundingRect(0, 0, INT_MAX, INT_MAX,
-            Qt::AlignLeft | Qt::AlignTop, _mm_width).width();
-        typical_width = max(typical_width, p.boundingRect(0, 0, INT_MAX, INT_MAX,
-            Qt::AlignLeft | Qt::AlignTop, _mm_period).width());
-        typical_width = max(typical_width, p.boundingRect(0, 0, INT_MAX, INT_MAX,
-            Qt::AlignLeft | Qt::AlignTop, _mm_freq).width());
-        typical_width = max(typical_width, p.boundingRect(0, 0, INT_MAX, INT_MAX,
-            Qt::AlignLeft | Qt::AlignTop, _mm_duty).width());
-        typical_width = typical_width + 100;
-
-        const double width = _view.get_view_width();
-        const double height = _view.viewport()->height();
-        const double left = _view.hover_point().x();
-        const double top = _view.hover_point().y();
-        const double right = left + typical_width;
-        const double bottom = top + 80;
-        QPointF org_pos = QPointF(right > width ? left - typical_width : left, bottom > height ? top - 80 : top);
-        QRectF measure_rect = QRectF(org_pos.x(), org_pos.y(), (double)typical_width, 80.0);
-        QRectF measure1_rect = QRectF(org_pos.x(), org_pos.y(), (double)typical_width, 20.0);
-        QRectF measure2_rect = QRectF(org_pos.x(), org_pos.y()+20, (double)typical_width, 20.0);
-        QRectF measure3_rect = QRectF(org_pos.x(), org_pos.y()+40, (double)typical_width, 20.0);
-        QRectF measure4_rect = QRectF(org_pos.x(), org_pos.y()+60, (double)typical_width, 20.0);
+    _hover_hit = false;
+    if (_measure_type == LOGIC) {
+        p.setPen(QColor(17, 133, 209,  255));
+        p.drawLine(QLineF(_cur_preX, _cur_midY, _cur_aftX, _cur_midY));
+        p.drawLine(QLineF(_cur_preX, _cur_midY, _cur_preX + 2, _cur_midY - 2));
+        p.drawLine(QLineF(_cur_preX, _cur_midY, _cur_preX + 2, _cur_midY + 2));
+        p.drawLine(QLineF(_cur_aftX - 2, _cur_midY - 2, _cur_aftX, _cur_midY));
+        p.drawLine(QLineF(_cur_aftX - 2, _cur_midY + 2, _cur_aftX, _cur_midY));
+        if (_thd_sample != 0) {
+            p.drawLine(QLineF(_cur_aftX, _cur_midY, _cur_thdX, _cur_midY));
+            p.drawLine(QLineF(_cur_aftX, _cur_midY, _cur_aftX + 2, _cur_midY - 2));
+            p.drawLine(QLineF(_cur_aftX, _cur_midY, _cur_aftX + 2, _cur_midY + 2));
+            p.drawLine(QLineF(_cur_thdX - 2, _cur_midY - 2, _cur_thdX, _cur_midY));
+            p.drawLine(QLineF(_cur_thdX - 2, _cur_midY + 2, _cur_thdX, _cur_midY));
+        }
 
-        p.setPen(Qt::NoPen);
-        p.setBrush(QColor(17, 133, 209,  150));
-        p.drawRect(measure_rect);
-
-        p.setPen(Qt::black);
-        p.drawText(measure1_rect, Qt::AlignRight | Qt::AlignVCenter,
-                   "Width: " + _mm_width);
-        p.drawText(measure2_rect, Qt::AlignRight | Qt::AlignVCenter,
-                   "Period: " + _mm_period);
-        p.drawText(measure3_rect, Qt::AlignRight | Qt::AlignVCenter,
-                   "Frequency: " + _mm_freq);
-        p.drawText(measure4_rect, Qt::AlignRight | Qt::AlignVCenter,
-                   "Duty Cycle: " + _mm_duty);
+        if (_measure_en) {
+            int typical_width = p.boundingRect(0, 0, INT_MAX, INT_MAX,
+                Qt::AlignLeft | Qt::AlignTop, _mm_width).width();
+            typical_width = max(typical_width, p.boundingRect(0, 0, INT_MAX, INT_MAX,
+                Qt::AlignLeft | Qt::AlignTop, _mm_period).width());
+            typical_width = max(typical_width, p.boundingRect(0, 0, INT_MAX, INT_MAX,
+                Qt::AlignLeft | Qt::AlignTop, _mm_freq).width());
+            typical_width = max(typical_width, p.boundingRect(0, 0, INT_MAX, INT_MAX,
+                Qt::AlignLeft | Qt::AlignTop, _mm_duty).width());
+            typical_width = typical_width + 100;
+
+            const double width = _view.get_view_width();
+            const double height = _view.viewport()->height();
+            const double left = _view.hover_point().x();
+            const double top = _view.hover_point().y();
+            const double right = left + typical_width;
+            const double bottom = top + 80;
+            QPointF org_pos = QPointF(right > width ? left - typical_width : left, bottom > height ? top - 80 : top);
+            QRectF measure_rect = QRectF(org_pos.x(), org_pos.y(), (double)typical_width, 80.0);
+            QRectF measure1_rect = QRectF(org_pos.x(), org_pos.y(), (double)typical_width, 20.0);
+            QRectF measure2_rect = QRectF(org_pos.x(), org_pos.y()+20, (double)typical_width, 20.0);
+            QRectF measure3_rect = QRectF(org_pos.x(), org_pos.y()+40, (double)typical_width, 20.0);
+            QRectF measure4_rect = QRectF(org_pos.x(), org_pos.y()+60, (double)typical_width, 20.0);
+
+            p.setPen(Qt::NoPen);
+            p.setBrush(QColor(17, 133, 209,  150));
+            p.drawRect(measure_rect);
+
+            p.setPen(Qt::black);
+            p.drawText(measure1_rect, Qt::AlignRight | Qt::AlignVCenter,
+                       "Width: " + _mm_width);
+            p.drawText(measure2_rect, Qt::AlignRight | Qt::AlignVCenter,
+                       "Period: " + _mm_period);
+            p.drawText(measure3_rect, Qt::AlignRight | Qt::AlignVCenter,
+                       "Frequency: " + _mm_freq);
+            p.drawText(measure4_rect, Qt::AlignRight | Qt::AlignVCenter,
+                       "Duty Cycle: " + _mm_duty);
+        }
+    } else if (_measure_type == DSO) {
+        const vector< boost::shared_ptr<Signal> > sigs(_view.session().get_signals());
+        BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) {
+            boost::shared_ptr<view::DsoSignal> dsoSig;
+            if (dsoSig = dynamic_pointer_cast<view::DsoSignal>(s)) {
+                uint64_t index;
+                double value;
+                QPointF hpoint;
+                const int arrow_size = 5;
+                const int mark_radius = 10;
+                const int mark_width = 20;
+                const int mark_cursor_height = 30;
+                if (dsoSig->get_hover(index, hpoint, value)) {
+                    p.setPen(dsoSig->get_colour());
+                    const QRectF hpoint_rect = QRectF(hpoint.x()-mark_radius/2, hpoint.y()-mark_radius/2, mark_radius, mark_radius);
+                    if (hpoint_rect.contains(_view.hover_point())) {
+                        p.setBrush(dsoSig->get_colour());
+                        const int cursor_up = hpoint.y()-mark_cursor_height;
+                        const int cursor_dn = hpoint.y()+mark_cursor_height;
+                        const int cursor_lf = hpoint.x()-arrow_size;
+                        const int cursor_md = hpoint.x();
+                        const int cursor_rt = hpoint.x()+arrow_size;
+
+                        const QPointF up_arrow[3] = {
+                            QPointF(cursor_lf, cursor_up+arrow_size),
+                            QPointF(cursor_md, cursor_up),
+                            QPointF(cursor_rt, cursor_up+arrow_size),
+                        };
+                        const QPointF dn_arrow[3] = {
+                            QPointF(cursor_lf, cursor_dn-arrow_size),
+                            QPointF(cursor_md, cursor_dn),
+                            QPointF(cursor_rt, cursor_dn-arrow_size),
+                        };
+                        p.drawPolyline(up_arrow, 3);
+                        p.drawPolyline(dn_arrow, 3);
+                        p.drawLine(cursor_md, cursor_up, cursor_md, cursor_dn);
+                        _hover_hit = true;
+                        _hover_index = index;
+                    } else {
+                        p.setBrush(Qt::NoBrush);
+                    }
+                    p.drawEllipse(hpoint, mark_radius, mark_radius);
+                    QString value_c = abs(value) > 1000 ? QString::number(value/1000.0, 'f', 2) + "V" : QString::number(value, 'f', 2) + "mV";
+                    int value_width = p.boundingRect(0, 0, INT_MAX, INT_MAX,
+                                                       Qt::AlignLeft | Qt::AlignTop, value_c).width();
+                    const bool right = dsoSig->get_index()%2 ? hpoint.x() < value_width : hpoint.x() < _view.get_view_width() - value_width;
+                    const bool up = hpoint.y() > 50;
+                    const QPointF hpoint_sec = QPointF(hpoint.x() - (right ? -mark_width : mark_width), hpoint.y() - (up ? mark_width : -mark_width));
+                    p.drawLine(hpoint, hpoint_sec);
+                    p.drawLine(hpoint_sec, QPointF(hpoint_sec.x() + (right ? value_width : -value_width), hpoint_sec.y()));
+                    p.drawText(QRectF(right ? hpoint_sec.x() : hpoint_sec.x() - value_width, hpoint_sec.y() - mark_width, value_width, mark_width),
+                               Qt::AlignLeft | Qt::AlignBottom,
+                               value_c);
+                }
+            }
+        }
     }
 }
 
diff --git a/DSView/pv/view/viewport.h b/DSView/pv/view/viewport.h
index ae43c0e2a7863f6740767838d7247bb01944090b..4899577bc0a0498dc7d164117397b641b0892de4 100644
--- a/DSView/pv/view/viewport.h
+++ b/DSView/pv/view/viewport.h
@@ -56,8 +56,6 @@ public:
 
     QPoint get_mouse_point() const;
 
-    void set_receive_len(quint64 length);
-
     QString get_measure(QString option);
 
     void set_measure_en(int enable);
@@ -85,6 +83,7 @@ private:
 private slots:
     void on_traces_moved();
     void on_trigger_timer();
+    void set_receive_len(quint64 length);
 
 signals:
     void mouse_measure();
@@ -92,7 +91,7 @@ signals:
 private:
 	View &_view;
 
-    quint64 _total_receive_len;
+    uint64_t _total_receive_len;
     QPoint _mouse_point;
 	QPoint _mouse_down_point;
 	double _mouse_down_offset;
@@ -107,6 +106,7 @@ private:
 
     bool _measure_en;
     bool _measure_shown;
+    int _measure_type;
     uint64_t _cur_sample;
     uint64_t _nxt_sample;
     uint64_t _thd_sample;
@@ -124,6 +124,9 @@ private:
     int timer_cnt;
 
     boost::shared_ptr<Signal> _drag_sig;
+
+    uint64_t _hover_index;
+    bool _hover_hit;
 };
 
 } // namespace view
diff --git a/DSView/res/DSCope.bin b/DSView/res/DSCope.bin
index c79028f488688609779c96902795bc9770db54de..a37ddece547c9a9ae63179ddd47cbb3dc26ab614 100644
Binary files a/DSView/res/DSCope.bin and b/DSView/res/DSCope.bin differ
diff --git a/libsigrok4DSL/hardware/DSL/dscope.c b/libsigrok4DSL/hardware/DSL/dscope.c
index d4be1a7cb94335212a30c284ac32b67bbb4995ef..bcd6e05287849c8202b2e8aac10901aa245f1ca6 100644
--- a/libsigrok4DSL/hardware/DSL/dscope.c
+++ b/libsigrok4DSL/hardware/DSL/dscope.c
@@ -249,7 +249,7 @@ static int fpga_setting(const struct sr_dev_inst *sdi)
                    ((sdi->mode == ANALOG) << 7) +
                    ((devc->filter == SR_FILTER_1T) << 8) +
                    (devc->instant << 9) + (devc->zero << 10);
-    setting.divider = devc->zero ? 0x1 : (uint32_t)ceil(SR_MHZ(100) * 1.0 / devc->cur_samplerate);
+    setting.divider = devc->zero ? 0x1 : (uint32_t)ceil(DSCOPE_MAX_SAMPLERATE * 1.0 / devc->cur_samplerate / channel_en_cnt);
     setting.count = (uint32_t)(devc->limit_samples / (channel_cnt / channel_en_cnt));
     setting.trig_pos = (uint32_t)(trigger->trigger_pos / 100.0 * devc->limit_samples);
     setting.trig_glb = trigger->trigger_stages;
@@ -847,7 +847,7 @@ static uint64_t dso_cmd_gen(struct sr_dev_inst *sdi, struct sr_channel* ch, int
             channel_cnt += probe->enabled;
         }
         cmd += 0x18;
-        uint32_t divider = devc->zero ? 0x1 : (uint32_t)ceil(SR_MHZ(100) * 1.0 / devc->cur_samplerate);
+        uint32_t divider = devc->zero ? 0x1 : (uint32_t)ceil(DSCOPE_MAX_SAMPLERATE * 1.0 / devc->cur_samplerate / channel_cnt);
         cmd += divider << 8;
         break;
     case SR_CONF_HORIZ_TRIGGERPOS:
@@ -1174,6 +1174,11 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
             return SR_ERR;
         *data = g_variant_new_uint64(ch->vdiv);
         break;
+    case SR_CONF_FACTOR:
+        if (!ch)
+            return SR_ERR;
+        *data = g_variant_new_uint64(ch->vfactor);
+        break;
     case SR_CONF_VPOS:
         if (!ch)
             return SR_ERR;
@@ -1422,6 +1427,8 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi,
         else
             sr_dbg("%s: setting VDIV of channel %d to %d mv failed",
                 __func__, ch->index, ch->vdiv);
+    } else if (id == SR_CONF_FACTOR) {
+        ch->vfactor = g_variant_get_uint64(data);
     } else if (id == SR_CONF_VPOS) {
         ch->vpos = g_variant_get_double(data);
         if (sdi->mode == DSO) {
@@ -1854,11 +1861,12 @@ static void receive_transfer(struct libusb_transfer *transfer)
                 mstatus.ch0_max = *((const uint8_t*)cur_buf + mstatus_offset*2 + 1*2);
                 mstatus.ch0_min = *((const uint8_t*)cur_buf + mstatus_offset*2 + 3);
                 mstatus.ch0_period = *((const uint32_t*)cur_buf + mstatus_offset/2 + 2/2);
-                mstatus.ch0_pcnt = *((const uint32_t*)cur_buf + mstatus_offset/2 + 4/2);
-                mstatus.ch1_max = *((const uint8_t*)cur_buf + mstatus_offset*2 + 7*2);
-                mstatus.ch1_min = *((const uint8_t*)cur_buf + mstatus_offset*2 + 15);
-                mstatus.ch1_period = *((const uint32_t*)cur_buf + mstatus_offset/2 + 8/2);
-                mstatus.ch1_pcnt = *((const uint32_t*)cur_buf + mstatus_offset/2 + 10/2);
+                mstatus.ch0_period += ((uint64_t)*((const uint32_t*)cur_buf + mstatus_offset/2 + 4/2)) << 32;
+                mstatus.ch0_pcnt = *((const uint32_t*)cur_buf + mstatus_offset/2 + 6/2);
+                mstatus.ch1_max = *((const uint8_t*)cur_buf + mstatus_offset*2 + 9*2);
+                mstatus.ch1_min = *((const uint8_t*)cur_buf + mstatus_offset*2 + 19);
+                mstatus.ch1_period = *((const uint32_t*)cur_buf + mstatus_offset/2 + 10/2);
+                mstatus.ch1_period += ((uint64_t)*((const uint32_t*)cur_buf + mstatus_offset/2 + 12/2)) << 32;
                 mstatus.vlen = *((const uint32_t*)cur_buf + mstatus_offset/2 + 16/2) & 0x7fffffff;
                 mstatus.stream_mode = *((const uint32_t*)cur_buf + mstatus_offset/2 + 16/2) & 0x80000000;
                 mstatus.sample_divider = *((const uint32_t*)cur_buf + mstatus_offset/2 + 18/2);
@@ -1880,7 +1888,7 @@ static void receive_transfer(struct libusb_transfer *transfer)
                 mstatus.vlen = instant_buffer_size;
             }
 
-            const uint32_t divider = devc->zero ? 0x1 : (uint32_t)ceil(SR_MHZ(100) * 1.0 / devc->cur_samplerate);
+            const uint32_t divider = devc->zero ? 0x1 : (uint32_t)ceil(DSCOPE_MAX_SAMPLERATE * 1.0 / devc->cur_samplerate / channel_en_cnt);
             if ((mstatus.sample_divider == divider &&
                 mstatus.vlen != 0 &&
                 mstatus.vlen <= (transfer->actual_length - 512) / sample_width) ||
diff --git a/libsigrok4DSL/hardware/DSL/dslogic.c b/libsigrok4DSL/hardware/DSL/dslogic.c
index 01f017a39e340eef566ddf11d077a036fdd5a733..16bf94b6da8062682f6141a139bcf109466fdbfd 100644
--- a/libsigrok4DSL/hardware/DSL/dslogic.c
+++ b/libsigrok4DSL/hardware/DSL/dslogic.c
@@ -287,7 +287,10 @@ static int fpga_setting(const struct sr_dev_inst *sdi)
                    ((sdi->mode == ANALOG) << 7) +
                    ((devc->filter == SR_FILTER_1T) << 8) +
                    (devc->instant << 9) + (devc->zero << 10);
-    setting.divider = devc->zero ? 0x1 : (uint32_t)ceil(SR_MHZ(100) * 1.0 / devc->cur_samplerate);
+    if (sdi->mode == DSO)
+        setting.divider = devc->zero ? 0x1 : (uint32_t)ceil(DSLOGIC_MAX_DSO_SAMPLERATE * 1.0 / devc->cur_samplerate / channel_en_cnt);
+    else
+        setting.divider = devc->zero ? 0x1 : (uint32_t)ceil(DSLOGIC_MAX_LOGIC_SAMPLERATE * 1.0 / devc->cur_samplerate);
     setting.count = (sdi->mode == DSO) ? (uint32_t)(devc->limit_samples / (channel_cnt / channel_en_cnt)) : (uint32_t)(devc->limit_samples);
     setting.trig_pos = (uint32_t)(trigger->trigger_pos / 100.0 * devc->limit_samples);
     setting.trig_glb = trigger->trigger_stages;
@@ -882,7 +885,7 @@ static uint64_t dso_cmd_gen(struct sr_dev_inst *sdi, struct sr_channel* ch, int
             channel_cnt += probe->enabled;
         }
         cmd += 0x18;
-        uint32_t divider = devc->zero ? 0x1 : (uint32_t)ceil(SR_MHZ(100) * 1.0  / devc->cur_samplerate);
+        uint32_t divider = devc->zero ? 0x1 : (uint32_t)ceil(DSLOGIC_MAX_DSO_SAMPLERATE * 1.0  / devc->cur_samplerate / channel_cnt);
         cmd += divider << 8;
         break;
     case SR_CONF_HORIZ_TRIGGERPOS:
@@ -1157,6 +1160,11 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
             return SR_ERR;
         *data = g_variant_new_uint64(ch->vdiv);
         break;
+    case SR_CONF_FACTOR:
+        if (!ch)
+            return SR_ERR;
+        *data = g_variant_new_uint64(ch->vfactor);
+        break;
     case SR_CONF_TIMEBASE:
         if (!sdi)
             return SR_ERR;
@@ -1519,6 +1527,8 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi,
         else
             sr_dbg("%s: setting VDIV of channel %d to %d mv failed",
                 __func__, ch->index, ch->vdiv);
+    } else if (id == SR_CONF_FACTOR) {
+        ch->vfactor = g_variant_get_uint64(data);
     } else if (id == SR_CONF_TIMEBASE) {
         devc->timebase = g_variant_get_uint64(data);
     } else if (id == SR_CONF_COUPLING) {
@@ -1936,11 +1946,13 @@ static void receive_transfer(struct libusb_transfer *transfer)
                 mstatus.ch0_max = *((const uint8_t*)cur_buf + mstatus_offset*2 + 1*2);
                 mstatus.ch0_min = *((const uint8_t*)cur_buf + mstatus_offset*2 + 3);
                 mstatus.ch0_period = *((const uint32_t*)cur_buf + mstatus_offset/2 + 2/2);
-                mstatus.ch0_pcnt = *((const uint32_t*)cur_buf + mstatus_offset/2 + 4/2);
-                mstatus.ch1_max = *((const uint8_t*)cur_buf + mstatus_offset*2 + 7*2);
-                mstatus.ch1_min = *((const uint8_t*)cur_buf + mstatus_offset*2 + 15);
-                mstatus.ch1_period = *((const uint32_t*)cur_buf + mstatus_offset/2 + 8/2);
-                mstatus.ch1_pcnt = *((const uint32_t*)cur_buf + mstatus_offset/2 + 10/2);
+                mstatus.ch0_period += *((const uint32_t*)cur_buf + mstatus_offset/2 + 4/2) << 32;
+                mstatus.ch0_pcnt = *((const uint32_t*)cur_buf + mstatus_offset/2 + 6/2);
+                mstatus.ch1_max = *((const uint8_t*)cur_buf + mstatus_offset*2 + 9*2);
+                mstatus.ch1_min = *((const uint8_t*)cur_buf + mstatus_offset*2 + 19);
+                mstatus.ch1_period = *((const uint32_t*)cur_buf + mstatus_offset/2 + 10/2);
+                mstatus.ch1_period += *((const uint32_t*)cur_buf + mstatus_offset/2 + 12/2) << 32;
+                mstatus.ch1_pcnt = *((const uint32_t*)cur_buf + mstatus_offset/2 + 14/2);
                 mstatus.vlen = *((const uint32_t*)cur_buf + mstatus_offset/2 + 16/2) & 0x7fffffff;
                 mstatus.stream_mode = *((const uint32_t*)cur_buf + mstatus_offset/2 + 16/2) & 0x80000000;
                 mstatus.sample_divider = *((const uint32_t*)cur_buf + mstatus_offset/2 + 18/2);
@@ -1955,7 +1967,7 @@ static void receive_transfer(struct libusb_transfer *transfer)
             } else {
                 mstatus.vlen = instant_buffer_size;
             }
-            const uint32_t divider = devc->zero ? 0x1 : (uint32_t)ceil(SR_MHZ(100) * 1.0 / devc->cur_samplerate);
+            const uint32_t divider = devc->zero ? 0x1 : (uint32_t)ceil(DSLOGIC_MAX_DSO_SAMPLERATE * 1.0 / devc->cur_samplerate / channel_en_cnt);
             if ((mstatus.sample_divider == divider &&
                 mstatus.vlen != 0 &&
                 mstatus.vlen <= (transfer->actual_length - 512) / sample_width) ||
diff --git a/libsigrok4DSL/hardware/demo/demo.c b/libsigrok4DSL/hardware/demo/demo.c
index b31c1a08c2ee4a72aa2ffe2ed81a7730dc75a38a..861b38a0cc5616f8ff48f642dd8497251d4576f7 100644
--- a/libsigrok4DSL/hardware/demo/demo.c
+++ b/libsigrok4DSL/hardware/demo/demo.c
@@ -344,6 +344,9 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
     case SR_CONF_VDIV:
         *data = g_variant_new_uint64(ch->vdiv);
         break;
+    case SR_CONF_FACTOR:
+        *data = g_variant_new_uint64(ch->vfactor);
+        break;
     case SR_CONF_TIMEBASE:
         *data = g_variant_new_uint64(devc->timebase);
         break;
@@ -424,6 +427,7 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi,
                     ret = SR_ERR;
                 else {
                     probe->vdiv = 1000;
+                    probe->vfactor = 1;
                     probe->coupling = SR_DC_COUPLING;
                     probe->trig_value = 0x80;
                     sdi->channels = g_slist_append(sdi->channels, probe);
@@ -472,6 +476,11 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi,
         sr_dbg("%s: setting VDIV of channel %d to %" PRIu64, __func__,
                ch->index, ch->vdiv);
         ret = SR_OK;
+    } else if (id == SR_CONF_FACTOR) {
+        ch->vfactor = g_variant_get_uint64(data);
+        sr_dbg("%s: setting FACTOR of channel %d to %" PRIu64, __func__,
+               ch->index, ch->vfactor);
+        ret = SR_OK;
     } else if (id == SR_CONF_TIMEBASE) {
         devc->timebase = g_variant_get_uint64(data);
         sr_dbg("%s: setting TIMEBASE to %" PRIu64, __func__,
diff --git a/libsigrok4DSL/hwdriver.c b/libsigrok4DSL/hwdriver.c
index 239827eb9174bd8abe572eb9ce071069ab60e807..3b2af0ae3ce779fde156405b1345400dc8f8e52b 100644
--- a/libsigrok4DSL/hwdriver.c
+++ b/libsigrok4DSL/hwdriver.c
@@ -83,6 +83,8 @@ static struct sr_config_info sr_config_info_data[] = {
         "Filter Targets", NULL},
     {SR_CONF_VDIV, SR_T_RATIONAL_VOLT, "vdiv",
 		"Volts/div", NULL},
+    {SR_CONF_VDIV, SR_T_RATIONAL_VOLT, "factor",
+        "Probe Factor", NULL},
     {SR_CONF_COUPLING, SR_T_CHAR, "coupling",
         "Coupling", NULL},
 	{SR_CONF_DATALOG, SR_T_BOOL, "datalog",
diff --git a/libsigrok4DSL/libsigrok.h b/libsigrok4DSL/libsigrok.h
index 1836bf25bc2e7b516936d3b74ecc5a710eb15a2f..dac954c2058ad5051468ab6f5dc355587f2a89c5 100644
--- a/libsigrok4DSL/libsigrok.h
+++ b/libsigrok4DSL/libsigrok.h
@@ -32,7 +32,7 @@
 #define WINVER 0x0501
 #define _WIN32_WINNT WINVER
 #include <Winsock2.h>
-#include <ddk/usbiodef.h>
+#include <usbiodef.h>
 #endif
 
 #ifdef __cplusplus
@@ -389,7 +389,7 @@ struct sr_input_format {
 
 	/**
 	 * Load a file, parsing the input according to the file's format.
-	 *
+     *
 	 * This function will send datafeed packets to the session bus, so
 	 * the calling frontend must have registered its session callbacks
 	 * beforehand.
@@ -404,7 +404,7 @@ struct sr_input_format {
 	 *           the responsibility of the caller to free it later.
 	 * @param filename The name (and path) of the file to use.
 	 *
-	 * @return SR_OK upon success, a negative error code upon failure.
+     * @return SR_OK upon succcess, a negative error code upon failure.
 	 */
 	int (*loadfile) (struct sr_input *in, const char *filename);
 };
@@ -610,11 +610,11 @@ struct sr_status {
 
     uint8_t ch0_max;
     uint8_t ch0_min;
-    uint32_t ch0_period;
+    uint64_t ch0_period;
     uint32_t ch0_pcnt;
     uint8_t ch1_max;
     uint8_t ch1_min;
-    uint32_t ch1_period;
+    uint64_t ch1_period;
     uint32_t ch1_pcnt;
 
     uint32_t vlen;
@@ -767,6 +767,9 @@ enum {
     /** Channel enable for dso channel. */
     SR_CONF_EN_CH,
 
+    /** probe factor for dso channel. */
+    SR_CONF_FACTOR,
+
 	/** Trigger types.  */
 	SR_CONF_TRIGGER_TYPE,