From 2d2ee8d1f0cf3155cb561d59b028f2d2cc40103c Mon Sep 17 00:00:00 2001 From: Mihai Tudor Panu Date: Thu, 25 Aug 2016 17:33:41 -0700 Subject: [PATCH] apa102: added extra functionality Exposed call to MRAA SPI frequency for those super long strips where the clock signal will degrade and introduce glitches. Slowing down will fix it without the need for extra filtering or redrivers. Batch mode also helps since only one write per frame will be required. Added functions that control brightness only for fade effects without the need to keep an extra copy of the pixel color map. Signed-off-by: Mihai Tudor Panu --- src/apa102/apa102.cxx | 30 ++++++++++++++++++++++++++++++ src/apa102/apa102.hpp | 35 +++++++++++++++++++++++++++++++---- 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/src/apa102/apa102.cxx b/src/apa102/apa102.cxx index a43004a9..264c7418 100644 --- a/src/apa102/apa102.cxx +++ b/src/apa102/apa102.cxx @@ -96,6 +96,12 @@ APA102::setLed(uint16_t ledIdx, uint8_t brightness, uint8_t r, uint8_t g, uint8_ setLeds(ledIdx, ledIdx, brightness, r, g, b); } +void +APA102::setLedBrightness(uint16_t ledIdx, uint8_t brightness) +{ + setLedsBrightness(ledIdx, ledIdx, brightness); +} + void APA102::setAllLeds(uint8_t brightness, uint8_t r, uint8_t g, uint8_t b) { @@ -120,6 +126,21 @@ APA102::setLeds(uint16_t startIdx, uint16_t endIdx, uint8_t brightness, uint8_t } } +void +APA102::setLedsBrightness(uint16_t startIdx, uint16_t endIdx, uint8_t brightness) +{ + uint16_t s_idx = (startIdx + 1) * 4; + uint16_t e_idx = (endIdx + 1) * 4; + + for (uint16_t i = s_idx; i <= e_idx; i += 4) { + m_leds[i] = brightness | 224; + } + + if (!m_batchMode) { + pushState(); + } +} + void APA102::setLeds(uint16_t startIdx, uint16_t endIdx, uint8_t* colors) { @@ -131,6 +152,15 @@ APA102::setLeds(uint16_t startIdx, uint16_t endIdx, uint8_t* colors) } } +void +APA102::setBusSpeed(int hz) +{ + if (m_spi->frequency(hz) != mraa::SUCCESS) { + throw std::runtime_error(std::string(__FUNCTION__) + + ": Failed to change SPI bus speed"); + } +} + void APA102::pushState(void) { diff --git a/src/apa102/apa102.hpp b/src/apa102/apa102.hpp index 34033e8b..24437306 100644 --- a/src/apa102/apa102.hpp +++ b/src/apa102/apa102.hpp @@ -74,7 +74,7 @@ class APA102 ~APA102(); /** - * Change the color for a single led + * Change the color and brightness for a single led * * @param ledIdx Index of the LED in the strip (0 based) * @param brightness Brightness value (0-31) @@ -85,7 +85,15 @@ class APA102 void setLed(uint16_t ledIdx, uint8_t brightness, uint8_t r, uint8_t g, uint8_t b); /** - * Change the color for all leds + * Change the brightness for a single led + * + * @param ledIdx Index of the LED in the strip (0 based) + * @param brightness Brightness value (0-31) + */ + void setLedBrightness(uint16_t ledIdx, uint8_t brightness); + + /** + * Change the color and brightness for all leds * * @param brightness Brightness value (0-31) * @param r Red component (0-255) @@ -95,7 +103,7 @@ class APA102 void setAllLeds(uint8_t brightness, uint8_t r, uint8_t g, uint8_t b); /** - * Change the color for a range of leds + * Change the color and brightness for a range of leds * * @param startIdx Start index of the range of LEDs in the strip (0 based) * @param endIdx End index of the range of LEDs in the strip (0 based) @@ -108,7 +116,17 @@ class APA102 setLeds(uint16_t startIdx, uint16_t endIdx, uint8_t brightness, uint8_t r, uint8_t g, uint8_t b); /** - * (Advanced) Manually control the colors of a range of LEDS + * Change the brightness for a range of leds + * + * @param startIdx Start index of the range of LEDs in the strip (0 based) + * @param endIdx End index of the range of LEDs in the strip (0 based) + * @param brightness Brightness value (0-31) + */ + void + setLedsBrightness(uint16_t startIdx, uint16_t endIdx, uint8_t brightness); + + /** + * (Advanced) Manually control the colors and brightness of a range of LEDS * Best used to maximize performance * * @param startIdx Start index of the range of LEDs to update (0 based) @@ -120,6 +138,15 @@ class APA102 */ void setLeds(uint16_t startIdx, uint16_t endIdx, uint8_t* colors); + /** + * Change the speed/frequency of the SPI bus + * Note: Slower speeds will allow driving longer strips without having to + * condition the clock signal with extra hardware + * + * @param hz Desired bus speed in Hz + */ + void setBusSpeed(int hz); + /** * Outputs the current LED data to the SPI bus * Note: Only required if batch mode is set to TRUE