Saleae/Zeroplus: Coding style fixes.

This commit is contained in:
Uwe Hermann 2010-04-15 22:59:43 +02:00
parent 43fc7885d3
commit fed16f06e2
6 changed files with 609 additions and 537 deletions

View File

@ -44,7 +44,7 @@
#define NUM_SIMUL_TRANSFERS 10 #define NUM_SIMUL_TRANSFERS 10
#define MAX_EMPTY_TRANSFERS (NUM_SIMUL_TRANSFERS * 2) #define MAX_EMPTY_TRANSFERS (NUM_SIMUL_TRANSFERS * 2)
/* software trigger implementation: positive values indicate trigger stage */ /* Software trigger implementation: positive values indicate trigger stage. */
#define TRIGGER_FIRED -1 #define TRIGGER_FIRED -1
/* There is only one model Saleae Logic, and this is what it supports: */ /* There is only one model Saleae Logic, and this is what it supports: */
@ -98,12 +98,14 @@ static uint8_t probe_mask = 0;
static uint8_t trigger_mask[NUM_TRIGGER_STAGES] = { 0 }; static uint8_t trigger_mask[NUM_TRIGGER_STAGES] = { 0 };
static uint8_t trigger_value[NUM_TRIGGER_STAGES] = { 0 }; static uint8_t trigger_value[NUM_TRIGGER_STAGES] = { 0 };
static uint8_t trigger_buffer[NUM_TRIGGER_STAGES] = { 0 }; static uint8_t trigger_buffer[NUM_TRIGGER_STAGES] = { 0 };
int trigger_stage = TRIGGER_FIRED; int trigger_stage = TRIGGER_FIRED;
static int hw_set_configuration(int device_index, int capability, void *value); static int hw_set_configuration(int device_index, int capability, void *value);
/* returns 1 if the device's configuration profile match the Logic firmware's /*
* configuration, 0 otherwise * Returns 1 if the device's configuration profile match the Logic firmware's
* configuration, 0 otherwise.
*/ */
int check_conf_profile(libusb_device *dev) int check_conf_profile(libusb_device *dev)
{ {
@ -391,7 +393,8 @@ static int hw_init(char *deviceinfo)
* or uploading the firmware again. * or uploading the firmware again.
*/ */
if (upload_firmware(devlist[i]) > 0) if (upload_firmware(devlist[i]) > 0)
g_warning("firmware upload failed for device %d", devcnt); g_warning("firmware upload failed for "
"device %d", devcnt);
sdi->usb = usb_device_instance_new sdi->usb = usb_device_instance_new
(libusb_get_bus_number(devlist[i]), 0, NULL); (libusb_get_bus_number(devlist[i]), 0, NULL);
@ -399,8 +402,7 @@ static int hw_init(char *deviceinfo)
/* Already has the firmware, so fix the new address. */ /* Already has the firmware, so fix the new address. */
sdi->usb = usb_device_instance_new sdi->usb = usb_device_instance_new
(libusb_get_bus_number(devlist[i]), (libusb_get_bus_number(devlist[i]),
libusb_get_device_address(devlist[i]), libusb_get_device_address(devlist[i]), NULL);
NULL);
} }
devcnt++; devcnt++;
} }

View File

