mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
First Lighpack device version.
Former-commit-id: 2133e13ed421d363fa28d3f765607e455088618b
This commit is contained in:
parent
2bc84d63bf
commit
12c925d77f
@ -37,6 +37,9 @@ find_package(Qt4 COMPONENTS QtCore QtGui QtNetwork REQUIRED QUIET)
|
|||||||
# add protocol buffers
|
# add protocol buffers
|
||||||
find_package(Protobuf REQUIRED)
|
find_package(Protobuf REQUIRED)
|
||||||
|
|
||||||
|
#add libusb
|
||||||
|
find_package(libusb-1.0 REQUIRED)
|
||||||
|
|
||||||
#SET(QT_DONT_USE_QTGUI TRUE)
|
#SET(QT_DONT_USE_QTGUI TRUE)
|
||||||
#SET(QT_USE_QTCONSOLE TRUE)
|
#SET(QT_USE_QTCONSOLE TRUE)
|
||||||
include(${QT_USE_FILE})
|
include(${QT_USE_FILE})
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
ON RASPBERRY
|
ON RASPBERRY
|
||||||
--------------
|
--------------
|
||||||
sudo apt-get install libprotobuf-dev libQt4-dev rsync
|
sudo apt-get install libprotobuf-dev libQt4-dev libusb-1.0-0-dev rsync
|
||||||
|
|
||||||
ON HOST
|
ON HOST
|
||||||
---------
|
---------
|
||||||
|
98
cmake/Findlibusb-1.0.cmake
Normal file
98
cmake/Findlibusb-1.0.cmake
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
# - Try to find libusb-1.0
|
||||||
|
# Once done this will define
|
||||||
|
#
|
||||||
|
# LIBUSB_1_FOUND - system has libusb
|
||||||
|
# LIBUSB_1_INCLUDE_DIRS - the libusb include directory
|
||||||
|
# LIBUSB_1_LIBRARIES - Link these to use libusb
|
||||||
|
# LIBUSB_1_DEFINITIONS - Compiler switches required for using libusb
|
||||||
|
#
|
||||||
|
# Adapted from cmake-modules Google Code project
|
||||||
|
#
|
||||||
|
# Copyright (c) 2006 Andreas Schneider <mail@cynapses.org>
|
||||||
|
#
|
||||||
|
# (Changes for libusb) Copyright (c) 2008 Kyle Machulis <kyle@nonpolynomial.com>
|
||||||
|
#
|
||||||
|
# Redistribution and use is allowed according to the terms of the New BSD license.
|
||||||
|
#
|
||||||
|
# CMake-Modules Project New BSD License
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
# * Neither the name of the CMake-Modules Project nor the names of its
|
||||||
|
# contributors may be used to endorse or promote products derived from this
|
||||||
|
# software without specific prior written permission.
|
||||||
|
#
|
||||||
|
# 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 OWNER 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
if (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS)
|
||||||
|
# in cache already
|
||||||
|
set(LIBUSB_FOUND TRUE)
|
||||||
|
else (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS)
|
||||||
|
find_path(LIBUSB_1_INCLUDE_DIR
|
||||||
|
NAMES
|
||||||
|
libusb.h
|
||||||
|
PATHS
|
||||||
|
/usr/include
|
||||||
|
/usr/local/include
|
||||||
|
/opt/local/include
|
||||||
|
/sw/include
|
||||||
|
PATH_SUFFIXES
|
||||||
|
libusb-1.0
|
||||||
|
)
|
||||||
|
|
||||||
|
find_library(LIBUSB_1_LIBRARY
|
||||||
|
NAMES
|
||||||
|
usb-1.0 usb
|
||||||
|
PATHS
|
||||||
|
/usr/lib
|
||||||
|
/usr/local/lib
|
||||||
|
/opt/local/lib
|
||||||
|
/sw/lib
|
||||||
|
)
|
||||||
|
|
||||||
|
set(LIBUSB_1_INCLUDE_DIRS
|
||||||
|
${LIBUSB_1_INCLUDE_DIR}
|
||||||
|
)
|
||||||
|
set(LIBUSB_1_LIBRARIES
|
||||||
|
${LIBUSB_1_LIBRARY}
|
||||||
|
)
|
||||||
|
|
||||||
|
if (LIBUSB_1_INCLUDE_DIRS AND LIBUSB_1_LIBRARIES)
|
||||||
|
set(LIBUSB_1_FOUND TRUE)
|
||||||
|
endif (LIBUSB_1_INCLUDE_DIRS AND LIBUSB_1_LIBRARIES)
|
||||||
|
|
||||||
|
if (LIBUSB_1_FOUND)
|
||||||
|
if (NOT libusb_1_FIND_QUIETLY)
|
||||||
|
message(STATUS "Found libusb-1.0:")
|
||||||
|
message(STATUS " - Includes: ${LIBUSB_1_INCLUDE_DIRS}")
|
||||||
|
message(STATUS " - Libraries: ${LIBUSB_1_LIBRARIES}")
|
||||||
|
endif (NOT libusb_1_FIND_QUIETLY)
|
||||||
|
else (LIBUSB_1_FOUND)
|
||||||
|
if (libusb_1_FIND_REQUIRED)
|
||||||
|
message(FATAL_ERROR "Could not find libusb")
|
||||||
|
endif (libusb_1_FIND_REQUIRED)
|
||||||
|
endif (LIBUSB_1_FOUND)
|
||||||
|
|
||||||
|
# show the LIBUSB_1_INCLUDE_DIRS and LIBUSB_1_LIBRARIES variables only in the advanced view
|
||||||
|
mark_as_advanced(LIBUSB_1_INCLUDE_DIRS LIBUSB_1_LIBRARIES)
|
||||||
|
|
||||||
|
endif (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS)
|
@ -3,6 +3,8 @@
|
|||||||
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/hyperion)
|
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/hyperion)
|
||||||
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/hyperion)
|
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/hyperion)
|
||||||
|
|
||||||
|
include_directories(${LIBUSB_1_INCLUDE_DIRS})
|
||||||
|
|
||||||
# Group the headers that go through the MOC compiler
|
# Group the headers that go through the MOC compiler
|
||||||
SET(Hyperion_QT_HEADERS
|
SET(Hyperion_QT_HEADERS
|
||||||
${CURRENT_HEADER_DIR}/Hyperion.h
|
${CURRENT_HEADER_DIR}/Hyperion.h
|
||||||
@ -28,6 +30,7 @@ SET(Hyperion_HEADERS
|
|||||||
${CURRENT_SOURCE_DIR}/device/LedDeviceWs2801.h
|
${CURRENT_SOURCE_DIR}/device/LedDeviceWs2801.h
|
||||||
${CURRENT_SOURCE_DIR}/device/LedDeviceLpd6803.h
|
${CURRENT_SOURCE_DIR}/device/LedDeviceLpd6803.h
|
||||||
${CURRENT_SOURCE_DIR}/device/LedDeviceAdalight.h
|
${CURRENT_SOURCE_DIR}/device/LedDeviceAdalight.h
|
||||||
|
${CURRENT_SOURCE_DIR}/device/LedDeviceLightpack.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(Hyperion_SOURCES
|
SET(Hyperion_SOURCES
|
||||||
@ -49,6 +52,7 @@ SET(Hyperion_SOURCES
|
|||||||
${CURRENT_SOURCE_DIR}/device/LedDeviceWs2801.cpp
|
${CURRENT_SOURCE_DIR}/device/LedDeviceWs2801.cpp
|
||||||
${CURRENT_SOURCE_DIR}/device/LedDeviceLpd6803.cpp
|
${CURRENT_SOURCE_DIR}/device/LedDeviceLpd6803.cpp
|
||||||
${CURRENT_SOURCE_DIR}/device/LedDeviceAdalight.cpp
|
${CURRENT_SOURCE_DIR}/device/LedDeviceAdalight.cpp
|
||||||
|
${CURRENT_SOURCE_DIR}/device/LedDeviceLightpack.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(Hyperion_RESOURCES
|
set(Hyperion_RESOURCES
|
||||||
@ -70,4 +74,5 @@ add_library(hyperion
|
|||||||
target_link_libraries(hyperion
|
target_link_libraries(hyperion
|
||||||
hyperion-utils
|
hyperion-utils
|
||||||
serialport
|
serialport
|
||||||
${QT_LIBRARIES})
|
${QT_LIBRARIES}
|
||||||
|
${LIBUSB_1_LIBRARIES})
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "device/LedDeviceTest.h"
|
#include "device/LedDeviceTest.h"
|
||||||
#include "device/LedDeviceWs2801.h"
|
#include "device/LedDeviceWs2801.h"
|
||||||
#include "device/LedDeviceAdalight.h"
|
#include "device/LedDeviceAdalight.h"
|
||||||
|
#include "device/LedDeviceLightpack.h"
|
||||||
|
|
||||||
#include "LinearColorSmoothing.h"
|
#include "LinearColorSmoothing.h"
|
||||||
|
|
||||||
@ -72,6 +73,13 @@ LedDevice* Hyperion::createDevice(const Json::Value& deviceConfig)
|
|||||||
|
|
||||||
device = deviceAdalight;
|
device = deviceAdalight;
|
||||||
}
|
}
|
||||||
|
else if (type == "lightpack")
|
||||||
|
{
|
||||||
|
LedDeviceLightpack* deviceLightpack = new LedDeviceLightpack();
|
||||||
|
deviceLightpack->open();
|
||||||
|
|
||||||
|
device = deviceLightpack;
|
||||||
|
}
|
||||||
else if (type == "test")
|
else if (type == "test")
|
||||||
{
|
{
|
||||||
const std::string output = deviceConfig["output"].asString();
|
const std::string output = deviceConfig["output"].asString();
|
||||||
|
290
libsrc/hyperion/device/LedDeviceLightpack.cpp
Normal file
290
libsrc/hyperion/device/LedDeviceLightpack.cpp
Normal file
@ -0,0 +1,290 @@
|
|||||||
|
// stl includes
|
||||||
|
#include <exception>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
// Local Hyperion includes
|
||||||
|
#include "LedDeviceLightpack.h"
|
||||||
|
|
||||||
|
// from USB_ID.h (http://code.google.com/p/light-pack/source/browse/CommonHeaders/USB_ID.h)
|
||||||
|
#define USB_OLD_VENDOR_ID 0x03EB
|
||||||
|
#define USB_OLD_PRODUCT_ID 0x204F
|
||||||
|
#define USB_VENDOR_ID 0x1D50
|
||||||
|
#define USB_PRODUCT_ID 0x6022
|
||||||
|
|
||||||
|
#define LIGHTPACK_INTERFACE 0
|
||||||
|
|
||||||
|
// from commands.h (http://code.google.com/p/light-pack/source/browse/CommonHeaders/commands.h)
|
||||||
|
// Commands to device, sends it in first byte of data[]
|
||||||
|
enum COMMANDS{
|
||||||
|
CMD_UPDATE_LEDS = 1,
|
||||||
|
CMD_OFF_ALL,
|
||||||
|
CMD_SET_TIMER_OPTIONS,
|
||||||
|
CMD_SET_PWM_LEVEL_MAX_VALUE, /* deprecated */
|
||||||
|
CMD_SET_SMOOTH_SLOWDOWN,
|
||||||
|
CMD_SET_BRIGHTNESS,
|
||||||
|
|
||||||
|
CMD_NOP = 0x0F
|
||||||
|
};
|
||||||
|
|
||||||
|
// from commands.h (http://code.google.com/p/light-pack/source/browse/CommonHeaders/commands.h)
|
||||||
|
enum DATA_VERSION_INDEXES{
|
||||||
|
INDEX_FW_VER_MAJOR = 1,
|
||||||
|
INDEX_FW_VER_MINOR
|
||||||
|
};
|
||||||
|
|
||||||
|
LedDeviceLightpack::LedDeviceLightpack(const std::string &serialNumber) :
|
||||||
|
LedDevice(),
|
||||||
|
_libusbContext(nullptr),
|
||||||
|
_deviceHandle(nullptr),
|
||||||
|
_busNumber(-1),
|
||||||
|
_addressNumber(-1),
|
||||||
|
_serialNumber(serialNumber),
|
||||||
|
_firmwareVersion({-1,-1}),
|
||||||
|
_ledCount(-1),
|
||||||
|
_bitsPerChannel(-1),
|
||||||
|
_ledBuffer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
LedDeviceLightpack::~LedDeviceLightpack()
|
||||||
|
{
|
||||||
|
if (_deviceHandle != nullptr)
|
||||||
|
{
|
||||||
|
libusb_release_interface(_deviceHandle, LIGHTPACK_INTERFACE);
|
||||||
|
libusb_attach_kernel_driver(_deviceHandle, LIGHTPACK_INTERFACE);
|
||||||
|
libusb_close(_deviceHandle);
|
||||||
|
|
||||||
|
_deviceHandle = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_libusbContext != nullptr)
|
||||||
|
{
|
||||||
|
libusb_exit(_libusbContext);
|
||||||
|
_libusbContext = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int LedDeviceLightpack::open()
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
|
||||||
|
// initialize the usb context
|
||||||
|
if ((error = libusb_init(&_libusbContext)) != LIBUSB_SUCCESS)
|
||||||
|
{
|
||||||
|
std::cerr << "Error while initializing USB context(" << error << "): " << libusb_error_name(error) << std::endl;
|
||||||
|
_libusbContext = nullptr;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
std::cout << "USB context initialized" << std::endl;
|
||||||
|
|
||||||
|
// retrieve the list of usb devices
|
||||||
|
libusb_device ** deviceList;
|
||||||
|
ssize_t deviceCount = libusb_get_device_list(_libusbContext, &deviceList);
|
||||||
|
|
||||||
|
// iterate the list of devices
|
||||||
|
for (ssize_t i = 0 ; i < deviceCount; ++i)
|
||||||
|
{
|
||||||
|
libusb_device_descriptor deviceDescriptor;
|
||||||
|
error = libusb_get_device_descriptor(deviceList[i], &deviceDescriptor);
|
||||||
|
if (error != LIBUSB_SUCCESS)
|
||||||
|
{
|
||||||
|
std::cerr << "Error while retrieving device descriptor(" << error << "): " << libusb_error_name(error) << std::endl;
|
||||||
|
// continue with next usb device
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((deviceDescriptor.idVendor == USB_VENDOR_ID && deviceDescriptor.idProduct == USB_PRODUCT_ID) ||
|
||||||
|
(deviceDescriptor.idVendor == USB_OLD_VENDOR_ID && deviceDescriptor.idProduct == USB_OLD_PRODUCT_ID))
|
||||||
|
{
|
||||||
|
// get the hardware address
|
||||||
|
int busNumber = libusb_get_bus_number(deviceList[i]);
|
||||||
|
int addressNumber = libusb_get_device_address(deviceList[i]);
|
||||||
|
|
||||||
|
// get the serial number
|
||||||
|
std::string serialNumber;
|
||||||
|
if (deviceDescriptor.iSerialNumber != 0)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
serialNumber = LedDeviceLightpack::getString(deviceList[i], deviceDescriptor.iSerialNumber);
|
||||||
|
}
|
||||||
|
catch (int e)
|
||||||
|
{
|
||||||
|
std::cerr << "unable to retrieve serial number from Lightpack device(" << e << "): " << libusb_error_name(e) << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the firmware version
|
||||||
|
Version version = {-1,-1};
|
||||||
|
try
|
||||||
|
{
|
||||||
|
version = LedDeviceLightpack::getVersion(deviceList[i]);
|
||||||
|
}
|
||||||
|
catch (int e)
|
||||||
|
{
|
||||||
|
std::cerr << "unable to retrieve firmware version number from Lightpack device(" << e << "): " << libusb_error_name(e) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Lightpack device found: bus=" << busNumber << " address=" << addressNumber << " serial=" << serialNumber << " version=" << version.majorVersion << "." << version.minorVersion << std::endl;
|
||||||
|
|
||||||
|
// check if this is the device we are looking for
|
||||||
|
if (_serialNumber.empty() || _serialNumber == serialNumber)
|
||||||
|
{
|
||||||
|
// This is it!
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_deviceHandle = openDevice(deviceList[i]);
|
||||||
|
_serialNumber = serialNumber;
|
||||||
|
_busNumber = busNumber;
|
||||||
|
_addressNumber = addressNumber;
|
||||||
|
|
||||||
|
std::cout << "Lightpack device successfully opened" << std::endl;
|
||||||
|
|
||||||
|
// break from the search loop
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
catch(int e)
|
||||||
|
{
|
||||||
|
std::cerr << "unable to retrieve open Lightpack device(" << e << "): " << libusb_error_name(e) << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// free the device list
|
||||||
|
libusb_free_device_list(deviceList, 1);
|
||||||
|
|
||||||
|
if (_deviceHandle != nullptr)
|
||||||
|
{
|
||||||
|
// FOR TESTING PURPOSE: FORCE MAJOR VERSION TO 6
|
||||||
|
_firmwareVersion.majorVersion = 6;
|
||||||
|
|
||||||
|
// disable smoothing of the chosen device
|
||||||
|
disableSmoothing();
|
||||||
|
|
||||||
|
// determine the number of leds
|
||||||
|
if (_firmwareVersion.majorVersion == 4)
|
||||||
|
{
|
||||||
|
_ledCount = 8;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_ledCount = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
// determine the bits per channel
|
||||||
|
if (_firmwareVersion.majorVersion == 6)
|
||||||
|
{
|
||||||
|
// maybe also or version 7? The firmware suggest this is only for 6... (2013-11-13)
|
||||||
|
_bitsPerChannel = 12;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_bitsPerChannel = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the led buffer size (command + 6 bytes per led)
|
||||||
|
_ledBuffer.resize(1 + _ledCount * 6, 0);
|
||||||
|
_ledBuffer[0] = CMD_UPDATE_LEDS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _deviceHandle == nullptr ? -1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LedDeviceLightpack::write(const std::vector<ColorRgb> &ledValues)
|
||||||
|
{
|
||||||
|
int count = std::min(_ledCount, (int) ledValues.size());
|
||||||
|
|
||||||
|
for (int i = 0; i < count ; ++i)
|
||||||
|
{
|
||||||
|
const ColorRgb & color = ledValues[i];
|
||||||
|
|
||||||
|
// copy the most significant bits of the rgb values to the first three bytes
|
||||||
|
_ledBuffer[6*i] = color.red;
|
||||||
|
_ledBuffer[6*i+1] = color.green;
|
||||||
|
_ledBuffer[6*i+2] = color.blue;
|
||||||
|
|
||||||
|
// leave the next three bytes on zero...
|
||||||
|
// 12-bit values have zeros in the lowest 4 bits which is almost correct, but it saves extra
|
||||||
|
// switches to determine what to do and some bit shuffling
|
||||||
|
}
|
||||||
|
|
||||||
|
return writeBytes(_ledBuffer.data(), _ledBuffer.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
int LedDeviceLightpack::switchOff()
|
||||||
|
{
|
||||||
|
unsigned char buf[1] = {CMD_OFF_ALL};
|
||||||
|
return writeBytes(buf, sizeof(buf)) == sizeof(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
int LedDeviceLightpack::writeBytes(uint8_t *data, int size)
|
||||||
|
{
|
||||||
|
return libusb_control_transfer(_deviceHandle,
|
||||||
|
LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE,
|
||||||
|
0x09,
|
||||||
|
(2 << 8),
|
||||||
|
0x00,
|
||||||
|
data, size, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
int LedDeviceLightpack::disableSmoothing()
|
||||||
|
{
|
||||||
|
unsigned char buf[2] = {CMD_SET_SMOOTH_SLOWDOWN, 0};
|
||||||
|
return writeBytes(buf, sizeof(buf)) == sizeof(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
libusb_device_handle * LedDeviceLightpack::openDevice(libusb_device *device)
|
||||||
|
{
|
||||||
|
libusb_device_handle * handle = nullptr;
|
||||||
|
|
||||||
|
int error = libusb_open(device, &handle);
|
||||||
|
if (error != LIBUSB_SUCCESS)
|
||||||
|
{
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = libusb_detach_kernel_driver(handle, LIGHTPACK_INTERFACE);
|
||||||
|
if (error != LIBUSB_SUCCESS)
|
||||||
|
{
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = libusb_claim_interface(handle, LIGHTPACK_INTERFACE);
|
||||||
|
if (error != LIBUSB_SUCCESS)
|
||||||
|
{
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string LedDeviceLightpack::getString(libusb_device * device, int stringDescriptorIndex)
|
||||||
|
{
|
||||||
|
libusb_device_handle * deviceHandle = openDevice(device);
|
||||||
|
|
||||||
|
char buffer[256];
|
||||||
|
int error = libusb_get_string_descriptor_ascii(deviceHandle, stringDescriptorIndex, reinterpret_cast<unsigned char *>(buffer), sizeof(buffer));
|
||||||
|
if (error <= 0)
|
||||||
|
{
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
libusb_close(deviceHandle);
|
||||||
|
return std::string(buffer, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
LedDeviceLightpack::Version LedDeviceLightpack::getVersion(libusb_device *device)
|
||||||
|
{
|
||||||
|
libusb_device_handle * deviceHandle = openDevice(device);
|
||||||
|
|
||||||
|
uint8_t buffer[256];
|
||||||
|
int error = libusb_get_descriptor(deviceHandle, LIBUSB_DT_REPORT, 0, buffer, sizeof(buffer));
|
||||||
|
if (error <= 3)
|
||||||
|
{
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
libusb_close(deviceHandle);
|
||||||
|
return Version{buffer[INDEX_FW_VER_MAJOR], buffer[INDEX_FW_VER_MINOR]};
|
||||||
|
}
|
85
libsrc/hyperion/device/LedDeviceLightpack.h
Normal file
85
libsrc/hyperion/device/LedDeviceLightpack.h
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// stl includes
|
||||||
|
#include <vector>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// libusb include
|
||||||
|
#include <libusb.h>
|
||||||
|
|
||||||
|
// Hyperion includes
|
||||||
|
#include <hyperion/LedDevice.h>
|
||||||
|
|
||||||
|
///
|
||||||
|
/// LedDevice implementation for a lightpack device (http://code.google.com/p/light-pack/)
|
||||||
|
///
|
||||||
|
class LedDeviceLightpack : public LedDevice
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
///
|
||||||
|
/// Constructs the LedDeviceLightpack
|
||||||
|
///
|
||||||
|
LedDeviceLightpack(const std::string & serialNumber = "");
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Destructor of the LedDevice; closes the output device if it is open
|
||||||
|
///
|
||||||
|
virtual ~LedDeviceLightpack();
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Opens and configures the output device7
|
||||||
|
///
|
||||||
|
/// @return Zero on succes else negative
|
||||||
|
///
|
||||||
|
int open();
|
||||||
|
|
||||||
|
int write(const std::vector<ColorRgb>& ledValues);
|
||||||
|
|
||||||
|
int switchOff();
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Version
|
||||||
|
{
|
||||||
|
int majorVersion;
|
||||||
|
int minorVersion;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// write bytes to the device
|
||||||
|
int writeBytes(uint8_t *data, int size);
|
||||||
|
|
||||||
|
/// Disable the internal smoothing on the Lightpack device
|
||||||
|
int disableSmoothing();
|
||||||
|
|
||||||
|
static libusb_device_handle * openDevice(libusb_device * device);
|
||||||
|
static std::string getString(libusb_device * device, int stringDescriptorIndex);
|
||||||
|
static Version getVersion(libusb_device * device);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// libusb context
|
||||||
|
libusb_context * _libusbContext;
|
||||||
|
|
||||||
|
/// libusb device handle
|
||||||
|
libusb_device_handle * _deviceHandle;
|
||||||
|
|
||||||
|
/// harware bus number
|
||||||
|
int _busNumber;
|
||||||
|
|
||||||
|
/// hardware address number
|
||||||
|
int _addressNumber;
|
||||||
|
|
||||||
|
/// device serial number
|
||||||
|
std::string _serialNumber;
|
||||||
|
|
||||||
|
/// firmware version of the device
|
||||||
|
Version _firmwareVersion;
|
||||||
|
|
||||||
|
/// the number of leds of the device
|
||||||
|
int _ledCount;
|
||||||
|
|
||||||
|
/// the number of bits per channel
|
||||||
|
int _bitsPerChannel;
|
||||||
|
|
||||||
|
/// buffer for led data
|
||||||
|
std::vector<uint8_t> _ledBuffer;
|
||||||
|
};
|
@ -10,7 +10,8 @@
|
|||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
#include <utils/RgbImage.h>
|
#include <utils/Image.h>
|
||||||
|
#include <utils/ColorRgb.h>
|
||||||
|
|
||||||
///
|
///
|
||||||
/// FbWriter allows direct access tot the FrameBuffer. It writes and image to the framebuffer,
|
/// FbWriter allows direct access tot the FrameBuffer. It writes and image to the framebuffer,
|
||||||
@ -83,7 +84,7 @@ public:
|
|||||||
///
|
///
|
||||||
/// @param image The RGB Image
|
/// @param image The RGB Image
|
||||||
///
|
///
|
||||||
void writeImage(const RgbImage& image)
|
void writeImage(const Image<ColorRgb>& image)
|
||||||
{
|
{
|
||||||
std::cout << "Writing image [" << image.width() << "x" << image.height() << "]" << std::endl;
|
std::cout << "Writing image [" << image.width() << "x" << image.height() << "]" << std::endl;
|
||||||
|
|
||||||
|
@ -6,7 +6,8 @@
|
|||||||
#include <png.h>
|
#include <png.h>
|
||||||
|
|
||||||
// Utils includes
|
// Utils includes
|
||||||
#include <utils/RgbImage.h>
|
#include <utils/Image.h>
|
||||||
|
#include <utils/ColorRgb.h>
|
||||||
#include <utils/jsonschema/JsonFactory.h>
|
#include <utils/jsonschema/JsonFactory.h>
|
||||||
|
|
||||||
// Raspilight includes
|
// Raspilight includes
|
||||||
@ -15,7 +16,7 @@
|
|||||||
// Local includes
|
// Local includes
|
||||||
#include "FbWriter.h"
|
#include "FbWriter.h"
|
||||||
|
|
||||||
bool read_png(std::string file_name, RgbImage*& rgbImage)
|
bool read_png(std::string file_name, Image<ColorRgb>*& rgbImage)
|
||||||
{
|
{
|
||||||
png_structp png_ptr;
|
png_structp png_ptr;
|
||||||
png_infop info_ptr;
|
png_infop info_ptr;
|
||||||
@ -70,16 +71,16 @@ bool read_png(std::string file_name, RgbImage*& rgbImage)
|
|||||||
png_bytepp row_pointers;
|
png_bytepp row_pointers;
|
||||||
row_pointers = png_get_rows(png_ptr, info_ptr);
|
row_pointers = png_get_rows(png_ptr, info_ptr);
|
||||||
|
|
||||||
rgbImage = new RgbImage(width, height);
|
rgbImage = new Image<ColorRgb>(width, height);
|
||||||
|
|
||||||
for (unsigned iRow=0; iRow<height; ++iRow)
|
for (unsigned iRow=0; iRow<height; ++iRow)
|
||||||
{
|
{
|
||||||
if (color_type == PNG_COLOR_TYPE_RGB)
|
if (color_type == PNG_COLOR_TYPE_RGB)
|
||||||
{
|
{
|
||||||
RgbColor* rowPtr = reinterpret_cast<RgbColor*>(row_pointers[iRow]);
|
ColorRgb* rowPtr = reinterpret_cast<ColorRgb*>(row_pointers[iRow]);
|
||||||
for (unsigned iCol=0; iCol<width; ++iCol)
|
for (unsigned iCol=0; iCol<width; ++iCol)
|
||||||
{
|
{
|
||||||
rgbImage->setPixel(iCol, iRow, rowPtr[iCol]);
|
(*rgbImage)(iCol, iRow) = rowPtr[iCol];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (color_type == PNG_COLOR_TYPE_RGBA)
|
else if (color_type == PNG_COLOR_TYPE_RGBA)
|
||||||
@ -88,7 +89,7 @@ bool read_png(std::string file_name, RgbImage*& rgbImage)
|
|||||||
for (unsigned iCol=0; iCol<width; ++iCol)
|
for (unsigned iCol=0; iCol<width; ++iCol)
|
||||||
{
|
{
|
||||||
const unsigned argbValue = rowPtr[iCol];
|
const unsigned argbValue = rowPtr[iCol];
|
||||||
rgbImage->setPixel(iCol, iRow, {uint8_t((argbValue >> 16) & 0xFF), uint8_t((argbValue >> 8) & 0xFF), uint8_t((argbValue) & 0xFF)});
|
(*rgbImage)(iCol, iRow) = ColorRgb{uint8_t((argbValue >> 16) & 0xFF), uint8_t((argbValue >> 8) & 0xFF), uint8_t((argbValue) & 0xFF)};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -115,7 +116,7 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
const std::string pngFilename = argv[1];
|
const std::string pngFilename = argv[1];
|
||||||
|
|
||||||
RgbImage* image = nullptr;
|
Image<ColorRgb>* image = nullptr;
|
||||||
if (!read_png(pngFilename, image) || image == nullptr)
|
if (!read_png(pngFilename, image) || image == nullptr)
|
||||||
{
|
{
|
||||||
std::cout << "Failed to load image" << std::endl;
|
std::cout << "Failed to load image" << std::endl;
|
||||||
|
Loading…
Reference in New Issue
Block a user