- Default to 1MHz.
   The default sample rate is the lowest frequency (100Hz),
   but it takes a very long time until 128K memory is full.

 - Fix the 1MHz setting.

 - Use samplerate list.

 - Fix 10MHz frequency.

 - Fix trigger.

 - Change the size of memory according to the number of samples.

 - Add pre-trigger (capture ratio) setting.

 - Fix the first acquisition after power on.
---
 hardware/zeroplus-logic-cube/analyzer.c | 151 ++++++++++++++++-------
 hardware/zeroplus-logic-cube/analyzer.h |   1 +
 hardware/zeroplus-logic-cube/zeroplus.c | 205 ++++++++++++++++++++++++++------
 3 files changed, 279 insertions(+), 78 deletions(-)

diff --git a/hardware/zeroplus-logic-cube/analyzer.c 
b/hardware/zeroplus-logic-cube/analyzer.c
index 4f86aa5..6f3e6cf 100644
--- a/hardware/zeroplus-logic-cube/analyzer.c
+++ b/hardware/zeroplus-logic-cube/analyzer.c
@@ -110,11 +110,11 @@ static int g_trigger_count = 1;
 static int g_filter_status[8] = { 0 };
 static int g_filter_enable = 0;
 
-static int g_freq_value = 100;
+static int g_freq_value = 1;
 static int g_freq_scale = FREQ_SCALE_MHZ;
-static int g_memory_size = MEMORY_SIZE_512K;
-static int g_ramsize_triggerbar_addr = 0x80000 >> 2;
-static int g_triggerbar_addr = 0x3fe;
+static int g_memory_size = MEMORY_SIZE_8K;
+static int g_ramsize_triggerbar_addr = 2 * 1024;
+static int g_triggerbar_addr = 0;
 static int g_compression = COMPRESSION_NONE;
 
 /* Maybe unk specifies an "endpoint" or "register" of sorts. */
@@ -125,6 +125,7 @@ static int analyzer_write_status(libusb_device_handle 
*devh, unsigned char unk,
        return gl_reg_write(devh, START_STATUS, unk << 6 | flags);
 }
 
+#if 0
 static int __analyzer_set_freq(libusb_device_handle *devh, int freq, int scale)
 {
        int reg0 = 0, divisor = 0, reg2 = 0;
@@ -261,6 +262,80 @@ static int __analyzer_set_freq(libusb_device_handle *devh, 
int freq, int scale)
 
        return 0;
 }
