X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;f=hardware%2Fzeroplus-logic-cube%2Fapi.c;h=78036892a00ea3f8cbf51256b7b52872a9a73a60;hb=aa7066353c9a54d90695fca3b303e1476dd772fd;hp=7fbe25d8490de75b270e287dc67b51c64496cf9b;hpb=58c5f2ed1785ead87d1398c28b5dbe60ba4610dd;p=libsigrok.git diff --git a/hardware/zeroplus-logic-cube/api.c b/hardware/zeroplus-logic-cube/api.c index 7fbe25d8..78036892 100644 --- a/hardware/zeroplus-logic-cube/api.c +++ b/hardware/zeroplus-logic-cube/api.c @@ -19,69 +19,59 @@ #include "protocol.h" -#define USB_VENDOR 0x0c12 - #define VENDOR_NAME "ZEROPLUS" -#define MODEL_NAME "Logic Cube LAP-C" -#define MODEL_VERSION NULL - -#define NUM_PROBES 16 #define USB_INTERFACE 0 #define USB_CONFIGURATION 1 #define NUM_TRIGGER_STAGES 4 #define TRIGGER_TYPE "01" - #define PACKET_SIZE 2048 /* ?? */ //#define ZP_EXPERIMENTAL -typedef struct { - unsigned short vid; - unsigned short pid; +struct zp_model { + uint16_t vid; + uint16_t pid; char *model_name; unsigned int channels; unsigned int sample_depth; /* In Ksamples/channel */ unsigned int max_sampling_freq; -} model_t; +}; /* * Note -- 16032, 16064 and 16128 *usually* -- but not always -- have the * same 128K sample depth. */ -static model_t zeroplus_models[] = { +static const struct zp_model zeroplus_models[] = { + {0x0c12, 0x7002, "LAP-16128U", 16, 128, 200}, {0x0c12, 0x7009, "LAP-C(16064)", 16, 64, 100}, - {0x0c12, 0x700A, "LAP-C(16128)", 16, 128, 200}, - /* TODO: we don't know anything about these - {0x0c12, 0x700B, "LAP-C(32128)", 32, 128, 200}, - {0x0c12, 0x700C, "LAP-C(321000)", 32, 1024, 200}, - {0x0c12, 0x700D, "LAP-C(322000)", 32, 2048, 200}, + {0x0c12, 0x700a, "LAP-C(16128)", 16, 128, 200}, + /* TODO: We don't know anything about these. + {0x0c12, 0x700b, "LAP-C(32128)", 32, 128, 200}, + {0x0c12, 0x700c, "LAP-C(321000)", 32, 1024, 200}, + {0x0c12, 0x700d, "LAP-C(322000)", 32, 2048, 200}, */ - {0x0c12, 0x700E, "LAP-C(16032)", 16, 32, 100}, + {0x0c12, 0x700e, "LAP-C(16032)", 16, 32, 100}, {0x0c12, 0x7016, "LAP-C(162000)", 16, 2048, 200}, { 0, 0, 0, 0, 0, 0 } }; -static const int hwcaps[] = { +static const int32_t hwcaps[] = { SR_CONF_LOGIC_ANALYZER, SR_CONF_SAMPLERATE, SR_CONF_CAPTURE_RATIO, - - /* These are really implemented in the driver, not the hardware. */ SR_CONF_LIMIT_SAMPLES, - 0, }; /* * ZEROPLUS LAP-C (16032) numbers the 16 probes A0-A7 and B0-B7. * We currently ignore other untested/unsupported devices here. */ -static const char *probe_names[NUM_PROBES + 1] = { +static const char *probe_names[] = { "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", NULL, }; -/* List of struct sr_dev_inst, maintained by dev_open()/dev_close(). */ SR_PRIV struct sr_dev_driver zeroplus_logic_cube_driver_info; static struct sr_dev_driver *di = &zeroplus_logic_cube_driver_info; @@ -90,11 +80,7 @@ static struct sr_dev_driver *di = &zeroplus_logic_cube_driver_info; * options hardcoded into the vendor's Windows GUI. */ -/* - * TODO: We shouldn't support 150MHz and 200MHz on devices that don't go up - * that high. - */ -const uint64_t zp_supported_samplerates[] = { +static const uint64_t samplerates_100[] = { SR_HZ(100), SR_HZ(500), SR_KHZ(1), @@ -111,16 +97,27 @@ const uint64_t zp_supported_samplerates[] = { SR_MHZ(50), SR_MHZ(80), SR_MHZ(100), - SR_MHZ(150), - SR_MHZ(200), - 0, }; -static const struct sr_samplerates samplerates = { - .low = 0, - .high = 0, - .step = 0, - .list = zp_supported_samplerates, +const uint64_t samplerates_200[] = { + SR_HZ(100), + SR_HZ(500), + SR_KHZ(1), + SR_KHZ(5), + SR_KHZ(25), + SR_KHZ(50), + SR_KHZ(100), + SR_KHZ(200), + SR_KHZ(400), + SR_KHZ(800), + SR_MHZ(1), + SR_MHZ(10), + SR_MHZ(25), + SR_MHZ(50), + SR_MHZ(80), + SR_MHZ(100), + SR_MHZ(150), + SR_MHZ(200), }; static int hw_dev_close(struct sr_dev_inst *sdi); @@ -214,6 +211,33 @@ static int configure_probes(const struct sr_dev_inst *sdi) return SR_OK; } +SR_PRIV int zp_set_samplerate(struct dev_context *devc, uint64_t samplerate) +{ + int i; + + for (i = 0; ARRAY_SIZE(samplerates_200); i++) + if (samplerate == samplerates_200[i]) + break; + + if (i == ARRAY_SIZE(samplerates_200) || samplerate > devc->max_samplerate) { + sr_err("Unsupported samplerate: %" PRIu64 "Hz.", samplerate); + return SR_ERR_ARG; + } + + sr_info("Setting samplerate to %" PRIu64 "Hz.", samplerate); + + if (samplerate >= SR_MHZ(1)) + analyzer_set_freq(samplerate / SR_MHZ(1), FREQ_SCALE_MHZ); + else if (samplerate >= SR_KHZ(1)) + analyzer_set_freq(samplerate / SR_KHZ(1), FREQ_SCALE_KHZ); + else + analyzer_set_freq(samplerate, FREQ_SCALE_HZ); + + devc->cur_samplerate = samplerate; + + return SR_OK; +} + static int clear_instances(void) { GSList *l; @@ -252,7 +276,7 @@ static GSList *hw_scan(GSList *options) struct sr_probe *probe; struct drv_context *drvc; struct dev_context *devc; - model_t *prof; + const struct zp_model *prof; struct libusb_device_descriptor des; libusb_device **devlist; GSList *devices; @@ -285,10 +309,10 @@ static GSList *hw_scan(GSList *options) prof = &zeroplus_models[j]; } } - /* Skip if the device was not found */ + /* Skip if the device was not found. */ if (!prof) continue; - sr_info("Found ZEROPLUS model %s.", prof->model_name); + sr_info("Found ZEROPLUS %s.", prof->model_name); /* Register the device with libsigrok. */ if (!(sdi = sr_dev_inst_new(devcnt, SR_ST_INACTIVE, @@ -303,7 +327,9 @@ static GSList *hw_scan(GSList *options) sr_err("Device context malloc failed."); return NULL; } + sdi->priv = devc; + devc->prof = prof; devc->num_channels = prof->channels; #ifdef ZP_EXPERIMENTAL devc->max_memory_size = 128 * 1024; @@ -345,11 +371,13 @@ static GSList *hw_dev_list(void) static int hw_dev_open(struct sr_dev_inst *sdi) { struct dev_context *devc; - struct drv_context *drvc = di->priv; + struct drv_context *drvc; libusb_device **devlist, *dev; struct libusb_device_descriptor des; int device_count, ret, i; + drvc = di->priv; + if (!(devc = sdi->priv)) { sr_err("%s: sdi->priv was NULL", __func__); return SR_ERR_ARG; @@ -405,7 +433,7 @@ static int hw_dev_open(struct sr_dev_inst *sdi) return SR_ERR; } - /* Set default configuration after power on */ + /* Set default configuration after power on. */ if (analyzer_read_status(devc->usb->devhdl) == 0) analyzer_configure(devc->usb->devhdl); @@ -468,7 +496,7 @@ static int hw_cleanup(void) return SR_OK; } -static int config_get(int id, const void **data, const struct sr_dev_inst *sdi) +static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi) { struct dev_context *devc; @@ -476,20 +504,20 @@ static int config_get(int id, const void **data, const struct sr_dev_inst *sdi) case SR_CONF_SAMPLERATE: if (sdi) { devc = sdi->priv; - *data = &devc->cur_samplerate; + *data = g_variant_new_uint64(devc->cur_samplerate); sr_spew("Returning samplerate: %" PRIu64 "Hz.", devc->cur_samplerate); } else return SR_ERR; break; default: - return SR_ERR_ARG; + return SR_ERR_NA; } return SR_OK; } -static int config_set(int id, const void *value, const struct sr_dev_inst *sdi) +static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi) { struct dev_context *devc; @@ -505,32 +533,53 @@ static int config_set(int id, const void *value, const struct sr_dev_inst *sdi) switch (id) { case SR_CONF_SAMPLERATE: - return zp_set_samplerate(devc, *(const uint64_t *)value); + return zp_set_samplerate(devc, g_variant_get_uint64(data)); case SR_CONF_LIMIT_SAMPLES: - return set_limit_samples(devc, *(const uint64_t *)value); + return set_limit_samples(devc, g_variant_get_uint64(data)); case SR_CONF_CAPTURE_RATIO: - return set_capture_ratio(devc, *(const uint64_t *)value); + return set_capture_ratio(devc, g_variant_get_uint64(data)); default: - return SR_ERR; + return SR_ERR_NA; } + + return SR_OK; } -static int config_list(int key, const void **data, const struct sr_dev_inst *sdi) +static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi) { - (void)sdi; + struct dev_context *devc; + GVariant *gvar; + GVariantBuilder gvb; switch (key) { case SR_CONF_DEVICE_OPTIONS: - *data = hwcaps; + *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32, + hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t)); break; case SR_CONF_SAMPLERATE: - *data = &samplerates; + devc = sdi->priv; + g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}")); + if (devc->prof->max_sampling_freq == 100) { + gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), + samplerates_100, ARRAY_SIZE(samplerates_100), + sizeof(uint64_t)); + } else if (devc->prof->max_sampling_freq == 200) { + gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), + samplerates_200, ARRAY_SIZE(samplerates_200), + sizeof(uint64_t)); + } else { + sr_err("Internal error: Unknown max. samplerate: %d.", + devc->prof->max_sampling_freq); + return SR_ERR_ARG; + } + g_variant_builder_add(&gvb, "{sv}", "samplerates", gvar); + *data = g_variant_builder_end(&gvb); break; case SR_CONF_TRIGGER_TYPE: - *data = TRIGGER_TYPE; + *data = g_variant_new_string(TRIGGER_TYPE); break; default: - return SR_ERR_ARG; + return SR_ERR_NA; } return SR_OK; @@ -543,8 +592,7 @@ static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi, struct sr_datafeed_logic logic; //uint64_t samples_read; int res; - unsigned int packet_num; - unsigned int n; + unsigned int packet_num, n; unsigned char *buf; struct dev_context *devc; @@ -560,7 +608,7 @@ static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi, set_triggerbar(devc); - /* push configured settings to device */ + /* Push configured settings to device. */ analyzer_configure(devc->usb->devhdl); analyzer_start(devc->usb->devhdl);