X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fhardware%2Fdreamsourcelab-dslogic%2Fprotocol.c;h=bb98d61a4b4f467f4eafa5cfb5d487b6a20f79ac;hb=HEAD;hp=43280cc56333e44586ebaee608e8cf07cca6783b;hpb=6402c379161ec138e451901c411817a55846a75b;p=libsigrok.git diff --git a/src/hardware/dreamsourcelab-dslogic/protocol.c b/src/hardware/dreamsourcelab-dslogic/protocol.c index 43280cc5..bb98d61a 100644 --- a/src/hardware/dreamsourcelab-dslogic/protocol.c +++ b/src/hardware/dreamsourcelab-dslogic/protocol.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include "protocol.h" @@ -98,7 +99,7 @@ struct cmd_start_acquisition { uint8_t sample_delay_l; }; -struct dslogic_fpga_config { +struct fpga_config { uint32_t sync; uint16_t mode_header; @@ -336,9 +337,9 @@ static uint16_t enabled_channel_mask(const struct sr_dev_inst *sdi) /* * Get the session trigger and configure the FPGA structure * accordingly. + * @return @c true if any triggers are enabled, @c false otherwise. */ -static void set_trigger(const struct sr_dev_inst *sdi, - struct dslogic_fpga_config *cfg) +static bool set_trigger(const struct sr_dev_inst *sdi, struct fpga_config *cfg) { struct sr_trigger *trigger; struct sr_trigger_stage *stage; @@ -355,23 +356,7 @@ static void set_trigger(const struct sr_dev_inst *sdi, cfg->ch_en = enabled_channel_mask(sdi); - cfg->trig_mask0[0] = 0xffff; - cfg->trig_mask1[0] = 0xffff; - - cfg->trig_value0[0] = 0; - cfg->trig_value1[0] = 0; - - cfg->trig_edge0[0] = 0; - cfg->trig_edge1[0] = 0; - - cfg->trig_logic0[0] = 2; - cfg->trig_logic1[0] = 2; - - cfg->trig_count[0] = 0; - - cfg->trig_glb = num_enabled_channels << 4; - - for (i = 1; i < NUM_TRIGGER_STAGES; i++) { + for (i = 0; i < NUM_TRIGGER_STAGES; i++) { cfg->trig_mask0[i] = 0xffff; cfg->trig_mask1[i] = 0xffff; cfg->trig_value0[i] = 0; @@ -395,7 +380,7 @@ static void set_trigger(const struct sr_dev_inst *sdi, if (!(trigger = sr_session_trigger_get(sdi->session))) { sr_dbg("No session trigger found"); - return; + return false; } for (l = trigger->stages; l; l = l->next) { @@ -435,24 +420,23 @@ static void set_trigger(const struct sr_dev_inst *sdi, } } - cfg->trig_glb |= num_trigger_stages; + cfg->trig_glb = (num_enabled_channels << 4) | (num_trigger_stages - 1); + + return num_trigger_stages != 0; } static int fpga_configure(const struct sr_dev_inst *sdi) { - struct dev_context *devc; - struct sr_usb_dev_inst *usb; + const struct dev_context *const devc = sdi->priv; + const struct sr_usb_dev_inst *const usb = sdi->conn; uint8_t c[3]; - struct dslogic_fpga_config cfg; - uint16_t v16; - uint32_t v32; + struct fpga_config cfg; + uint16_t mode = 0; + uint32_t divider; int transferred, len, ret; sr_dbg("Configuring FPGA."); - usb = sdi->conn; - devc = sdi->priv; - WL32(&cfg.sync, DS_CFG_START); WL16(&cfg.mode_header, DS_CFG_MODE); WL16(&cfg.divider_header, DS_CFG_DIVIDER); @@ -464,7 +448,7 @@ static int fpga_configure(const struct sr_dev_inst *sdi) WL32(&cfg.end_sync, DS_CFG_END); /* Pass in the length of a fixed-size struct. Really. */ - len = sizeof(struct dslogic_fpga_config) / 2; + len = sizeof(struct fpga_config) / 2; c[0] = len & 0xff; c[1] = (len >> 8) & 0xff; c[2] = (len >> 16) & 0xff; @@ -478,26 +462,27 @@ static int fpga_configure(const struct sr_dev_inst *sdi) return SR_ERR; } - v16 = 0x0000; + if (set_trigger(sdi, &cfg)) + mode |= DS_MODE_TRIG_EN; if (devc->mode == DS_OP_INTERNAL_TEST) - v16 = DS_MODE_INT_TEST; + mode |= DS_MODE_INT_TEST; else if (devc->mode == DS_OP_EXTERNAL_TEST) - v16 = DS_MODE_EXT_TEST; + mode |= DS_MODE_EXT_TEST; else if (devc->mode == DS_OP_LOOPBACK_TEST) - v16 = DS_MODE_LPB_TEST; + mode |= DS_MODE_LPB_TEST; if (devc->cur_samplerate == DS_MAX_LOGIC_SAMPLERATE * 2) - v16 |= DS_MODE_HALF_MODE; + mode |= DS_MODE_HALF_MODE; else if (devc->cur_samplerate == DS_MAX_LOGIC_SAMPLERATE * 4) - v16 |= DS_MODE_QUAR_MODE; + mode |= DS_MODE_QUAR_MODE; if (devc->continuous_mode) - v16 |= DS_MODE_STREAM_MODE; + mode |= DS_MODE_STREAM_MODE; if (devc->external_clock) { - v16 |= DS_MODE_CLK_TYPE; + mode |= DS_MODE_CLK_TYPE; if (devc->clock_edge == DS_EDGE_FALLING) - v16 |= DS_MODE_CLK_EDGE; + mode |= DS_MODE_CLK_EDGE; } if (devc->limit_samples > DS_MAX_LOGIC_DEPTH * ceil(devc->cur_samplerate * 1.0 / DS_MAX_LOGIC_SAMPLERATE) @@ -505,19 +490,17 @@ static int fpga_configure(const struct sr_dev_inst *sdi) /* Enable RLE for long captures. * Without this, captured data present errors. */ - v16 |= DS_MODE_RLE_MODE; + mode |= DS_MODE_RLE_MODE; } - WL16(&cfg.mode, v16); - v32 = ceil(DS_MAX_LOGIC_SAMPLERATE * 1.0 / devc->cur_samplerate); - WL32(&cfg.divider, v32); + WL16(&cfg.mode, mode); + divider = ceil(DS_MAX_LOGIC_SAMPLERATE * 1.0 / devc->cur_samplerate); + WL32(&cfg.divider, divider); /* Number of 16-sample units. */ WL32(&cfg.count, devc->limit_samples / 16); - set_trigger(sdi, &cfg); - - len = sizeof(struct dslogic_fpga_config); + len = sizeof(struct fpga_config); ret = libusb_bulk_transfer(usb->devhdl, 2 | LIBUSB_ENDPOINT_OUT, (unsigned char *)&cfg, len, &transferred, USB_TIMEOUT); if (ret < 0 || transferred != len) { @@ -560,7 +543,7 @@ SR_PRIV int dslogic_dev_open(struct sr_dev_inst *sdi, struct sr_dev_driver *di) struct dev_context *devc; struct drv_context *drvc; struct version_info vi; - int ret, i, device_count; + int ret = SR_ERR, i, device_count; uint8_t revid; char connection_id[64]; @@ -584,10 +567,10 @@ SR_PRIV int dslogic_dev_open(struct sr_dev_inst *sdi, struct sr_dev_driver *di) if ((sdi->status == SR_ST_INITIALIZING) || (sdi->status == SR_ST_INACTIVE)) { - /* - * Check device by its physical USB bus/port address. - */ - usb_get_port_path(devlist[i], connection_id, sizeof(connection_id)); + /* Check device by its physical USB bus/port address. */ + if (usb_get_port_path(devlist[i], connection_id, sizeof(connection_id)) < 0) + continue; + if (strcmp(sdi->connection_id, connection_id)) /* This is not the one. */ continue; @@ -603,6 +586,7 @@ SR_PRIV int dslogic_dev_open(struct sr_dev_inst *sdi, struct sr_dev_driver *di) } else { sr_err("Failed to open device: %s.", libusb_error_name(ret)); + ret = SR_ERR; break; } @@ -611,7 +595,8 @@ SR_PRIV int dslogic_dev_open(struct sr_dev_inst *sdi, struct sr_dev_driver *di) if ((ret = libusb_detach_kernel_driver(usb->devhdl, USB_INTERFACE)) < 0) { sr_err("Failed to detach kernel driver: %s.", libusb_error_name(ret)); - return SR_ERR; + ret = SR_ERR; + break; } } } @@ -637,10 +622,10 @@ SR_PRIV int dslogic_dev_open(struct sr_dev_inst *sdi, struct sr_dev_driver *di) sr_err("Expected firmware version %d.x, " "got %d.%d.", DSLOGIC_REQUIRED_VERSION_MAJOR, vi.major, vi.minor); + ret = SR_ERR; break; } - sdi->status = SR_ST_ACTIVE; sr_info("Opened device on %d.%d (logical) / %s (physical), " "interface %d, firmware %d.%d.", usb->bus, usb->address, connection_id, @@ -649,14 +634,14 @@ SR_PRIV int dslogic_dev_open(struct sr_dev_inst *sdi, struct sr_dev_driver *di) sr_info("Detected REVID=%d, it's a Cypress CY7C68013%s.", revid, (revid != 1) ? " (FX2)" : "A (FX2LP)"); + ret = SR_OK; + break; } - libusb_free_device_list(devlist, 1); - if (sdi->status != SR_ST_ACTIVE) - return SR_ERR; + libusb_free_device_list(devlist, 1); - return SR_OK; + return ret; } SR_PRIV struct dev_context *dslogic_dev_new(void) @@ -750,10 +735,12 @@ static void deinterleave_buffer(const uint8_t *src, size_t length, for (int bit = 0; bit != 64; bit++) { const uint64_t *word_ptr = src_ptr; sample = 0; - for (size_t channel = 0; channel != channel_count; + for (unsigned int channel = 0; channel != 16; channel++) { - if ((channel_mask & (1 << channel)) && - (*word_ptr++ & (1ULL << bit))) + const uint16_t m = channel_mask >> channel; + if (!m) + break; + if ((m & 1) && ((*word_ptr++ >> bit) & UINT64_C(1))) sample |= 1 << channel; } *dst_ptr++ = sample; @@ -789,7 +776,6 @@ static void LIBUSB_CALL receive_transfer(struct libusb_transfer *transfer) (DSLOGIC_ATOMIC_BYTES * channel_count); gboolean packet_has_error = FALSE; - struct sr_datafeed_packet packet; unsigned int num_samples; int trigger_offset; @@ -869,9 +855,7 @@ static void LIBUSB_CALL receive_transfer(struct libusb_transfer *transfer) devc->sent_samples += trigger_offset; /* Trigger position. */ devc->trigger_pos = 0; - packet.type = SR_DF_TRIGGER; - packet.payload = NULL; - sr_session_send(sdi, &packet); + std_session_send_df_trigger(sdi); /* Post trigger samples. */ num_samples -= trigger_offset; send_data(sdi, devc->deinterleave_buffer @@ -929,6 +913,8 @@ static size_t get_buffer_size(const struct sr_dev_inst *sdi) */ const size_t block_size = enabled_channel_count(sdi) * 512; const size_t s = 10 * to_bytes_per_ms(sdi); + if (!block_size) + return s; return ((s + block_size - 1) / block_size) * block_size; } @@ -1031,8 +1017,8 @@ static void LIBUSB_CALL trigger_receive(struct libusb_transfer *transfer) } else if (transfer->status == LIBUSB_TRANSFER_COMPLETED && transfer->actual_length == sizeof(struct dslogic_trigger_pos)) { tpos = (struct dslogic_trigger_pos *)transfer->buffer; - sr_info("tpos real_pos %d ram_saddr %d cnt %d", tpos->real_pos, - tpos->ram_saddr, tpos->remain_cnt); + sr_info("tpos real_pos %d ram_saddr %d cnt_h %d cnt_l %d", tpos->real_pos, + tpos->ram_saddr, tpos->remain_cnt_h, tpos->remain_cnt_l); devc->trigger_pos = tpos->real_pos; g_free(tpos); start_transfers(sdi);