X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;f=hardware%2Fzeroplus-logic-cube%2Fanalyzer.c;h=79377f184e591d92d529c3a8b4323245a573550d;hb=cea26f6e9f1a58f28a4b790756a2f95dcf0eaa9d;hp=283820b2dbc1e15306757ddbe52c8179b5a40ec9;hpb=38ba2522516b481fa3619bdec56d1e2a4b7a5f45;p=libsigrok.git diff --git a/hardware/zeroplus-logic-cube/analyzer.c b/hardware/zeroplus-logic-cube/analyzer.c index 283820b2..79377f18 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,11 +112,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. */ @@ -124,6 +127,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 +245,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 +264,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) @@ -302,30 +385,31 @@ static void analyzer_set_filter(libusb_device_handle *devh) gl_reg_write(devh, FILTER_STATUS + i, g_filter_status[i]); } -void analyzer_reset(libusb_device_handle *devh) +SR_PRIV void analyzer_reset(libusb_device_handle *devh) { analyzer_write_status(devh, 3, STATUS_FLAG_NONE); // reset device analyzer_write_status(devh, 3, STATUS_FLAG_RESET); // reset device } -void analyzer_initialize(libusb_device_handle *devh) +SR_PRIV void analyzer_initialize(libusb_device_handle *devh) { analyzer_write_status(devh, 1, STATUS_FLAG_NONE); analyzer_write_status(devh, 1, STATUS_FLAG_INIT); analyzer_write_status(devh, 1, STATUS_FLAG_NONE); } -void analyzer_wait(libusb_device_handle *devh, int set, int unset) +SR_PRIV void analyzer_wait(libusb_device_handle *devh, int set, int unset) { int status; + while (1) { - status = gl_reg_read(devh, DEVICE_STATUS); + status = gl_reg_read(devh, DEV_STATUS); if ((status & set) && ((status & unset) == 0)) return; } } -void analyzer_read_start(libusb_device_handle *devh) +SR_PRIV void analyzer_read_start(libusb_device_handle *devh) { int i; @@ -335,19 +419,19 @@ void analyzer_read_start(libusb_device_handle *devh) (void)gl_reg_read(devh, READ_RAM_STATUS); } -int analyzer_read_data(libusb_device_handle *devh, void *buffer, +SR_PRIV int analyzer_read_data(libusb_device_handle *devh, void *buffer, unsigned int size) { return gl_read_bulk(devh, buffer, size); } -void analyzer_read_stop(libusb_device_handle *devh) +SR_PRIV void analyzer_read_stop(libusb_device_handle *devh) { analyzer_write_status(devh, 3, STATUS_FLAG_20); analyzer_write_status(devh, 3, STATUS_FLAG_NONE); } -void analyzer_start(libusb_device_handle *devh) +SR_PRIV void analyzer_start(libusb_device_handle *devh) { analyzer_write_status(devh, 1, STATUS_FLAG_NONE); analyzer_write_status(devh, 1, STATUS_FLAG_INIT); @@ -355,7 +439,7 @@ void analyzer_start(libusb_device_handle *devh) analyzer_write_status(devh, 1, STATUS_FLAG_GO); } -void analyzer_configure(libusb_device_handle *devh) +SR_PRIV void analyzer_configure(libusb_device_handle *devh) { int i; @@ -393,7 +477,10 @@ 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); @@ -405,50 +492,32 @@ void analyzer_configure(libusb_device_handle *devh) __analyzer_set_compression(devh, g_compression); } -void analyzer_add_trigger(int channel, int type) +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; } } -void analyzer_add_filter(int channel, int type) +SR_PRIV void analyzer_add_filter(int channel, int type) { int i; @@ -479,73 +548,77 @@ void analyzer_add_filter(int channel, int type) g_filter_enable = 1; } -void analyzer_set_trigger_count(int count) +SR_PRIV void analyzer_set_trigger_count(int count) { g_trigger_count = count; } -void analyzer_set_freq(int freq, int scale) +SR_PRIV void analyzer_set_freq(int freq, int scale) { g_freq_value = freq; g_freq_scale = scale; } -void analyzer_set_memory_size(unsigned int size) +SR_PRIV void analyzer_set_memory_size(unsigned int size) { g_memory_size = size; } -void analyzer_set_ramsize_trigger_address(unsigned int address) +SR_PRIV void analyzer_set_ramsize_trigger_address(unsigned int address) { g_ramsize_triggerbar_addr = address; } -void analyzer_set_triggerbar_address(unsigned int address) +SR_PRIV void analyzer_set_triggerbar_address(unsigned int address) { g_triggerbar_addr = address; } -unsigned int analyzer_read_id(libusb_device_handle *devh) +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); } -unsigned int analyzer_get_stop_address(libusb_device_handle *devh) +SR_PRIV unsigned int analyzer_get_stop_address(libusb_device_handle *devh) { return gl_reg_read(devh, STOP_ADDRESS2) << 16 | gl_reg_read(devh, STOP_ADDRESS1) << 8 | gl_reg_read(devh, STOP_ADDRESS0); } -unsigned int analyzer_get_now_address(libusb_device_handle *devh) +SR_PRIV unsigned int analyzer_get_now_address(libusb_device_handle *devh) { return gl_reg_read(devh, NOW_ADDRESS2) << 16 | gl_reg_read(devh, NOW_ADDRESS1) << 8 | gl_reg_read(devh, NOW_ADDRESS0); } -unsigned int analyzer_get_trigger_address(libusb_device_handle *devh) +SR_PRIV unsigned int analyzer_get_trigger_address(libusb_device_handle *devh) { return gl_reg_read(devh, TRIGGER_ADDRESS2) << 16 | gl_reg_read(devh, TRIGGER_ADDRESS1) << 8 | gl_reg_read(devh, TRIGGER_ADDRESS0); } -void analyzer_set_compression(unsigned int type) +SR_PRIV void analyzer_set_compression(unsigned int type) { g_compression = type; } -void analyzer_wait_button(libusb_device_handle *devh) +SR_PRIV void analyzer_wait_button(libusb_device_handle *devh) { analyzer_wait(devh, STATUS_BUTTON_PRESSED, 0); } -void analyzer_wait_data(libusb_device_handle *devh) +SR_PRIV void analyzer_wait_data(libusb_device_handle *devh) { analyzer_wait(devh, STATUS_READY | 8, STATUS_BUSY); } -int analyzer_decompress(void *input, unsigned int input_len, void *output, - unsigned int output_len) +SR_PRIV int analyzer_decompress(void *input, unsigned int input_len, + void *output, unsigned int output_len) { unsigned char *in = input; unsigned char *out = output;