This is a library for the DIGI-DOT-BOOSTER which can control LED stripes using the single wire protocol - ws2812 and compatible as well as RGBW LEDs like SK6812. Detailed information including the datasheet and protocol description are available here: http://www.led-genial.de/DIGI-DOT-Booster-WS2812-und-SK6812-ueber-SPI-Schnittstelle-ansteuern DIGI-DOT-BOOSTER acts as a SPI slave and waits for commands sent by a SPI master. This Library provides an easy to use abstraction layer for commands supported by the DD-Booster and adds some additional effects.
Dependents: DD-Booster-waterdrop BLE_DD-Booster
DDBooster.cpp
00001 /* 00002 * DDBoster.cpp - Library to control the Digi-Dot-Booster using a high-level API 00003 * 00004 * https://github.com/Gamadril/DD-Booster-mbed 00005 * MIT License 00006 */ 00007 00008 #include "DDBooster.h" 00009 00010 #define BOOSTER_CMD_DELAY 500 00011 #define BOOSTER_LED_DELAY 30 00012 00013 #define BOOSTER_SETRGB 0xA1 00014 #define BOOSTER_SETRGBW 0xA2 00015 #define BOOSTER_SETHSV 0xA3 00016 #define BOOSTER_SETLED 0xA4 00017 #define BOOSTER_SETALL 0xA5 00018 #define BOOSTER_SETRANGE 0xA6 00019 #define BOOSTER_SETRAINBOW 0xA7 00020 #define BOOSTER_GRADIENT 0xA8 00021 00022 #define BOOSTER_INIT 0xB1 00023 #define BOOSTER_SHOW 0xB2 00024 #define BOOSTER_SHIFTUP 0xB3 00025 #define BOOSTER_SHIFTDOWN 0xB4 00026 #define BOOSTER_COPYLED 0xB5 00027 #define BOOSTER_REPEAT 0xB6 00028 00029 #define BOOSTER_RGBORDER 0xC1 00030 00031 DDBooster::DDBooster(PinName MOSI, PinName SCK, PinName CS, PinName RESET) 00032 : _lastIndex(0) 00033 , _device(MOSI, NC, SCK) 00034 , _cs(CS, 1) 00035 , _reset(RESET, 1) 00036 { 00037 _device.format(8,0); 00038 _device.frequency(12000000); 00039 } 00040 00041 void DDBooster::init(uint16_t ledCount, LedType ledType, LedColorOrder colorOrder) 00042 { 00043 // DD Booster expects the number of LEDs to be an even value (rounded up). 00044 // 256 is defined as 0 to fit in one byte. 00045 if (ledCount > 256) { 00046 ledCount = 256; 00047 } 00048 00049 _lastIndex = ledCount - 1; 00050 00051 uint8_t buffer[4]; 00052 buffer[0] = BOOSTER_INIT; 00053 buffer[1] = ledCount + (ledCount & 1); 00054 buffer[2] = ledType; 00055 sendRawBytes(buffer, 3); 00056 00057 if (ledType == LED_RGB && colorOrder != ORDER_GRB) { 00058 buffer[0] = BOOSTER_RGBORDER; 00059 buffer[1] = 3; 00060 buffer[2] = 2; 00061 buffer[3] = 1; 00062 sendRawBytes(buffer, 4); 00063 } 00064 00065 // a delay after init is not documented, but seems to be necessary 00066 wait_ms(40); 00067 } 00068 00069 void DDBooster::reset() 00070 { 00071 if (_reset.is_connected()) { 00072 _reset = 0; 00073 wait_ms(100); 00074 _reset = 1; 00075 wait_ms(100); 00076 } 00077 } 00078 00079 void DDBooster::setRGB(uint8_t r, uint8_t g, uint8_t b) 00080 { 00081 uint8_t cmd[] = { 00082 BOOSTER_SETRGB, 00083 r, 00084 g, 00085 b 00086 }; 00087 sendRawBytes(cmd, sizeof (cmd)); 00088 } 00089 00090 void DDBooster::setRGBW(uint8_t r, uint8_t g, uint8_t b, uint8_t w) 00091 { 00092 uint8_t cmd[] = { 00093 BOOSTER_SETRGBW, 00094 r, 00095 g, 00096 b, 00097 w 00098 }; 00099 sendRawBytes(cmd, sizeof (cmd)); 00100 } 00101 00102 void DDBooster::setHSV(uint16_t h, uint8_t s, uint8_t v) 00103 { 00104 if (h > 359) { 00105 h = 359; 00106 } 00107 uint8_t cmd[] = { 00108 BOOSTER_SETHSV, 00109 h & 0xFF, 00110 h >> 8, 00111 s, 00112 v 00113 }; 00114 sendRawBytes(cmd, sizeof (cmd)); 00115 } 00116 00117 void DDBooster::setLED(uint8_t index) 00118 { 00119 if (index > _lastIndex) { 00120 return; 00121 } 00122 uint8_t cmd[] = { 00123 BOOSTER_SETLED, 00124 index 00125 }; 00126 sendRawBytes(cmd, sizeof (cmd)); 00127 } 00128 00129 void DDBooster::clearLED(uint8_t index) 00130 { 00131 if (index > _lastIndex) { 00132 return; 00133 } 00134 // optimization by sending two commands in one transaction 00135 uint8_t cmd[] = { 00136 BOOSTER_SETRGB, 00137 0, 00138 0, 00139 0, 00140 BOOSTER_SETLED, 00141 index 00142 }; 00143 sendRawBytes(cmd, sizeof (cmd)); 00144 } 00145 00146 void DDBooster::setAll() 00147 { 00148 uint8_t cmd[] = {BOOSTER_SETALL}; 00149 sendRawBytes(cmd, sizeof (cmd)); 00150 } 00151 00152 void DDBooster::clearAll() 00153 { 00154 // optimization by sending two commands in one transaction 00155 uint8_t cmd[] = { 00156 BOOSTER_SETRGB, 00157 0, 00158 0, 00159 0, 00160 BOOSTER_SETALL 00161 }; 00162 sendRawBytes(cmd, sizeof (cmd)); 00163 } 00164 00165 void DDBooster::setRange(uint8_t start, uint8_t end) 00166 { 00167 if (start > end || end > _lastIndex || start > _lastIndex) { 00168 return; 00169 } 00170 uint8_t cmd[] = { 00171 BOOSTER_SETRANGE, 00172 start, 00173 end 00174 }; 00175 sendRawBytes(cmd, sizeof (cmd)); 00176 } 00177 00178 void DDBooster::setRainbow(uint16_t h, uint8_t s, uint8_t v, uint8_t start, uint8_t end, uint8_t step) 00179 { 00180 if (start > end || end > _lastIndex || start > _lastIndex) { 00181 return; 00182 } 00183 if (h > 359) { 00184 h = 359; 00185 } 00186 uint8_t cmd[] = { 00187 BOOSTER_SETRAINBOW, 00188 h & 0xFF, 00189 h >> 8, 00190 s, 00191 v, 00192 start, 00193 end, 00194 step 00195 }; 00196 sendRawBytes(cmd, sizeof (cmd)); 00197 } 00198 00199 void DDBooster::setGradient(int start, int end, uint8_t from[3], uint8_t to[3]) 00200 { 00201 if (start > end || start > _lastIndex) { 00202 return; 00203 } 00204 00205 uint8_t steps = end - start; 00206 if (steps == 0) { 00207 setRGB(from[0], from[1], from[2]); 00208 return; 00209 } 00210 00211 uint8_t s = 0, e = steps; 00212 if (start < 0) { 00213 s = 0 - start; 00214 } 00215 if (end > _lastIndex) { 00216 e -= (end - _lastIndex); 00217 } 00218 00219 // optimized setRGB(r,g,b) and setLED(start + i) with one transaction and shared memory 00220 uint8_t cmd[6]; 00221 cmd[0] = BOOSTER_SETRGB; 00222 cmd[4] = BOOSTER_SETLED; 00223 for (; s <= e; s++) { 00224 cmd[1] = from[0] + (to[0] - from[0]) * s / steps; 00225 cmd[2] = from[1] + (to[1] - from[1]) * s / steps; 00226 cmd[3] = from[2] + (to[2] - from[2]) * s / steps; 00227 cmd[5] = start + s; 00228 sendRawBytes(cmd, sizeof (cmd)); 00229 } 00230 } 00231 00232 void DDBooster::shiftUp(uint8_t start, uint8_t end, uint8_t count) 00233 { 00234 if (start > end || end > _lastIndex || start > _lastIndex) { 00235 return; 00236 } 00237 uint8_t cmd[4] = { 00238 BOOSTER_SHIFTDOWN, 00239 start, 00240 end, 00241 count 00242 }; 00243 sendRawBytes(cmd, sizeof (cmd)); 00244 } 00245 00246 void DDBooster::shiftDown(uint8_t start, uint8_t end, uint8_t count) 00247 { 00248 if (start > end || end > _lastIndex || start > _lastIndex) { 00249 return; 00250 } 00251 uint8_t cmd[4] = { 00252 BOOSTER_SHIFTDOWN, 00253 start, 00254 end, 00255 count 00256 }; 00257 sendRawBytes(cmd, sizeof (cmd)); 00258 } 00259 00260 void DDBooster::copyLED(uint8_t from, uint8_t to) 00261 { 00262 if (from > _lastIndex || to > _lastIndex) { 00263 return; 00264 } 00265 uint8_t cmd[] = { 00266 BOOSTER_COPYLED, 00267 from, 00268 to 00269 }; 00270 sendRawBytes(cmd, sizeof (cmd)); 00271 } 00272 00273 void DDBooster::repeat(uint8_t start, uint8_t end, uint8_t count) 00274 { 00275 if (start > end || end > _lastIndex || start > _lastIndex) { 00276 return; 00277 } 00278 uint8_t cmd[] = { 00279 BOOSTER_REPEAT, 00280 start, 00281 end, 00282 count 00283 }; 00284 sendRawBytes(cmd, sizeof (cmd)); 00285 } 00286 00287 void DDBooster::show() 00288 { 00289 uint8_t cmd[] = {BOOSTER_SHOW}; 00290 sendRawBytes(cmd, sizeof (cmd)); 00291 wait_us(BOOSTER_LED_DELAY * (_lastIndex + 1)); 00292 } 00293 00294 void DDBooster::sendRawBytes(const uint8_t *buffer, uint8_t length) 00295 { 00296 _cs = 0; 00297 for (int i = 0; i < length; i++) { 00298 _device.write(buffer[i]); 00299 } 00300 _cs = 1; 00301 wait_us(BOOSTER_CMD_DELAY); 00302 }
Generated on Tue Jul 12 2022 19:56:05 by 1.7.2