diff --git a/devices/CMakeLists.txt b/devices/CMakeLists.txt
index ebd573256..d41f4de9d 100644
--- a/devices/CMakeLists.txt
+++ b/devices/CMakeLists.txt
@@ -28,4 +28,9 @@ else(BUILD_DEBIAN)
add_subdirectory(plutosdr)
endif(LIBUSB_FOUND AND LIBIIO_FOUND)
+ find_package(LibPerseus)
+ if(LIBUSB_FOUND AND LIBPERSEUS_FOUND)
+ add_subdirectory(perseus)
+ endif()
+
endif (BUILD_DEBIAN)
diff --git a/devices/perseus/CMakeLists.txt b/devices/perseus/CMakeLists.txt
new file mode 100644
index 000000000..659af597a
--- /dev/null
+++ b/devices/perseus/CMakeLists.txt
@@ -0,0 +1,48 @@
+project(perseusdevice)
+
+set (CMAKE_CXX_STANDARD 11)
+
+set(perseusdevice_SOURCES
+ deviceperseus.cpp
+ deviceperseusscan.cpp
+)
+
+set(perseusdevice_HEADERS
+ deviceperseus.h
+ deviceperseusscan.h
+)
+
+if (BUILD_DEBIAN)
+include_directories(
+ .
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${LIBPERSEUSSRC}
+)
+else (BUILD_DEBIAN)
+include_directories(
+ .
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${LIBPERSEUS_INCLUDE_DIR}
+)
+endif (BUILD_DEBIAN)
+
+#add_definitions(${QT_DEFINITIONS})
+#add_definitions(-DQT_SHARED)
+
+add_library(perseusdevice SHARED
+ ${perseusdevice_SOURCES}
+)
+
+if (BUILD_DEBIAN)
+target_link_libraries(perseusdevice
+ perseus
+ sdrbase
+)
+else (BUILD_DEBIAN)
+target_link_libraries(perseusdevice
+ ${LIBPERSEUS_LIBRARIES}
+ sdrbase
+)
+endif (BUILD_DEBIAN)
+
+install(TARGETS perseusdevice DESTINATION lib)
diff --git a/devices/perseus/deviceperseus.cpp b/devices/perseus/deviceperseus.cpp
new file mode 100644
index 000000000..0b3bbec2e
--- /dev/null
+++ b/devices/perseus/deviceperseus.cpp
@@ -0,0 +1,35 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2018 Edouard Griffiths, F4EXB //
+// //
+// This program is free software; you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation as version 3 of the License, or //
+// //
+// This program is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License V3 for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#include "perseus-sdr.h"
+#include "deviceperseus.h"
+
+DevicePerseus::DevicePerseus()
+{
+ m_nbDevices = perseus_init();
+}
+
+DevicePerseus::~DevicePerseus()
+{
+ perseus_exit();
+}
+
+DevicePerseus& DevicePerseus::instance()
+{
+ static DevicePerseus inst;
+ return inst;
+}
+
diff --git a/devices/perseus/deviceperseus.h b/devices/perseus/deviceperseus.h
new file mode 100644
index 000000000..1419da5fb
--- /dev/null
+++ b/devices/perseus/deviceperseus.h
@@ -0,0 +1,39 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2018 Edouard Griffiths, F4EXB //
+// //
+// This program is free software; you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation as version 3 of the License, or //
+// //
+// This program is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License V3 for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef DEVICES_PERSEUS_DEVICEPERSEUS_H_
+#define DEVICES_PERSEUS_DEVICEPERSEUS_H_
+
+#include "deviceperseusscan.h"
+
+class DevicePerseus
+{
+public:
+ static DevicePerseus& instance();
+ void scan() { m_scan.scan(m_nbDevices); }
+ void getSerials(std::vector& serials) const { m_scan.getSerials(serials); }
+protected:
+ DevicePerseus();
+ DevicePerseus(const DevicePerseus&) : m_nbDevices(0) {}
+ DevicePerseus& operator=(const DevicePerseus& other __attribute__((unused))) { return *this; }
+ ~DevicePerseus();
+private:
+ int m_nbDevices;
+ DevicePerseusScan m_scan;
+};
+
+
+#endif /* DEVICES_PERSEUS_DEVICEPERSEUS_H_ */
diff --git a/devices/perseus/deviceperseusscan.cpp b/devices/perseus/deviceperseusscan.cpp
new file mode 100644
index 000000000..ecc532903
--- /dev/null
+++ b/devices/perseus/deviceperseusscan.cpp
@@ -0,0 +1,116 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2018 Edouard Griffiths, F4EXB //
+// //
+// This program is free software; you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation as version 3 of the License, or //
+// //
+// This program is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License V3 for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#include "deviceperseusscan.h"
+#include "perseus-sdr.h"
+#include
+#include
+
+
+void DevicePerseusScan::scan(int nbDevices)
+{
+ if (nbDevices == 0) {
+ qInfo("DevicePerseusScan::scan: no Perseus devices");
+ return;
+ }
+
+ perseus_descr *descr;
+ eeprom_prodid prodid;
+
+ for (int deviceIndex = 0; deviceIndex < nbDevices; deviceIndex++)
+ {
+ if ((descr = perseus_open(deviceIndex)) == 0) {
+ qCritical("DevicePerseusScan::scan: open error: %s\n", perseus_errorstr());
+ continue;
+ }
+
+// if (perseus_firmware_download(descr, 0) < 0) {
+// qCritical("DevicePerseusScan::scan: firmware download error: %s", perseus_errorstr());
+// continue;
+// }
+// else
+// {
+// qInfo("DevicePerseusScan::scan: device #%d firmware downloaded", deviceIndex);
+// }
+
+ if (perseus_get_product_id(descr,&prodid) < 0) {
+ qCritical("DevicePerseusScan::scan: get product id error: %s", perseus_errorstr());
+ perseus_close(descr);
+ continue;
+ }
+ else
+ {
+ uint32_t sigA = (prodid.signature[5]<<16) + prodid.signature[4];
+ uint32_t sigB = (prodid.signature[3]<<16) + prodid.signature[2];
+ uint32_t sigC = (prodid.signature[1]<<16) + prodid.signature[0];
+ std::stringstream ss;
+ ss << prodid.sn << "-" << std::hex << sigA << "-" << sigB << "-" << sigC;
+ m_scans.push_back({ss.str(), prodid.sn, deviceIndex});
+ m_serialMap[m_scans.back().m_serial] = &m_scans.back();
+ perseus_close(descr);
+ }
+ }
+}
+
+const std::string* DevicePerseusScan::getSerialAt(unsigned int index) const
+{
+ if (index < m_scans.size()) {
+ return &(m_scans[index].m_serial);
+ } else {
+ return 0;
+ }
+}
+
+uint16_t DevicePerseusScan::getSerialNumberAt(unsigned int index) const
+{
+ if (index < m_scans.size()) {
+ return m_scans[index].m_serialNumber;
+ } else {
+ return 0;
+ }
+}
+
+int DevicePerseusScan::getSequenceAt(unsigned int index) const
+{
+ if (index < m_scans.size()) {
+ return m_scans[index].m_sequence;
+ } else {
+ return 0;
+ }
+}
+
+int DevicePerseusScan::getSequenceFromSerial(const std::string& serial) const
+{
+ std::map::const_iterator it = m_serialMap.find(serial);
+ if (it == m_serialMap.end()) {
+ return -1;
+ } else {
+ return ((it->second)->m_sequence);
+ }
+}
+
+void DevicePerseusScan::getSerials(std::vector& serials) const
+{
+ std::vector::const_iterator it = m_scans.begin();
+ serials.clear();
+
+ for (; it != m_scans.end(); ++it) {
+ serials.push_back(it->m_serial);
+ }
+}
+
+
+
diff --git a/devices/perseus/deviceperseusscan.h b/devices/perseus/deviceperseusscan.h
new file mode 100644
index 000000000..8eb85677a
--- /dev/null
+++ b/devices/perseus/deviceperseusscan.h
@@ -0,0 +1,51 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2018 Edouard Griffiths, F4EXB //
+// //
+// This program is free software; you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation as version 3 of the License, or //
+// //
+// This program is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License V3 for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef DEVICES_PERSEUS_DEVICEPERSEUSSCAN_H_
+#define DEVICES_PERSEUS_DEVICEPERSEUSSCAN_H_
+
+#include
+#include
+#include
+#include