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 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
/* 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_value[NUM_TRIGGER_STAGES] = { 0 };
static uint8_t trigger_buffer[NUM_TRIGGER_STAGES] = { 0 };
int trigger_stage = TRIGGER_FIRED;
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)
{
@ -300,7 +302,7 @@ static void close_device(struct sigrok_device_instance *sdi)
sdi->status = ST_INACTIVE;
}
static int configure_probes(GSList * probes)
static int configure_probes(GSList *probes)
{
struct probe *probe;
GSList *l;
@ -391,16 +393,16 @@ static int hw_init(char *deviceinfo)
* or uploading the firmware again.
*/
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
(libusb_get_bus_number(devlist[i]), 0, NULL);
(libusb_get_bus_number(devlist[i]), 0, NULL);
} else {
/* Already has the firmware, so fix the new address. */
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++;
}
@ -446,7 +448,7 @@ static int hw_opendev(int device_index)
if (cur_samplerate == 0) {
/* Samplerate hasn't been set; default to the slowest one. */
if (hw_set_configuration(device_index, HWCAP_SAMPLERATE,
&supported_samplerates[0]) == SIGROK_ERR)
&supported_samplerates[0]) == SIGROK_ERR)
return SIGROK_ERR;
}

View File

@ -1,47 +1,48 @@
/*
Copyright (c) 2010 Sven Peter <sven@fail0verflow.com>
Copyright (c) 2010 Haxx Enterprises <bushing@gmail.com>
All rights reserved.
* This file is part of the sigrok project.
*
* Copyright (C) 2010 Sven Peter <sven@fail0verflow.com>
* Copyright (C) 2010 Haxx Enterprises <bushing@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* 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.
*/
Redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
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 "analyzer.h"
#include "gl_usb.h"
enum {
HARD_DATA_CHECK_SUM = 0x00,
HARD_DATA_CHECK_SUM = 0x00,
PASS_WORD,
DEVICE_ID0 = 0x10,
DEVICE_ID0 = 0x10,
DEVICE_ID1,
START_STATUS = 0x20,
DEVICE_STATUS = 0x21,
FREQUENCY_REG0 = 0x30,
START_STATUS = 0x20,
DEVICE_STATUS = 0x21,
FREQUENCY_REG0 = 0x30,
FREQUENCY_REG1,
FREQUENCY_REG2,
FREQUENCY_REG3,
@ -49,7 +50,7 @@ enum {
MEMORY_LENGTH,
CLOCK_SOURCE,
TRIGGER_STATUS0 = 0x40,
TRIGGER_STATUS0 = 0x40,
TRIGGER_STATUS1,
TRIGGER_STATUS2,
TRIGGER_STATUS3,
@ -59,10 +60,10 @@ enum {
TRIGGER_STATUS7,
TRIGGER_STATUS8,
TRIGGER_COUNT0 = 0x50,
TRIGGER_COUNT0 = 0x50,
TRIGGER_COUNT1,
TRIGGER_LEVEL0 = 0x55,
TRIGGER_LEVEL0 = 0x55,
TRIGGER_LEVEL1,
TRIGGER_LEVEL2,
TRIGGER_LEVEL3,
@ -78,46 +79,46 @@ enum {
FILTER_ENABLE = 0x70,
FILTER_STATUS,
ENABLE_DELAY_TIME0 = 0x7A,
ENABLE_DELAY_TIME0 = 0x7a,
ENABLE_DELAY_TIME1,
ENABLE_INSERT_DATA0 = 0x80,
ENABLE_INSERT_DATA0 = 0x80,
ENABLE_INSERT_DATA1,
ENABLE_INSERT_DATA2,
ENABLE_INSERT_DATA3,
COMPRESSION_TYPE0,
COMPRESSION_TYPE1,
TRIGGER_ADDRESS0 = 0x90,
TRIGGER_ADDRESS0 = 0x90,
TRIGGER_ADDRESS1,
TRIGGER_ADDRESS2,
NOW_ADDRESS0 = 0x96,
NOW_ADDRESS0 = 0x96,
NOW_ADDRESS1,
NOW_ADDRESS2,
STOP_ADDRESS0 = 0x9B,
STOP_ADDRESS0 = 0x9b,
STOP_ADDRESS1,
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_filter_status[8] = {0};
static int g_filter_status[8] = { 0 };
static int g_filter_enable = 0;
static int g_freq_value = 100;
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_ramsize_triggerbar_addr = 0x80000 >> 2;
static int g_triggerbar_addr = 0x3fe;
static int g_compression = COMPRESSION_NONE;
// maybe unk specifies an "endpoint" or "register" of sorts
static int analyzer_write_status(libusb_device_handle *devh, unsigned char unk, unsigned char flags)
/* Maybe unk specifies an "endpoint" or "register" of sorts. */
static int analyzer_write_status(libusb_device_handle *devh, unsigned char unk,
unsigned char flags)
{
assert(unk <= 3);
return gl_reg_write(devh, START_STATUS, unk << 6 | flags);
@ -125,128 +126,129 @@ 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)
{
int reg0=0, divisor=0, reg2=0;
int reg0 = 0, divisor = 0, reg2 = 0;
switch (scale) {
case FREQ_SCALE_MHZ: // MHz
if (freq >= 100 && freq <= 200) {
reg0 = freq * 0.1;
divisor = 1;
reg2 = 0;
break;
}
if (freq >= 50 && freq < 100) {
reg0 = freq * 0.2;
divisor = 2;
reg2 = 0;
break;
}
if (freq >= 10 && freq < 50) {
if (freq == 25) {
reg0 = 25;
divisor = 5;
reg2 = 1;
break;
} else {
reg0 = freq * 0.5;
divisor = 5;
reg2 = 1;
break;
}
}
if (freq >= 2 && freq < 10) {
divisor = 5;
reg0 = freq * 2;
reg2 = 2;
break;
}
if (freq == 1) {
divisor = 5;
reg2 = 16;
reg0 = 5;
break;
}
divisor = 5;
reg0 = 5;
reg2 = 64;
case FREQ_SCALE_MHZ: /* MHz */
if (freq >= 100 && freq <= 200) {
reg0 = freq * 0.1;
divisor = 1;
reg2 = 0;
break;
case FREQ_SCALE_HZ: // Hz
if (freq >= 500 && freq < 1000) {
reg0 = freq * 0.01;
divisor = 10;
reg2 = 64;
break;
}
if (freq >= 300 && freq < 500) {
reg0 = freq * 0.005 * 8;
divisor = 5;
reg2 = 67;
break;
}
if (freq >= 100 && freq < 300) {
reg0 = freq * 0.005 * 16;
divisor = 5;
reg2 = 68;
break;
}
divisor = 5;
reg0 = 5;
reg2 = 64;
}
if (freq >= 50 && freq < 100) {
reg0 = freq * 0.2;
divisor = 2;
reg2 = 0;
break;
case FREQ_SCALE_KHZ: // KHz
if (freq >= 500 && freq < 1000) {
reg0 = freq * 0.01;
}
if (freq >= 10 && freq < 50) {
if (freq == 25) {
reg0 = 25;
divisor = 5;
reg2 = 17;
reg2 = 1;
break;
}
if (freq >= 100 && freq < 500) {
reg0 = freq * 0.05;
divisor = 5;
reg2 = 32;
break;
}
if (freq >= 50 && freq < 100) {
reg0 = freq * 0.1;
divisor = 5;
reg2 = 33;
break;
}
if (freq >= 10 && freq < 50) {
if (freq == 25) {
reg0 = 25;
divisor = 5;
reg2 = 49;
break;
}
} else {
reg0 = freq * 0.5;
divisor = 5;
reg2 = 48;
reg2 = 1;
break;
}
if (freq >= 2 && freq < 10) {
}
if (freq >= 2 && freq < 10) {
divisor = 5;
reg0 = freq * 2;
reg2 = 2;
break;
}
if (freq == 1) {
divisor = 5;
reg2 = 16;
reg0 = 5;
break;
}
divisor = 5;
reg0 = 5;
reg2 = 64;
break;
case FREQ_SCALE_HZ: /* Hz */
if (freq >= 500 && freq < 1000) {
reg0 = freq * 0.01;
divisor = 10;
reg2 = 64;
break;
}
if (freq >= 300 && freq < 500) {
reg0 = freq * 0.005 * 8;
divisor = 5;
reg2 = 67;
break;
}
if (freq >= 100 && freq < 300) {
reg0 = freq * 0.005 * 16;
divisor = 5;
reg2 = 68;
break;
}
divisor = 5;
reg0 = 5;
reg2 = 64;
break;
case FREQ_SCALE_KHZ: /* KHz */
if (freq >= 500 && freq < 1000) {
reg0 = freq * 0.01;
divisor = 5;
reg2 = 17;
break;
}
if (freq >= 100 && freq < 500) {
reg0 = freq * 0.05;
divisor = 5;
reg2 = 32;
break;
}
if (freq >= 50 && freq < 100) {
reg0 = freq * 0.1;
divisor = 5;
reg2 = 33;
break;
}
if (freq >= 10 && freq < 50) {
if (freq == 25) {
reg0 = 25;
divisor = 5;
reg0 = freq * 2;
reg2 = 50;
reg2 = 49;
break;
}
reg0 = freq * 0.5;
divisor = 5;
reg0 = 5;
reg2 = 64;
reg2 = 48;
break;
default:
}
if (freq >= 2 && freq < 10) {
divisor = 5;
reg0 = 5;
reg2 = 64;
reg0 = freq * 2;
reg2 = 50;
break;
}
divisor = 5;
reg0 = 5;
reg2 = 64;
break;
default:
divisor = 5;
reg0 = 5;
reg2 = 64;
break;
}
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)
return -1; // 10 / 0.2
return -1; /* 10 / 0.2 */
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)
return -1;
@ -254,27 +256,31 @@ static int __analyzer_set_freq(libusb_device_handle *devh, int freq, int scale)
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_ADDRESS1, (address >> 8) & 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_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_ADDRESS1, (address >> 8) & 0xFF);
gl_reg_write(devh, TRIGGERBAR_ADDRESS0, (address >> 0) & 0xFF);
gl_reg_write(devh, TRIGGERBAR_ADDRESS1, (address >> 8) & 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_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_COUNT1, (count >> 8) & 0xFF);
@ -298,8 +304,8 @@ static void analyzer_set_filter(libusb_device_handle *devh)
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
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)
@ -312,7 +318,7 @@ void analyzer_initialize(libusb_device_handle *devh)
void analyzer_wait(libusb_device_handle *devh, int set, int unset)
{
int status;
while(1) {
while (1) {
status = gl_reg_read(devh, DEVICE_STATUS);
if ((status & set) && ((status & unset) == 0))
return;
@ -329,7 +335,8 @@ 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, unsigned int size)
int analyzer_read_data(libusb_device_handle *devh, void *buffer,
unsigned int size)
{
return gl_read_bulk(devh, buffer, size);
}
@ -350,59 +357,62 @@ void analyzer_start(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_NONE);
// Start_Config_Outside_Device ?
/* Start_Config_Outside_Device ? */
analyzer_write_status(devh, 1, STATUS_FLAG_INIT);
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);
//SetMemory_Length
/* SetMemory_Length */
gl_reg_write(devh, MEMORY_LENGTH, g_memory_size);
//Sele_Inside_Outside_Clock
/* Sele_Inside_Outside_Clock */
gl_reg_write(devh, CLOCK_SOURCE, 0x03);
//Set_Trigger_Status
int i;
/* Set_Trigger_Status */
for (i = 0; i < 9; i++)
gl_reg_write(devh, TRIGGER_STATUS0 + i, g_trigger_status[i]);
__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_LEVEL1, 0x31);
gl_reg_write(devh, TRIGGER_LEVEL2, 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);
//Set_Dont_Care_TriggerBar
/* Set_Dont_Care_TriggerBar */
gl_reg_write(devh, DONT_CARE_TRIGGERBAR, 0x01);
//Enable_Status
/* Enable_Status */
analyzer_set_filter(devh);
//Set_Enable_Delay_Time
/* Set_Enable_Delay_Time */
gl_reg_write(devh, 0x7a, 0x00);
gl_reg_write(devh, 0x7b, 0x00);
analyzer_write_enable_insert_data(devh);
__analyzer_set_compression(devh,g_compression);
__analyzer_set_compression(devh, g_compression);
}
void analyzer_add_trigger(int channel, int type)
{
int i;
if ((channel & 0xf) >= 8)
return;
if (type == TRIGGER_HIGH || type == TRIGGER_LOW) {
int i;
if (channel & CHANNEL_A)
i = 0;
else if (channel & CHANNEL_B)
@ -417,16 +427,17 @@ void analyzer_add_trigger(int channel, int type)
i++;
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 {
if (type == TRIGGER_POSEDGE)
g_trigger_status[8] = 0x40;
else if(type == TRIGGER_NEGEDGE)
else if (type == TRIGGER_NEGEDGE)
g_trigger_status[8] = 0x80;
else
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)
g_trigger_status[8] += 8;
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)
{
int i;
if (type != FILTER_HIGH && type != FILTER_LOW)
return;
if ((channel & 0xf) >= 8)
return;
int i;
if (channel & CHANNEL_A)
i = 0;
else if (channel & CHANNEL_B)
@ -455,11 +467,15 @@ void analyzer_add_filter(int channel, int type)
i = 6;
else
return;
if ((channel & 0xf) >= 4) {
i++;
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;
}
@ -479,7 +495,6 @@ void analyzer_set_memory_size(unsigned int size)
g_memory_size = size;
}
void analyzer_set_ramsize_trigger_address(unsigned int 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)
{
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)
{
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)
{
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)
{
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)
@ -525,7 +544,8 @@ 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)
int analyzer_decompress(void *input, unsigned int input_len, void *output,
unsigned int output_len)
{
unsigned char *in = input;
unsigned char *out = output;
@ -547,7 +567,7 @@ int analyzer_decompress(void *input, unsigned int input_len, void *output, unsig
*out++ = A;
*out++ = B;
*out++ = C;
*out++ = 0; // channel D
*out++ = 0; /* Channel D */
}
input_len -= 4;

View File

@ -1,74 +1,78 @@
/*
Copyright (c) 2010 Sven Peter <sven@fail0verflow.com>
Copyright (c) 2010 Haxx Enterprises <bushing@gmail.com>
All rights reserved.
* This file is part of the sigrok project.
*
* Copyright (C) 2010 Sven Peter <sven@fail0verflow.com>
* Copyright (C) 2010 Haxx Enterprises <bushing@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* 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.
*/
Redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
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__
#define ANALYZER_H__ 1
#define ANALYZER_H__
#include <libusb.h>
#define STATUS_FLAG_NONE 0x00
#define STATUS_FLAG_RESET 0x01
#define STATUS_FLAG_INIT 0x02
#define STATUS_FLAG_GO 0x04
#define STATUS_FLAG_PAUSE 0x08
#define STATUS_FLAG_READ 0x10
#define STATUS_FLAG_20 0x20
#define MEMORY_SIZE_8K 0x00
#define MEMORY_SIZE_64K 0x01
#define MEMORY_SIZE_128K 0x02
#define MEMORY_SIZE_512K 0x04
#define STATUS_FLAG_NONE 0x00
#define STATUS_FLAG_RESET 0x01
#define STATUS_FLAG_INIT 0x02
#define STATUS_FLAG_GO 0x04
#define STATUS_FLAG_PAUSE 0x08
#define STATUS_FLAG_READ 0x10
#define STATUS_FLAG_20 0x20
#define STATUS_BUSY 0x01 // WTF / ???
#define STATUS_READY 0x02
#define STATUS_BUTTON_PRESSED 0x04
#define MEMORY_SIZE_8K 0x00
#define MEMORY_SIZE_64K 0x01
#define MEMORY_SIZE_128K 0x02
#define MEMORY_SIZE_512K 0x04
#define CHANNEL_A 0x1000
#define CHANNEL_B 0x2000
#define CHANNEL_C 0x3000
#define CHANNEL_D 0x4000
#define STATUS_BUSY 0x01 /* WTF / ??? */
#define STATUS_READY 0x02
#define STATUS_BUTTON_PRESSED 0x04
#define FREQ_SCALE_HZ 0
#define FREQ_SCALE_KHZ 1
#define FREQ_SCALE_MHZ 2
#define CHANNEL_A 0x1000
#define CHANNEL_B 0x2000
#define CHANNEL_C 0x3000
#define CHANNEL_D 0x4000
#define FILTER_HIGH 0
#define FILTER_LOW 1
#define FREQ_SCALE_HZ 0
#define FREQ_SCALE_KHZ 1
#define FREQ_SCALE_MHZ 2
#define COMPRESSION_NONE 0x0001
#define COMPRESSION_ENABLE 0x8001
#define COMPRESSION_DOUBLE 0x8002
#define FILTER_HIGH 0
#define FILTER_LOW 1
#define COMPRESSION_NONE 0x0001
#define COMPRESSION_ENABLE 0x8001
#define COMPRESSION_DOUBLE 0x8002
enum {
TRIGGER_HIGH = 0,
TRIGGER_LOW,
TRIGGER_POSEDGE,
TRIGGER_NEGEDGE,
TRIGGER_ANYEDGE
TRIGGER_ANYEDGE,
};
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_now_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_initialize(libusb_device_handle *devh);
void analyzer_wait(libusb_device_handle *devh, int set, int unset);
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_start(libusb_device_handle *devh);
void analyzer_configure(libusb_device_handle *devh);
void analyzer_wait_button(libusb_device_handle *devh);
void analyzer_wait_data(libusb_device_handle *devh);
#endif

View File

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

View File

@ -1,47 +1,49 @@
/*
Copyright (c) 2010 Sven Peter <sven@fail0verflow.com>
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>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* 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.
*/
Redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
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 GL_H__
#define GL_G__ 1
#define GL_G__
#include <libusb.h>
#define GL_OK 0
#define GL_ELIBUSB -1
#define GL_EOPEN -2
#define GL_ESETCONFIG -3
#define GL_ECLAIM -4
#define GL_OK 0
#define GL_ELIBUSB -1
#define GL_EOPEN -2
#define GL_ESETCONFIG -3
#define GL_ECLAIM -4
int gl_write_address(libusb_device_handle *devh, unsigned int address);
int gl_write_data(libusb_device_handle *devh, unsigned int val);
int gl_read_data(libusb_device_handle *devh);
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_open(int vid);
int gl_close(void);

View File

@ -23,12 +23,12 @@
#include <inttypes.h>
#include <glib.h>
#include <libusb.h>
#include <sigrok.h>
#include "config.h"
#include "sigrok.h"
#include "analyzer.h"
#define USB_VENDOR 0x0c12
#define USB_VENDOR_NAME "Zeroplus"
#define USB_VENDOR 0x0c12
#define USB_VENDOR_NAME "Zeroplus"
#define USB_MODEL_NAME "Logic Cube"
#define USB_MODEL_VERSION ""
@ -37,17 +37,20 @@
#define NUM_TRIGGER_STAGES 4
#define TRIGGER_TYPES "01"
#define PACKET_SIZE 2048 // ??
#define PACKET_SIZE 2048 /* ?? */
typedef struct {
unsigned short pid;
char model_name[64];
unsigned int channels;
unsigned int sample_depth; // in Ksamples/channel
unsigned int sample_depth; /* In Ksamples/channel */
unsigned int max_sampling_freq;
} 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[] = {
{0x7009, "LAP-C(16064)", 16, 64, 100},
{0x700A, "LAP-C(16128)", 16, 128, 200},
@ -63,21 +66,26 @@ static int capabilities[] = {
HWCAP_SAMPLERATE,
HWCAP_PROBECONFIG,
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,
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 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[] = {
100,
500,
@ -97,39 +105,39 @@ static uint64_t supported_samplerates[] = {
MHZ(100),
MHZ(150),
MHZ(200),
0
0,
};
static struct samplerates samplerates = {
0,0,0,
supported_samplerates
0, 0, 0,
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 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;
static uint8_t probe_mask = 0;
static uint8_t trigger_mask[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_mask[NUM_TRIGGER_STAGES] = { 0 };
static uint8_t trigger_value[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 unsigned int get_memory_size(int type)
{
if (type == MEMORY_SIZE_8K)
return 8*1024;
else if (type == MEMORY_SIZE_64K)
return 64*1024;
else if (type == MEMORY_SIZE_128K)
return 128*1024;
else if (type == MEMORY_SIZE_512K)
return 512*1024;
else
return 0;
if (type == MEMORY_SIZE_8K)
return 8 * 1024;
else if (type == MEMORY_SIZE_64K)
return 64 * 1024;
else if (type == MEMORY_SIZE_128K)
return 128 * 1024;
else if (type == MEMORY_SIZE_512K)
return 512 * 1024;
else
return 0;
}
struct sigrok_device_instance *zp_open_device(int device_index)
@ -140,77 +148,92 @@ struct sigrok_device_instance *zp_open_device(int device_index)
unsigned int j;
int err, i;
if(!(sdi = get_sigrok_device_instance(device_instances, device_index)))
if (!(sdi = get_sigrok_device_instance(device_instances, device_index)))
return NULL;
libusb_get_device_list(usb_context, &devlist);
if(sdi->status == ST_INACTIVE) {
/* find the device by vendor, product, bus and address */
if (sdi->status == ST_INACTIVE) {
/* Find the device by vendor, product, bus and address. */
libusb_get_device_list(usb_context, &devlist);
for(i = 0; devlist[i]; i++) {
if( (err = libusb_get_device_descriptor(devlist[i], &des)) ) {
g_warning("failed to get device descriptor: %d", err);
for (i = 0; devlist[i]; i++) {
if ((err = libusb_get_device_descriptor(devlist[i],
&des))) {
g_warning("failed to get device descriptor:"
"%d", err);
continue;
}
if(des.idVendor == USB_VENDOR) {
if(libusb_get_bus_number(devlist[i]) == sdi->usb->bus &&
libusb_get_device_address(devlist[i]) == sdi->usb->address) {
for (j = 0; j < ARRAY_SIZE(zeroplus_models); 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;
}
}
if (num_channels == 0) {
g_warning("Unknown ZeroPlus device %04X", des.idProduct);
continue;
}
/* found it */
if( !(err = libusb_open(devlist[i], &(sdi->usb->devhdl))) ) {
sdi->status = ST_ACTIVE;
g_message("opened device %d on %d.%d interface %d", sdi->index,
sdi->usb->bus, sdi->usb->address, USB_INTERFACE);
if (des.idVendor == USB_VENDOR) {
if (libusb_get_bus_number(devlist[i]) ==
sdi->usb->bus
&& libusb_get_device_address(devlist[i]) ==
sdi->usb->address) {
for (j = 0;
j < ARRAY_SIZE(zeroplus_models);
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;
}
}
else {
g_warning("failed to open device: %d", err);
if (num_channels == 0) {
g_warning
("Unknown ZeroPlus device %04X",
des.idProduct);
continue;
}
/* Found it */
if (!(err = libusb_open(devlist[i],
&(sdi->usb->devhdl)))) {
sdi->status = ST_ACTIVE;
g_message("opened device %d on"
" %d.%d interface %d",
sdi->index, sdi->usb->bus,
sdi->usb->address,
USB_INTERFACE);
} else {
g_warning("failed to open "
"device: %d", err);
sdi = NULL;
}
}
}
}
}
else {
/* status must be ST_ACTIVE, i.e. already in use... */
} else {
/* Status must be ST_ACTIVE, i.e. already in use... */
sdi = NULL;
}
libusb_free_device_list(devlist, 1);
if(sdi && sdi->status != ST_ACTIVE)
if (sdi && sdi->status != ST_ACTIVE)
sdi = NULL;
return sdi;
}
static void close_device(struct sigrok_device_instance *sdi)
{
if(sdi->usb->devhdl)
{
g_message("closing device %d on %d.%d interface %d", sdi->index, sdi->usb->bus,
sdi->usb->address, USB_INTERFACE);
if (sdi->usb->devhdl) {
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_close(sdi->usb->devhdl);
sdi->usb->devhdl = NULL;
sdi->status = ST_INACTIVE;
}
}
static int configure_probes(GSList *probes)
{
struct probe *probe;
@ -219,30 +242,27 @@ static int configure_probes(GSList *probes)
char *tc;
probe_mask = 0;
for(i = 0; i < NUM_TRIGGER_STAGES; i++)
{
for (i = 0; i < NUM_TRIGGER_STAGES; i++) {
trigger_mask[i] = 0;
trigger_value[i] = 0;
}
stage = -1;
for(l = probes; l; l = l->next)
{
probe = (struct probe *) l->data;
if(probe->enabled == FALSE)
for (l = probes; l; l = l->next) {
probe = (struct probe *)l->data;
if (probe->enabled == FALSE)
continue;
probe_bit = 1 << (probe->index - 1);
probe_mask |= probe_bit;
if(probe->trigger)
{
if (probe->trigger) {
stage = 0;
for(tc = probe->trigger; *tc; tc++)
{
for (tc = probe->trigger; *tc; tc++) {
trigger_mask[stage] |= probe_bit;
if(*tc == '1')
if (*tc == '1')
trigger_value[stage] |= probe_bit;
stage++;
if(stage > NUM_TRIGGER_STAGES)
if (stage > NUM_TRIGGER_STAGES)
return SIGROK_ERR;
}
}
@ -251,8 +271,6 @@ static int configure_probes(GSList *probes)
return SIGROK_OK;
}
/*
* API callbacks
*/
@ -267,31 +285,38 @@ static int hw_init(char *deviceinfo)
/* QUICK HACK */
deviceinfo = deviceinfo;
if(libusb_init(&usb_context) != 0) {
if (libusb_init(&usb_context) != 0) {
g_warning("Failed to initialize USB.");
return 0;
}
/* find all ZeroPlus analyzers and add them to device list */
/* Find all ZeroPlus analyzers and add them to device list. */
devcnt = 0;
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);
if(err != 0) {
if (err != 0) {
g_warning("failed to get device descriptor: %d", err);
continue;
}
if(des.idVendor == USB_VENDOR) {
/* definitely a Zeroplus */
/* TODO: any way to detect specific model/version in the zeroplus range? */
sdi = sigrok_device_instance_new(devcnt, ST_INACTIVE,
USB_VENDOR_NAME, USB_MODEL_NAME, USB_MODEL_VERSION);
if(!sdi)
if (des.idVendor == USB_VENDOR) {
/*
* Definitely a Zeroplus.
* TODO: Any way to detect specific model/version in
* the zeroplus range?
*/
sdi = sigrok_device_instance_new(devcnt,
ST_INACTIVE, USB_VENDOR_NAME,
USB_MODEL_NAME, USB_MODEL_VERSION);
if (!sdi)
return 0;
device_instances = 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);
device_instances =
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);
devcnt++;
}
}
@ -300,19 +325,18 @@ static int hw_init(char *deviceinfo)
return devcnt;
}
static int hw_opendev(int device_index)
{
struct sigrok_device_instance *sdi;
int err;
if( !(sdi = zp_open_device(device_index)) ) {
if (!(sdi = zp_open_device(device_index))) {
g_warning("unable to open device");
return SIGROK_ERR;
}
err = libusb_claim_interface(sdi->usb->devhdl, USB_INTERFACE);
if(err != 0) {
if (err != 0) {
g_warning("Unable to claim interface: %d", err);
return SIGROK_ERR;
}
@ -321,70 +345,68 @@ static int hw_opendev(int device_index)
analyzer_configure(sdi->usb->devhdl);
analyzer_set_memory_size(MEMORY_SIZE_512K);
// analyzer_set_freq(g_freq, g_freq_scale);
// 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);
// 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 (g_double_mode == 1)
#if 0
if (g_double_mode == 1)
analyzer_set_compression(COMPRESSION_DOUBLE);
else if (g_compression == 1)
analyzer_set_compression(COMPRESSION_ENABLE);
else */
analyzer_set_compression(COMPRESSION_NONE);
else
#endif
analyzer_set_compression(COMPRESSION_NONE);
if(cur_samplerate == 0) {
/* sample rate hasn't been set; default to the slowest it has */
if(hw_set_configuration(device_index, HWCAP_SAMPLERATE, &samplerates.low) == SIGROK_ERR)
if (cur_samplerate == 0) {
/* Sample rate hasn't been set. Default to the slowest one. */
if (hw_set_configuration(device_index, HWCAP_SAMPLERATE,
&samplerates.low) == SIGROK_ERR)
return SIGROK_ERR;
}
return SIGROK_OK;
}
static void hw_closedev(int device_index)
{
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);
}
static void hw_cleanup(void)
{
GSList *l;
/* properly close all devices */
for(l = device_instances; l; l = l->next)
close_device( (struct sigrok_device_instance *) l->data);
/* Properly close all devices. */
for (l = device_instances; l; l = l->next)
close_device((struct sigrok_device_instance *)l->data);
/* and free all their memory */
for(l = device_instances; l; l = l->next)
/* And free all their memory. */
for (l = device_instances; l; l = l->next)
g_free(l->data);
g_slist_free(device_instances);
device_instances = NULL;
if(usb_context)
if (usb_context)
libusb_exit(usb_context);
usb_context = NULL;
}
static void *hw_get_device_info(int device_index, int device_info_id)
{
struct sigrok_device_instance *sdi;
void *info;
if( !(sdi = get_sigrok_device_instance(device_instances, device_index)) )
if (!(sdi = get_sigrok_device_instance(device_instances, device_index)))
return NULL;
info = NULL;
switch(device_info_id)
{
switch (device_info_id) {
case DI_INSTANCE:
info = sdi;
break;
@ -405,25 +427,23 @@ static void *hw_get_device_info(int device_index, int device_info_id)
return info;
}
static int hw_get_status(int device_index)
{
struct sigrok_device_instance *sdi;
sdi = get_sigrok_device_instance(device_instances, device_index);
if(sdi)
if (sdi)
return sdi->status;
else
return ST_NOT_FOUND;
}
static int *hw_get_capabilities(void)
{
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)
{
g_message("%s(%llu)", __FUNCTION__, samplerate);
@ -432,7 +452,7 @@ static int set_configuration_samplerate(uint64_t samplerate)
else if (samplerate > KHZ(1))
analyzer_set_freq(samplerate / KHZ(1), FREQ_SCALE_KHZ);
else
analyzer_set_freq(samplerate , FREQ_SCALE_HZ);
analyzer_set_freq(samplerate, FREQ_SCALE_HZ);
cur_samplerate = samplerate;
@ -444,23 +464,20 @@ static int hw_set_configuration(int device_index, int capability, void *value)
struct sigrok_device_instance *sdi;
uint64_t *tmp_u64;
if( !(sdi = get_sigrok_device_instance(device_instances, device_index)) )
if (!(sdi = get_sigrok_device_instance(device_instances, device_index)))
return SIGROK_ERR;
switch (capability) {
case HWCAP_SAMPLERATE:
tmp_u64 = value;
return set_configuration_samplerate(*tmp_u64);
case HWCAP_PROBECONFIG:
return configure_probes( (GSList *) value);
case HWCAP_LIMIT_SAMPLES:
limit_samples = strtoull(value, NULL, 10);
return SIGROK_OK;
default:
return SIGROK_ERR;
case HWCAP_SAMPLERATE:
tmp_u64 = value;
return set_configuration_samplerate(*tmp_u64);
case HWCAP_PROBECONFIG:
return configure_probes((GSList *) value);
case HWCAP_LIMIT_SAMPLES:
limit_samples = strtoull(value, NULL, 10);
return SIGROK_OK;
default:
return SIGROK_ERR;
}
}
@ -473,20 +490,23 @@ static int hw_start_acquisition(int device_index, gpointer session_device_id)
unsigned int packet_num;
unsigned char *buf;
if( !(sdi = get_sigrok_device_instance(device_instances, device_index)))
if (!(sdi = get_sigrok_device_instance(device_instances, device_index)))
return SIGROK_ERR;
analyzer_start(sdi->usb->devhdl);
g_message("Waiting for data");
analyzer_wait_data(sdi->usb->devhdl);
g_message("Stop address = 0x%x", analyzer_get_stop_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));
g_message("Stop address = 0x%x",
analyzer_get_stop_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.length = sizeof(struct datafeed_header);
packet.payload = (unsigned char *) &header;
packet.payload = (unsigned char *)&header;
header.feed_version = 1;
gettimeofday(&header.starttime, NULL);
header.samplerate = cur_samplerate;
@ -498,15 +518,16 @@ static int hw_start_acquisition(int device_index, gpointer session_device_id)
if (!buf)
return SIGROK_ERR;
analyzer_read_start(sdi->usb->devhdl);
/* send the incoming transfer to the session bus */
for(packet_num = 0; packet_num < (memory_size * 4 / PACKET_SIZE); packet_num++) {
/* Send the incoming transfer to the session bus. */
for (packet_num = 0; packet_num < (memory_size * 4 / PACKET_SIZE);
packet_num++) {
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);
packet.type = DF_LOGIC32;
packet.length = PACKET_SIZE;
packet.payload = buf;
session_bus(session_device_id, &packet);
session_bus(session_device_id, &packet);
}
analyzer_read_stop(sdi->usb->devhdl);
g_free(buf);
@ -517,8 +538,7 @@ static int hw_start_acquisition(int device_index, gpointer session_device_id)
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)
{
struct datafeed_packet packet;
@ -527,21 +547,18 @@ static void hw_stop_acquisition(int device_index, gpointer session_device_id)
packet.type = DF_END;
session_bus(session_device_id, &packet);
if( !(sdi = get_sigrok_device_instance(device_instances, device_index)))
return; // XXX cry?
if (!(sdi = get_sigrok_device_instance(device_instances, device_index)))
return; /* TODO: Cry? */
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 = {
"zeroplus-logic-cube",
1,
hw_init,
hw_cleanup,
hw_opendev,
hw_closedev,
hw_get_device_info,
@ -549,6 +566,5 @@ struct device_plugin zeroplus_logic_cube_plugin_info = {
hw_get_capabilities,
hw_set_configuration,
hw_start_acquisition,
hw_stop_acquisition
hw_stop_acquisition,
};