]> sigrok.org Git - libsigrok.git/commitdiff
kingst-la2016: add support for kingst la1016
authorKevin Grant <redacted>
Mon, 5 Apr 2021 12:01:16 +0000 (13:01 +0100)
committerSoeren Apel <redacted>
Fri, 10 Sep 2021 21:23:15 +0000 (23:23 +0200)
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
src/hardware/kingst-la2016/protocol.c
src/hardware/kingst-la2016/protocol.h

index 477aacf8d8aeba0245a3f7eaa9c6d84605e60122..32d67f61b81ae821bfef2a809d658f96e805c41c 100644 (file)
@@ -64,7 +64,7 @@ static const char *channel_names[] = {
        "8", "9", "10", "11", "12", "13", "14", "15",
 };
 
        "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),
        SR_KHZ(20),
        SR_KHZ(50),
        SR_KHZ(100),
@@ -82,6 +82,23 @@ static const uint64_t samplerates[] = {
        SR_MHZ(200),
 };
 
        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,
 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)
 {
 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:
        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);
                break;
        case SR_CONF_LIMIT_SAMPLES:
                *data = std_gvar_tuple_u64(LA2016_NUM_SAMPLES_MIN, LA2016_NUM_SAMPLES_MAX);
index 1f399624fdc3194ba21b36cbfb8699711ff84ec2..1058a345fb2e4536d5d5b40bf0c739eef4834da9 100644 (file)
 #define UC_FIRMWARE    "kingst-la-%04x.fw"
 #define FPGA_FW_LA2016 "kingst-la2016-fpga.bitstream"
 #define FPGA_FW_LA2016A        "kingst-la2016a1-fpga.bitstream"
 #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 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 */
 
 /* 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->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)
 
        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;
 
        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;
        }
 
                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);
        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);
 
        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)
 {
 
 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;
 
        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.
        /* 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);
        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);
                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:
                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;
        }
 
                return SR_ERR;
        }
 
index 7518cb759f9a768cb373a78ca885fdfaa0f6d652..58998b24290bd0b9f7251f48e376aa86384822bf 100644 (file)
@@ -80,6 +80,7 @@ struct dev_context {
        pwm_setting_t pwm_setting[2];
        unsigned int threshold_voltage_idx;
        float threshold_voltage;
        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;
        uint64_t cur_samplerate;
        uint64_t limit_samples;
        uint64_t capture_ratio;