From 8b172e78f6b9643cd62384df87459acb71f60d62 Mon Sep 17 00:00:00 2001 From: Kevin Grant Date: Mon, 5 Apr 2021 13:01:16 +0100 Subject: [PATCH] kingst-la2016: add support for kingst la1016 The Kingst LA2016 and LA1016 use the same hardware, just the coding of authentication IC U10 is different. U10 limits the LA1016 to using an FPGA bitstream that samples at a maximum of 100MHz. Other than that, the devices operate identically and the driver just needs to select the correct bitstream and limit the maximum sample rate appropriately. This commit adds support for the existing two hardware revisions of LA1016, which require different bitstreams. --- src/hardware/kingst-la2016/api.c | 30 +++++++++++++++++++++++++-- src/hardware/kingst-la2016/protocol.c | 30 ++++++++++++++++++++------- src/hardware/kingst-la2016/protocol.h | 1 + 3 files changed, 52 insertions(+), 9 deletions(-) diff --git a/src/hardware/kingst-la2016/api.c b/src/hardware/kingst-la2016/api.c index 477aacf8..32d67f61 100644 --- a/src/hardware/kingst-la2016/api.c +++ b/src/hardware/kingst-la2016/api.c @@ -64,7 +64,7 @@ static const char *channel_names[] = { "8", "9", "10", "11", "12", "13", "14", "15", }; -static const uint64_t samplerates[] = { +static const uint64_t samplerates_la2016[] = { SR_KHZ(20), SR_KHZ(50), SR_KHZ(100), @@ -82,6 +82,23 @@ static const uint64_t samplerates[] = { SR_MHZ(200), }; +static const uint64_t samplerates_la1016[] = { + SR_KHZ(20), + SR_KHZ(50), + SR_KHZ(100), + SR_KHZ(200), + SR_KHZ(500), + SR_MHZ(1), + SR_MHZ(2), + SR_MHZ(4), + SR_MHZ(5), + SR_MHZ(8), + SR_MHZ(10), + SR_MHZ(20), + SR_MHZ(50), + SR_MHZ(100), +}; + static const float logic_threshold_value[] = { 1.58, 2.5, @@ -485,12 +502,21 @@ static int config_set(uint32_t key, GVariant *data, static int config_list(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi, const struct sr_channel_group *cg) { + struct dev_context *devc; + + devc = sdi->priv; + switch (key) { case SR_CONF_SCAN_OPTIONS: case SR_CONF_DEVICE_OPTIONS: return STD_CONFIG_LIST(key, data, sdi, cg, scanopts, drvopts, devopts); case SR_CONF_SAMPLERATE: - *data = std_gvar_samplerates(ARRAY_AND_SIZE(samplerates)); + if (devc->max_samplerate == SR_MHZ(200)) { + *data = std_gvar_samplerates(ARRAY_AND_SIZE(samplerates_la2016)); + } + else { + *data = std_gvar_samplerates(ARRAY_AND_SIZE(samplerates_la1016)); + } break; case SR_CONF_LIMIT_SAMPLES: *data = std_gvar_tuple_u64(LA2016_NUM_SAMPLES_MIN, LA2016_NUM_SAMPLES_MAX); diff --git a/src/hardware/kingst-la2016/protocol.c b/src/hardware/kingst-la2016/protocol.c index 1f399624..1058a345 100644 --- a/src/hardware/kingst-la2016/protocol.c +++ b/src/hardware/kingst-la2016/protocol.c @@ -36,11 +36,14 @@ #define UC_FIRMWARE "kingst-la-%04x.fw" #define FPGA_FW_LA2016 "kingst-la2016-fpga.bitstream" #define FPGA_FW_LA2016A "kingst-la2016a1-fpga.bitstream" +#define FPGA_FW_LA1016 "kingst-la1016-fpga.bitstream" +#define FPGA_FW_LA1016A "kingst-la1016a1-fpga.bitstream" -#define MAX_SAMPLE_RATE SR_MHZ(200) +#define MAX_SAMPLE_RATE_LA2016 SR_MHZ(200) +#define MAX_SAMPLE_RATE_LA1016 SR_MHZ(100) #define MAX_SAMPLE_DEPTH 10e9 #define MAX_PWM_FREQ SR_MHZ(20) -#define PWM_CLOCK SR_MHZ(200) +#define PWM_CLOCK SR_MHZ(200) /* this is 200MHz for both the LA2016 and LA1016 */ /* usb vendor class control requests to the cypress FX2 microcontroller */ #define CMD_EEPROM 0xa2 /* ctrl_in reads, ctrl_out writes */ @@ -357,7 +360,7 @@ static int set_defaults(const struct sr_dev_inst *sdi) devc->capture_ratio = 5; /* percent */ devc->cur_channels = 0xffff; devc->limit_samples = 5000000; - devc->cur_samplerate = 200000000; + devc->cur_samplerate = SR_MHZ(100); ret = set_threshold_voltage(sdi, devc->threshold_voltage); if (ret) @@ -482,16 +485,16 @@ static int set_sample_config(const struct sr_dev_inst *sdi) devc = sdi->priv; total = 128 * 1024 * 1024; - if (devc->cur_samplerate > MAX_SAMPLE_RATE) { + if (devc->cur_samplerate > devc->max_samplerate) { sr_err("too high sample rate: %" PRIu64, devc->cur_samplerate); return SR_ERR; } - clock_divisor = MAX_SAMPLE_RATE / (double)devc->cur_samplerate; + clock_divisor = devc->max_samplerate / (double)devc->cur_samplerate; if (clock_divisor > 0xffff) clock_divisor = 0xffff; divisor = (uint16_t)(clock_divisor + 0.5); - devc->cur_samplerate = MAX_SAMPLE_RATE / divisor; + devc->cur_samplerate = devc->max_samplerate / divisor; if (devc->limit_samples > MAX_SAMPLE_DEPTH) { sr_err("too high sample depth: %" PRIu64, devc->limit_samples); @@ -748,12 +751,15 @@ SR_PRIV int la2016_start_retrieval(const struct sr_dev_inst *sdi, libusb_transfe SR_PRIV int la2016_init_device(const struct sr_dev_inst *sdi) { + struct dev_context *devc; uint16_t state; uint8_t buf[8]; int16_t purchase_date_bcd[2]; uint8_t magic; int ret; + devc = sdi->priv; + /* Four bytes of eeprom at 0x20 are purchase year & month in BCD format, with 16bit * complemented checksum; e.g. 2004DFFB = 2020-April. * This helps to identify the age of devices if unknown magic numbers occur. @@ -823,12 +829,22 @@ SR_PRIV int la2016_init_device(const struct sr_dev_inst *sdi) switch (magic) { case 2: ret = upload_fpga_bitstream(sdi, FPGA_FW_LA2016); + devc->max_samplerate = MAX_SAMPLE_RATE_LA2016; + break; + case 3: + ret = upload_fpga_bitstream(sdi, FPGA_FW_LA1016); + devc->max_samplerate = MAX_SAMPLE_RATE_LA1016; break; case 8: ret = upload_fpga_bitstream(sdi, FPGA_FW_LA2016A); + devc->max_samplerate = MAX_SAMPLE_RATE_LA2016; + break; + case 9: + ret = upload_fpga_bitstream(sdi, FPGA_FW_LA1016A); + devc->max_samplerate = MAX_SAMPLE_RATE_LA1016; break; default: - sr_err("device_type: device not supported; magic number indicates this is not an LA2016"); + sr_err("device_type: device not supported; magic number indicates this is not a LA2016 or LA1016"); return SR_ERR; } diff --git a/src/hardware/kingst-la2016/protocol.h b/src/hardware/kingst-la2016/protocol.h index 7518cb75..58998b24 100644 --- a/src/hardware/kingst-la2016/protocol.h +++ b/src/hardware/kingst-la2016/protocol.h @@ -80,6 +80,7 @@ struct dev_context { pwm_setting_t pwm_setting[2]; unsigned int threshold_voltage_idx; float threshold_voltage; + uint64_t max_samplerate; uint64_t cur_samplerate; uint64_t limit_samples; uint64_t capture_ratio; -- 2.30.2