diff --git a/DSView/pv/device/devinst.cpp b/DSView/pv/device/devinst.cpp index 604424d9..f0234e52 100644 --- a/DSView/pv/device/devinst.cpp +++ b/DSView/pv/device/devinst.cpp @@ -19,8 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - - #include #include diff --git a/DSView/pv/mainwindow.cpp b/DSView/pv/mainwindow.cpp index 0557933d..422ddee1 100644 --- a/DSView/pv/mainwindow.cpp +++ b/DSView/pv/mainwindow.cpp @@ -523,8 +523,8 @@ void MainWindow::show_error() ch_status += (i > 9 ? " " : ""); error_pattern >>= 1; } - details = tr("the received data are not consist with pre-defined test data!\n") + - tr("0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\n") + ch_status; + details = tr("the received data are not consist with pre-defined test data!") + "\n" + + tr("0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15")+ "\n" + ch_status; break; case SigSession::Pkt_data_err: title = tr("Packet Error"); @@ -723,6 +723,13 @@ bool MainWindow::load_session(QString name) return false; } + // clear decoders + #ifdef ENABLE_DECODE + if (sdi->mode == LOGIC) { + _protocol_widget->del_all_protocol(); + } + #endif + // load device settings GVariant *gvar_opts; gsize num_opts; diff --git a/DSView/pv/sigsession.cpp b/DSView/pv/sigsession.cpp index ed5d6514..90748c84 100644 --- a/DSView/pv/sigsession.cpp +++ b/DSView/pv/sigsession.cpp @@ -445,7 +445,6 @@ bool SigSession::get_capture_status(bool &triggered, int &progress) sr_status status; if (sr_status_get(_dev_inst->dev_inst(), &status, SR_STATUS_TRIG_BEGIN, SR_STATUS_TRIG_END) == SR_OK){ triggered = status.trig_hit & 0x01; - const bool captured_cnt_dec = status.trig_hit & 0x02; uint64_t captured_cnt = status.trig_hit >> 2; captured_cnt = ((uint64_t)status.captured_cnt0 + ((uint64_t)status.captured_cnt1 << 8) + @@ -454,7 +453,7 @@ bool SigSession::get_capture_status(bool &triggered, int &progress) (captured_cnt << 32)); if (_dev_inst->dev_inst()->mode == DSO) captured_cnt = captured_cnt * _signals.size() / get_ch_num(SR_CHANNEL_DSO); - if (captured_cnt_dec) + if (triggered) progress = (sample_limits - captured_cnt) * 100.0 / sample_limits; else progress = captured_cnt * 100.0 / sample_limits; @@ -1057,8 +1056,10 @@ void SigSession::data_feed_in(const struct sr_dev_inst *sdi, case SR_DF_OVERFLOW: { - _error = Data_overflow; - session_error(); + if (_error == No_err) { + _error = Data_overflow; + session_error(); + } break; } case SR_DF_END: diff --git a/DSView/res/DSCope.bin b/DSView/res/DSCope.bin old mode 100644 new mode 100755 index da90491c..d5d30015 Binary files a/DSView/res/DSCope.bin and b/DSView/res/DSCope.bin differ diff --git a/DSView/res/DSCope.fw b/DSView/res/DSCope.fw old mode 100644 new mode 100755 index 2de2f3fb..ce7248eb Binary files a/DSView/res/DSCope.fw and b/DSView/res/DSCope.fw differ diff --git a/DSView/res/DSCope20.bin b/DSView/res/DSCope20.bin old mode 100644 new mode 100755 index f4ae400c..98f2414e Binary files a/DSView/res/DSCope20.bin and b/DSView/res/DSCope20.bin differ diff --git a/DSView/res/DSCope20.fw b/DSView/res/DSCope20.fw old mode 100644 new mode 100755 index 193c8504..a75b5a32 Binary files a/DSView/res/DSCope20.fw and b/DSView/res/DSCope20.fw differ diff --git a/DSView/res/DSCopeB20.fw b/DSView/res/DSCopeB20.fw new file mode 100755 index 00000000..15331d72 Binary files /dev/null and b/DSView/res/DSCopeB20.fw differ diff --git a/DSView/res/DSLogic.fw b/DSView/res/DSLogic.fw old mode 100644 new mode 100755 index 6f048773..6b006b13 Binary files a/DSView/res/DSLogic.fw and b/DSView/res/DSLogic.fw differ diff --git a/DSView/res/DSLogic33.bin b/DSView/res/DSLogic33.bin old mode 100644 new mode 100755 index 168d68fa..df21b86f Binary files a/DSView/res/DSLogic33.bin and b/DSView/res/DSLogic33.bin differ diff --git a/DSView/res/DSLogic50.bin b/DSView/res/DSLogic50.bin old mode 100644 new mode 100755 index 44457683..bd441607 Binary files a/DSView/res/DSLogic50.bin and b/DSView/res/DSLogic50.bin differ diff --git a/DSView/res/DSLogicBasic.bin b/DSView/res/DSLogicBasic.bin old mode 100644 new mode 100755 index fb63035f..8175040b Binary files a/DSView/res/DSLogicBasic.bin and b/DSView/res/DSLogicBasic.bin differ diff --git a/DSView/res/DSLogicBasic.fw b/DSView/res/DSLogicBasic.fw old mode 100644 new mode 100755 index 486c2b4f..a25b2d23 Binary files a/DSView/res/DSLogicBasic.fw and b/DSView/res/DSLogicBasic.fw differ diff --git a/DSView/res/DSLogicPlus.bin b/DSView/res/DSLogicPlus.bin old mode 100644 new mode 100755 index 605392ac..9eb96a7a Binary files a/DSView/res/DSLogicPlus.bin and b/DSView/res/DSLogicPlus.bin differ diff --git a/DSView/res/DSLogicPlus.fw b/DSView/res/DSLogicPlus.fw old mode 100644 new mode 100755 index 69096b44..036fafa6 Binary files a/DSView/res/DSLogicPlus.fw and b/DSView/res/DSLogicPlus.fw differ diff --git a/DSView/res/DSLogicPro.bin b/DSView/res/DSLogicPro.bin old mode 100644 new mode 100755 index a236b61d..89b1a9b3 Binary files a/DSView/res/DSLogicPro.bin and b/DSView/res/DSLogicPro.bin differ diff --git a/DSView/res/DSLogicPro.fw b/DSView/res/DSLogicPro.fw old mode 100644 new mode 100755 index dcf0543a..44b1b7a1 Binary files a/DSView/res/DSLogicPro.fw and b/DSView/res/DSLogicPro.fw differ diff --git a/libsigrok4DSL/hardware/DSL/Makefile.am b/libsigrok4DSL/hardware/DSL/Makefile.am index 0d025752..6ad8ba7a 100644 --- a/libsigrok4DSL/hardware/DSL/Makefile.am +++ b/libsigrok4DSL/hardware/DSL/Makefile.am @@ -23,6 +23,7 @@ noinst_LTLIBRARIES = libsigrok4DSL_hw_dsl.la libsigrok4DSL_hw_dsl_la_SOURCES = \ command.c \ + dsl.c \ dslogic.c \ dscope.c diff --git a/libsigrok4DSL/hardware/DSL/command.c b/libsigrok4DSL/hardware/DSL/command.c index 3317eb5f..1048a950 100644 --- a/libsigrok4DSL/hardware/DSL/command.c +++ b/libsigrok4DSL/hardware/DSL/command.c @@ -19,179 +19,22 @@ #include "libsigrok.h" #include "libsigrok-internal.h" -//#include + #include "command.h" -//#include "libsigrok.h" #include "dsl.h" #include -SR_PRIV int command_get_fw_version(libusb_device_handle *devhdl, - struct version_info *vi) +SR_PRIV int command_ctl_wr(libusb_device_handle *devhdl, struct ctl_wr_cmd cmd) { - int ret; - - ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR | - LIBUSB_ENDPOINT_IN, CMD_GET_FW_VERSION, 0x0000, 0x0000, - (unsigned char *)vi, sizeof(struct version_info), 3000); - - if (ret < 0) { - sr_err("Unable to get version info: %s.", - libusb_error_name(ret)); - return SR_ERR; - } - - return SR_OK; -} - -SR_PRIV int command_get_revid_version(libusb_device_handle *devhdl, - uint8_t *revid) -{ - int ret; - - ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR | - LIBUSB_ENDPOINT_IN, CMD_GET_REVID_VERSION, 0x0000, 0x0000, - revid, 1, 3000); - - if (ret < 0) { - sr_err("Unable to get REVID: %s.", libusb_error_name(ret)); - return SR_ERR; - } - - return SR_OK; -} - -SR_PRIV int command_start_acquisition(libusb_device_handle *devhdl, - uint64_t samplerate, gboolean samplewide, gboolean la_mode) -{ - struct cmd_start_acquisition cmd; - int delay = 0, ret; - - (void) samplerate; - - cmd.flags = la_mode ? CMD_START_FLAGS_MODE_LA : 0; - - cmd.flags |= CMD_START_FLAGS_CLK_30MHZ; - delay = 0; - - sr_info("GPIF delay = %d, clocksource = %sMHz.", delay, - (cmd.flags & CMD_START_FLAGS_CLK_48MHZ) ? "48" : "30"); - -// if (delay <= 0 || delay > MAX_SAMPLE_DELAY) { -// sr_err("Unable to sample at %" PRIu64 "Hz.", samplerate); -// return SR_ERR; -// } - - cmd.sample_delay_h = (delay >> 8) & 0xff; - cmd.sample_delay_l = delay & 0xff; - - /* Select the sampling width. */ - cmd.flags |= samplewide ? CMD_START_FLAGS_SAMPLE_16BIT : - CMD_START_FLAGS_SAMPLE_8BIT; - - /* Send the control message. */ - ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR | - LIBUSB_ENDPOINT_OUT, CMD_START, 0x0000, 0x0000, - (unsigned char *)&cmd, sizeof(cmd), 3000); - if (ret < 0) { - sr_err("Unable to send start command: %s.", - libusb_error_name(ret)); - return SR_ERR; - } - - return SR_OK; -} - -SR_PRIV int command_stop_acquisition(libusb_device_handle *devhdl) -{ - struct cmd_start_acquisition cmd; int ret; - /* stop acquisition command */ - cmd.flags = CMD_START_FLAGS_STOP; - cmd.sample_delay_h = 0; - cmd.sample_delay_l = 0; - - /* Send the control message. */ - ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR | - LIBUSB_ENDPOINT_OUT, CMD_START, 0x0000, 0x0000, - (unsigned char *)&cmd, sizeof(cmd), 3000); - if (ret < 0) { - sr_err("Unable to send stop command: %s.", - libusb_error_name(ret)); - return SR_ERR; - } - - return SR_OK; -} - -SR_PRIV int command_fpga_config(libusb_device_handle *devhdl) -{ - struct cmd_cfg_count cmd; - int ret; - - /* ... */ - cmd.byte0 = (uint8_t)0; - cmd.byte1 = (uint8_t)0; - cmd.byte2 = (uint8_t)0; - - /* Send the control message. */ - ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR | - LIBUSB_ENDPOINT_OUT, CMD_CONFIG, 0x0000, 0x0000, - (unsigned char *)&cmd, sizeof(cmd), 3000); - if (ret < 0) { - sr_err("Unable to send FPGA configure command: %s.", - libusb_error_name(ret)); - return SR_ERR; - } - - return SR_OK; -} - -SR_PRIV int command_fpga_setting(libusb_device_handle *devhdl, uint32_t setting_count) -{ - struct cmd_setting_count cmd; - int ret; - - /* ... */ - cmd.byte0 = (uint8_t)setting_count; - cmd.byte1 = (uint8_t)(setting_count >> 8); - cmd.byte2 = (uint8_t)(setting_count >> 16); - - /* Send the control message. */ - ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR | - LIBUSB_ENDPOINT_OUT, CMD_SETTING, 0x0000, 0x0000, - (unsigned char *)&cmd, sizeof(cmd), 3000); - if (ret < 0) { - sr_err("Unable to send FPGA setting command: %s.", - libusb_error_name(ret)); - return SR_ERR; - } - - return SR_OK; -} - -SR_PRIV int command_dso_ctrl(libusb_device_handle *devhdl, uint64_t command) -{ - struct cmd_control cmd; - int ret; - - /* ... */ - cmd.byte0 = (uint8_t)command; - cmd.byte1 = (uint8_t)(command >> 8); - cmd.byte2 = (uint8_t)(command >> 16); - cmd.byte3 = (uint8_t)(command >> 24); - cmd.byte4 = (uint8_t)(command >> 32); - cmd.byte5 = (uint8_t)(command >> 40); - cmd.byte6 = (uint8_t)(command >> 48); - cmd.byte7 = (uint8_t)(command >> 56); - - /* Send the control command. */ ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR | - LIBUSB_ENDPOINT_OUT, CMD_CONTROL, 0x0000, 0x0000, - (unsigned char *)&cmd, sizeof(cmd), 3000); + LIBUSB_ENDPOINT_OUT, CMD_CTL_WR, 0x0000, 0x0000, + (unsigned char *)&cmd, cmd.header.size+sizeof(struct ctl_header), 3000); if (ret < 0) { - sr_err("Unable to send oscilloscope control command: %s.", + sr_err("Unable to send CMD_CTL_WR command(dest:%d/offset:%d/size:%d): %s.", + cmd.header.dest, cmd.header.offset, cmd.header.size, libusb_error_name(ret)); return SR_ERR; } @@ -199,95 +42,17 @@ SR_PRIV int command_dso_ctrl(libusb_device_handle *devhdl, uint64_t command) return SR_OK; } -SR_PRIV int command_get_status(libusb_device_handle *devhdl, - unsigned char *status, int begin, int end) -{ - struct cmd_status_info cmd; - int ret; - - /* status acquisition command */ - assert(begin >= 0); - assert(end >= 0); - cmd.begin = begin; - cmd.end = end; - - /* Send the control message. */ - ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR | - LIBUSB_ENDPOINT_OUT, CMD_STATUS_INFO, 0x0000, 0x0000, - (unsigned char *)&cmd, sizeof(cmd), 3000); - if (ret < 0) { - sr_err("Unable to send status info: %s.", - libusb_error_name(ret)); - return SR_ERR; - } - - g_usleep(10*1000); - - ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR | - LIBUSB_ENDPOINT_IN, CMD_STATUS, 0x0000, 0x0000, - (unsigned char *)status, CMD_STATUS_CNT, 3000); - - if (ret < 0) { - sr_err("Unable to get status info: %s.", - libusb_error_name(ret)); - return SR_ERR; - } - - return SR_OK; -} - -SR_PRIV int command_wr_reg(libusb_device_handle *devhdl, uint8_t value, uint8_t addr) -{ - int ret; - uint16_t cmd; - - cmd = value + (addr << 8); - /* Send the control command. */ - ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR | - LIBUSB_ENDPOINT_OUT, CMD_WR_REG, 0x0000, 0x0000, - (unsigned char *)&cmd, sizeof(cmd), 3000); - if (ret < 0) { - sr_err("Unable to write REG @ address %d : %s.", - addr, libusb_error_name(ret)); - return SR_ERR; - } - - return SR_OK; -} - -SR_PRIV int command_wr_nvm(libusb_device_handle *devhdl, unsigned char *ctx, uint8_t len) +SR_PRIV int command_ctl_rd(libusb_device_handle *devhdl, struct ctl_rd_cmd cmd) { int ret; /* Send the control message. */ ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR | - LIBUSB_ENDPOINT_OUT, CMD_WR_NVM, 0x0000, 0x0000, - (unsigned char *)ctx, len, 3000); - + LIBUSB_ENDPOINT_OUT, CMD_CTL_RD_PRE, 0x0000, 0x0000, + (unsigned char *)&cmd, sizeof(struct ctl_header), 3000); if (ret < 0) { - sr_err("Unable to get status info: %s.", - libusb_error_name(ret)); - return SR_ERR; - } - - return SR_OK; -} - -SR_PRIV int command_rd_nvm(libusb_device_handle *devhdl, unsigned char *ctx, uint16_t addr, uint8_t len) -{ - int ret; - - struct cmd_nvm_info nvm_info; - assert(len <= 32); - nvm_info.addr = addr; - nvm_info.len = len; - - /* Send the control message. */ - ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR | - LIBUSB_ENDPOINT_OUT, CMD_RD_NVM_PRE, 0x0000, 0x0000, - (unsigned char *)&nvm_info, sizeof(struct cmd_nvm_info), 3000); - if (ret < 0) { - sr_err("Unable to send CMD_RD_NVM_PRE command: %s.", + sr_err("Unable to send CMD_CTL_RD_PRE command(dest:%d/offset:%d/size:%d): %s.", + cmd.header.dest, cmd.header.offset, cmd.header.size, libusb_error_name(ret)); return SR_ERR; } @@ -296,32 +61,14 @@ SR_PRIV int command_rd_nvm(libusb_device_handle *devhdl, unsigned char *ctx, uin /* Send the control message. */ ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR | - LIBUSB_ENDPOINT_IN, CMD_RD_NVM, 0x0000, 0x0000, - (unsigned char *)ctx, len, 3000); + LIBUSB_ENDPOINT_IN, CMD_CTL_RD, 0x0000, 0x0000, + (unsigned char *)cmd.data, cmd.header.size, 3000); if (ret < 0) { - sr_err("Unable to get zero info: %s.", + sr_err("Unable to send CMD_CTL_RD command: %s.", libusb_error_name(ret)); return SR_ERR; } return SR_OK; } - -SR_PRIV int command_get_hw_info(libusb_device_handle *devhdl, uint8_t *info) -{ - int ret; - - ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR | - LIBUSB_ENDPOINT_IN, CMD_GET_HW_INFO, 0x0000, 0x0000, - info, 1, 3000); - - if (ret < 0) { - sr_err("Unable to get hardware info: %s.", - libusb_error_name(ret)); - return SR_ERR; - } - - return SR_OK; -} - diff --git a/libsigrok4DSL/hardware/DSL/command.h b/libsigrok4DSL/hardware/DSL/command.h index 071ef312..80ae79b7 100644 --- a/libsigrok4DSL/hardware/DSL/command.h +++ b/libsigrok4DSL/hardware/DSL/command.h @@ -25,82 +25,54 @@ #include "libsigrok-internal.h" /* Protocol commands */ -#define CMD_GET_FW_VERSION 0xb0 -#define CMD_GET_REVID_VERSION 0xb1 -#define CMD_START 0xb2 -#define CMD_CONFIG 0xb3 -#define CMD_SETTING 0xb4 -#define CMD_CONTROL 0xb5 -#define CMD_STATUS 0xb6 -#define CMD_STATUS_INFO 0xb7 -#define CMD_WR_REG 0xb8 -#define CMD_WR_NVM 0xb9 -#define CMD_RD_NVM 0xba -#define CMD_RD_NVM_PRE 0xbb -#define CMD_GET_HW_INFO 0xbc +#define CMD_CTL_WR 0xb0 +#define CMD_CTL_RD_PRE 0xb1 +#define CMD_CTL_RD 0xb2 -#define CMD_START_FLAGS_MODE_POS 4 -#define CMD_START_FLAGS_WIDE_POS 5 -#define CMD_START_FLAGS_CLK_SRC_POS 6 -#define CMD_START_FLAGS_STOP_POS 7 +#define bmGPIF_DONE (1 << 7) +#define bmFPGA_DONE (1 << 6) +#define bmFPGA_INIT_B (1 << 5) +#define bmSYS_OVERFLOW (1 << 4) +#define bmSYS_CLR (1 << 3) +#define bmSYS_EN (1 << 2) +#define bmLED_RED (1 << 1) +#define bmLED_GREEN (1 << 0) -#define CMD_START_FLAGS_MODE_LA (1 << CMD_START_FLAGS_MODE_POS) - -#define CMD_START_FLAGS_SAMPLE_8BIT (0 << CMD_START_FLAGS_WIDE_POS) -#define CMD_START_FLAGS_SAMPLE_16BIT (1 << CMD_START_FLAGS_WIDE_POS) - -#define CMD_START_FLAGS_CLK_30MHZ (0 << CMD_START_FLAGS_CLK_SRC_POS) -#define CMD_START_FLAGS_CLK_48MHZ (1 << CMD_START_FLAGS_CLK_SRC_POS) - -#define CMD_START_FLAGS_STOP (1 << CMD_START_FLAGS_STOP_POS) - -#define CMD_STATUS_CNT 32 +#define bmWR_PROG_B (1 << 2) +#define bmWR_INTRDY (1 << 7) +#define bmWR_WORDWIDE (1 << 0) #define VTH_ADDR 0x78 #define EEWP_ADDR 0x70 #define COMB_ADDR 0x68 -#pragma pack(push, 1) +enum { + DSL_CTL_FW_VERSION = 0, + DSL_CTL_REVID_VERSION = 1, + DSL_CTL_HW_STATUS = 2, + DSL_CTL_PROG_B = 3, + DSL_CTL_SYS = 4, + DSL_CTL_LED = 5, + DSL_CTL_INTRDY = 6, + DSL_CTL_WORDWIDE = 7, + DSL_CTL_START = 8, + DSL_CTL_STOP = 9, + DSL_CTL_BULK_WR = 10, + DSL_CTL_REG = 11, + DSL_CTL_NVM = 12, + + DSL_CTL_I2C_DSO = 13, + DSL_CTL_I2C_REG = 14, + DSL_CTL_DSO_MEASURE = 15, +}; + +#pragma pack(push, 1) // byte align struct version_info { uint8_t major; uint8_t minor; }; -struct cmd_start_acquisition { - uint8_t flags; - uint8_t sample_delay_h; - uint8_t sample_delay_l; -}; - -struct cmd_setting_count { - uint8_t byte0; - uint8_t byte1; - uint8_t byte2; -}; - -struct cmd_cfg_count { - uint8_t byte0; - uint8_t byte1; - uint8_t byte2; -}; - -struct cmd_control { - uint8_t byte0; - uint8_t byte1; - uint8_t byte2; - uint8_t byte3; - uint8_t byte4; - uint8_t byte5; - uint8_t byte6; - uint8_t byte7; -}; - -struct cmd_status_info { - uint8_t begin; - uint8_t end; -}; - struct cmd_zero_info { uint8_t zero_addr; uint8_t voff0; @@ -137,35 +109,23 @@ struct cmd_vga_info { uint16_t vga7; }; -struct cmd_nvm_info { - uint16_t addr; - uint8_t len; +struct ctl_header { + uint8_t dest; + uint16_t offset; + uint8_t size; +}; +struct ctl_wr_cmd { + struct ctl_header header; + uint8_t data[60]; +}; +struct ctl_rd_cmd { + struct ctl_header header; + uint8_t *data; }; - #pragma pack(pop) -SR_PRIV int command_get_fw_version(libusb_device_handle *devhdl, - struct version_info *vi); -SR_PRIV int command_get_revid_version(libusb_device_handle *devhdl, - uint8_t *revid); -SR_PRIV int command_start_acquisition(libusb_device_handle *devhdl, - uint64_t samplerate, gboolean samplewide, gboolean la_mode); -SR_PRIV int command_stop_acquisition(libusb_device_handle *devhdl); -SR_PRIV int command_fpga_config(libusb_device_handle *devhdl); -SR_PRIV int command_fpga_setting(libusb_device_handle *devhdl, uint32_t setting_count); +SR_PRIV int command_ctl_wr(libusb_device_handle *devhdl, struct ctl_wr_cmd cmd); +SR_PRIV int command_ctl_rd(libusb_device_handle *devhdl, struct ctl_rd_cmd cmd); -SR_PRIV int command_dso_ctrl(libusb_device_handle *devhdl, uint64_t command); - -SR_PRIV int command_get_status(libusb_device_handle *devhdl, - unsigned char *status, - int begin, int end); - -SR_PRIV int command_wr_reg(libusb_device_handle *devhdl, uint8_t value, uint8_t addr); - -SR_PRIV int command_wr_nvm(libusb_device_handle *devhdl, unsigned char *ctx, uint8_t len); -SR_PRIV int command_rd_nvm(libusb_device_handle *devhdl, unsigned char *ctx, uint16_t addr, uint8_t len); - -SR_PRIV int command_get_hw_info(libusb_device_handle *devhdl, - uint8_t *fpga_done); #endif diff --git a/libsigrok4DSL/hardware/DSL/dscope.c b/libsigrok4DSL/hardware/DSL/dscope.c index 750fe186..b37804f7 100644 --- a/libsigrok4DSL/hardware/DSL/dscope.c +++ b/libsigrok4DSL/hardware/DSL/dscope.c @@ -20,28 +20,13 @@ #include "libsigrok.h" #include "libsigrok-internal.h" -#include -#include -#include -#include -#include -#include -#include -#include -//#include #include "dsl.h" #include "command.h" #undef min #define min(a,b) ((a)<(b)?(a):(b)) -static const int single_buffer_time = 20; -static const int buffer_size = 1024 * 1024; -static const int instant_buffer_size = 1024 * 1024; -static const int cons_buffer_size = 128; -static const int total_buffer_time = 200; - static struct sr_dev_mode mode_list[] = { {"OSC", DSO}, }; @@ -57,11 +42,6 @@ static const char *thresholds[] = { "5.0V Level", }; -static const char *filters[] = { - "None", - "1 Sample Clock", -}; - static const int32_t hwopts[] = { SR_CONF_CONN, }; @@ -141,15 +121,11 @@ static const uint64_t samplecounts[] = { static uint16_t opmodes_show_count = 2; static const uint8_t zero_base_addr = 0x40; +static const uint8_t zero_big_addr = 0x20; SR_PRIV struct sr_dev_driver DSCope_driver_info; static struct sr_dev_driver *di = &DSCope_driver_info; -extern struct ds_trigger *trigger; - -gboolean mstatus_valid = FALSE; -struct sr_status mstatus; - static const uint64_t DSCOPE_DEFAULT_VGAIN[] = { DSCOPE_DEFAULT_VGAIN0, DSCOPE_DEFAULT_VGAIN1, @@ -195,569 +171,12 @@ struct DSL_vga DSCope20_vga[] = { {0, 0, 0, 0, 0}, }; -/** - * Check the USB configuration to determine if this is an DSCope device. - * - * @return TRUE if the device's configuration profile match DSCope - * configuration, FALSE otherwise. - */ -static gboolean check_conf_profile(libusb_device *dev) -{ - struct libusb_device_descriptor des; - struct libusb_device_handle *hdl; - gboolean ret; - unsigned char strdesc[64]; - - hdl = NULL; - ret = FALSE; - while (!ret) { - /* Assume the FW has not been loaded, unless proven wrong. */ - if (libusb_get_device_descriptor(dev, &des) != 0) - break; - - if (libusb_open(dev, &hdl) != 0) - break; - - if (libusb_get_string_descriptor_ascii(hdl, - des.iManufacturer, strdesc, sizeof(strdesc)) < 0) - break; - if (strncmp((const char *)strdesc, "DreamSourceLab", 14)) - break; - - if (libusb_get_string_descriptor_ascii(hdl, - des.iProduct, strdesc, sizeof(strdesc)) < 0) - break; - if (strncmp((const char *)strdesc, "USB-based Instrument", 20)) - break; - - /* If we made it here, it must be an DSCope. */ - ret = TRUE; - } - if (hdl) - libusb_close(hdl); - - return ret; -} - -static int en_ch_num(const struct sr_dev_inst *sdi) -{ - GSList *l; - int channel_en_cnt = 0; - - for (l = sdi->channels; l; l = l->next) { - struct sr_channel *probe = (struct sr_channel *)l->data; - channel_en_cnt += probe->enabled; - } - channel_en_cnt += (channel_en_cnt == 0); - - return channel_en_cnt; -} - -static int fpga_setting(const struct sr_dev_inst *sdi) -{ - struct DSL_context *devc; - struct sr_usb_dev_inst *usb; - struct libusb_device_handle *hdl; - struct DSL_setting setting; - int ret; - int transferred; - int result; - int i; - GSList *l; - uint32_t tmp_u32; - uint64_t tmp_u64; - - devc = sdi->priv; - usb = sdi->conn; - hdl = usb->devhdl; - - setting.sync = 0xf5a5f5a5; - setting.mode_header = 0x0001; - setting.divider_header = 0x0102; - setting.count_header = 0x0302; - setting.trig_pos_header = 0x0502; - setting.trig_glb_header = 0x0701; - setting.ch_en_header = 0x0801; - setting.trig_header = 0x40a0; - setting.end_sync = 0xfa5afa5a; - - //setting.mode = (test_mode ? 0x8000 : 0x0000) + trigger->trigger_en + (sdi->mode << 4); - setting.mode = (trigger->trigger_en << TRIG_EN_BIT) + - (devc->clock_type << CLK_TYPE_BIT) + - (devc->clock_edge << CLK_EDGE_BIT) + - ((sdi->mode == DSO) << DSO_MODE_BIT) + - ((((devc->cur_samplerate == (2 * DSLOGIC_MAX_LOGIC_SAMPLERATE)) && sdi->mode != DSO) || (sdi->mode == ANALOG)) << HALF_MODE_BIT) + - ((devc->cur_samplerate == (4 * DSLOGIC_MAX_LOGIC_SAMPLERATE)) << QUAR_MODE_BIT) + - ((sdi->mode == ANALOG) << ANALOG_MODE_BIT) + - ((devc->filter == SR_FILTER_1T) << FILTER_BIT) + - (devc->instant << INSTANT_BIT) + - ((devc->op_mode == SR_OP_LOOPBACK_TEST) << LPB_TEST_BIT) + - ((devc->op_mode == SR_OP_EXTERNAL_TEST) << EXT_TEST_BIT) + - ((devc->op_mode == SR_OP_INTERNAL_TEST) << INT_TEST_BIT); - - // sample rate divider - tmp_u32 = (sdi->mode == DSO) ? (uint32_t)ceil(DSLOGIC_MAX_DSO_SAMPLERATE * 1.0 / devc->cur_samplerate / en_ch_num(sdi)) : - (uint32_t)ceil(DSLOGIC_MAX_LOGIC_SAMPLERATE * 1.0 / devc->cur_samplerate); - setting.div_l = tmp_u32 & 0x0000ffff; - setting.div_h = tmp_u32 >> 16; - - // capture counter - // analog: 16bits, but sample with half mode(0-7 valid only) - tmp_u64 = (sdi->mode == DSO) ? (devc->limit_samples / (g_slist_length(sdi->channels) / en_ch_num(sdi))) : - (sdi->mode == ANALOG) ? (devc->limit_samples * g_slist_length(sdi->channels) * 4) : - (devc->limit_samples); - tmp_u64 >>= 4; // hardware minimum unit 64 - setting.cnt_l = tmp_u64 & 0x0000ffff; - setting.cnt_h = tmp_u64 >> 16; - - // trigger position - tmp_u32 = (uint32_t)(trigger->trigger_pos / 100.0 * devc->limit_samples); - if (setting.mode & (1 << QUAR_MODE_BIT)) - setting.tpos_l = tmp_u32 & 0x0000fffc; - else if (setting.mode & (1 << HALF_MODE_BIT)) - setting.tpos_l = tmp_u32 & 0x0000fffe; - else - setting.tpos_l = tmp_u32 & 0x0000ffff; - setting.tpos_h = tmp_u32 >> 16; - - // trigger global settings - setting.trig_glb = ((en_ch_num(sdi) & 0xf) << 4) + - trigger->trigger_stages; - - // channel enable mapping - setting.ch_en = 0; - for (l = sdi->channels; l; l = l->next) { - struct sr_channel *probe = (struct sr_channel *)l->data; - setting.ch_en += probe->enabled << probe->index; - } - - // trigger advanced configuration - if (trigger->trigger_mode == SIMPLE_TRIGGER) { - setting.trig_mask0[0] = ds_trigger_get_mask0(TriggerStages); - setting.trig_mask1[0] = ds_trigger_get_mask1(TriggerStages); - - setting.trig_value0[0] = ds_trigger_get_value0(TriggerStages); - setting.trig_value1[0] = ds_trigger_get_value1(TriggerStages); - - setting.trig_edge0[0] = ds_trigger_get_edge0(TriggerStages); - setting.trig_edge1[0] = ds_trigger_get_edge1(TriggerStages); - - if (setting.mode & (1 << QUAR_MODE_BIT)) { - setting.trig_mask0[0] = ((setting.trig_mask0[0] & 0x0f) << 12) + - ((setting.trig_mask0[0] & 0x0f) << 8) + - ((setting.trig_mask0[0] & 0x0f) << 4) + - ((setting.trig_mask0[0] & 0x0f) << 0); - setting.trig_mask1[0] = ((setting.trig_mask1[0] & 0x0f) << 12) + - ((setting.trig_mask1[0] & 0x0f) << 8) + - ((setting.trig_mask1[0] & 0x0f) << 4) + - ((setting.trig_mask1[0] & 0x0f) << 0); - setting.trig_value0[0] = ((setting.trig_value0[0] & 0x0f) << 12) + - ((setting.trig_value0[0] & 0x0f) << 8) + - ((setting.trig_value0[0] & 0x0f) << 4) + - ((setting.trig_value0[0] & 0x0f) << 0); - setting.trig_value1[0] = ((setting.trig_value1[0] & 0x0f) << 12) + - ((setting.trig_value1[0] & 0x0f) << 8) + - ((setting.trig_value1[0] & 0x0f) << 4) + - ((setting.trig_value1[0] & 0x0f) << 0); - setting.trig_edge0[0] = ((setting.trig_edge0[0] & 0x0f) << 12) + - ((setting.trig_edge0[0] & 0x0f) << 8) + - ((setting.trig_edge0[0] & 0x0f) << 4) + - ((setting.trig_edge0[0] & 0x0f) << 0); - setting.trig_edge1[0] = ((setting.trig_edge1[0] & 0x0f) << 12) + - ((setting.trig_edge1[0] & 0x0f) << 8) + - ((setting.trig_edge1[0] & 0x0f) << 4) + - ((setting.trig_edge1[0] & 0x0f) << 0); - } else if (setting.mode & (1 << HALF_MODE_BIT)) { - setting.trig_mask0[0] = ((setting.trig_mask0[0] & 0xff) << 8) + - ((setting.trig_mask0[0] & 0xff) << 0); - setting.trig_mask1[0] = ((setting.trig_mask1[0] & 0xff) << 8) + - ((setting.trig_mask1[0] & 0xff) << 0); - setting.trig_value0[0] = ((setting.trig_value0[0] & 0xff) << 8) + - ((setting.trig_value0[0] & 0xff) << 0); - setting.trig_value1[0] = ((setting.trig_value1[0] & 0xff) << 8) + - ((setting.trig_value1[0] & 0xff) << 0); - setting.trig_edge0[0] = ((setting.trig_edge0[0] & 0xff) << 8) + - ((setting.trig_edge0[0] & 0xff) << 0); - setting.trig_edge1[0] = ((setting.trig_edge1[0] & 0xff) << 8) + - ((setting.trig_edge1[0] & 0xff) << 0); - } - - setting.trig_logic0[0] = (trigger->trigger_logic[TriggerStages] << 1) + trigger->trigger0_inv[TriggerStages]; - setting.trig_logic1[0] = (trigger->trigger_logic[TriggerStages] << 1) + trigger->trigger1_inv[TriggerStages]; - - setting.trig_count[0] = trigger->trigger0_count[TriggerStages]; - - for (i = 1; i < NUM_TRIGGER_STAGES; i++) { - setting.trig_mask0[i] = 0xffff; - setting.trig_mask1[i] = 0xffff; - - setting.trig_value0[i] = 0; - setting.trig_value1[i] = 0; - - setting.trig_edge0[i] = 0; - setting.trig_edge1[i] = 0; - - setting.trig_logic0[i] = 2; - setting.trig_logic1[i] = 2; - - setting.trig_count[i] = 0; - } - } else { - for (i = 0; i < NUM_TRIGGER_STAGES; i++) { - setting.trig_mask0[i] = ds_trigger_get_mask0(i); - setting.trig_mask1[i] = ds_trigger_get_mask1(i); - - setting.trig_value0[i] = ds_trigger_get_value0(i); - setting.trig_value1[i] = ds_trigger_get_value1(i); - - setting.trig_edge0[i] = ds_trigger_get_edge0(i); - setting.trig_edge1[i] = ds_trigger_get_edge1(i); - - if (setting.mode & (1 << STRIG_MODE_BIT) && i == STriggerDataStage) { - // serial trigger, data mask/value should not be duplicated - } else { - if (setting.mode & (1 << QUAR_MODE_BIT)) { - setting.trig_mask0[i] = ((setting.trig_mask0[i] & 0x0f) << 12) + - ((setting.trig_mask0[i] & 0x0f) << 8) + - ((setting.trig_mask0[i] & 0x0f) << 4) + - ((setting.trig_mask0[i] & 0x0f) << 0); - setting.trig_mask1[i] = ((setting.trig_mask1[i] & 0x0f) << 12) + - ((setting.trig_mask1[i] & 0x0f) << 8) + - ((setting.trig_mask1[i] & 0x0f) << 4) + - ((setting.trig_mask1[i] & 0x0f) << 0); - setting.trig_value0[i] = ((setting.trig_value0[i] & 0x0f) << 12) + - ((setting.trig_value0[i] & 0x0f) << 8) + - ((setting.trig_value0[i] & 0x0f) << 4) + - ((setting.trig_value0[i] & 0x0f) << 0); - setting.trig_value1[i] = ((setting.trig_value1[i] & 0x0f) << 12) + - ((setting.trig_value1[i] & 0x0f) << 8) + - ((setting.trig_value1[i] & 0x0f) << 4) + - ((setting.trig_value1[i] & 0x0f) << 0); - setting.trig_edge0[i] = ((setting.trig_edge0[i] & 0x0f) << 12) + - ((setting.trig_edge0[i] & 0x0f) << 8) + - ((setting.trig_edge0[i] & 0x0f) << 4) + - ((setting.trig_edge0[i] & 0x0f) << 0); - setting.trig_edge1[i] = ((setting.trig_edge1[i] & 0x0f) << 12) + - ((setting.trig_edge1[i] & 0x0f) << 8) + - ((setting.trig_edge1[i] & 0x0f) << 4) + - ((setting.trig_edge1[i] & 0x0f) << 0); - } else if (setting.mode & (1 << HALF_MODE_BIT)) { - setting.trig_mask0[i] = ((setting.trig_mask0[i] & 0xff) << 8) + - ((setting.trig_mask0[i] & 0xff) << 0); - setting.trig_mask1[i] = ((setting.trig_mask1[i] & 0xff) << 8) + - ((setting.trig_mask1[i] & 0xff) << 0); - setting.trig_value0[i] = ((setting.trig_value0[i] & 0xff) << 8) + - ((setting.trig_value0[i] & 0xff) << 0); - setting.trig_value1[i] = ((setting.trig_value1[i] & 0xff) << 8) + - ((setting.trig_value1[i] & 0xff) << 0); - setting.trig_edge0[i] = ((setting.trig_edge0[i] & 0xff) << 8) + - ((setting.trig_edge0[i] & 0xff) << 0); - setting.trig_edge1[i] = ((setting.trig_edge1[i] & 0xff) << 8) + - ((setting.trig_edge1[i] & 0xff) << 0); - } - } - - setting.trig_logic0[i] = (trigger->trigger_logic[i] << 1) + trigger->trigger0_inv[i]; - setting.trig_logic1[i] = (trigger->trigger_logic[i] << 1) + trigger->trigger1_inv[i]; - - setting.trig_count[i] = trigger->trigger0_count[i]; - } - } - - result = SR_OK; - ret = libusb_bulk_transfer(hdl, 2 | LIBUSB_ENDPOINT_OUT, - (unsigned char*)&setting, sizeof(struct DSL_setting), - &transferred, 1000); - - if (ret < 0) { - sr_err("Unable to setting FPGA of DSCope: %s.", - libusb_error_name(ret)); - result = SR_ERR; - } else if (transferred != sizeof(struct DSL_setting)) { - sr_err("Setting FPGA error: expacted transfer size %d; actually %d", - sizeof(struct DSL_setting), transferred); - result = SR_ERR; - } - - if (result == SR_OK) - sr_info("FPGA setting done"); - - return result; -} - -static int fpga_config(struct libusb_device_handle *hdl, const char *filename) -{ - FILE *fw; - int offset, chunksize, ret, result; - unsigned char *buf; - int transferred; - uint64_t filesize; - struct stat f_stat; - - sr_info("Configure FPGA using %s", filename); - if ((fw = fopen(filename, "rb")) == NULL) { - sr_err("Unable to open FPGA bit file %s for reading: %s", - filename, strerror(errno)); - return SR_ERR; - } - - if (stat(filename, &f_stat) == -1) - return SR_ERR; - - filesize = (uint64_t)f_stat.st_size; - - if (!(buf = g_try_malloc(filesize))) { - sr_err("FPGA configure bit malloc failed."); - return SR_ERR; - } - - result = SR_OK; - offset = 0; - while (1) { - chunksize = fread(buf, 1, filesize, fw); - if (chunksize == 0) - break; - - //do { - ret = libusb_bulk_transfer(hdl, 2 | LIBUSB_ENDPOINT_OUT, - buf, chunksize, - &transferred, 1000); - //} while(ret == LIBUSB_ERROR_TIMEOUT); - - if (ret < 0) { - sr_err("Unable to configure FPGA of DSCope: %s.", - libusb_error_name(ret)); - result = SR_ERR; - break; - } else if (transferred != chunksize) { - sr_err("Configure FPGA error: expacted transfer size %d; actually %d", - chunksize, transferred); - result = SR_ERR; - break; - } - sr_info("Configure %d bytes", chunksize); - offset += chunksize; - } - fclose(fw); - g_free(buf); - if (result == SR_OK) - sr_info("FPGA configure done"); - - return result; -} - -static int DSCope_dev_open(struct sr_dev_inst *sdi) -{ - libusb_device **devlist; - struct sr_usb_dev_inst *usb; - struct libusb_device_descriptor des; - struct DSL_context *devc; - struct drv_context *drvc; - struct version_info vi; - int ret, skip, i, device_count; - uint8_t revid; - - drvc = di->priv; - devc = sdi->priv; - usb = sdi->conn; - - if (sdi->status == SR_ST_ACTIVE) { - /* Device is already in use. */ - return SR_ERR; - } - - skip = 0; - device_count = libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist); - if (device_count < 0) { - sr_err("Failed to get device list: %s.", - libusb_error_name(device_count)); - return SR_ERR; - } - - for (i = 0; i < device_count; i++) { - if ((ret = libusb_get_device_descriptor(devlist[i], &des))) { - sr_err("Failed to get device descriptor: %s.", - libusb_error_name(ret)); - continue; - } - - if (des.idVendor != devc->profile->vid - || des.idProduct != devc->profile->pid) - continue; - - if (sdi->status == SR_ST_INITIALIZING) { - if (skip != sdi->index) { - /* Skip devices of this type that aren't the one we want. */ - skip += 1; - continue; - } - } else if (sdi->status == SR_ST_INACTIVE) { - /* - * This device is fully enumerated, so we need to find - * this device by vendor, product, bus and address. - */ - if (libusb_get_bus_number(devlist[i]) != usb->bus - || libusb_get_device_address(devlist[i]) != usb->address) - /* This is not the one. */ - continue; - } - - if (!(ret = libusb_open(devlist[i], &usb->devhdl))) { - if (usb->address == 0xff) - /* - * First time we touch this device after FW - * upload, so we don't know the address yet. - */ - usb->address = libusb_get_device_address(devlist[i]); - } else { - sr_err("Failed to open device: %s.", - libusb_error_name(ret)); - break; - } - - ret = command_get_fw_version(usb->devhdl, &vi); - if (ret != SR_OK) { - sr_err("Failed to get firmware version."); - break; - } - - ret = command_get_revid_version(usb->devhdl, &revid); - if (ret != SR_OK) { - sr_err("Failed to get REVID."); - break; - } - - /* - * Different versions may have incompatible issue, - * Mark for up level process - */ - if (vi.major != DSL_REQUIRED_VERSION_MAJOR || - vi.minor != DSL_REQUIRED_VERSION_MINOR) { - sr_err("Expected firmware version %d.%d, " - "got %d.%d.", DSL_REQUIRED_VERSION_MAJOR, DSL_REQUIRED_VERSION_MINOR, - vi.major, vi.minor); - sdi->status = SR_ST_INCOMPATIBLE; - } else { - sdi->status = SR_ST_ACTIVE; - } - - sr_info("Opened device %d on %d.%d, " - "interface %d, firmware %d.%d.", - sdi->index, usb->bus, usb->address, - USB_INTERFACE, vi.major, vi.minor); - - sr_info("Detected REVID=%d, it's a Cypress CY7C68013%s.", - revid, (revid != 1) ? " (FX2)" : "A (FX2LP)"); - - break; - } - libusb_free_device_list(devlist, 1); - - if ((sdi->status != SR_ST_ACTIVE) && - (sdi->status != SR_ST_INCOMPATIBLE)) - return SR_ERR; - - return SR_OK; -} - -static int configure_probes(const struct sr_dev_inst *sdi) -{ - struct DSL_context *devc; - struct sr_channel *probe; - GSList *l; - int probe_bit, stage, i; - char *tc; - - devc = sdi->priv; - for (i = 0; i < NUM_TRIGGER_STAGES; i++) { - devc->trigger_mask[i] = 0; - devc->trigger_value[i] = 0; - } - - stage = -1; - for (l = sdi->channels; l; l = l->next) { - probe = (struct sr_channel *)l->data; - if (probe->enabled == FALSE) - continue; - - if ((probe->index > 7 && probe->type == SR_CHANNEL_LOGIC) || - (probe->type == SR_CHANNEL_ANALOG || probe->type == SR_CHANNEL_DSO)) - devc->sample_wide = TRUE; - else - devc->sample_wide = FALSE; - - probe_bit = 1 << (probe->index); - if (!(probe->trigger)) - continue; - - stage = 0; - for (tc = probe->trigger; *tc; tc++) { - devc->trigger_mask[stage] |= probe_bit; - if (*tc == '1') - devc->trigger_value[stage] |= probe_bit; - stage++; - if (stage > NUM_TRIGGER_STAGES) - return SR_ERR; - } - } - - return SR_OK; -} - -static struct DSL_context *DSCope_dev_new(void) -{ - struct DSL_context *devc; - - if (!(devc = g_try_malloc(sizeof(struct DSL_context)))) { - sr_err("Device context malloc failed."); - return NULL; - } - - devc->profile = NULL; - devc->fw_updated = 0; - devc->cur_samplerate = DSCOPE_MAX_SAMPLERATE / MAX_DSO_PROBES_NUM; - devc->limit_samples = DSCOPE_MAX_DEPTH / MAX_DSO_PROBES_NUM; - devc->sample_wide = 0; - devc->clock_type = FALSE; - devc->clock_edge = FALSE; - devc->instant = FALSE; - devc->op_mode = SR_OP_BUFFER; - devc->th_level = SR_TH_3V3; - devc->filter = SR_FILTER_NONE; - devc->timebase = 10000; - devc->trigger_slope = DSO_TRIGGER_RISING; - devc->trigger_source = DSO_TRIGGER_AUTO; - devc->trigger_holdoff = 0; - devc->trigger_hpos = 0x0; - devc->trigger_hrate = 0; - devc->zero = FALSE; - devc->data_lock = FALSE; - devc->cali = FALSE; - devc->dso_bits = 8; - devc->trigger_margin = 8; - devc->trigger_channel = 0; - devc->rle_mode = FALSE; - - return devc; -} - -static int dev_clear(void) -{ - return std_dev_clear(di, NULL); -} - -static int init(struct sr_context *sr_ctx) -{ - return std_hw_init(sr_ctx, di, LOG_PREFIX); -} - - static struct DSL_vga* get_vga_ptr(const struct sr_dev_inst *sdi) { struct DSL_vga *vga_ptr = NULL; if (strcmp(sdi->model, "DSCope") == 0) vga_ptr = DSCope_vga; - else if (strcmp(sdi->model, "DSCope20") == 0) + else vga_ptr = DSCope20_vga; return vga_ptr; @@ -768,7 +187,7 @@ static uint16_t get_default_trans(const struct sr_dev_inst *sdi) uint16_t trans = 1; if (strcmp(sdi->model, "DSCope") == 0) trans = DSCOPE_DEFAULT_TRANS; - else if (strcmp(sdi->model, "DSCope20") == 0) + else trans = DSCOPE20_DEFAULT_TRANS; return trans; @@ -779,7 +198,7 @@ static uint16_t get_default_voff(const struct sr_dev_inst *sdi, int ch_index) uint16_t voff = 0; if (strcmp(sdi->model, "DSCope") == 0) { voff = DSCOPE_DEFAULT_VOFF; - } else if (strcmp(sdi->model, "DSCope20") == 0) { + } else { if (ch_index == 1) voff = CALI_VOFF_RANGE - DSCOPE20_DEFAULT_VOFF; else @@ -795,8 +214,7 @@ static uint64_t get_default_vgain(const struct sr_dev_inst *sdi, unsigned int nu if (strcmp(sdi->model, "DSCope") == 0) { assert(num < sizeof(DSCOPE_DEFAULT_VGAIN)); vgain = DSCOPE_DEFAULT_VGAIN[num]; - } - else if (strcmp(sdi->model, "DSCope20") == 0) { + } else { assert(num < sizeof(DSCOPE20_DEFAULT_VGAIN)); vgain = DSCOPE20_DEFAULT_VGAIN[num]; } @@ -824,7 +242,7 @@ static void probe_init(struct sr_dev_inst *sdi) } } -static int set_probes(struct sr_dev_inst *sdi, int num_probes) +static int setup_probes(struct sr_dev_inst *sdi, int num_probes) { uint16_t j; struct sr_channel *probe; @@ -863,6 +281,55 @@ static int adjust_probes(struct sr_dev_inst *sdi, int num_probes) return SR_OK; } +static struct DSL_context *DSCope_dev_new(void) +{ + struct DSL_context *devc; + + if (!(devc = g_try_malloc(sizeof(struct DSL_context)))) { + sr_err("Device context malloc failed."); + return NULL; + } + + devc->channel = NULL; + devc->profile = NULL; + devc->fw_updated = 0; + devc->cur_samplerate = DSCOPE_MAX_SAMPLERATE / MAX_DSO_PROBES_NUM; + devc->limit_samples = DSCOPE_MAX_DEPTH / MAX_DSO_PROBES_NUM; + devc->sample_wide = TRUE; + devc->clock_type = FALSE; + devc->clock_edge = FALSE; + devc->instant = FALSE; + devc->op_mode = SR_OP_BUFFER; + devc->th_level = SR_TH_3V3; + devc->filter = SR_FILTER_NONE; + devc->timebase = 10000; + devc->trigger_slope = DSO_TRIGGER_RISING; + devc->trigger_source = DSO_TRIGGER_AUTO; + devc->trigger_holdoff = 0; + devc->trigger_hpos = 0x0; + devc->trigger_hrate = 0; + devc->zero = FALSE; + devc->data_lock = FALSE; + devc->cali = FALSE; + devc->dso_bits = 8; + devc->trigger_margin = 8; + devc->trigger_channel = 0; + devc->rle_mode = FALSE; + devc->stream = FALSE; + + return devc; +} + +static int dev_clear(void) +{ + return std_dev_clear(di, NULL); +} + +static int init(struct sr_context *sr_ctx) +{ + return std_hw_init(sr_ctx, di, LOG_PREFIX); +} + static GSList *scan(GSList *options) { struct drv_context *drvc; @@ -937,7 +404,7 @@ static GSList *scan(GSList *options) sdi->driver = di; /* Fill in probelist according to this device's profile. */ - if (set_probes(sdi, 2) != SR_OK) + if (setup_probes(sdi, 2) != SR_OK) return NULL; devc = DSCope_dev_new(); @@ -946,7 +413,7 @@ static GSList *scan(GSList *options) drvc->instances = g_slist_append(drvc->instances, sdi); //devices = g_slist_append(devices, sdi); - if (check_conf_profile(devlist[i])) { + if (dsl_check_conf_profile(devlist[i])) { /* Already has the firmware, so fix the new address. */ sr_dbg("Found an DSCope device."); sdi->status = SR_ST_INACTIVE; @@ -956,9 +423,11 @@ static GSList *scan(GSList *options) /* only report device after firmware is ready */ devices = g_slist_append(devices, sdi); } else { - char *firmware = malloc(strlen(DS_RES_PATH)+strlen(prof->firmware)+1); - if (firmware == NULL) + char *firmware; + if (!(firmware = g_try_malloc(strlen(DS_RES_PATH)+strlen(prof->firmware)+1))) { + sr_err("Firmware path malloc error!"); return NULL; + } strcpy(firmware, DS_RES_PATH); strcat(firmware, prof->firmware); if (ezusb_upload_firmware(devlist[i], USB_CONFIGURATION, @@ -1039,17 +508,15 @@ static uint64_t dso_vpos(const struct sr_dev_inst *sdi, const struct sr_channel* vpos_fine = floor((voltage + vpos_coarse*trans_coarse)*DSCOPE_TRANS_FMULTI/trans_fine + 0.5); } //vpos = (vpos_coarse << 16) + vpos_fine; - } else if (strcmp(sdi->model, "DSCope20") == 0) { + } else { vpos = ((ch->vdiv*5.0) - voltage)/(ch->vdiv*10.0)*ch->vpos_trans; } const uint64_t voff = dso_voff(sdi, ch); if (strcmp(sdi->model, "DSCope") == 0) return ((vpos_coarse+DSCOPE_CONSTANT_BIAS+(voff>>10)) << 16)+vpos_fine+(voff&0x03ff); - else if (strcmp(sdi->model, "DSCope20") == 0) - return vpos+voff; else - return 0; + return vpos+voff; } static uint64_t dso_cmd_gen(const struct sr_dev_inst *sdi, struct sr_channel* ch, int id) @@ -1064,10 +531,10 @@ static uint64_t dso_cmd_gen(const struct sr_dev_inst *sdi, struct sr_channel* ch switch (id) { case SR_CONF_EN_CH: case SR_CONF_COUPLING: - if (devc->zero || en_ch_num(sdi) == 2) { + if (devc->zero || dsl_en_ch_num(sdi) == 2) { cmd += 0x0E00; //cmd += 0x000; - } else if (en_ch_num(sdi) == 1) { + } else if (dsl_en_ch_num(sdi) == 1) { if (((ch->index == 0) && ch->enabled) || ((ch->index == 1) && !ch->enabled)) cmd += 0x1600; else if (((ch->index == 1) && ch->enabled) || ((ch->index == 0) && !ch->enabled)) @@ -1097,7 +564,7 @@ static uint64_t dso_cmd_gen(const struct sr_dev_inst *sdi, struct sr_channel* ch break; case SR_CONF_SAMPLERATE: cmd += 0x18; - uint32_t divider = devc->zero ? 0x1 : (uint32_t)ceil(DSCOPE_MAX_SAMPLERATE * 1.0 / devc->cur_samplerate / en_ch_num(sdi)); + uint32_t divider = devc->zero ? 0x1 : (uint32_t)ceil(DSCOPE_MAX_SAMPLERATE * 1.0 / devc->cur_samplerate / dsl_en_ch_num(sdi)); cmd += divider << 8; break; case SR_CONF_HORIZ_TRIGGERPOS: @@ -1137,15 +604,83 @@ static uint64_t dso_cmd_gen(const struct sr_dev_inst *sdi, struct sr_channel* ch return cmd; } +static int dso_init(const struct sr_dev_inst *sdi) +{ + int ret; + GSList *l; + + for(l = sdi->channels; l; l = l->next) { + struct sr_channel *probe = (struct sr_channel *)l->data; + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_COUPLING)); + if (ret != SR_OK) { + sr_err("DSO set coupling of channel %d command failed!", probe->index); + return ret; + } + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_VDIV)); + if (ret != SR_OK) { + sr_err("Set VDIV of channel %d command failed!", probe->index); + return ret; + } + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_VPOS)); + if (ret != SR_OK) { + sr_err("Set VPOS of channel %d command failed!", probe->index); + return ret; + } + } + + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, 0, SR_CONF_SAMPLERATE)); + if (ret != SR_OK) { + sr_err("Set Sample Rate command failed!"); + return ret; + } + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, NULL, SR_CONF_HORIZ_TRIGGERPOS)); + if (ret != SR_OK) { + sr_err("Set Horiz Trigger Position command failed!"); + return ret; + } + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_HOLDOFF)); + if (ret != SR_OK) { + sr_err("Set Trigger Holdoff Time command failed!"); + return ret; + } + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_SLOPE)); + if (ret != SR_OK) { + sr_err("Set Trigger Slope command failed!"); + return ret; + } + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_SOURCE)); + if (ret != SR_OK) { + sr_err("Set Trigger Source command failed!"); + return ret; + } + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_VALUE)); + if (ret != SR_OK) { + sr_err("Set Trigger Value command failed!"); + return ret; + } + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_MARGIN)); + if (ret != SR_OK) { + sr_err("Set Trigger Margin command failed!"); + return ret; + } + return ret; +} + static gboolean dso_load_eep(struct sr_dev_inst *sdi, struct sr_channel *probe, gboolean fpga_done) { int ret, i; - struct sr_usb_dev_inst *usb = sdi->conn; + uint16_t real_zero_addr; + struct cmd_zero_info zero_info; uint8_t dst_addr = (zero_base_addr + probe->index * (sizeof(struct cmd_zero_info) + sizeof(struct cmd_vga_info))); zero_info.zero_addr = dst_addr; - if ((ret = command_rd_nvm(usb->devhdl, (unsigned char *)&zero_info, zero_info.zero_addr, sizeof(struct cmd_zero_info))) != SR_OK) { + if (strcmp(sdi->model, "DSCope20") == 0 || + strcmp(sdi->model, "DSCope") == 0) + real_zero_addr = zero_info.zero_addr; + else + real_zero_addr = (zero_big_addr << 8) + zero_info.zero_addr; + if ((ret = dsl_rd_nvm(sdi, (unsigned char *)&zero_info, real_zero_addr, sizeof(struct cmd_zero_info))) != SR_OK) { return FALSE; sr_err("%s: Send Get Zero command failed!", __func__); } else { @@ -1165,11 +700,11 @@ static gboolean dso_load_eep(struct sr_dev_inst *sdi, struct sr_channel *probe, if (!fpga_done) { const double slope = (probe->comb_diff_bom - probe->comb_diff_top)/(2.0*255.0); for (i = 0; i < 256; i++) { - ret = command_wr_reg(usb->devhdl, i, COMB_ADDR + probe->index*2); + ret = dsl_wr_reg(sdi, COMB_ADDR + probe->index*2, i); int value = i+i*slope+probe->comb_diff_top*0.5+0.5; value = (value < 0) ? 0 : (value > 255) ? 255 : value; - ret = command_wr_reg(usb->devhdl, value, COMB_ADDR + probe->index*2 + 1); + ret = dsl_wr_reg(sdi, COMB_ADDR + probe->index*2 + 1, value); } } } @@ -1180,7 +715,12 @@ static gboolean dso_load_eep(struct sr_dev_inst *sdi, struct sr_channel *probe, struct cmd_vga_info vga_info; vga_info.vga_addr = dst_addr + sizeof(struct cmd_zero_info); - if ((ret = command_rd_nvm(usb->devhdl, (unsigned char *)&vga_info, vga_info.vga_addr, sizeof(struct cmd_vga_info))) != SR_OK) { + if (strcmp(sdi->model, "DSCope20") == 0 || + strcmp(sdi->model, "DSCope") == 0) + real_zero_addr = vga_info.vga_addr; + else + real_zero_addr = (zero_big_addr << 8) + vga_info.vga_addr; + if ((ret = dsl_rd_nvm(sdi, (unsigned char *)&vga_info, real_zero_addr, sizeof(struct cmd_vga_info))) != SR_OK) { return FALSE; sr_err("%s: Send Get Zero command failed!", __func__); } else { @@ -1206,264 +746,99 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, const struct sr_channel_group *cg) { struct DSL_context *devc; - struct sr_usb_dev_inst *usb; - char str[128]; unsigned int i; struct DSL_vga *vga_ptr; - uint8_t tmp_u8; int ret; - (void)cg; - - switch (id) { - case SR_CONF_CONN: - if (!sdi || !sdi->conn) - return SR_ERR_ARG; - usb = sdi->conn; - if (usb->address == 255) - /* Device still needs to re-enumerate after firmware - * upload, so we don't know its (future) address. */ - return SR_ERR; - snprintf(str, 128, "%d.%d", usb->bus, usb->address); - *data = g_variant_new_string(str); - break; - case SR_CONF_LIMIT_SAMPLES: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_uint64(devc->limit_samples); - break; - case SR_CONF_SAMPLERATE: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_uint64(devc->cur_samplerate); - break; - case SR_CONF_CLOCK_TYPE: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_boolean(devc->clock_type); - break; - case SR_CONF_CLOCK_EDGE: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_boolean(devc->clock_edge); - break; - case SR_CONF_INSTANT: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_boolean(devc->instant); - break; - case SR_CONF_OPERATION_MODE: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_string(opmodes[devc->op_mode]); - break; - case SR_CONF_FILTER: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_string(filters[devc->filter]); - break; - case SR_CONF_THRESHOLD: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_string(thresholds[devc->th_level]); - break; - case SR_CONF_VDIV: - if (!ch) - 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; - *data = g_variant_new_double(ch->vpos); - break; - case SR_CONF_TIMEBASE: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_uint64(devc->timebase); - break; - case SR_CONF_COUPLING: - if (!ch) - return SR_ERR; - *data = g_variant_new_byte(ch->coupling); - break; - case SR_CONF_EN_CH: - if (!ch) - return SR_ERR; - *data = g_variant_new_boolean(ch->enabled); - break; - case SR_CONF_DATALOCK: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_boolean(devc->data_lock); - break; - case SR_CONF_TRIGGER_SLOPE: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_byte(devc->trigger_slope); - break; - case SR_CONF_TRIGGER_SOURCE: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_byte(devc->trigger_source&0x0f); - break; - case SR_CONF_TRIGGER_CHANNEL: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_byte(devc->trigger_source>>4); - break; - case SR_CONF_TRIGGER_VALUE: - if (!ch) - return SR_ERR; - *data = g_variant_new_byte(ch->trig_value); - break; - case SR_CONF_HORIZ_TRIGGERPOS: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - if (sdi->mode == DSO) { - *data = g_variant_new_byte(devc->trigger_hrate); - } else { - *data = g_variant_new_byte(devc->trigger_hpos); - } - break; - case SR_CONF_TRIGGER_HOLDOFF: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_uint64(devc->trigger_holdoff); - break; - case SR_CONF_TRIGGER_MARGIN: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_byte(devc->trigger_margin); - break; - case SR_CONF_ZERO: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_boolean(devc->zero); - break; - case SR_CONF_CALI: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_boolean(devc->cali); - break; - case SR_CONF_ROLL: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_boolean(devc->roll); - break; - case SR_CONF_TEST: - if (!sdi) - return SR_ERR; - *data = g_variant_new_boolean(FALSE); - break; - case SR_CONF_MAX_DSO_SAMPLERATE: - if (!sdi) - return SR_ERR; - *data = g_variant_new_uint64(DSCOPE_MAX_SAMPLERATE); - break; - case SR_CONF_MAX_DSO_SAMPLELIMITS: - if (!sdi) - return SR_ERR; - *data = g_variant_new_uint64(DSCOPE_MAX_DEPTH); - break; - case SR_CONF_HW_DEPTH: - if (!sdi) - return SR_ERR; - *data = g_variant_new_uint64(DSCOPE_INSTANT_DEPTH); - break; - case SR_CONF_VGAIN: - if (!sdi || !ch) - return SR_ERR; - *data = g_variant_new_uint64(dso_vga(sdi, ch)>>8); - break; - case SR_CONF_VGAIN_DEFAULT: - if (!sdi || !ch) - return SR_ERR; - vga_ptr = get_vga_ptr(sdi); - for (i = 0; vga_ptr && (vga_ptr+i)->key; i++) { - if ((vga_ptr+i)->key == ch->vdiv) - break; + ret = dsl_config_get(id, data, sdi, ch, cg); + if (ret != SR_OK) { + switch (id) { + case SR_CONF_OPERATION_MODE: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_string(opmodes[devc->op_mode]); + break; + case SR_CONF_CALI: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_boolean(devc->cali); + break; + case SR_CONF_TEST: + if (!sdi) + return SR_ERR; + *data = g_variant_new_boolean(FALSE); + break; + case SR_CONF_MAX_DSO_SAMPLERATE: + if (!sdi) + return SR_ERR; + *data = g_variant_new_uint64(DSCOPE_MAX_SAMPLERATE); + break; + case SR_CONF_MAX_DSO_SAMPLELIMITS: + if (!sdi) + return SR_ERR; + *data = g_variant_new_uint64(DSCOPE_MAX_DEPTH); + break; + case SR_CONF_HW_DEPTH: + if (!sdi) + return SR_ERR; + *data = g_variant_new_uint64(DSCOPE_INSTANT_DEPTH); + break; + case SR_CONF_VGAIN: + if (!sdi || !ch) + return SR_ERR; + *data = g_variant_new_uint64(dso_vga(sdi, ch)>>8); + break; + case SR_CONF_VGAIN_DEFAULT: + if (!sdi || !ch) + return SR_ERR; + vga_ptr = get_vga_ptr(sdi); + for (i = 0; vga_ptr && (vga_ptr+i)->key; i++) { + if ((vga_ptr+i)->key == ch->vdiv) + break; + } + *data = g_variant_new_uint64(get_default_vgain(sdi, i)>>8); + break; + case SR_CONF_VGAIN_RANGE: + if (!sdi) + return SR_ERR; + vga_ptr = get_vga_ptr(sdi); + for (i = 0; vga_ptr && (vga_ptr+i)->key; i++) { + if ((vga_ptr+i)->key == ch->vdiv) + break; + } + uint16_t vgain_default= (get_default_vgain(sdi, i)>>8) & 0x0FFF; + *data = g_variant_new_uint16(min(CALI_VGAIN_RANGE, vgain_default*2)); + break; + case SR_CONF_VOFF: + if (!sdi || !ch) + return SR_ERR; + uint16_t voff = dso_voff(sdi, ch); + uint16_t voff_default = get_default_voff(sdi, ch->index); + if (strcmp(sdi->model, "DSCope") == 0) { + int voff_skew_coarse = (voff >> 10) - (voff_default >> 10); + int voff_skew_fine = (voff & 0x03ff) - (voff_default & 0x03ff); + double trans_coarse = (ch->vdiv < 500) ? (ch->vpos_trans >> 8)/DSCOPE_TRANS_CMULTI : (ch->vpos_trans >> 8); + double trans_fine = (ch->vdiv < 500) ? (ch->vpos_trans & 0x00ff) / 1000.0 : (ch->vpos_trans & 0x00ff) / DSCOPE_TRANS_FMULTI; + double voff_rate = (voff_skew_coarse*trans_coarse - voff_skew_fine*trans_fine) / ch->vdiv; + voff = (voff_rate * 0.5 + 0.5) * CALI_VOFF_RANGE; + } + *data = g_variant_new_uint16(voff); + break; + case SR_CONF_VOFF_DEFAULT: + if (!sdi || !ch) + return SR_ERR; + *data = g_variant_new_uint16(get_default_voff(sdi, ch->index)); + break; + case SR_CONF_VOFF_RANGE: + if (!sdi) + return SR_ERR; + *data = g_variant_new_uint16(CALI_VOFF_RANGE); + break; + default: + return SR_ERR_NA; } - *data = g_variant_new_uint64(get_default_vgain(sdi, i)>>8); - break; - case SR_CONF_VGAIN_RANGE: - if (!sdi) - return SR_ERR; - vga_ptr = get_vga_ptr(sdi); - for (i = 0; vga_ptr && (vga_ptr+i)->key; i++) { - if ((vga_ptr+i)->key == ch->vdiv) - break; - } - uint16_t vgain_default= (get_default_vgain(sdi, i)>>8) & 0x0FFF; - *data = g_variant_new_uint16(min(CALI_VGAIN_RANGE, vgain_default*2)); - break; - case SR_CONF_VOFF: - if (!sdi || !ch) - return SR_ERR; - uint16_t voff = dso_voff(sdi, ch); - uint16_t voff_default = get_default_voff(sdi, ch->index); - if (strcmp(sdi->model, "DSCope") == 0) { - int voff_skew_coarse = (voff >> 10) - (voff_default >> 10); - int voff_skew_fine = (voff & 0x03ff) - (voff_default & 0x03ff); - double trans_coarse = (ch->vdiv < 500) ? (ch->vpos_trans >> 8)/DSCOPE_TRANS_CMULTI : (ch->vpos_trans >> 8); - double trans_fine = (ch->vdiv < 500) ? (ch->vpos_trans & 0x00ff) / 1000.0 : (ch->vpos_trans & 0x00ff) / DSCOPE_TRANS_FMULTI; - double voff_rate = (voff_skew_coarse*trans_coarse - voff_skew_fine*trans_fine) / ch->vdiv; - voff = (voff_rate * 0.5 + 0.5) * CALI_VOFF_RANGE; - } - *data = g_variant_new_uint16(voff); - break; - case SR_CONF_VOFF_DEFAULT: - if (!sdi || !ch) - return SR_ERR; - *data = g_variant_new_uint16(get_default_voff(sdi, ch->index)); - break; - case SR_CONF_VOFF_RANGE: - if (!sdi) - return SR_ERR; - *data = g_variant_new_uint16(CALI_VOFF_RANGE); - break; - case SR_CONF_DSO_BITS: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_byte(devc->dso_bits); - break; - case SR_CONF_HW_STATUS: - if (!sdi) - return SR_ERR; - usb = sdi->conn; - ret = command_get_hw_info(usb->devhdl, &tmp_u8); - if (ret == SR_OK) - *data = g_variant_new_byte(tmp_u8); - else - *data = g_variant_new_byte(0); - break; - default: - return SR_ERR_NA; } return SR_OK; @@ -1476,7 +851,6 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, struct DSL_context *devc; const char *stropt; int ret, num_probes; - struct sr_usb_dev_inst *usb; struct drv_context *drvc; (void)cg; @@ -1485,11 +859,113 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, return SR_ERR; drvc = di->priv; - devc = sdi->priv; - usb = sdi->conn; + devc = sdi->priv; ret = SR_OK; - if (id == SR_CONF_SAMPLERATE) { + + if (id == SR_CONF_CLOCK_TYPE) { + devc->clock_type = g_variant_get_boolean(data); + } else if (id == SR_CONF_CLOCK_EDGE) { + devc->clock_edge = g_variant_get_boolean(data); + } else if (id == SR_CONF_LIMIT_SAMPLES) { + devc->limit_samples = g_variant_get_uint64(data); + } else if (id == SR_CONF_DATALOCK) { + while(libusb_try_lock_events(drvc->sr_ctx->libusb_ctx)); + devc->data_lock = g_variant_get_boolean(data); + libusb_unlock_events(drvc->sr_ctx->libusb_ctx); + } else if (id == SR_CONF_VDIV) { + ch->vdiv = g_variant_get_uint64(data); + if (sdi->mode == DSO) { + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, ch, SR_CONF_VDIV)); + } + if (ret == SR_OK) + sr_dbg("%s: setting VDIV of channel %d to %d mv", + __func__, ch->index, ch->vdiv); + 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); + sr_dbg("%s: setting Factor of channel %d to %d", __func__, + ch->index, ch->vfactor); + } else if (id == SR_CONF_TIMEBASE) { + devc->timebase = g_variant_get_uint64(data); + } else if (id == SR_CONF_COUPLING) { + ch->coupling = g_variant_get_byte(data); + if (ch->coupling == SR_GND_COUPLING) + ch->coupling = SR_DC_COUPLING; + if (sdi->mode == DSO) { + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, ch, SR_CONF_COUPLING)); + } + if (ret == SR_OK) + sr_dbg("%s: setting AC COUPLING of channel %d to %d", + __func__, ch->index, ch->coupling); + else + sr_dbg("%s: setting AC COUPLING of channel %d to %d failed", + __func__, ch->index, ch->coupling); + } else if (id == SR_CONF_TRIGGER_SLOPE) { + devc->trigger_slope = g_variant_get_byte(data); + if (sdi->mode == DSO) { + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_SLOPE)); + } + if (ret == SR_OK) + sr_dbg("%s: setting DSO Trigger Slope to %d", + __func__, devc->trigger_slope); + else + sr_dbg("%s: setting DSO Trigger Slope to %d failed", + __func__, devc->trigger_slope); + } else if (id == SR_CONF_TRIGGER_VALUE) { + ch->trig_value = g_variant_get_byte(data); + if (sdi->mode == DSO) { + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, ch, SR_CONF_TRIGGER_VALUE)); + } + if (ret == SR_OK) + sr_dbg("%s: setting channel %d Trigger Value to %d", + __func__, ch->index, ch->trig_value); + else + sr_dbg("%s: setting DSO Trigger Value to %d failed", + __func__, ch->index, ch->trig_value); + } else if (id == SR_CONF_HORIZ_TRIGGERPOS) { + if (sdi->mode == DSO) { + devc->trigger_hrate = g_variant_get_byte(data); + //devc->trigger_hpos = devc->trigger_hrate * dsl_en_ch_num(sdi) * devc->limit_samples / 200.0; + /* + * devc->trigger_hpos should be updated before each acquisition + * because the samplelimits may changed + */ + devc->trigger_hpos = devc->trigger_hrate * dsl_en_ch_num(sdi) * devc->limit_samples / 200.0; + if ((ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, NULL, SR_CONF_HORIZ_TRIGGERPOS))) == SR_OK) + sr_dbg("%s: setting DSO Horiz Trigger Position to %d", + __func__, devc->trigger_hpos); + else + sr_dbg("%s: setting DSO Horiz Trigger Position to %d failed", + __func__, devc->trigger_hpos); + } else { + devc->trigger_hpos = g_variant_get_byte(data) * devc->limit_samples / 100.0; + } + } else if (id == SR_CONF_TRIGGER_HOLDOFF) { + devc->trigger_holdoff = g_variant_get_uint64(data); + if (sdi->mode == DSO) { + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_HOLDOFF)); + } + if (ret == SR_OK) + sr_dbg("%s: setting Trigger Holdoff Time to %d", + __func__, devc->trigger_holdoff); + else + sr_dbg("%s: setting Trigger Holdoff Time to %d failed", + __func__, devc->trigger_holdoff); + } else if (id == SR_CONF_TRIGGER_MARGIN) { + devc->trigger_margin = g_variant_get_byte(data); + if (sdi->mode == DSO) { + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_MARGIN)); + } + if (ret == SR_OK) + sr_dbg("%s: setting Trigger Margin to %d", + __func__, devc->trigger_margin); + else + sr_dbg("%s: setting Trigger Margin to %d failed", + __func__, devc->trigger_margin); + } else if (id == SR_CONF_SAMPLERATE) { devc->cur_samplerate = g_variant_get_uint64(data); if (sdi->mode == LOGIC) { if (devc->cur_samplerate >= SR_MHZ(200)) { @@ -1498,22 +974,16 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, adjust_probes(sdi, 16); } } else if(sdi->mode == DSO) { - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, 0, SR_CONF_SAMPLERATE)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, 0, SR_CONF_SAMPLERATE)); } - } else if (id == SR_CONF_CLOCK_TYPE) { - devc->clock_type = g_variant_get_boolean(data); - } else if (id == SR_CONF_CLOCK_EDGE) { - devc->clock_edge = g_variant_get_boolean(data); } else if (id == SR_CONF_INSTANT) { devc->instant = g_variant_get_boolean(data); - if (en_ch_num(sdi) != 0) { + if (dsl_en_ch_num(sdi) != 0) { if (devc->instant) - devc->limit_samples = DSCOPE_INSTANT_DEPTH / en_ch_num(sdi); + devc->limit_samples = DSCOPE_INSTANT_DEPTH / dsl_en_ch_num(sdi); else - devc->limit_samples = DSCOPE_MAX_DEPTH / en_ch_num(sdi); + devc->limit_samples = DSCOPE_MAX_DEPTH / dsl_en_ch_num(sdi); } - } else if (id == SR_CONF_LIMIT_SAMPLES) { - devc->limit_samples = g_variant_get_uint64(data); } else if (id == SR_CONF_DEVICE_MODE) { sdi->mode = g_variant_get_int16(data); if (sdi->mode == LOGIC) { @@ -1521,10 +991,10 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, } else if (sdi->mode == DSO) { sdi->mode = DSO; num_probes = devc->profile->dev_caps & DEV_CAPS_16BIT ? MAX_DSO_PROBES_NUM : 1; - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, NULL, SR_CONF_DSO_SYNC)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, NULL, SR_CONF_DSO_SYNC)); if (ret != SR_OK) sr_dbg("%s: DSO configuration sync failed", __func__); - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, sdi->channels->data, SR_CONF_VDIV)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, sdi->channels->data, SR_CONF_VDIV)); if (ret == SR_OK) sr_dbg("%s: Initial setting for DSO mode", __func__); else @@ -1535,7 +1005,7 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, num_probes = devc->profile->dev_caps & DEV_CAPS_16BIT ? MAX_ANALOG_PROBES_NUM : 1; } sr_dev_probes_free(sdi); - set_probes(sdi, num_probes); + setup_probes(sdi, num_probes); sr_dbg("%s: setting mode to %d", __func__, sdi->mode); } else if (id == SR_CONF_OPERATION_MODE) { stropt = g_variant_get_string(data, NULL); @@ -1548,53 +1018,13 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, } sr_dbg("%s: setting pattern to %d", __func__, devc->op_mode); - } else if (id == SR_CONF_THRESHOLD) { - stropt = g_variant_get_string(data, NULL); - if (!strcmp(stropt, thresholds[SR_TH_3V3])) { - devc->th_level = SR_TH_3V3; - } else if (!strcmp(stropt, thresholds[SR_TH_5V0])) { - devc->th_level = SR_TH_5V0; - } else { - ret = SR_ERR; - } - 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 filename[256]; - //sprintf(filename,"%s%s",DS_RES_PATH,devc->profile->fpga_bit33); - //const char *fpga_bit = filename; - char *fpga_bit = malloc(strlen(DS_RES_PATH)+strlen(devc->profile->fpga_bit33)+1); - if (fpga_bit == NULL) - return SR_ERR_MALLOC; - strcpy(fpga_bit, DS_RES_PATH); - strcat(fpga_bit, devc->profile->fpga_bit33); - ret = fpga_config(usb->devhdl, fpga_bit); - if (ret != SR_OK) { - sr_err("Configure FPGA failed!"); - } - } - sr_dbg("%s: setting threshold to %d", - __func__, devc->th_level); - } else if (id == SR_CONF_FILTER) { - stropt = g_variant_get_string(data, NULL); - if (!strcmp(stropt, filters[SR_FILTER_NONE])) { - devc->filter = SR_FILTER_NONE; - } else if (!strcmp(stropt, filters[SR_FILTER_1T])) { - devc->filter = SR_FILTER_1T; - } else { - ret = SR_ERR; - } - sr_dbg("%s: setting threshold to %d", - __func__, devc->th_level); } else if (id == SR_CONF_EN_CH) { ch->enabled = g_variant_get_boolean(data); if (sdi->mode == DSO) { - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, ch, SR_CONF_EN_CH)); - if (en_ch_num(sdi) != 0) { - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, 0, SR_CONF_SAMPLERATE)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, ch, SR_CONF_EN_CH)); + if (dsl_en_ch_num(sdi) != 0) { + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, 0, SR_CONF_SAMPLERATE)); } } if (ret == SR_OK) @@ -1603,27 +1033,10 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, else sr_dbg("%s: setting ENABLE of channel %d to %d failed", __func__, ch->index, ch->enabled); - } else if (id == SR_CONF_DATALOCK) { - while(libusb_try_lock_events(drvc->sr_ctx->libusb_ctx)); - devc->data_lock = g_variant_get_boolean(data); - libusb_unlock_events(drvc->sr_ctx->libusb_ctx); - } else if (id == SR_CONF_VDIV) { - ch->vdiv = g_variant_get_uint64(data); - if (sdi->mode == DSO) { - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, ch, SR_CONF_VDIV)); - } - if (ret == SR_OK) - sr_dbg("%s: setting VDIV of channel %d to %d mv", - __func__, ch->index, ch->vdiv); - 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) { - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, ch, SR_CONF_VPOS)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, ch, SR_CONF_VPOS)); } if (ret == SR_OK) sr_dbg("%s: setting VPOS of channel %d to %lf mv", @@ -1631,33 +1044,9 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, else sr_dbg("%s: setting VPOS of channel %d to %lf mv failed", __func__, ch->index, ch->vpos); - } else if (id == SR_CONF_TIMEBASE) { - devc->timebase = g_variant_get_uint64(data); - } else if (id == SR_CONF_COUPLING) { - ch->coupling = g_variant_get_byte(data); - if (sdi->mode == DSO) { - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, ch, SR_CONF_COUPLING)); - } - if (ret == SR_OK) - sr_dbg("%s: setting AC COUPLING of channel %d to %d", - __func__, ch->index, ch->coupling); - else - sr_dbg("%s: setting AC COUPLING of channel %d to %d failed", - __func__, ch->index, ch->coupling); - } else if (id == SR_CONF_TRIGGER_SLOPE) { - devc->trigger_slope = g_variant_get_byte(data); - if (sdi->mode == DSO) { - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_SLOPE)); - } - if (ret == SR_OK) - sr_dbg("%s: setting DSO Trigger Slope to %d", - __func__, devc->trigger_slope); - else - sr_dbg("%s: setting DSO Trigger Slope to %d failed", - __func__, devc->trigger_slope); } else if (id == SR_CONF_TRIGGER_SOURCE) { devc->trigger_source = (devc->trigger_source & 0xf0) + (g_variant_get_byte(data) & 0x0f); - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_SOURCE)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_SOURCE)); if (ret == SR_OK) sr_dbg("%s: setting DSO Trigger Source to %d", __func__, devc->trigger_source); @@ -1666,60 +1055,13 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, __func__, devc->trigger_source); } else if (id == SR_CONF_TRIGGER_CHANNEL) { devc->trigger_source = (g_variant_get_byte(data) << 4) + (devc->trigger_source & 0x0f); - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_SOURCE)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_SOURCE)); if (ret == SR_OK) sr_dbg("%s: setting DSO Trigger Source to %d", __func__, devc->trigger_source); else sr_dbg("%s: setting DSO Trigger Source to %d failed", __func__, devc->trigger_source); - } else if (id == SR_CONF_TRIGGER_VALUE) { - ch->trig_value = g_variant_get_byte(data); - if (sdi->mode == DSO) { - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, ch, SR_CONF_TRIGGER_VALUE)); - } - if (ret == SR_OK) - sr_dbg("%s: setting channel %d Trigger Value to %d", - __func__, ch->index, ch->trig_value); - else - sr_dbg("%s: setting DSO Trigger Value to %d failed", - __func__, ch->index, ch->trig_value); - } else if (id == SR_CONF_HORIZ_TRIGGERPOS) { - devc->trigger_hrate = g_variant_get_byte(data); - //devc->trigger_hpos = devc->trigger_hrate * en_ch_num(sdi) * devc->limit_samples / 200.0; - /* - * devc->trigger_hpos should be updated before each acquisition - * because the samplelimits may changed - */ - devc->trigger_hpos = devc->trigger_hrate * en_ch_num(sdi) * devc->limit_samples / 200.0; - if ((ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, NULL, SR_CONF_HORIZ_TRIGGERPOS))) == SR_OK) - sr_dbg("%s: setting DSO Horiz Trigger Position to %d", - __func__, devc->trigger_hpos); - else - sr_dbg("%s: setting DSO Horiz Trigger Position to %d failed", - __func__, devc->trigger_hpos); - } else if (id == SR_CONF_TRIGGER_HOLDOFF) { - devc->trigger_holdoff = g_variant_get_uint64(data); - if (sdi->mode == DSO) { - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_HOLDOFF)); - } - if (ret == SR_OK) - sr_dbg("%s: setting Trigger Holdoff Time to %d", - __func__, devc->trigger_holdoff); - else - sr_dbg("%s: setting Trigger Holdoff Time to %d failed", - __func__, devc->trigger_holdoff); - } else if (id == SR_CONF_TRIGGER_MARGIN) { - devc->trigger_margin = g_variant_get_byte(data); - if (sdi->mode == DSO) { - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_MARGIN)); - } - if (ret == SR_OK) - sr_dbg("%s: setting Trigger Margin to %d", - __func__, devc->trigger_margin); - else - sr_dbg("%s: setting Trigger Margin to %d failed", - __func__, devc->trigger_margin); } else if (id == SR_CONF_ZERO) { devc->zero = g_variant_get_boolean(data); if (devc->zero) { @@ -1761,6 +1103,7 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, zero_info.zero_addr = zero_base_addr + probe->index * (sizeof(struct cmd_zero_info) + sizeof(struct cmd_vga_info)); int i; + uint16_t real_zero_addr; struct DSL_vga *vga_ptr = get_vga_ptr(sdi); uint8_t *voff_ptr = &zero_info.zero_addr + 1; for (i = 0; vga_ptr && (vga_ptr+i)->key; i++) { @@ -1778,29 +1121,41 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, for (i=0; vga_ptr && (vga_ptr+i)->key; i++){ *(vgain_ptr+i) = ((probe->index == 0) ? (vga_ptr+i)->vgain0 : (vga_ptr+i)->vgain1) >> 8; } - ret = command_wr_reg(usb->devhdl, bmEEWP, EEWP_ADDR); + ret = dsl_wr_reg(sdi, EEWP_ADDR, bmEEWP); + if (ret == SR_OK) { + if (strcmp(sdi->model, "DSCope20") == 0 || + strcmp(sdi->model, "DSCope") == 0) + real_zero_addr = zero_info.zero_addr; + else + real_zero_addr = (zero_big_addr << 8) + zero_info.zero_addr; + ret = dsl_wr_nvm(sdi, (unsigned char *)&zero_info, real_zero_addr, sizeof(struct cmd_zero_info)); + } + if (ret == SR_OK) { + if (strcmp(sdi->model, "DSCope20") == 0 || + strcmp(sdi->model, "DSCope") == 0) + real_zero_addr = vga_info.vga_addr; + else + real_zero_addr = (zero_big_addr << 8) + vga_info.vga_addr; + ret = dsl_wr_nvm(sdi, (unsigned char *)&vga_info, real_zero_addr, sizeof(struct cmd_vga_info)); + } if (ret == SR_OK) - ret = command_wr_nvm(usb->devhdl, (unsigned char *)&zero_info, sizeof(struct cmd_zero_info)); - if (ret == SR_OK) - ret = command_wr_nvm(usb->devhdl, (unsigned char *)&vga_info, sizeof(struct cmd_vga_info)); - if (ret == SR_OK) - ret = command_wr_reg(usb->devhdl, bmZERO, EEWP_ADDR); + ret = dsl_wr_reg(sdi, EEWP_ADDR, bmZERO); if (ret != SR_OK) sr_err("DSO channel %d Set Zero command failed!", probe->index); const double slope = (probe->comb_diff_bom - probe->comb_diff_top)/(2.0*255.0); for (i = 0; i < 256; i++) { - ret = command_wr_reg(usb->devhdl, i, COMB_ADDR + probe->index*2); + ret = dsl_wr_reg(sdi, COMB_ADDR + probe->index*2, i); int value = i+i*slope+probe->comb_diff_top*0.5+0.5; value = (value < 0) ? 0 : (value > 255) ? 255 : value; - ret = command_wr_reg(usb->devhdl, value, COMB_ADDR + probe->index*2 + 1); + ret = dsl_wr_reg(sdi, COMB_ADDR + probe->index*2 + 1, value); } } } } else if (id == SR_CONF_VOCM) { const uint8_t vocm = g_variant_get_byte(data); - ret = command_wr_reg(usb->devhdl, vocm, COMB_ADDR+4); + ret = dsl_wr_reg(sdi, COMB_ADDR+4, vocm); } else if (id == SR_CONF_VGAIN) { const uint64_t vgain = g_variant_get_uint64(data) << 8; int i; @@ -1813,7 +1168,7 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, (vga_ptr+i)->vgain1 = vgain; } } - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, ch, SR_CONF_VDIV)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, ch, SR_CONF_VDIV)); if (ret == SR_OK) sr_dbg("%s: setting VDIV of channel %d to %d mv", __func__, ch->index, ch->vdiv); @@ -1844,18 +1199,18 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, (vga_ptr+i)->voff1 = voff; } } - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, ch, SR_CONF_VPOS)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, ch, SR_CONF_VPOS)); if (ret == SR_OK) sr_dbg("%s: setting VPOS of channel %d to %lf mv", __func__, ch->index, ch->vpos); else sr_dbg("%s: setting VPOS of channel %d to %lf mv failed", __func__, ch->index, ch->vpos); - }else { + } else { ret = SR_ERR_NA; - } + } - return ret; + return ret; } static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi, @@ -1915,9 +1270,6 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi, case SR_CONF_THRESHOLD: *data = g_variant_new_strv(thresholds, ARRAY_SIZE(thresholds)); break; - case SR_CONF_FILTER: - *data = g_variant_new_strv(filters, ARRAY_SIZE(filters)); - break; default: return SR_ERR_NA; } @@ -1925,73 +1277,9 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi, return SR_OK; } -static int dso_init(const struct sr_dev_inst *sdi) -{ - int ret; - GSList *l; - struct sr_usb_dev_inst *usb = sdi->conn; - - for(l = sdi->channels; l; l = l->next) { - struct sr_channel *probe = (struct sr_channel *)l->data; - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, probe, SR_CONF_COUPLING)); - if (ret != SR_OK) { - sr_err("DSO set coupling of channel %d command failed!", probe->index); - return ret; - } - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, probe, SR_CONF_VDIV)); - if (ret != SR_OK) { - sr_err("Set VDIV of channel %d command failed!", probe->index); - return ret; - } - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, probe, SR_CONF_VPOS)); - if (ret != SR_OK) { - sr_err("Set VPOS of channel %d command failed!", probe->index); - return ret; - } - } - - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, 0, SR_CONF_SAMPLERATE)); - if (ret != SR_OK) { - sr_err("Set Sample Rate command failed!"); - return ret; - } - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, NULL, SR_CONF_HORIZ_TRIGGERPOS)); - if (ret != SR_OK) { - sr_err("Set Horiz Trigger Position command failed!"); - return ret; - } - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_HOLDOFF)); - if (ret != SR_OK) { - sr_err("Set Trigger Holdoff Time command failed!"); - return ret; - } - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_SLOPE)); - if (ret != SR_OK) { - sr_err("Set Trigger Slope command failed!"); - return ret; - } - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_SOURCE)); - if (ret != SR_OK) { - sr_err("Set Trigger Source command failed!"); - return ret; - } - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_VALUE)); - if (ret != SR_OK) { - sr_err("Set Trigger Value command failed!"); - return ret; - } - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_MARGIN)); - if (ret != SR_OK) { - sr_err("Set Trigger Margin command failed!"); - return ret; - } - return ret; -} - -static int dso_zero(const struct sr_dev_inst *sdi, struct sr_status mstatus) +static int dso_zero(const struct sr_dev_inst *sdi) { struct DSL_context *devc = sdi->priv; - struct sr_usb_dev_inst *usb = sdi->conn; GSList *l; int ret; static double vpos_back[2]; @@ -2012,21 +1300,21 @@ static int dso_zero(const struct sr_dev_inst *sdi, struct sr_status mstatus) devc->zero_stage = 0; } else if ((vga_ptr+devc->zero_stage)->key == 0) { ret = SR_OK; - if (strcmp(sdi->model, "DSCope20") == 0) { + if (strcmp(sdi->model, "DSCope") != 0) { if (devc->zero_pcnt == 0) { devc->zero_comb = 0; vpos_back[0] = probe0->vpos; probe0->vpos = (vga_ptr+devc->zero_stage-1)->key * -4.8; vdiv_back[0] = probe0->vdiv; probe0->vdiv = (vga_ptr+devc->zero_stage-1)->key; - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, probe0, SR_CONF_VPOS)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe0, SR_CONF_VPOS)); } else if (devc->zero_pcnt == 4) { - const double voff = 255*0.98 - (mstatus.ch0_max + mstatus.ch0_min) / 2.0; + const double voff = 255*0.98 - (devc->mstatus.ch0_max + devc->mstatus.ch0_min) / 2.0; if (abs(voff) < 0.5) { probe0->vpos = vpos_back[0]; } else { probe0->vpos_trans += voff; - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, probe0, SR_CONF_VPOS)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe0, SR_CONF_VPOS)); devc->zero_pcnt = 1; } } else if (devc->zero_pcnt == 5) { @@ -2035,61 +1323,61 @@ static int dso_zero(const struct sr_dev_inst *sdi, struct sr_status mstatus) probe1->vpos = (vga_ptr+devc->zero_stage-1)->key * -4.8; vdiv_back[1] = probe1->vdiv; probe1->vdiv = (vga_ptr+devc->zero_stage-1)->key; - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, probe1, SR_CONF_VPOS)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe1, SR_CONF_VPOS)); } else if (devc->zero_pcnt == 9) { - const double voff = 255*0.98 - (mstatus.ch1_max + mstatus.ch1_min) / 2.0; + const double voff = 255*0.98 - (devc->mstatus.ch1_max + devc->mstatus.ch1_min) / 2.0; if (abs(voff) < 0.5) { probe1->vpos = vpos_back[1]; } else { probe1->vpos_trans += voff; - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, probe1, SR_CONF_VPOS)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe1, SR_CONF_VPOS)); devc->zero_pcnt = 6; } } } if (devc->zero_pcnt == 10) { - ret = command_wr_reg(usb->devhdl, 0b1101, COMB_ADDR+6); + ret = dsl_wr_reg(sdi, COMB_ADDR+6, 0b1101); devc->zero_comb = 0; vpos_back[0] = probe0->vpos; probe0->vpos = (vga_ptr+devc->zero_stage-1)->key * 4.5; - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, probe0, SR_CONF_VPOS)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe0, SR_CONF_VPOS)); } else if (devc->zero_pcnt == 15) { - probe0->comb_diff_top = (mstatus.ch0_max - mstatus.ch1_max) + - (mstatus.ch0_min - mstatus.ch1_min); + probe0->comb_diff_top = (devc->mstatus.ch0_max - devc->mstatus.ch1_max) + + (devc->mstatus.ch0_min - devc->mstatus.ch1_min); probe0->vpos = (vga_ptr+devc->zero_stage-1)->key * -4.5; - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, probe0, SR_CONF_VPOS)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe0, SR_CONF_VPOS)); } else if (devc->zero_pcnt == 20) { - probe0->comb_diff_bom = (mstatus.ch0_max - mstatus.ch1_max) + - (mstatus.ch0_min - mstatus.ch1_min); + probe0->comb_diff_bom = (devc->mstatus.ch0_max - devc->mstatus.ch1_max) + + (devc->mstatus.ch0_min - devc->mstatus.ch1_min); probe0->vpos = vpos_back[0]; - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, probe0, SR_CONF_VPOS)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe0, SR_CONF_VPOS)); } if (devc->zero_pcnt == 25) { - ret = command_wr_reg(usb->devhdl, 0b1110, COMB_ADDR+6); + ret = dsl_wr_reg(sdi, COMB_ADDR+6, 0b1110); devc->zero_comb = 1; vpos_back[1] = probe1->vpos; probe1->vpos = (vga_ptr+devc->zero_stage-1)->key * 4.5; - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, probe1, SR_CONF_VPOS)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe1, SR_CONF_VPOS)); } else if (devc->zero_pcnt == 30) { - probe1->comb_diff_top = (mstatus.ch1_max - mstatus.ch0_max) + - (mstatus.ch1_min - mstatus.ch0_min); + probe1->comb_diff_top = (devc->mstatus.ch1_max - devc->mstatus.ch0_max) + + (devc->mstatus.ch1_min - devc->mstatus.ch0_min); probe1->vpos = (vga_ptr+devc->zero_stage-1)->key * -4.5; - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, probe1, SR_CONF_VPOS)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe1, SR_CONF_VPOS)); } else if (devc->zero_pcnt == 35) { - probe1->comb_diff_bom = (mstatus.ch1_max - mstatus.ch0_max) + - (mstatus.ch1_min - mstatus.ch0_min); + probe1->comb_diff_bom = (devc->mstatus.ch1_max - devc->mstatus.ch0_max) + + (devc->mstatus.ch1_min - devc->mstatus.ch0_min); probe1->vpos = vpos_back[1]; - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, probe1, SR_CONF_VPOS)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe1, SR_CONF_VPOS)); } if (devc->zero_pcnt == 40) { - if (strcmp(sdi->model, "DSCope20") == 0) { + if (strcmp(sdi->model, "DSCope") != 0) { probe0->vdiv = vdiv_back[0]; probe1->vdiv = vdiv_back[1]; } - ret = command_wr_reg(usb->devhdl, 0b0011, COMB_ADDR+6); + ret = dsl_wr_reg(sdi, COMB_ADDR+6, 0b0011); devc->zero = FALSE; dso_init(sdi); } @@ -2102,15 +1390,15 @@ static int dso_zero(const struct sr_dev_inst *sdi, struct sr_status mstatus) struct sr_channel *probe = (struct sr_channel *)l->data; uint64_t vdiv_back = probe->vdiv; probe->vdiv = (vga_ptr+devc->zero_stage)->key; - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, probe, SR_CONF_VDIV)); - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, probe, SR_CONF_VPOS)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_VDIV)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_VPOS)); probe->vdiv = vdiv_back; } } if (devc->zero_pcnt == 4) { - const double voff0 = 255/2.0 - (mstatus.ch0_max + mstatus.ch0_min)/2.0; - const double voff1 = 255/2.0 - (mstatus.ch1_max + mstatus.ch1_min)/2.0; + const double voff0 = 255/2.0 - (devc->mstatus.ch0_max + devc->mstatus.ch0_min)/2.0; + const double voff1 = 255/2.0 - (devc->mstatus.ch1_max + devc->mstatus.ch1_min)/2.0; if (abs(voff0) < 0.5 && abs(voff1) < 0.5) { devc->zero_stage++; } else { @@ -2131,7 +1419,7 @@ static int dso_zero(const struct sr_dev_inst *sdi, struct sr_status mstatus) else if (probe->index == 1) (vga_ptr+devc->zero_stage)->voff1 = (voff_coarse << 10) + voff_fine; } - } else if (strcmp(sdi->model, "DSCope20") == 0) { + } else { (vga_ptr+devc->zero_stage)->voff0 += voff0; (vga_ptr+devc->zero_stage)->voff1 += voff1; } @@ -2147,81 +1435,13 @@ static int dso_zero(const struct sr_dev_inst *sdi, struct sr_status mstatus) static int dev_open(struct sr_dev_inst *sdi) { - struct sr_usb_dev_inst *usb; - struct DSL_context *devc; - int ret; - uint8_t hw_info; + gboolean fpga_done; + int ret; GSList *l; gboolean zeroed; - gboolean fpga_done; - devc = sdi->priv; - usb = sdi->conn; - - /* - * If the firmware was recently uploaded, no dev_open operation should be called. - * Just wait for renumerate -> detach -> attach - */ - ret = SR_ERR; - if (devc->fw_updated > 0) { - return SR_ERR; - } else { - sr_info("%s: Firmware upload was not needed.", __func__); - ret = DSCope_dev_open(sdi); - } - - if (ret != SR_OK) { - sr_err("%s: Unable to open device.", __func__); - return SR_ERR; - } - - ret = libusb_claim_interface(usb->devhdl, USB_INTERFACE); - if (ret != 0) { - switch(ret) { - case LIBUSB_ERROR_BUSY: - sr_err("%s: Unable to claim USB interface. Another " - "program or driver has already claimed it.", __func__); - break; - case LIBUSB_ERROR_NO_DEVICE: - sr_err("%s: Device has been disconnected.", __func__); - break; - default: - sr_err("%s: Unable to claim interface: %s.", - __func__, libusb_error_name(ret)); - break; - } - - return SR_ERR; - } - - ret = command_get_hw_info(usb->devhdl, &hw_info); - if (ret != SR_OK) { - sr_err("Failed to get hardware infos."); - return SR_ERR; - } - fpga_done = (hw_info & 0x80) != 0; - - if (sdi->status == SR_ST_ACTIVE && !fpga_done) { - if ((ret = command_fpga_config(usb->devhdl)) != SR_OK) { - sr_err("%s: Send FPGA configure command failed!", __func__); - } else { - /* Takes >= 10ms for the FX2 to be ready for FPGA configure. */ - g_usleep(10 * 1000); - char *fpga_bit = malloc(strlen(DS_RES_PATH)+strlen(devc->profile->fpga_bit33)+1); - if (fpga_bit == NULL) - return SR_ERR_MALLOC; - strcpy(fpga_bit, DS_RES_PATH); - strcat(fpga_bit, devc->profile->fpga_bit33); - ret = fpga_config(usb->devhdl, fpga_bit); - if (ret != SR_OK) { - sr_err("%s: Configure FPGA failed!", __func__); - } - g_free(fpga_bit); - } - } - - // load zero informations - if (sdi->mode == DSO) { + if ((ret = dsl_dev_open(di, sdi, &fpga_done)) == SR_OK) { + // load zero informations for(l = sdi->channels; l; l = l->next) { struct sr_channel *probe = (struct sr_channel *)l->data; zeroed = dso_load_eep(sdi, probe, fpga_done); @@ -2236,25 +1456,13 @@ static int dev_open(struct sr_dev_inst *sdi) dso_init(sdi); } - return SR_OK; + return ret; } static int dev_close(struct sr_dev_inst *sdi) { - struct sr_usb_dev_inst *usb; - - usb = sdi->conn; - if (usb->devhdl == NULL) - return SR_ERR; - - sr_info("DSCope: Closing device %d on %d.%d interface %d.", - sdi->index, usb->bus, usb->address, USB_INTERFACE); - libusb_release_interface(usb->devhdl, USB_INTERFACE); - libusb_close(usb->devhdl); - usb->devhdl = NULL; - sdi->status = SR_ST_INACTIVE; - - return SR_OK; + int ret = dsl_dev_close(sdi); + return ret; } static int cleanup(void) @@ -2283,334 +1491,6 @@ static void remove_sources(struct DSL_context *devc) g_free(devc->usbfd); } -static void finish_acquisition(struct DSL_context *devc) -{ - struct sr_datafeed_packet packet; - - sr_err("%s: send SR_DF_END packet", __func__); - /* Terminate session. */ - packet.type = SR_DF_END; - packet.status = SR_PKT_OK; - sr_session_send(devc->cb_data, &packet); - - if (devc->num_transfers != 0) { - devc->num_transfers = 0; - g_free(devc->transfers); - } - - devc->status = DSL_FINISH; -} - -static void free_transfer(struct libusb_transfer *transfer) -{ - struct DSL_context *devc; - unsigned int i; - - devc = transfer->user_data; - - g_free(transfer->buffer); - transfer->buffer = NULL; - libusb_free_transfer(transfer); - - for (i = 0; i < devc->num_transfers; i++) { - if (devc->transfers[i] == transfer) { - devc->transfers[i] = NULL; - break; - } - } - - devc->submitted_transfers--; - if (devc->submitted_transfers == 0 && devc->status != DSL_TRIGGERED) - finish_acquisition(devc); -} - -static void resubmit_transfer(struct libusb_transfer *transfer) -{ - int ret; - - if ((ret = libusb_submit_transfer(transfer)) == LIBUSB_SUCCESS) - return; - - free_transfer(transfer); - /* TODO: Stop session? */ - - sr_err("%s: %s", __func__, libusb_error_name(ret)); -} - -static void receive_transfer(struct libusb_transfer *transfer) -{ - struct sr_datafeed_packet packet; - struct sr_datafeed_logic logic; - struct sr_datafeed_dso dso; - struct sr_datafeed_analog analog; - - uint8_t *cur_buf = transfer->buffer; - struct DSL_context *devc = transfer->user_data; - struct sr_dev_inst *sdi = devc->cb_data; - const int sample_width = 2; - int cur_sample_count = transfer->actual_length / sample_width; - unsigned int i; - - if (devc->data_lock) { - resubmit_transfer(transfer); - return; - } - - if (devc->abort) - devc->status = DSL_STOP; - - sr_info("receive_transfer(): status %d; timeout %d; received %d bytes.", - transfer->status, transfer->timeout, transfer->actual_length); - - switch (transfer->status) { - case LIBUSB_TRANSFER_COMPLETED: - case LIBUSB_TRANSFER_TIMED_OUT: /* We may have received some data though. */ - break; - default: - devc->status = DSL_ERROR; - break; - } - - packet.status = SR_PKT_OK; - if (devc->status == DSL_DATA && - transfer->actual_length != 0) { - // check packet type - if (sdi->mode == LOGIC) { - packet.type = SR_DF_LOGIC; - packet.payload = &logic; - logic.length = transfer->actual_length; - logic.data_error = 0; - logic.data = cur_buf; - } else if (sdi->mode == DSO) { - if (!devc->instant) { - const uint32_t mstatus_offset = devc->limit_samples / (g_slist_length(sdi->channels)/en_ch_num(sdi)); - mstatus.pkt_id = *((const uint16_t*)cur_buf + mstatus_offset); - 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_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.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) & 0x0fffffff; - mstatus.sample_divider_tog = *((const uint32_t*)cur_buf + mstatus_offset/2 + 18/2) & 0x80000000; - mstatus.trig_flag = *((const uint32_t*)cur_buf + mstatus_offset/2 + 18/2) & 0x40000000; - } else { - mstatus.vlen = instant_buffer_size; - } - - const uint32_t divider = devc->zero ? 0x1 : (uint32_t)ceil(DSCOPE_MAX_SAMPLERATE * 1.0 / devc->cur_samplerate / en_ch_num(sdi)); - if ((mstatus.pkt_id == DSO_PKTID && - mstatus.sample_divider == divider && - mstatus.vlen != 0 && - mstatus.vlen <= (transfer->actual_length - 512) / sample_width) || - devc->instant) { - devc->roll = (mstatus.stream_mode != 0); - devc->mstatus_valid = devc->instant ? FALSE : TRUE; - packet.type = SR_DF_DSO; - packet.payload = &dso; - dso.probes = sdi->channels; - //dso.num_samples = (transfer->actual_length - 512) / sample_width; - cur_sample_count = 2 * mstatus.vlen / en_ch_num(sdi) ; - dso.num_samples = cur_sample_count; - dso.mq = SR_MQ_VOLTAGE; - dso.unit = SR_UNIT_VOLT; - dso.mqflags = SR_MQFLAG_AC; - dso.samplerate_tog = (mstatus.sample_divider_tog != 0); - dso.trig_flag = (mstatus.trig_flag != 0); - dso.data = cur_buf; - } else { - packet.type = SR_DF_DSO; - packet.status = SR_PKT_DATA_ERROR; - devc->mstatus_valid = FALSE; - } - } else { - packet.type = SR_DF_ANALOG; - packet.payload = &analog; - analog.probes = sdi->channels; - analog.num_samples = (transfer->actual_length / sample_width)/g_slist_length(analog.probes); - analog.mq = SR_MQ_VOLTAGE; - analog.unit = SR_UNIT_VOLT; - analog.mqflags = SR_MQFLAG_AC; - analog.data = (float *)cur_buf; - } - - if (devc->limit_samples) { - const uint64_t remain_length= (devc->limit_samples - devc->num_samples) * sample_width; - logic.length = min(logic.length, remain_length); - - /* in test mode, check data content*/ - if (devc->op_mode == SR_OP_INTERNAL_TEST) { - //for (i = 0; i < logic.length / sample_width; i++) { - for (i = 0; i < logic.length / 2; i++) { -// const uint16_t cur_sample = devc->sample_wide ? -// *((const uint16_t*)cur_buf + i) : -// *((const uint8_t*)cur_buf + i); - const uint16_t cur_sample = *((const uint16_t*)cur_buf + i); - if (test_init == 1) { - test_sample_value = cur_sample; - test_init = 0; - } - if (cur_sample != test_sample_value) { - logic.data_error = 1; - sr_err("exp: %d; act: %d", test_sample_value, cur_sample); - break; - } - test_sample_value++; - } - } - if (devc->op_mode == SR_OP_EXTERNAL_TEST) { - for (i = 0; i < logic.length / 2; i++) { - const uint16_t cur_sample = *((const uint16_t*)cur_buf + i); - if (test_init == 1) { - test_sample_value = cur_sample; - test_init = 0; - } - if (cur_sample != test_sample_value) { - logic.data_error = 1; - sr_err("exp: %d; act: %d", test_sample_value, cur_sample); - break; - } - test_sample_value = (test_sample_value + 1) % 65001; - //test_sample_value = test_sample_value + 1; - } - } - - /* send data to session bus */ - if (packet.status != SR_PKT_DATA_ERROR) - sr_session_send(sdi, &packet); - } - - devc->num_samples += cur_sample_count; - if ((sdi->mode == LOGIC || devc->instant) && - devc->limit_samples && - devc->num_samples >= devc->limit_samples) { - devc->status = DSL_STOP; - } - } - - if (devc->status == DSL_DATA) - resubmit_transfer(transfer); - else - free_transfer(transfer); -} - -static unsigned int to_bytes_per_ms(struct DSL_context *devc) -{ - if (devc->cur_samplerate > SR_MHZ(100)) - return SR_MHZ(100) / 1000 * (devc->sample_wide ? 2 : 1); - else - return devc->cur_samplerate / 1000 * (devc->sample_wide ? 2 : 1); -} - -static size_t get_buffer_size(struct DSL_context *devc) -{ - size_t s; - - /* - * The buffer should be large enough to hold 10ms of data and - * a multiple of 512. - */ - s = single_buffer_time * to_bytes_per_ms(devc); - //s = to_bytes_per_ms(devc->cur_samplerate); - return (s + 511) & ~511; -} - -static unsigned int get_number_of_transfers(struct DSL_context *devc) -{ - unsigned int n; - size_t total_size; - total_size = min(devc->limit_samples * (devc->sample_wide ? 2 : 1), - total_buffer_time * to_bytes_per_ms(devc)); - /* Total buffer size should be able to hold about 500ms of data. */ - //n = 500 * to_bytes_per_ms(devc) / get_buffer_size(devc); - n = ceil(total_size * 1.0f / get_buffer_size(devc)); - - if (n > NUM_SIMUL_TRANSFERS) - return NUM_SIMUL_TRANSFERS; - - return n; - //return 1; -} - -static unsigned int get_timeout(struct DSL_context *devc) -{ - size_t total_size; - unsigned int timeout; - - total_size = get_buffer_size(devc) * get_number_of_transfers(devc); - timeout = total_size / to_bytes_per_ms(devc); - //return timeout + timeout / 4; /* Leave a headroom of 25% percent. */ - return timeout * 4; -} - -static int dev_transfer_start(const struct sr_dev_inst *sdi) -{ - struct DSL_context *devc; - struct sr_usb_dev_inst *usb; - struct libusb_transfer *transfer; - unsigned int i, num_transfers; - int ret; - unsigned char *buf; - size_t size; - int dso_buffer_size; - - devc = sdi->priv; - usb = sdi->conn; - - #ifndef _WIN32 - num_transfers = 1; - #else - num_transfers = buffer_cnt; - #endif - - if (devc->instant) - dso_buffer_size = instant_buffer_size * g_slist_length(sdi->channels); - else - dso_buffer_size = devc->limit_samples * en_ch_num(sdi) + 512; - size = (sdi->mode == ANALOG) ? cons_buffer_size : ((sdi->mode == DSO) ? dso_buffer_size : buffer_size); - devc->submitted_transfers = 0; - - devc->transfers = g_try_malloc0(sizeof(*devc->transfers) * num_transfers); - if (!devc->transfers) { - sr_err("%s: USB transfers malloc failed.", __func__); - return SR_ERR_MALLOC; - } - - for (i = 0; i < num_transfers; i++) { - if (!(buf = g_try_malloc(size))) { - sr_err("%s: USB transfer buffer malloc failed.", __func__); - return SR_ERR_MALLOC; - } - transfer = libusb_alloc_transfer(0); - libusb_fill_bulk_transfer(transfer, usb->devhdl, - 6 | LIBUSB_ENDPOINT_IN, buf, size, - receive_transfer, devc, 0); - if ((ret = libusb_submit_transfer(transfer)) != 0) { - sr_err("%s: Failed to submit transfer: %s.", - __func__, libusb_error_name(ret)); - libusb_free_transfer(transfer); - g_free(buf); - devc->status = DSL_ERROR; - devc->abort = TRUE; - return SR_ERR; - } - devc->transfers[i] = transfer; - devc->submitted_transfers++; - devc->num_transfers++; - } - - devc->status = DSL_DATA; - - return SR_OK; -} - - static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi) { int completed = 0; @@ -2627,73 +1507,29 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi) tv.tv_sec = tv.tv_usec = 0; libusb_handle_events_timeout_completed(drvc->sr_ctx->libusb_ctx, &tv, &completed); - if (devc->zero) { - dso_zero(sdi, mstatus); + if (devc->zero && devc->trf_completed) { + dso_zero(sdi); } if (devc->status == DSL_FINISH) { remove_sources(devc); } + devc->trf_completed = 0; return TRUE; } -static void receive_trigger_pos(struct libusb_transfer *transfer) -{ - struct DSL_context *devc; - struct sr_datafeed_packet packet; - struct ds_trigger_pos *trigger_pos; - const struct sr_dev_inst *sdi; - int ret; - - packet.status = SR_PKT_OK; - devc = transfer->user_data; - sdi = devc->cb_data; - trigger_pos = (struct ds_trigger_pos *)transfer->buffer; - devc->status = DSL_ERROR; - if (transfer->status == LIBUSB_TRANSFER_COMPLETED && - trigger_pos->check_id == TRIG_CHECKID) { - sr_info("receive_trigger_pos(): status %d; timeout %d; received %d bytes.", - transfer->status, transfer->timeout, transfer->actual_length); - if (transfer->actual_length == sizeof(struct ds_trigger_pos)) { - packet.type = SR_DF_TRIGGER; - packet.payload = trigger_pos; - sr_session_send(sdi, &packet); - - devc->status = DSL_TRIGGERED; - devc->num_transfers = 0; - devc->empty_transfer_count = 0; - } - } - - if (devc->status == DSL_TRIGGERED) { - // successfull - free_transfer(transfer); - if ((ret = dev_transfer_start(devc->cb_data)) != SR_OK) { - sr_err("%s: could not start data transfer" - "(%d)%d", __func__, ret, errno); - } - } else if (devc->status == DSL_START) { - // retry - resubmit_transfer(transfer); - } else { - // failed - free_transfer(transfer); - } -} - static int dev_acquisition_start(struct sr_dev_inst *sdi, void *cb_data) { (void)cb_data; struct DSL_context *devc; struct sr_usb_dev_inst *usb; - struct libusb_transfer *transfer; - struct ds_trigger_pos *trigger_pos; struct drv_context *drvc; const struct libusb_pollfd **lupfd; unsigned int i; int ret; + struct ctl_wr_cmd wr_cmd; test_init = 1; @@ -2711,31 +1547,32 @@ static int dev_acquisition_start(struct sr_dev_inst *sdi, void *cb_data) devc->status = DSL_INIT; devc->num_transfers = 0; devc->submitted_transfers = 0; - test_sample_value = 0; - devc->abort = FALSE; + devc->actual_samples = devc->limit_samples; + test_sample_value = 0; + devc->abort = FALSE; + devc->mstatus_valid = FALSE; + devc->overflow = FALSE; /* Configures devc->trigger_* and devc->sample_wide */ - if (configure_probes(sdi) != SR_OK) { + if (dsl_configure_probes(sdi) != SR_OK) { sr_err("%s: Failed to configure probes.", __func__); return SR_ERR; } /* Stop Previous GPIF acquisition */ - if ((ret = command_stop_acquisition (usb->devhdl)) != SR_OK) { + wr_cmd.header.dest = DSL_CTL_STOP; + wr_cmd.header.size = 0; + if ((ret = command_ctl_wr(usb->devhdl, wr_cmd)) != SR_OK) { sr_err("%s: Stop DSCope acquisition failed!", __func__); return ret; } else { sr_info("%s: Stop Previous DSCope acquisition!", __func__); } - /* Setting FPGA before acquisition start*/ - if ((ret = command_fpga_setting(usb->devhdl, sizeof(struct DSL_setting) / sizeof(uint16_t))) != SR_OK) { - sr_err("%s: Send FPGA setting command failed!", __func__); - } else { - if ((ret = fpga_setting(sdi)) != SR_OK) { - sr_err("%s: Configure FPGA failed!", __func__); - return ret; - } + /* Arm FPGA before acquisition start*/ + if ((ret = dsl_fpga_arm(sdi)) != SR_OK) { + sr_err("%s: Arm FPGA failed!", __func__); + return ret; } if (devc->zero && devc->zero_stage == -1) { @@ -2753,8 +1590,8 @@ static int dev_acquisition_start(struct sr_dev_inst *sdi, void *cb_data) * settings must be updated before acquisition */ if (sdi->mode == DSO) { - devc->trigger_hpos = devc->trigger_hrate * en_ch_num(sdi) * devc->limit_samples / 200.0; - if ((ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, NULL, SR_CONF_HORIZ_TRIGGERPOS))) == SR_OK) + devc->trigger_hpos = devc->trigger_hrate * dsl_en_ch_num(sdi) * devc->limit_samples / 200.0; + if ((ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, NULL, SR_CONF_HORIZ_TRIGGERPOS))) == SR_OK) sr_dbg("%s: setting DSO Horiz Trigger Position to %d", __func__, devc->trigger_hpos); else @@ -2762,53 +1599,34 @@ static int dev_acquisition_start(struct sr_dev_inst *sdi, void *cb_data) __func__, devc->trigger_hpos); } - /* poll trigger status transfer*/ - if (!(trigger_pos = g_try_malloc0(sizeof(struct ds_trigger_pos)))) { - sr_err("%s: USB trigger_pos buffer malloc failed.", __func__); - return SR_ERR_MALLOC; - } - devc->transfers = g_try_malloc0(sizeof(*devc->transfers)); - if (!devc->transfers) { - sr_err("%s: USB trigger_pos transfer malloc failed.", __func__); - return SR_ERR_MALLOC; - } - transfer = libusb_alloc_transfer(0); - libusb_fill_bulk_transfer(transfer, usb->devhdl, - 6 | LIBUSB_ENDPOINT_IN, (unsigned char*)trigger_pos, sizeof(struct ds_trigger_pos), - receive_trigger_pos, devc, 0); - if ((ret = libusb_submit_transfer(transfer)) != 0) { - sr_err("%s: Failed to submit trigger_pos transfer: %s.", - __func__, libusb_error_name(ret)); - libusb_free_transfer(transfer); - g_free(trigger_pos); - return SR_ERR; - } else { - devc->num_transfers++; - devc->transfers[0] = transfer; - devc->submitted_transfers++; + /* setup and submit usb transfer */ + if ((ret = dsl_start_transfers(devc->cb_data)) != SR_OK) { + sr_err("%s: Could not submit usb transfer" + "(%d)%d", __func__, ret, errno); + return ret; } /* setup callback function for data transfer */ lupfd = libusb_get_pollfds(drvc->sr_ctx->libusb_ctx); for (i = 0; lupfd[i]; i++); if (!(devc->usbfd = g_try_malloc(sizeof(struct libusb_pollfd) * (i + 1)))) - return SR_ERR; + return SR_ERR; for (i = 0; lupfd[i]; i++) { sr_source_add(lupfd[i]->fd, lupfd[i]->events, - get_timeout(devc), receive_data, sdi); + dsl_get_timeout(devc), receive_data, sdi); devc->usbfd[i] = lupfd[i]->fd; } devc->usbfd[i] = -1; free(lupfd); - devc->status = DSL_START; - devc->mstatus_valid = FALSE; - if ((ret = command_start_acquisition (usb->devhdl, - devc->cur_samplerate, devc->sample_wide, (sdi->mode == LOGIC))) != SR_OK) { + wr_cmd.header.dest = DSL_CTL_START; + wr_cmd.header.size = 0; + if ((ret = command_ctl_wr(usb->devhdl, wr_cmd)) != SR_OK) { devc->status = DSL_ERROR; devc->abort = TRUE; return ret; } + devc->status = DSL_START; /* Send header packet to the session bus. */ //std_session_send_df_header(cb_data, LOG_PREFIX); @@ -2819,46 +1637,13 @@ static int dev_acquisition_start(struct sr_dev_inst *sdi, void *cb_data) static int dev_acquisition_stop(const struct sr_dev_inst *sdi, void *cb_data) { - (void)cb_data; - - struct DSL_context *devc; - struct sr_usb_dev_inst *usb; - int ret; - - devc = sdi->priv; - usb = sdi->conn; - - if (!devc->abort) { - devc->abort = TRUE; - command_wr_reg(usb->devhdl, bmFORCE_RDY, EEWP_ADDR); - } else if (devc->status == DSL_FINISH) { - /* Stop GPIF acquisition */ - if ((ret = command_stop_acquisition (usb->devhdl)) != SR_OK) - sr_err("%s: Sent acquisition stop command failed!", __func__); - else - sr_info("%s: Sent acquisition stop command!", __func__); - } - - return SR_OK; + int ret = dsl_dev_acquisition_stop(sdi, cb_data); + return ret; } static int dev_status_get(const struct sr_dev_inst *sdi, struct sr_status *status, int begin, int end) { - int ret = SR_ERR; - if (sdi) { - struct DSL_context *devc; - struct sr_usb_dev_inst *usb; - - devc = sdi->priv; - usb = sdi->conn; - if (devc->status == DSL_START) { - ret = command_get_status(usb->devhdl, (unsigned char*)status, begin, end); - } else if (devc->mstatus_valid) { - *status = mstatus; - ret = SR_OK; - } - } - + int ret = dsl_dev_status_get(sdi, status, begin, end); return ret; } diff --git a/libsigrok4DSL/hardware/DSL/dsl.c b/libsigrok4DSL/hardware/DSL/dsl.c new file mode 100755 index 00000000..70e8cee7 --- /dev/null +++ b/libsigrok4DSL/hardware/DSL/dsl.c @@ -0,0 +1,1482 @@ +/* + * This file is part of the libsigrok project. + * + * Copyright (C) 2017 DreamSourceLab + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "libsigrok.h" +#include "libsigrok-internal.h" +#include "command.h" +#include "dsl.h" + +#include +#include +#include + +extern struct ds_trigger *trigger; + +static const unsigned int single_buffer_time = 20; +static const unsigned int total_buffer_time = 100; +static const unsigned int instant_buffer_size = 1024 * 1024; + +SR_PRIV int dsl_en_ch_num(const struct sr_dev_inst *sdi) +{ + GSList *l; + int channel_en_cnt = 0; + + for (l = sdi->channels; l; l = l->next) { + struct sr_channel *probe = (struct sr_channel *)l->data; + channel_en_cnt += probe->enabled; + } + channel_en_cnt += (channel_en_cnt == 0); + + return channel_en_cnt; +} + +/** + * Check the USB configuration to determine if this is an dsl device. + * + * @return TRUE if the device's configuration profile match dsl hardware + * configuration, FALSE otherwise. + */ +SR_PRIV gboolean dsl_check_conf_profile(libusb_device *dev) +{ + struct libusb_device_descriptor des; + struct libusb_device_handle *hdl; + gboolean ret; + unsigned char strdesc[64]; + + hdl = NULL; + ret = FALSE; + while (!ret) { + /* Assume the FW has not been loaded, unless proven wrong. */ + if (libusb_get_device_descriptor(dev, &des) != 0) + break; + + if (libusb_open(dev, &hdl) != 0) + break; + + if (libusb_get_string_descriptor_ascii(hdl, + des.iManufacturer, strdesc, sizeof(strdesc)) < 0) + break; + if (strncmp((const char *)strdesc, "DreamSourceLab", 14)) + break; + + if (libusb_get_string_descriptor_ascii(hdl, + des.iProduct, strdesc, sizeof(strdesc)) < 0) + break; + if (strncmp((const char *)strdesc, "USB-based DSL Instrument v2", 27)) + break; + + /* If we made it here, it must be an dsl device. */ + ret = TRUE; + } + if (hdl) + libusb_close(hdl); + + return ret; +} + +static int hw_dev_open(struct sr_dev_driver *di, struct sr_dev_inst *sdi) +{ + libusb_device **devlist; + struct sr_usb_dev_inst *usb; + struct libusb_device_descriptor des; + struct DSL_context *devc; + struct drv_context *drvc; + struct version_info vi; + int ret, skip, i, device_count; + uint8_t revid; + struct ctl_rd_cmd rd_cmd; + uint8_t rd_cmd_data[2]; + + drvc = di->priv; + devc = sdi->priv; + usb = sdi->conn; + + if (sdi->status == SR_ST_ACTIVE) { + /* Device is already in use. */ + return SR_ERR; + } + + skip = 0; + device_count = libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist); + if (device_count < 0) { + sr_err("Failed to get device list: %s.", + libusb_error_name(device_count)); + return SR_ERR; + } + + for (i = 0; i < device_count; i++) { + if ((ret = libusb_get_device_descriptor(devlist[i], &des))) { + sr_err("Failed to get device descriptor: %s.", + libusb_error_name(ret)); + continue; + } + + if (des.idVendor != devc->profile->vid + || des.idProduct != devc->profile->pid) + continue; + + if (sdi->status == SR_ST_INITIALIZING) { + if (skip != sdi->index) { + /* Skip devices of this type that aren't the one we want. */ + skip += 1; + continue; + } + } else if (sdi->status == SR_ST_INACTIVE) { + /* + * This device is fully enumerated, so we need to find + * this device by vendor, product, bus and address. + */ + if (libusb_get_bus_number(devlist[i]) != usb->bus + || libusb_get_device_address(devlist[i]) != usb->address) + /* This is not the one. */ + continue; + } + + if (!(ret = libusb_open(devlist[i], &usb->devhdl))) { + if (usb->address == 0xff) + /* + * First time we touch this device after FW + * upload, so we don't know the address yet. + */ + usb->address = libusb_get_device_address(devlist[i]); + } else { + sr_err("Failed to open device: %s.", + libusb_error_name(ret)); + break; + } + + rd_cmd.header.dest = DSL_CTL_FW_VERSION; + rd_cmd.header.size = 2; + rd_cmd.data = rd_cmd_data; + if ((ret = command_ctl_rd(usb->devhdl, rd_cmd)) != SR_OK) { + sr_err("Failed to get firmware version."); + break; + } + vi.major = rd_cmd_data[0]; + vi.minor = rd_cmd_data[1]; + + rd_cmd.header.dest = DSL_CTL_REVID_VERSION; + rd_cmd.header.size = 1; + rd_cmd.data = &revid; + if ((ret = command_ctl_rd(usb->devhdl, rd_cmd)) != SR_OK) { + sr_err("Failed to get REVID."); + break; + } + + /* + * Different versions may have incompatible issue, + * Mark for up level process + */ + if (vi.major != DSL_REQUIRED_VERSION_MAJOR || + vi.minor != DSL_REQUIRED_VERSION_MINOR) { + sr_err("Expected firmware version %d.%d, " + "got %d.%d.", DSL_REQUIRED_VERSION_MAJOR, DSL_REQUIRED_VERSION_MINOR, + vi.major, vi.minor); + sdi->status = SR_ST_INCOMPATIBLE; + } else { + sdi->status = SR_ST_ACTIVE; + } + + sr_info("Opened device %d on %d.%d, " + "interface %d, firmware %d.%d.", + sdi->index, usb->bus, usb->address, + USB_INTERFACE, vi.major, vi.minor); + + sr_info("Detected REVID=%d, it's a Cypress CY7C68013%s.", + revid, (revid != 1) ? " (FX2)" : "A (FX2LP)"); + + break; + } + libusb_free_device_list(devlist, 1); + + if ((sdi->status != SR_ST_ACTIVE) && + (sdi->status != SR_ST_INCOMPATIBLE)) + return SR_ERR; + + return SR_OK; +} + +SR_PRIV int dsl_configure_probes(const struct sr_dev_inst *sdi) +{ + struct DSL_context *devc; + struct sr_channel *probe; + GSList *l; + int probe_bit, stage, i; + char *tc; + + devc = sdi->priv; + for (i = 0; i < NUM_TRIGGER_STAGES; i++) { + devc->trigger_mask[i] = 0; + devc->trigger_value[i] = 0; + } + + stage = -1; + for (l = sdi->channels; l; l = l->next) { + probe = (struct sr_channel *)l->data; + if (probe->enabled == FALSE) + continue; + + probe_bit = 1 << (probe->index); + if (!(probe->trigger)) + continue; + + stage = 0; + for (tc = probe->trigger; *tc; tc++) { + devc->trigger_mask[stage] |= probe_bit; + if (*tc == '1') + devc->trigger_value[stage] |= probe_bit; + stage++; + if (stage > NUM_TRIGGER_STAGES) + return SR_ERR; + } + } + + return SR_OK; +} + +SR_PRIV uint64_t dsl_channel_depth(const struct sr_dev_inst *sdi) +{ + int ch_num = dsl_en_ch_num(sdi); + if (strcmp(sdi->model, "DSLogic Basic") == 0) + return DSLOGIC_BASIC_MEM_DEPTH / (ch_num ? ch_num : 1); + else + return DSLOGIC_MEM_DEPTH / (ch_num ? ch_num : 1); +} + +SR_PRIV int dsl_wr_reg(const struct sr_dev_inst *sdi, uint8_t addr, uint8_t value) +{ + struct sr_usb_dev_inst *usb; + struct libusb_device_handle *hdl; + struct ctl_wr_cmd wr_cmd; + int ret; + + usb = sdi->conn; + hdl = usb->devhdl; + + wr_cmd.header.dest = DSL_CTL_I2C_REG; + wr_cmd.header.offset = addr; + wr_cmd.header.size = 1; + wr_cmd.data[0] = value; + if ((ret = command_ctl_wr(hdl, wr_cmd)) != SR_OK) { + sr_err("Sent DSL_CTL_I2C_REG command failed."); + return SR_ERR; + } + + return SR_OK; +} + +SR_PRIV int dsl_wr_dso(const struct sr_dev_inst *sdi, uint64_t cmd) +{ + struct sr_usb_dev_inst *usb; + struct libusb_device_handle *hdl; + struct ctl_wr_cmd wr_cmd; + int ret; + + usb = sdi->conn; + hdl = usb->devhdl; + + wr_cmd.header.dest = DSL_CTL_I2C_DSO; + wr_cmd.header.offset = 0; + wr_cmd.header.size = 8; + wr_cmd.data[0] = (uint8_t)cmd; + wr_cmd.data[1] = (uint8_t)(cmd >> 8); + wr_cmd.data[2] = (uint8_t)(cmd >> 16); + wr_cmd.data[3] = (uint8_t)(cmd >> 24); + wr_cmd.data[4] = (uint8_t)(cmd >> 32); + wr_cmd.data[5] = (uint8_t)(cmd >> 40); + wr_cmd.data[6] = (uint8_t)(cmd >> 48); + wr_cmd.data[7] = (uint8_t)(cmd >> 56); + if ((ret = command_ctl_wr(hdl, wr_cmd)) != SR_OK) { + sr_err("Sent DSL_CTL_I2C_DSO command failed."); + return SR_ERR; + } + + return SR_OK; +} + +SR_PRIV int dsl_wr_nvm(const struct sr_dev_inst *sdi, unsigned char *ctx, uint16_t addr, uint8_t len) +{ + struct sr_usb_dev_inst *usb; + struct libusb_device_handle *hdl; + struct ctl_wr_cmd wr_cmd; + int ret; + int i; + + usb = sdi->conn; + hdl = usb->devhdl; + + wr_cmd.header.dest = DSL_CTL_NVM; + wr_cmd.header.offset = addr; + wr_cmd.header.size = len; + for (i = 0; i < len; i++) + wr_cmd.data[i] = *(ctx+i); + if ((ret = command_ctl_wr(hdl, wr_cmd)) != SR_OK) { + sr_err("Sent DSL_CTL_NVM write command failed."); + return SR_ERR; + } + + return SR_OK; +} + +SR_PRIV int dsl_rd_nvm(const struct sr_dev_inst *sdi, unsigned char *ctx, uint16_t addr, uint8_t len) +{ + struct sr_usb_dev_inst *usb; + struct libusb_device_handle *hdl; + struct ctl_rd_cmd rd_cmd; + int ret; + + usb = sdi->conn; + hdl = usb->devhdl; + + rd_cmd.header.dest = DSL_CTL_NVM; + rd_cmd.header.size = len; + rd_cmd.header.offset = addr; + rd_cmd.data = ctx; + if ((ret = command_ctl_rd(hdl, rd_cmd)) != SR_OK) { + sr_err("Sent DSL_CTL_NVM read command failed."); + return SR_ERR; + } + + return SR_OK; +} + +SR_PRIV int dsl_fpga_arm(const struct sr_dev_inst *sdi) +{ + struct DSL_context *devc; + struct sr_usb_dev_inst *usb; + struct libusb_device_handle *hdl; + struct DSL_setting setting; + int ret; + int transferred; + int i; + GSList *l; + uint32_t tmp_u32; + uint64_t tmp_u64; + const int ch_num = dsl_en_ch_num(sdi); + uint32_t arm_size; + struct ctl_wr_cmd wr_cmd; + struct ctl_rd_cmd rd_cmd; + uint8_t rd_cmd_data; + + devc = sdi->priv; + usb = sdi->conn; + hdl = usb->devhdl; + + setting.sync = 0xf5a5f5a5; + setting.mode_header = 0x0001; + setting.divider_header = 0x0102; + setting.count_header = 0x0302; + setting.trig_pos_header = 0x0502; + setting.trig_glb_header = 0x0701; + setting.ch_en_header = 0x0801; + setting.trig_header = 0x40a0; + setting.end_sync = 0xfa5afa5a; + + // basic configuration + setting.mode = (trigger->trigger_en << TRIG_EN_BIT) + + (devc->clock_type << CLK_TYPE_BIT) + + (devc->clock_edge << CLK_EDGE_BIT) + + (devc->rle_mode << RLE_MODE_BIT) + + ((sdi->mode == DSO) << DSO_MODE_BIT) + + ((((devc->cur_samplerate == (2 * DSLOGIC_MAX_LOGIC_SAMPLERATE)) && sdi->mode != DSO) || (sdi->mode == ANALOG)) << HALF_MODE_BIT) + + ((devc->cur_samplerate == (4 * DSLOGIC_MAX_LOGIC_SAMPLERATE)) << QUAR_MODE_BIT) + + ((sdi->mode == ANALOG) << ANALOG_MODE_BIT) + + ((devc->filter == SR_FILTER_1T) << FILTER_BIT) + + (devc->instant << INSTANT_BIT) + + ((trigger->trigger_mode == SERIAL_TRIGGER) << STRIG_MODE_BIT) + + ((devc->stream) << STREAM_MODE_BIT) + + ((devc->op_mode == SR_OP_LOOPBACK_TEST) << LPB_TEST_BIT) + + ((devc->op_mode == SR_OP_EXTERNAL_TEST) << EXT_TEST_BIT) + + ((devc->op_mode == SR_OP_INTERNAL_TEST) << INT_TEST_BIT); + + // sample rate divider + tmp_u32 = (sdi->mode == DSO) ? (uint32_t)ceil(DSLOGIC_MAX_DSO_SAMPLERATE * 1.0 / devc->cur_samplerate / ch_num) : + (uint32_t)ceil(DSLOGIC_MAX_LOGIC_SAMPLERATE * 1.0 / devc->cur_samplerate); + setting.div_l = tmp_u32 & 0x0000ffff; + setting.div_h = tmp_u32 >> 16; + + // capture counter + // analog: 16bits, but sample with half mode(0-7 valid only) + tmp_u64 = (sdi->mode == DSO) ? (devc->limit_samples / (g_slist_length(sdi->channels) / ch_num)) : + (sdi->mode == ANALOG) ? (devc->limit_samples * g_slist_length(sdi->channels) * 4) : + (devc->limit_samples); + tmp_u64 >>= 4; // hardware minimum unit 64 + setting.cnt_l = tmp_u64 & 0x0000ffff; + setting.cnt_h = tmp_u64 >> 16; + + // trigger position + // must be align to minimum parallel bits + tmp_u32 = max((uint32_t)(trigger->trigger_pos / 100.0 * devc->limit_samples), DSLOGIC_ATOMIC_SAMPLES); + if (devc->stream) + tmp_u32 = min(tmp_u32, dsl_channel_depth(sdi) * 10 / 100); + else + tmp_u32 = min(tmp_u32, dsl_channel_depth(sdi) * DS_MAX_TRIG_PERCENT / 100); + setting.tpos_l = tmp_u32 & DSLOGIC_ATOMIC_MASK; + setting.tpos_h = tmp_u32 >> 16; + + // trigger global settings + setting.trig_glb = ((ch_num & 0xf) << 4) + + trigger->trigger_stages; + + // channel enable mapping + setting.ch_en = 0; + for (l = sdi->channels; l; l = l->next) { + struct sr_channel *probe = (struct sr_channel *)l->data; + setting.ch_en += probe->enabled << probe->index; + } + + // trigger advanced configuration + if (trigger->trigger_mode == SIMPLE_TRIGGER) { + setting.trig_mask0[0] = ds_trigger_get_mask0(TriggerStages); + setting.trig_mask1[0] = ds_trigger_get_mask1(TriggerStages); + + setting.trig_value0[0] = ds_trigger_get_value0(TriggerStages); + setting.trig_value1[0] = ds_trigger_get_value1(TriggerStages); + + setting.trig_edge0[0] = ds_trigger_get_edge0(TriggerStages); + setting.trig_edge1[0] = ds_trigger_get_edge1(TriggerStages); + + if (setting.mode & (1 << QUAR_MODE_BIT)) { + setting.trig_mask0[0] = ((setting.trig_mask0[0] & 0x0f) << 12) + + ((setting.trig_mask0[0] & 0x0f) << 8) + + ((setting.trig_mask0[0] & 0x0f) << 4) + + ((setting.trig_mask0[0] & 0x0f) << 0); + setting.trig_mask1[0] = ((setting.trig_mask1[0] & 0x0f) << 12) + + ((setting.trig_mask1[0] & 0x0f) << 8) + + ((setting.trig_mask1[0] & 0x0f) << 4) + + ((setting.trig_mask1[0] & 0x0f) << 0); + setting.trig_value0[0] = ((setting.trig_value0[0] & 0x0f) << 12) + + ((setting.trig_value0[0] & 0x0f) << 8) + + ((setting.trig_value0[0] & 0x0f) << 4) + + ((setting.trig_value0[0] & 0x0f) << 0); + setting.trig_value1[0] = ((setting.trig_value1[0] & 0x0f) << 12) + + ((setting.trig_value1[0] & 0x0f) << 8) + + ((setting.trig_value1[0] & 0x0f) << 4) + + ((setting.trig_value1[0] & 0x0f) << 0); + setting.trig_edge0[0] = ((setting.trig_edge0[0] & 0x0f) << 12) + + ((setting.trig_edge0[0] & 0x0f) << 8) + + ((setting.trig_edge0[0] & 0x0f) << 4) + + ((setting.trig_edge0[0] & 0x0f) << 0); + setting.trig_edge1[0] = ((setting.trig_edge1[0] & 0x0f) << 12) + + ((setting.trig_edge1[0] & 0x0f) << 8) + + ((setting.trig_edge1[0] & 0x0f) << 4) + + ((setting.trig_edge1[0] & 0x0f) << 0); + } else if (setting.mode & (1 << HALF_MODE_BIT)) { + setting.trig_mask0[0] = ((setting.trig_mask0[0] & 0xff) << 8) + + ((setting.trig_mask0[0] & 0xff) << 0); + setting.trig_mask1[0] = ((setting.trig_mask1[0] & 0xff) << 8) + + ((setting.trig_mask1[0] & 0xff) << 0); + setting.trig_value0[0] = ((setting.trig_value0[0] & 0xff) << 8) + + ((setting.trig_value0[0] & 0xff) << 0); + setting.trig_value1[0] = ((setting.trig_value1[0] & 0xff) << 8) + + ((setting.trig_value1[0] & 0xff) << 0); + setting.trig_edge0[0] = ((setting.trig_edge0[0] & 0xff) << 8) + + ((setting.trig_edge0[0] & 0xff) << 0); + setting.trig_edge1[0] = ((setting.trig_edge1[0] & 0xff) << 8) + + ((setting.trig_edge1[0] & 0xff) << 0); + } + + setting.trig_logic0[0] = (trigger->trigger_logic[TriggerStages] << 1) + trigger->trigger0_inv[TriggerStages]; + setting.trig_logic1[0] = (trigger->trigger_logic[TriggerStages] << 1) + trigger->trigger1_inv[TriggerStages]; + + setting.trig_count[0] = trigger->trigger0_count[TriggerStages]; + + for (i = 1; i < NUM_TRIGGER_STAGES; i++) { + setting.trig_mask0[i] = 0xffff; + setting.trig_mask1[i] = 0xffff; + + setting.trig_value0[i] = 0; + setting.trig_value1[i] = 0; + + setting.trig_edge0[i] = 0; + setting.trig_edge1[i] = 0; + + setting.trig_logic0[i] = 2; + setting.trig_logic1[i] = 2; + + setting.trig_count[i] = 0; + } + } else { + for (i = 0; i < NUM_TRIGGER_STAGES; i++) { + setting.trig_mask0[i] = ds_trigger_get_mask0(i); + setting.trig_mask1[i] = ds_trigger_get_mask1(i); + + setting.trig_value0[i] = ds_trigger_get_value0(i); + setting.trig_value1[i] = ds_trigger_get_value1(i); + + setting.trig_edge0[i] = ds_trigger_get_edge0(i); + setting.trig_edge1[i] = ds_trigger_get_edge1(i); + + if (setting.mode & (1 << STRIG_MODE_BIT) && i == STriggerDataStage) { + // serial trigger, data mask/value should not be duplicated + } else { + if (setting.mode & (1 << QUAR_MODE_BIT)) { + setting.trig_mask0[i] = ((setting.trig_mask0[i] & 0x0f) << 12) + + ((setting.trig_mask0[i] & 0x0f) << 8) + + ((setting.trig_mask0[i] & 0x0f) << 4) + + ((setting.trig_mask0[i] & 0x0f) << 0); + setting.trig_mask1[i] = ((setting.trig_mask1[i] & 0x0f) << 12) + + ((setting.trig_mask1[i] & 0x0f) << 8) + + ((setting.trig_mask1[i] & 0x0f) << 4) + + ((setting.trig_mask1[i] & 0x0f) << 0); + setting.trig_value0[i] = ((setting.trig_value0[i] & 0x0f) << 12) + + ((setting.trig_value0[i] & 0x0f) << 8) + + ((setting.trig_value0[i] & 0x0f) << 4) + + ((setting.trig_value0[i] & 0x0f) << 0); + setting.trig_value1[i] = ((setting.trig_value1[i] & 0x0f) << 12) + + ((setting.trig_value1[i] & 0x0f) << 8) + + ((setting.trig_value1[i] & 0x0f) << 4) + + ((setting.trig_value1[i] & 0x0f) << 0); + setting.trig_edge0[i] = ((setting.trig_edge0[i] & 0x0f) << 12) + + ((setting.trig_edge0[i] & 0x0f) << 8) + + ((setting.trig_edge0[i] & 0x0f) << 4) + + ((setting.trig_edge0[i] & 0x0f) << 0); + setting.trig_edge1[i] = ((setting.trig_edge1[i] & 0x0f) << 12) + + ((setting.trig_edge1[i] & 0x0f) << 8) + + ((setting.trig_edge1[i] & 0x0f) << 4) + + ((setting.trig_edge1[i] & 0x0f) << 0); + } else if (setting.mode & (1 << HALF_MODE_BIT)) { + setting.trig_mask0[i] = ((setting.trig_mask0[i] & 0xff) << 8) + + ((setting.trig_mask0[i] & 0xff) << 0); + setting.trig_mask1[i] = ((setting.trig_mask1[i] & 0xff) << 8) + + ((setting.trig_mask1[i] & 0xff) << 0); + setting.trig_value0[i] = ((setting.trig_value0[i] & 0xff) << 8) + + ((setting.trig_value0[i] & 0xff) << 0); + setting.trig_value1[i] = ((setting.trig_value1[i] & 0xff) << 8) + + ((setting.trig_value1[i] & 0xff) << 0); + setting.trig_edge0[i] = ((setting.trig_edge0[i] & 0xff) << 8) + + ((setting.trig_edge0[i] & 0xff) << 0); + setting.trig_edge1[i] = ((setting.trig_edge1[i] & 0xff) << 8) + + ((setting.trig_edge1[i] & 0xff) << 0); + } + } + + setting.trig_logic0[i] = (trigger->trigger_logic[i] << 1) + trigger->trigger0_inv[i]; + setting.trig_logic1[i] = (trigger->trigger_logic[i] << 1) + trigger->trigger1_inv[i]; + + setting.trig_count[i] = trigger->trigger0_count[i]; + } + } + + // set GPIF to be wordwide + wr_cmd.header.dest = DSL_CTL_WORDWIDE; + wr_cmd.header.size = 1; + wr_cmd.data[0] = bmWR_WORDWIDE; + if ((ret = command_ctl_wr(hdl, wr_cmd)) != SR_OK) { + sr_err("Sent DSL_CTL_WORDWIDE command failed."); + return SR_ERR; + } + + // send bulk write control command + arm_size = sizeof(struct DSL_setting) / sizeof(uint16_t); + wr_cmd.header.dest = DSL_CTL_BULK_WR; + wr_cmd.header.size = 3; + wr_cmd.data[0] = (uint8_t)arm_size; + wr_cmd.data[1] = (uint8_t)(arm_size >> 8); + wr_cmd.data[2] = (uint8_t)(arm_size >> 16); + if ((ret = command_ctl_wr(hdl, wr_cmd)) != SR_OK) { + sr_err("Sent bulk write command of arm FPGA failed."); + return SR_ERR; + } + //command_fpga_setting(hdl, arm_size); + + // send bulk data + ret = libusb_bulk_transfer(hdl, 2 | LIBUSB_ENDPOINT_OUT, + (unsigned char *)&setting, + sizeof(struct DSL_setting), + &transferred, 1000); + if (ret < 0) { + sr_err("Unable to arm FPGA of dsl device: %s.", + libusb_error_name(ret)); + return SR_ERR; + } else if (transferred != sizeof(struct DSL_setting)) { + sr_err("Arm FPGA error: expacted transfer size %d; actually %d", + sizeof(struct DSL_setting), transferred); + return SR_ERR; + } + + // assert INTRDY high (indicate data end) + wr_cmd.header.dest = DSL_CTL_INTRDY; + wr_cmd.header.size = 1; + wr_cmd.data[0] = bmWR_INTRDY; + if ((ret = command_ctl_wr(hdl, wr_cmd)) != SR_OK) + return SR_ERR; + + + // check FPGA_DONE bit + rd_cmd.header.dest = DSL_CTL_HW_STATUS; + rd_cmd.header.size = 1; + rd_cmd_data = 0; + rd_cmd.data = &rd_cmd_data; + if ((ret = command_ctl_rd(hdl, rd_cmd)) != SR_OK) + return SR_ERR; + if (rd_cmd_data & bmGPIF_DONE) { + sr_info("Arm FPGA done"); + return SR_OK; + } else { + return SR_ERR; + } +} + +SR_PRIV int dsl_fpga_config(struct libusb_device_handle *hdl, const char *filename) +{ + FILE *fw; + int chunksize, ret; + unsigned char *buf; + int transferred; + uint64_t filesize; + struct ctl_wr_cmd wr_cmd; + struct ctl_rd_cmd rd_cmd; + uint8_t rd_cmd_data; + struct stat f_stat; + + sr_info("Configure FPGA using %s", filename); + if ((fw = fopen(filename, "rb")) == NULL) { + sr_err("Unable to open FPGA bit file %s for reading: %s", + filename, strerror(errno)); + return SR_ERR; + } + + if (stat(filename, &f_stat) == -1) + return SR_ERR; + + filesize = (uint64_t)f_stat.st_size; + + if (!(buf = g_try_malloc(filesize))) { + sr_err("FPGA configure buf malloc failed."); + return SR_ERR; + } + + // step0: assert PROG_B low + wr_cmd.header.dest = DSL_CTL_PROG_B; + wr_cmd.header.size = 1; + wr_cmd.data[0] = ~bmWR_PROG_B; + if ((ret = command_ctl_wr(hdl, wr_cmd)) != SR_OK) + return SR_ERR; + + // step1: turn off GREEN/RED led + wr_cmd.header.dest = DSL_CTL_LED; + wr_cmd.header.size = 1; + wr_cmd.data[0] = ~bmLED_GREEN & ~bmLED_RED; + if ((ret = command_ctl_wr(hdl, wr_cmd)) != SR_OK) + return SR_ERR; + + // step2: assert PORG_B high + wr_cmd.header.dest = DSL_CTL_PROG_B; + wr_cmd.header.size = 1; + wr_cmd.data[0] = bmWR_PROG_B; + if ((ret = command_ctl_wr(hdl, wr_cmd)) != SR_OK) + return SR_ERR; + + // step3: wait INIT_B go high + rd_cmd.header.dest = DSL_CTL_HW_STATUS; + rd_cmd.header.size = 1; + rd_cmd_data = 0; + rd_cmd.data = &rd_cmd_data; + while(1) { + if ((ret = command_ctl_rd(hdl, rd_cmd)) != SR_OK) + return SR_ERR; + if (rd_cmd_data & bmFPGA_INIT_B) + break; + } + + // step4: send config ctl command + wr_cmd.header.dest = DSL_CTL_WORDWIDE; + wr_cmd.header.size = 1; + wr_cmd.data[0] = ~bmWR_WORDWIDE; + if ((ret = command_ctl_wr(hdl, wr_cmd)) != SR_OK) { + sr_err("Sent DSL_CTL_WORDWIDE command failed."); + return SR_ERR; + } + wr_cmd.header.dest = DSL_CTL_INTRDY; + wr_cmd.header.size = 1; + wr_cmd.data[0] = (uint8_t)~bmWR_INTRDY; + if ((ret = command_ctl_wr(hdl, wr_cmd)) != SR_OK) + return SR_ERR; + + wr_cmd.header.dest = DSL_CTL_BULK_WR; + wr_cmd.header.size = 3; + wr_cmd.data[0] = (uint8_t)filesize; + wr_cmd.data[1] = (uint8_t)(filesize >> 8); + wr_cmd.data[2] = (uint8_t)(filesize >> 16); + if ((ret = command_ctl_wr(hdl, wr_cmd)) != SR_OK) { + sr_err("Configure FPGA error: send command fpga_config failed."); + return SR_ERR; + } + + // step5: send config data + chunksize = fread(buf, 1, filesize, fw); + if (chunksize == 0) + return SR_ERR; + + ret = libusb_bulk_transfer(hdl, 2 | LIBUSB_ENDPOINT_OUT, + buf, chunksize, + &transferred, 1000); + fclose(fw); + g_free(buf); + + if (ret < 0) { + sr_err("Unable to configure FPGA of dsl device: %s.", + libusb_error_name(ret)); + return SR_ERR; + } else if (transferred != chunksize) { + sr_err("Configure FPGA error: expacted transfer size %d; actually %d.", + chunksize, transferred); + return SR_ERR; + } + + // step6: assert INTRDY high (indicate data end) + wr_cmd.header.dest = DSL_CTL_INTRDY; + wr_cmd.header.size = 1; + wr_cmd.data[0] = bmWR_INTRDY; + if ((ret = command_ctl_wr(hdl, wr_cmd)) != SR_OK) + return SR_ERR; + + // step7: check GPIF_DONE + rd_cmd.header.dest = DSL_CTL_HW_STATUS; + rd_cmd.header.size = 1; + rd_cmd_data = 0; + rd_cmd.data = &rd_cmd_data; + while ((ret = command_ctl_rd(hdl, rd_cmd)) == SR_OK) { + if (rd_cmd_data & bmGPIF_DONE) { + break; + } + } + + // step8: assert INTRDY low + wr_cmd.header.dest = DSL_CTL_INTRDY; + wr_cmd.header.size = 1; + wr_cmd.data[0] = (uint8_t)~bmWR_INTRDY; + if ((ret = command_ctl_wr(hdl, wr_cmd)) != SR_OK) + return SR_ERR; + + // step9: check FPGA_DONE bit + rd_cmd.header.dest = DSL_CTL_HW_STATUS; + rd_cmd.header.size = 1; + rd_cmd_data = 0; + rd_cmd.data = &rd_cmd_data; + if ((ret = command_ctl_rd(hdl, rd_cmd)) != SR_OK) + return SR_ERR; + if (rd_cmd_data & bmFPGA_DONE) { + // step10: turn on GREEN led + wr_cmd.header.dest = DSL_CTL_LED; + wr_cmd.data[0] = bmLED_GREEN; + if ((ret = command_ctl_wr(hdl, wr_cmd)) != SR_OK) + return SR_ERR; + } else { + return SR_ERR; + } + + sr_info("FPGA configure done: %d bytes.", chunksize); + return SR_OK; +} + +SR_PRIV int dsl_config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, + const struct sr_channel *ch, + const struct sr_channel_group *cg) +{ + struct DSL_context *devc; + struct sr_usb_dev_inst *usb; + char str[128]; + + (void)cg; + + switch (id) { + case SR_CONF_CONN: + if (!sdi || !sdi->conn) + return SR_ERR_ARG; + usb = sdi->conn; + if (usb->address == 255) + /* Device still needs to re-enumerate after firmware + * upload, so we don't know its (future) address. */ + return SR_ERR; + snprintf(str, 128, "%d.%d", usb->bus, usb->address); + *data = g_variant_new_string(str); + break; + case SR_CONF_LIMIT_SAMPLES: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_uint64(devc->limit_samples); + break; + case SR_CONF_SAMPLERATE: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_uint64(devc->cur_samplerate); + break; + case SR_CONF_CLOCK_TYPE: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_boolean(devc->clock_type); + break; + case SR_CONF_CLOCK_EDGE: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_boolean(devc->clock_edge); + break; + case SR_CONF_INSTANT: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_boolean(devc->instant); + break; + case SR_CONF_VDIV: + if (!ch) + 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; + *data = g_variant_new_double(ch->vpos); + break; + case SR_CONF_TIMEBASE: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_uint64(devc->timebase); + break; + case SR_CONF_COUPLING: + if (!ch) + return SR_ERR; + *data = g_variant_new_byte(ch->coupling); + break; + case SR_CONF_EN_CH: + if (!ch) + return SR_ERR; + *data = g_variant_new_boolean(ch->enabled); + break; + case SR_CONF_DATALOCK: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_boolean(devc->data_lock); + break; + case SR_CONF_TRIGGER_SLOPE: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_byte(devc->trigger_slope); + break; + case SR_CONF_TRIGGER_SOURCE: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_byte(devc->trigger_source&0x0f); + break; + case SR_CONF_TRIGGER_CHANNEL: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_byte(devc->trigger_source>>4); + break; + case SR_CONF_TRIGGER_VALUE: + if (!ch) + return SR_ERR; + *data = g_variant_new_byte(ch->trig_value); + break; + case SR_CONF_HORIZ_TRIGGERPOS: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + if (sdi->mode == DSO) { + *data = g_variant_new_byte(devc->trigger_hrate); + } else { + *data = g_variant_new_byte(devc->trigger_hpos); + } + break; + case SR_CONF_TRIGGER_HOLDOFF: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_uint64(devc->trigger_holdoff); + break; + case SR_CONF_TRIGGER_MARGIN: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_byte(devc->trigger_margin); + break; + case SR_CONF_ZERO: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + if (sdi->mode == DSO) + *data = g_variant_new_boolean(devc->zero); + else + *data = g_variant_new_boolean(FALSE); + break; + case SR_CONF_ROLL: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_boolean(devc->roll); + break; + case SR_CONF_DSO_BITS: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_byte(devc->dso_bits); + break; + default: + return SR_ERR_NA; + } + + return SR_OK; +} + +SR_PRIV int dsl_dev_open(struct sr_dev_driver *di, struct sr_dev_inst *sdi, gboolean *fpga_done) +{ + struct sr_usb_dev_inst *usb; + struct DSL_context *devc; + int ret; + uint8_t hw_info; + struct ctl_rd_cmd rd_cmd; + + devc = sdi->priv; + usb = sdi->conn; + + /* + * If the firmware was recently uploaded, no dev_open operation should be called. + * Just wait for renumerate -> detach -> attach + */ + ret = SR_ERR; + if (devc->fw_updated > 0) { + return SR_ERR; + } else { + sr_info("%s: Firmware upload was not needed.", __func__); + ret = hw_dev_open(di, sdi); + } + + if (ret != SR_OK) { + sr_err("%s: Unable to open device.", __func__); + return SR_ERR; + } + + ret = libusb_claim_interface(usb->devhdl, USB_INTERFACE); + if (ret != 0) { + switch(ret) { + case LIBUSB_ERROR_BUSY: + sr_err("%s: Unable to claim USB interface. Another " + "program or driver has already claimed it.", __func__); + break; + case LIBUSB_ERROR_NO_DEVICE: + sr_err("%s: Device has been disconnected.", __func__); + break; + default: + sr_err("%s: Unable to claim interface: %s.", + __func__, libusb_error_name(ret)); + break; + } + + return SR_ERR; + } + + rd_cmd.header.dest = DSL_CTL_HW_STATUS; + rd_cmd.header.size = 1; + hw_info = 0; + rd_cmd.data = &hw_info; + if ((ret = command_ctl_rd(usb->devhdl, rd_cmd)) != SR_OK) { + sr_err("Failed to get hardware infos."); + return SR_ERR; + } + *fpga_done = (hw_info & bmFPGA_DONE) != 0; + + if ((sdi->status == SR_ST_ACTIVE) && !(*fpga_done)) { + char *fpga_bit; + if (!(fpga_bit = g_try_malloc(strlen(DS_RES_PATH)+strlen(devc->profile->fpga_bit33)+1))) { + sr_err("fpag_bit path malloc error!"); + return SR_ERR_MALLOC; + } + strcpy(fpga_bit, DS_RES_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 = dsl_fpga_config(usb->devhdl, fpga_bit); + g_free(fpga_bit); + if (ret != SR_OK) { + sr_err("%s: Configure FPGA failed!", __func__); + return SR_ERR; + } + } + + + return SR_OK; +} + +SR_PRIV int dsl_dev_close(struct sr_dev_inst *sdi) +{ + struct sr_usb_dev_inst *usb; + + usb = sdi->conn; + if (usb->devhdl == NULL) + return SR_ERR; + + sr_info("%s: Closing device %d on %d.%d interface %d.", + sdi->driver->name, sdi->index, usb->bus, usb->address, USB_INTERFACE); + libusb_release_interface(usb->devhdl, USB_INTERFACE); + libusb_close(usb->devhdl); + usb->devhdl = NULL; + sdi->status = SR_ST_INACTIVE; + + return SR_OK; +} + +SR_PRIV int dsl_dev_acquisition_stop(const struct sr_dev_inst *sdi, void *cb_data) +{ + (void)cb_data; + + struct DSL_context *devc; + struct sr_usb_dev_inst *usb; + int ret; + struct ctl_wr_cmd wr_cmd; + + devc = sdi->priv; + usb = sdi->conn; + + if (!devc->abort) { + devc->abort = TRUE; + dsl_wr_reg(sdi, EEWP_ADDR, bmFORCE_RDY); + } else if (devc->status == DSL_FINISH) { + /* Stop GPIF acquisition */ + wr_cmd.header.dest = DSL_CTL_STOP; + wr_cmd.header.size = 0; + if ((ret = command_ctl_wr(usb->devhdl, wr_cmd)) != SR_OK) + sr_err("%s: Sent acquisition stop command failed!", __func__); + else + sr_info("%s: Sent acquisition stop command!", __func__); + } + + return SR_OK; +} + +SR_PRIV int dsl_dev_status_get(const struct sr_dev_inst *sdi, struct sr_status *status, int begin, int end) +{ + int ret = SR_ERR; + struct ctl_rd_cmd rd_cmd; + + if (sdi) { + struct DSL_context *devc; + struct sr_usb_dev_inst *usb; + + devc = sdi->priv; + usb = sdi->conn; + if (devc->status == DSL_START) { + rd_cmd.header.dest = DSL_CTL_DSO_MEASURE; + rd_cmd.header.offset = begin; + rd_cmd.header.size = end - begin + 1; + rd_cmd.data = (unsigned char*)status; + ret = command_ctl_rd(usb->devhdl, rd_cmd); + } else if (devc->mstatus_valid) { + *status = devc->mstatus; + ret = SR_OK; + } + } + + return ret; +} + +static unsigned int to_bytes_per_ms(struct DSL_context *devc) +{ + struct sr_dev_inst *sdi = devc->cb_data; + if (devc->cur_samplerate > SR_MHZ(100)) + return SR_MHZ(100) / 1000 * dsl_en_ch_num(sdi) / 8; + else + return devc->cur_samplerate / 1000 * dsl_en_ch_num(sdi) / 8; +} + +static size_t get_buffer_size(struct DSL_context *devc) +{ + size_t s; + + /* + * The buffer should be large enough to hold 10ms of data and + * a multiple of 512. + */ + s = single_buffer_time * to_bytes_per_ms(devc); + //s = to_bytes_per_ms(devc->cur_samplerate); + return (s + 511) & ~511; +} + +static unsigned int get_number_of_transfers(struct DSL_context *devc) +{ + unsigned int n; + /* Total buffer size should be able to hold about 100ms of data. */ + n = ceil(total_buffer_time * 1.0f * to_bytes_per_ms(devc) / get_buffer_size(devc)); + + if (n > NUM_SIMUL_TRANSFERS) + return NUM_SIMUL_TRANSFERS; + + return n; +} + +SR_PRIV unsigned int dsl_get_timeout(struct DSL_context *devc) +{ + size_t total_size; + unsigned int timeout; + + total_size = get_buffer_size(devc) * get_number_of_transfers(devc); + timeout = total_size / to_bytes_per_ms(devc); + + if (devc->op_mode == SR_OP_STREAM) + return timeout + timeout / 4; /* Leave a headroom of 25% percent. */ + else + return 1000; +} + +static void finish_acquisition(struct DSL_context *devc) +{ + struct sr_datafeed_packet packet; + + sr_err("%s: send SR_DF_END packet", __func__); + /* Terminate session. */ + packet.type = SR_DF_END; + packet.status = SR_PKT_OK; + sr_session_send(devc->cb_data, &packet); + + if (devc->num_transfers != 0) { + devc->num_transfers = 0; + g_free(devc->transfers); + } + + devc->status = DSL_FINISH; +} + +static void free_transfer(struct libusb_transfer *transfer) +{ + struct DSL_context *devc; + unsigned int i; + + devc = transfer->user_data; + + g_free(transfer->buffer); + transfer->buffer = NULL; + libusb_free_transfer(transfer); + + for (i = 0; i < devc->num_transfers; i++) { + if (devc->transfers[i] == transfer) { + devc->transfers[i] = NULL; + break; + } + } + + devc->submitted_transfers--; + if (devc->submitted_transfers == 0) + finish_acquisition(devc); +} + +static void resubmit_transfer(struct libusb_transfer *transfer) +{ + int ret; + + if ((ret = libusb_submit_transfer(transfer)) == LIBUSB_SUCCESS) + return; + + free_transfer(transfer); + /* TODO: Stop session? */ + + sr_err("%s: %s", __func__, libusb_error_name(ret)); +} + +static void receive_transfer(struct libusb_transfer *transfer) +{ + struct sr_datafeed_packet packet; + struct sr_datafeed_logic logic; + struct sr_datafeed_dso dso; + struct sr_datafeed_analog analog; + uint64_t cur_sample_count = 0; + + uint8_t *cur_buf = transfer->buffer; + struct DSL_context *devc = transfer->user_data; + struct sr_dev_inst *sdi = devc->cb_data; + const int sample_width = (devc->sample_wide) ? 2 : 1; + + if (devc->status == DSL_START) + devc->status = DSL_DATA; + if (devc->data_lock) { + resubmit_transfer(transfer); + devc->trf_completed = 1; + return; + } + + if (devc->abort) + devc->status = DSL_STOP; + + sr_info("%" PRIu64 ": receive_transfer(): status %d; timeout %d; received %d bytes.", + g_get_monotonic_time(), transfer->status, transfer->timeout, transfer->actual_length); + + switch (transfer->status) { + case LIBUSB_TRANSFER_COMPLETED: + case LIBUSB_TRANSFER_TIMED_OUT: /* We may have received some data though. */ + break; + default: + devc->status = DSL_ERROR; + break; + } + + packet.status = SR_PKT_OK; + if (devc->status == DSL_DATA && + transfer->actual_length != 0) { + /* Send the incoming transfer to the session bus. */ + // check packet type + if (sdi->mode == LOGIC) { + packet.type = SR_DF_LOGIC; + packet.payload = &logic; + cur_sample_count = transfer->actual_length * 8 / dsl_en_ch_num(sdi) ; + logic.length = transfer->actual_length; + logic.format = LA_CROSS_DATA; + logic.data_error = 0; + logic.data = cur_buf; + } else if (sdi->mode == DSO) { + if (!devc->instant) { + const uint32_t mstatus_offset = devc->limit_samples / (g_slist_length(sdi->channels)/dsl_en_ch_num(sdi)); + devc->mstatus.pkt_id = *((const uint16_t*)cur_buf + mstatus_offset); + devc->mstatus.ch0_max = *((const uint8_t*)cur_buf + mstatus_offset*2 + 1*2); + devc->mstatus.ch0_min = *((const uint8_t*)cur_buf + mstatus_offset*2 + 3); + devc->mstatus.ch0_period = *((const uint32_t*)cur_buf + mstatus_offset/2 + 2/2); + devc->mstatus.ch0_period += ((uint64_t)*((const uint32_t*)cur_buf + mstatus_offset/2 + 4/2)) << 32; + devc->mstatus.ch0_pcnt = *((const uint32_t*)cur_buf + mstatus_offset/2 + 6/2); + devc->mstatus.ch1_max = *((const uint8_t*)cur_buf + mstatus_offset*2 + 9*2); + devc->mstatus.ch1_min = *((const uint8_t*)cur_buf + mstatus_offset*2 + 19); + devc->mstatus.ch1_period = *((const uint32_t*)cur_buf + mstatus_offset/2 + 10/2); + devc->mstatus.ch1_period += ((uint64_t)*((const uint32_t*)cur_buf + mstatus_offset/2 + 12/2)) << 32; + devc->mstatus.ch1_pcnt = *((const uint32_t*)cur_buf + mstatus_offset/2 + 14/2); + devc->mstatus.vlen = *((const uint32_t*)cur_buf + mstatus_offset/2 + 16/2) & 0x7fffffff; + devc->mstatus.stream_mode = *((const uint32_t*)cur_buf + mstatus_offset/2 + 16/2) & 0x80000000; + devc->mstatus.sample_divider = *((const uint32_t*)cur_buf + mstatus_offset/2 + 18/2) & 0x0fffffff; + devc->mstatus.sample_divider_tog = *((const uint32_t*)cur_buf + mstatus_offset/2 + 18/2) & 0x80000000; + devc->mstatus.trig_flag = *((const uint32_t*)cur_buf + mstatus_offset/2 + 18/2) & 0x40000000; + } else { + devc->mstatus.vlen = instant_buffer_size; + } + + const uint32_t divider = devc->zero ? 0x1 : (uint32_t)ceil(DSCOPE_MAX_SAMPLERATE * 1.0 / devc->cur_samplerate / dsl_en_ch_num(sdi)); + if ((devc->mstatus.pkt_id == DSO_PKTID && + devc->mstatus.sample_divider == divider && + devc->mstatus.vlen != 0 && + devc->mstatus.vlen <= (transfer->actual_length - 512) / sample_width) || + devc->instant) { + devc->roll = (devc->mstatus.stream_mode != 0); + devc->mstatus_valid = devc->instant ? FALSE : TRUE; + packet.type = SR_DF_DSO; + packet.payload = &dso; + dso.probes = sdi->channels; + //dso.num_samples = (transfer->actual_length - 512) / sample_width; + cur_sample_count = 2 * devc->mstatus.vlen / dsl_en_ch_num(sdi) ; + dso.num_samples = cur_sample_count; + dso.mq = SR_MQ_VOLTAGE; + dso.unit = SR_UNIT_VOLT; + dso.mqflags = SR_MQFLAG_AC; + dso.samplerate_tog = (devc->mstatus.sample_divider_tog != 0); + dso.trig_flag = (devc->mstatus.trig_flag != 0); + dso.data = cur_buf; + } else { + packet.type = SR_DF_DSO; + packet.status = SR_PKT_DATA_ERROR; + devc->mstatus_valid = FALSE; + } + } else { + packet.type = SR_DF_ANALOG; + packet.payload = &analog; + analog.probes = sdi->channels; + cur_sample_count = transfer->actual_length / (sample_width * g_slist_length(analog.probes)); + analog.num_samples = cur_sample_count; + analog.mq = SR_MQ_VOLTAGE; + analog.unit = SR_UNIT_VOLT; + analog.mqflags = SR_MQFLAG_AC; + analog.data = (float *)cur_buf; + } + + if ((devc->limit_samples && devc->num_bytes < devc->actual_bytes) || + sdi->mode != LOGIC ) { + const uint64_t remain_length= devc->actual_bytes - devc->num_bytes; + logic.length = min(logic.length, remain_length); + + /* send data to session bus */ + if (!devc->overflow) { + if (packet.status == SR_PKT_OK) + sr_session_send(sdi, &packet); + } else { + packet.type = SR_DF_OVERFLOW; + packet.payload = NULL; + sr_session_send(sdi, &packet); + } + } + + devc->num_samples += cur_sample_count; + devc->num_bytes += logic.length; + if (sdi->mode == LOGIC && + devc->limit_samples && + devc->num_bytes >= devc->actual_bytes) { + devc->status = DSL_STOP; + } else if ((sdi->mode != DSO || devc->instant) && + devc->limit_samples && + devc->num_samples >= devc->actual_samples) { + devc->status = DSL_STOP; + } + } + + if (devc->status == DSL_DATA) + resubmit_transfer(transfer); + else + free_transfer(transfer); + + devc->trf_completed = 1; +} + +static void receive_trigger_pos(struct libusb_transfer *transfer) +{ + struct DSL_context *devc; + struct sr_datafeed_packet packet; + struct ds_trigger_pos *trigger_pos; + const struct sr_dev_inst *sdi; + uint64_t remain_cnt; + + packet.status = SR_PKT_OK; + devc = transfer->user_data; + sdi = devc->cb_data; + trigger_pos = (struct ds_trigger_pos *)transfer->buffer; + if (devc->status != DSL_ABORT) + devc->status = DSL_ERROR; + if (!devc->abort && transfer->status == LIBUSB_TRANSFER_COMPLETED && + trigger_pos->check_id == TRIG_CHECKID) { + sr_info("%" PRIu64 ": receive_trigger_pos(): status %d; timeout %d; received %d bytes.", + g_get_monotonic_time(), transfer->status, transfer->timeout, transfer->actual_length); + remain_cnt = trigger_pos->remain_cnt_h; + remain_cnt = (remain_cnt << 32) + trigger_pos->remain_cnt_l; + if (transfer->actual_length == sizeof(struct ds_trigger_pos)) { + if (sdi->mode != LOGIC || + devc->stream || + remain_cnt < devc->limit_samples) { + if (sdi->mode == LOGIC && (!devc->stream || (devc->status == DSL_ABORT))) { + devc->actual_samples = devc->limit_samples - remain_cnt; + devc->actual_bytes = devc->actual_samples / DSLOGIC_ATOMIC_SAMPLES * dsl_en_ch_num(sdi) * DSLOGIC_ATOMIC_SIZE; + devc->actual_samples = devc->actual_bytes / dsl_en_ch_num(sdi) * 8; + } + + packet.type = SR_DF_TRIGGER; + packet.payload = trigger_pos; + sr_session_send(sdi, &packet); + + devc->status = DSL_DATA; + } + } + } else if (!devc->abort) { + sr_err("%s: trigger packet data error.", __func__); + packet.type = SR_DF_TRIGGER; + packet.payload = trigger_pos; + packet.status = SR_PKT_DATA_ERROR; + sr_session_send(sdi, &packet); + } + + free_transfer(transfer); +} + +SR_PRIV int dsl_start_transfers(const struct sr_dev_inst *sdi) +{ + struct DSL_context *devc; + struct sr_usb_dev_inst *usb; + struct libusb_transfer *transfer; + unsigned int i, num_transfers; + int ret; + unsigned char *buf; + size_t size; + unsigned int dso_buffer_size; + struct ds_trigger_pos *trigger_pos; + + devc = sdi->priv; + usb = sdi->conn; + + if (devc->instant) + dso_buffer_size = instant_buffer_size * g_slist_length(sdi->channels); + else + dso_buffer_size = devc->limit_samples * dsl_en_ch_num(sdi) + 512; + + num_transfers = (devc->stream) ? get_number_of_transfers(devc) : 1; + size = (sdi->mode == DSO) ? dso_buffer_size : + (devc->stream) ? get_buffer_size(devc) : instant_buffer_size; + + /* trigger packet transfer */ + if (!(trigger_pos = g_try_malloc0(sizeof(struct ds_trigger_pos)))) { + sr_err("%s: USB trigger_pos buffer malloc failed.", __func__); + return SR_ERR_MALLOC; + } + devc->transfers = g_try_malloc0(sizeof(*devc->transfers) * (num_transfers + 1)); + if (!devc->transfers) { + sr_err("%s: USB transfer malloc failed.", __func__); + return SR_ERR_MALLOC; + } + transfer = libusb_alloc_transfer(0); + libusb_fill_bulk_transfer(transfer, usb->devhdl, + 6 | LIBUSB_ENDPOINT_IN, (unsigned char *)trigger_pos, sizeof(struct ds_trigger_pos), + (libusb_transfer_cb_fn)receive_trigger_pos, devc, 0); + if ((ret = libusb_submit_transfer(transfer)) != 0) { + sr_err("%s: Failed to submit trigger_pos transfer: %s.", + __func__, libusb_error_name(ret)); + libusb_free_transfer(transfer); + g_free(trigger_pos); + devc->status = DSL_ERROR; + return SR_ERR; + } else { + devc->num_transfers++; + devc->transfers[0] = transfer; + devc->submitted_transfers++; + } + + /* data packet transfer */ + for (i = 1; i <= num_transfers; i++) { + if (!(buf = g_try_malloc(size))) { + sr_err("%s: USB transfer buffer malloc failed.", __func__); + return SR_ERR_MALLOC; + } + transfer = libusb_alloc_transfer(0); + libusb_fill_bulk_transfer(transfer, usb->devhdl, + 6 | LIBUSB_ENDPOINT_IN, buf, size, + (libusb_transfer_cb_fn)receive_transfer, devc, 0); + if ((ret = libusb_submit_transfer(transfer)) != 0) { + sr_err("%s: Failed to submit transfer: %s.", + __func__, libusb_error_name(ret)); + libusb_free_transfer(transfer); + g_free(buf); + devc->status = DSL_ERROR; + devc->abort = TRUE; + return SR_ERR; + } + devc->transfers[i] = transfer; + devc->submitted_transfers++; + devc->num_transfers++; + } + + return SR_OK; +} diff --git a/libsigrok4DSL/hardware/DSL/dsl.h b/libsigrok4DSL/hardware/DSL/dsl.h index 85fce25c..42dbddd6 100644 --- a/libsigrok4DSL/hardware/DSL/dsl.h +++ b/libsigrok4DSL/hardware/DSL/dsl.h @@ -25,6 +25,21 @@ #include "libsigrok.h" #include "libsigrok-internal.h" +#include +#include +#include +#include +#include +#include + +#include +#include + +#undef min +#define min(a,b) ((a)<(b)?(a):(b)) +#undef max +#define max(a,b) ((a)>(b)?(a):(b)) + /* Message logging helpers with subsystem-specific prefix string. */ #define LOG_PREFIX "DSL Hardware: " #define ds_log(l, s, args...) ds_log(l, LOG_PREFIX s, ## args) @@ -43,8 +58,8 @@ #define NUM_SIMUL_TRANSFERS 64 #define MAX_EMPTY_TRANSFERS (NUM_SIMUL_TRANSFERS * 2) -#define DSL_REQUIRED_VERSION_MAJOR 1 -#define DSL_REQUIRED_VERSION_MINOR 1 +#define DSL_REQUIRED_VERSION_MAJOR 2 +#define DSL_REQUIRED_VERSION_MINOR 0 #define MAX_8BIT_SAMPLE_RATE DS_MHZ(24) #define MAX_16BIT_SAMPLE_RATE DS_MHZ(12) @@ -233,6 +248,12 @@ static const struct DSL_profile supported_DSCope[] = { "DSCope20.bin", DEV_CAPS_16BIT}, + {0x2A0E, 0x0022, NULL, "DSCope B20", NULL, + "DSCopeB20.fw", + "DSCope20.bin", + "DSCope20.bin", + DEV_CAPS_16BIT}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; @@ -326,7 +347,9 @@ struct DSL_context { GIOChannel *channel; int status; + int trf_completed; gboolean mstatus_valid; + struct sr_status mstatus; gboolean abort; gboolean overflow; }; @@ -375,4 +398,29 @@ struct DSL_vga { uint16_t voff1; }; +SR_PRIV int dsl_en_ch_num(const struct sr_dev_inst *sdi); +SR_PRIV gboolean dsl_check_conf_profile(libusb_device *dev); +SR_PRIV int dsl_configure_probes(const struct sr_dev_inst *sdi); +SR_PRIV uint64_t dsl_channel_depth(const struct sr_dev_inst *sdi); + +SR_PRIV int dsl_wr_reg(const struct sr_dev_inst *sdi, uint8_t addr, uint8_t value); +SR_PRIV int dsl_wr_dso(const struct sr_dev_inst *sdi, uint64_t cmd); +SR_PRIV int dsl_wr_nvm(const struct sr_dev_inst *sdi, unsigned char *ctx, uint16_t addr, uint8_t len); +SR_PRIV int dsl_rd_nvm(const struct sr_dev_inst *sdi, unsigned char *ctx, uint16_t addr, uint8_t len); + +SR_PRIV int dsl_fpga_arm(const struct sr_dev_inst *sdi); +SR_PRIV int dsl_fpga_config(struct libusb_device_handle *hdl, const char *filename); + +SR_PRIV int dsl_config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, + const struct sr_channel *ch, + const struct sr_channel_group *cg); + +SR_PRIV int dsl_dev_open(struct sr_dev_driver *di, struct sr_dev_inst *sdi, gboolean *fpga_done); +SR_PRIV int dsl_dev_close(struct sr_dev_inst *sdi); +SR_PRIV int dsl_dev_acquisition_stop(const struct sr_dev_inst *sdi, void *cb_data); +SR_PRIV int dsl_dev_status_get(const struct sr_dev_inst *sdi, struct sr_status *status, int begin, int end); + +SR_PRIV unsigned int dsl_get_timeout(struct DSL_context *devc); +SR_PRIV int dsl_start_transfers(const struct sr_dev_inst *sdi); + #endif diff --git a/libsigrok4DSL/hardware/DSL/dslogic.c b/libsigrok4DSL/hardware/DSL/dslogic.c old mode 100644 new mode 100755 index c89bd527..634ed533 --- a/libsigrok4DSL/hardware/DSL/dslogic.c +++ b/libsigrok4DSL/hardware/DSL/dslogic.c @@ -20,16 +20,7 @@ #include "libsigrok.h" #include "libsigrok-internal.h" -#include -#include -#include -#include -#include -#include -#include -#include -//#include #include "dsl.h" #include "command.h" @@ -258,68 +249,6 @@ static uint16_t opmodes_show_count = 3; SR_PRIV struct sr_dev_driver DSLogic_driver_info; static struct sr_dev_driver *di = &DSLogic_driver_info; -extern struct ds_trigger *trigger; - -struct sr_status mstatus; - -/** - * Check the USB configuration to determine if this is an DSLogic device. - * - * @return TRUE if the device's configuration profile match DSLogic - * configuration, FALSE otherwise. - */ -static gboolean check_conf_profile(libusb_device *dev) -{ - struct libusb_device_descriptor des; - struct libusb_device_handle *hdl; - gboolean ret; - unsigned char strdesc[64]; - - hdl = NULL; - ret = FALSE; - while (!ret) { - /* Assume the FW has not been loaded, unless proven wrong. */ - if (libusb_get_device_descriptor(dev, &des) != 0) - break; - - if (libusb_open(dev, &hdl) != 0) - break; - - if (libusb_get_string_descriptor_ascii(hdl, - des.iManufacturer, strdesc, sizeof(strdesc)) < 0) - break; - if (strncmp((const char *)strdesc, "DreamSourceLab", 14)) - break; - - if (libusb_get_string_descriptor_ascii(hdl, - des.iProduct, strdesc, sizeof(strdesc)) < 0) - break; - if (strncmp((const char *)strdesc, "USB-based Instrument", 20)) - break; - - /* If we made it here, it must be an DSLogic. */ - ret = TRUE; - } - if (hdl) - libusb_close(hdl); - - return ret; -} - -static int en_ch_num(const struct sr_dev_inst *sdi) -{ - GSList *l; - int channel_en_cnt = 0; - - for (l = sdi->channels; l; l = l->next) { - struct sr_channel *probe = (struct sr_channel *)l->data; - channel_en_cnt += probe->enabled; - } - channel_en_cnt += (channel_en_cnt == 0); - - return channel_en_cnt; -} - static int counts_size(const struct sr_dev_inst *sdi) { struct DSL_context *devc = sdi->priv; @@ -337,459 +266,60 @@ static int counts_size(const struct sr_dev_inst *sdi) return ARRAY_SIZE(samplecounts); } -static uint64_t channel_depth(const struct sr_dev_inst *sdi) +static void probe_init(struct sr_dev_inst *sdi) { - int ch_num = en_ch_num(sdi); - if (strcmp(sdi->model, "DSLogic Basic") == 0) - return DSLOGIC_BASIC_MEM_DEPTH / (ch_num ? ch_num : 1); - else - return DSLOGIC_MEM_DEPTH / (ch_num ? ch_num : 1); -} - -static int fpga_setting(const struct sr_dev_inst *sdi) -{ - struct DSL_context *devc; - struct sr_usb_dev_inst *usb; - struct libusb_device_handle *hdl; - struct DSL_setting setting; - int ret; - int transferred; - int result; int i; GSList *l; - uint32_t tmp_u32; - uint64_t tmp_u64; - const int ch_num = en_ch_num(sdi); - - devc = sdi->priv; - usb = sdi->conn; - hdl = usb->devhdl; - - setting.sync = 0xf5a5f5a5; - setting.mode_header = 0x0001; - setting.divider_header = 0x0102; - setting.count_header = 0x0302; - setting.trig_pos_header = 0x0502; - setting.trig_glb_header = 0x0701; - setting.ch_en_header = 0x0801; - setting.trig_header = 0x40a0; - setting.end_sync = 0xfa5afa5a; - - // basic configuration - setting.mode = (trigger->trigger_en << TRIG_EN_BIT) + - (devc->clock_type << CLK_TYPE_BIT) + - (devc->clock_edge << CLK_EDGE_BIT) + - (devc->rle_mode << RLE_MODE_BIT) + - ((sdi->mode == DSO) << DSO_MODE_BIT) + - ((((devc->cur_samplerate == (2 * DSLOGIC_MAX_LOGIC_SAMPLERATE)) && sdi->mode != DSO) || (sdi->mode == ANALOG)) << HALF_MODE_BIT) + - ((devc->cur_samplerate == (4 * DSLOGIC_MAX_LOGIC_SAMPLERATE)) << QUAR_MODE_BIT) + - ((sdi->mode == ANALOG) << ANALOG_MODE_BIT) + - ((devc->filter == SR_FILTER_1T) << FILTER_BIT) + - (devc->instant << INSTANT_BIT) + - ((trigger->trigger_mode == SERIAL_TRIGGER) << STRIG_MODE_BIT) + - ((devc->stream) << STREAM_MODE_BIT) + - ((devc->op_mode == SR_OP_LOOPBACK_TEST) << LPB_TEST_BIT) + - ((devc->op_mode == SR_OP_EXTERNAL_TEST) << EXT_TEST_BIT) + - ((devc->op_mode == SR_OP_INTERNAL_TEST) << INT_TEST_BIT); - - // sample rate divider - tmp_u32 = (sdi->mode == DSO) ? (uint32_t)ceil(DSLOGIC_MAX_DSO_SAMPLERATE * 1.0 / devc->cur_samplerate / ch_num) : - (uint32_t)ceil(DSLOGIC_MAX_LOGIC_SAMPLERATE * 1.0 / devc->cur_samplerate); - setting.div_l = tmp_u32 & 0x0000ffff; - setting.div_h = tmp_u32 >> 16; - - // capture counter - // analog: 16bits, but sample with half mode(0-7 valid only) - tmp_u64 = (sdi->mode == DSO) ? (devc->limit_samples / (g_slist_length(sdi->channels) / ch_num)) : - (sdi->mode == ANALOG) ? (devc->limit_samples * g_slist_length(sdi->channels) * 4) : - (devc->limit_samples); - tmp_u64 >>= 4; // hardware minimum unit 64 - setting.cnt_l = tmp_u64 & 0x0000ffff; - setting.cnt_h = tmp_u64 >> 16; - - // trigger position - // must be align to minimum parallel bits - tmp_u32 = max((uint32_t)(trigger->trigger_pos / 100.0 * devc->limit_samples), DSLOGIC_ATOMIC_SAMPLES); - if (devc->stream) - tmp_u32 = min(tmp_u32, channel_depth(sdi) * 10 / 100); - else - tmp_u32 = min(tmp_u32, channel_depth(sdi) * DS_MAX_TRIG_PERCENT / 100); - setting.tpos_l = tmp_u32 & DSLOGIC_ATOMIC_MASK; - setting.tpos_h = tmp_u32 >> 16; - - // trigger global settings - setting.trig_glb = ((ch_num & 0xf) << 4) + - trigger->trigger_stages; - - // channel enable mapping - setting.ch_en = 0; for (l = sdi->channels; l; l = l->next) { struct sr_channel *probe = (struct sr_channel *)l->data; - setting.ch_en += probe->enabled << probe->index; - } - - // trigger advanced configuration - if (trigger->trigger_mode == SIMPLE_TRIGGER) { - setting.trig_mask0[0] = ds_trigger_get_mask0(TriggerStages); - setting.trig_mask1[0] = ds_trigger_get_mask1(TriggerStages); - - setting.trig_value0[0] = ds_trigger_get_value0(TriggerStages); - setting.trig_value1[0] = ds_trigger_get_value1(TriggerStages); - - setting.trig_edge0[0] = ds_trigger_get_edge0(TriggerStages); - setting.trig_edge1[0] = ds_trigger_get_edge1(TriggerStages); - - if (setting.mode & (1 << QUAR_MODE_BIT)) { - setting.trig_mask0[0] = ((setting.trig_mask0[0] & 0x0f) << 12) + - ((setting.trig_mask0[0] & 0x0f) << 8) + - ((setting.trig_mask0[0] & 0x0f) << 4) + - ((setting.trig_mask0[0] & 0x0f) << 0); - setting.trig_mask1[0] = ((setting.trig_mask1[0] & 0x0f) << 12) + - ((setting.trig_mask1[0] & 0x0f) << 8) + - ((setting.trig_mask1[0] & 0x0f) << 4) + - ((setting.trig_mask1[0] & 0x0f) << 0); - setting.trig_value0[0] = ((setting.trig_value0[0] & 0x0f) << 12) + - ((setting.trig_value0[0] & 0x0f) << 8) + - ((setting.trig_value0[0] & 0x0f) << 4) + - ((setting.trig_value0[0] & 0x0f) << 0); - setting.trig_value1[0] = ((setting.trig_value1[0] & 0x0f) << 12) + - ((setting.trig_value1[0] & 0x0f) << 8) + - ((setting.trig_value1[0] & 0x0f) << 4) + - ((setting.trig_value1[0] & 0x0f) << 0); - setting.trig_edge0[0] = ((setting.trig_edge0[0] & 0x0f) << 12) + - ((setting.trig_edge0[0] & 0x0f) << 8) + - ((setting.trig_edge0[0] & 0x0f) << 4) + - ((setting.trig_edge0[0] & 0x0f) << 0); - setting.trig_edge1[0] = ((setting.trig_edge1[0] & 0x0f) << 12) + - ((setting.trig_edge1[0] & 0x0f) << 8) + - ((setting.trig_edge1[0] & 0x0f) << 4) + - ((setting.trig_edge1[0] & 0x0f) << 0); - } else if (setting.mode & (1 << HALF_MODE_BIT)) { - setting.trig_mask0[0] = ((setting.trig_mask0[0] & 0xff) << 8) + - ((setting.trig_mask0[0] & 0xff) << 0); - setting.trig_mask1[0] = ((setting.trig_mask1[0] & 0xff) << 8) + - ((setting.trig_mask1[0] & 0xff) << 0); - setting.trig_value0[0] = ((setting.trig_value0[0] & 0xff) << 8) + - ((setting.trig_value0[0] & 0xff) << 0); - setting.trig_value1[0] = ((setting.trig_value1[0] & 0xff) << 8) + - ((setting.trig_value1[0] & 0xff) << 0); - setting.trig_edge0[0] = ((setting.trig_edge0[0] & 0xff) << 8) + - ((setting.trig_edge0[0] & 0xff) << 0); - setting.trig_edge1[0] = ((setting.trig_edge1[0] & 0xff) << 8) + - ((setting.trig_edge1[0] & 0xff) << 0); - } - - setting.trig_logic0[0] = (trigger->trigger_logic[TriggerStages] << 1) + trigger->trigger0_inv[TriggerStages]; - setting.trig_logic1[0] = (trigger->trigger_logic[TriggerStages] << 1) + trigger->trigger1_inv[TriggerStages]; - - setting.trig_count[0] = trigger->trigger0_count[TriggerStages]; - - for (i = 1; i < NUM_TRIGGER_STAGES; i++) { - setting.trig_mask0[i] = 0xffff; - setting.trig_mask1[i] = 0xffff; - - setting.trig_value0[i] = 0; - setting.trig_value1[i] = 0; - - setting.trig_edge0[i] = 0; - setting.trig_edge1[i] = 0; - - setting.trig_logic0[i] = 2; - setting.trig_logic1[i] = 2; - - setting.trig_count[i] = 0; - } - } else { - for (i = 0; i < NUM_TRIGGER_STAGES; i++) { - setting.trig_mask0[i] = ds_trigger_get_mask0(i); - setting.trig_mask1[i] = ds_trigger_get_mask1(i); - - setting.trig_value0[i] = ds_trigger_get_value0(i); - setting.trig_value1[i] = ds_trigger_get_value1(i); - - setting.trig_edge0[i] = ds_trigger_get_edge0(i); - setting.trig_edge1[i] = ds_trigger_get_edge1(i); - - if (setting.mode & (1 << STRIG_MODE_BIT) && i == STriggerDataStage) { - // serial trigger, data mask/value should not be duplicated - } else { - if (setting.mode & (1 << QUAR_MODE_BIT)) { - setting.trig_mask0[i] = ((setting.trig_mask0[i] & 0x0f) << 12) + - ((setting.trig_mask0[i] & 0x0f) << 8) + - ((setting.trig_mask0[i] & 0x0f) << 4) + - ((setting.trig_mask0[i] & 0x0f) << 0); - setting.trig_mask1[i] = ((setting.trig_mask1[i] & 0x0f) << 12) + - ((setting.trig_mask1[i] & 0x0f) << 8) + - ((setting.trig_mask1[i] & 0x0f) << 4) + - ((setting.trig_mask1[i] & 0x0f) << 0); - setting.trig_value0[i] = ((setting.trig_value0[i] & 0x0f) << 12) + - ((setting.trig_value0[i] & 0x0f) << 8) + - ((setting.trig_value0[i] & 0x0f) << 4) + - ((setting.trig_value0[i] & 0x0f) << 0); - setting.trig_value1[i] = ((setting.trig_value1[i] & 0x0f) << 12) + - ((setting.trig_value1[i] & 0x0f) << 8) + - ((setting.trig_value1[i] & 0x0f) << 4) + - ((setting.trig_value1[i] & 0x0f) << 0); - setting.trig_edge0[i] = ((setting.trig_edge0[i] & 0x0f) << 12) + - ((setting.trig_edge0[i] & 0x0f) << 8) + - ((setting.trig_edge0[i] & 0x0f) << 4) + - ((setting.trig_edge0[i] & 0x0f) << 0); - setting.trig_edge1[i] = ((setting.trig_edge1[i] & 0x0f) << 12) + - ((setting.trig_edge1[i] & 0x0f) << 8) + - ((setting.trig_edge1[i] & 0x0f) << 4) + - ((setting.trig_edge1[i] & 0x0f) << 0); - } else if (setting.mode & (1 << HALF_MODE_BIT)) { - setting.trig_mask0[i] = ((setting.trig_mask0[i] & 0xff) << 8) + - ((setting.trig_mask0[i] & 0xff) << 0); - setting.trig_mask1[i] = ((setting.trig_mask1[i] & 0xff) << 8) + - ((setting.trig_mask1[i] & 0xff) << 0); - setting.trig_value0[i] = ((setting.trig_value0[i] & 0xff) << 8) + - ((setting.trig_value0[i] & 0xff) << 0); - setting.trig_value1[i] = ((setting.trig_value1[i] & 0xff) << 8) + - ((setting.trig_value1[i] & 0xff) << 0); - setting.trig_edge0[i] = ((setting.trig_edge0[i] & 0xff) << 8) + - ((setting.trig_edge0[i] & 0xff) << 0); - setting.trig_edge1[i] = ((setting.trig_edge1[i] & 0xff) << 8) + - ((setting.trig_edge1[i] & 0xff) << 0); - } - } - - setting.trig_logic0[i] = (trigger->trigger_logic[i] << 1) + trigger->trigger0_inv[i]; - setting.trig_logic1[i] = (trigger->trigger_logic[i] << 1) + trigger->trigger1_inv[i]; - - setting.trig_count[i] = trigger->trigger0_count[i]; + if (sdi->mode == DSO) { + probe->vdiv = 1000; + probe->vfactor = 1; + probe->vpos = 0; + probe->coupling = SR_DC_COUPLING; + probe->trig_value = 0x80; + probe->ms_show = TRUE; + for (i = DSO_MS_BEGIN; i < DSO_MS_END; i++) + probe->ms_en[i] = default_ms_en[i]; } } - - result = SR_OK; - ret = libusb_bulk_transfer(hdl, 2 | LIBUSB_ENDPOINT_OUT, - (unsigned char *)&setting, - sizeof(struct DSL_setting), - &transferred, 1000); - - if (ret < 0) { - sr_err("Unable to setting FPGA of DSLogic: %s.", - libusb_error_name(ret)); - result = SR_ERR; - } else if (transferred != sizeof(struct DSL_setting)) { - sr_err("Setting FPGA error: expacted transfer size %d; actually %d", - sizeof(struct DSL_setting), transferred); - result = SR_ERR; - } - - if (result == SR_OK) - sr_info("FPGA setting done"); - - return result; } -static int fpga_config(struct libusb_device_handle *hdl, const char *filename) +static int setup_probes(struct sr_dev_inst *sdi, int num_probes) { - FILE *fw; - int offset, chunksize, ret, result; - unsigned char *buf; - int transferred; - uint64_t filesize; - struct stat f_stat; + uint16_t j; + struct sr_channel *probe; - sr_info("Configure FPGA using %s", filename); - if ((fw = fopen(filename, "rb")) == NULL) { - sr_err("Unable to open FPGA bit file %s for reading: %s", - filename, strerror(errno)); - return SR_ERR; - } - - if (stat(filename, &f_stat) == -1) - return SR_ERR; - - filesize = (uint64_t)f_stat.st_size; - - if (!(buf = g_try_malloc(filesize))) { - sr_err("FPGA configure bit malloc failed."); + for (j = 0; j < num_probes; j++) { + if (!(probe = sr_channel_new(j, (sdi->mode == LOGIC) ? SR_CHANNEL_LOGIC : ((sdi->mode == DSO) ? SR_CHANNEL_DSO : SR_CHANNEL_ANALOG), + TRUE, probe_names[j]))) return SR_ERR; + sdi->channels = g_slist_append(sdi->channels, probe); } - - result = SR_OK; - offset = 0; - while (1) { - chunksize = fread(buf, 1, filesize, fw); - if (chunksize == 0) - break; - - ret = libusb_bulk_transfer(hdl, 2 | LIBUSB_ENDPOINT_OUT, - buf, chunksize, - &transferred, 1000); - - if (ret < 0) { - sr_err("Unable to configure FPGA of DSLogic: %s.", - libusb_error_name(ret)); - result = SR_ERR; - break; - } else if (transferred != chunksize) { - sr_err("Configure FPGA error: expacted transfer size %d; actually %d", - chunksize, transferred); - result = SR_ERR; - break; - } - sr_info("Configure %d bytes", chunksize); - offset += chunksize; - } - fclose(fw); - g_free(buf); - if (result == SR_OK) - sr_info("FPGA configure done"); - - return result; -} - -static int DSLogic_dev_open(struct sr_dev_inst *sdi) -{ - libusb_device **devlist; - struct sr_usb_dev_inst *usb; - struct libusb_device_descriptor des; - struct DSL_context *devc; - struct drv_context *drvc; - struct version_info vi; - int ret, skip, i, device_count; - uint8_t revid; - - drvc = di->priv; - devc = sdi->priv; - usb = sdi->conn; - - if (sdi->status == SR_ST_ACTIVE) { - /* Device is already in use. */ - return SR_ERR; - } - - skip = 0; - device_count = libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist); - if (device_count < 0) { - sr_err("Failed to get device list: %s.", - libusb_error_name(device_count)); - return SR_ERR; - } - - for (i = 0; i < device_count; i++) { - if ((ret = libusb_get_device_descriptor(devlist[i], &des))) { - sr_err("Failed to get device descriptor: %s.", - libusb_error_name(ret)); - continue; - } - - if (des.idVendor != devc->profile->vid - || des.idProduct != devc->profile->pid) - continue; - - if (sdi->status == SR_ST_INITIALIZING) { - if (skip != sdi->index) { - /* Skip devices of this type that aren't the one we want. */ - skip += 1; - continue; - } - } else if (sdi->status == SR_ST_INACTIVE) { - /* - * This device is fully enumerated, so we need to find - * this device by vendor, product, bus and address. - */ - if (libusb_get_bus_number(devlist[i]) != usb->bus - || libusb_get_device_address(devlist[i]) != usb->address) - /* This is not the one. */ - continue; - } - - if (!(ret = libusb_open(devlist[i], &usb->devhdl))) { - if (usb->address == 0xff) - /* - * First time we touch this device after FW - * upload, so we don't know the address yet. - */ - usb->address = libusb_get_device_address(devlist[i]); - } else { - sr_err("Failed to open device: %s.", - libusb_error_name(ret)); - break; - } - - ret = command_get_fw_version(usb->devhdl, &vi); - if (ret != SR_OK) { - sr_err("Failed to get firmware version."); - break; - } - - ret = command_get_revid_version(usb->devhdl, &revid); - if (ret != SR_OK) { - sr_err("Failed to get REVID."); - break; - } - - /* - * Different versions may have incompatible issue, - * Mark for up level process - */ - if (vi.major != DSL_REQUIRED_VERSION_MAJOR || - vi.minor != DSL_REQUIRED_VERSION_MINOR) { - sr_err("Expected firmware version %d.%d, " - "got %d.%d.", DSL_REQUIRED_VERSION_MAJOR, DSL_REQUIRED_VERSION_MINOR, - vi.major, vi.minor); - sdi->status = SR_ST_INCOMPATIBLE; - } else { - sdi->status = SR_ST_ACTIVE; - } - - sr_info("Opened device %d on %d.%d, " - "interface %d, firmware %d.%d.", - sdi->index, usb->bus, usb->address, - USB_INTERFACE, vi.major, vi.minor); - - sr_info("Detected REVID=%d, it's a Cypress CY7C68013%s.", - revid, (revid != 1) ? " (FX2)" : "A (FX2LP)"); - - break; - } - libusb_free_device_list(devlist, 1); - - if ((sdi->status != SR_ST_ACTIVE) && - (sdi->status != SR_ST_INCOMPATIBLE)) - return SR_ERR; - + probe_init(sdi); return SR_OK; } -static int configure_probes(const struct sr_dev_inst *sdi) +static int adjust_probes(struct sr_dev_inst *sdi, int num_probes) { - struct DSL_context *devc; + uint16_t j; struct sr_channel *probe; - GSList *l; - int probe_bit, stage, i; - char *tc; - devc = sdi->priv; - for (i = 0; i < NUM_TRIGGER_STAGES; i++) { - devc->trigger_mask[i] = 0; - devc->trigger_value[i] = 0; - } + assert(num_probes > 0); - stage = -1; - for (l = sdi->channels; l; l = l->next) { - probe = (struct sr_channel *)l->data; - if (probe->enabled == FALSE) - continue; + j = g_slist_length(sdi->channels); + while(j < num_probes) { + if (!(probe = sr_channel_new(j, (sdi->mode == LOGIC) ? SR_CHANNEL_LOGIC : ((sdi->mode == DSO) ? SR_CHANNEL_DSO : SR_CHANNEL_ANALOG), + TRUE, probe_names[j]))) + return SR_ERR; + sdi->channels = g_slist_append(sdi->channels, probe); + j++; + } - probe_bit = 1 << (probe->index); - if (!(probe->trigger)) - continue; - - stage = 0; - for (tc = probe->trigger; *tc; tc++) { - devc->trigger_mask[stage] |= probe_bit; - if (*tc == '1') - devc->trigger_value[stage] |= probe_bit; - stage++; - if (stage > NUM_TRIGGER_STAGES) - return SR_ERR; - } - } + while(j > num_probes) { + sdi->channels = g_slist_delete_link(sdi->channels, g_slist_last(sdi->channels)); + j--; + } return SR_OK; } @@ -803,6 +333,7 @@ static struct DSL_context *DSLogic_dev_new(const struct sr_dev_inst *sdi) return NULL; } + devc->channel = NULL; devc->profile = NULL; devc->fw_updated = 0; devc->cur_samplerate = DEFAULT_SAMPLERATE; @@ -848,64 +379,6 @@ static int init(struct sr_context *sr_ctx) return std_hw_init(sr_ctx, di, LOG_PREFIX); } -static void probe_init(struct sr_dev_inst *sdi) -{ - int i; - GSList *l; - for (l = sdi->channels; l; l = l->next) { - struct sr_channel *probe = (struct sr_channel *)l->data; - if (sdi->mode == DSO) { - probe->vdiv = 1000; - probe->vfactor = 1; - probe->vpos = 0; - probe->coupling = SR_DC_COUPLING; - probe->trig_value = 0x80; - probe->ms_show = TRUE; - for (i = DSO_MS_BEGIN; i < DSO_MS_END; i++) - probe->ms_en[i] = default_ms_en[i]; - } - } -} - -static int set_probes(struct sr_dev_inst *sdi, int num_probes) -{ - uint16_t j; - struct sr_channel *probe; - - for (j = 0; j < num_probes; j++) { - if (!(probe = sr_channel_new(j, (sdi->mode == LOGIC) ? SR_CHANNEL_LOGIC : ((sdi->mode == DSO) ? SR_CHANNEL_DSO : SR_CHANNEL_ANALOG), - TRUE, probe_names[j]))) - return SR_ERR; - sdi->channels = g_slist_append(sdi->channels, probe); - } - probe_init(sdi); - return SR_OK; -} - -static int adjust_probes(struct sr_dev_inst *sdi, int num_probes) -{ - uint16_t j; - struct sr_channel *probe; - - assert(num_probes > 0); - - j = g_slist_length(sdi->channels); - while(j < num_probes) { - if (!(probe = sr_channel_new(j, (sdi->mode == LOGIC) ? SR_CHANNEL_LOGIC : ((sdi->mode == DSO) ? SR_CHANNEL_DSO : SR_CHANNEL_ANALOG), - TRUE, probe_names[j]))) - return SR_ERR; - sdi->channels = g_slist_append(sdi->channels, probe); - j++; - } - - while(j > num_probes) { - sdi->channels = g_slist_delete_link(sdi->channels, g_slist_last(sdi->channels)); - j--; - } - - return SR_OK; -} - static GSList *scan(GSList *options) { struct drv_context *drvc; @@ -981,7 +454,7 @@ static GSList *scan(GSList *options) /* Fill in probelist according to this device's profile. */ num_logic_probes = prof->dev_caps & DEV_CAPS_16BIT ? 16 : 8; - if (set_probes(sdi, num_logic_probes) != SR_OK) + if (setup_probes(sdi, num_logic_probes) != SR_OK) return NULL; devc = DSLogic_dev_new(sdi); @@ -990,7 +463,7 @@ static GSList *scan(GSList *options) drvc->instances = g_slist_append(drvc->instances, sdi); //devices = g_slist_append(devices, sdi); - if (check_conf_profile(devlist[i])) { + if (dsl_check_conf_profile(devlist[i])) { /* Already has the firmware, so fix the new address. */ sr_dbg("Found an DSLogic device."); sdi->status = SR_ST_INACTIVE; @@ -1171,53 +644,52 @@ static int dso_init(const struct sr_dev_inst *sdi) { int ret; GSList *l; - struct sr_usb_dev_inst *usb = sdi->conn; for(l = sdi->channels; l; l = l->next) { struct sr_channel *probe = (struct sr_channel *)l->data; - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, probe, SR_CONF_COUPLING)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_COUPLING)); if (ret != SR_OK) { sr_err("DSO set coupling of channel %d command failed!", probe->index); return ret; } - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, probe, SR_CONF_VDIV)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_VDIV)); if (ret != SR_OK) { sr_err("Set VDIV of channel %d command failed!", probe->index); return ret; } } - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, 0, SR_CONF_SAMPLERATE)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, 0, SR_CONF_SAMPLERATE)); if (ret != SR_OK) { sr_err("Set Sample Rate command failed!"); return ret; } - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, NULL, SR_CONF_HORIZ_TRIGGERPOS)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, NULL, SR_CONF_HORIZ_TRIGGERPOS)); if (ret != SR_OK) { sr_err("Set Horiz Trigger Position command failed!"); return ret; } - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_HOLDOFF)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_HOLDOFF)); if (ret != SR_OK) { sr_err("Set Trigger Holdoff Time command failed!"); return ret; } - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_SLOPE)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_SLOPE)); if (ret != SR_OK) { sr_err("Set Trigger Slope command failed!"); return ret; } - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_SOURCE)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_SOURCE)); if (ret != SR_OK) { sr_err("Set Trigger Source command failed!"); return ret; } - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_VALUE)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_VALUE)); if (ret != SR_OK) { sr_err("Set Trigger Value command failed!"); return ret; } - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_MARGIN)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_MARGIN)); if (ret != SR_OK) { sr_err("Set Trigger Margin command failed!"); return ret; @@ -1230,289 +702,138 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, const struct sr_channel_group *cg) { struct DSL_context *devc; - struct sr_usb_dev_inst *usb; - char str[128]; - uint8_t tmp_u8; int ret; - (void)cg; - - switch (id) { - case SR_CONF_CONN: - if (!sdi || !sdi->conn) - return SR_ERR_ARG; - usb = sdi->conn; - if (usb->address == 255) - /* Device still needs to re-enumerate after firmware - * upload, so we don't know its (future) address. */ - return SR_ERR; - snprintf(str, 128, "%d.%d", usb->bus, usb->address); - *data = g_variant_new_string(str); - break; - case SR_CONF_LIMIT_SAMPLES: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_uint64(devc->limit_samples); - break; - case SR_CONF_ACTUAL_SAMPLES: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_uint64(devc->actual_samples); - break; - case SR_CONF_SAMPLERATE: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_uint64(devc->cur_samplerate); - break; - case SR_CONF_CLOCK_TYPE: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_boolean(devc->clock_type); - break; - case SR_CONF_CLOCK_EDGE: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_boolean(devc->clock_edge); - break; - case SR_CONF_RLE: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_boolean(devc->rle_mode); - break; - case SR_CONF_WAIT_UPLOAD: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - usb = sdi->conn; - if (devc->buf_options == SR_BUF_UPLOAD && - devc->status == DSL_START) { - devc->status = DSL_ABORT; - command_wr_reg(usb->devhdl, bmFORCE_STOP, EEWP_ADDR); - *data = g_variant_new_boolean(TRUE); - } else { - *data = g_variant_new_boolean(FALSE); + ret = dsl_config_get(id, data, sdi, ch, cg); + if (ret != SR_OK) { + switch (id) { + case SR_CONF_OPERATION_MODE: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_string(opmodes[devc->op_mode]); + break; + case SR_CONF_FILTER: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_string(filters[devc->filter]); + break; + case SR_CONF_RLE: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_boolean(devc->rle_mode); + break; + case SR_CONF_TEST: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_boolean((devc->op_mode != SR_OP_BUFFER) && + (devc->op_mode != SR_OP_STREAM)); + break; + case SR_CONF_ACTUAL_SAMPLES: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_uint64(devc->actual_samples); + break; + case SR_CONF_WAIT_UPLOAD: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + if (devc->buf_options == SR_BUF_UPLOAD && + devc->status == DSL_START) { + devc->status = DSL_ABORT; + dsl_wr_reg(sdi, EEWP_ADDR, bmFORCE_STOP); + *data = g_variant_new_boolean(TRUE); + } else { + *data = g_variant_new_boolean(FALSE); + } + break; + case SR_CONF_BUFFER_OPTIONS: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_string(bufoptions[devc->buf_options]); + break; + case SR_CONF_CHANNEL_MODE: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + if (devc->stream) + *data = g_variant_new_string(stream_ch_modes[devc->ch_mode]); + else + *data = g_variant_new_string(buffer_ch_modes[devc->ch_mode]); + break; + case SR_CONF_MAX_HEIGHT: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_string(maxHeights[devc->max_height]); + break; + case SR_CONF_MAX_HEIGHT_VALUE: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_byte(devc->max_height); + break; + case SR_CONF_THRESHOLD: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_string(thresholds[devc->th_level]); + break; + case SR_CONF_VTH: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_double(devc->vth); + break; + case SR_CONF_ZERO: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + if (sdi->mode == DSO) + *data = g_variant_new_boolean(devc->zero); + else + *data = g_variant_new_boolean(FALSE); + break; + case SR_CONF_STREAM: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_boolean(devc->stream); + break; + case SR_CONF_MAX_DSO_SAMPLERATE: + if (!sdi) + return SR_ERR; + *data = g_variant_new_uint64(DSLOGIC_MAX_DSO_SAMPLERATE); + break; + case SR_CONF_MAX_DSO_SAMPLELIMITS: + if (!sdi) + return SR_ERR; + *data = g_variant_new_uint64(DSLOGIC_MAX_DSO_DEPTH); + break; + case SR_CONF_HW_DEPTH: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_uint64(dsl_channel_depth(sdi)); + break; + case SR_CONF_VLD_CH_NUM: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + if (devc->stream) + *data = g_variant_new_int16(stream_ch_num[devc->ch_mode]); + else + *data = g_variant_new_int16(buffer_ch_num[devc->ch_mode]); + break; + default: + return SR_ERR_NA; } - break; - case SR_CONF_INSTANT: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_boolean(devc->instant); - break; - case SR_CONF_OPERATION_MODE: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_string(opmodes[devc->op_mode]); - break; - case SR_CONF_BUFFER_OPTIONS: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_string(bufoptions[devc->buf_options]); - break; - case SR_CONF_CHANNEL_MODE: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - if (devc->stream) - *data = g_variant_new_string(stream_ch_modes[devc->ch_mode]); - else - *data = g_variant_new_string(buffer_ch_modes[devc->ch_mode]); - break; - case SR_CONF_TEST: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_boolean((devc->op_mode != SR_OP_BUFFER) && - (devc->op_mode != SR_OP_STREAM)); - break; - case SR_CONF_FILTER: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_string(filters[devc->filter]); - break; - case SR_CONF_MAX_HEIGHT: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_string(maxHeights[devc->max_height]); - break; - case SR_CONF_MAX_HEIGHT_VALUE: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_byte(devc->max_height); - break; - case SR_CONF_THRESHOLD: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_string(thresholds[devc->th_level]); - break; - case SR_CONF_VTH: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_double(devc->vth); - break; - case SR_CONF_VDIV: - if (!ch) - 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; - *data = g_variant_new_double(ch->vpos); - break; - case SR_CONF_TIMEBASE: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_uint64(devc->timebase); - break; - case SR_CONF_COUPLING: - if (!ch) - return SR_ERR; - *data = g_variant_new_byte(ch->coupling); - break; - case SR_CONF_EN_CH: - if (!ch) - return SR_ERR; - *data = g_variant_new_boolean(ch->enabled); - break; - case SR_CONF_DATALOCK: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_boolean(devc->data_lock); - break; - case SR_CONF_TRIGGER_SLOPE: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_byte(devc->trigger_slope); - break; - case SR_CONF_TRIGGER_SOURCE: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_byte(devc->trigger_source&0x0f); - break; - case SR_CONF_TRIGGER_CHANNEL: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_byte(devc->trigger_source>>4); - break; - case SR_CONF_TRIGGER_VALUE: - if (!ch) - return SR_ERR; - *data = g_variant_new_byte(ch->trig_value); - break; - case SR_CONF_HORIZ_TRIGGERPOS: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - if (sdi->mode == DSO) { - *data = g_variant_new_byte(devc->trigger_hrate); - } else { - *data = g_variant_new_byte(devc->trigger_hpos); - } - break; - case SR_CONF_TRIGGER_HOLDOFF: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_uint64(devc->trigger_holdoff); - break; - case SR_CONF_TRIGGER_MARGIN: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_byte(devc->trigger_margin); - break; - case SR_CONF_ZERO: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - if (sdi->mode == DSO) - *data = g_variant_new_boolean(devc->zero); - else - *data = g_variant_new_boolean(FALSE); - break; - case SR_CONF_STREAM: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_boolean(devc->stream); - break; - case SR_CONF_ROLL: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_boolean(devc->roll); - break; - case SR_CONF_MAX_DSO_SAMPLERATE: - if (!sdi) - return SR_ERR; - *data = g_variant_new_uint64(DSLOGIC_MAX_DSO_SAMPLERATE); - break; - case SR_CONF_MAX_DSO_SAMPLELIMITS: - if (!sdi) - return SR_ERR; - *data = g_variant_new_uint64(DSLOGIC_MAX_DSO_DEPTH); - break; - case SR_CONF_HW_DEPTH: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_uint64(channel_depth(sdi)); - break; - case SR_CONF_DSO_BITS: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - *data = g_variant_new_byte(devc->dso_bits); - break; - case SR_CONF_HW_STATUS: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - usb = sdi->conn; - ret = command_get_hw_info(usb->devhdl, &tmp_u8); - if (ret == SR_OK) { - devc->overflow = tmp_u8 & 0x10; - *data = g_variant_new_byte(tmp_u8); - } else { - *data = g_variant_new_byte(0); - } - break; - case SR_CONF_VLD_CH_NUM: - if (!sdi) - return SR_ERR; - devc = sdi->priv; - if (devc->stream) - *data = g_variant_new_int16(stream_ch_num[devc->ch_mode]); - else - *data = g_variant_new_int16(buffer_ch_num[devc->ch_mode]); - break; - default: - return SR_ERR_NA; - } + } return SR_OK; } @@ -1538,51 +859,159 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, usb = sdi->conn; ret = SR_OK; - if (id == SR_CONF_SAMPLERATE) { + + if (id == SR_CONF_CLOCK_TYPE) { + devc->clock_type = g_variant_get_boolean(data); + } else if (id == SR_CONF_CLOCK_EDGE) { + devc->clock_edge = g_variant_get_boolean(data); + } else if (id == SR_CONF_LIMIT_SAMPLES) { + devc->limit_samples = g_variant_get_uint64(data); + } else if (id == SR_CONF_DATALOCK) { + while(libusb_try_lock_events(drvc->sr_ctx->libusb_ctx)); + devc->data_lock = g_variant_get_boolean(data); + libusb_unlock_events(drvc->sr_ctx->libusb_ctx); + } else if (id == SR_CONF_VDIV) { + ch->vdiv = g_variant_get_uint64(data); + if (sdi->mode == DSO) { + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, ch, SR_CONF_VDIV)); + } + if (ret == SR_OK) + sr_dbg("%s: setting VDIV of channel %d to %d mv", + __func__, ch->index, ch->vdiv); + 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); + sr_dbg("%s: setting Factor of channel %d to %d", __func__, + ch->index, ch->vfactor); + } else if (id == SR_CONF_TIMEBASE) { + devc->timebase = g_variant_get_uint64(data); + } else if (id == SR_CONF_COUPLING) { + ch->coupling = g_variant_get_byte(data); + if (ch->coupling == SR_GND_COUPLING) + ch->coupling = SR_DC_COUPLING; + if (sdi->mode == DSO) { + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, ch, SR_CONF_COUPLING)); + } + if (ret == SR_OK) + sr_dbg("%s: setting AC COUPLING of channel %d to %d", + __func__, ch->index, ch->coupling); + else + sr_dbg("%s: setting AC COUPLING of channel %d to %d failed", + __func__, ch->index, ch->coupling); + } else if (id == SR_CONF_TRIGGER_SLOPE) { + devc->trigger_slope = g_variant_get_byte(data); + if (sdi->mode == DSO) { + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_SLOPE)); + } + if (ret == SR_OK) + sr_dbg("%s: setting DSO Trigger Slope to %d", + __func__, devc->trigger_slope); + else + sr_dbg("%s: setting DSO Trigger Slope to %d failed", + __func__, devc->trigger_slope); + } else if (id == SR_CONF_TRIGGER_VALUE) { + ch->trig_value = g_variant_get_byte(data); + if (sdi->mode == DSO) { + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, ch, SR_CONF_TRIGGER_VALUE)); + } + if (ret == SR_OK) + sr_dbg("%s: setting channel %d Trigger Value to %d", + __func__, ch->index, ch->trig_value); + else + sr_dbg("%s: setting DSO Trigger Value to %d failed", + __func__, ch->index, ch->trig_value); + } else if (id == SR_CONF_HORIZ_TRIGGERPOS) { + if (sdi->mode == DSO) { + devc->trigger_hrate = g_variant_get_byte(data); + //devc->trigger_hpos = devc->trigger_hrate * dsl_en_ch_num(sdi) * devc->limit_samples / 200.0; + /* + * devc->trigger_hpos should be updated before each acquisition + * because the samplelimits may changed + */ + devc->trigger_hpos = devc->trigger_hrate * dsl_en_ch_num(sdi) * devc->limit_samples / 200.0; + if ((ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, NULL, SR_CONF_HORIZ_TRIGGERPOS))) == SR_OK) + sr_dbg("%s: setting DSO Horiz Trigger Position to %d", + __func__, devc->trigger_hpos); + else + sr_dbg("%s: setting DSO Horiz Trigger Position to %d failed", + __func__, devc->trigger_hpos); + } else { + devc->trigger_hpos = g_variant_get_byte(data) * devc->limit_samples / 100.0; + } + } else if (id == SR_CONF_TRIGGER_HOLDOFF) { + devc->trigger_holdoff = g_variant_get_uint64(data); + if (sdi->mode == DSO) { + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_HOLDOFF)); + } + if (ret == SR_OK) + sr_dbg("%s: setting Trigger Holdoff Time to %d", + __func__, devc->trigger_holdoff); + else + sr_dbg("%s: setting Trigger Holdoff Time to %d failed", + __func__, devc->trigger_holdoff); + } else if (id == SR_CONF_TRIGGER_MARGIN) { + devc->trigger_margin = g_variant_get_byte(data); + if (sdi->mode == DSO) { + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_MARGIN)); + } + if (ret == SR_OK) + sr_dbg("%s: setting Trigger Margin to %d", + __func__, devc->trigger_margin); + else + sr_dbg("%s: setting Trigger Margin to %d failed", + __func__, devc->trigger_margin); + } else if (id == SR_CONF_SAMPLERATE) { if ((devc->op_mode != SR_OP_INTERNAL_TEST) && (devc->op_mode != SR_OP_EXTERNAL_TEST)) { devc->cur_samplerate = g_variant_get_uint64(data); if(sdi->mode == DSO) { devc->sample_wide = (devc->cur_samplerate <= DSLOGIC_MAX_DSO_SAMPLERATE); - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, 0, SR_CONF_SAMPLERATE)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, 0, SR_CONF_SAMPLERATE)); } else { devc->sample_wide = (devc->cur_samplerate <= DSLOGIC_MAX_LOGIC_SAMPLERATE); } } - } else if (id == SR_CONF_CLOCK_TYPE) { - devc->clock_type = g_variant_get_boolean(data); - } else if (id == SR_CONF_CLOCK_EDGE) { - devc->clock_edge = g_variant_get_boolean(data); + } else if (id == SR_CONF_FILTER) { + stropt = g_variant_get_string(data, NULL); + if (!strcmp(stropt, filters[SR_FILTER_NONE])) { + devc->filter = SR_FILTER_NONE; + } else if (!strcmp(stropt, filters[SR_FILTER_1T])) { + devc->filter = SR_FILTER_1T; + } else { + ret = SR_ERR; + } + sr_dbg("%s: setting filter to %d", + __func__, devc->filter); } else if (id == SR_CONF_RLE) { devc->rle_mode = g_variant_get_boolean(data); } else if (id == SR_CONF_INSTANT) { if (sdi->mode == DSO) { devc->instant = g_variant_get_boolean(data); - if (en_ch_num(sdi) != 0) { + if (dsl_en_ch_num(sdi) != 0) { if (devc->instant) - devc->limit_samples = DSLOGIC_INSTANT_DEPTH / en_ch_num(sdi); + devc->limit_samples = DSLOGIC_INSTANT_DEPTH / dsl_en_ch_num(sdi); else - devc->limit_samples = DSLOGIC_MAX_DSO_DEPTH / en_ch_num(sdi); + devc->limit_samples = DSLOGIC_MAX_DSO_DEPTH / dsl_en_ch_num(sdi); } } - } else if (id == SR_CONF_LIMIT_SAMPLES) { - devc->limit_samples = g_variant_get_uint64(data); } else if (id == SR_CONF_DEVICE_MODE) { sdi->mode = g_variant_get_int16(data); if (sdi->mode == LOGIC) { - command_wr_reg(usb->devhdl, bmSCOPE_CLR, EEWP_ADDR); + dsl_wr_reg(sdi, EEWP_ADDR, bmSCOPE_CLR); num_probes = devc->profile->dev_caps & DEV_CAPS_16BIT ? 16 : 8; } else if (sdi->mode == DSO) { - command_wr_reg(usb->devhdl, bmSCOPE_SET, EEWP_ADDR); + dsl_wr_reg(sdi, EEWP_ADDR, bmSCOPE_SET); num_probes = devc->profile->dev_caps & DEV_CAPS_16BIT ? MAX_DSO_PROBES_NUM : 1; - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, NULL, SR_CONF_DSO_SYNC)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, NULL, SR_CONF_DSO_SYNC)); if (ret != SR_OK) sr_dbg("%s: DSO configuration sync failed", __func__); devc->cur_samplerate = DSLOGIC_MAX_DSO_SAMPLERATE / num_probes; devc->limit_samples = DSLOGIC_MAX_DSO_DEPTH / num_probes; devc->samplerates_size = 15; } else { - command_wr_reg(usb->devhdl, bmSCOPE_CLR, EEWP_ADDR); + dsl_wr_reg(sdi, EEWP_ADDR, bmSCOPE_CLR); num_probes = devc->profile->dev_caps & DEV_CAPS_16BIT ? MAX_ANALOG_PROBES_NUM : 1; devc->op_mode = SR_OP_STREAM; devc->stream = TRUE; @@ -1590,7 +1019,7 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, } devc->samplecounts_size = counts_size(sdi); sr_dev_probes_free(sdi); - set_probes(sdi, num_probes); + setup_probes(sdi, num_probes); sr_dbg("%s: setting mode to %d", __func__, sdi->mode); if (sdi->mode == DSO) { dso_init(sdi); @@ -1614,7 +1043,7 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, devc->op_mode = SR_OP_INTERNAL_TEST; if (strcmp(sdi->model, "DSLogic Basic") == 0) { devc->stream = TRUE; - devc->samplerates_size = 11; + devc->samplerates_size = 10; } else { devc->stream = FALSE; devc->samplerates_size = 14; @@ -1698,20 +1127,16 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, sr_dbg("%s: setting channel mode to %d", __func__, devc->ch_mode); } else if (id == SR_CONF_THRESHOLD) { - stropt = g_variant_get_string(data, NULL); - if (!strcmp(stropt, thresholds[SR_TH_3V3])) { - devc->th_level = SR_TH_3V3; - } else if (!strcmp(stropt, thresholds[SR_TH_5V0])) { - devc->th_level = SR_TH_5V0; - } else { - ret = SR_ERR; - } if (sdi->mode == LOGIC) { - 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); + stropt = g_variant_get_string(data, NULL); + if (strcmp(stropt, thresholds[devc->th_level])) { + if (!strcmp(stropt, thresholds[SR_TH_3V3])) { + devc->th_level = SR_TH_3V3; + } else if (!strcmp(stropt, thresholds[SR_TH_5V0])) { + devc->th_level = SR_TH_5V0; + } else { + ret = SR_ERR; + } char *fpga_bit; if (!(fpga_bit = g_try_malloc(strlen(DS_RES_PATH)+strlen(devc->profile->fpga_bit33)+1))) { sr_err("fpag_bit path malloc error!"); @@ -1720,43 +1145,26 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, strcpy(fpga_bit, DS_RES_PATH); switch(devc->th_level) { case SR_TH_3V3: - strcat(fpga_bit, devc->profile->fpga_bit33);; + strcat(fpga_bit, devc->profile->fpga_bit33); break; case SR_TH_5V0: - strcat(fpga_bit, devc->profile->fpga_bit50);; + strcat(fpga_bit, devc->profile->fpga_bit50); break; default: return SR_ERR; } - ret = fpga_config(usb->devhdl, fpga_bit); + ret = dsl_fpga_config(usb->devhdl, fpga_bit); + g_free(fpga_bit); if (ret != SR_OK) { sr_err("Configure FPGA failed!"); } - g_free(fpga_bit); } + sr_dbg("%s: setting threshold to %d", + __func__, devc->th_level); } - sr_dbg("%s: setting threshold to %d", - __func__, devc->th_level); } else if (id == SR_CONF_VTH) { devc->vth = g_variant_get_double(data); - if ((ret = command_wr_reg(usb->devhdl, (uint8_t)(devc->vth/5.0*255), VTH_ADDR)) == SR_OK) { - sr_err("%s: setting threshold voltage to %f", - __func__, devc->vth); - } else { - sr_info("%s: setting threshold voltage to %f failed", - __func__, devc->vth); - } - } else if (id == SR_CONF_FILTER) { - stropt = g_variant_get_string(data, NULL); - if (!strcmp(stropt, filters[SR_FILTER_NONE])) { - devc->filter = SR_FILTER_NONE; - } else if (!strcmp(stropt, filters[SR_FILTER_1T])) { - devc->filter = SR_FILTER_1T; - } else { - ret = SR_ERR; - } - sr_dbg("%s: setting filter to %d", - __func__, devc->filter); + ret = dsl_wr_reg(sdi, VTH_ADDR, (uint8_t)(devc->vth/5.0*255)); } else if (id == SR_CONF_MAX_HEIGHT) { stropt = g_variant_get_string(data, NULL); for (i = 0; i < ARRAY_SIZE(maxHeights); i++) { @@ -1770,7 +1178,7 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, } else if (id == SR_CONF_EN_CH) { ch->enabled = g_variant_get_boolean(data); if (sdi->mode == DSO) { - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, ch, SR_CONF_EN_CH)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, ch, SR_CONF_EN_CH)); uint16_t channel_cnt = 0; GSList *l; for (l = sdi->channels; l; l = l->next) { @@ -1778,7 +1186,7 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, channel_cnt += probe->enabled; } if (channel_cnt != 0) - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, 0, SR_CONF_SAMPLERATE)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, 0, SR_CONF_SAMPLERATE)); } if (ret == SR_OK) sr_dbg("%s: setting ENABLE of channel %d to %d", @@ -1786,59 +1194,14 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, else sr_dbg("%s: setting ENABLE of channel %d to %d", __func__, ch->index, ch->enabled); - } else if (id == SR_CONF_DATALOCK) { - while(libusb_try_lock_events(drvc->sr_ctx->libusb_ctx)); - devc->data_lock = g_variant_get_boolean(data); - libusb_unlock_events(drvc->sr_ctx->libusb_ctx); - } else if (id == SR_CONF_VDIV) { - ch->vdiv = g_variant_get_uint64(data); - if (sdi->mode == DSO) { - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, ch, SR_CONF_VDIV)); - } - if (ret == SR_OK) - sr_dbg("%s: setting VDIV of channel %d to %d mv", - __func__, ch->index, ch->vdiv); - 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); - sr_dbg("%s: setting Factor of channel %d to %d", __func__, - ch->index, ch->vfactor); } else if (id == SR_CONF_VPOS) { ch->vpos = g_variant_get_double(data); sr_dbg("%s: setting VPOS of channel %d to %lf", __func__, ch->index, ch->vpos); - } else if (id == SR_CONF_TIMEBASE) { - devc->timebase = g_variant_get_uint64(data); - } else if (id == SR_CONF_COUPLING) { - ch->coupling = g_variant_get_byte(data); - if (ch->coupling == SR_GND_COUPLING) - ch->coupling = SR_DC_COUPLING; - if (sdi->mode == DSO) { - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, ch, SR_CONF_COUPLING)); - } - if (ret == SR_OK) - sr_dbg("%s: setting AC COUPLING of channel %d to %d", - __func__, ch->index, ch->coupling); - else - sr_dbg("%s: setting AC COUPLING of channel %d to %d failed", - __func__, ch->index, ch->coupling); - } else if (id == SR_CONF_TRIGGER_SLOPE) { - devc->trigger_slope = g_variant_get_byte(data); - if (sdi->mode == DSO) { - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_SLOPE)); - } - if (ret == SR_OK) - sr_dbg("%s: setting DSO Trigger Slope to %d", - __func__, devc->trigger_slope); - else - sr_dbg("%s: setting DSO Trigger Slope to %d failed", - __func__, devc->trigger_slope); } else if (id == SR_CONF_TRIGGER_SOURCE) { devc->trigger_source = g_variant_get_byte(data); if (sdi->mode == DSO) { - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_SOURCE)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_SOURCE)); } if (ret == SR_OK) sr_dbg("%s: setting DSO Trigger Source to %d", @@ -1846,57 +1209,6 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, else sr_dbg("%s: setting DSO Trigger Source to %d failed", __func__, devc->trigger_source); - } else if (id == SR_CONF_TRIGGER_VALUE) { - ch->trig_value = g_variant_get_byte(data); - if (sdi->mode == DSO) { - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, ch, SR_CONF_TRIGGER_VALUE)); - } - if (ret == SR_OK) - sr_dbg("%s: setting channel %d Trigger Value to %d", - __func__, ch->index, ch->trig_value); - else - sr_dbg("%s: setting DSO Trigger Value to %d failed", - __func__, ch->index, ch->trig_value); - } else if (id == SR_CONF_HORIZ_TRIGGERPOS) { - if (sdi->mode == DSO) { - devc->trigger_hrate = g_variant_get_byte(data); - //devc->trigger_hpos = devc->trigger_hrate * en_ch_num(sdi) * devc->limit_samples / 200.0; - /* - * devc->trigger_hpos should be updated before each acquisition - * because the samplelimits may changed - */ - devc->trigger_hpos = devc->trigger_hrate * en_ch_num(sdi) * devc->limit_samples / 200.0; - if ((ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, NULL, SR_CONF_HORIZ_TRIGGERPOS))) == SR_OK) - sr_dbg("%s: setting DSO Horiz Trigger Position to %d", - __func__, devc->trigger_hpos); - else - sr_dbg("%s: setting DSO Horiz Trigger Position to %d failed", - __func__, devc->trigger_hpos); - } else { - devc->trigger_hpos = g_variant_get_byte(data) * devc->limit_samples / 100.0; - } - } else if (id == SR_CONF_TRIGGER_HOLDOFF) { - devc->trigger_holdoff = g_variant_get_uint64(data); - if (sdi->mode == DSO) { - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_HOLDOFF)); - } - if (ret == SR_OK) - sr_dbg("%s: setting Trigger Holdoff Time to %d", - __func__, devc->trigger_holdoff); - else - sr_dbg("%s: setting Trigger Holdoff Time to %d failed", - __func__, devc->trigger_holdoff); - } else if (id == SR_CONF_TRIGGER_MARGIN) { - devc->trigger_margin = g_variant_get_byte(data); - if (sdi->mode == DSO) { - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, NULL, SR_CONF_TRIGGER_MARGIN)); - } - if (ret == SR_OK) - sr_dbg("%s: setting Trigger Margin to %d", - __func__, devc->trigger_margin); - else - sr_dbg("%s: setting Trigger Margin to %d failed", - __func__, devc->trigger_margin); } else if (id == SR_CONF_STREAM) { devc->stream = g_variant_get_boolean(data); } else { @@ -1999,115 +1311,24 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi, static int dev_open(struct sr_dev_inst *sdi) { - struct sr_usb_dev_inst *usb; - struct DSL_context *devc; - int ret; - uint8_t hw_info; gboolean fpga_done; + int ret; + struct DSL_context *devc; - devc = sdi->priv; - usb = sdi->conn; + devc = sdi->priv; - /* - * If the firmware was recently uploaded, no dev_open operation should be called. - * Just wait for renumerate -> detach -> attach - */ - ret = SR_ERR; - if (devc->fw_updated > 0) { - return SR_ERR; - } else { - sr_info("%s: Firmware upload was not needed.", __func__); - ret = DSLogic_dev_open(sdi); + if ((ret = dsl_dev_open(di, sdi, &fpga_done)) == SR_OK) { + // set threshold + ret = dsl_wr_reg(sdi, VTH_ADDR, (uint8_t)(devc->vth/5.0*255)); } - if (ret != SR_OK) { - sr_err("%s: Unable to open device.", __func__); - return SR_ERR; - } - - ret = libusb_claim_interface(usb->devhdl, USB_INTERFACE); - if (ret != 0) { - switch(ret) { - case LIBUSB_ERROR_BUSY: - sr_err("%s: Unable to claim USB interface. Another " - "program or driver has already claimed it.", __func__); - break; - case LIBUSB_ERROR_NO_DEVICE: - sr_err("%s: Device has been disconnected.", __func__); - break; - default: - sr_err("%s: Unable to claim interface: %s.", - __func__, libusb_error_name(ret)); - break; - } - - return SR_ERR; - } - - ret = command_get_hw_info(usb->devhdl, &hw_info); - if (ret != SR_OK) { - sr_err("Failed to get hardware infos."); - return SR_ERR; - } - fpga_done = (hw_info & 0x80) != 0; - - if (sdi->status == SR_ST_ACTIVE && !fpga_done) { - if ((ret = command_fpga_config(usb->devhdl)) != SR_OK) { - sr_err("%s: Send FPGA configure command failed!", __func__); - } 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(DS_RES_PATH)+strlen(devc->profile->fpga_bit33)+1))) { - sr_err("fpag_bit path malloc error!"); - return SR_ERR_MALLOC; - } - strcpy(fpga_bit, DS_RES_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("%s: Configure FPGA failed!", __func__); - } - g_free(fpga_bit); - - if ((ret = command_wr_reg(usb->devhdl, (uint8_t)(devc->vth/5.0*255), VTH_ADDR)) == SR_OK) { - sr_err("%s: setting threshold voltage to %f", - __func__, devc->vth); - } else { - sr_info("%s: setting threshold voltage to %f failed", - __func__, devc->vth); - } - } - } - - return SR_OK; + return ret; } static int dev_close(struct sr_dev_inst *sdi) { - struct sr_usb_dev_inst *usb; - - usb = sdi->conn; - if (usb->devhdl == NULL) - return SR_ERR; - - sr_info("DSLogic: Closing device %d on %d.%d interface %d.", - sdi->index, usb->bus, usb->address, USB_INTERFACE); - libusb_release_interface(usb->devhdl, USB_INTERFACE); - libusb_close(usb->devhdl); - usb->devhdl = NULL; - sdi->status = SR_ST_INACTIVE; - - return SR_OK; + int ret = dsl_dev_close(sdi); + return ret; } static int cleanup(void) @@ -2136,398 +1357,48 @@ static void remove_sources(struct DSL_context *devc) g_free(devc->usbfd); } -static void finish_acquisition(struct DSL_context *devc) -{ - struct sr_datafeed_packet packet; - - sr_err("%s: send SR_DF_END packet", __func__); - /* Terminate session. */ - packet.type = SR_DF_END; - packet.status = SR_PKT_OK; - sr_session_send(devc->cb_data, &packet); - - if (devc->num_transfers != 0) { - devc->num_transfers = 0; - g_free(devc->transfers); - } - - devc->status = DSL_FINISH; -} - -static void free_transfer(struct libusb_transfer *transfer) -{ - struct DSL_context *devc; - unsigned int i; - - devc = transfer->user_data; - - g_free(transfer->buffer); - transfer->buffer = NULL; - libusb_free_transfer(transfer); - - for (i = 0; i < devc->num_transfers; i++) { - if (devc->transfers[i] == transfer) { - devc->transfers[i] = NULL; - break; - } - } - - devc->submitted_transfers--; - if (devc->submitted_transfers == 0) - finish_acquisition(devc); -} - -static void resubmit_transfer(struct libusb_transfer *transfer) -{ - int ret; - - if ((ret = libusb_submit_transfer(transfer)) == LIBUSB_SUCCESS) - return; - - free_transfer(transfer); - /* TODO: Stop session? */ - - sr_err("%s: %s", __func__, libusb_error_name(ret)); -} - - -static void receive_transfer(struct libusb_transfer *transfer) -{ - struct sr_datafeed_packet packet; - struct sr_datafeed_logic logic; - struct sr_datafeed_dso dso; - struct sr_datafeed_analog analog; - uint64_t cur_sample_count = 0; - - uint8_t *cur_buf = transfer->buffer; - struct DSL_context *devc = transfer->user_data; - struct sr_dev_inst *sdi = devc->cb_data; - const int sample_width = (devc->sample_wide) ? 2 : 1; - - if (devc->status == DSL_START) - devc->status = DSL_DATA; - if (devc->data_lock) { - resubmit_transfer(transfer); - return; - } - - if (devc->abort) - devc->status = DSL_STOP; - - sr_info("%" PRIu64 ": receive_transfer(): status %d; timeout %d; received %d bytes.", - g_get_monotonic_time(), transfer->status, transfer->timeout, transfer->actual_length); - - switch (transfer->status) { - case LIBUSB_TRANSFER_COMPLETED: - case LIBUSB_TRANSFER_TIMED_OUT: /* We may have received some data though. */ - break; - default: - devc->status = DSL_ERROR; - break; - } - - packet.status = SR_PKT_OK; - if (devc->status == DSL_DATA && - transfer->actual_length != 0) { - /* Send the incoming transfer to the session bus. */ - // check packet type - if (sdi->mode == LOGIC) { - packet.type = SR_DF_LOGIC; - packet.payload = &logic; - cur_sample_count = transfer->actual_length * 8 / en_ch_num(sdi) ; - logic.length = transfer->actual_length; - logic.format = LA_CROSS_DATA; - logic.data_error = 0; - logic.data = cur_buf; - } else if (sdi->mode == DSO) { - if (!devc->instant) { - const uint32_t mstatus_offset = devc->limit_samples / (g_slist_length(sdi->channels)/en_ch_num(sdi)); - mstatus.pkt_id = *((const uint16_t*)cur_buf + mstatus_offset); - 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_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.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) & 0x0fffffff; - mstatus.sample_divider_tog = *((const uint32_t*)cur_buf + mstatus_offset/2 + 18/2) & 0x80000000; - mstatus.trig_flag = *((const uint32_t*)cur_buf + mstatus_offset/2 + 18/2) & 0x40000000; - } else { - mstatus.vlen = instant_buffer_size; - } - - const uint32_t divider = devc->zero ? 0x1 : (uint32_t)ceil(DSCOPE_MAX_SAMPLERATE * 1.0 / devc->cur_samplerate / en_ch_num(sdi)); - if ((mstatus.pkt_id == DSO_PKTID && - mstatus.sample_divider == divider && - mstatus.vlen != 0 && - mstatus.vlen <= (transfer->actual_length - 512) / sample_width) || - devc->instant) { - devc->roll = (mstatus.stream_mode != 0); - devc->mstatus_valid = TRUE; - packet.type = SR_DF_DSO; - packet.payload = &dso; - dso.probes = sdi->channels; - //dso.num_samples = (transfer->actual_length - 512) / sample_width; - cur_sample_count = 2 * mstatus.vlen / en_ch_num(sdi) ; - dso.num_samples = cur_sample_count; - dso.mq = SR_MQ_VOLTAGE; - dso.unit = SR_UNIT_VOLT; - dso.mqflags = SR_MQFLAG_AC; - dso.samplerate_tog = (mstatus.sample_divider_tog != 0); - dso.trig_flag = (mstatus.trig_flag != 0); - dso.data = cur_buf; - } else { - packet.type = SR_DF_DSO; - packet.status = SR_PKT_DATA_ERROR; - devc->mstatus_valid = FALSE; - } - } else { - packet.type = SR_DF_ANALOG; - packet.payload = &analog; - analog.probes = sdi->channels; - cur_sample_count = transfer->actual_length / (sample_width * g_slist_length(analog.probes)); - analog.num_samples = cur_sample_count; - analog.mq = SR_MQ_VOLTAGE; - analog.unit = SR_UNIT_VOLT; - analog.mqflags = SR_MQFLAG_AC; - analog.data = (float *)cur_buf; - } - - if ((devc->limit_samples && devc->num_bytes < devc->actual_bytes) || - sdi->mode != LOGIC ) { - const uint64_t remain_length= devc->actual_bytes - devc->num_bytes; - logic.length = min(logic.length, remain_length); - - /* send data to session bus */ - if (!devc->overflow) - sr_session_send(sdi, &packet); - } - - devc->num_samples += cur_sample_count; - devc->num_bytes += logic.length; - if (sdi->mode == LOGIC && - devc->limit_samples && - devc->num_bytes >= devc->actual_bytes) { - devc->status = DSL_STOP; - } else if ((sdi->mode != DSO || devc->instant) && - devc->limit_samples && - devc->num_samples >= devc->actual_samples) { - devc->status = DSL_STOP; - } - } - - if (devc->status == DSL_DATA) - resubmit_transfer(transfer); - else - free_transfer(transfer); -} - -static unsigned int to_bytes_per_ms(struct DSL_context *devc) -{ - struct sr_dev_inst *sdi = devc->cb_data; - if (devc->cur_samplerate > SR_MHZ(100)) - return SR_MHZ(100) / 1000 * en_ch_num(sdi) / 8; - else - return devc->cur_samplerate / 1000 * en_ch_num(sdi) / 8; -} - -static size_t get_buffer_size(struct DSL_context *devc) -{ - size_t s; - - /* - * The buffer should be large enough to hold 10ms of data and - * a multiple of 512. - */ - s = single_buffer_time * to_bytes_per_ms(devc); - //s = to_bytes_per_ms(devc->cur_samplerate); - return (s + 511) & ~511; -} - -static unsigned int get_number_of_transfers(struct DSL_context *devc) -{ - unsigned int n; - /* Total buffer size should be able to hold about 100ms of data. */ - n = ceil(total_buffer_time * 1.0f * to_bytes_per_ms(devc) / get_buffer_size(devc)); - - if (n > NUM_SIMUL_TRANSFERS) - return NUM_SIMUL_TRANSFERS; - - return n; -} - -static unsigned int get_timeout(struct DSL_context *devc) -{ - size_t total_size; - unsigned int timeout; - - total_size = get_buffer_size(devc) * get_number_of_transfers(devc); - timeout = total_size / to_bytes_per_ms(devc); - - if (devc->op_mode == SR_OP_STREAM) - return timeout + timeout / 4; /* Leave a headroom of 25% percent. */ - else - return 1000; -} - static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi) { int completed = 0; struct timeval tv; struct drv_context *drvc; struct DSL_context *devc; + struct sr_usb_dev_inst *usb; + struct ctl_rd_cmd rd_cmd; + uint8_t hw_info; + int ret; (void)fd; (void)revents; drvc = di->priv; devc = sdi->priv; + usb = sdi->conn; tv.tv_sec = tv.tv_usec = 0; libusb_handle_events_timeout_completed(drvc->sr_ctx->libusb_ctx, &tv, &completed); + // overflow check + if (devc->stream && devc->trf_completed) { + rd_cmd.header.dest = DSL_CTL_HW_STATUS; + rd_cmd.header.size = 1; + hw_info = 0; + rd_cmd.data = &hw_info; + if ((ret = command_ctl_rd(usb->devhdl, rd_cmd)) != SR_OK) + sr_err("Failed to get hardware infos."); + else + devc->overflow = (hw_info & bmSYS_OVERFLOW) != 0; + } + if (devc->status == DSL_FINISH) { /* Remove polling */ remove_sources(devc); } + devc->trf_completed = 0; return TRUE; } -static void receive_trigger_pos(struct libusb_transfer *transfer) -{ - struct DSL_context *devc; - struct sr_datafeed_packet packet; - struct ds_trigger_pos *trigger_pos; - const struct sr_dev_inst *sdi; - uint64_t remain_cnt; - - packet.status = SR_PKT_OK; - devc = transfer->user_data; - sdi = devc->cb_data; - trigger_pos = (struct ds_trigger_pos *)transfer->buffer; - if (devc->status != DSL_ABORT) - devc->status = DSL_ERROR; - if (!devc->abort && transfer->status == LIBUSB_TRANSFER_COMPLETED && - trigger_pos->check_id == TRIG_CHECKID) { - sr_info("%" PRIu64 ": receive_trigger_pos(): status %d; timeout %d; received %d bytes.", - g_get_monotonic_time(), transfer->status, transfer->timeout, transfer->actual_length); - remain_cnt = trigger_pos->remain_cnt_h; - remain_cnt = (remain_cnt << 32) + trigger_pos->remain_cnt_l; - if (transfer->actual_length == sizeof(struct ds_trigger_pos)) { - if (sdi->mode != LOGIC || - devc->stream || - remain_cnt < devc->limit_samples) { - if (sdi->mode == LOGIC && (!devc->stream || (devc->status == DSL_ABORT))) { - devc->actual_samples = devc->limit_samples - remain_cnt; - devc->actual_bytes = devc->actual_samples / DSLOGIC_ATOMIC_SAMPLES * en_ch_num(sdi) * DSLOGIC_ATOMIC_SIZE; - devc->actual_samples = devc->actual_bytes / en_ch_num(sdi) * 8; - } - - packet.type = SR_DF_TRIGGER; - packet.payload = trigger_pos; - sr_session_send(sdi, &packet); - - devc->status = DSL_DATA; - } - } - } else if (!devc->abort) { - sr_err("%s: trigger packet data error.", __func__); - packet.type = SR_DF_TRIGGER; - packet.payload = trigger_pos; - packet.status = SR_PKT_DATA_ERROR; - sr_session_send(sdi, &packet); - } - - free_transfer(transfer); -} - - -static int start_transfers(const struct sr_dev_inst *sdi) -{ - struct DSL_context *devc; - struct sr_usb_dev_inst *usb; - struct libusb_transfer *transfer; - unsigned int i, num_transfers; - int ret; - unsigned char *buf; - size_t size; - unsigned int dso_buffer_size; - struct ds_trigger_pos *trigger_pos; - - devc = sdi->priv; - usb = sdi->conn; - - if (devc->instant) - dso_buffer_size = instant_buffer_size * g_slist_length(sdi->channels); - else - dso_buffer_size = devc->limit_samples * en_ch_num(sdi) + 512; - - num_transfers = (devc->stream) ? get_number_of_transfers(devc) : 1; - size = (sdi->mode == DSO) ? dso_buffer_size : - (devc->stream) ? get_buffer_size(devc) : instant_buffer_size; - - - /* trigger packet transfer */ - if (!(trigger_pos = g_try_malloc0(sizeof(struct ds_trigger_pos)))) { - sr_err("%s: USB trigger_pos buffer malloc failed.", __func__); - return SR_ERR_MALLOC; - } - devc->transfers = g_try_malloc0(sizeof(*devc->transfers) * (num_transfers + 1)); - if (!devc->transfers) { - sr_err("%s: USB transfer malloc failed.", __func__); - return SR_ERR_MALLOC; - } - transfer = libusb_alloc_transfer(0); - libusb_fill_bulk_transfer(transfer, usb->devhdl, - 6 | LIBUSB_ENDPOINT_IN, (unsigned char *)trigger_pos, sizeof(struct ds_trigger_pos), - receive_trigger_pos, devc, 0); - if ((ret = libusb_submit_transfer(transfer)) != 0) { - sr_err("%s: Failed to submit trigger_pos transfer: %s.", - __func__, libusb_error_name(ret)); - libusb_free_transfer(transfer); - g_free(trigger_pos); - devc->status = DSL_ERROR; - return SR_ERR; - } else { - devc->num_transfers++; - devc->transfers[0] = transfer; - devc->submitted_transfers++; - } - - /* data packet transfer */ - for (i = 1; i <= num_transfers; i++) { - if (!(buf = g_try_malloc(size))) { - sr_err("%s: USB transfer buffer malloc failed.", __func__); - return SR_ERR_MALLOC; - } - transfer = libusb_alloc_transfer(0); - libusb_fill_bulk_transfer(transfer, usb->devhdl, - 6 | LIBUSB_ENDPOINT_IN, buf, size, - receive_transfer, devc, 0); - if ((ret = libusb_submit_transfer(transfer)) != 0) { - sr_err("%s: Failed to submit transfer: %s.", - __func__, libusb_error_name(ret)); - libusb_free_transfer(transfer); - g_free(buf); - devc->status = DSL_ERROR; - devc->abort = TRUE; - return SR_ERR; - } - devc->transfers[i] = transfer; - devc->submitted_transfers++; - devc->num_transfers++; - } - - return SR_OK; -} - static int dev_acquisition_start(struct sr_dev_inst *sdi, void *cb_data) { (void)cb_data; @@ -2538,6 +1409,7 @@ static int dev_acquisition_start(struct sr_dev_inst *sdi, void *cb_data) const struct libusb_pollfd **lupfd; unsigned int i; int ret; + struct ctl_wr_cmd wr_cmd; test_init = 1; @@ -2557,20 +1429,22 @@ static int dev_acquisition_start(struct sr_dev_inst *sdi, void *cb_data) devc->num_transfers = 0; devc->submitted_transfers = 0; devc->actual_samples = devc->limit_samples; - devc->actual_bytes = devc->actual_samples / DSLOGIC_ATOMIC_SAMPLES * en_ch_num(sdi) * DSLOGIC_ATOMIC_SIZE; + devc->actual_bytes = devc->actual_samples / DSLOGIC_ATOMIC_SAMPLES * dsl_en_ch_num(sdi) * DSLOGIC_ATOMIC_SIZE; test_sample_value = 0; devc->abort = FALSE; devc->mstatus_valid = FALSE; devc->overflow = FALSE; /* Configures devc->trigger_* and devc->sample_wide */ - if (configure_probes(sdi) != SR_OK) { + if (dsl_configure_probes(sdi) != SR_OK) { sr_err("%s: Failed to configure probes.", __func__); return SR_ERR; } /* Stop Previous GPIF acquisition */ - if ((ret = command_stop_acquisition (usb->devhdl)) != SR_OK) { + wr_cmd.header.dest = DSL_CTL_STOP; + wr_cmd.header.size = 0; + if ((ret = command_ctl_wr(usb->devhdl, wr_cmd)) != SR_OK) { sr_err("%s: Stop DSLogic acquisition failed!", __func__); return ret; } else { @@ -2578,21 +1452,17 @@ static int dev_acquisition_start(struct sr_dev_inst *sdi, void *cb_data) } /* Setting FPGA before acquisition start*/ - if ((ret = command_fpga_setting(usb->devhdl, sizeof(struct DSL_setting) / sizeof(uint16_t))) != SR_OK) { - sr_err("%s: Send FPGA setting command failed!", __func__); - } else { - if ((ret = fpga_setting(sdi)) != SR_OK) { - sr_err("%s: Configure FPGA failed!", __func__); - return ret; - } + if ((ret = dsl_fpga_arm(sdi)) != SR_OK) { + sr_err("%s: Arm FPGA failed!", __func__); + return ret; } /* * settings must be updated before acquisition */ if (sdi->mode == DSO) { - devc->trigger_hpos = devc->trigger_hrate * en_ch_num(sdi) * devc->limit_samples / 200.0; - if ((ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, NULL, SR_CONF_HORIZ_TRIGGERPOS))) == SR_OK) + devc->trigger_hpos = devc->trigger_hrate * dsl_en_ch_num(sdi) * devc->limit_samples / 200.0; + if ((ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, NULL, SR_CONF_HORIZ_TRIGGERPOS))) == SR_OK) sr_dbg("%s: setting DSO Horiz Trigger Position to %d", __func__, devc->trigger_hpos); else @@ -2601,7 +1471,7 @@ static int dev_acquisition_start(struct sr_dev_inst *sdi, void *cb_data) } /* setup and submit usb transfer */ - if ((ret = start_transfers(devc->cb_data)) != SR_OK) { + if ((ret = dsl_start_transfers(devc->cb_data)) != SR_OK) { sr_err("%s: Could not submit usb transfer" "(%d)%d", __func__, ret, errno); return ret; @@ -2611,17 +1481,18 @@ static int dev_acquisition_start(struct sr_dev_inst *sdi, void *cb_data) lupfd = libusb_get_pollfds(drvc->sr_ctx->libusb_ctx); for (i = 0; lupfd[i]; i++); if (!(devc->usbfd = g_try_malloc(sizeof(struct libusb_pollfd) * (i + 1)))) - return SR_ERR; + return SR_ERR; for (i = 0; lupfd[i]; i++) { sr_source_add(lupfd[i]->fd, lupfd[i]->events, - get_timeout(devc), receive_data, sdi); + dsl_get_timeout(devc), receive_data, sdi); devc->usbfd[i] = lupfd[i]->fd; } devc->usbfd[i] = -1; free(lupfd); - if ((ret = command_start_acquisition (usb->devhdl, - devc->cur_samplerate, devc->sample_wide, (sdi->mode == LOGIC))) != SR_OK) { + wr_cmd.header.dest = DSL_CTL_START; + wr_cmd.header.size = 0; + if ((ret = command_ctl_wr(usb->devhdl, wr_cmd)) != SR_OK) { devc->status = DSL_ERROR; devc->abort = TRUE; return ret; @@ -2637,46 +1508,13 @@ static int dev_acquisition_start(struct sr_dev_inst *sdi, void *cb_data) static int dev_acquisition_stop(const struct sr_dev_inst *sdi, void *cb_data) { - (void)cb_data; - - struct DSL_context *devc; - struct sr_usb_dev_inst *usb; - int ret; - - devc = sdi->priv; - usb = sdi->conn; - - if (!devc->abort) { - devc->abort = TRUE; - command_wr_reg(usb->devhdl, bmFORCE_RDY, EEWP_ADDR); - } else if (devc->status == DSL_FINISH) { - /* Stop GPIF acquisition */ - if ((ret = command_stop_acquisition (usb->devhdl)) != SR_OK) - sr_err("%s: Sent acquisition stop command failed!", __func__); - else - sr_info("%s: Sent acquisition stop command!", __func__); - } - - return SR_OK; + int ret = dsl_dev_acquisition_stop(sdi, cb_data); + return ret; } static int dev_status_get(const struct sr_dev_inst *sdi, struct sr_status *status, int begin, int end) { - int ret = SR_ERR; - if (sdi) { - struct DSL_context *devc; - struct sr_usb_dev_inst *usb; - - devc = sdi->priv; - usb = sdi->conn; - if (devc->status == DSL_START) { - ret = command_get_status(usb->devhdl, (unsigned char*)status, begin, end); - } else if (devc->mstatus_valid) { - *status = mstatus; - ret = SR_OK; - } - } - + int ret = dsl_dev_status_get(sdi, status, begin, end); return ret; } diff --git a/libsigrok4DSL/hardware/demo/demo.c b/libsigrok4DSL/hardware/demo/demo.c index 6e37c4b5..6a9356a8 100644 --- a/libsigrok4DSL/hardware/demo/demo.c +++ b/libsigrok4DSL/hardware/demo/demo.c @@ -556,9 +556,6 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, case SR_CONF_DSO_BITS: *data = g_variant_new_byte(devc->dso_bits); break; - case SR_CONF_HW_STATUS: - *data = g_variant_new_byte(0); - break; case SR_CONF_VLD_CH_NUM: *data = g_variant_new_int16(NUM_PROBES); break; diff --git a/libsigrok4DSL/libsigrok.h b/libsigrok4DSL/libsigrok.h index 2dfec1c3..8f8240e6 100644 --- a/libsigrok4DSL/libsigrok.h +++ b/libsigrok4DSL/libsigrok.h @@ -878,9 +878,6 @@ enum { SR_CONF_MAX_DSO_SAMPLELIMITS, SR_CONF_HW_DEPTH, - /** Hardware status */ - SR_CONF_HW_STATUS, - /*--- Special stuff -------------------------------------------------*/ /** Scan options supported by the driver. */