diff --git a/DSView/pv/data/decoderstack.cpp b/DSView/pv/data/decoderstack.cpp
index e52a91f4cf71c023c9f50186bfa6b3be7f0578b5..e9ac125da40c2787ebcd2cae54c221dae186519e 100644
--- a/DSView/pv/data/decoderstack.cpp
+++ b/DSView/pv/data/decoderstack.cpp
@@ -332,6 +332,7 @@ void DecoderStack::clear()
 	_sample_count = 0;
 	_frame_complete = false;
 	_samples_decoded = 0;
+    //new_decode_data();
 	_error_message = QString();
     for (map<const Row, RowData>::const_iterator i = _rows.begin();
         i != _rows.end(); i++)
@@ -468,7 +469,6 @@ void DecoderStack::decode_data(
     }
     _options_changed = false;
     decode_done();
-    //new_decode_data();
 }
 
 void DecoderStack::decode_proc()
diff --git a/DSView/pv/dock/protocoldock.cpp b/DSView/pv/dock/protocoldock.cpp
index 637022e169e3fc8b20d12c905069c7a12bb8d2de..087a63bbd7715323fa883d363fa7f61231bba94c 100644
--- a/DSView/pv/dock/protocoldock.cpp
+++ b/DSView/pv/dock/protocoldock.cpp
@@ -200,6 +200,7 @@ void ProtocolDock::add_protocol()
             _set_button->setIcon(QIcon::fromTheme("protocol",
                                  QIcon(":/icons/gear.png")));
             QLabel *_protocol_label = new QLabel(_up_widget);
+            QLabel *_progress_label = new QLabel(_up_widget);
 
             _del_button->setCheckable(true);
             _protocol_label->setText(_protocol_combobox->currentText());
@@ -212,17 +213,23 @@ void ProtocolDock::add_protocol()
             _del_button_list.push_back(_del_button);
             _set_button_list.push_back(_set_button);
             _protocol_label_list.push_back(_protocol_label);
+            _progress_label_list.push_back(_progress_label);
             _protocol_index_list.push_back(_protocol_combobox->currentIndex());
 
             QHBoxLayout *hori_layout = new QHBoxLayout();
             hori_layout->addWidget(_set_button);
             hori_layout->addWidget(_del_button);
             hori_layout->addWidget(_protocol_label);
+            hori_layout->addWidget(_progress_label);
             hori_layout->addStretch(1);
             _hori_layout_list.push_back(hori_layout);
             _up_layout->insertLayout(_del_button_list.size(), hori_layout);
 
-            //_session.add_protocol_analyzer(_protocol_combobox->currentIndex(), _sel_probes, _options, _options_index);
+            // progress connection
+            const std::vector< boost::shared_ptr<pv::view::DecodeTrace> > decode_sigs(
+                _session.get_decode_signals());
+            //connect(decode_sigs.back().get(), SIGNAL(decoded_progress(int)), this, SLOT(decoded_progess(int)));
+
             protocol_updated();
         }
     }
@@ -265,6 +272,7 @@ void ProtocolDock::del_protocol()
                 delete _del_button_list.at(del_index);
                 delete _set_button_list.at(del_index);
                 delete _protocol_label_list.at(del_index);
+                delete _progress_label_list.at(del_index);
 
                 _session.remove_decode_signal(0);
                 del_index++;
@@ -273,6 +281,7 @@ void ProtocolDock::del_protocol()
             _del_button_list.clear();
             _set_button_list.clear();
             _protocol_label_list.clear();
+            _progress_label_list.clear();
             _protocol_index_list.clear();
         } else {
             QMessageBox msg(this);
@@ -293,11 +302,13 @@ void ProtocolDock::del_protocol()
                delete _del_button_list.at(del_index);
                delete _set_button_list.at(del_index);
                delete _protocol_label_list.at(del_index);
+               delete _progress_label_list.at(del_index);
 
                _hori_layout_list.remove(del_index);
                _del_button_list.remove(del_index);
                _set_button_list.remove(del_index);
                _protocol_label_list.remove(del_index);
+               _progress_label_list.remove(del_index);
                _protocol_index_list.remove(del_index);
 
                _session.remove_decode_signal(del_index);
@@ -320,6 +331,7 @@ void ProtocolDock::del_all_protocol()
             delete _del_button_list.at(del_index);
             delete _set_button_list.at(del_index);
             delete _protocol_label_list.at(del_index);
+            delete _progress_label_list.at(del_index);
 
             _session.remove_decode_signal(0);
             del_index++;
@@ -328,12 +340,31 @@ void ProtocolDock::del_all_protocol()
         _del_button_list.clear();
         _set_button_list.clear();
         _protocol_label_list.clear();
+        _progress_label_list.clear();
         _protocol_index_list.clear();
 
         protocol_updated();
     }
 }
 
