Skip to content

Commit

Permalink
Added savemem script. Added cgi-screenshot. Switched from make to scons.
Browse files Browse the repository at this point in the history
  • Loading branch information
cktben committed Mar 22, 2011
1 parent ab9ed54 commit 2e9a778
Show file tree
Hide file tree
Showing 7 changed files with 290 additions and 17 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Original file line Diff line number Diff line change
@@ -1,2 +1,5 @@
*.pyc *.pyc
*.o
cgi-screenshot
gpib_console gpib_console
.sconsign.dblite
17 changes: 0 additions & 17 deletions Makefile

This file was deleted.

7 changes: 7 additions & 0 deletions SConstruct
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,7 @@
env = Environment()
env.ParseConfig('pkg-config --cflags --libs libusb')
env.ParseConfig('pkg-config --cflags --libs libusb-1.0')
env.ParseConfig('pkg-config --cflags --libs libpng')

env.Program('gpib_console')
env.Program('cgi-screenshot', ['cgi-screenshot.cpp', 'dso3000.cpp'])
80 changes: 80 additions & 0 deletions cgi-screenshot.cpp
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,80 @@
#include "dso3000.hpp"

#include <png.h>
#include <setjmp.h>
#include <stdio.h>
#include <stdexcept>

using namespace std;

void error(const char *str)
{
printf("Content-type: text/plain\n\nERROR: %s\n", str);
}

int main(int argc, char *argv[])
{
DSO3000 *scope;
try
{
scope = new DSO3000();
} catch (exception &e)
{
error(e.what());
return 1;
}

unsigned char image[76800];
if (!scope->screenshot(image))
{
error("Failed to acquire screenshot");
return 1;
}

delete scope;

printf("Content-type: image/png\n\n");

png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
if (!png_ptr)
{
return 1;
}

png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
{
png_destroy_write_struct(&png_ptr, 0);
return 1;
}

if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_write_struct(&png_ptr, 0);
return 1;
}

png_init_io(png_ptr, stdout);
png_set_IHDR(png_ptr, info_ptr, 320, 240, 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);

png_color palette[256];
for (int i = 0; i < 256; ++i)
{
palette[i].red = i / 64 * 255 / 3;
palette[i].green = (i & 0x30) / 16 * 255 / 3;
palette[i].blue = (i & 0x0c) / 4 * 255 / 3;
}
png_set_PLTE(png_ptr, info_ptr, palette, 256);

png_bytep row_pointers[240];
for (int i = 0; i < 240; ++i)
{
row_pointers[i] = image + i * 320;
}
png_set_rows(png_ptr, info_ptr, row_pointers);

png_write_png(png_ptr, info_ptr, 0, 0);
png_destroy_write_struct(&png_ptr, &info_ptr);

return 0;
}
148 changes: 148 additions & 0 deletions dso3000.cpp
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,148 @@
#include "dso3000.hpp"

#include <libusb.h>
#include <stdexcept>

using namespace std;

DSO3000::DSO3000()
{
_usb = 0;
_timeout = 10000;

if (libusb_init(&_usb))
{
throw runtime_error("Failed to initialize libusb");
}

_device = libusb_open_device_with_vid_pid(_usb, 0x0400, 0xc55d);
if (!_device)
{
throw runtime_error("Failed to open USB device");
}

if (libusb_set_configuration(_device, 1))
{
throw runtime_error("Can't set configuration");
}

if (libusb_claim_interface(_device, 0))
{
throw runtime_error("Can't claim interface");
}

flush();
}

DSO3000::~DSO3000()
{
if (_device)
{
libusb_close(_device);
}

libusb_exit(_usb);
}

int DSO3000::flush()
{
char buf[256];
int len, total = 0;

do
{
len = read(buf, sizeof(buf));
total += len;
} while (len);

return total;
}

void DSO3000::writeChar(char ch)
{
libusb_control_transfer(_device, 0xc0, 1, ch, 0, 0, 0, _timeout);
}

void DSO3000::write(const char *str)
{
for (int i = 0; str[i]; i++)
{
writeChar(str[i]);
}
writeChar('\r');
}

int DSO3000::getResponseLength()
{
unsigned char len;

libusb_control_transfer(_device, 0xc0, 0, 0, 0, &len, 1, _timeout);

return len;
}

int DSO3000::read(char *buf, int maxlen)
{
int i, len;

len = getResponseLength();
if (!len)
{
if (maxlen)
buf[0] = 0;

return 0;
}

if (len > (maxlen - 1))
{
len = maxlen - 1;
}

len = libusb_control_transfer(_device, 0xc0, 0, 1, 0, (unsigned char *)buf, len, _timeout);

// Truncate the response at the first '\n' because the scope firmware sometimes
// sends extra junk.
for (i = 0; i < len; i++)
{
if (buf[i] == '\n')
{
len = i;
break;
}
}
buf[len] = 0;

return len;
}

bool DSO3000::screenshot(unsigned char* buf)
{
write(":HARD_COPY");

if (libusb_control_transfer(_device, 0xc0, 8, 0, 0x50, 0, 0, _timeout))
{
return false;
}

// wIndex:wValue is the length of data returned
if (libusb_control_transfer(_device, 0xc0, 9, 0x2c00, 1, 0, 0, _timeout))
{
return false;
}

if (libusb_control_transfer(_device, 0xc0, 7, 0, 0x50, 0, 0, _timeout))
{
return false;
}

int len = 0;
if (libusb_bulk_transfer(_device, 0x81, buf, 76800, &len, _timeout))
{
return false;
}

getResponseLength();

return len == 76800;
}
31 changes: 31 additions & 0 deletions dso3000.hpp
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma once

#include <libusb.h>

class DSO3000
{
public:
DSO3000();
~DSO3000();

// Reads and discards all data from the scope's response buffer.
// Returns the number of bytes read.
int flush();

void writeChar(char ch);
void write(const char *str);
int getResponseLength();
int read(char *buf, int maxlen);

// Acquires a screenshot.
// buf must point to a 76800-byte buffer to hold the 320x240 image,
// one byte per pixel. Each byte is a color with the form RRGGBBxx.
bool screenshot(unsigned char *buf);

private:
libusb_context *_usb;
libusb_device_handle *_device;

// Time in milliseconds to wait for USB transfers to complete
unsigned int _timeout;
};
21 changes: 21 additions & 0 deletions savemem
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env python

import sys
from dso3000 import *
from numpy import *

scope = DSO3000()

if len(sys.argv) < 3:
print >> sys.stderr, 'Usage: %s <file> <channels...>' % sys.argv[0]
sys.exit(1)

data = array([[]])
for ch in sys.argv[2:]:
mem = scope.readMemory(int(ch))
if not data.any():
data.shape = (0, len(mem))
data = append(data, [mem], 0)

savetxt(sys.argv[1], data)

0 comments on commit 2e9a778

Please sign in to comment.