@ -1,34 +1,35 @@
/* /*
Copyright (c) 2010 Sven Peter <sven@fail0verflow.com> * This file is part of the sigrok project.
Copyright (c) 2010 Haxx Enterprises <bushing@gmail.com> *
All rights reserved. * Copyright (C) 2010 Sven Peter <sven@fail0verflow.com>
* Copyright (C) 2010 Haxx Enterprises <bushing@gmail.com>
Redistribution and use in source and binary forms, with or * All rights reserved.
without modification, are permitted provided that the following *
conditions are met: * Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* Redistributions of source code must retain the above copyright notice, * conditions are met:
this list of conditions and the following disclaimer. *
* * Redistributions of source code must retain the above copyright notice,
* Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer.
this list of conditions and the following disclaimer in the documentation *
and/or other materials provided with the distribution. * * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * and/or other materials provided with the distribution.
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE *
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
THE POSSIBILITY OF SUCH DAMAGE. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <assert.h>
#include <assert.h>
#include "analyzer.h" #include "analyzer.h"
#include "gl_usb.h" #include "gl_usb.h"
@ -78,7 +79,7 @@ enum {
FILTER_ENABLE = 0x70, FILTER_ENABLE = 0x70,
FILTER_STATUS, FILTER_STATUS,
ENABLE_DELAY_TIME0 = 0x7A, ENABLE_DELAY_TIME0 = 0x7a,
ENABLE_DELAY_TIME1, ENABLE_DELAY_TIME1,
ENABLE_INSERT_DATA0 = 0x80, ENABLE_INSERT_DATA0 = 0x80,
@ -96,16 +97,15 @@ enum {
NOW_ADDRESS1, NOW_ADDRESS1,
NOW_ADDRESS2, NOW_ADDRESS2,
STOP_ADDRESS0 = 0x9B, STOP_ADDRESS0 = 0x9b,
STOP_ADDRESS1, STOP_ADDRESS1,
STOP_ADDRESS2, STOP_ADDRESS2,
READ_RAM_STATUS = 0xA0 READ_RAM_STATUS = 0xa0,
}; };
static int g_trigger_status[9] = { 0 }; static int g_trigger_status[9] = { 0 };
static int g_trigger_count = 1; static int g_trigger_count = 1;
static int g_filter_status[8] = { 0 }; static int g_filter_status[8] = { 0 };
static int g_filter_enable = 0; static int g_filter_enable = 0;
@ -116,8 +116,9 @@ static int g_ramsize_triggerbar_addr = 0x80000>>2;
static int g_triggerbar_addr = 0x3fe; static int g_triggerbar_addr = 0x3fe;
static int g_compression = COMPRESSION_NONE; static int g_compression = COMPRESSION_NONE;
// maybe unk specifies an "endpoint" or "register" of sorts /* Maybe unk specifies an "endpoint" or "register" of sorts. */
static int analyzer_write_status(libusb_device_handle *devh, unsigned char unk, unsigned char flags) static int analyzer_write_status(libusb_device_handle *devh, unsigned char unk,
unsigned char flags)
{ {
assert(unk <= 3); assert(unk <= 3);
return gl_reg_write(devh, START_STATUS, unk << 6 | flags); return gl_reg_write(devh, START_STATUS, unk << 6 | flags);
@ -126,8 +127,9 @@ static int analyzer_write_status(libusb_device_handle *devh, unsigned char unk,
static int __analyzer_set_freq(libusb_device_handle *devh, int freq, int scale) static int __analyzer_set_freq(libusb_device_handle *devh, int freq, int scale)
{ {
int reg0 = 0, divisor = 0, reg2 = 0; int reg0 = 0, divisor = 0, reg2 = 0;
switch (scale) { switch (scale) {
case FREQ_SCALE_MHZ: // MHz case FREQ_SCALE_MHZ: /* MHz */
if (freq >= 100 && freq <= 200) { if (freq >= 100 && freq <= 200) {
reg0 = freq * 0.1; reg0 = freq * 0.1;
divisor = 1; divisor = 1;
@ -169,7 +171,7 @@ static int __analyzer_set_freq(libusb_device_handle *devh, int freq, int scale)
reg0 = 5; reg0 = 5;
reg2 = 64; reg2 = 64;
break; break;
case FREQ_SCALE_HZ: // Hz case FREQ_SCALE_HZ: /* Hz */
if (freq >= 500 && freq < 1000) { if (freq >= 500 && freq < 1000) {
reg0 = freq * 0.01; reg0 = freq * 0.01;
divisor = 10; divisor = 10;
@ -192,7 +194,7 @@ static int __analyzer_set_freq(libusb_device_handle *devh, int freq, int scale)
reg0 = 5; reg0 = 5;
reg2 = 64; reg2 = 64;
break; break;
case FREQ_SCALE_KHZ: // KHz case FREQ_SCALE_KHZ: /* KHz */
if (freq >= 500 && freq < 1000) { if (freq >= 500 && freq < 1000) {
reg0 = freq * 0.01; reg0 = freq * 0.01;
divisor = 5; divisor = 5;
@ -240,13 +242,13 @@ static int __analyzer_set_freq(libusb_device_handle *devh, int freq, int scale)
break; break;
} }
if (gl_reg_write(devh, FREQUENCY_REG0, divisor) < 0) if (gl_reg_write(devh, FREQUENCY_REG0, divisor) < 0)
return -1; // divisor maybe? return -1; /* Divisor maybe? */
if (gl_reg_write(devh, FREQUENCY_REG1, reg0) < 0) if (gl_reg_write(devh, FREQUENCY_REG1, reg0) < 0)
return -1; // 10 / 0.2 return -1; /* 10 / 0.2 */
if (gl_reg_write(devh, FREQUENCY_REG2, 0x02) < 0) if (gl_reg_write(devh, FREQUENCY_REG2, 0x02) < 0)
return -1; // always 2 return -1; /* Always 2 */
if (gl_reg_write(devh, FREQUENCY_REG4, reg2) < 0) if (gl_reg_write(devh, FREQUENCY_REG4, reg2) < 0)
return -1; return -1;
@ -254,27 +256,31 @@ static int __analyzer_set_freq(libusb_device_handle *devh, int freq, int scale)
return 0; return 0;
} }
static void __analyzer_set_ramsize_trigger_address(libusb_device_handle *devh, unsigned int address) static void __analyzer_set_ramsize_trigger_address(libusb_device_handle *devh,
unsigned int address)
{ {
gl_reg_write(devh, RAMSIZE_TRIGGERBAR_ADDRESS0, (address >> 0) & 0xFF); gl_reg_write(devh, RAMSIZE_TRIGGERBAR_ADDRESS0, (address >> 0) & 0xFF);
gl_reg_write(devh, RAMSIZE_TRIGGERBAR_ADDRESS1, (address >> 8) & 0xFF); gl_reg_write(devh, RAMSIZE_TRIGGERBAR_ADDRESS1, (address >> 8) & 0xFF);
gl_reg_write(devh, RAMSIZE_TRIGGERBAR_ADDRESS2, (address >> 16) & 0xFF); gl_reg_write(devh, RAMSIZE_TRIGGERBAR_ADDRESS2, (address >> 16) & 0xFF);
} }
static void __analyzer_set_triggerbar_address(libusb_device_handle *devh, unsigned int address) static void __analyzer_set_triggerbar_address(libusb_device_handle *devh,
unsigned int address)
{ {
gl_reg_write(devh, TRIGGERBAR_ADDRESS0, (address >> 0) & 0xFF); gl_reg_write(devh, TRIGGERBAR_ADDRESS0, (address >> 0) & 0xFF);
gl_reg_write(devh, TRIGGERBAR_ADDRESS1, (address >> 8) & 0xFF); gl_reg_write(devh, TRIGGERBAR_ADDRESS1, (address >> 8) & 0xFF);
gl_reg_write(devh, TRIGGERBAR_ADDRESS2, (address >> 16) & 0xFF); gl_reg_write(devh, TRIGGERBAR_ADDRESS2, (address >> 16) & 0xFF);
} }
static void __analyzer_set_compression(libusb_device_handle *devh, unsigned int type) static void __analyzer_set_compression(libusb_device_handle *devh,
unsigned int type)
{ {
gl_reg_write(devh, COMPRESSION_TYPE0, (type >> 0) & 0xFF); gl_reg_write(devh, COMPRESSION_TYPE0, (type >> 0) & 0xFF);
gl_reg_write(devh, COMPRESSION_TYPE1, (type >> 8) & 0xFF); gl_reg_write(devh, COMPRESSION_TYPE1, (type >> 8) & 0xFF);
} }
static void __analyzer_set_trigger_count(libusb_device_handle *devh, unsigned int count) static void __analyzer_set_trigger_count(libusb_device_handle *devh,
unsigned int count)
{ {
gl_reg_write(devh, TRIGGER_COUNT0, (count >> 0) & 0xFF); gl_reg_write(devh, TRIGGER_COUNT0, (count >> 0) & 0xFF);
gl_reg_write(devh, TRIGGER_COUNT1, (count >> 8) & 0xFF); gl_reg_write(devh, TRIGGER_COUNT1, (count >> 8) & 0xFF);
@ -329,7 +335,8 @@ void analyzer_read_start(libusb_device_handle *devh)
(void)gl_reg_read(devh, READ_RAM_STATUS); (void)gl_reg_read(devh, READ_RAM_STATUS);
} }
int analyzer_read_data(libusb_device_handle *devh, void *buffer, unsigned int size) int analyzer_read_data(libusb_device_handle *devh, void *buffer,
unsigned int size)
{ {
return gl_read_bulk(devh, buffer, size); return gl_read_bulk(devh, buffer, size);
} }
@ -350,46 +357,48 @@ void analyzer_start(libusb_device_handle *devh)
void analyzer_configure(libusb_device_handle *devh) void analyzer_configure(libusb_device_handle *devh)
{ {
// Write_Start_Status int i;
/* Write_Start_Status */
analyzer_write_status(devh, 1, STATUS_FLAG_RESET); analyzer_write_status(devh, 1, STATUS_FLAG_RESET);
analyzer_write_status(devh, 1, STATUS_FLAG_NONE); analyzer_write_status(devh, 1, STATUS_FLAG_NONE);
// Start_Config_Outside_Device ? /* Start_Config_Outside_Device ? */
analyzer_write_status(devh, 1, STATUS_FLAG_INIT); analyzer_write_status(devh, 1, STATUS_FLAG_INIT);
analyzer_write_status(devh, 1, STATUS_FLAG_NONE); analyzer_write_status(devh, 1, STATUS_FLAG_NONE);
//SetData_To_Frequence_Reg /* SetData_To_Frequence_Reg */
__analyzer_set_freq(devh, g_freq_value, g_freq_scale); __analyzer_set_freq(devh, g_freq_value, g_freq_scale);
//SetMemory_Length /* SetMemory_Length */
gl_reg_write(devh, MEMORY_LENGTH, g_memory_size); gl_reg_write(devh, MEMORY_LENGTH, g_memory_size);
//Sele_Inside_Outside_Clock /* Sele_Inside_Outside_Clock */
gl_reg_write(devh, CLOCK_SOURCE, 0x03); gl_reg_write(devh, CLOCK_SOURCE, 0x03);
//Set_Trigger_Status /* Set_Trigger_Status */
int i;
for (i = 0; i < 9; i++) for (i = 0; i < 9; i++)
gl_reg_write(devh, TRIGGER_STATUS0 + i, g_trigger_status[i]); gl_reg_write(devh, TRIGGER_STATUS0 + i, g_trigger_status[i]);
__analyzer_set_trigger_count(devh, g_trigger_count); __analyzer_set_trigger_count(devh, g_trigger_count);
//Set_Trigger_Level /* Set_Trigger_Level */
gl_reg_write(devh, TRIGGER_LEVEL0, 0x31); gl_reg_write(devh, TRIGGER_LEVEL0, 0x31);
gl_reg_write(devh, TRIGGER_LEVEL1, 0x31); gl_reg_write(devh, TRIGGER_LEVEL1, 0x31);
gl_reg_write(devh, TRIGGER_LEVEL2, 0x31); gl_reg_write(devh, TRIGGER_LEVEL2, 0x31);
gl_reg_write(devh, TRIGGER_LEVEL3, 0x31); gl_reg_write(devh, TRIGGER_LEVEL3, 0x31);
__analyzer_set_ramsize_trigger_address(devh, g_ramsize_triggerbar_addr); // size of actual memory >> 2 /* Size of actual memory >> 2 */
__analyzer_set_ramsize_trigger_address(devh, g_ramsize_triggerbar_addr);
__analyzer_set_triggerbar_address(devh, g_triggerbar_addr); __analyzer_set_triggerbar_address(devh, g_triggerbar_addr);
//Set_Dont_Care_TriggerBar /* Set_Dont_Care_TriggerBar */
gl_reg_write(devh, DONT_CARE_TRIGGERBAR, 0x01); gl_reg_write(devh, DONT_CARE_TRIGGERBAR, 0x01);
//Enable_Status /* Enable_Status */
analyzer_set_filter(devh); analyzer_set_filter(devh);
//Set_Enable_Delay_Time /* Set_Enable_Delay_Time */
gl_reg_write(devh, 0x7a, 0x00); gl_reg_write(devh, 0x7a, 0x00);
gl_reg_write(devh, 0x7b, 0x00); gl_reg_write(devh, 0x7b, 0x00);
analyzer_write_enable_insert_data(devh); analyzer_write_enable_insert_data(devh);
@ -398,11 +407,12 @@ void analyzer_configure(libusb_device_handle *devh)
void analyzer_add_trigger(int channel, int type) void analyzer_add_trigger(int channel, int type)
{ {
int i;
if ((channel & 0xf) >= 8) if ((channel & 0xf) >= 8)
return; return;
if (type == TRIGGER_HIGH || type == TRIGGER_LOW) { if (type == TRIGGER_HIGH || type == TRIGGER_LOW) {
int i;
if (channel & CHANNEL_A) if (channel & CHANNEL_A)
i = 0; i = 0;
else if (channel & CHANNEL_B) else if (channel & CHANNEL_B)
@ -417,7 +427,8 @@ void analyzer_add_trigger(int channel, int type)
i++; i++;
channel -= 4; channel -= 4;
} }
g_trigger_status[i] |= 1 << ((2 * channel) + (type == TRIGGER_LOW ? 1 : 0)); g_trigger_status[i] |=
1 << ((2 * channel) + (type == TRIGGER_LOW ? 1 : 0));
} else { } else {
if (type == TRIGGER_POSEDGE) if (type == TRIGGER_POSEDGE)
g_trigger_status[8] = 0x40; g_trigger_status[8] = 0x40;
@ -426,7 +437,7 @@ void analyzer_add_trigger(int channel, int type)
else else
g_trigger_status[8] = 0xc0; g_trigger_status[8] = 0xc0;
// FIXME: just guessed the index; need to verify /* FIXME: Just guessed the index; need to verify. */
if (channel & CHANNEL_B) if (channel & CHANNEL_B)
g_trigger_status[8] += 8; g_trigger_status[8] += 8;
else if (channel & CHANNEL_C) else if (channel & CHANNEL_C)
@ -439,12 +450,13 @@ void analyzer_add_trigger(int channel, int type)
void analyzer_add_filter(int channel, int type) void analyzer_add_filter(int channel, int type)
{ {
int i;
if (type != FILTER_HIGH && type != FILTER_LOW) if (type != FILTER_HIGH && type != FILTER_LOW)
return; return;
if ((channel & 0xf) >= 8) if ((channel & 0xf) >= 8)
return; return;
int i;
if (channel & CHANNEL_A) if (channel & CHANNEL_A)
i = 0; i = 0;
else if (channel & CHANNEL_B) else if (channel & CHANNEL_B)
@ -455,11 +467,15 @@ void analyzer_add_filter(int channel, int type)
i = 6; i = 6;
else else
return; return;
if ((channel & 0xf) >= 4) { if ((channel & 0xf) >= 4) {
i++; i++;
channel -= 4; channel -= 4;
} }
g_filter_status[i] |= 1 << ((2 * channel) + (type == FILTER_LOW ? 1 : 0));
g_filter_status[i] |=
1 << ((2 * channel) + (type == FILTER_LOW ? 1 : 0));
g_filter_enable = 1; g_filter_enable = 1;
} }
@ -479,7 +495,6 @@ void analyzer_set_memory_size(unsigned int size)
g_memory_size = size; g_memory_size = size;
} }
void analyzer_set_ramsize_trigger_address(unsigned int address) void analyzer_set_ramsize_trigger_address(unsigned int address)
{ {
g_ramsize_triggerbar_addr = address; g_ramsize_triggerbar_addr = address;
@ -492,22 +507,26 @@ void analyzer_set_triggerbar_address(unsigned int address)
unsigned int analyzer_read_id(libusb_device_handle *devh) 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, DEVICE_ID1) << 8 | gl_reg_read(devh,
DEVICE_ID0);
} }
unsigned int analyzer_get_stop_address(libusb_device_handle *devh) 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); 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) 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); 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) 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); 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) void analyzer_set_compression(unsigned int type)
@ -525,7 +544,8 @@ void analyzer_wait_data(libusb_device_handle *devh)
analyzer_wait(devh, STATUS_READY | 8, STATUS_BUSY); analyzer_wait(devh, STATUS_READY | 8, STATUS_BUSY);
} }
int analyzer_decompress(void *input, unsigned int input_len, void *output, unsigned int output_len) int analyzer_decompress(void *input, unsigned int input_len, void *output,
unsigned int output_len)
{ {
unsigned char *in = input; unsigned char *in = input;
unsigned char *out = output; unsigned char *out = output;
@ -547,7 +567,7 @@ int analyzer_decompress(void *input, unsigned int input_len, void *output, unsig
*out++ = A; *out++ = A;
*out++ = B; *out++ = B;
*out++ = C; *out++ = C;
*out++ = 0; // channel D *out++ = 0; /* Channel D */
} }
input_len -= 4; input_len -= 4;

View File

@ -1,35 +1,39 @@
/* /*
Copyright (c) 2010 Sven Peter <sven@fail0verflow.com> * This file is part of the sigrok project.
Copyright (c) 2010 Haxx Enterprises <bushing@gmail.com> *
All rights reserved. * Copyright (C) 2010 Sven Peter <sven@fail0verflow.com>
* Copyright (C) 2010 Haxx Enterprises <bushing@gmail.com>
Redistribution and use in source and binary forms, with or * All rights reserved.
without modification, are permitted provided that the following *
conditions are met: * Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* Redistributions of source code must retain the above copyright notice, * conditions are met:
this list of conditions and the following disclaimer. *
* * Redistributions of source code must retain the above copyright notice,
* Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer.
this list of conditions and the following disclaimer in the documentation *
and/or other materials provided with the distribution. * * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * and/or other materials provided with the distribution.
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE *
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
THE POSSIBILITY OF SUCH DAMAGE. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef ANALYZER_H__ #ifndef ANALYZER_H__
#define ANALYZER_H__ 1 #define ANALYZER_H__
#include <libusb.h> #include <libusb.h>
#define STATUS_FLAG_NONE 0x00 #define STATUS_FLAG_NONE 0x00
#define STATUS_FLAG_RESET 0x01 #define STATUS_FLAG_RESET 0x01
#define STATUS_FLAG_INIT 0x02 #define STATUS_FLAG_INIT 0x02
@ -43,7 +47,7 @@
#define MEMORY_SIZE_128K 0x02 #define MEMORY_SIZE_128K 0x02
#define MEMORY_SIZE_512K 0x04 #define MEMORY_SIZE_512K 0x04
#define STATUS_BUSY 0x01 // WTF / ??? #define STATUS_BUSY 0x01 /* WTF / ??? */
#define STATUS_READY 0x02 #define STATUS_READY 0x02
#define STATUS_BUTTON_PRESSED 0x04 #define STATUS_BUTTON_PRESSED 0x04
@ -68,7 +72,7 @@ enum {
TRIGGER_LOW, TRIGGER_LOW,
TRIGGER_POSEDGE, TRIGGER_POSEDGE,
TRIGGER_NEGEDGE, TRIGGER_NEGEDGE,
TRIGGER_ANYEDGE TRIGGER_ANYEDGE,
}; };
void analyzer_set_freq(int freq, int scale); void analyzer_set_freq(int freq, int scale);
@ -84,17 +88,20 @@ unsigned int analyzer_read_id(libusb_device_handle *devh);
unsigned int analyzer_get_stop_address(libusb_device_handle *devh); unsigned int analyzer_get_stop_address(libusb_device_handle *devh);
unsigned int analyzer_get_now_address(libusb_device_handle *devh); unsigned int analyzer_get_now_address(libusb_device_handle *devh);
unsigned int analyzer_get_trigger_address(libusb_device_handle *devh); unsigned int analyzer_get_trigger_address(libusb_device_handle *devh);
int analyzer_decompress(void *input, unsigned int input_len, void *output, unsigned int output_len); int analyzer_decompress(void *input, unsigned int input_len, void *output,
unsigned int output_len);
void analyzer_reset(libusb_device_handle *devh); void analyzer_reset(libusb_device_handle *devh);
void analyzer_initialize(libusb_device_handle *devh); void analyzer_initialize(libusb_device_handle *devh);
void analyzer_wait(libusb_device_handle *devh, int set, int unset); void analyzer_wait(libusb_device_handle *devh, int set, int unset);
void analyzer_read_start(libusb_device_handle *devh); void analyzer_read_start(libusb_device_handle *devh);
int analyzer_read_data(libusb_device_handle *devh, void *buffer, unsigned int size); int analyzer_read_data(libusb_device_handle *devh, void *buffer,
unsigned int size);
void analyzer_read_stop(libusb_device_handle *devh); void analyzer_read_stop(libusb_device_handle *devh);
void analyzer_start(libusb_device_handle *devh); void analyzer_start(libusb_device_handle *devh);
void analyzer_configure(libusb_device_handle *devh); void analyzer_configure(libusb_device_handle *devh);
void analyzer_wait_button(libusb_device_handle *devh); void analyzer_wait_button(libusb_device_handle *devh);
void analyzer_wait_data(libusb_device_handle *devh); void analyzer_wait_data(libusb_device_handle *devh);
#endif #endif

View File

@ -1,48 +1,52 @@
/* /*
Copyright (c) 2010 Sven Peter <sven@fail0verflow.com> * This file is part of the sigrok project.
Copyright (c) 2010 Haxx Enterprises <bushing@gmail.com> *
All rights reserved. * Copyright (C) 2010 Sven Peter <sven@fail0verflow.com>
* Copyright (C) 2010 Haxx Enterprises <bushing@gmail.com>
Redistribution and use in source and binary forms, with or * All rights reserved.
without modification, are permitted provided that the following *
conditions are met: * Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* Redistributions of source code must retain the above copyright notice, * conditions are met:
this list of conditions and the following disclaimer. *
* * Redistributions of source code must retain the above copyright notice,
* Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer.
this list of conditions and the following disclaimer in the documentation *
and/or other materials provided with the distribution. * * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * and/or other materials provided with the distribution.
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE *
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
THE POSSIBILITY OF SUCH DAMAGE. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <libusb.h> #include <libusb.h>
#include <stdio.h> #include <stdio.h>
#include "gl_usb.h" #include "gl_usb.h"
#define CTRL_IN (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN | LIBUSB_RECIPIENT_INTERFACE) #define CTRL_IN (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN | \
#define CTRL_OUT (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT | LIBUSB_RECIPIENT_INTERFACE) LIBUSB_RECIPIENT_INTERFACE)
const int PACKET_CTRL_LEN=2; #define CTRL_OUT (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT | \
LIBUSB_RECIPIENT_INTERFACE)
const int PACKET_CTRL_LEN = 2;
const int PACKET_INT_LEN = 2; const int PACKET_INT_LEN = 2;
const int PACKET_BULK_LEN = 64; const int PACKET_BULK_LEN = 64;
const int INTERFACE = 0; const int INTERFACE = 0;
const int ENDPOINT_INT_IN=0x81; /* endpoint 0x81 address for IN */ const int ENDPOINT_INT_IN = 0x81; /* Endpoint 0x81 address for IN */
const int ENDPOINT_INT_OUT=0x01; /* endpoint 1 address for OUT */ const int ENDPOINT_INT_OUT = 0x01; /* Endpoint 1 address for OUT */
const int ENDPOINT_BULK_IN=0x81; /* endpoint 0x81 address for IN */ const int ENDPOINT_BULK_IN = 0x81; /* Endpoint 0x81 address for IN */
const int ENDPOINT_BULK_OUT=0x02; /* endpoint 1 address for OUT */ const int ENDPOINT_BULK_OUT = 0x02; /* Endpoint 1 address for OUT */
const int TIMEOUT=5000; /* timeout in ms */ const int TIMEOUT = 5000; /* Timeout in ms */
enum { enum {
REQ_READBULK = 0x82, REQ_READBULK = 0x82,
@ -56,84 +60,105 @@ static struct libusb_device_handle *g_devh = NULL;
int gl_write_address(libusb_device_handle *devh, unsigned int address) int gl_write_address(libusb_device_handle *devh, unsigned int address)
{ {
unsigned char packet[8] = { address & 0xFF }; unsigned char packet[8] = { address & 0xFF };
int retval = libusb_control_transfer(devh, CTRL_OUT, 0xc, REQ_WRITEADDR, 0, packet, 1,TIMEOUT); int ret;
if (retval != 1) printf("%s: libusb_control_transfer returned %d\n", __FUNCTION__, retval);
return retval; ret = libusb_control_transfer(devh, CTRL_OUT, 0xc, REQ_WRITEADDR,
0, packet, 1, TIMEOUT);
if (ret != 1)
printf("%s: libusb_control_transfer returned %d\n",
__FUNCTION__, ret);
return ret;
} }
int gl_write_data(libusb_device_handle *devh, unsigned int val) int gl_write_data(libusb_device_handle *devh, unsigned int val)
{ {
unsigned char packet[8] = { val & 0xFF }; unsigned char packet[8] = { val & 0xFF };
int retval = libusb_control_transfer(devh, CTRL_OUT, 0xc, REQ_WRITEDATA, 0, packet, 1,TIMEOUT); int ret;
if (retval != 1) printf("%s: libusb_control_transfer returned %d\n", __FUNCTION__, retval);
return retval; ret = libusb_control_transfer(devh, CTRL_OUT, 0xc, REQ_WRITEDATA,
0, packet, 1, TIMEOUT);
if (ret != 1)
printf("%s: libusb_control_transfer returned %d\n",
__FUNCTION__, ret);
return ret;
} }
int gl_read_data(libusb_device_handle *devh) int gl_read_data(libusb_device_handle *devh)
{ {
unsigned char packet[8] = { 0 }; unsigned char packet[8] = { 0 };
int retval = libusb_control_transfer(devh, CTRL_IN, 0xc, REQ_READDATA, 0, packet, 1,TIMEOUT); int ret;
if (retval != 1) printf("%s: libusb_control_transfer returned %d, val=%hhx\n", __FUNCTION__, retval, packet[0]);
return retval == 1 ? packet[0] : retval; ret = libusb_control_transfer(devh, CTRL_IN, 0xc, REQ_READDATA,
0, packet, 1, TIMEOUT);
if (ret != 1)
printf("%s: libusb_control_transfer returned %d, val=%hhx\n",
__FUNCTION__, ret, packet[0]);
return (ret == 1) ? packet[0] : ret;
} }
int gl_read_bulk(libusb_device_handle *devh, void *buffer, unsigned int size) int gl_read_bulk(libusb_device_handle *devh, void *buffer, unsigned int size)
{ {
unsigned char packet[8] = {0, 0, 0, 0, size & 0xff, (size & 0xff00) >> 8, (size & 0xff0000) >> 16, (size & 0xff000000)>>24}; unsigned char packet[8] =
int transferred = 0; { 0, 0, 0, 0, size & 0xff, (size & 0xff00) >> 8,
(size & 0xff0000) >> 16, (size & 0xff000000) >> 24 };
int ret, transferred = 0;
int retval = libusb_control_transfer(devh, CTRL_OUT, 0x4, REQ_READBULK, 0, packet, 8, TIMEOUT); ret = libusb_control_transfer(devh, CTRL_OUT, 0x4, REQ_READBULK,
if (retval != 8) printf("%s: libusb_control_transfer returned %d\n", __FUNCTION__, retval); 0, packet, 8, TIMEOUT);
if (ret != 8)
printf("%s: libusb_control_transfer returned %d\n",
__FUNCTION__, ret);
retval = libusb_bulk_transfer(devh, ENDPOINT_BULK_IN, buffer, size, ret = libusb_bulk_transfer(devh, ENDPOINT_BULK_IN, buffer, size,
&transferred, TIMEOUT); &transferred, TIMEOUT);
if (retval < 0) { if (ret < 0)
fprintf(stderr, "Bulk read error %d\n", retval); fprintf(stderr, "Bulk read error %d\n", ret);
}
return transferred; return transferred;
} }
int gl_reg_write(libusb_device_handle *devh, unsigned int reg, unsigned int val) int gl_reg_write(libusb_device_handle *devh, unsigned int reg,
unsigned int val)
{ {
int retval; int ret;
retval = gl_write_address(devh, reg);
if (retval < 0) ret = gl_write_address(devh, reg);
return retval; if (ret < 0)
retval = gl_write_data(devh, val); return ret;
return retval; ret = gl_write_data(devh, val);
return ret;
} }
int gl_reg_read(libusb_device_handle *devh, unsigned int reg) int gl_reg_read(libusb_device_handle *devh, unsigned int reg)
{ {
int retval; int ret;
retval = gl_write_address(devh, reg);
if (retval < 0) ret = gl_write_address(devh, reg);
return retval; if (ret < 0)
retval = gl_read_data(devh); return ret;
return retval; ret = gl_read_data(devh);
return ret;
} }
int gl_open(int vid) int gl_open(int vid)
{ {
int r = 1; int ret;
struct libusb_device **devs;
struct libusb_device *dev;
size_t i = 0;
struct libusb_device_descriptor desc;
r = libusb_init(NULL); ret = libusb_init(NULL);
if (r < 0) if (ret < 0)
return GL_ELIBUSB; return GL_ELIBUSB;
libusb_set_debug(NULL, 0); libusb_set_debug(NULL, 0);
struct libusb_device **devs;
struct libusb_device *dev;
size_t i = 0;
if (libusb_get_device_list(NULL, &devs) < 0) { if (libusb_get_device_list(NULL, &devs) < 0) {
r = GL_EOPEN; ret = GL_EOPEN;
goto gl_open_error; goto gl_open_error;
} }
while ((dev = devs[i++]) != NULL) { while ((dev = devs[i++]) != NULL) {
struct libusb_device_descriptor desc;
if (libusb_get_device_descriptor(dev, &desc) < 0) if (libusb_get_device_descriptor(dev, &desc) < 0)
break; break;
@ -147,19 +172,19 @@ int gl_open(int vid)
libusb_free_device_list(devs, 1); libusb_free_device_list(devs, 1);
if (!g_devh) { if (!g_devh) {
r = GL_EOPEN; ret = GL_EOPEN;
goto gl_open_error; goto gl_open_error;
} }
r = libusb_set_configuration(g_devh, 1); ret = libusb_set_configuration(g_devh, 1);
if (r < 0) { if (ret < 0) {
r = GL_ESETCONFIG; ret = GL_ESETCONFIG;
goto gl_open_error; goto gl_open_error;
} }
r = libusb_claim_interface(g_devh, 0); ret = libusb_claim_interface(g_devh, 0);
if (r < 0) { if (ret < 0) {
r = GL_ECLAIM; ret = GL_ECLAIM;
goto gl_open_error; goto gl_open_error;
} }
@ -167,7 +192,7 @@ int gl_open(int vid)
gl_open_error: gl_open_error:
gl_close(); gl_close();
return r; return ret;
} }
int gl_close(void) int gl_close(void)

View File

@ -1,34 +1,35 @@
/* /*
Copyright (c) 2010 Sven Peter <sven@fail0verflow.com> * Copyright (C) 2010 Sven Peter <sven@fail0verflow.com>
Copyright (c) 2010 Haxx Enterprises <bushing@gmail.com> * Copyright (C) 2010 Haxx Enterprises <bushing@gmail.com>
All rights reserved. * All rights reserved.
*
Redistribution and use in source and binary forms, with or * Redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following * without modification, are permitted provided that the following
conditions are met: * conditions are met:
*
* Redistributions of source code must retain the above copyright notice, * * Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, * * Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE. * THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef GL_H__ #ifndef GL_H__
#define GL_G__ 1 #define GL_G__
#include <libusb.h> #include <libusb.h>
#define GL_OK 0 #define GL_OK 0
@ -41,7 +42,8 @@ int gl_write_address(libusb_device_handle *devh, unsigned int address);
int gl_write_data(libusb_device_handle *devh, unsigned int val); int gl_write_data(libusb_device_handle *devh, unsigned int val);
int gl_read_data(libusb_device_handle *devh); int gl_read_data(libusb_device_handle *devh);
int gl_read_bulk(libusb_device_handle *devh, void *buffer, unsigned int size); int gl_read_bulk(libusb_device_handle *devh, void *buffer, unsigned int size);
int gl_reg_write(libusb_device_handle *devh, unsigned int reg, unsigned int val); int gl_reg_write(libusb_device_handle *devh, unsigned int reg,
unsigned int val);
int gl_reg_read(libusb_device_handle *devh, unsigned int reg); int gl_reg_read(libusb_device_handle *devh, unsigned int reg);
int gl_open(int vid); int gl_open(int vid);
int gl_close(void); int gl_close(void);

View File

@ -23,8 +23,8 @@
#include <inttypes.h> #include <inttypes.h>
#include <glib.h> #include <glib.h>
#include <libusb.h> #include <libusb.h>
#include <sigrok.h>
#include "config.h" #include "config.h"
#include "sigrok.h"
#include "analyzer.h" #include "analyzer.h"
#define USB_VENDOR 0x0c12 #define USB_VENDOR 0x0c12
@ -37,17 +37,20 @@
#define NUM_TRIGGER_STAGES 4 #define NUM_TRIGGER_STAGES 4
#define TRIGGER_TYPES "01" #define TRIGGER_TYPES "01"
#define PACKET_SIZE 2048 // ?? #define PACKET_SIZE 2048 /* ?? */
typedef struct { typedef struct {
unsigned short pid; unsigned short pid;
char model_name[64]; char model_name[64];
unsigned int channels; unsigned int channels;
unsigned int sample_depth; // in Ksamples/channel unsigned int sample_depth; /* In Ksamples/channel */
unsigned int max_sampling_freq; unsigned int max_sampling_freq;
} model_t; } model_t;
/* Note -- 16032, 16064 and 16128 *usually* -- but not always -- have the same 128K sample depth */ /*
* Note -- 16032, 16064 and 16128 *usually* -- but not always -- have the
* same 128K sample depth.
*/
model_t zeroplus_models[] = { model_t zeroplus_models[] = {
{0x7009, "LAP-C(16064)", 16, 64, 100}, {0x7009, "LAP-C(16064)", 16, 64, 100},
{0x700A, "LAP-C(16128)", 16, 128, 200}, {0x700A, "LAP-C(16128)", 16, 128, 200},
@ -63,21 +66,26 @@ static int capabilities[] = {
HWCAP_SAMPLERATE, HWCAP_SAMPLERATE,
HWCAP_PROBECONFIG, HWCAP_PROBECONFIG,
HWCAP_CAPTURE_RATIO, HWCAP_CAPTURE_RATIO,
/* these are really implemented in the driver, not the hardware */
/* These are really implemented in the driver, not the hardware. */
HWCAP_LIMIT_SAMPLES, HWCAP_LIMIT_SAMPLES,
0 0,
}; };
/* list of struct sigrok_device_instance, maintained by opendev() and closedev() */ /* List of struct sigrok_device_instance, maintained by opendev()/closedev(). */
static GSList *device_instances = NULL; static GSList *device_instances = NULL;
static libusb_context *usb_context = NULL; static libusb_context *usb_context = NULL;
/* The hardware supports more samplerates than these, but these are the options /*
hardcoded into the vendor's Windows GUI */ * The hardware supports more samplerates than these, but these are the
* options hardcoded into the vendor's Windows GUI.
*/
// XXX we shouldn't support 150MHz and 200MHz on devices that don't go up that high /*
* TODO: We shouldn't support 150MHz and 200MHz on devices that don't go up
* that high.
*/
static uint64_t supported_samplerates[] = { static uint64_t supported_samplerates[] = {
100, 100,
500, 500,
@ -97,24 +105,24 @@ static uint64_t supported_samplerates[] = {
MHZ(100), MHZ(100),
MHZ(150), MHZ(150),
MHZ(200), MHZ(200),
0 0,
}; };
static struct samplerates samplerates = { static struct samplerates samplerates = {
0, 0, 0, 0, 0, 0,
supported_samplerates supported_samplerates,
}; };
/* TODO: all of these should go in a device-specific struct */ /* TODO: All of these should go in a device-specific struct. */
static uint64_t cur_samplerate = 0; static uint64_t cur_samplerate = 0;
static uint64_t limit_samples = 0; static uint64_t limit_samples = 0;
int num_channels = 32; // XXX this is not getting initialized before it is needed :( int num_channels = 32; /* TODO: This isn't initialized before it's needed :( */
uint64_t memory_size = 0; uint64_t memory_size = 0;
static uint8_t probe_mask = 0; static uint8_t probe_mask = 0;
static uint8_t trigger_mask[NUM_TRIGGER_STAGES] = { 0 }; static uint8_t trigger_mask[NUM_TRIGGER_STAGES] = { 0 };
static uint8_t trigger_value[NUM_TRIGGER_STAGES] = { 0 }; static uint8_t trigger_value[NUM_TRIGGER_STAGES] = { 0 };
// static uint8_t trigger_buffer[NUM_TRIGGER_STAGES] = {0};
// static uint8_t trigger_buffer[NUM_TRIGGER_STAGES] = { 0 };
static int hw_set_configuration(int device_index, int capability, void *value); static int hw_set_configuration(int device_index, int capability, void *value);
@ -145,45 +153,65 @@ struct sigrok_device_instance *zp_open_device(int device_index)
libusb_get_device_list(usb_context, &devlist); libusb_get_device_list(usb_context, &devlist);
if (sdi->status == ST_INACTIVE) { if (sdi->status == ST_INACTIVE) {
/* find the device by vendor, product, bus and address */ /* Find the device by vendor, product, bus and address. */
libusb_get_device_list(usb_context, &devlist); libusb_get_device_list(usb_context, &devlist);
for (i = 0; devlist[i]; i++) { for (i = 0; devlist[i]; i++) {
if( (err = libusb_get_device_descriptor(devlist[i], &des)) ) { if ((err = libusb_get_device_descriptor(devlist[i],
g_warning("failed to get device descriptor: %d", err); &des))) {
g_warning("failed to get device descriptor:"
"%d", err);
continue; continue;
} }
if (des.idVendor == USB_VENDOR) { if (des.idVendor == USB_VENDOR) {
if(libusb_get_bus_number(devlist[i]) == sdi->usb->bus && if (libusb_get_bus_number(devlist[i]) ==
libusb_get_device_address(devlist[i]) == sdi->usb->address) { sdi->usb->bus
for (j = 0; j < ARRAY_SIZE(zeroplus_models); j++) { && libusb_get_device_address(devlist[i]) ==
if (des.idProduct == zeroplus_models[j].pid) { sdi->usb->address) {
g_message("Found PID=%04X (%s)", des.idProduct, zeroplus_models[j].model_name); for (j = 0;
num_channels = zeroplus_models[j].channels; j < ARRAY_SIZE(zeroplus_models);
memory_size = zeroplus_models[j].sample_depth * 1024; j++) {
if (des.idProduct ==
zeroplus_models[j].pid) {
g_message
("Found PID=%04X (%s)",
des.idProduct,
zeroplus_models[j].
model_name);
num_channels =
zeroplus_models[j].
channels;
memory_size =
zeroplus_models[j].
sample_depth * 1024;
break; break;
} }
} }
if (num_channels == 0) { if (num_channels == 0) {
g_warning("Unknown ZeroPlus device %04X", des.idProduct); g_warning
("Unknown ZeroPlus device %04X",
des.idProduct);
continue; continue;
} }
/* found it */ /* Found it */
if( !(err = libusb_open(devlist[i], &(sdi->usb->devhdl))) ) { if (!(err = libusb_open(devlist[i],
&(sdi->usb->devhdl)))) {
sdi->status = ST_ACTIVE; sdi->status = ST_ACTIVE;
g_message("opened device %d on %d.%d interface %d", sdi->index, g_message("opened device %d on"
sdi->usb->bus, sdi->usb->address, USB_INTERFACE); " %d.%d interface %d",
} sdi->index, sdi->usb->bus,
else { sdi->usb->address,
g_warning("failed to open device: %d", err); USB_INTERFACE);
} else {
g_warning("failed to open "
"device: %d", err);
sdi = NULL; sdi = NULL;
} }
} }
} }
} }
} } else {
else { /* Status must be ST_ACTIVE, i.e. already in use... */
/* status must be ST_ACTIVE, i.e. already in use... */
sdi = NULL; sdi = NULL;
} }
libusb_free_device_list(devlist, 1); libusb_free_device_list(devlist, 1);
@ -194,23 +222,18 @@ struct sigrok_device_instance *zp_open_device(int device_index)
return sdi; return sdi;
} }
static void close_device(struct sigrok_device_instance *sdi) static void close_device(struct sigrok_device_instance *sdi)
{ {
if (sdi->usb->devhdl) {
if(sdi->usb->devhdl) g_message("closing device %d on %d.%d interface %d", sdi->index,
{ sdi->usb->bus, sdi->usb->address, USB_INTERFACE);
g_message("closing device %d on %d.%d interface %d", sdi->index, sdi->usb->bus,
sdi->usb->address, USB_INTERFACE);
libusb_release_interface(sdi->usb->devhdl, USB_INTERFACE); libusb_release_interface(sdi->usb->devhdl, USB_INTERFACE);
libusb_close(sdi->usb->devhdl); libusb_close(sdi->usb->devhdl);
sdi->usb->devhdl = NULL; sdi->usb->devhdl = NULL;
sdi->status = ST_INACTIVE; sdi->status = ST_INACTIVE;
} }
} }
static int configure_probes(GSList *probes) static int configure_probes(GSList *probes)
{ {
struct probe *probe; struct probe *probe;
@ -219,25 +242,22 @@ static int configure_probes(GSList *probes)
char *tc; char *tc;
probe_mask = 0; probe_mask = 0;
for(i = 0; i < NUM_TRIGGER_STAGES; i++) for (i = 0; i < NUM_TRIGGER_STAGES; i++) {
{
trigger_mask[i] = 0; trigger_mask[i] = 0;
trigger_value[i] = 0; trigger_value[i] = 0;
} }
stage = -1; stage = -1;
for(l = probes; l; l = l->next) for (l = probes; l; l = l->next) {
{
probe = (struct probe *)l->data; probe = (struct probe *)l->data;
if (probe->enabled == FALSE) if (probe->enabled == FALSE)
continue; continue;
probe_bit = 1 << (probe->index - 1); probe_bit = 1 << (probe->index - 1);
probe_mask |= probe_bit; probe_mask |= probe_bit;
if(probe->trigger)
{ if (probe->trigger) {
stage = 0; stage = 0;
for(tc = probe->trigger; *tc; tc++) for (tc = probe->trigger; *tc; tc++) {
{
trigger_mask[stage] |= probe_bit; trigger_mask[stage] |= probe_bit;
if (*tc == '1') if (*tc == '1')
trigger_value[stage] |= probe_bit; trigger_value[stage] |= probe_bit;
@ -251,8 +271,6 @@ static int configure_probes(GSList *probes)
return SIGROK_OK; return SIGROK_OK;
} }
/* /*
* API callbacks * API callbacks
*/ */
@ -272,9 +290,10 @@ static int hw_init(char *deviceinfo)
return 0; return 0;
} }
/* find all ZeroPlus analyzers and add them to device list */ /* Find all ZeroPlus analyzers and add them to device list. */
devcnt = 0; devcnt = 0;
libusb_get_device_list(usb_context, &devlist); libusb_get_device_list(usb_context, &devlist);
for (i = 0; devlist[i]; i++) { for (i = 0; devlist[i]; i++) {
err = libusb_get_device_descriptor(devlist[i], &des); err = libusb_get_device_descriptor(devlist[i], &des);
if (err != 0) { if (err != 0) {
@ -283,14 +302,20 @@ static int hw_init(char *deviceinfo)
} }
if (des.idVendor == USB_VENDOR) { if (des.idVendor == USB_VENDOR) {
/* definitely a Zeroplus */ /*
/* TODO: any way to detect specific model/version in the zeroplus range? */ * Definitely a Zeroplus.
sdi = sigrok_device_instance_new(devcnt, ST_INACTIVE, * TODO: Any way to detect specific model/version in
USB_VENDOR_NAME, USB_MODEL_NAME, USB_MODEL_VERSION); * the zeroplus range?
*/
sdi = sigrok_device_instance_new(devcnt,
ST_INACTIVE, USB_VENDOR_NAME,
USB_MODEL_NAME, USB_MODEL_VERSION);
if (!sdi) if (!sdi)
return 0; return 0;
device_instances = g_slist_append(device_instances, sdi); device_instances =
sdi->usb = usb_device_instance_new(libusb_get_bus_number(devlist[i]), g_slist_append(device_instances, sdi);
sdi->usb = usb_device_instance_new(
libusb_get_bus_number(devlist[i]),
libusb_get_device_address(devlist[i]), NULL); libusb_get_device_address(devlist[i]), NULL);
devcnt++; devcnt++;
} }
@ -300,7 +325,6 @@ static int hw_init(char *deviceinfo)
return devcnt; return devcnt;
} }
static int hw_opendev(int device_index) static int hw_opendev(int device_index)
{ {
struct sigrok_device_instance *sdi; struct sigrok_device_instance *sdi;
@ -324,44 +348,45 @@ static int hw_opendev(int device_index)
// analyzer_set_freq(g_freq, g_freq_scale); // analyzer_set_freq(g_freq, g_freq_scale);
analyzer_set_trigger_count(1); 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 - 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); analyzer_set_ramsize_trigger_address(
(100 * get_memory_size(MEMORY_SIZE_512K) / 100) >> 2);
/* if (g_double_mode == 1) #if 0
if (g_double_mode == 1)
analyzer_set_compression(COMPRESSION_DOUBLE); analyzer_set_compression(COMPRESSION_DOUBLE);
else if (g_compression == 1) else if (g_compression == 1)
analyzer_set_compression(COMPRESSION_ENABLE); analyzer_set_compression(COMPRESSION_ENABLE);
else */ else
#endif
analyzer_set_compression(COMPRESSION_NONE); analyzer_set_compression(COMPRESSION_NONE);
if (cur_samplerate == 0) { if (cur_samplerate == 0) {
/* sample rate hasn't been set; default to the slowest it has */ /* Sample rate hasn't been set. Default to the slowest one. */
if(hw_set_configuration(device_index, HWCAP_SAMPLERATE, &samplerates.low) == SIGROK_ERR) if (hw_set_configuration(device_index, HWCAP_SAMPLERATE,
&samplerates.low) == SIGROK_ERR)
return SIGROK_ERR; return SIGROK_ERR;
} }
return SIGROK_OK; return SIGROK_OK;
} }
static void hw_closedev(int device_index) static void hw_closedev(int device_index)
{ {
struct sigrok_device_instance *sdi; struct sigrok_device_instance *sdi;
if ((sdi = get_sigrok_device_instance(device_instances, device_index))) if ((sdi = get_sigrok_device_instance(device_instances, device_index)))
close_device(sdi); close_device(sdi);
} }
static void hw_cleanup(void) static void hw_cleanup(void)
{ {
GSList *l; GSList *l;
/* properly close all devices */ /* Properly close all devices. */
for (l = device_instances; l; l = l->next) for (l = device_instances; l; l = l->next)
close_device((struct sigrok_device_instance *)l->data); close_device((struct sigrok_device_instance *)l->data);
/* and free all their memory */ /* And free all their memory. */
for (l = device_instances; l; l = l->next) for (l = device_instances; l; l = l->next)
g_free(l->data); g_free(l->data);
g_slist_free(device_instances); g_slist_free(device_instances);
@ -370,10 +395,8 @@ static void hw_cleanup(void)
if (usb_context) if (usb_context)
libusb_exit(usb_context); libusb_exit(usb_context);
usb_context = NULL; usb_context = NULL;
} }
static void *hw_get_device_info(int device_index, int device_info_id) static void *hw_get_device_info(int device_index, int device_info_id)
{ {
struct sigrok_device_instance *sdi; struct sigrok_device_instance *sdi;
@ -383,8 +406,7 @@ static void *hw_get_device_info(int device_index, int device_info_id)
return NULL; return NULL;
info = NULL; info = NULL;
switch(device_info_id) switch (device_info_id) {
{
case DI_INSTANCE: case DI_INSTANCE:
info = sdi; info = sdi;
break; break;
@ -405,7 +427,6 @@ static void *hw_get_device_info(int device_index, int device_info_id)
return info; return info;
} }
static int hw_get_status(int device_index) static int hw_get_status(int device_index)
{ {
struct sigrok_device_instance *sdi; struct sigrok_device_instance *sdi;
@ -417,13 +438,12 @@ static int hw_get_status(int device_index)
return ST_NOT_FOUND; return ST_NOT_FOUND;
} }
static int *hw_get_capabilities(void) static int *hw_get_capabilities(void)
{ {
return capabilities; return capabilities;
} }
// XXX this will set the same samplerate for all devices /* TODO: This will set the same samplerate for all devices. */
static int set_configuration_samplerate(uint64_t samplerate) static int set_configuration_samplerate(uint64_t samplerate)
{ {
g_message("%s(%llu)", __FUNCTION__, samplerate); g_message("%s(%llu)", __FUNCTION__, samplerate);
@ -451,14 +471,11 @@ static int hw_set_configuration(int device_index, int capability, void *value)
case HWCAP_SAMPLERATE: case HWCAP_SAMPLERATE:
tmp_u64 = value; tmp_u64 = value;
return set_configuration_samplerate(*tmp_u64); return set_configuration_samplerate(*tmp_u64);
case HWCAP_PROBECONFIG: case HWCAP_PROBECONFIG:
return configure_probes((GSList *) value); return configure_probes((GSList *) value);
case HWCAP_LIMIT_SAMPLES: case HWCAP_LIMIT_SAMPLES:
limit_samples = strtoull(value, NULL, 10); limit_samples = strtoull(value, NULL, 10);
return SIGROK_OK; return SIGROK_OK;
default: default:
return SIGROK_ERR; return SIGROK_ERR;
} }
@ -480,9 +497,12 @@ static int hw_start_acquisition(int device_index, gpointer session_device_id)
g_message("Waiting for data"); g_message("Waiting for data");
analyzer_wait_data(sdi->usb->devhdl); analyzer_wait_data(sdi->usb->devhdl);
g_message("Stop address = 0x%x", analyzer_get_stop_address(sdi->usb->devhdl)); g_message("Stop address = 0x%x",
g_message("Now address = 0x%x", analyzer_get_now_address(sdi->usb->devhdl)); analyzer_get_stop_address(sdi->usb->devhdl));
g_message("Trigger address = 0x%x", analyzer_get_trigger_address(sdi->usb->devhdl)); g_message("Now address = 0x%x",
analyzer_get_now_address(sdi->usb->devhdl));
g_message("Trigger address = 0x%x",
analyzer_get_trigger_address(sdi->usb->devhdl));
packet.type = DF_HEADER; packet.type = DF_HEADER;
packet.length = sizeof(struct datafeed_header); packet.length = sizeof(struct datafeed_header);
@ -498,8 +518,9 @@ static int hw_start_acquisition(int device_index, gpointer session_device_id)
if (!buf) if (!buf)
return SIGROK_ERR; return SIGROK_ERR;
analyzer_read_start(sdi->usb->devhdl); analyzer_read_start(sdi->usb->devhdl);
/* send the incoming transfer to the session bus */ /* Send the incoming transfer to the session bus. */
for(packet_num = 0; packet_num < (memory_size * 4 / PACKET_SIZE); packet_num++) { for (packet_num = 0; packet_num < (memory_size * 4 / PACKET_SIZE);
packet_num++) {
res = analyzer_read_data(sdi->usb->devhdl, buf, PACKET_SIZE); res = analyzer_read_data(sdi->usb->devhdl, buf, PACKET_SIZE);
// g_message("Tried to read %llx bytes, actually read %x bytes", PACKET_SIZE, res); // g_message("Tried to read %llx bytes, actually read %x bytes", PACKET_SIZE, res);
@ -517,8 +538,7 @@ static int hw_start_acquisition(int device_index, gpointer session_device_id)
return SIGROK_OK; return SIGROK_OK;
} }
/* This stops acquisition on ALL devices, ignoring device_index. */
/* this stops acquisition on ALL devices, ignoring device_index */
static void hw_stop_acquisition(int device_index, gpointer session_device_id) static void hw_stop_acquisition(int device_index, gpointer session_device_id)
{ {
struct datafeed_packet packet; struct datafeed_packet packet;
@ -528,20 +548,17 @@ static void hw_stop_acquisition(int device_index, gpointer session_device_id)
session_bus(session_device_id, &packet); session_bus(session_device_id, &packet);
if (!(sdi = get_sigrok_device_instance(device_instances, device_index))) if (!(sdi = get_sigrok_device_instance(device_instances, device_index)))
return; // XXX cry? return; /* TODO: Cry? */
analyzer_reset(sdi->usb->devhdl); analyzer_reset(sdi->usb->devhdl);
/* TODO: need to cancel and free any queued up transfers */ /* TODO: Need to cancel and free any queued up transfers. */
} }
struct device_plugin zeroplus_logic_cube_plugin_info = { struct device_plugin zeroplus_logic_cube_plugin_info = {
"zeroplus-logic-cube", "zeroplus-logic-cube",
1, 1,
hw_init, hw_init,
hw_cleanup, hw_cleanup,
hw_opendev, hw_opendev,
hw_closedev, hw_closedev,
hw_get_device_info, hw_get_device_info,
@ -549,6 +566,5 @@ struct device_plugin zeroplus_logic_cube_plugin_info = {
hw_get_capabilities, hw_get_capabilities,
hw_set_configuration, hw_set_configuration,
hw_start_acquisition, hw_start_acquisition,
hw_stop_acquisition hw_stop_acquisition,
}; };