+void ProtocolDock::decoded_progess(int progress)
+{
+    (void) progress;
+
+    const std::vector< boost::shared_ptr<pv::view::DecodeTrace> > decode_sigs(
+        _session.get_decode_signals());
+    int index = 0;
+    BOOST_FOREACH(boost::shared_ptr<pv::view::DecodeTrace> d, decode_sigs) {
+        QString progress_str = QString::number(d->get_progress()) + "%";
+        if (d->get_progress() == 100)
+            _progress_label_list.at(index)->setStyleSheet("color:green;");
+        else
+            _progress_label_list.at(index)->setStyleSheet("color:red;");
+        _progress_label_list.at(index)->setText(progress_str);
+        index++;
+    }
+}
+
 void ProtocolDock::set_model()
 {
     pv::dialogs::ProtocolList *protocollist_dlg = new pv::dialogs::ProtocolList(this, _session);
diff --git a/DSView/pv/dock/protocoldock.h b/DSView/pv/dock/protocoldock.h
index 96d3112478b756a27cd4c1a994bde79d569b2111..8ca0d1986f7a141941c4cb59386a241f5d11d147 100644
--- a/DSView/pv/dock/protocoldock.h
+++ b/DSView/pv/dock/protocoldock.h
@@ -72,6 +72,7 @@ private slots:
     void add_protocol();
     void rst_protocol();
     void del_protocol();
+    void decoded_progess(int progress);
     void set_model();
     void update_model();
     void export_table_view();
@@ -96,6 +97,7 @@ private:
     QVector <QPushButton *> _del_button_list;
     QVector <QPushButton *> _set_button_list;
     QVector <QLabel *> _protocol_label_list;
+    QVector <QLabel *> _progress_label_list;
     QVector <int > _protocol_index_list;
     QVector <QHBoxLayout *> _hori_layout_list;
     QVBoxLayout *_up_layout;
diff --git a/DSView/pv/dock/triggerdock.cpp b/DSView/pv/dock/triggerdock.cpp
index dc32ad8a10e6acd890e5c5267ea6a36d9e160bcd..6dc4ca6df501445fae13c89590089c741a3b3543 100644
--- a/DSView/pv/dock/triggerdock.cpp
+++ b/DSView/pv/dock/triggerdock.cpp
@@ -38,6 +38,8 @@
 namespace pv {
 namespace dock {
 
+const int TriggerDock::MinTrigPosition = 1;
+
 TriggerDock::TriggerDock(QWidget *parent, SigSession &session) :
     QScrollArea(parent),
     _session(session)
@@ -56,10 +58,10 @@ TriggerDock::TriggerDock(QWidget *parent, SigSession &session) :
 
     position_label = new QLabel(tr("Trigger Position: "), _widget);
     position_spinBox = new QSpinBox(_widget);
-    position_spinBox->setRange(0, 99);
+    position_spinBox->setRange(MinTrigPosition, 99);
     position_spinBox->setButtonSymbols(QAbstractSpinBox::NoButtons);
     position_slider = new QSlider(Qt::Horizontal, _widget);
-    position_slider->setRange(0, 99);
+    position_slider->setRange(MinTrigPosition, 99);
     connect(position_slider, SIGNAL(valueChanged(int)), position_spinBox, SLOT(setValue(int)));
     connect(position_spinBox, SIGNAL(valueChanged(int)), position_slider, SLOT(setValue(int)));
 
@@ -356,8 +358,8 @@ void TriggerDock::device_change()
                 maxRange = 99;
             else
                 maxRange = max_hd_depth*70 / sample_limits;
-            position_spinBox->setRange(0, maxRange);
-            position_slider->setRange(0, maxRange);
+            position_spinBox->setRange(MinTrigPosition, maxRange);
+            position_slider->setRange(MinTrigPosition, maxRange);
 
 
 
diff --git a/DSView/pv/dock/triggerdock.h b/DSView/pv/dock/triggerdock.h
index 4ec977a31a1ef1fc397d8dee796a8ab7e283339e..ece32316e405f53fb409d071fc83783d534a64fb 100644
--- a/DSView/pv/dock/triggerdock.h
+++ b/DSView/pv/dock/triggerdock.h
@@ -55,6 +55,9 @@ class TriggerDock : public QScrollArea
 {
     Q_OBJECT
 
+private:
+    static const int MinTrigPosition;
+
 public:
     TriggerDock(QWidget *parent, SigSession &session);
     ~TriggerDock();
diff --git a/DSView/pv/mainwindow.cpp b/DSView/pv/mainwindow.cpp
index 0806142ab38a2a1885b0351b81d23401c3ce0f89..57ca57f24bb50ae8bbb2c33e851bd19ae8c76e3b 100644
--- a/DSView/pv/mainwindow.cpp
+++ b/DSView/pv/mainwindow.cpp
@@ -112,7 +112,7 @@ void MainWindow::setup_ui()
 {
 	setObjectName(QString::fromUtf8("MainWindow"));
     setMinimumHeight(680);
-    setMinimumWidth(300);
+    setMinimumWidth(500);
 	resize(1024, 768);
 
 	// Set the window icon
@@ -192,8 +192,6 @@ void MainWindow::setup_ui()
         SLOT(run_stop()));
     connect(_sampling_bar, SIGNAL(instant_stop()), this,
         SLOT(instant_stop()));
-    connect(_sampling_bar, SIGNAL(update_scale()), _view,
-        SLOT(update_scale()), Qt::DirectConnection);
     connect(_sampling_bar, SIGNAL(sample_count_changed()), _trigger_widget,
         SLOT(device_change()));
     connect(_dso_trigger_widget, SIGNAL(set_trig_pos(quint64)), _view,
@@ -248,6 +246,8 @@ void MainWindow::setup_ui()
             SLOT(test_data_error()));
     connect(&_session, SIGNAL(malloc_error()), this,
             SLOT(malloc_error()));
+    connect(&_session, SIGNAL(hardware_connect_failed()), this,
+            SLOT(hardware_connect_failed()));
 
     connect(_view, SIGNAL(cursor_update()), _measure_widget,
             SLOT(cursor_update()));
@@ -471,6 +471,17 @@ void MainWindow::malloc_error()
     msg.exec();
 }
 
+void MainWindow::hardware_connect_failed()
+{
+    _session.stop_capture();
+    QMessageBox msg(this);
+    msg.setText(tr("Hardware Connect Failed"));
+    msg.setInformativeText(tr("Please check hardware connection!"));
+    msg.setStandardButtons(QMessageBox::Ok);
+    msg.setIcon(QMessageBox::Warning);
+    msg.exec();
+}
+
 void MainWindow::capture_state_changed(int state)
 {
     _file_bar->enable_toggle(state != SigSession::Running);
@@ -492,7 +503,7 @@ void MainWindow::capture_state_changed(int state)
                     if (gvar != NULL) {
                         uint64_t actual_samples = g_variant_get_uint64(gvar);
                         g_variant_unref(gvar);
-                        if (actual_samples != _session.get_device()->get_sample_limit()) {
+                        if (actual_samples != _session.cur_samplelimits()) {
                             show_session_error(tr("RLE Mode Warning"),
                                                tr("Hardware buffer is full!\nActually received samples is less than setted sample depth!"));
                         }
diff --git a/DSView/pv/mainwindow.h b/DSView/pv/mainwindow.h
index 0ae691385814e2a599bf47badbea8d484b0f4cdb..36abdf6f10f6f756047ebf1e0901f94f04dbb5b1 100644
--- a/DSView/pv/mainwindow.h
+++ b/DSView/pv/mainwindow.h
@@ -131,6 +131,11 @@ private slots:
     void device_attach();
     void device_detach();
 
+    /*
+     * errors
+     */
+    void hardware_connect_failed();
+
 private:
 	DeviceManager &_device_manager;
 
diff --git a/DSView/pv/sigsession.cpp b/DSView/pv/sigsession.cpp
index e0b443dff9a626f6f9b01593052ea87ce5978299..a3851d2719427470ce1071c5db1ec7e41f814786 100644
--- a/DSView/pv/sigsession.cpp
+++ b/DSView/pv/sigsession.cpp
@@ -151,6 +151,8 @@ void SigSession::set_device(boost::shared_ptr<device::DevInst> dev_inst) throw(Q
     if (_dev_inst) {
         try {
             _dev_inst->use(this);
+            _cur_samplerate = _dev_inst->get_sample_rate();
+            _cur_samplelimits = _dev_inst->get_sample_limit();
         } catch(const QString e) {
             throw(e);
             return;
@@ -423,6 +425,24 @@ SigSession::capture_state SigSession::get_capture_state() const
 	return _capture_state;
 }
 
+uint64_t SigSession::cur_samplelimits() const
+{
+    return _cur_samplelimits;
+}
+
+uint64_t SigSession::cur_samplerate() const
+{
+    return _cur_samplerate;
+}
+
+double SigSession::cur_sampletime() const
+{
+    if (_cur_samplerate == 0)
+        return 0;
+    else
+        return  _cur_samplelimits * 1.0 / _cur_samplerate;
+}
+
 void SigSession::start_capture(bool instant,
     boost::function<void (const QString)> error_handler)
 {
@@ -582,36 +602,60 @@ void SigSession::sample_thread_proc(boost::shared_ptr<device::DevInst> dev_inst,
     assert(!_cur_analog_snapshot);
 }
 
-void SigSession::read_sample_rate(const sr_dev_inst *const sdi)
+void SigSession::update_data_header(const sr_dev_inst *const sdi)
 {
     GVariant *gvar;
-    uint64_t sample_rate = 0;
+    int ret;
 
     // Read out the sample rate
     if(sdi->driver)
     {
-        const int ret = sr_config_get(sdi->driver, sdi, NULL, NULL, SR_CONF_SAMPLERATE, &gvar);
+        ret = sr_config_get(sdi->driver, sdi, NULL, NULL, SR_CONF_SAMPLERATE, &gvar);
+        if (ret != SR_OK) {
+            hardware_connect_failed();
+            return;
+        }
+
+        _cur_samplerate = g_variant_get_uint64(gvar);
+        g_variant_unref(gvar);
+
+        ret = sr_config_get(sdi->driver, sdi, NULL, NULL, SR_CONF_LIMIT_SAMPLES, &gvar);
         if (ret != SR_OK) {
-            qDebug("Failed to get samplerate\n");
+            hardware_connect_failed();
             return;
         }
 
-        sample_rate = g_variant_get_uint64(gvar);
+        _cur_samplelimits = g_variant_get_uint64(gvar);
         g_variant_unref(gvar);
     }
 
-    // Set the sample rate of all data
-    const set< boost::shared_ptr<data::SignalData> > data_set = get_data();
+    // Set the sample rate of all SignalData
+    // Logic/Analog/Dso
+    set< boost::shared_ptr<data::SignalData> > data_set;
+    BOOST_FOREACH(const boost::shared_ptr<view::Signal> sig, _signals) {
+        assert(sig);
+        data_set.insert(sig->data());
+    }
     BOOST_FOREACH(boost::shared_ptr<data::SignalData> data, data_set) {
         assert(data);
-        data->set_samplerate(sample_rate);
+        data->set_samplerate(_cur_samplerate);
+    }
+#ifdef ENABLE_DECODE
+    // DecoderStack
+    BOOST_FOREACH(const boost::shared_ptr<view::DecodeTrace> d, _decode_traces)
+    {
+        assert(d);
+        d->decoder()->set_samplerate(_cur_samplerate);
     }
+#endif
+    // MathStack
     BOOST_FOREACH(const boost::shared_ptr<view::MathTrace> m, _math_traces)
     {
         assert(m);
-        m->get_math_stack()->set_samplerate(sample_rate);
+        m->get_math_stack()->set_samplerate(_cur_samplerate);
     }
-    _group_data->set_samplerate(sample_rate);
+    // Group
+    _group_data->set_samplerate(_cur_samplerate);
 }
 
 void SigSession::feed_in_header(const sr_dev_inst *sdi)
@@ -623,7 +667,7 @@ void SigSession::feed_in_header(const sr_dev_inst *sdi)
         i++)
         (*i)->decoder()->stop_decode();
 #endif
-    read_sample_rate(sdi);
+    update_data_header(sdi);
     //receive_data(0);
 }
 
@@ -640,8 +684,9 @@ void SigSession::add_group()
 
     if (probe_index_list.size() > 1) {
         //_group_data.reset(new data::Group(_last_sample_rate));
-        if (_group_data->get_snapshots().empty())
-            _group_data->set_samplerate(_dev_inst->get_sample_rate());
+//        if (_group_data->get_snapshots().empty())
+//            _group_data->set_samplerate(_dev_inst->get_sample_rate());
+        _group_data->set_samplerate(_cur_samplerate);
         const boost::shared_ptr<view::GroupSignal> signal(
                     new view::GroupSignal("New Group",
                                           _group_data, probe_index_list, _group_cnt));
@@ -811,6 +856,7 @@ void SigSession::reload()
     if (_capture_state == Running)
         stop_capture();
 
+    //refresh(0);
     vector< boost::shared_ptr<view::Signal> > sigs;
     boost::shared_ptr<view::Signal> signal;
 
@@ -869,10 +915,23 @@ void SigSession::refresh(int holdtime)
     if (_logic_data) {
         _logic_data->clear();
         _cur_logic_snapshot.reset();
+#ifdef ENABLE_DECODE
+        BOOST_FOREACH(const boost::shared_ptr<view::DecodeTrace> d, _decode_traces)
+        {
+            assert(d);
+            d->decoder()->clear();
+        }
+#endif
     }
     if (_dso_data) {
         _dso_data->clear();
         _cur_dso_snapshot.reset();
+        // MathStack
+        BOOST_FOREACH(const boost::shared_ptr<view::MathTrace> m, _math_traces)
+        {
+            assert(m);
+            m->get_math_stack()->clear();
+        }
     }
     if (_analog_data) {
         _analog_data->clear();
diff --git a/DSView/pv/sigsession.h b/DSView/pv/sigsession.h
index 9005ab7fd4044bc75e5debe024ad4c3e1e4a3f25..55e9ec53a60cd4126b50d5e87378f9e2e62408e3 100644
--- a/DSView/pv/sigsession.h
+++ b/DSView/pv/sigsession.h
@@ -128,6 +128,10 @@ public:
 
 	capture_state get_capture_state() const;
 
+    uint64_t cur_samplerate() const;
+    uint64_t cur_samplelimits() const;
+    double cur_sampletime() const;
+
     void start_capture(bool instant,
 		boost::function<void (const QString)> error_handler);
 
@@ -187,7 +191,7 @@ public:
 private:
 	void set_capture_state(capture_state state);
 
-    void read_sample_rate(const sr_dev_inst *const sdi);
+    void update_data_header(const sr_dev_inst *const sdi);
 
 private:
     /**
@@ -237,6 +241,8 @@ private:
 	mutable boost::mutex _sampling_mutex;
 	capture_state _capture_state;
     bool _instant;
+    uint64_t _cur_samplerate;
+    uint64_t _cur_samplelimits;
 
 	mutable boost::mutex _signals_mutex;
 	std::vector< boost::shared_ptr<view::Signal> > _signals;
@@ -306,6 +312,8 @@ signals:
 
     void show_region(uint64_t start, uint64_t end);
 
+    void hardware_connect_failed();
+
 public slots:
     void reload();
     void refresh(int holdtime);
diff --git a/DSView/pv/storesession.cpp b/DSView/pv/storesession.cpp
index 6d2ea359a2a6818d47ec2e0b1b845d63bf867228..14fe7cd1c1cbf24e699d507c688cfe380c4e9344 100644
--- a/DSView/pv/storesession.cpp
+++ b/DSView/pv/storesession.cpp
@@ -25,6 +25,8 @@
 #include <pv/data/logicsnapshot.h>
 #include <pv/view/signal.h>
 
+#include <boost/foreach.hpp>
+
 using boost::dynamic_pointer_cast;
 using boost::mutex;
 using boost::shared_ptr;
@@ -70,9 +72,12 @@ const QString& StoreSession::error() const
 
 bool StoreSession::start()
 {
-	set< shared_ptr<data::SignalData> > data_set =
-		_session.get_data();
     const vector< shared_ptr<view::Signal> > sigs(_session.get_signals());
+    set< boost::shared_ptr<data::SignalData> > data_set;
+    BOOST_FOREACH(const boost::shared_ptr<view::Signal> sig, sigs) {
+        assert(sig);
+        data_set.insert(sig->data());
+    }
 
 	// Check we have logic data
 	if (data_set.empty() || sigs.empty()) {
diff --git a/DSView/pv/toolbars/samplingbar.cpp b/DSView/pv/toolbars/samplingbar.cpp
index 466e382d5f72ede0bcda2007ed395f5a62a2b901..05616ca3aca561eff973932de7d9184d10ff2ed8 100644
--- a/DSView/pv/toolbars/samplingbar.cpp
+++ b/DSView/pv/toolbars/samplingbar.cpp
@@ -126,17 +126,6 @@ SamplingBar::SamplingBar(SigSession &session, QWidget *parent) :
     _run_stop_button.setIcon(_icon_start);
     _instant_button.setIcon(_icon_instant);
 
-//	for (size_t i = 0; i < countof(RecordLengths); i++)
-//	{
-//		const uint64_t &l = RecordLengths[i];
-//		char *const text = ds_si_string_u64(l, " samples");
-//		_sample_count.addItem(QString(text),
-//			qVariantFromValue(l));
-//		g_free(text);
-
-//		if (l == DefaultRecordLength)
-//			_sample_count.setCurrentIndex(i);
-//	}
     _sample_count.setSizeAdjustPolicy(QComboBox::AdjustToContents);
 	set_sampling(false);
     connect(&_sample_count, SIGNAL(currentIndexChanged(int)),
@@ -191,7 +180,6 @@ void SamplingBar::set_device_list(
 
     update_sample_rate_selector();
     update_sample_count_selector();
-    update_scale();
 
     _updating_device_selector = false;
 }
@@ -454,8 +442,7 @@ void SamplingBar::update_sample_rate_selector_value()
             break;
         }
     }
-    if (samplerate != _sample_rate.itemData(_sample_rate.currentIndex()).value<uint64_t>())
-        update_scale();
+
     _updating_sample_rate = false;
 }
 
@@ -486,7 +473,6 @@ void SamplingBar::commit_sample_rate()
         get_selected_device()->set_config(NULL, NULL,
                                           SR_CONF_SAMPLERATE,
                                           g_variant_new_uint64(sample_rate));
-        update_scale();
     }
 
     _updating_sample_rate = false;
@@ -512,7 +498,6 @@ void SamplingBar::on_samplecount_sel(int index)
                              g_variant_new_uint64(sample_count));
 
         sample_count_changed();
-        //update_scale();
     }
 }
 
@@ -535,8 +520,6 @@ void SamplingBar::on_samplerate_sel(int index)
             get_selected_device()->set_config(NULL, NULL,
                                               SR_CONF_SAMPLERATE,
                                               g_variant_new_uint64(sample_rate));
-
-            //update_scale();
     }
 }
 
@@ -628,7 +611,6 @@ void SamplingBar::update_sample_count_selector_value()
 
     if (samplecount != _sample_count.itemData(_sample_count.currentIndex()).value<uint64_t>()) {
         sample_count_changed();
-        update_scale();
     }
     _updating_sample_count = false;
 }
@@ -661,7 +643,6 @@ void SamplingBar::commit_sample_count()
         get_selected_device()->set_config(NULL, NULL,
                                           SR_CONF_LIMIT_SAMPLES,
                                           g_variant_new_uint64(sample_count));
-        update_scale();
     }
 
     _updating_sample_count = false;
diff --git a/DSView/pv/toolbars/samplingbar.h b/DSView/pv/toolbars/samplingbar.h
index ad48c179e0bd90ce52eae9fe0ddbd208efd313e3..377246e41845988615319b129e6b9b6c9a338203 100644
--- a/DSView/pv/toolbars/samplingbar.h
+++ b/DSView/pv/toolbars/samplingbar.h
@@ -95,7 +95,6 @@ signals:
     void instant_stop();
     void device_selected();
     void device_updated();
-    void update_scale();
     void sample_count_changed();
 
 private:
diff --git a/DSView/pv/view/cursor.cpp b/DSView/pv/view/cursor.cpp
index baa00faf4bb8db69d61a078cb915979b5f1e45a9..9f108e9acac27a8c584883421d7ba2f5b2cbe5d2 100644
--- a/DSView/pv/view/cursor.cpp
+++ b/DSView/pv/view/cursor.cpp
@@ -60,7 +60,7 @@ Cursor::Cursor(View &view, QColor color, uint64_t index) :
 
 QRectF Cursor::get_label_rect(const QRect &rect) const
 {
-    const double samples_per_pixel = _view.session().get_device()->get_sample_rate() * _view.scale();
+    const double samples_per_pixel = _view.session().cur_samplerate() * _view.scale();
     const double x = _index/samples_per_pixel - (_view.offset() / _view.scale());
 
 	const QSizeF label_size(
@@ -116,7 +116,7 @@ void Cursor::paint_label(QPainter &p, const QRect &rect,
     p.drawLine(close.left() + 2, close.bottom() - 2, close.right() - 2, close.top() + 2);
 
 	p.drawText(r, Qt::AlignCenter | Qt::AlignVCenter,
-        Ruler::format_real_time(_index, _view.session().get_device()->get_sample_rate()));
+        Ruler::format_real_time(_index, _view.session().cur_samplerate()));
 
     const QRectF arrowRect = QRectF(r.bottomLeft().x(), r.bottomLeft().y(), r.width(), ArrowSize);
     p.drawText(arrowRect, Qt::AlignCenter | Qt::AlignVCenter, QString::number(index));
@@ -143,7 +143,7 @@ void Cursor::paint_fix_label(QPainter &p, const QRect &rect,
 
     p.setPen(Qt::white);
     p.drawText(r, Qt::AlignCenter | Qt::AlignVCenter,
-        Ruler::format_real_time(_index, _view.session().get_device()->get_sample_rate()));
+        Ruler::format_real_time(_index, _view.session().cur_samplerate()));
 
     const QRectF arrowRect = QRectF(r.bottomLeft().x(), r.bottomLeft().y(), r.width(), ArrowSize);
     p.drawText(arrowRect, Qt::AlignCenter | Qt::AlignVCenter, label);
@@ -153,7 +153,7 @@ void Cursor::compute_text_size(QPainter &p, unsigned int prefix)
 {
     (void)prefix;
     _text_size = p.boundingRect(QRectF(), 0,
-        Ruler::format_real_time(_index, _view.session().get_device()->get_sample_rate())).size();
+        Ruler::format_real_time(_index, _view.session().cur_samplerate())).size();
 }
 
 } // namespace view
diff --git a/DSView/pv/view/decodetrace.cpp b/DSView/pv/view/decodetrace.cpp
index b7117769b99575d24733b95fdc28d41a0d72993e..8d9ea2d707f5b4e02dcadb19ba139913848e48d1 100644
--- a/DSView/pv/view/decodetrace.cpp
+++ b/DSView/pv/view/decodetrace.cpp
@@ -125,6 +125,7 @@ DecodeTrace::DecodeTrace(pv::SigSession &session,
     _end_index(0),
     _start_count(0),
     _end_count(0),
+    _progress(0),
     _popup_form(NULL),
     _popup()
 {
@@ -175,7 +176,7 @@ void DecodeTrace::paint_back(QPainter &p, int left, int right)
     p.drawLine(left, sigY, right, sigY);
 
     // --draw decode region control
-    const double samples_per_pixel = _session.get_device()->get_sample_rate() * _view->scale();
+    const double samples_per_pixel = _session.cur_samplerate() * _view->scale();
     const double startX = _decode_start/samples_per_pixel - (_view->offset() / _view->scale());
     const double endX = _decode_end/samples_per_pixel - (_view->offset() / _view->scale());
     const double regionY = get_y() - _totalHeight*0.5 - ControlRectWidth;
@@ -665,7 +666,7 @@ bool DecodeTrace::draw_unresolved_period(QPainter &p, int h, int left,
     font.setPointSize(_view->get_signalHeight()*2/3);
     font.setBold(true);
     p.setFont(font);
-    p.drawText(no_decode_rect, Qt::AlignCenter | Qt::AlignVCenter, QString::number(progress100)+"%");
+    p.drawText(no_decode_rect, Qt::AlignCenter | Qt::AlignVCenter, QString::number(_progress)+"%");
 
     return true;
 }
@@ -829,10 +830,24 @@ void DecodeTrace::commit_probes()
 
 void DecodeTrace::on_new_decode_data()
 {
+    const uint64_t need_sample_count = _decode_end - _decode_start + 1;
+    if (need_sample_count == 0) {
+        _progress = 100;
+    } else {
+        const uint64_t samples_decoded = _decoder_stack->samples_decoded();
+        _progress = ceil(samples_decoded * 100.0 / need_sample_count);
+    }
+    decoded_progress(_progress);
+
     if (_view && _view->session().get_capture_state() == SigSession::Stopped)
         _view->data_updated();
 }
 
+int DecodeTrace::get_progress() const
+{
+    return _progress;
+}
+
 void DecodeTrace::on_decode_done()
 {
     if (_view) {
@@ -937,7 +952,7 @@ QRectF DecodeTrace::get_rect(DecodeSetRegions type, int y, int right)
 void DecodeTrace::on_region_set(int index)
 {
     (void)index;
-    const uint64_t last_samples = _session.get_device()->get_sample_limit() - 1;
+    const uint64_t last_samples = _session.cur_samplelimits() - 1;
     const int index1 = _start_comboBox->currentIndex();
     const int index2 = _end_comboBox->currentIndex();
     uint64_t decode_start, decode_end;
@@ -974,7 +989,7 @@ void DecodeTrace::on_region_set(int index)
 
 void DecodeTrace::frame_ended()
 {
-    const uint64_t last_samples = _session.get_device()->get_sample_limit() - 1;
+    const uint64_t last_samples = _session.cur_samplelimits() - 1;
     if (_decode_start > last_samples) {
         _decode_start = 0;
         _start_index = 0;
diff --git a/DSView/pv/view/decodetrace.h b/DSView/pv/view/decodetrace.h
index 553da4d9eb5912402a298f680cb3a781aebb5bef..41cc94fef8b4086f5e5f0f127e15f515881d0d92 100644
--- a/DSView/pv/view/decodetrace.h
+++ b/DSView/pv/view/decodetrace.h
@@ -141,6 +141,8 @@ public:
      **/
     void frame_ended();
 
+    int get_progress() const;
+
 protected:
     void paint_type_options(QPainter &p, int right, const QPoint pt);
 
@@ -187,6 +189,9 @@ private:
 
 	void commit_probes();
 
+signals:
+    void decoded_progress(int progress);
+
 private slots:
 	void on_new_decode_data();
 
@@ -209,6 +214,7 @@ private:
     int _start_index, _end_index;
     int _start_count, _end_count;
     QComboBox *_start_comboBox, *_end_comboBox;
+    int _progress;
 
 	std::list< boost::shared_ptr<pv::prop::binding::DecoderOptions> >
 		_bindings;
diff --git a/DSView/pv/view/dsosignal.cpp b/DSView/pv/view/dsosignal.cpp
index 558ce007e032ae70c56acd359585af20ca793762..f2a4b66b7ea6d185cef6cd779c6a97a273825deb 100644
--- a/DSView/pv/view/dsosignal.cpp
+++ b/DSView/pv/view/dsosignal.cpp
@@ -305,7 +305,7 @@ bool DsoSignal::go_hDialPre(bool setted)
 {
     int ch_num = _view->session().get_ch_num(SR_CHANNEL_DSO);
     if (ch_num != 0 && !_hDial->isMin()) {
-        uint64_t sample_rate = _view->session().get_device()->get_sample_rate();
+        uint64_t sample_rate = _view->session().cur_samplerate();
         const uint64_t min_div = std::pow(10.0, 9.0) / sample_rate;
         if (_view->session().get_capture_state() != SigSession::Running &&
             !_data->get_snapshots().empty()) {
@@ -764,8 +764,8 @@ void DsoSignal::paint_back(QPainter &p, int left, int right)
 
     p.setPen(Trace::dsLightBlue);
     p.drawLine(left, UpMargin/2, left + width, UpMargin/2);
-    const uint64_t sample_len = _dev_inst->get_sample_limit();
-    const double samplerate = _dev_inst->get_sample_rate();
+    const uint64_t sample_len = _view->session().cur_samplelimits();
+    const double samplerate = _view->session().cur_samplerate();
     const double samples_per_pixel = samplerate * _view->scale();
     const double shown_rate = min(samples_per_pixel * width * 1.0 / sample_len, 1.0);
     const double start_time = _data->get_start_time();
@@ -843,7 +843,7 @@ void DsoSignal::paint_mid(QPainter &p, int left, int right)
 
         const double pixels_offset = offset / scale;
         //const double samplerate = _data->samplerate();
-        const double samplerate = _dev_inst->get_sample_rate();
+        const double samplerate = _view->session().cur_samplerate();
         const double start_time = _data->get_start_time();
         const int64_t last_sample = max((int64_t)(snapshot->get_sample_count() - 1), (int64_t)0);
         const double samples_per_pixel = samplerate * scale;
@@ -1280,7 +1280,7 @@ void DsoSignal::paint_measure(QPainter &p)
         double value_p2p = value_max - value_min;
         _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();
+        uint64_t sample_rate = _view->session().cur_samplerate();
         _period = _period * 200.0 / (channel_count * sample_rate * 1.0 / SR_MHZ(1));
         _ms_string[DSO_MS_VMAX] = "Vmax: " + (abs(value_max) > 1000 ? QString::number(value_max/1000.0, 'f', 2) + "V" : QString::number(value_max, 'f', 2) + "mV");
         _ms_string[DSO_MS_VMIN] = "Vmin: " + (abs(value_min) > 1000 ? QString::number(value_min/1000.0, 'f', 2) + "V" : QString::number(value_min, 'f', 2) + "mV");
@@ -1455,7 +1455,7 @@ bool DsoSignal::measure(const QPointF &p)
     assert(scale > 0);
     const double offset = _view->offset();
     const double pixels_offset = offset / scale;
-    const double samplerate = _dev_inst->get_sample_rate();
+    const double samplerate = _view->session().cur_samplerate();
     const double samples_per_pixel = samplerate * scale;
 
     _hover_index = floor((p.x() + pixels_offset) * samples_per_pixel+0.5);
diff --git a/DSView/pv/view/mathtrace.cpp b/DSView/pv/view/mathtrace.cpp
index d8bb16c254a1fae9926e1b53eb376df99faeef8c..459c15a99b6fe65d487660473b922a4452035133 100644
--- a/DSView/pv/view/mathtrace.cpp
+++ b/DSView/pv/view/mathtrace.cpp
@@ -359,8 +359,8 @@ void MathTrace::paint_fore(QPainter &p, int left, int right)
     double blank_right = width;
 
     // horizontal ruler
-    const double NyFreq = _session.get_device()->get_sample_rate() / (2.0 * _math_stack->get_sample_interval());
-    const double deltaFreq = _session.get_device()->get_sample_rate() * 1.0 /
+    const double NyFreq = _session.cur_samplerate() / (2.0 * _math_stack->get_sample_interval());
+    const double deltaFreq = _session.cur_samplerate() * 1.0 /
                             (_math_stack->get_sample_num() * _math_stack->get_sample_interval());
     const double FreqRange = NyFreq * _scale;
     const double FreqOffset = NyFreq * _offset;
diff --git a/DSView/pv/view/ruler.cpp b/DSView/pv/view/ruler.cpp
index 1bbfb340007e6c62b0079956f16e8b2e81f57baf..61963fed96c0c73bf41a2d58513f34ca85785700 100644
--- a/DSView/pv/view/ruler.cpp
+++ b/DSView/pv/view/ruler.cpp
@@ -205,7 +205,7 @@ void Ruler::mouseMoveEvent(QMouseEvent *e)
 
     if (_grabbed_marker) {
         _grabbed_marker->set_index((_view.offset() +
-            _view.hover_point().x() * _view.scale()) * _view.session().get_device()->get_sample_rate());
+            _view.hover_point().x() * _view.scale()) * _view.session().cur_samplerate());
     }
 
     update();
@@ -264,7 +264,7 @@ void Ruler::mouseReleaseEvent(QMouseEvent *event)
                     _cursor_sel_visible = true;
                 } else {
                     int overCursor;
-                    uint64_t index = (_view.offset() + (_cursor_sel_x + 0.5) * _view.scale()) * _view.session().get_device()->get_sample_rate();
+                    uint64_t index = (_view.offset() + (_cursor_sel_x + 0.5) * _view.scale()) * _view.session().cur_samplerate();
                     overCursor = in_cursor_sel_rect(event->pos());
                     if (overCursor == 0) {
                         _view.add_cursor(CursorColor[_view.get_cursorList().size() % 8], index);
@@ -426,7 +426,7 @@ void Ruler::draw_logic_tick_mark(QPainter &p)
     const double MinValueSpacing = 16.0;
     const int ValueMargin = 5;
 
-    const double abs_min_period = 10.0 / _view.session().get_device()->get_sample_rate();
+    const double abs_min_period = 10.0 / _view.session().cur_samplerate();
 
     double min_width = SpacingIncrement;
     double typical_width;
diff --git a/DSView/pv/view/timemarker.cpp b/DSView/pv/view/timemarker.cpp
index 34a0e7d772a690fa66bcb0c5eb3d4f3114b7713f..bf4f9c87a503fc54e26026156e684d7442997307 100644
--- a/DSView/pv/view/timemarker.cpp
+++ b/DSView/pv/view/timemarker.cpp
@@ -70,7 +70,7 @@ void TimeMarker::set_index(uint64_t index)
 
 void TimeMarker::paint(QPainter &p, const QRect &rect, const bool highlight)
 {
-    const double samples_per_pixel = _view.session().get_device()->get_sample_rate() * _view.scale();
+    const double samples_per_pixel = _view.session().cur_samplerate() * _view.scale();
     const double x = _index/samples_per_pixel - (_view.offset() / _view.scale());
     p.setPen((_grabbed | highlight) ? QPen(_colour.lighter(), 2, Qt::DashLine) : QPen(_colour, 1, Qt::DashLine));
     p.drawLine(QPointF(x, rect.top()), QPointF(x, rect.bottom()));
diff --git a/DSView/pv/view/view.cpp b/DSView/pv/view/view.cpp
index 43cf5868f75f1a9f8bbd28589b073303ce97e86d..d97d4759bb0e6d4210d3b6a3c48a20b0794c381b 100644
--- a/DSView/pv/view/view.cpp
+++ b/DSView/pv/view/view.cpp
@@ -418,14 +418,16 @@ void View::show_search_cursor(bool show)
 
 void View::set_trig_pos(quint64 trig_pos)
 {
-    const double time = trig_pos * 1.0 / _session.get_device()->get_sample_rate();
+    const double time = trig_pos * 1.0 / _session.cur_samplerate();
     _trig_pos = trig_pos;
     _trig_cursor->set_index(trig_pos);
-    _show_trig_cursor = true;
-    set_scale_offset(_scale,  time - _scale * get_view_width() / 2);
+    if (ds_trigger_get_en()) {
+        _show_trig_cursor = true;
+        set_scale_offset(_scale,  time - _scale * get_view_width() / 2);
+    }
 
     _trigger_time = QDateTime::currentDateTime();
-    const int64_t secs = time - _session.get_device()->get_sample_time();
+    const int64_t secs = time - _session.cur_sampletime();
     _trigger_time = _trigger_time.addSecs(secs);
 
     _ruler->update();
@@ -436,7 +438,7 @@ void View::set_search_pos(uint64_t search_pos)
 {
     //assert(search_pos >= 0);
 
-    const double time = search_pos * 1.0 / _session.get_device()->get_sample_rate();
+    const double time = search_pos * 1.0 / _session.cur_samplerate();
     _search_pos = search_pos;
     _search_cursor->set_index(search_pos);
     set_scale_offset(_scale,  time - _scale * get_view_width() / 2);
@@ -492,7 +494,7 @@ void View::get_scroll_layout(double &length, double &offset) const
     if (data_set.empty())
 		return;
 
-    length = _session.get_device()->get_sample_time() / _scale;
+    length = _session.cur_sampletime() / _scale;
 	offset = _offset / _scale;
 }
 
@@ -527,23 +529,25 @@ void View::update_scroll()
     verticalScrollBar()->setRange(0,0);
 }
 
-void View::update_scale()
+void View::update_scale_offset()
 {
-    const uint64_t sample_rate = _session.get_device()->get_sample_rate();
+    const uint64_t sample_rate = _session.cur_samplerate();
     assert(sample_rate > 0);
 
     if (_session.get_device()->dev_inst()->mode != DSO) {
-        _scale = (1.0 / sample_rate) / WellPixelsPerSample;
-        _maxscale = _session.get_device()->get_sample_time() / (get_view_width() * MaxViewRate);
+        //_scale = (1.0 / sample_rate) / WellPixelsPerSample;
+        _maxscale = _session.cur_sampletime() / (get_view_width() * MaxViewRate);
     } else {
         _scale = _session.get_device()->get_time_base() * 10.0 / get_view_width() * std::pow(10.0, -9.0);
         _maxscale = 1e9;
     }
-
     _minscale = (1.0 / sample_rate) / MaxPixelsPerSample;
-    //_offset = 0;
+
+    _scale = max(min(_scale, _maxscale), _minscale);
+    _offset = max(min(_offset, get_max_offset()), get_min_offset());
+
     _preScale = _scale;
-    //_preOffset = _offset;
+    _preOffset = _offset;
 
     _trig_cursor->set_index(_trig_pos);
 
@@ -722,7 +726,7 @@ void View::resizeEvent(QResizeEvent*)
         _scale = _session.get_device()->get_time_base() * std::pow(10.0, -9.0) * DS_CONF_DSO_HDIVS / get_view_width();
 
     if (_session.get_device()->dev_inst()->mode != DSO)
-        _maxscale = _session.get_device()->get_sample_time() / (get_view_width() * MaxViewRate);
+        _maxscale = _session.cur_sampletime() / (get_view_width() * MaxViewRate);
     else
         _maxscale = 1e9;
 
@@ -860,7 +864,7 @@ void View::set_cursor_middle(int index)
     list<Cursor*>::iterator i = _cursorList.begin();
     while (index-- != 0)
             i++;
-    set_scale_offset(_scale, (*i)->index() * 1.0 / _session.get_device()->get_sample_rate() - _scale * get_view_width() / 2);
+    set_scale_offset(_scale, (*i)->index() * 1.0 / _session.cur_samplerate() - _scale * get_view_width() / 2);
 }
 
 void View::on_measure_updated()
@@ -879,7 +883,7 @@ QString View::get_measure(QString option)
 
 QString View::get_cm_time(int index)
 {
-    return _ruler->format_real_time(get_cursor_samples(index), _session.get_device()->get_sample_rate());
+    return _ruler->format_real_time(get_cursor_samples(index), _session.cur_samplerate());
 }
 
 QString View::get_cm_delta(int index1, int index2)
@@ -890,7 +894,7 @@ QString View::get_cm_delta(int index1, int index2)
     uint64_t samples1 = get_cursor_samples(index1);
     uint64_t samples2 = get_cursor_samples(index2);
     uint64_t delta_sample = (samples1 > samples2) ? samples1 - samples2 : samples2 - samples1;
-    return _ruler->format_real_time(delta_sample, _session.get_device()->get_sample_rate());
+    return _ruler->format_real_time(delta_sample, _session.cur_samplerate());
 }
 
 uint64_t View::get_cursor_samples(int index)
@@ -924,6 +928,7 @@ void View::on_state_changed(bool stop)
         BOOST_FOREACH(Viewport *viewport, _viewport_list)
             viewport->stop_trigger_timer();
     }
+    update_scale_offset();
 }
 
 int View::get_view_width()
@@ -963,7 +968,7 @@ double View::get_min_offset()
 
 double View::get_max_offset()
 {
-    return _session.get_device()->get_sample_time()
+    return _session.cur_sampletime()
             - _scale * (get_view_width() * MaxViewRate);
 }
 
@@ -975,9 +980,9 @@ QString View::trigger_time()
 void View::show_region(uint64_t start, uint64_t end)
 {
     assert(start <= end);
-    const double ideal_scale = (end-start) * 2.0 / _session.get_device()->get_sample_rate() / get_view_width();
+    const double ideal_scale = (end-start) * 2.0 / _session.cur_samplerate() / get_view_width();
     const double new_scale = max(min(ideal_scale, _maxscale), _minscale);
-    const double new_off = (start + end)  * 0.5 / _session.get_device()->get_sample_rate() - new_scale * get_view_width() / 2;
+    const double new_off = (start + end)  * 0.5 / _session.cur_samplerate() - new_scale * get_view_width() / 2;
     set_scale_offset(new_scale, new_off);
 }
 
diff --git a/DSView/pv/view/view.h b/DSView/pv/view/view.h
index a90f8fb4695cdd320a9dc45cb222d659f6a58302..028eee48fbd340f84967914aad411a51ebfd3428 100644
--- a/DSView/pv/view/view.h
+++ b/DSView/pv/view/view.h
@@ -229,7 +229,7 @@ public slots:
     void set_measure_en(int enable);
     void signals_changed();
     void data_updated();
-    void update_scale();
+    void update_scale_offset();
     void show_region(uint64_t start, uint64_t end);
 
 private slots:
diff --git a/DSView/pv/view/viewport.cpp b/DSView/pv/view/viewport.cpp
index 4ecbc2946941bf54eb0030ffb32ada66ce5cd1a6..99263a850b5ccdde50f16002dde568b0de842be6 100644
--- a/DSView/pv/view/viewport.cpp
+++ b/DSView/pv/view/viewport.cpp
@@ -206,7 +206,7 @@ void Viewport::paintSignals(QPainter &p)
     if (_view.cursors_shown() && _type == TIME_VIEW) {
         list<Cursor*>::iterator i = _view.get_cursorList().begin();
         double cursorX;
-        const double samples_per_pixel = _view.session().get_device()->get_sample_rate() * _view.scale();
+        const double samples_per_pixel = _view.session().cur_samplerate() * _view.scale();
         while (i != _view.get_cursorList().end()) {
             cursorX = (*i)->index()/samples_per_pixel - (_view.offset() / _view.scale());
             if (rect().contains(_view.hover_point().x(), _view.hover_point().y()) &&
@@ -242,7 +242,7 @@ void Viewport::paintProgress(QPainter &p)
 {
     using pv::view::Signal;
 
-    const uint64_t _total_sample_len = _view.session().get_device()->get_sample_limit();
+    const uint64_t _total_sample_len = _view.session().cur_samplelimits();
     double progress = -(_total_receive_len * 1.0 / _total_sample_len * 360 * 16);
     int captured_progress = 0;
 
@@ -407,7 +407,7 @@ void Viewport::mousePressEvent(QMouseEvent *event)
             _action_type = LOGIC_ZOOM;
         } else if (_view.session().get_device()->dev_inst()->mode == DSO) {
             if (_hover_hit) {
-                uint64_t index = (_view.offset() + (event->pos().x() + 0.5) * _view.scale()) * _view.session().get_device()->get_sample_rate();
+                uint64_t index = (_view.offset() + (event->pos().x() + 0.5) * _view.scale()) * _view.session().cur_samplerate();
                 _view.add_cursor(view::Ruler::CursorColor[_view.get_cursorList().size() % 8], index);
                 _view.show_cursors(true);
             }
@@ -450,7 +450,7 @@ void Viewport::mouseMoveEvent(QMouseEvent *event)
             }
 
             if (_action_type == CURS_MOVE) {
-                uint64_t sample_rate = _view.session().get_device()->get_sample_rate();
+                uint64_t sample_rate = _view.session().cur_samplerate();
                 TimeMarker* grabbed_marker = _view.get_ruler()->get_grabbed_cursor();
                 if (_view.cursors_shown() && grabbed_marker) {
                     const double cur_time = _view.offset() + _view.hover_point().x() * _view.scale();
@@ -485,7 +485,7 @@ void Viewport::mouseReleaseEvent(QMouseEvent *event)
             if (_action_type == NO_ACTION && _view.cursors_shown()) {
                 list<Cursor*>::iterator i = _view.get_cursorList().begin();
                 double cursorX;
-                const double samples_per_pixel = _view.session().get_device()->get_sample_rate() * _view.scale();
+                const double samples_per_pixel = _view.session().cur_samplerate() * _view.scale();
                 while (i != _view.get_cursorList().end()) {
                     cursorX = (*i)->index()/samples_per_pixel - (_view.offset() / _view.scale());
                     if ((*i)->grabbed()) {
@@ -526,7 +526,7 @@ void Viewport::mouseReleaseEvent(QMouseEvent *event)
                             assert(s);
                             if (abs(event->pos().y() - s->get_y()) < _view.get_signalHeight()) {
                                 _action_type = LOGIC_EDGE;
-                                _edge_start = (_view.offset() + (event->pos().x() + 0.5) * _view.scale()) * _view.session().get_device()->get_sample_rate();
+                                _edge_start = (_view.offset() + (event->pos().x() + 0.5) * _view.scale()) * _view.session().cur_samplerate();
                                 break;
                             }
                         }
@@ -581,7 +581,7 @@ void Viewport::mouseReleaseEvent(QMouseEvent *event)
             }
         } else if (_action_type == DSO_XM_STEP1) {
             if (event->button() == Qt::LeftButton) {
-                const uint64_t sample_rate = _view.session().get_device()->get_sample_rate();
+                const uint64_t sample_rate = _view.session().cur_samplerate();
                 const double scale = _view.scale();
                 const double samples_per_pixel =  sample_rate * scale;
 
@@ -602,7 +602,7 @@ void Viewport::mouseReleaseEvent(QMouseEvent *event)
             }
         } else if (_action_type == DSO_XM_STEP2) {
             if (event->button() == Qt::LeftButton) {
-                const uint64_t sample_rate = _view.session().get_device()->get_sample_rate();
+                const uint64_t sample_rate = _view.session().cur_samplerate();
                 const double scale = _view.scale();
                 const double samples_per_pixel =  sample_rate * scale;
                 _dso_xm_index[2] = event->pos().x() * samples_per_pixel + _view.offset() * sample_rate;
@@ -666,7 +666,7 @@ void Viewport::mouseDoubleClickEvent(QMouseEvent *event)
             else
                 _view.set_scale_offset(_view.get_maxscale(), 0);
         } else if (event->button() == Qt::LeftButton) {
-            uint64_t index = (_view.offset() + (event->pos().x() + 0.5) * _view.scale()) * _view.session().get_device()->get_sample_rate();
+            uint64_t index = (_view.offset() + (event->pos().x() + 0.5) * _view.scale()) * _view.session().cur_samplerate();
             _view.add_cursor(view::Ruler::CursorColor[_view.get_cursorList().size() % 8], index);
             _view.show_cursors(true);
         }
@@ -683,7 +683,7 @@ void Viewport::mouseDoubleClickEvent(QMouseEvent *event)
             _mm_duty = "#####";
             measure_updated();
         } else if (_action_type == NO_ACTION) {
-            uint64_t sample_rate = _view.session().get_device()->get_sample_rate();
+            uint64_t sample_rate = _view.session().cur_samplerate();
             double scale = _view.scale();
             const double samples_per_pixel =  sample_rate * scale;
             _dso_xm_index[0] = event->pos().x() * samples_per_pixel +
@@ -774,8 +774,8 @@ void Viewport::set_receive_len(quint64 length)
         start_trigger_timer(333);
     } else {
         stop_trigger_timer();
-        if (_total_receive_len + length > _view.session().get_device()->get_sample_limit())
-            _total_receive_len = _view.session().get_device()->get_sample_limit();
+        if (_total_receive_len + length > _view.session().cur_samplelimits())
+            _total_receive_len = _view.session().cur_samplelimits();
         else
             _total_receive_len += length;
     }
@@ -792,7 +792,7 @@ void Viewport::measure()
 {
     _measure_type = NO_MEASURE;
     if (_type == TIME_VIEW) {
-        const uint64_t sample_rate = _view.session().get_device()->get_sample_rate();
+        const uint64_t sample_rate = _view.session().cur_samplerate();
         const vector< boost::shared_ptr<Signal> > sigs(_view.session().get_signals());
         BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) {
             assert(s);
@@ -988,7 +988,7 @@ void Viewport::paintMeasure(QPainter &p)
                     p.setPen(QPen(dsoSig->get_colour(), 1, Qt::DotLine));
                     const int text_height = p.boundingRect(0, 0, INT_MAX, INT_MAX,
                         Qt::AlignLeft | Qt::AlignTop, "W").height();
-                    const uint64_t sample_rate = _view.session().get_device()->get_sample_rate();
+                    const uint64_t sample_rate = _view.session().cur_samplerate();
                     const double x = (_dso_ym_index / (sample_rate * _view.scale())) -
                         _view.offset() /_view.scale();
                     p.drawLine(x-10, _dso_ym_start,
@@ -1034,7 +1034,7 @@ void Viewport::paintMeasure(QPainter &p)
         int measure_line_count = 6;
         const int text_height = p.boundingRect(0, 0, INT_MAX, INT_MAX,
             Qt::AlignLeft | Qt::AlignTop, "W").height();
-        const uint64_t sample_rate = _view.session().get_device()->get_sample_rate();
+        const uint64_t sample_rate = _view.session().cur_samplerate();
         QLineF *line;
         QLineF *const measure_lines = new QLineF[measure_line_count];
         line = measure_lines;
diff --git a/libsigrok4DSL/hardware/DSL/dslogic.c b/libsigrok4DSL/hardware/DSL/dslogic.c
index 2250da53716de8afe8bf686c4bbc08e116824d39..bed144296632eb4af1ff0e093ea3f94b062d564d 100644
--- a/libsigrok4DSL/hardware/DSL/dslogic.c
+++ b/libsigrok4DSL/hardware/DSL/dslogic.c
@@ -393,8 +393,8 @@ static int fpga_setting(const struct sr_dev_inst *sdi)
         setting.trig_logic1[0] = (trigger->trigger_logic[TriggerStages] << 1) + trigger->trigger1_inv[TriggerStages];
 
         for (i = 1; i < NUM_TRIGGER_STAGES; i++) {
-            setting.trig_mask0[i] = 0xff;
-            setting.trig_mask1[i] = 0xff;
+            setting.trig_mask0[i] = 0xffff;
+            setting.trig_mask1[i] = 0xffff;
 
             setting.trig_value0[i] = 0;
             setting.trig_value1[i] = 0;
@@ -1100,34 +1100,32 @@ static int dev_open(struct sr_dev_inst *sdi)
         return SR_ERR;
 	}
 
-    if (devc->fw_updated > 0) {
-        if ((ret = command_fpga_config(usb->devhdl)) != SR_OK) {
-            sr_err("Send FPGA configure command failed!");
-        } else {
-            /* Takes >= 10ms for the FX2 to be ready for FPGA configure. */
-            g_usleep(10 * 1000);
-            char *fpga_bit;
-            if (!(fpga_bit = g_try_malloc(strlen(config_path)+strlen(devc->profile->fpga_bit33)+1))) {
-                sr_err("fpag_bit path malloc error!");
-                return SR_ERR_MALLOC;
-            }
-            strcpy(fpga_bit, config_path);
-            switch(devc->th_level) {
-            case SR_TH_3V3:
-                strcat(fpga_bit, devc->profile->fpga_bit33);;
-                break;
-            case SR_TH_5V0:
-                strcat(fpga_bit, devc->profile->fpga_bit50);;
-                break;
-            default:
-                return SR_ERR;
-            }
-            ret = fpga_config(usb->devhdl, fpga_bit);
-            if (ret != SR_OK) {
-                sr_err("Configure FPGA failed!");
-            }
-            g_free(fpga_bit);
+    if ((ret = command_fpga_config(usb->devhdl)) != SR_OK) {
+        sr_err("Send FPGA configure command failed!");
+    } else {
+        /* Takes >= 10ms for the FX2 to be ready for FPGA configure. */
+        g_usleep(10 * 1000);
+        char *fpga_bit;
+        if (!(fpga_bit = g_try_malloc(strlen(config_path)+strlen(devc->profile->fpga_bit33)+1))) {
+            sr_err("fpag_bit path malloc error!");
+            return SR_ERR_MALLOC;
+        }
+        strcpy(fpga_bit, config_path);
+        switch(devc->th_level) {
+        case SR_TH_3V3:
+            strcat(fpga_bit, devc->profile->fpga_bit33);;
+            break;
+        case SR_TH_5V0:
+            strcat(fpga_bit, devc->profile->fpga_bit50);;
+            break;
+        default:
+            return SR_ERR;
+        }
+        ret = fpga_config(usb->devhdl, fpga_bit);
+        if (ret != SR_OK) {
+            sr_err("Configure FPGA failed!");
         }
+        g_free(fpga_bit);
     }
 
     ret = command_vth(usb->devhdl, devc->vth);
diff --git a/libsigrok4DSL/proto.h b/libsigrok4DSL/proto.h
index fe9b1d951d432b30747d5b05b5f9e4bcc9b00e8c..854f445ef2880c2ae9b4dfacc7405745542b2ee2 100644
--- a/libsigrok4DSL/proto.h
+++ b/libsigrok4DSL/proto.h
@@ -181,6 +181,7 @@ SR_API int ds_trigger_set_stage(uint16_t stages);
 SR_API int ds_trigger_set_pos(uint16_t position);
 SR_API uint16_t ds_trigger_get_pos();
 SR_API int ds_trigger_set_en(uint16_t enable);
+SR_API uint16_t ds_trigger_get_en();
 SR_API int ds_trigger_set_mode(uint16_t mode);
 
 #endif
diff --git a/libsigrok4DSL/trigger.c b/libsigrok4DSL/trigger.c
index c3350c955629778c8c03e0f00b5cd37024e8a604..6baf5d7eb251ba201e245078ff7e29ca9e636b76 100644
--- a/libsigrok4DSL/trigger.c
+++ b/libsigrok4DSL/trigger.c
@@ -207,6 +207,16 @@ SR_API int ds_trigger_set_en(uint16_t enable)
     return SR_OK;
 }
 
+/**
+ * get trigger en
+ *
+ * @return SR_OK upon success.
+ */
+SR_API uint16_t ds_trigger_get_en()
+{
+    return trigger->trigger_en;
+}
+
 /**
  * set trigger mode
  *