X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fhardware%2Fhantek-4032l%2Fprotocol.c;h=fb18e8978a47cd0269a21bcda0851261361f762d;hb=2bd5d17c70dc7bab6dbf9aed0919fbc1049f79ba;hp=509a196e4b5f67bd550346aaab5d6d7622f89bd6;hpb=5089a14345442bb87d0970efc0bc10235a530d60;p=libsigrok.git diff --git a/src/hardware/hantek-4032l/protocol.c b/src/hardware/hantek-4032l/protocol.c index 509a196e..fb18e897 100644 --- a/src/hardware/hantek-4032l/protocol.c +++ b/src/hardware/hantek-4032l/protocol.c @@ -25,17 +25,40 @@ #define H4032L_USB_TIMEOUT 500 enum h4032l_cmd { - CMD_CONFIGURE = 0x2b1a, /* Also arms the logic analyzer. */ + CMD_RESET = 0x00b3, /* Also arms the logic analyzer. */ + CMD_CONFIGURE = 0x2b1a, CMD_STATUS = 0x4b3a, CMD_GET = 0x6b5a }; -struct __attribute__((__packed__)) h4032l_status_packet { +struct h4032l_status_packet { uint32_t magic; uint32_t values; uint32_t status; + uint32_t usbxi_data; + uint32_t fpga_version; }; +static void finish_acquisition(struct sr_dev_inst *sdi) +{ + struct drv_context *drvc = sdi->driver->context; + + std_session_send_df_end(sdi); + usb_source_remove(sdi->session, drvc->sr_ctx); +} + +static void free_transfer(struct libusb_transfer *transfer) +{ + struct sr_dev_inst *sdi = transfer->user_data; + struct dev_context *devc = sdi->priv; + + transfer->buffer = NULL; + libusb_free_transfer(transfer); + devc->usb_transfer = NULL; + + finish_acquisition(sdi); +} + SR_PRIV int h4032l_receive_data(int fd, int revents, void *cb_data) { struct timeval tv; @@ -67,11 +90,18 @@ void LIBUSB_CALL h4032l_usb_callback(struct libusb_transfer *transfer) uint32_t number_samples; int ret; - if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { - sr_err("%s error: %d.", __func__, transfer->status); + /* + * If acquisition has already ended, just free any queued up + * transfers that come in. + */ + if (devc->acq_aborted) { + free_transfer(transfer); return; } + if (transfer->status != LIBUSB_TRANSFER_COMPLETED) + sr_dbg("%s error: %d.", __func__, transfer->status); + buffer = (uint32_t *)transfer->buffer; switch (devc->status) { @@ -94,10 +124,9 @@ void LIBUSB_CALL h4032l_usb_callback(struct libusb_transfer *transfer) * First Transfer as next. */ status = (struct h4032l_status_packet *)transfer->buffer; + sr_dbg("FPGA version: 0x%x.", status->fpga_version); if (status->magic != H4032L_STATUS_PACKET_MAGIC) { - devc->status = H4032L_STATUS_CMD_STATUS; - devc->cmd_pkt.cmd = CMD_STATUS; - cmd = TRUE; + devc->status = H4032L_STATUS_RESPONSE_STATUS; } else if (status->status == 2) { devc->status = H4032L_STATUS_RESPONSE_STATUS_CONTINUE; } else { @@ -118,15 +147,15 @@ void LIBUSB_CALL h4032l_usb_callback(struct libusb_transfer *transfer) devc->status = H4032L_STATUS_FIRST_TRANSFER; break; case H4032L_STATUS_FIRST_TRANSFER: + /* Drop packets until H4032L_START_PACKET_MAGIC. */ if (buffer[0] != H4032L_START_PACKET_MAGIC) { - sr_err("Mismatch magic number of start poll."); - devc->status = H4032L_STATUS_IDLE; + sr_dbg("Mismatch magic number of start poll."); break; } devc->status = H4032L_STATUS_TRANSFER; max_samples--; buffer++; - break; + /* Fallthrough. */ case H4032L_STATUS_TRANSFER: number_samples = (devc->remaining_samples < max_samples) ? devc->remaining_samples : max_samples; devc->remaining_samples -= number_samples; @@ -167,7 +196,7 @@ void LIBUSB_CALL h4032l_usb_callback(struct libusb_transfer *transfer) h4032l_usb_callback, (void *)sdi, H4032L_USB_TIMEOUT); } - /* Send prepared usb packet. */ + /* Send prepared USB packet. */ if ((ret = libusb_submit_transfer(transfer)) != 0) { sr_err("Failed to submit transfer: %s.", libusb_error_name(ret)); @@ -178,7 +207,7 @@ void LIBUSB_CALL h4032l_usb_callback(struct libusb_transfer *transfer) } if (devc->status == H4032L_STATUS_IDLE) - libusb_free_transfer(transfer); + free_transfer(transfer); } uint16_t h4032l_voltage2pwm(double voltage) @@ -209,9 +238,21 @@ SR_PRIV int h4032l_start(const struct sr_dev_inst *sdi) struct dev_context *devc = sdi->priv; struct sr_usb_dev_inst *usb = sdi->conn; struct libusb_transfer *transfer; + unsigned char buffer[] = {0x0f, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; int ret; - /* Send configure command to arm the logic analyzer. */ + /* Send reset command to arm the logic analyzer. */ + if ((ret = libusb_control_transfer(usb->devhdl, + LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT, CMD_RESET, + 0x00, 0x00, buffer, ARRAY_SIZE(buffer), H4032L_USB_TIMEOUT)) < 0) { + sr_err("Failed to send vendor request %s.", libusb_error_name(ret)); + return SR_ERR; + } + + /* Wait for reset vendor request. */ + g_usleep(20 * 1000); + + /* Send configure command. */ devc->cmd_pkt.cmd = CMD_CONFIGURE; devc->status = H4032L_STATUS_CMD_CONFIGURE; devc->remaining_samples = devc->cmd_pkt.sample_size;