+#endif
+
+/*
+ * It seems that ...
+ *     FREQUENCT_REG0 - division factor (?)
+ *     FREQUENCT_REG1 - multiplication factor (?)
+ *     FREQUENCT_REG4 - clock selection (?)
+ *
+ *     clock selection
+ *     0  10MHz  16   1MHz  32 100kHz  48  10kHz  64   1kHz
+ *     1   5MHz  17 500kHz  33  50kHz  49   5kHz  65  500Hz
+ *     2 2.5MHz   .          .         50 2.5kHz  66  250Hz
+ *     .          .          .          .         67  125Hz
+ *     .          .          .          .         68 62.5Hz
+ */
+static int __analyzer_set_freq(libusb_device_handle *devh, int freq, int scale)
+{
+       struct freq_factor {
+               int freq;
+               int scale;
+               int sel;
+               int div;
+               int mul;
+       };
+
+       static const struct freq_factor f[] = {
+               { 200, FREQ_SCALE_MHZ,  0,  1, 20 },
+               { 150, FREQ_SCALE_MHZ,  0,  1, 15 },
+               { 100, FREQ_SCALE_MHZ,  0,  1, 10 },
+               {  80, FREQ_SCALE_MHZ,  0,  2, 16 },
+               {  50, FREQ_SCALE_MHZ,  0,  2, 10 },
+               {  25, FREQ_SCALE_MHZ,  1,  5, 25 },
+               {  10, FREQ_SCALE_MHZ,  1,  5, 10 },
+               {   1, FREQ_SCALE_MHZ, 16,  5,  5 },
+               { 800, FREQ_SCALE_KHZ, 17,  5,  8 },
+               { 400, FREQ_SCALE_KHZ, 32,  5, 20 },
+               { 200, FREQ_SCALE_KHZ, 32,  5, 10 },
+               { 100, FREQ_SCALE_KHZ, 32,  5,  5 },
+               {  50, FREQ_SCALE_KHZ, 33,  5,  5 },
+               {  25, FREQ_SCALE_KHZ, 49,  5, 25 },
+               {   5, FREQ_SCALE_KHZ, 50,  5, 10 },
+               {   1, FREQ_SCALE_KHZ, 64,  5,  5 },
+               { 500, FREQ_SCALE_HZ,  64, 10,  5 },
+               { 100, FREQ_SCALE_HZ,  68,  5,  8 },
+               {   0, 0,              0,   0,  0 }
+       };
+
+       int i;
+
+       for (i = 0; f[i].freq; i++) {
+               if (scale == f[i].scale && freq == f[i].freq)
+                       break;
+       }
+       if (!f[i].freq)
+               return -1;
+
+       sr_dbg("zp: Setting samplerate regs (freq=%d, scale=%d): "
+              "reg0: %d, reg1: %d, reg2: %d, reg3: %d.",
+              freq, scale, f[i].div, f[i].mul, 0x02, f[i].sel);
+
+       if (gl_reg_write(devh, FREQUENCY_REG0, f[i].div) < 0)
+               return -1;
+
+       if (gl_reg_write(devh, FREQUENCY_REG1, f[i].mul) < 0)
+               return -1;
+
+       if (gl_reg_write(devh, FREQUENCY_REG2, 0x02) < 0)
+               return -1;
+
+       if (gl_reg_write(devh, FREQUENCY_REG4, f[i].sel) < 0)
+               return -1;
+
+       return 0;
+}
 
 static void __analyzer_set_ramsize_trigger_address(libusb_device_handle *devh,
                                                   unsigned int address)
@@ -399,7 +474,10 @@ SR_PRIV void analyzer_configure(libusb_device_handle *devh)
        __analyzer_set_triggerbar_address(devh, g_triggerbar_addr);
 
        /* Set_Dont_Care_TriggerBar */
-       gl_reg_write(devh, DONT_CARE_TRIGGERBAR, 0x01);
+       if (g_triggerbar_addr)
+               gl_reg_write(devh, DONT_CARE_TRIGGERBAR, 0x00);
+       else
+               gl_reg_write(devh, DONT_CARE_TRIGGERBAR, 0x01);
 
        /* Enable_Status */
        analyzer_set_filter(devh);
@@ -413,44 +491,26 @@ SR_PRIV void analyzer_configure(libusb_device_handle 
*devh)
 
 SR_PRIV void analyzer_add_trigger(int channel, int type)
 {
-       int i;
-
-       if ((channel & 0xf) >= 8)
-               return;
-
-       if (type == TRIGGER_HIGH || type == TRIGGER_LOW) {
-               if (channel & CHANNEL_A)
-                       i = 0;
-               else if (channel & CHANNEL_B)
-                       i = 2;
-               else if (channel & CHANNEL_C)
-                       i = 4;
-               else if (channel & CHANNEL_D)
-                       i = 6;
-               else
-                       return;
-               if ((channel & 0xf) >= 4) {
-                       i++;
-                       channel -= 4;
-               }
-               g_trigger_status[i] |=
-                   1 << ((2 * channel) + (type == TRIGGER_LOW ? 1 : 0));
-       } else {
-               if (type == TRIGGER_POSEDGE)
-                       g_trigger_status[8] = 0x40;
-               else if (type == TRIGGER_NEGEDGE)
-                       g_trigger_status[8] = 0x80;
-               else
-                       g_trigger_status[8] = 0xc0;
-
-               /* FIXME: Just guessed the index; need to verify. */
-               if (channel & CHANNEL_B)
-                       g_trigger_status[8] += 8;
-               else if (channel & CHANNEL_C)
-                       g_trigger_status[8] += 16;
-               else if (channel & CHANNEL_D)
-                       g_trigger_status[8] += 24;
-               g_trigger_status[8] += channel % 8;
+       switch (type) {
+       case TRIGGER_HIGH:
+               g_trigger_status[channel / 4] |= 1 << (channel % 4 * 2);
+               break;
+       case TRIGGER_LOW:
+               g_trigger_status[channel / 4] |= 2 << (channel % 4 * 2);
+               break;
+#if 0
+       case TRIGGER_POSEDGE:
+               g_trigger_status[8] = 0x40 | channel;
+               break;
+       case TRIGGER_NEGEDGE:
+               g_trigger_status[8] = 0x80 | channel;
+               break;
+       case TRIGGER_ANYEDGE:
+               g_trigger_status[8] = 0xc0 | channel;
+               break;
+#endif
+       default:
+               break;
        }
 }
 
@@ -511,6 +571,11 @@ SR_PRIV void analyzer_set_triggerbar_address(unsigned int 
address)
        g_triggerbar_addr = address;
 }
 
