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.
"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),
+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,
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);
#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 */
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)
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);
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;
/* 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.
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;
- 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");
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;