X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fhardware%2Fsysclk-lwla%2Fprotocol.h;h=0db4bc79eb19fa7b71e7380019fe1cea84306949;hb=f272d7ddc0ac67f07ae3e2ac13e0d8f386232d41;hp=61ed4c5f4d6388904e6cafa5422b28ac01b1fd8d;hpb=225d3cb0c52fc3df5b26fec94d3b3d2de796a41c;p=libsigrok.git diff --git a/src/hardware/sysclk-lwla/protocol.h b/src/hardware/sysclk-lwla/protocol.h index 61ed4c5f..0db4bc79 100644 --- a/src/hardware/sysclk-lwla/protocol.h +++ b/src/hardware/sysclk-lwla/protocol.h @@ -20,243 +20,139 @@ #ifndef LIBSIGROK_HARDWARE_SYSCLK_LWLA_PROTOCOL_H #define LIBSIGROK_HARDWARE_SYSCLK_LWLA_PROTOCOL_H -#define LOG_PREFIX "sysclk-lwla" - #include +#include #include #include -#include "libsigrok-internal.h" -#include "lwla.h" - -/* For now, only the LWLA1034 is supported. - */ -#define VENDOR_NAME "SysClk" -#define MODEL_NAME "LWLA1034" - -#define USB_VID_PID "2961.6689" -#define USB_INTERFACE 0 -#define USB_TIMEOUT_MS 3000 - -#define NUM_CHANNELS 34 - -/* Bit mask covering all 34 channels. - */ -#define ALL_CHANNELS_MASK (((uint64_t)1 << NUM_CHANNELS) - 1) - -/** Unit and packet size for the sigrok logic datafeed. - */ -#define UNIT_SIZE ((NUM_CHANNELS + 7) / 8) -#define PACKET_LENGTH (10 * 1000) /* units */ - -/** Size of the acquisition buffer in device memory units. - */ -#define MEMORY_DEPTH (256 * 1024) /* 256k x 36 bit */ - -/** Number of device memory units (36 bit) to read at a time. Slices of 8 - * consecutive 36-bit words are mapped to 9 32-bit words each, so the chunk - * length should be a multiple of 8 to ensure alignment to slice boundaries. - * - * Experimentation has shown that reading chunks larger than about 1024 bytes - * is unreliable. The threshold seems to relate to the buffer size on the FX2 - * USB chip: The configured endpoint buffer size is 512, and with double or - * triple buffering enabled a multiple of 512 bytes can be kept in fly. - * - * The vendor software limits reads to 120 words (15 slices, 540 bytes) at - * a time. So far, it appears safe to increase this to 224 words (28 slices, - * 1008 bytes), thus making the most of two 512 byte buffers. - */ -#define READ_CHUNK_LEN (28 * 8) - -/** Calculate the required buffer size in 32-bit units for reading a given - * number of device memory words. Rounded to a multiple of 8 device words. - */ -#define LWLA1034_MEMBUF_LEN(count) (((count) + 7) / 8 * 9) +#include -/** Maximum number of 16-bit words sent at a time during acquisition. - * Used for allocating the libusb transfer buffer. - */ -#define MAX_ACQ_SEND_WORDS 8 /* 5 for memory read request plus stuffing */ +#define LOG_PREFIX "sysclk-lwla" -/** Maximum number of 32-bit words received at a time during acquisition. - * Round to the next multiple of the endpoint buffer size to avoid nasty - * transfer overflow conditions on hiccups. +/* Maximum configurable sample count limit. + * Due to compression, there is no meaningful hardware limit the driver + * could report. So this value is less than 2^64-1 for no reason other + * than to safeguard against integer overflows. */ -#define MAX_ACQ_RECV_LEN ((READ_CHUNK_LEN / 8 * 9 + 127) / 128 * 128) +#define MAX_LIMIT_SAMPLES (UINT64_C(1000) * 1000 * 1000 * 1000) -/** Maximum length of a register write sequence. +/* Maximum configurable acquisition time limit. + * Due to compression, there is no hardware limit that would be meaningful + * in practice. However, the LWLA1016 reports the elapsed time as a 32-bit + * value, so keep this below 2^32. */ -#define MAX_REG_WRITE_SEQ_LEN 5 +#define MAX_LIMIT_MSEC (1000 * 1000 * 1000) -/** Default configured samplerate. - */ -#define DEFAULT_SAMPLERATE SR_MHZ(125) +struct acquisition_state; -/** Maximum configurable sample count limit. - */ -#define MAX_LIMIT_SAMPLES (UINT64_C(1) << 48) +/* USB vendor and product IDs. */ +enum { + USB_VID_SYSCLK = 0x2961, + USB_PID_LWLA1016 = 0x6688, + USB_PID_LWLA1034 = 0x6689, +}; -/** Maximum configurable capture duration in milliseconds. - */ -#define MAX_LIMIT_MSEC (UINT64_C(1) << 32) +/* USB device characteristics. */ +enum { + USB_CONFIG = 1, + USB_INTERFACE = 0, + USB_TIMEOUT_MS = 1000, +}; -/** LWLA1034 FPGA clock configurations. - */ -enum clock_config { - CONF_CLOCK_NONE, - CONF_CLOCK_INT, - CONF_CLOCK_EXT_RISE, - CONF_CLOCK_EXT_FALL, +/** USB device end points. */ +enum usb_endpoint { + EP_COMMAND = 2, + EP_CONFIG = 4, + EP_REPLY = 6 | LIBUSB_ENDPOINT_IN }; -/** Available clock sources. - */ +/** LWLA1034 clock sources. */ enum clock_source { - CLOCK_INTERNAL, + CLOCK_INTERNAL = 0, CLOCK_EXT_CLK, }; -/** Available trigger sources. - */ +/** LWLA1034 trigger sources. */ enum trigger_source { TRIGGER_CHANNELS = 0, TRIGGER_EXT_TRG, }; -/** Available edge choices for the external clock and trigger inputs. - */ +/** Edge choices for the LWLA1034 external clock and trigger inputs. */ enum signal_edge { EDGE_POSITIVE = 0, EDGE_NEGATIVE, }; -/** LWLA device states. - */ -enum device_state { - STATE_IDLE = 0, - - STATE_START_CAPTURE, +/* Common indicator for no or unknown FPGA config. */ +enum { + FPGA_NOCONF = -1, +}; +/** Acquisition protocol states. */ +enum protocol_state { + /* idle states */ + STATE_IDLE = 0, STATE_STATUS_WAIT, - STATE_STATUS_REQUEST, - STATE_STATUS_RESPONSE, - + /* device command states */ + STATE_START_CAPTURE, STATE_STOP_CAPTURE, - - STATE_LENGTH_REQUEST, - STATE_LENGTH_RESPONSE, - STATE_READ_PREPARE, + STATE_READ_FINISH, + /* command followed by response */ + STATE_EXPECT_RESPONSE = 1 << 3, + STATE_STATUS_REQUEST = STATE_EXPECT_RESPONSE, + STATE_LENGTH_REQUEST, STATE_READ_REQUEST, - STATE_READ_RESPONSE, - STATE_READ_END, -}; - -/** LWLA run-length encoding states. - */ -enum rle_state { - RLE_STATE_DATA, - RLE_STATE_LEN -}; - -/** LWLA sample acquisition and decompression state. - */ -struct acquisition_state { - uint64_t sample; - uint64_t run_len; - - /** Maximum number of samples to process. */ - uint64_t samples_max; - /** Number of samples sent to the session bus. */ - uint64_t samples_done; - - /** Maximum duration of capture, in milliseconds. */ - uint64_t duration_max; - /** Running capture duration since trigger event. */ - uint64_t duration_now; - - /** Capture memory fill level. */ - size_t mem_addr_fill; - - size_t mem_addr_done; - size_t mem_addr_next; - size_t mem_addr_stop; - - size_t out_index; - - struct libusb_transfer *xfer_in; - struct libusb_transfer *xfer_out; - - unsigned int capture_flags; - - enum rle_state rle; - - /** Whether to bypass the clock divider. */ - gboolean bypass_clockdiv; - - /* Payload data buffers for incoming and outgoing transfers. */ - uint32_t xfer_buf_in[MAX_ACQ_RECV_LEN]; - uint16_t xfer_buf_out[MAX_ACQ_SEND_WORDS]; - - /* Payload buffer for sigrok logic packets. */ - uint8_t out_packet[PACKET_LENGTH * UNIT_SIZE]; }; -/** Private, per-device-instance driver context. - */ struct dev_context { - /** The samplerate selected by the user. */ - uint64_t samplerate; - - /** The maximum sampling duration, in milliseconds. */ - uint64_t limit_msec; - - /** The maximum number of samples to acquire. */ - uint64_t limit_samples; - - /** Channels to use. */ - uint64_t channel_mask; - - uint64_t trigger_mask; - uint64_t trigger_edge_mask; - uint64_t trigger_values; - - struct acquisition_state *acquisition; - - struct regval_pair reg_write_seq[MAX_REG_WRITE_SEQ_LEN]; - int reg_write_pos; - int reg_write_len; - - enum device_state state; + uint64_t samplerate; /* requested samplerate */ + uint64_t limit_msec; /* requested capture duration in ms */ + uint64_t limit_samples; /* requested capture length in samples */ + + uint64_t channel_mask; /* bit mask of enabled channels */ + uint64_t trigger_mask; /* trigger enable mask */ + uint64_t trigger_edge_mask; /* trigger type mask */ + uint64_t trigger_values; /* trigger level/slope bits */ + + const struct model_info *model; /* device model descriptor */ + struct acquisition_state *acquisition; /* running capture state */ + int active_fpga_config; /* FPGA configuration index */ + gboolean short_transfer_quirk; /* 64 bytes response limit */ + + enum protocol_state state; /* async protocol state */ + gboolean cancel_requested; /* stop after current transfer */ + gboolean transfer_error; /* error during device communication */ + + gboolean cfg_rle; /* RLE compression setting */ + enum clock_source cfg_clock_source; /* clock source setting */ + enum signal_edge cfg_clock_edge; /* ext clock edge setting */ + enum trigger_source cfg_trigger_source; /* trigger source setting */ + enum signal_edge cfg_trigger_slope; /* ext trigger slope setting */ +}; - /** The currently active clock configuration of the device. */ - enum clock_config cur_clock_config; +/** LWLA model descriptor. */ +struct model_info { + char name[12]; + int num_channels; - /** Clock source configuration setting. */ - enum clock_source cfg_clock_source; - /** Clock edge configuration setting. */ - enum signal_edge cfg_clock_edge; + unsigned int num_devopts; + uint32_t devopts[8]; - /** Trigger source configuration setting. */ - enum trigger_source cfg_trigger_source; - /** Trigger slope configuration setting. */ - enum signal_edge cfg_trigger_slope; + unsigned int num_samplerates; + uint64_t samplerates[20]; - /* Indicates that stopping the acquisition is currently in progress. */ - gboolean stopping_in_progress; + int (*apply_fpga_config)(const struct sr_dev_inst *sdi); + int (*device_init_check)(const struct sr_dev_inst *sdi); + int (*setup_acquisition)(const struct sr_dev_inst *sdi); - /* Indicates whether a transfer failed. */ - gboolean transfer_error; + int (*prepare_request)(const struct sr_dev_inst *sdi); + int (*handle_response)(const struct sr_dev_inst *sdi); }; -SR_PRIV struct acquisition_state *lwla_alloc_acquisition_state(void); -SR_PRIV void lwla_free_acquisition_state(struct acquisition_state *acq); +extern SR_PRIV const struct model_info lwla1016_info; +extern SR_PRIV const struct model_info lwla1034_info; -SR_PRIV int lwla_init_device(const struct sr_dev_inst *sdi); -SR_PRIV int lwla_set_clock_config(const struct sr_dev_inst *sdi); -SR_PRIV int lwla_setup_acquisition(const struct sr_dev_inst *sdi); SR_PRIV int lwla_start_acquisition(const struct sr_dev_inst *sdi); -SR_PRIV int lwla_abort_acquisition(const struct sr_dev_inst *sdi); - -SR_PRIV int lwla_receive_data(int fd, int revents, void *cb_data); #endif