+SR_PRIV unsigned int analyzer_read_status(libusb_device_handle *devh)
+{
+       return gl_reg_read(devh, DEV_STATUS);
+}
+
 SR_PRIV unsigned int analyzer_read_id(libusb_device_handle *devh)
 {
        return gl_reg_read(devh, DEV_ID1) << 8 | gl_reg_read(devh, DEV_ID0);
diff --git a/hardware/zeroplus-logic-cube/analyzer.h 
b/hardware/zeroplus-logic-cube/analyzer.h
index d427c43..6fad571 100644
--- a/hardware/zeroplus-logic-cube/analyzer.h
+++ b/hardware/zeroplus-logic-cube/analyzer.h
@@ -85,6 +85,7 @@ SR_PRIV void analyzer_add_trigger(int channel, int type);
 SR_PRIV void analyzer_set_trigger_count(int count);
 SR_PRIV void analyzer_add_filter(int channel, int type);
 
+SR_PRIV unsigned int analyzer_read_status(libusb_device_handle *devh);
 SR_PRIV unsigned int analyzer_read_id(libusb_device_handle *devh);
 SR_PRIV unsigned int analyzer_get_stop_address(libusb_device_handle *devh);
 SR_PRIV unsigned int analyzer_get_now_address(libusb_device_handle *devh);
diff --git a/hardware/zeroplus-logic-cube/zeroplus.c 
b/hardware/zeroplus-logic-cube/zeroplus.c
index f1b6431..f292ba5 100644
--- a/hardware/zeroplus-logic-cube/zeroplus.c
+++ b/hardware/zeroplus-logic-cube/zeroplus.c
@@ -42,6 +42,8 @@
 
 #define PACKET_SIZE                    2048    /* ?? */
 
+//#define ZP_EXPERIMENTAL
+
 typedef struct {
        unsigned short vid;
        unsigned short pid;
@@ -149,20 +151,22 @@ static const struct sr_samplerates samplerates = {
 /* Private, per-device-instance driver context. */
 struct dev_context {
        uint64_t cur_samplerate;
+       uint64_t max_samplerate;
        uint64_t limit_samples;
        int num_channels; /* TODO: This isn't initialized before it's needed :( 
*/
-       uint64_t memory_size;
-       uint8_t probe_mask;
-       uint8_t trigger_mask[NUM_TRIGGER_STAGES];
-       uint8_t trigger_value[NUM_TRIGGER_STAGES];
+       int memory_size;
+       unsigned int max_memory_size;
+       //uint8_t probe_mask;
+       //uint8_t trigger_mask[NUM_TRIGGER_STAGES];
+       //uint8_t trigger_value[NUM_TRIGGER_STAGES];
        // uint8_t trigger_buffer[NUM_TRIGGER_STAGES];
+       int trigger;
+       unsigned int capture_ratio;
 
        /* TODO: this belongs in the device instance */
        struct sr_usb_dev_inst *usb;
 };
 
-static int hw_dev_config_set(const struct sr_dev_inst *sdi, int hwcap,
-               const void *value);
 static int hw_dev_close(struct sr_dev_inst *sdi);
 
 static unsigned int get_memory_size(int type)
@@ -179,6 +183,7 @@ static unsigned int get_memory_size(int type)
                return 0;
 }
 
+#if 0
 static int configure_probes(const struct sr_dev_inst *sdi)
 {
        struct dev_context *devc;
@@ -219,6 +224,53 @@ static int configure_probes(const struct sr_dev_inst *sdi)
 
        return SR_OK;
 }
+#endif
+
+static int configure_probes(const struct sr_dev_inst *sdi)
+{
+       struct dev_context *devc;
+       const GSList *l;
+       const struct sr_probe *probe;
+       char *tc;
+       int type;
+
+       /* Note: sdi and sdi->priv are non-NULL, the caller checked this. */
+       devc = sdi->priv;
+
+       for (l = sdi->probes; l; l = l->next) {
+               probe = (struct sr_probe *)l->data;
+               if (probe->enabled == FALSE)
+                       continue;
+
+               if ((tc = probe->trigger)) {
+                       switch (*tc) {
+                       case '1':
+                               type = TRIGGER_HIGH;
+                               break;
+                       case '0':
+                               type = TRIGGER_LOW;
+                               break;
+#if 0
+                       case 'r':
+                               type = TRIGGER_POSEDGE;
+                               break;
+                       case 'f':
+                               type = TRIGGER_NEGEDGE;
+                               break;
+                       case 'c':
+                               type = TRIGGER_ANYEDGE;
+                               break;
+#endif
+                       default:
+                               return SR_ERR;
+                       }
+                       analyzer_add_trigger(probe->index, type);
+                       devc->trigger = 1;
+               }
+       }
+
+       return SR_OK;
+}
 
 static int clear_instances(void)
 {
@@ -325,7 +377,15 @@ static GSList *hw_scan(GSList *options)
                }
                sdi->priv = devc;
                devc->num_channels = prof->channels;
-               devc->memory_size = prof->sample_depth * 1024;
+#ifdef ZP_EXPERIMENTAL
+               devc->max_memory_size = 128 * 1024;
+               devc->max_samplerate = 200;
+#else
+               devc->max_memory_size = prof->sample_depth * 1024;
+               devc->max_samplerate = prof->max_sampling_freq;
+#endif
+               devc->max_samplerate *= SR_MHZ(1);
+               devc->memory_size = MEMORY_SIZE_8K;
                // memset(devc->trigger_buffer, 0, NUM_TRIGGER_STAGES);
 
                /* Fill in probelist according to this device's profile. */
@@ -418,16 +478,18 @@ static int hw_dev_open(struct sr_dev_inst *sdi)
                return SR_ERR;
        }
 
+       /* Set default configuration after power on */
+       if (analyzer_read_status(devc->usb->devhdl) == 0)
+               analyzer_configure(devc->usb->devhdl);
+
        analyzer_reset(devc->usb->devhdl);
        analyzer_initialize(devc->usb->devhdl);
 
-       analyzer_set_memory_size(MEMORY_SIZE_512K);
+       //analyzer_set_memory_size(MEMORY_SIZE_512K);
        // analyzer_set_freq(g_freq, g_freq_scale);
        analyzer_set_trigger_count(1);
        // analyzer_set_ramsize_trigger_address((((100 - g_pre_trigger)
        // * get_memory_size(g_memory_size)) / 100) >> 2);
-       analyzer_set_ramsize_trigger_address(
-               (100 * get_memory_size(MEMORY_SIZE_512K) / 100) >> 2);
 
 #if 0
        if (g_double_mode == 1)
@@ -439,10 +501,9 @@ static int hw_dev_open(struct sr_dev_inst *sdi)
        analyzer_set_compression(COMPRESSION_NONE);
 
        if (devc->cur_samplerate == 0) {
-               /* Samplerate hasn't been set. Default to the slowest one. */
-               if (hw_dev_config_set(sdi, SR_HWCAP_SAMPLERATE,
-                    &samplerates.list[0]) == SR_ERR)
-                       return SR_ERR;
+               /* Samplerate hasn't been set. Default to 1MHz. */
+               analyzer_set_freq(1, FREQ_SCALE_MHZ);
+               devc->cur_samplerate = SR_MHZ(1);
        }
 
        return SR_OK;
@@ -533,25 +594,23 @@ static int hw_info_get(int info_id, const void **data,
        return SR_OK;
 }
 
-static int set_samplerate(const struct sr_dev_inst *sdi, uint64_t samplerate)
+static int set_samplerate(struct dev_context *devc, uint64_t samplerate)
 {
-       struct dev_context *devc;
-
-       if (!sdi) {
-               sr_err("zp: %s: sdi was NULL", __func__);
-               return SR_ERR_ARG;
-       }
+       int i;
 
-       if (!(devc = sdi->priv)) {
-               sr_err("zp: %s: sdi->priv was NULL", __func__);
+       for (i = 0; supported_samplerates[i]; i++)
+               if (samplerate == supported_samplerates[i])
+                       break;
+       if (!supported_samplerates[i] || samplerate > devc->max_samplerate) {
+               sr_err("zp: %s: unsupported samplerate", __func__);
                return SR_ERR_ARG;
        }
 
        sr_info("zp: Setting samplerate to %" PRIu64 "Hz.", samplerate);
 
-       if (samplerate > SR_MHZ(1))
+       if (samplerate >= SR_MHZ(1))
                analyzer_set_freq(samplerate / SR_MHZ(1), FREQ_SCALE_MHZ);
-       else if (samplerate > SR_KHZ(1))
+       else if (samplerate >= SR_KHZ(1))
                analyzer_set_freq(samplerate / SR_KHZ(1), FREQ_SCALE_KHZ);
        else
                analyzer_set_freq(samplerate, FREQ_SCALE_HZ);
@@ -561,11 +620,52 @@ static int set_samplerate(const struct sr_dev_inst *sdi, 
uint64_t samplerate)
        return SR_OK;
 }
 
+static int set_limit_samples(struct dev_context *devc, uint64_t samples)
+{
+       devc->limit_samples = samples;
+
+       if (samples <= 2 * 1024)
+               devc->memory_size = MEMORY_SIZE_8K;
+       else if (samples <= 16 * 1024)
+               devc->memory_size = MEMORY_SIZE_64K;
+       else if (samples <= 32 * 1024 ||
+                devc->max_memory_size <= 32 * 1024)
+               devc->memory_size = MEMORY_SIZE_128K;
+       else
+               devc->memory_size = MEMORY_SIZE_512K;
+
+       sr_info("zp: Setting memory size to %dK.",
+               get_memory_size(devc->memory_size) / 1024);
+
+       analyzer_set_memory_size(devc->memory_size);
+
+       return SR_OK;
+}
+
+static int set_capture_ratio(struct dev_context *devc, uint64_t ratio)
+{
+       if (ratio > 100) {
+               sr_err("zp: %s: invalid capture ratio", __func__);
+               return SR_ERR_ARG;
+       }
+
+       devc->capture_ratio = ratio;
+
+       sr_info("zp: Setting capture ratio to %d%%.", devc->capture_ratio);
+
+       return SR_OK;
+}
+
 static int hw_dev_config_set(const struct sr_dev_inst *sdi, int hwcap,
-               const void *value)
+                            const void *value)
 {
        struct dev_context *devc;
 
+       if (!sdi) {
+               sr_err("zp: %s: sdi was NULL", __func__);
+               return SR_ERR_ARG;
+       }
+
        if (!(devc = sdi->priv)) {
                sr_err("zp: %s: sdi->priv was NULL", __func__);
                return SR_ERR_ARG;
@@ -573,15 +673,45 @@ static int hw_dev_config_set(const struct sr_dev_inst 
*sdi, int hwcap,
 
        switch (hwcap) {
        case SR_HWCAP_SAMPLERATE:
-               return set_samplerate(sdi, *(const uint64_t *)value);
+               return set_samplerate(devc, *(const uint64_t *)value);
        case SR_HWCAP_LIMIT_SAMPLES:
-               devc->limit_samples = *(const uint64_t *)value;
-               return SR_OK;
+               return set_limit_samples(devc, *(const uint64_t *)value);
+       case SR_HWCAP_CAPTURE_RATIO:
+               return set_capture_ratio(devc, *(const uint64_t *)value);
        default:
                return SR_ERR;
        }
 }
 
+static void set_triggerbar(struct dev_context *devc)
+{
+       unsigned int ramsize;
+       unsigned int n;
+       unsigned int triggerbar;
+
+       ramsize = get_memory_size(devc->memory_size) / 4;
+       if (devc->trigger) {
+               n = ramsize;
+               if (devc->max_memory_size < n)
+                       n = devc->max_memory_size;
+               if (devc->limit_samples < n)
+                       n = devc->limit_samples;
+               n = n * devc->capture_ratio / 100;
+               if (n > ramsize - 8)
+                       triggerbar = ramsize - 8;
+               else
+                       triggerbar = n;
+       } else {
+               triggerbar = 0;
+       }
+       analyzer_set_triggerbar_address(triggerbar);
+       analyzer_set_ramsize_trigger_address(ramsize - triggerbar);
+
+       sr_dbg("zp: triggerbar_address = %d(0x%x)", triggerbar, triggerbar);
+       sr_dbg("zp: ramsize_triggerbar_address = %d(0x%x)",
+              ramsize - triggerbar, ramsize - triggerbar);
+}
+
 static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi,
                void *cb_data)
 {
@@ -589,9 +719,10 @@ static int hw_dev_acquisition_start(const struct 
sr_dev_inst *sdi,
        struct sr_datafeed_logic logic;
        struct sr_datafeed_header header;
        struct sr_datafeed_meta_logic meta;
-       uint64_t samples_read;
+       //uint64_t samples_read;
        int res;
        unsigned int packet_num;
+       unsigned int n;
        unsigned char *buf;
        struct dev_context *devc;
 
@@ -605,6 +736,8 @@ static int hw_dev_acquisition_start(const struct 
sr_dev_inst *sdi,
                return SR_ERR;
        }
 
+       set_triggerbar(devc);
+
        /* push configured settings to device */
        analyzer_configure(devc->usb->devhdl);
 
@@ -637,13 +770,15 @@ static int hw_dev_acquisition_start(const struct 
sr_dev_inst *sdi,
                return SR_ERR_MALLOC;
        }
 
-       samples_read = 0;
+       //samples_read = 0;
        analyzer_read_start(devc->usb->devhdl);
        /* Send the incoming transfer to the session bus. */
-       for (packet_num = 0; packet_num < (devc->memory_size * 4 / PACKET_SIZE);
-            packet_num++) {
+       n = get_memory_size(devc->memory_size);
+       if (devc->max_memory_size * 4 < n)
+               n = devc->max_memory_size * 4;
+       for (packet_num = 0; packet_num < n / PACKET_SIZE; packet_num++) {
                res = analyzer_read_data(devc->usb->devhdl, buf, PACKET_SIZE);
-               sr_info("zp: Tried to read %llx bytes, actually read %x bytes",
+               sr_info("zp: Tried to read %d bytes, actually read %d bytes",
                        PACKET_SIZE, res);
 
                packet.type = SR_DF_LOGIC;
@@ -652,7 +787,7 @@ static int hw_dev_acquisition_start(const struct 
sr_dev_inst *sdi,
                logic.unitsize = 4;
                logic.data = buf;
                sr_session_send(cb_data, &packet);
-               samples_read += res / 4;
+               //samples_read += res / 4;
        }
        analyzer_read_stop(devc->usb->devhdl);
        g_free(buf);
-- 
1.7.11.7


------------------------------------------------------------------------------
LogMeIn Central: Instant, anywhere, Remote PC access and management.
Stay in control, update software, and manage PCs from one command center
Diagnose problems and improve visibility into emerging IT issues
Automate, monitor and manage. Do more in less time with Central
http://p.sf.net/sfu/logmein12331_d2d
_______________________________________________
sigrok-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sigrok-devel

Reply via email to