26 #include "sigrok-internal.h"
28 #define USB_VENDOR_ID 0x0403
29 #define USB_PRODUCT_ID 0x6001
30 #define USB_DESCRIPTION "ChronoVu LA8"
31 #define USB_VENDOR_NAME "ChronoVu"
32 #define USB_MODEL_NAME "LA8"
33 #define USB_MODEL_VERSION ""
36 #define TRIGGER_TYPES "01"
37 #define SDRAM_SIZE (8 * 1024 * 1024)
38 #define MIN_NUM_SAMPLES 1
41 #define NUM_BLOCKS 2048
43 static GSList *dev_insts = NULL;
46 static const char *probe_names[
NUM_PROBES + 1] = {
117 static uint64_t supported_samplerates[255 + 1] = { 0 };
127 .list = supported_samplerates,
131 static int hwcaps[] = {
140 static int la8_close_usb_reset_sequencer(
struct context *ctx);
141 static int hw_dev_acquisition_stop(
int dev_index,
void *cb_data);
142 static int la8_reset(
struct context *ctx);
144 static void fill_supported_samplerates_if_needed(
void)
149 if (supported_samplerates[0] != 0)
153 for (i = 0; i < 255; i++)
154 supported_samplerates[254 - i] =
SR_MHZ(100) / (i + 1);
155 supported_samplerates[255] = 0;
164 static int is_valid_samplerate(uint64_t samplerate)
168 fill_supported_samplerates_if_needed();
170 for (i = 0; i < 255; i++) {
171 if (supported_samplerates[i] == samplerate)
175 sr_err(
"la8: %s: invalid samplerate (%" PRIu64
"Hz)",
176 __func__, samplerate);
191 static uint8_t samplerate_to_divcount(uint64_t samplerate)
193 if (samplerate == 0) {
194 sr_err(
"la8: %s: samplerate was 0", __func__);
198 if (!is_valid_samplerate(samplerate)) {
199 sr_err(
"la8: %s: can't get divcount, samplerate invalid",
204 return (
SR_MHZ(100) / samplerate) - 1;
216 static int la8_write(
struct context *ctx, uint8_t *buf,
int size)
223 sr_err(
"la8: %s: buf was NULL", __func__);
228 sr_err(
"la8: %s: size was < 0", __func__);
232 bytes_written = ftdi_write_data(ctx->
ftdic, buf, size);
234 if (bytes_written < 0) {
235 sr_err(
"la8: %s: ftdi_write_data: (%d) %s", __func__,
236 bytes_written, ftdi_get_error_string(ctx->
ftdic));
237 (void) la8_close_usb_reset_sequencer(ctx);
238 }
else if (bytes_written != size) {
239 sr_err(
"la8: %s: bytes to write: %d, bytes written: %d",
240 __func__, size, bytes_written);
241 (void) la8_close_usb_reset_sequencer(ctx);
244 return bytes_written;
257 static int la8_read(
struct context *ctx, uint8_t *buf,
int size)
264 sr_err(
"la8: %s: buf was NULL", __func__);
269 sr_err(
"la8: %s: size was <= 0", __func__);
273 bytes_read = ftdi_read_data(ctx->
ftdic, buf, size);
275 if (bytes_read < 0) {
276 sr_err(
"la8: %s: ftdi_read_data: (%d) %s", __func__,
277 bytes_read, ftdi_get_error_string(ctx->
ftdic));
278 }
else if (bytes_read != size) {
286 static int la8_close(
struct context *ctx)
291 sr_err(
"la8: %s: ctx was NULL", __func__);
296 sr_err(
"la8: %s: ctx->ftdic was NULL", __func__);
300 if ((ret = ftdi_usb_close(ctx->
ftdic)) < 0) {
301 sr_err(
"la8: %s: ftdi_usb_close: (%d) %s",
302 __func__, ret, ftdi_get_error_string(ctx->
ftdic));
314 static int la8_close_usb_reset_sequencer(
struct context *ctx)
317 uint8_t buf[8] = {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
321 sr_err(
"la8: %s: ctx was NULL", __func__);
326 sr_err(
"la8: %s: ctx->ftdic was NULL", __func__);
330 if (ctx->
ftdic->usb_dev) {
332 sr_dbg(
"la8: Resetting sequencer logic.");
333 (void) la8_write(ctx, buf, 8);
334 g_usleep(100 * 1000);
337 sr_dbg(
"la8: Purging buffers, resetting+closing FTDI device.");
340 if ((ret = ftdi_usb_purge_buffers(ctx->
ftdic)) < 0)
341 sr_err(
"la8: %s: ftdi_usb_purge_buffers: (%d) %s",
342 __func__, ret, ftdi_get_error_string(ctx->
ftdic));
343 if ((ret = ftdi_usb_reset(ctx->
ftdic)) < 0)
344 sr_err(
"la8: %s: ftdi_usb_reset: (%d) %s", __func__,
345 ret, ftdi_get_error_string(ctx->
ftdic));
346 if ((ret = ftdi_usb_close(ctx->
ftdic)) < 0)
347 sr_err(
"la8: %s: ftdi_usb_close: (%d) %s", __func__,
348 ret, ftdi_get_error_string(ctx->
ftdic));
352 ftdi_free(ctx->
ftdic);
366 static int la8_reset(
struct context *ctx)
373 sr_err(
"la8: %s: ctx was NULL", __func__);
378 sr_err(
"la8: %s: ctx->ftdic was NULL", __func__);
382 sr_dbg(
"la8: Resetting the device.");
388 done = 20 + time(NULL);
391 bytes_read = la8_read(ctx, (uint8_t *)&buf,
BS);
393 }
while ((done > now) && (bytes_read > 0));
396 (void) la8_close_usb_reset_sequencer(ctx);
398 sr_dbg(
"la8: Device reset finished.");
403 static int configure_probes(
struct context *ctx, GSList *probes)
415 for (l = probes; l; l = l->next) {
419 sr_err(
"la8: %s: probe was NULL", __func__);
433 sr_err(
"la8: %s: invalid probe index %d, must be "
434 "between 0 and 7", __func__, probe->
index);
438 probe_bit = (1 << (probe->
index - 1));
441 for (tc = probe->
trigger; tc && *tc; tc++) {
445 if (*tc !=
'0' && *tc !=
'1') {
446 sr_err(
"la8: %s: invalid trigger '%c', only "
447 "'0'/'1' supported", __func__, *tc);
456 sr_dbg(
"la8: trigger_mask = 0x%x, trigger_pattern = 0x%x",
462 static int hw_init(
const char *devinfo)
472 if (!(ctx = g_try_malloc(
sizeof(
struct context)))) {
473 sr_err(
"la8: %s: struct context malloc failed", __func__);
474 goto err_free_nothing;
495 sr_err(
"la8: %s: final_buf malloc failed", __func__);
500 if (!(ctx->
ftdic = ftdi_new())) {
501 sr_err(
"la8: %s: ftdi_new failed", __func__);
502 goto err_free_final_buf;
508 (void) la8_close_usb_reset_sequencer(ctx);
518 sr_err(
"la8: %s: sr_dev_inst_new failed", __func__);
519 goto err_close_ftdic;
524 dev_insts = g_slist_append(dev_insts, sdi);
526 sr_spew(
"la8: Device init successful.");
529 (void) la8_close(ctx);
534 (void) la8_close(ctx);
553 sr_err(
"la8: %s: sdi was NULL", __func__);
557 if (!(ctx = sdi->
priv)) {
558 sr_err(
"la8: %s: sdi->priv was NULL", __func__);
568 sr_err(
"la8: %s: ftdi_usb_open_desc: (%d) %s",
569 __func__, ret, ftdi_get_error_string(ctx->
ftdic));
570 (void) la8_close_usb_reset_sequencer(ctx);
573 sr_dbg(
"la8: Device opened successfully.");
576 if ((ret = ftdi_usb_purge_buffers(ctx->
ftdic)) < 0) {
577 sr_err(
"la8: %s: ftdi_usb_purge_buffers: (%d) %s",
578 __func__, ret, ftdi_get_error_string(ctx->
ftdic));
579 (void) la8_close_usb_reset_sequencer(ctx);
580 goto err_dev_open_close_ftdic;
582 sr_dbg(
"la8: FTDI buffers purged successfully.");
585 if ((ret = ftdi_setflowctrl(ctx->
ftdic, SIO_RTS_CTS_HS)) < 0) {
586 sr_err(
"la8: %s: ftdi_setflowcontrol: (%d) %s",
587 __func__, ret, ftdi_get_error_string(ctx->
ftdic));
588 (void) la8_close_usb_reset_sequencer(ctx);
589 goto err_dev_open_close_ftdic;
591 sr_dbg(
"la8: FTDI flow control enabled successfully.");
594 g_usleep(100 * 1000);
600 err_dev_open_close_ftdic:
601 (void) la8_close(ctx);
605 static int set_samplerate(
struct sr_dev_inst *sdi, uint64_t samplerate)
613 sr_spew(
"la8: Trying to set samplerate to %" PRIu64
"Hz.", samplerate);
615 fill_supported_samplerates_if_needed();
618 if (!is_valid_samplerate(samplerate))
629 static int hw_dev_close(
int dev_index)
635 sr_err(
"la8: %s: sdi was NULL", __func__);
639 if (!(ctx = sdi->
priv)) {
640 sr_err(
"la8: %s: sdi->priv was NULL", __func__);
644 sr_dbg(
"la8: Closing device.");
647 sr_dbg(
"la8: Status ACTIVE, closing device.");
649 (void) la8_close_usb_reset_sequencer(ctx);
651 sr_spew(
"la8: Status not ACTIVE, nothing to do.");
656 sr_dbg(
"la8: Freeing sample buffer.");
662 static int hw_cleanup(
void)
669 for (l = dev_insts; l; l = l->next) {
670 if (!(sdi = l->data)) {
672 sr_err(
"la8: %s: sdi was NULL, continuing", __func__);
678 g_slist_free(dev_insts);
684 static void *hw_dev_info_get(
int dev_index,
int dev_info_id)
691 sr_err(
"la8: %s: sdi was NULL", __func__);
695 if (!(ctx = sdi->
priv)) {
696 sr_err(
"la8: %s: sdi->priv was NULL", __func__);
700 sr_spew(
"la8: %s: dev_index %d, dev_info_id %d.", __func__,
701 dev_index, dev_info_id);
703 switch (dev_info_id) {
706 sr_spew(
"la8: %s: Returning sdi.", __func__);
710 sr_spew(
"la8: %s: Returning number of probes: %d.", __func__,
715 sr_spew(
"la8: %s: Returning probenames.", __func__);
718 fill_supported_samplerates_if_needed();
720 sr_spew(
"la8: %s: Returning samplerates.", __func__);
724 sr_spew(
"la8: %s: Returning trigger types: %s.", __func__,
729 sr_spew(
"la8: %s: Returning samplerate: %" PRIu64
"Hz.",
734 sr_err(
"la8: %s: Unknown device info ID", __func__);
742 static int hw_dev_status_get(
int dev_index)
747 sr_err(
"la8: %s: sdi was NULL, device not found", __func__);
756 static int *hw_hwcap_get_all(
void)
758 sr_spew(
"la8: Returning list of device capabilities.");
763 static int hw_dev_config_set(
int dev_index,
int hwcap,
void *value)
769 sr_err(
"la8: %s: sdi was NULL", __func__);
773 if (!(ctx = sdi->
priv)) {
774 sr_err(
"la8: %s: sdi->priv was NULL", __func__);
778 sr_spew(
"la8: %s: dev_index %d, hwcap %d", __func__, dev_index, hwcap);
782 if (set_samplerate(sdi, *(uint64_t *)value) ==
SR_ERR) {
783 sr_err(
"la8: %s: setting samplerate failed.", __func__);
789 if (configure_probes(ctx, (GSList *)value) !=
SR_OK) {
790 sr_err(
"la8: %s: probe config failed.", __func__);
795 if (*(uint64_t *)value == 0) {
796 sr_err(
"la8: %s: LIMIT_MSEC can't be 0.", __func__);
804 sr_err(
"la8: %s: LIMIT_SAMPLES too small.", __func__);
812 sr_err(
"la8: %s: Unknown capability.", __func__);
827 static int la8_read_block(
struct context *ctx)
829 int i, byte_offset, m, mi, p, index, bytes_read;
841 sr_spew(
"la8: Reading block 0 (again).");
845 }
while ((ctx->
done > now) && (bytes_read == 0));
849 if (bytes_read !=
BS) {
850 sr_err(
"la8: Trigger timed out. Bytes read: %d.", bytes_read);
851 (void) la8_reset(ctx);
858 m = byte_offset / (1024 * 1024);
859 mi = m * (1024 * 1024);
860 for (i = 0; i <
BS; i++) {
862 index = m * 2 + (((byte_offset + i) - mi) / 2) * 16;
863 index += (ctx->
divcount == 0) ? p : (1 - p);
870 static void send_block_to_session_bus(
struct context *ctx,
int block)
873 uint8_t
sample, expected_sample;
883 for (i = 0; i <
BS; i++) {
906 if (trigger_point == -1) {
908 sr_spew(
"la8: sending SR_DF_LOGIC packet (%d bytes) for "
909 "block %d", BS, block);
911 packet.payload = &logic;
929 if (trigger_point > 0) {
931 sr_spew(
"la8: sending pre-trigger SR_DF_LOGIC packet, "
932 "start = %d, length = %d", block * BS, trigger_point);
934 packet.payload = &logic;
935 logic.length = trigger_point;
942 sr_spew(
"la8: sending SR_DF_TRIGGER packet, sample = %d",
943 (block * BS) + trigger_point);
945 packet.payload = NULL;
949 if (trigger_point < (BS - 1)) {
951 sr_spew(
"la8: sending post-trigger SR_DF_LOGIC packet, "
952 "start = %d, length = %d",
953 (block * BS) + trigger_point, BS - trigger_point);
955 packet.payload = &logic;
956 logic.length = BS - trigger_point;
958 logic.data = ctx->
final_buf + (block *
BS) + trigger_point;
963 static int receive_data(
int fd,
int revents,
void *cb_data)
973 if (!(sdi = cb_data)) {
974 sr_err(
"la8: %s: cb_data was NULL", __func__);
978 if (!(ctx = sdi->
priv)) {
979 sr_err(
"la8: %s: sdi->priv was NULL", __func__);
984 sr_err(
"la8: %s: ctx->ftdic was NULL", __func__);
989 if ((ret = la8_read_block(ctx)) < 0) {
990 sr_err(
"la8: %s: la8_read_block error: %d", __func__, ret);
991 hw_dev_acquisition_stop(sdi->
index, sdi);
1001 sr_dbg(
"la8: Sampling finished, sending data to session bus now.");
1005 send_block_to_session_bus(ctx, i);
1007 hw_dev_acquisition_stop(sdi->
index, sdi);
1013 static int hw_dev_acquisition_start(
int dev_index,
void *cb_data)
1023 sr_err(
"la8: %s: sdi was NULL", __func__);
1027 if (!(ctx = sdi->
priv)) {
1028 sr_err(
"la8: %s: sdi->priv was NULL", __func__);
1033 sr_err(
"la8: %s: ctx->ftdic was NULL", __func__);
1039 sr_err(
"la8: %s: invalid divcount/samplerate", __func__);
1043 sr_dbg(
"la8: Starting acquisition.");
1052 bytes_written = la8_write(ctx, buf, 4);
1054 if (bytes_written < 0) {
1055 sr_err(
"la8: Acquisition failed to start.");
1057 }
else if (bytes_written != 4) {
1058 sr_err(
"la8: Acquisition failed to start.");
1062 sr_dbg(
"la8: Acquisition started successfully.");
1067 sr_dbg(
"la8: Sending SR_DF_HEADER.");
1069 packet.payload = &header;
1070 header.feed_version = 1;
1071 gettimeofday(&header.starttime, NULL);
1077 ctx->
done = (ctx->
divcount + 1) * 0.08388608 + time(NULL)
1088 static int hw_dev_acquisition_stop(
int dev_index,
void *cb_data)
1094 sr_dbg(
"la8: Stopping acquisition.");
1097 sr_err(
"la8: %s: sdi was NULL", __func__);
1101 if (!(ctx = sdi->
priv)) {
1102 sr_err(
"la8: %s: sdi->priv was NULL", __func__);
1107 sr_dbg(
"la8: Sending SR_DF_END.");
1115 .
name =
"chronovu-la8",
1116 .longname =
"ChronoVu LA8",
1119 .cleanup = hw_cleanup,
1120 .dev_open = hw_dev_open,
1121 .dev_close = hw_dev_close,
1122 .dev_info_get = hw_dev_info_get,
1123 .dev_status_get = hw_dev_status_get,
1124 .hwcap_get_all = hw_hwcap_get_all,
1125 .dev_config_set = hw_dev_config_set,
1126 .dev_acquisition_start = hw_dev_acquisition_start,
1127 .dev_acquisition_stop = hw_dev_acquisition_stop,
struct ftdi_context ftdic
uint64_t cur_samplerate
The currently configured samplerate of the device.
struct ftdi_context * ftdic
FTDI device context (used by libftdi).
SR_PRIV struct sr_dev_driver chronovu_la8_driver_info
The device supports setting a sample number limit, i.e.
int trigger_found
Tells us whether an SR_DF_TRIGGER packet was already sent.
uint64_t trigger_timeout
Time (in seconds) before the trigger times out.
The device can act as logic analyzer.
SR_PRIV int sr_source_add(int fd, int events, int timeout, sr_receive_data_callback_t cb, void *cb_data)
uint8_t * final_buf
An 8MB buffer where we'll store the de-mangled samples.
uint8_t mangled_buf[BS]
A buffer containing some (mangled) samples from the device.
#define USB_MODEL_VERSION
The device supports setting a sample time limit, i.e.
void * session_dev_id
TODO.
SR_PRIV struct sr_dev_inst * sr_dev_inst_get(GSList *dev_insts, int dev_index)
uint8_t trigger_pattern
Trigger pattern (MSB = channel 7, LSB = channel 0).
uint64_t limit_msec
The current sampling limit (in ms).
SR_PRIV struct sr_dev_inst * sr_dev_inst_new(int index, int status, const char *vendor, const char *model, const char *version)
The device supports setting/changing its samplerate.
The device supports setting a probe mask.
SR_PRIV void sr_dev_inst_free(struct sr_dev_inst *sdi)
int block_counter
Counter/index for the data block to be read.
SR_PRIV int sr_dbg(const char *format,...)
uint8_t trigger_mask
Trigger mask (MSB = channel 7, LSB = channel 0).
SR_PRIV int sr_spew(const char *format,...)
uint64_t limit_samples
The current sampling limit (in number of samples).
SR_PRIV int sr_session_send(struct sr_dev *dev, struct sr_datafeed_packet *packet)
Send a packet to whatever is listening on the datafeed bus.
uint8_t divcount
The divcount value (determines the sample period) for the LA8.
SR_PRIV int sr_err(const char *format,...)