Skip to content

Commit

Permalink
Implement ftdi apa102 device
Browse files Browse the repository at this point in the history
  • Loading branch information
nurikk-sa committed Feb 25, 2023
1 parent de9cffa commit 097f613
Show file tree
Hide file tree
Showing 9 changed files with 496 additions and 2 deletions.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ SET ( DEFAULT_BONJOUR ON )
SET ( DEFAULT_MQTT ON )
SET ( DEFAULT_STATIC_QT_PLUGINS OFF )
SET ( DEFAULT_PRECOMPILED_HEADERS ON )
SET ( DEFAULT_ENABLE_FTDIDEV OFF )

# Configure CCache if available
find_program(CCACHE_FOUND ccache)
Expand Down Expand Up @@ -326,6 +327,9 @@ colorMe("ENABLE_SPIDEV = " ${ENABLE_SPIDEV})
option(ENABLE_WS281XPWM "Enable the WS281x-PWM device" ${DEFAULT_WS281XPWM} )
colorMe("ENABLE_WS281XPWM = " ${ENABLE_WS281XPWM})

option(ENABLE_FTDIDEV "Enable the FTDI device" ${DEFAULT_ENABLE_FTDIDEV})
colorMe("ENABLE_FTDIDEV = " ${ENABLE_FTDIDEV})

message( STATUS "\n${CyanColor}SOFTWARE GRABBERS${ColorReset}")

option(ENABLE_DX "Enable Windows DirectX 11 system grabber" ${DEFAULT_DX})
Expand Down
24 changes: 24 additions & 0 deletions sources/leddevice/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ include_directories(
dev_spi
dev_rpi_pwm
dev_tinker
dev_ftdi
)

