]> sigrok.org Git - libsigrok.git/blobdiff - src/hardware/kingst-la2016/protocol.c
kingst-la2016: rephrase manufacture date and device type support
[libsigrok.git] / src / hardware / kingst-la2016 / protocol.c
index 7888ed3ec7ebd0c45bf8764b52ce5281b5858473..609c8aa20517e9d4741134f85cd54f41072ec229 100644 (file)
@@ -662,14 +662,20 @@ static int set_sample_config(const struct sr_dev_inst *sdi)
  */
 static uint16_t run_state(const struct sr_dev_inst *sdi)
 {
-       uint16_t state;
-       static uint16_t previous_state = 0;
+       static uint16_t previous_state;
+
        int ret;
+       uint16_t state;
+       uint8_t buff[sizeof(state)];
+       const uint8_t *rdptr;
+       const char *label;
 
-       if ((ret = ctrl_in(sdi, CMD_FPGA_SPI, REG_RUN, 0, &state, sizeof(state))) != SR_OK) {
+       if ((ret = ctrl_in(sdi, CMD_FPGA_SPI, REG_RUN, 0, buff, sizeof(state))) != SR_OK) {
                sr_err("Cannot read run state.");
                return ret;
        }
+       rdptr = buff;
+       state = read_u16le_inc(&rdptr);
 
        /*
         * Avoid flooding the log, only dump values as they change.
@@ -677,17 +683,19 @@ static uint16_t run_state(const struct sr_dev_inst *sdi)
         */
        if (state != previous_state) {
                previous_state = state;
-               if ((state & 0x0003) == 0x01) {
-                       sr_dbg("Run state: 0x%04x (%s).", state, "idle");
-               } else if ((state & 0x000f) == 0x02) {
-                       sr_dbg("Run state: 0x%04x (%s).", state,
-                               "pre-trigger sampling");
-               } else if ((state & 0x000f) == 0x0a) {
-                       sr_dbg("Run state: 0x%04x (%s).", state,
-                               "sampling, waiting for trigger");
-               } else if ((state & 0x000f) == 0x0e) {
-                       sr_dbg("Run state: 0x%04x (%s).", state,
-                               "post-trigger sampling");
+               if ((state & 0x3) == 0x1) {
+                       label = "idle";
+               } else if ((state & 0xf) == 0x2) {
+                       label = "pre-trigger sampling";
+               } else if ((state & 0xf) == 0xa) {
+                       label = "sampling, waiting for trigger";
+               } else if ((state & 0xf) == 0xe) {
+                       label = "post-trigger sampling";
+               } else {
+                       label = NULL;
+               }
+               if (label && *label) {
+                       sr_dbg("Run state: 0x%04x (%s).", state, label);
                } else {
                        sr_dbg("Run state: 0x%04x.", state);
                }
@@ -914,22 +922,23 @@ static void send_chunk(struct sr_dev_inst *sdi,
        unsigned int max_samples, n_samples, total_samples, free_n_samples;
        unsigned int i, j, k;
        int do_signal_trigger;
-       uint16_t *wp;
+       uint8_t *wp;
        const uint8_t *rp;
        uint16_t state;
        uint8_t repetitions;
+       uint8_t sample_buff[sizeof(state)];
 
        devc = sdi->priv;
 
-       logic.unitsize = 2;
+       logic.unitsize = sizeof(sample_buff);
        logic.data = devc->convbuffer;
 
        sr_packet.type = SR_DF_LOGIC;
        sr_packet.payload = &logic;
 
-       max_samples = devc->convbuffer_size / 2;
+       max_samples = devc->convbuffer_size / sizeof(sample_buff);
        n_samples = 0;
-       wp = (uint16_t *)devc->convbuffer;
+       wp = devc->convbuffer;
        total_samples = 0;
        do_signal_trigger = 0;
 
@@ -946,7 +955,7 @@ static void send_chunk(struct sr_dev_inst *sdi,
                                logic.length = n_samples * 2;
                                sr_session_send(sdi, &sr_packet);
                                n_samples = 0;
-                               wp = (uint16_t *)devc->convbuffer;
+                               wp = devc->convbuffer;
                                if (do_signal_trigger) {
                                        std_session_send_df_trigger(sdi);
                                        do_signal_trigger = 0;
@@ -955,8 +964,11 @@ static void send_chunk(struct sr_dev_inst *sdi,
 
                        state = read_u16le_inc(&rp);
                        repetitions = read_u8_inc(&rp);
-                       for (j = 0; j < repetitions; j++)
-                               *wp++ = state;
+                       write_u16le((void *)&sample_buff, state);
+                       for (j = 0; j < repetitions; j++) {
+                               memcpy(wp, sample_buff, logic.unitsize);
+                               wp += logic.unitsize;
+                       }
 
                        n_samples += repetitions;
                        total_samples += repetitions;
@@ -975,7 +987,7 @@ static void send_chunk(struct sr_dev_inst *sdi,
                (void)read_u8_inc(&rp); /* Skip sequence number. */
        }
        if (n_samples) {
-               logic.length = n_samples * 2;
+               logic.length = n_samples * logic.unitsize;
                sr_session_send(sdi, &sr_packet);
                if (do_signal_trigger) {
                        std_session_send_df_trigger(sdi);
@@ -1094,7 +1106,9 @@ 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];
+       const uint8_t *rdptr;
+       uint8_t date_yy, date_mm;
+       uint8_t dinv_yy, dinv_mm;
        uint8_t magic;
        const char *bitstream_fn;
        int ret;
@@ -1102,20 +1116,24 @@ SR_PRIV int la2016_init_device(const struct sr_dev_inst *sdi)
        devc = sdi->priv;
 
        /*
-        * Four EEPROM bytes at offset 0x20 are purchase year and month
-        * in BCD format, with 16bit complemented checksum. For example
-        * 20 04 df fb translates to 2020-04. This can help identify the
-        * age of devices when unknown magic numbers are seen.
+        * Four EEPROM bytes at offset 0x20 are the manufacturing date,
+        * year and month in BCD format, followed by inverted values for
+        * consistency checks. For example bytes 20 04 df fb translate
+        * to 2020-04. This information can help identify the vintage of
+        * devices when unknown magic numbers are seen.
         */
-       if ((ret = ctrl_in(sdi, CMD_EEPROM, 0x20, 0, purchase_date_bcd, sizeof(purchase_date_bcd))) != SR_OK) {
-               sr_err("Cannot read purchase date in EEPROM.");
+       ret = ctrl_in(sdi, CMD_EEPROM, 0x20, 0, buf, 4 * sizeof(uint8_t));
+       if (ret != SR_OK) {
+               sr_err("Cannot read manufacture date in EEPROM.");
        } else {
-               sr_dbg("Purchase date: 20%02hx-%02hx.",
-                       (purchase_date_bcd[0]) & 0xff,
-                       (purchase_date_bcd[0] >> 8) & 0xff);
-               if (purchase_date_bcd[0] != (0x0ffff & ~purchase_date_bcd[1])) {
-                       sr_err("Purchase date fails checksum test.");
-               }
+               rdptr = &buf[0];
+               date_yy = read_u8_inc(&rdptr);
+               date_mm = read_u8_inc(&rdptr);
+               dinv_yy = read_u8_inc(&rdptr);
+               dinv_mm = read_u8_inc(&rdptr);
+               sr_info("Manufacture date: 20%02hx-%02hx.", date_yy, date_mm);
+               if ((date_mm ^ dinv_mm) != 0xff || (date_yy ^ dinv_yy) != 0xff)
+                       sr_warn("Manufacture date fails checksum test.");
        }
 
        /*
@@ -1160,17 +1178,18 @@ SR_PRIV int la2016_init_device(const struct sr_dev_inst *sdi)
                sr_err("Cannot read EEPROM device identifier bytes.");
                return ret;
        }
-
-       magic = 0;
-       if (buf[0] == (0xff & ~buf[1])) {
+       if ((buf[0] ^ buf[1]) == 0xff) {
                /* Primary copy of magic passes complement check. */
+               sr_dbg("Using primary copy of device type magic number.");
                magic = buf[0];
-       } else if (buf[4] == (0xff & ~buf[5])) {
+       } else if ((buf[4] ^ buf[5]) == 0xff) {
                /* Backup copy of magic passes complement check. */
                sr_dbg("Using backup copy of device type magic number.");
                magic = buf[4];
+       } else {
+               sr_err("Cannot find consistent device type identification.");
+               magic = 0;
        }
-
        sr_dbg("Device type: magic number is %hhu.", magic);
 
        /* Select the FPGA bitstream depending on the model. */