X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;f=hardware%2Fzeroplus-logic-cube%2Fanalyzer.c;h=c404a66b73b04a47324f5c5c539c866fe8a0300e;hb=43cd4637285833706f8a404ca027bcf0ee75b9ae;hp=78db7baf68936757f19d2be0d8434e2253dcb045;hpb=ca070ed9a0237e5cea10e5dd974e06da62de890d;p=libsigrok.git diff --git a/hardware/zeroplus-logic-cube/analyzer.c b/hardware/zeroplus-logic-cube/analyzer.c index 78db7baf..c404a66b 100644 --- a/hardware/zeroplus-logic-cube/analyzer.c +++ b/hardware/zeroplus-logic-cube/analyzer.c @@ -1,5 +1,5 @@ /* - * This file is part of the sigrok project. + * This file is part of the libsigrok project. * * Copyright (C) 2010 Sven Peter * Copyright (C) 2010 Haxx Enterprises @@ -30,18 +30,21 @@ */ #include +#include "libsigrok.h" +#include "libsigrok-internal.h" #include "analyzer.h" #include "gl_usb.h" +#include "protocol.h" enum { HARD_DATA_CHECK_SUM = 0x00, PASS_WORD, - DEVICE_ID0 = 0x10, - DEVICE_ID1, + DEV_ID0 = 0x10, + DEV_ID1, START_STATUS = 0x20, - DEVICE_STATUS = 0x21, + DEV_STATUS = 0x21, FREQUENCY_REG0 = 0x30, FREQUENCY_REG1, FREQUENCY_REG2, @@ -109,12 +112,13 @@ 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; +static int g_thresh = 0x31; /* 1.5V */ /* Maybe unk specifies an "endpoint" or "register" of sorts. */ static int analyzer_write_status(libusb_device_handle *devh, unsigned char unk, @@ -124,6 +128,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; @@ -241,6 +246,11 @@ static int __analyzer_set_freq(libusb_device_handle *devh, int freq, int scale) reg2 = 64; break; } + + sr_dbg("Setting samplerate regs (freq=%d, scale=%d): " + "reg0: %d, reg1: %d, reg2: %d, reg3: %d.", + freq, scale, divisor, reg0, 0x02, reg2); + if (gl_reg_write(devh, FREQUENCY_REG0, divisor) < 0) return -1; /* Divisor maybe? */ @@ -255,6 +265,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("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) @@ -318,21 +402,20 @@ SR_PRIV void analyzer_initialize(libusb_device_handle *devh) SR_PRIV void analyzer_wait(libusb_device_handle *devh, int set, int unset) { int status; + while (1) { - status = gl_reg_read(devh, DEVICE_STATUS); - if ((status & set) && ((status & unset) == 0)) + status = gl_reg_read(devh, DEV_STATUS); + if ((!set || (status & set)) && ((status & unset) == 0)) return; } } SR_PRIV void analyzer_read_start(libusb_device_handle *devh) { - int i; - analyzer_write_status(devh, 3, STATUS_FLAG_20 | STATUS_FLAG_READ); - for (i = 0; i < 8; i++) - (void)gl_reg_read(devh, READ_RAM_STATUS); + /* Prep for bulk reads */ + gl_reg_read_buf(devh, READ_RAM_STATUS, NULL, 0); } SR_PRIV int analyzer_read_data(libusb_device_handle *devh, void *buffer, @@ -383,10 +466,10 @@ SR_PRIV void analyzer_configure(libusb_device_handle *devh) __analyzer_set_trigger_count(devh, g_trigger_count); /* Set_Trigger_Level */ - gl_reg_write(devh, TRIGGER_LEVEL0, 0x31); - gl_reg_write(devh, TRIGGER_LEVEL1, 0x31); - gl_reg_write(devh, TRIGGER_LEVEL2, 0x31); - gl_reg_write(devh, TRIGGER_LEVEL3, 0x31); + gl_reg_write(devh, TRIGGER_LEVEL0, g_thresh); + gl_reg_write(devh, TRIGGER_LEVEL1, g_thresh); + gl_reg_write(devh, TRIGGER_LEVEL2, g_thresh); + gl_reg_write(devh, TRIGGER_LEVEL3, g_thresh); /* Size of actual memory >> 2 */ __analyzer_set_ramsize_trigger_address(devh, g_ramsize_triggerbar_addr); @@ -405,47 +488,43 @@ SR_PRIV void analyzer_configure(libusb_device_handle *devh) __analyzer_set_compression(devh, g_compression); } -SR_PRIV void analyzer_add_trigger(int channel, int type) +SR_PRIV int analyzer_add_triggers(const struct sr_dev_inst *sdi) { - 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; + struct dev_context *devc; + struct sr_trigger *trigger; + struct sr_trigger_stage *stage; + struct sr_trigger_match *match; + GSList *l, *m; + int channel; + + devc = sdi->priv; + + if (!(trigger = sr_session_trigger_get(sdi->session))) + return SR_OK; + + for (l = trigger->stages; l; l = l->next) { + stage = l->data; + for (m = stage->matches; m; m = m->next) { + match = m->data; + devc->trigger = 1; + if (!match->channel->enabled) + /* Ignore disabled channels with a trigger. */ + continue; + channel = match->channel->index; + switch (match->match) { + case SR_TRIGGER_ZERO: + g_trigger_status[channel / 4] |= 2 << (channel % 4 * 2); + case SR_TRIGGER_ONE: + g_trigger_status[channel / 4] |= 1 << (channel % 4 * 2); + break; + default: + sr_err("Unsupported match %d", match->match); + return SR_ERR; + } } - 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; } + + return SR_OK; } SR_PRIV void analyzer_add_filter(int channel, int type) @@ -500,15 +579,29 @@ SR_PRIV void analyzer_set_ramsize_trigger_address(unsigned int address) g_ramsize_triggerbar_addr = address; } +SR_PRIV unsigned int analyzer_get_ramsize_trigger_address(void) +{ + return g_ramsize_triggerbar_addr; +} + SR_PRIV void analyzer_set_triggerbar_address(unsigned int address) { g_triggerbar_addr = address; } +SR_PRIV unsigned int analyzer_get_triggerbar_address(void) +{ + return g_triggerbar_addr; +} + +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, DEVICE_ID1) << 8 | gl_reg_read(devh, - DEVICE_ID0); + return gl_reg_read(devh, DEV_ID1) << 8 | gl_reg_read(devh, DEV_ID0); } SR_PRIV unsigned int analyzer_get_stop_address(libusb_device_handle *devh) @@ -534,6 +627,11 @@ SR_PRIV void analyzer_set_compression(unsigned int type) g_compression = type; } +SR_PRIV void analyzer_set_voltage_threshold(int thresh) +{ + g_thresh = thresh; +} + SR_PRIV void analyzer_wait_button(libusb_device_handle *devh) { analyzer_wait(devh, STATUS_BUTTON_PRESSED, 0); @@ -541,7 +639,7 @@ SR_PRIV void analyzer_wait_button(libusb_device_handle *devh) SR_PRIV void analyzer_wait_data(libusb_device_handle *devh) { - analyzer_wait(devh, STATUS_READY | 8, STATUS_BUSY); + analyzer_wait(devh, 0, STATUS_BUSY); } SR_PRIV int analyzer_decompress(void *input, unsigned int input_len,