FILE ( GLOB Leddevice_SOURCES
Expand All @@ -43,6 +44,10 @@ if ( ENABLE_SPIDEV )
FILE ( GLOB Leddevice_SPI_SOURCES "${CURRENT_SOURCE_DIR}/dev_spi/*.h" "${CURRENT_SOURCE_DIR}/dev_spi/*.cpp")
endif()

if (ENABLE_FTDIDEV)
FILE ( GLOB Leddevice_FTDI_SOURCES "${CURRENT_SOURCE_DIR}/dev_ftdi/*.h" "${CURRENT_SOURCE_DIR}/dev_ftdi/*.cpp")
endif()

if ( ENABLE_WS281XPWM )
include_directories(../../dependencies/external/rpi_ws281x)
FILE ( GLOB Leddevice_PWM_SOURCES "${CURRENT_SOURCE_DIR}/dev_rpi_pwm/*.h" "${CURRENT_SOURCE_DIR}/dev_rpi_pwm/*.cpp")
Expand All @@ -58,6 +63,7 @@ SET( Leddevice_SOURCES
${Leddevice_TINKER_SOURCES}
${Leddevice_SPI_SOURCES}
${Leddevice_PWM_SOURCES}
${Leddevice_FTDI_SOURCES}
)

# auto generate header file that include all available leddevice headers
Expand Down Expand Up @@ -124,3 +130,21 @@ endif()
if(USE_PRECOMPILED_HEADERS AND COMMAND target_precompile_headers)
target_precompile_headers(leddevice REUSE_FROM precompiled_hyperhdr_headers)
endif()


# if(ENABLE_WS281XPWM)
# add_library(ws281x
# ${CMAKE_CURRENT_SOURCE_DIR}/external/rpi_ws281x/mailbox.c ${CMAKE_CURRENT_SOURCE_DIR}/external/rpi_ws281x/ws2811.c
# ${CMAKE_CURRENT_SOURCE_DIR}/external/rpi_ws281x/pwm.c ${CMAKE_CURRENT_SOURCE_DIR}/external/rpi_ws281x/dma.c
# ${CMAKE_CURRENT_SOURCE_DIR}/external/rpi_ws281x/pcm.c
# ${CMAKE_CURRENT_SOURCE_DIR}/external/rpi_ws281x/rpihw.c)
# endif()


if( ENABLE_FTDIDEV )
FIND_PACKAGE(PkgConfig REQUIRED)
pkg_check_modules(LIB_FTDI REQUIRED libftdi1)
add_library(libftdi1 SHARED IMPORTED)
target_include_directories(leddevice PUBLIC ${LIB_FTDI_INCLUDE_DIRS})
target_link_libraries(leddevice ${LIB_FTDI_LINK_LIBRARIES})
endif()
2 changes: 0 additions & 2 deletions sources/leddevice/LedDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@ void LedDevice::start()
{
Info(_log, "Start LedDevice '%s'.", QSTRING_CSTR(_activeDeviceType));

close();

_isDeviceInitialised = false;
// General initialisation and configuration of LedDevice
if (init(_devConfig))
Expand Down
1 change: 1 addition & 0 deletions sources/leddevice/LedDeviceSchemas.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,6 @@
<file alias="schema-yeelight">schemas/schema-yeelight.json</file>
<file alias="schema-cololight">schemas/schema-cololight.json</file>
<file alias="schema-awa_spi">schemas/schema-awa_spi.json</file>
<file alias="schema-apa102_ftdi">schemas/schema-apa102_ftdi.json</file>
</qresource>
</RCC>
62 changes: 62 additions & 0 deletions sources/leddevice/dev_ftdi/LedDeviceAPA102_ftdi.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#include "LedDeviceAPA102_ftdi.h"


LedDeviceAPA102_ftdi::LedDeviceAPA102_ftdi(const QJsonObject &deviceConfig) : ProviderFtdi(deviceConfig)
{
}

LedDevice *LedDeviceAPA102_ftdi::construct(const QJsonObject &deviceConfig)
{
return new LedDeviceAPA102_ftdi(deviceConfig);
}

bool LedDeviceAPA102_ftdi::init(const QJsonObject &deviceConfig)
{
bool isInitOK = false;

// Initialise sub-class
if (ProviderFtdi::init(deviceConfig))
{
CreateHeader();
isInitOK = true;
}
return isInitOK;
}

void LedDeviceAPA102_ftdi::CreateHeader()
{
const unsigned int startFrameSize = 4;
const unsigned int endFrameSize = qMax<unsigned int>(((_ledCount + 15) / 16), 4);
const unsigned int APAbufferSize = (_ledCount * 4) + startFrameSize + endFrameSize;

_ledBuffer.resize(0, 0xFF);
_ledBuffer.resize(APAbufferSize, 0xFF);
_ledBuffer[0] = 0x00;
_ledBuffer[1] = 0x00;
_ledBuffer[2] = 0x00;
_ledBuffer[3] = 0x00;

Debug(_log, "APA102 buffer created. Led's number: %d", _ledCount);
}

int LedDeviceAPA102_ftdi::write(const std::vector<ColorRgb> &ledValues)
{
if (_ledCount != ledValues.size())
{
Warning(_log, "APA102 led's number has changed (old: %d, new: %d). Rebuilding buffer.", _ledCount, ledValues.size());
_ledCount = ledValues.size();

CreateHeader();
}

for (signed iLed = 0; iLed < static_cast<int>(_ledCount); ++iLed)
{
const ColorRgb &rgb = ledValues[iLed];
_ledBuffer[4 + iLed * 4 + 0] = 0xFF;
_ledBuffer[4 + iLed * 4 + 1] = rgb.red;
_ledBuffer[4 + iLed * 4 + 2] = rgb.green;
_ledBuffer[4 + iLed * 4 + 3] = rgb.blue;
}

return writeBytes(_ledBuffer.size(), _ledBuffer.data());
}
47 changes: 47 additions & 0 deletions sources/leddevice/dev_ftdi/LedDeviceAPA102_ftdi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#ifndef LEDEVICET_APA102_H
#define LEDEVICET_APA102_H
#include "ProviderFtdi.h"

class LedDeviceAPA102_ftdi : public ProviderFtdi
{
Q_OBJECT

public:

///
/// @brief Constructs an APA102 LED-device
///
/// @param deviceConfig Device's configuration as JSON-Object
///
explicit LedDeviceAPA102_ftdi(const QJsonObject& deviceConfig);

///
/// @brief Constructs the LED-device
///
/// @param[in] deviceConfig Device's configuration as JSON-Object
/// @return LedDevice constructed
static LedDevice* construct(const QJsonObject& deviceConfig);

private:

///
/// @brief Initialise the device's configuration
///
/// @param[in] deviceConfig the JSON device configuration
/// @return True, if success
///
bool init(const QJsonObject& deviceConfig) override;

void CreateHeader();

///
/// @brief Writes the RGB-Color values to the LEDs.
///
/// @param[in] ledValues The RGB-color per LED
/// @return Zero on success, else negative
///
int write(const std::vector<ColorRgb>& ledValues) override;

};

#endif // LEDEVICET_APA102_H
Loading

0 comments on commit 097f613

Please sign in to comment.