This library controls a strip of apa102 lights. It is heavily based on https://developer.mbed.org/users/wertyfrog/code/ws2801/ and is a little messy looking since my coding style does not match Mr Olsson's. It should work the same as Olsson's lib, and I'm definitely going to add more dox later.
Revision 0:cd4bcb59e36e, committed 2015-01-27
- Comitter:
- AlanRager
- Date:
- Tue Jan 27 17:33:01 2015 +0000
- Commit message:
- First commit - this is heavily based on the ws2801 found here: https://developer.mbed.org/users/wertyfrog/code/ws2801/
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/apa102.cpp Tue Jan 27 17:33:01 2015 +0000 @@ -0,0 +1,80 @@ +#include "apa102.h" +#include "mbed.h" + +#define DO_N(N, F) for( int repetier = 0; repetier < N; repetier++) { F; } + +//------------------------------------------------------------------------------------------------------------ +apa102::apa102(PinName CKI, PinName SDI, int STRIP_LENGTH, int reset_delay) +: _CKI(CKI), _SDI(SDI), _STRIP_LENGTH(STRIP_LENGTH), _reset_delay(reset_delay) { + + _level=100; + this->clear(); + wait_us(_reset_delay); +} +//------------------------------------------------------------------------------------------------------------ +void apa102::post(int *strip_colors) { + this->preamble(); + + int scaled_level = 0xE0 | (_level * 31 / 100); + + for(int LED_number = 0 ; LED_number < _STRIP_LENGTH ; LED_number++) { + this->write_word(scaled_level, 8); + this->write_word(strip_colors[LED_number], 24); + } + + this->afterword(); + wait_us(_reset_delay); //Wait for 1ms to go into reset +} +//------------------------------------------------------------------------------------------------------------ +void apa102::clear(void) { + this->preamble(); + DO_N(_STRIP_LENGTH, this->write_word(0xE0000000, 32)); + this->afterword(); +} +//------------------------------------------------------------------------------------------------------------ +int apa102::level(int level) +{ +if((level <= 100) && level) + { + _level = level; + return _level; + } +return 0; +} + +//------------------------------------------------------------------------------------------------------------ +int apa102::delay(uint32_t reset_delay) +{ +if(reset_delay <= 0xffffffff)_reset_delay = reset_delay; +return _reset_delay; +} +//------------------------------------------------------------------------------------------------------------ +inline void apa102::write_hi() { + this->write_bit(1); +} +inline void apa102::write_lo() { + this->write_bit(0); +} +inline void apa102::write_bit(bool bit) { + _CKI = 0; + _SDI = bit; + _CKI = 1; +} +inline void apa102::write_word(uint32_t word, int bits) { + for(char color_bit = bits - 1 ; color_bit != 255 ; color_bit--) { + this->write_bit( + (word & (1 << color_bit)) ? 1 : 0 + ); + } +} +inline void apa102::write_done() { + _CKI = 0; +} +inline void apa102::preamble() { + DO_N(32, this->write_lo()); +} +inline void apa102::afterword() { + DO_N(32, this->write_hi()); + this->write_done(); +} +//---------EOF---------------EOF------------------------------------------------------------------------------ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/apa102.h Tue Jan 27 17:33:01 2015 +0000 @@ -0,0 +1,145 @@ + /* +Copyright (c) 2011 Thomas Olsson. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifndef APA102_H +#define APA102_H + +#include "mbed.h" +#include "HTML_color.h" + +#define APA102_MAX_LEVEL 100 + +/** APA102 class, controlling LED strips or arrays like this http://www.sparkfun.com/products/10312 +* +* the APA102 IC's are 5V but works well connected directly to mbed IO pins. +* +* You need a 5V power supply capable of about 2A to light up a 32 led strip, do NOT power from mbed(usb). +* +* the required reset delay is a blocking wait(), it can be lowered (or set to 0) if you want to use the +* time for executing code instead, data sheet says 500us but i found it need at least 800us. +* +* Example: +* @code +#include "mbed.h" +#include "apa102.h" + +#define STRIP_LENGTH 32 + +apa102 mystrip(p9, p10, STRIP_LENGTH); + +int dir=1, level=10; +int rainbow[] = {0xff00ff,0xff00cc,0xff0099,0xff0066,0xff0033,0xff0000,0xff3300,0xff6600, + 0xff9900,0xffcc00,0xffff00,0xccff00,0x99ff00,0x66ff00,0x33ff00,0x00ff00, + 0x00ff33,0x00ff66,0x00ff99,0x00ffcc,0x00ffff,0x00ccff,0x0099ff,0x0066ff, + 0x0033ff,0x0000ff,0x3300ff,0x6600ff,0x9900ff,0xcc00ff,0x9900ff,0x6600ff + }; + +void move(void){ + int temp = rainbow[31]; + for (int x = (STRIP_LENGTH - 1) ; x > 0 ; x--) rainbow[x] = rainbow[x - 1]; + rainbow[0] = temp; +} + +void pulse(void){ + if(dir) + { + mystrip.level(level+=2); + if(level >= 100)dir = 0; + } + else if(!dir) + { + mystrip.level(level--); + if(level <= 5)dir = 1; + } +} + +int main() { + mystrip.level(level); + while(1) + { + move(); + pulse(); + mystrip.post(rainbow); + wait_ms(100); + } +} +* @endcode + */ +class apa102 +{ +public: + /** Create a new apa102 object + * + * + * @param CKI clock pin + * @param SDI data pin + * @param STRIP_LENGTH number of apa102 IC's i strip or array defaults to 32 + * @param reset_delay delay in us to allow latching data defaults to 800 + * @returns nothing + */ + apa102(PinName CKI, PinName SDI, int STRIP_LENGTH = 32, int reset_delay = 800); + /** write RGB color data to strip or array + * + * color data for each LED is 3 bytes int the order of rrggbb. + * array must have STRIP_LENGTH number of elements + * + * @param strip_colors array of color data + */ + void post(int *strip_colors); + /** clears the array or strip (all off) + */ + void clear(void); + /** set level of the entire array 0-100% + * + * at low levels the colors may change because R,G or B + * reaches 0. + * + * @param level level in percent + * @returns current level + */ + int level(int level=0); + /** get/set reset/write delay + * + * mainly for experimenting with reset values without recompiling, + * leave at default to begin with & then lower to get faster execution. + * + * @param delay delay in us + * @returns delay in us + */ + int delay(uint32_t reset_delay=100); + +private: + DigitalOut _CKI; + DigitalOut _SDI; + int _STRIP_LENGTH; + int _level; + int _reset_delay; + inline void write_hi(); + inline void write_lo(); + inline void write_bit(bool bit); + inline void write_word(uint32_t word, int bits = 32); + inline void write_done(); + inline void preamble(); + inline void afterword(); +}; + +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Tue Jan 27 17:33:01 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/4fc01daae5a5 \ No newline at end of file