Created first implementation of SPI-dev abstraction and added Ldp6803 as derived led device.

Former-commit-id: 4701ed1ffe72accf3be818c73b95fb025c72149e
This commit is contained in:
T. van der Zwan 2013-11-01 22:48:39 +00:00
parent 3e4c38b57a
commit f158236910
7 changed files with 238 additions and 71 deletions

View File

@ -20,8 +20,10 @@ SET(Hyperion_HEADERS
${CURRENT_SOURCE_DIR}/BlackBorderDetector.h ${CURRENT_SOURCE_DIR}/BlackBorderDetector.h
${CURRENT_SOURCE_DIR}/BlackBorderProcessor.h ${CURRENT_SOURCE_DIR}/BlackBorderProcessor.h
${CURRENT_SOURCE_DIR}/ImageToLedsMap.h ${CURRENT_SOURCE_DIR}/ImageToLedsMap.h
${CURRENT_SOURCE_DIR}/LedSpiDevice.h
${CURRENT_SOURCE_DIR}/LedDeviceTest.h ${CURRENT_SOURCE_DIR}/LedDeviceTest.h
${CURRENT_SOURCE_DIR}/LedDeviceWs2801.h ${CURRENT_SOURCE_DIR}/LedDeviceWs2801.h
${CURRENT_SOURCE_DIR}/LedDeviceLdp6803.h
) )
SET(Hyperion_SOURCES SET(Hyperion_SOURCES
@ -34,8 +36,10 @@ SET(Hyperion_SOURCES
${CURRENT_SOURCE_DIR}/BlackBorderDetector.cpp ${CURRENT_SOURCE_DIR}/BlackBorderDetector.cpp
${CURRENT_SOURCE_DIR}/BlackBorderProcessor.cpp ${CURRENT_SOURCE_DIR}/BlackBorderProcessor.cpp
${CURRENT_SOURCE_DIR}/ImageToLedsMap.cpp ${CURRENT_SOURCE_DIR}/ImageToLedsMap.cpp
${CURRENT_SOURCE_DIR}/LedDeviceWs2801.cpp ${CURRENT_SOURCE_DIR}/LedSpiDevice.cpp
${CURRENT_SOURCE_DIR}/LedDeviceTest.cpp ${CURRENT_SOURCE_DIR}/LedDeviceTest.cpp
${CURRENT_SOURCE_DIR}/LedDeviceWs2801.cpp
${CURRENT_SOURCE_DIR}/LedDeviceLdp6803.cpp
${CURRENT_SOURCE_DIR}/LinearColorSmoothing.cpp ${CURRENT_SOURCE_DIR}/LinearColorSmoothing.cpp
) )

View File

@ -0,0 +1,89 @@
// STL includes
#include <cstring>
#include <cstdio>
#include <iostream>
// Linux includes
#include <fcntl.h>
#include <sys/ioctl.h>
// hyperion local includes
#include "LedDeviceLdp6803.h"
LedDeviceLDP6803::LedDeviceLDP6803(const std::string& outputDevice, const unsigned baudrate) :
LedSpiDevice(outputDevice, baudrate),
mLedCount(0)
{
latchTime.tv_sec = 0;
latchTime.tv_nsec = 500000;
}
int LedDeviceLDP6803::write(const std::vector<RgbColor> &ledValues)
{
mLedCount = ledValues.size();
// Define buffer sizes based on number of leds
// buffsize for actual buffer to be sent via SPI pins
// tempbuffsize for RGB data processing.
// buffsize = 4 zero bytes + 2 bytes per LED
// tempbuffsize will hold RGB values, so 3 bytes per LED
int buffsize = (mLedCount * 2) + 4;
int tempbuffsize = mLedCount *3;
int i,r,g,b,d,count;
uint8_t m_buff[buffsize];
const uint8_t *temp_buff;//[tempbuffsize];
if (mFid < 0)
{
std::cerr << "Can not write to device which is open." << std::endl;
return -1;
}
temp_buff = reinterpret_cast<const uint8_t*>(ledValues.data());
// set first 4 bytes to zero
m_buff[0]=0;
m_buff[1]=0;
m_buff[2]=0;
m_buff[3]=0;
// Set counter
count=4;
// Now process RGB values: 0-255 to be
// converted to 0-31, with bits combined
// to match hardware protocol
for (i=0 ; i < tempbuffsize ; i+=3) {
r = temp_buff[i] >> 3;
g = temp_buff[i+1] >> 3;
b = temp_buff[i+2] >> 3;
d = (r * 1024) + (g * 32) + b + 32768;
m_buff[count] = d >> 8;
m_buff[count+1] = d & 0x00FF;
count += 2;
}
spi.tx_buf = __u64(m_buff);
spi.len = buffsize;
int retVal = ioctl(mFid, SPI_IOC_MESSAGE(1), &spi);
if (retVal == 0)
{
// Sleep to latch the leds (only if write succesfull)
nanosleep(&latchTime, NULL);
}
return retVal;
}
int LedDeviceLDP6803::switchOff()
{
return write(std::vector<RgbColor>(mLedCount, RgbColor::BLACK));
}

View File

@ -0,0 +1,37 @@
#pragma once
// Local hyperion incluse
#include "LedSpiDevice.h"
///
/// Implementation of the LedDevice interface for writing to LDP6803 led device.
///
class LedDeviceLDP6803 : public LedSpiDevice
{
public:
///
/// Constructs the LedDevice for a string containing leds of the type LDP6803
///
/// @param[in] outputDevice The name of the output device (eg '/etc/SpiDev.0.0')
/// @param[in] baudrate The used baudrate for writing to the output device
///
LedDeviceLDP6803(const std::string& outputDevice, const unsigned baudrate);
///
/// Writes the led color values to the led-device
///
/// @param ledValues The color-value per led
/// @return Zero on succes else negative
///
virtual int write(const std::vector<RgbColor> &ledValues);
/// Switch the leds off
virtual int switchOff();
private:
/// The 'latch' time for latching the shifted-value into the leds
timespec latchTime;
/// the number of leds (needed when switching off)
size_t mLedCount;
};

View File

@ -11,54 +11,12 @@
// hyperion local includes // hyperion local includes
#include "LedDeviceWs2801.h" #include "LedDeviceWs2801.h"
LedDeviceWs2801::LedDeviceWs2801(const std::string& outputDevice, LedDeviceWs2801::LedDeviceWs2801(const std::string& outputDevice, const unsigned baudrate) :
const unsigned baudrate) : LedSpiDevice(outputDevice, baudrate),
mDeviceName(outputDevice),
mBaudRate_Hz(baudrate),
mFid(-1),
mLedCount(0) mLedCount(0)
{ {
memset(&spi, 0, sizeof(spi));
latchTime.tv_sec = 0; latchTime.tv_sec = 0;
latchTime.tv_nsec = 500000; latchTime.tv_nsec = 500000;
}
LedDeviceWs2801::~LedDeviceWs2801()
{
// close(mFid);
}
int LedDeviceWs2801::open()
{
const int bitsPerWord = 8;
mFid = ::open(mDeviceName.c_str(), O_RDWR);
if (mFid < 0)
{
std::cerr << "Failed to open device('" << mDeviceName << "') " << std::endl;
return -1;
}
int mode = SPI_MODE_0;
if (ioctl(mFid, SPI_IOC_WR_MODE, &mode) == -1 || ioctl(mFid, SPI_IOC_RD_MODE, &mode) == -1)
{
return -2;
}
if (ioctl(mFid, SPI_IOC_WR_BITS_PER_WORD, &bitsPerWord) == -1 || ioctl(mFid, SPI_IOC_RD_BITS_PER_WORD, &bitsPerWord) == -1)
{
return -4;
}
if (ioctl(mFid, SPI_IOC_WR_MAX_SPEED_HZ, &mBaudRate_Hz) == -1 || ioctl(mFid, SPI_IOC_RD_MAX_SPEED_HZ, &mBaudRate_Hz) == -1)
{
return -6;
}
return 0;
} }
int LedDeviceWs2801::write(const std::vector<RgbColor> &ledValues) int LedDeviceWs2801::write(const std::vector<RgbColor> &ledValues)

View File

@ -3,16 +3,13 @@
// STL includes // STL includes
#include <string> #include <string>
// Linux-SPI includes
#include <linux/spi/spidev.h>
// hyperion incluse // hyperion incluse
#include <hyperion/LedDevice.h> #include "LedSpiDevice.h"
/// ///
/// Implementation of the LedDevice interface for writing to Ws2801 led device. /// Implementation of the LedDevice interface for writing to Ws2801 led device.
/// ///
class LedDeviceWs2801 : public LedDevice class LedDeviceWs2801 : public LedSpiDevice
{ {
public: public:
/// ///
@ -24,18 +21,6 @@ public:
LedDeviceWs2801(const std::string& outputDevice, LedDeviceWs2801(const std::string& outputDevice,
const unsigned baudrate); const unsigned baudrate);
///
/// Destructor of the LedDevice; closes the output device if it is open
///
virtual ~LedDeviceWs2801();
///
/// Opens and configures the output device
///
/// @return Zero on succes else negative
///
int open();
/// ///
/// Writes the led color values to the led-device /// Writes the led color values to the led-device
/// ///
@ -48,15 +33,6 @@ public:
virtual int switchOff(); virtual int switchOff();
private: private:
/// The name of the output device
const std::string mDeviceName;
/// The used baudrate of the output device
const int mBaudRate_Hz;
/// The File Identifier of the opened output device (or -1 if not opened)
int mFid;
/// The transfer structure for writing to the spi-device
spi_ioc_transfer spi;
/// The 'latch' time for latching the shifted-value into the leds /// The 'latch' time for latching the shifted-value into the leds
timespec latchTime; timespec latchTime;

View File

@ -0,0 +1,57 @@
// STL includes
#include <cstring>
#include <cstdio>
#include <iostream>
// Linux includes
#include <fcntl.h>
#include <sys/ioctl.h>
// Local Hyperion includes
#include "LedSpiDevice.h"
LedSpiDevice::LedSpiDevice(const std::string& outputDevice, const unsigned baudrate) :
mDeviceName(outputDevice),
mBaudRate_Hz(baudrate),
mFid(-1)
{
memset(&spi, 0, sizeof(spi));
}
LedSpiDevice::~LedSpiDevice()
{
// close(mFid);
}
int LedSpiDevice::open()
{
const int bitsPerWord = 8;
mFid = ::open(mDeviceName.c_str(), O_RDWR);
if (mFid < 0)
{
std::cerr << "Failed to open device('" << mDeviceName << "') " << std::endl;
return -1;
}
int mode = SPI_MODE_0;
if (ioctl(mFid, SPI_IOC_WR_MODE, &mode) == -1 || ioctl(mFid, SPI_IOC_RD_MODE, &mode) == -1)
{
return -2;
}
if (ioctl(mFid, SPI_IOC_WR_BITS_PER_WORD, &bitsPerWord) == -1 || ioctl(mFid, SPI_IOC_RD_BITS_PER_WORD, &bitsPerWord) == -1)
{
return -4;
}
if (ioctl(mFid, SPI_IOC_WR_MAX_SPEED_HZ, &mBaudRate_Hz) == -1 || ioctl(mFid, SPI_IOC_RD_MAX_SPEED_HZ, &mBaudRate_Hz) == -1)
{
return -6;
}
return 0;
}

View File

@ -0,0 +1,46 @@
#pragma once
// Linux-SPI includes
#include <linux/spi/spidev.h>
// Hyperion includes
#include <hyperion/LedDevice.h>
///
/// The LedSpiDevice implements an abstract base-class for LedDevices using the SPI-device.
///
class LedSpiDevice : public LedDevice
{
public:
///
/// Constructs the LedDevice attached to a SPI-device
///
/// @param[in] outputDevice The name of the output device (eg '/etc/SpiDev.0.0')
/// @param[in] baudrate The used baudrate for writing to the output device
///
LedSpiDevice(const std::string& outputDevice, const unsigned baudrate);
///
/// Destructor of the LedDevice; closes the output device if it is open
///
virtual ~LedSpiDevice();
///
/// Opens and configures the output device
///
/// @return Zero on succes else negative
///
int open();
private:
/// The name of the output device
const std::string mDeviceName;
/// The used baudrate of the output device
const int mBaudRate_Hz;
protected:
/// The File Identifier of the opened output device (or -1 if not opened)
int mFid;
/// The transfer structure for writing to the spi-device
spi_ioc_transfer spi;
};