From 408e27f46c0d7cf8bce9ea4f2b8cd7db4b2eb8ad Mon Sep 17 00:00:00 2001 From: Tom Schouten Date: Sat, 9 Aug 2014 16:20:02 -0400 Subject: [PATCH] sigrok first sign of life --- CMakeLists.txt | 21 ++++++++--- pyla.txt | 31 ++++++++++++++++ pylacore.i | 2 + saleae.cpp | 14 +++---- sigrok.cpp | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++ sigrok.h | 33 +++++++++++++++++ 6 files changed, 187 insertions(+), 13 deletions(-) create mode 100644 sigrok.cpp create mode 100644 sigrok.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 7dcdd70..65ba983 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,12 @@ project(pyla) cmake_minimum_required (VERSION 2.8.6) +IF(WIN32) +ELSE(WIN32) + find_package(PkgConfig) + PKG_CHECK_MODULES(Sigrok REQUIRED libsigrok) +ENDIF(WIN32) + find_package(Boost COMPONENTS system REQUIRED) @@ -12,6 +18,7 @@ FIND_PACKAGE(PythonLibs) INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH}) INCLUDE_DIRECTORIES(${BOOST_INCLUDE_PATH}) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) + SET(CMAKE_SWIG_FLAGS "") SET_SOURCE_FILES_PROPERTIES(pylacore.i PROPERTIES CPLUSPLUS ON) SWIG_ADD_MODULE(pylacore python pylacore.i @@ -20,8 +27,8 @@ SWIG_ADD_MODULE(pylacore python pylacore.i saleae.cpp syncser.cpp measure.cpp -) - + sigrok.cpp +) include(ExternalProject) @@ -33,6 +40,7 @@ ExternalProject_Add(SaleaeDeviceSdk ) INCLUDE_DIRECTORIES( + ${Sigrok_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ${CMAKE_BINARY_DIR}/SaleaeDeviceSdk-prefix/src/SaleaeDeviceSdk/include ) @@ -55,11 +63,12 @@ endif(WIN32) SWIG_LINK_LIBRARIES(pylacore ${PYTHON_LIBRARIES} ${Boost_SYSTEM_LIBRARY} + ${Sigrok_LDFLAGS} ${SALEADEVICE_LIBRARY}) # DEBUG: print out all variables available to CMAKE -#get_cmake_property(_variableNames VARIABLES) -#foreach (_variableName ${_variableNames}) -# message(STATUS "${_variableName}=${${_variableName}}") -#endforeach() +get_cmake_property(_variableNames VARIABLES) +foreach (_variableName ${_variableNames}) + message(STATUS "${_variableName}=${${_variableName}}") +endforeach() diff --git a/pyla.txt b/pyla.txt index c0d9222..60fce43 100644 --- a/pyla.txt +++ b/pyla.txt @@ -352,3 +352,34 @@ works on tx: |__ Port 6: Dev 54, If 1, Class='bInterfaceClass 0xe0 not yet handled', Driver=btusb, 12M |__ Port 6: Dev 54, If 2, Class=vend., Driver=, 12M |__ Port 6: Dev 54, If 3, Class=app., Driver=, 12M + + + +Entry: sigrok +Date: Sat Aug 9 13:07:35 EDT 2014 + +Unfortunately pyla was already +- done when I heard of sigrok[1]. I'd +like to find a way to integrate. The simplest way would probably to +integrate into libsigrokdecode[2] from two ways: export pyla C++ as a +decoder and use the lsd decoders in pyla style python scripts. Former +is probably most useful. + +Second part is to use the libsigrok drivers as frontend to the pyla +C++ decoders. + +Problem is time. What I'm looking at is mostly direction: how to aim +at integration instead of reinventing the wheel. + +Roadmap: +- get sigrok to work with the custom FX2 firmware fx2lafw[3]. +- connect libsigrok driver to pylacore + +./sigrok-cli -d fx2lafw -C 0,1,2,3,4,5,6,7 --time 100 + +Next: how to get at the datafeed? + + + +[1] http://sigrok.org +[2] http://sigrok.org/wiki/Libsigrokdecode +[3] http://sigrok.org/wiki/Fx2lafw diff --git a/pylacore.i b/pylacore.i index 64812d4..7bd0e78 100644 --- a/pylacore.i +++ b/pylacore.i @@ -7,6 +7,7 @@ #include "uart.h" #include "syncser.h" #include "saleae.h" +#include "sigrok.h" #include "rpn.h" #include "shared.h" #include "measure.h" @@ -39,6 +40,7 @@ %include "rpn.h" %include "shared.h" %include "saleae.h" +%include "sigrok.h" %include "measure.h" diff --git a/saleae.cpp b/saleae.cpp index ffbb777..0e331e6 100644 --- a/saleae.cpp +++ b/saleae.cpp @@ -28,7 +28,7 @@ void __stdcall OnWriteData( U64 device_id, U8* data, U32 data_length, void* user /* Not used */ } void __stdcall OnError( U64 device_id, void* user_data ) { - LOG("salea.cpp:ERROR\n"); + LOG("saleae.cpp:ERROR\n"); saleae::find_device(device_id)->on_error(); } void __stdcall OnDisconnect( U64 device_id, void* user_data ) { @@ -36,7 +36,7 @@ void __stdcall OnDisconnect( U64 device_id, void* user_data ) { } void __stdcall OnConnect( U64 device_id, GenericInterface* device_interface, void* user_data ) { if( dynamic_cast( device_interface ) != NULL ) { - LOG("salea.cpp:%08llX Connect\n", device_id); + LOG("saleae.cpp:%08llX Connect\n", device_id); LogicInterface *i = (LogicInterface*)device_interface; saleae *dev = saleae::register_device(device_id, i); i->RegisterOnReadData( &OnReadData ); @@ -44,7 +44,7 @@ void __stdcall OnConnect( U64 device_id, GenericInterface* device_interface, voi i->RegisterOnError( &OnError ); double sr = dev->get_samplerate(); i->SetSampleRateHz( sr ); - LOG("salea.cpp:%08llX Start at %.3f MHz\n", device_id, sr/1000000.0); + LOG("saleae.cpp:%08llX Start at %.3f MHz\n", device_id, sr/1000000.0); i->ReadStart(); } } @@ -65,18 +65,18 @@ saleae::saleae(U64 device_id, GenericInterface* device_interface) : saleae::~saleae() { // Tear down the callback before deleting any instances. - LOG("salea.cpp:~saleae()\n"); + LOG("saleae.cpp:~saleae()\n"); } void saleae::start(double samplerate) { if (!_device_map_mutex) { - LOG("salea.cpp:default at %.3f MHz\n", samplerate/1000000.0); + LOG("saleae.cpp:default at %.3f MHz\n", samplerate/1000000.0); _default_samplerate = samplerate; _device_map_mutex = new boost::mutex(); DevicesManagerInterface::RegisterOnConnect( &OnConnect ); DevicesManagerInterface::RegisterOnDisconnect( &OnDisconnect ); DevicesManagerInterface::BeginConnect(); - LOG("salea.cpp:BeginConnect (waiting for Connect)\n"); + LOG("saleae.cpp:BeginConnect (waiting for Connect)\n"); } } @@ -121,7 +121,7 @@ void saleae::set_samplerate_hint(double sr) { _samplerate = sr; } void saleae::connect_sink(shared_ptr s) { - LOG("salea.cpp:%08llX connect_sink\n", _device_id); + LOG("saleae.cpp:%08llX connect_sink\n", _device_id); _sink_mutex.lock(); _sink = s; _sink_mutex.unlock(); diff --git a/sigrok.cpp b/sigrok.cpp new file mode 100644 index 0000000..798c708 --- /dev/null +++ b/sigrok.cpp @@ -0,0 +1,99 @@ +/* Dump Saleae Logic output to stdout. + Adapted from SaleaeDeviceSdk-1.1.14/source/ConsoleDemo.cpp */ + +#include "sigrok.h" + +#include +#include +#include +#include + +using boost::shared_ptr; +using std::cout; +using std::cerr; +using std::endl; + +static void wrap_datafeed_in(const struct sr_dev_inst *sdi, + const struct sr_datafeed_packet *packet, + void *cb_data) { + sigrok *s = (sigrok *)cb_data; + cerr << "."; + //s->datafeed_in(sdi, packet); +} + +sigrok::sigrok() : + _inst(NULL), + _samplerate(PYLA_DEFAULT_SAMPLERATE), + _sink(shared_ptr(new hole())) { + int rv; + if (SR_OK != (rv = sr_init(&_sr))) { + g_critical("sr_init() failed"); + exit(1); // FIXME + } + cout << "sigrok.cpp: scanning drivers" << endl; + struct sr_dev_driver **drivers = sr_driver_list(); + for (int i = 0; drivers[i]; i++) { + if(strcmp(drivers[i]->name, "fx2lafw")) continue; // FIXME: later use other + cout << " - " << drivers[i]->name << ": " << drivers[i]->longname << endl; + if (sr_driver_init(_sr, drivers[i]) != SR_OK) { + g_critical("Failed to initialize driver."); + exit(1); // FIXME + } + GSList *tmpdevs = sr_driver_scan(drivers[i], NULL); + for (GSList *l = tmpdevs; l; l = l->next) { + struct sr_dev_inst *inst = (typeof(inst))l->data; + int nchan = g_slist_length(inst->channels); + cout << " - " << inst << ": " << nchan << endl; + if (SR_OK != sr_dev_open(inst)) { + g_critical("Failed to open device"); + exit(1); + } + _inst = inst; + sr_session_new(&_session); + sr_session_datafeed_callback_add(_session, wrap_datafeed_in, this); + if (sr_session_dev_add(_session, _inst) != SR_OK) { + g_critical("Failed to add device to session."); + sr_session_destroy(_session); + exit(1); + } + for (GSList *l = _inst->channels; l; l = l->next) { + struct sr_channel *ch = (typeof(ch))l->data; + ch->enabled = TRUE; // enable all, we do our own filtering & triggering + } + + } + g_slist_free(tmpdevs); + } +} + +void sigrok::start() { + if (sr_session_start(_session) != SR_OK) { + g_critical("Failed to start session."); + sr_session_destroy(_session); + exit(1); + } + sr_session_run(_session); +} + +sigrok::~sigrok() { + // Tear down the callback before deleting any instances. + LOG("sigrok.cpp:~sigrok()\n"); + +} + + +double sigrok::get_samplerate() { + return _samplerate; +} +void sigrok::set_samplerate_hint(double sr) { + _samplerate = sr; +} +void sigrok::connect_sink(shared_ptr s) { + LOG("sigrok.cpp:connect_sink\n"); + // _sink_mutex.lock(); // FIXME! + _sink = s; + // _sink_mutex.unlock(); +} + + + diff --git a/sigrok.h b/sigrok.h new file mode 100644 index 0000000..a1f371b --- /dev/null +++ b/sigrok.h @@ -0,0 +1,33 @@ +#ifndef _SIGROK_H +#define _SIGROK_H + +#include "shared.h" +#include + + +class sigrok : public cosink, public sampler { + public: + sigrok(); + ~sigrok(); + /* cosink */ + void connect_sink(boost::shared_ptr); + + /* sampler */ + double get_samplerate(); + void set_samplerate_hint(double sr); + + void start(); + + private: + boost::shared_ptr _sink; + double _samplerate; + // FIXME: shared context? + struct sr_context *_sr; + struct sr_dev_inst *_inst; + struct sr_session *_session; + +}; + +#endif // _SIGROK_H + +