From cb27acbc047003b6c5d36a80358c71c7e8fcfd15 Mon Sep 17 00:00:00 2001 From: Adelin Dobre Date: Mon, 30 Jul 2018 16:14:58 +0300 Subject: [PATCH] APA102: Add string based constructor for LED Strip Signed-off-by: Adelin Dobre Signed-off-by: Mihai Tudor Panu --- src/apa102/apa102.cxx | 155 +++++++++++++++++++++++++++++++++++++++--- src/apa102/apa102.hpp | 9 +++ 2 files changed, 156 insertions(+), 8 deletions(-) diff --git a/src/apa102/apa102.cxx b/src/apa102/apa102.cxx index 46b7323e..79e9d3fc 100644 --- a/src/apa102/apa102.cxx +++ b/src/apa102/apa102.cxx @@ -28,10 +28,16 @@ #include #include +#include "upm_string_parser.hpp" #include "apa102.hpp" using namespace upm; +static bool operator!(mraa::MraaIo &mraaIo) +{ + return mraaIo.getMraaDescriptors() == NULL; +} + APA102::APA102(uint16_t ledCount, uint8_t spiBus, bool batchMode, int8_t csn) : m_ledCount(ledCount), m_batchMode(batchMode) { @@ -71,21 +77,154 @@ APA102::APA102(uint16_t ledCount, uint8_t spiBus, bool batchMode, int8_t csn) } } +APA102::APA102(std::string initStr) : mraaIo(initStr) +{ + mraa::Result res = mraa::SUCCESS; + m_leds = NULL; + m_batchMode = false; + + std::vector upmTokens; + + if(!mraaIo.getLeftoverStr().empty()) { + upmTokens = UpmStringParser::parse(mraaIo.getLeftoverStr()); + } + + std::string::size_type sz, prev_sz;; + for (std::string tok : upmTokens) { + if(tok.substr(0, 9) == "ledCount:") { + m_ledCount = (uint16_t)std::stoi(tok.substr(9), nullptr, 0); + } + if(tok.substr(0, 10) == "batchMode:") { + m_batchMode = std::stoi(tok.substr(10), nullptr, 0); + } + } + + // Optional chip select pin + m_csnPinCtx = NULL; + if(!mraaIo.gpios.empty()) { + m_csnPinCtx = &mraaIo.gpios[0]; + res = m_csnPinCtx->dir(mraa::DIR_OUT); + if (res != mraa::SUCCESS) { + throw std::invalid_argument(std::string(__FUNCTION__) + + ": GPIO failed to set direction"); + } + } + + CSOff(); + // Initialize SPI + if(!mraaIo.spis.empty()) { + m_spi = &mraaIo.spis[0]; + } else { + throw std::invalid_argument(std::string(__FUNCTION__) + + ": mraa_spi_init failed"); + } + + // Initialize LED array + uint16_t endFrameLength = (m_ledCount + 15) / 16; // End frame should be (leds/2) bits + m_frameLength = endFrameLength + (m_ledCount + 1) * 4; + if ((m_leds = (uint8_t*) malloc(m_frameLength))) { + memset(m_leds, 0x00, m_frameLength - 4); // Clear state + memset(&m_leds[m_frameLength - endFrameLength], 0xFF, endFrameLength); // Frame End + + // Need to set the brightness to "0" for each Led + for (int i = 1; i <= m_ledCount; i++) { + m_leds[i * 4] = 224; + } + } else { + throw std::runtime_error(std::string(__FUNCTION__) + + ": Failed to allocate memory for LED Strip"); + } + + + for (std::string tok : upmTokens) { + if(tok.substr(0, 7) == "setLed:") { + uint16_t ledIdx = std::stoul(tok.substr(7), &sz, 0); + tok = tok.substr(7); + prev_sz = sz; + uint8_t brightness = std::stoul(tok.substr(prev_sz + 1), &sz, 0); + tok = tok.substr(prev_sz + 1); + prev_sz = sz; + uint8_t r = std::stoul(tok.substr(prev_sz + 1), &sz, 0); + tok = tok.substr(prev_sz + 1); + prev_sz = sz; + uint8_t g = std::stoul(tok.substr(prev_sz + 1), &sz, 0); + tok = tok.substr(prev_sz + 1); + prev_sz = sz; + uint8_t b = std::stoul(tok.substr(prev_sz + 1), &sz, 0); + setLed(ledIdx, brightness, r, g, b); + } + if(tok.substr(0, 17) == "setLedBrightness:") { + uint16_t ledIdx = std::stoul(tok.substr(17), &sz, 0); + tok = tok.substr(17); + uint8_t brightness = std::stoul(tok.substr(sz + 1), nullptr, 0); + setLedBrightness(ledIdx, brightness); + } + if(tok.substr(0, 11) == "setAllLeds:") { + uint16_t brightness = std::stoul(tok.substr(11), &sz, 0); + tok = tok.substr(11); + prev_sz = sz; + uint8_t r = std::stoul(tok.substr(prev_sz + 1), &sz, 0); + tok = tok.substr(prev_sz + 1); + prev_sz = sz; + uint8_t g = std::stoul(tok.substr(prev_sz + 1), &sz, 0); + tok = tok.substr(prev_sz + 1); + prev_sz = sz; + uint8_t b = std::stoul(tok.substr(prev_sz + 1), &sz, 0); + setAllLeds(brightness, r, g, b); + } + if(tok.substr(0, 8) == "setLeds:") { + uint16_t startIdx = std::stoul(tok.substr(8), &sz, 0); + tok = tok.substr(8); + prev_sz = sz; + uint16_t endIdx = std::stoul(tok.substr(prev_sz + 1), &sz, 0); + tok = tok.substr(prev_sz + 1); + prev_sz = sz; + uint8_t brightness = std::stoul(tok.substr(prev_sz + 1), &sz, 0); + tok = tok.substr(prev_sz + 1); + prev_sz = sz; + uint8_t r = std::stoul(tok.substr(prev_sz + 1), &sz, 0); + tok = tok.substr(prev_sz + 1); + prev_sz = sz; + uint8_t g = std::stoul(tok.substr(prev_sz + 1), &sz, 0); + tok = tok.substr(prev_sz + 1); + prev_sz = sz; + uint8_t b = std::stoul(tok.substr(prev_sz + 1), &sz, 0); + setLeds(startIdx, endIdx, brightness, r, g, b); + } + if(tok.substr(0, 18) == "setLedsBrightness:") { + uint16_t startIdx = std::stoul(tok.substr(18), &sz, 0); + tok = tok.substr(18); + prev_sz = sz; + uint16_t endIdx = std::stoul(tok.substr(prev_sz + 1), &sz, 0); + tok = tok.substr(prev_sz + 1); + prev_sz = sz; + uint8_t brightness = std::stoul(tok.substr(prev_sz + 1), &sz, 0); + setLedsBrightness(startIdx, endIdx, brightness); + } + if(tok.substr(0, 12) == "setBusSpeed:") { + int hz = std::stoi(tok.substr(12), nullptr, 0); + setBusSpeed(hz); + } + } +} + + APA102::~APA102() { // Clear leds if (m_leds) { free(m_leds); } + if(!mraaIo) { + // Clear SPI + if (m_spi) { + delete m_spi; + } - // Clear SPI - if (m_spi) { - delete m_spi; - } - - // Clear GPIO - if (m_csnPinCtx) { - delete m_csnPinCtx; + // Clear GPIO + if (m_csnPinCtx) { + delete m_csnPinCtx; + } } } diff --git a/src/apa102/apa102.hpp b/src/apa102/apa102.hpp index 2adf4790..85d7f955 100644 --- a/src/apa102/apa102.hpp +++ b/src/apa102/apa102.hpp @@ -25,6 +25,7 @@ #include #include +#include #include #define HIGH 1 @@ -69,6 +70,13 @@ class APA102 */ APA102(uint16_t ledCount, uint8_t spiBus, bool batchMode = false, int8_t csn = -1); + /** + * Instantiates APA102 RGB LED Strip based on a given string. + * + * @param initStr string containing specific information for APA102 RGB LED Strip initialization. + */ + APA102(std::string initStr); + /** * APA102 destructor */ @@ -160,6 +168,7 @@ class APA102 APA102(const APA102&) = delete; APA102 &operator=(const APA102&) = delete; + mraa::MraaIo mraaIo; mraa::Spi* m_spi; mraa::Gpio* m_csnPinCtx;