Color pixels library using WS2812B and nRF51822
Dependents: BLE_Color_Pixels Grove_Node BLE_HeartRate
color_pixels.cpp
00001 /** Color pixels library using WS2812B and nRF51822 (16MHz) 00002 * It's for 00003 * + http://www.seeedstudio.com/depot/Digital-RGB-LED-FlexiStrip-60-LED-1-Meter-p-1666.html 00004 * + http://www.seeedstudio.com/depot/WS2812B-Digital-RGB-LED-Waterproof-FlexiStrip-144-LEDmeter-2-meter-p-1869.html 00005 * + http://www.seeedstudio.com/depot/WS2812B-RGB-LED-with-Integrated-Driver-Chip-10-PCs-pack-p-1675.html 00006 * 00007 * The MIT License (MIT) 00008 * 00009 * Copyright (c) 2014 Seeed Technology Inc. 00010 * 00011 * Permission is hereby granted, free of charge, to any person obtaining a copy 00012 * of this software and associated documentation files (the "Software"), to deal 00013 * in the Software without restriction, including without limitation the rights 00014 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00015 * copies of the Software, and to permit persons to whom the Software is 00016 * furnished to do so, subject to the following conditions: 00017 00018 * The above copyright notice and this permission notice shall be included in 00019 * all copies or substantial portions of the Software. 00020 00021 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00022 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00023 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00024 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00025 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00026 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00027 * THE SOFTWARE. 00028 */ 00029 00030 #include "color_pixels.h" 00031 #include "nrf51.h" 00032 #include "nrf51_bitfields.h" 00033 00034 #if !defined ( __GNUC__ ) 00035 // Generate a high level pulse (0.81us) of WS2812B's 1 code (0.9us +- 0.15us) 00036 #define COLOR_PIXELS_ONE_HIGH(mask) \ 00037 NRF_GPIO->OUTSET = (mask); \ 00038 __ASM ( \ 00039 " NOP\n\t" \ 00040 " NOP\n\t" \ 00041 " NOP\n\t" \ 00042 " NOP\n\t" \ 00043 " NOP\n\t" \ 00044 " NOP\n\t" \ 00045 " NOP\n\t" \ 00046 " NOP\n\t" \ 00047 " NOP\n\t" \ 00048 ); \ 00049 NRF_GPIO->OUTCLR = (mask) 00050 00051 // Generate a high level pulse (0.31us) of WS2812B's 0 code (0.35us +- 0.15us) 00052 #define COLOR_PIXELS_ZERO_HIGH(mask) \ 00053 NRF_GPIO->OUTSET = (mask); \ 00054 __ASM ( \ 00055 " NOP\n\t" \ 00056 ); \ 00057 NRF_GPIO->OUTCLR = (mask); \ 00058 __ASM ( \ 00059 " NOP\n\t" \ 00060 " NOP\n\t" \ 00061 " NOP\n\t" \ 00062 " NOP\n\t" \ 00063 " NOP\n\t" \ 00064 " NOP\n\t" \ 00065 " NOP\n\t" \ 00066 " NOP\n\t" \ 00067 ) 00068 #else 00069 // Generate a high level pulse (0.94us) of WS2812B's 1 code (0.9us +- 0.15us) 00070 #define COLOR_PIXELS_ONE_HIGH(mask) \ 00071 NRF_GPIO->OUTSET = (mask); \ 00072 __ASM ( \ 00073 " NOP\n\t" \ 00074 " NOP\n\t" \ 00075 " NOP\n\t" \ 00076 " NOP\n\t" \ 00077 " NOP\n\t" \ 00078 " NOP\n\t" \ 00079 " NOP\n\t" \ 00080 " NOP\n\t" \ 00081 ); \ 00082 NRF_GPIO->OUTCLR = (mask) 00083 00084 // Generate a high level pulse (0.44us) of WS2812B's 0 code (0.35us +- 0.15us) 00085 #define COLOR_PIXELS_ZERO_HIGH(mask) \ 00086 NRF_GPIO->OUTSET = (mask); \ 00087 __ASM ( \ 00088 " NOP\n\t" \ 00089 ); \ 00090 NRF_GPIO->OUTCLR = (mask); \ 00091 __ASM ( \ 00092 " NOP\n\t" \ 00093 " NOP\n\t" \ 00094 " NOP\n\t" \ 00095 " NOP\n\t" \ 00096 " NOP\n\t" \ 00097 " NOP\n\t" \ 00098 " NOP\n\t" \ 00099 " NOP\n\t" \ 00100 ) 00101 #endif 00102 00103 static void delay_us(uint32_t us) 00104 { 00105 do { 00106 __ASM volatile ( 00107 "NOP\n\t" 00108 "NOP\n\t" 00109 "NOP\n\t" 00110 "NOP\n\t" 00111 "NOP\n\t" 00112 "NOP\n\t" 00113 "NOP\n\t" 00114 "NOP\n\t" 00115 "NOP\n\t" 00116 "NOP\n\t" 00117 "NOP\n\t" 00118 "NOP\n\t" 00119 ); 00120 } while (--us); 00121 } 00122 00123 ColorPixels::ColorPixels(uint8_t pin, uint16_t num) 00124 { 00125 this->pin = pin; 00126 this->num = num; 00127 00128 NRF_GPIO->PIN_CNF[pin] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) 00129 | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) 00130 | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) 00131 | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) 00132 | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); 00133 NRF_GPIO->OUTCLR = (1UL << pin); 00134 00135 colors = new grb_t[num]; 00136 for (int i = 0; i < num; i++) { 00137 colors[i].grb = 0; 00138 } 00139 } 00140 00141 ColorPixels::~ColorPixels() 00142 { 00143 delete colors; 00144 } 00145 00146 00147 void ColorPixels::set_color(uint16_t index, uint8_t r, uint8_t g, uint8_t b) 00148 { 00149 if (index < num) { 00150 colors[index].r = r; 00151 colors[index].g = g; 00152 colors[index].b = b; 00153 } 00154 } 00155 00156 void ColorPixels::set_color(uint16_t index, uint32_t rgb) { 00157 color_t c = *(color_t *)&rgb; 00158 set_color(index, c.r, c.g, c.b); 00159 } 00160 00161 void ColorPixels::set_all_color(uint8_t r, uint8_t g, uint8_t b) 00162 { 00163 for (int i = 0; i < num; i++) { 00164 colors[i].r = r; 00165 colors[i].g = g; 00166 colors[i].b = b; 00167 } 00168 00169 update(); 00170 } 00171 00172 void ColorPixels::update() 00173 { 00174 uint32_t mask = 1 << pin; 00175 NRF_GPIO->OUTCLR = mask; 00176 delay_us(50); 00177 00178 grb_t *pcolor = colors; 00179 for (int i = 0; i < num; i++) { 00180 uint32_t grb = (*pcolor).grb; 00181 for (int bit = 0; bit < 24; bit++) { 00182 if (grb & 1) { 00183 COLOR_PIXELS_ONE_HIGH(mask); 00184 } else { 00185 COLOR_PIXELS_ZERO_HIGH(mask); 00186 } 00187 grb >>= 1; 00188 } 00189 pcolor++; 00190 } 00191 } 00192 00193 void ColorPixels::clear() 00194 { 00195 for (int i = 0; i < num; i++) { 00196 colors[i].grb = 0; 00197 } 00198 00199 update(); 00200 } 00201 00202 uint32_t toRGB(uint8_t red, uint8_t green, uint8_t blue) 00203 { 00204 color_t c; 00205 00206 c.r = red; 00207 c.g = green; 00208 c.b = blue; 00209 00210 return c.rgb; 00211 }; 00212 00213 uint32_t wheel(float position, uint8_t min = 0, uint8_t max = 255) 00214 { 00215 uint8_t d = max - min; 00216 uint32_t c; 00217 00218 if(position < 0.166) { 00219 c = toRGB(max, min + position * 6 * d, min); 00220 } else if(position < 0.332) { 00221 position -= 0.166; 00222 c = toRGB(max - position * 6 * d, max, min); 00223 } else if(position < 0.498) { 00224 position -= 0.332; 00225 c = toRGB(min, max, min + position * 6 * d); 00226 } else if(position < 0.664) { 00227 position -= 0.498; 00228 c = toRGB(min, max - position * 6 * d, max); 00229 } else if(position < 0.83) { 00230 position -= 0.664; 00231 c = toRGB(min + d * position * 6, min, max); 00232 } else { 00233 position -= 0.83; 00234 c = toRGB(max, min, max - position * 6 * d); 00235 } 00236 00237 return c; 00238 } 00239 00240 void find_wheel_options(uint32_t rgb, float *position, uint8_t *min, uint8_t *max) 00241 { 00242 color_t c; 00243 c.rgb = rgb; 00244 00245 if (c.r > c.g) { 00246 if (c.g >= c.b) { 00247 *max = c.r; 00248 *min = c.b; 00249 *position = (float)(c.g - c.b) / (c.r - c.b) / 6.0; 00250 } else if (c.b >= c.r) { 00251 *max = c.b; 00252 *min = c.g; 00253 *position = (float)(c.r - c.g) / (c.b - c.g) / 6.0 + 0.664; 00254 } else { 00255 *max = c.r; 00256 *min = c.g; 00257 *position = (float)(c.b - c.g) / (c.r - c.g) / 6.0 + 0.83; 00258 } 00259 } else { 00260 if (c.r > c.b) { 00261 *max = c.g; 00262 *min = c.b; 00263 *position = (float)(c.r - c.b) / (c.g - c.b) / 6.0 + 0.166; 00264 } else if (c.b > c.g) { 00265 *max = c.b; 00266 *min = c.r; 00267 *position = (float)(c.g - c.r) / (c.b - c.r) / 6.0 + 0.498; 00268 } else { 00269 *max = c.g; 00270 *min = c.r; 00271 *position = (float)(c.b - c.r) / (c.g - c.r) / 6.0 + 0.332; 00272 } 00273 } 00274 } 00275 00276 void ColorPixels::rainbow(uint32_t rgb) 00277 { 00278 float position; 00279 uint8_t min, max; 00280 00281 find_wheel_options(rgb, &position, &min, &max); 00282 for (int i = 0; i < num; i++) { 00283 float current = ((int)(i + num * position) % num) / (float)num; 00284 set_color(i, wheel(current, min, max)); 00285 } 00286 00287 update(); 00288 } 00289 00290 void ColorPixels::rainbow(uint8_t r, uint8_t g, uint8_t b) 00291 { 00292 color_t c; 00293 00294 c.r = r; 00295 c.g = g; 00296 c.b = b; 00297 00298 rainbow(c.rgb); 00299 } 00300
Generated on Tue Jul 12 2022 19:06:55 by 1.7.2