From 828834ad7abb256cba24f298109608e8689d8b9d Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Thu, 21 Jan 2016 21:45:23 -0800 Subject: [PATCH] Extract our the 'old' WS2812 implementation --- WS2812.cpp | 114 ---------------------------------- WS2812.h | 99 ------------------------------ cRGB.h | 115 ---------------------------------- light_ws2812.cpp | 156 ----------------------------------------------- 4 files changed, 484 deletions(-) delete mode 100644 WS2812.cpp delete mode 100644 WS2812.h delete mode 100644 cRGB.h delete mode 100644 light_ws2812.cpp diff --git a/WS2812.cpp b/WS2812.cpp deleted file mode 100644 index 2fb134bf..00000000 --- a/WS2812.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* -* light weight WS2812 lib V2.1 - Arduino support -* -* Controls WS2811/WS2812/WS2812B RGB-LEDs -* Author: Matthias Riegler -* -* Mar 07 2014: Added Arduino and C++ Library -* -* September 6, 2014: Added option to switch between most popular color orders -* (RGB, GRB, and BRG) -- Windell H. Oskay -* -* License: GNU GPL v2 (see License.txt) -*/ - -#include "WS2812.h" -#include - -WS2812::WS2812(uint16_t num_leds) { - count_led = num_leds; - - pixels = (uint8_t*)malloc(count_led*3); - #ifdef RGB_ORDER_ON_RUNTIME - offsetGreen = 0; - offsetRed = 1; - offsetBlue = 2; - #endif -} - -cRGB WS2812::get_crgb_at(uint16_t index) { - - cRGB px_value; - - if(index < count_led) { - - uint16_t tmp; - tmp = index * 3; - - px_value.r = pixels[OFFSET_R(tmp)]; - px_value.g = pixels[OFFSET_G(tmp)]; - px_value.b = pixels[OFFSET_B(tmp)]; - } - - return px_value; -} - -uint8_t WS2812::set_crgb_at(uint16_t index, cRGB px_value) { - - if(index < count_led) { - - uint16_t tmp; - tmp = index * 3; - - pixels[OFFSET_R(tmp)] = px_value.r; - pixels[OFFSET_G(tmp)] = px_value.g; - pixels[OFFSET_B(tmp)] = px_value.b; - return 0; - } - return 1; -} - -uint8_t WS2812::set_subpixel_at(uint16_t index, uint8_t offset, uint8_t px_value) { - if (index < count_led) { - uint16_t tmp; - tmp = index * 3; - - pixels[tmp + offset] = px_value; - return 0; - } - return 1; -} - -void WS2812::sync() { - *ws2812_port_reg |= pinMask; // Enable DDR - ws2812_sendarray_mask(pixels,3*count_led,pinMask,(uint8_t*) ws2812_port,(uint8_t*) ws2812_port_reg ); -} - -#ifdef RGB_ORDER_ON_RUNTIME -void WS2812::setColorOrderGRB() { // Default color order - offsetGreen = 0; - offsetRed = 1; - offsetBlue = 2; -} - -void WS2812::setColorOrderRGB() { - offsetRed = 0; - offsetGreen = 1; - offsetBlue = 2; -} - -void WS2812::setColorOrderBRG() { - offsetBlue = 0; - offsetRed = 1; - offsetGreen = 2; -} -#endif - -WS2812::~WS2812() { - - -} - -#ifndef ARDUINO -void WS2812::setOutput(const volatile uint8_t* port, volatile uint8_t* reg, uint8_t pin) { - pinMask = (1< -#include -#ifndef F_CPU -#define F_CPU 16000000UL -#endif -#include -#include - -#ifdef ARDUINO -#if (ARDUINO >= 100) -#include -#else -#include -#include -#endif -#endif - -//Easier to change cRGB into any other rgb struct -#include "cRGB.h" - -// If you want to use the setColorOrder functions, enable this line -#define RGB_ORDER_ON_RUNTIME - -#ifdef RGB_ORDER_ON_RUNTIME - #define OFFSET_R(r) r+offsetRed - #define OFFSET_G(g) g+offsetGreen - #define OFFSET_B(b) b+offsetBlue -#else -// CHANGE YOUR STATIC RGB ORDER HERE - #define OFFSET_R(r) r+1 - #define OFFSET_G(g) g - #define OFFSET_B(b) b+2 -#endif - -class WS2812 { -public: - WS2812(uint16_t num_led); - ~WS2812(); - - #ifndef ARDUINO - void setOutput(const volatile uint8_t* port, volatile uint8_t* reg, uint8_t pin); - #else - void setOutput(uint8_t pin); - #endif - - cRGB get_crgb_at(uint16_t index); - uint8_t set_crgb_at(uint16_t index, cRGB px_value); - uint8_t set_subpixel_at(uint16_t index, uint8_t offset, uint8_t px_value); - - void sync(); - -#ifdef RGB_ORDER_ON_RUNTIME - void setColorOrderRGB(); - void setColorOrderGRB(); - void setColorOrderBRG(); -#endif - -private: - uint16_t count_led; - uint8_t *pixels; - -#ifdef RGB_ORDER_ON_RUNTIME - uint8_t offsetRed; - uint8_t offsetGreen; - uint8_t offsetBlue; -#endif - - void ws2812_sendarray_mask(uint8_t *array,uint16_t length, uint8_t pinmask,uint8_t *port, uint8_t *portreg); - - const volatile uint8_t *ws2812_port; - volatile uint8_t *ws2812_port_reg; - uint8_t pinMask; -}; - - - -#endif /* WS2812_H_ */ diff --git a/cRGB.h b/cRGB.h deleted file mode 100644 index 227ee722..00000000 --- a/cRGB.h +++ /dev/null @@ -1,115 +0,0 @@ -#ifndef CRGB_H -#define CRGB_H - -/* -Control a RGB led with Hue, Saturation and Brightness (HSB / HSV ) - -Hue is change by an analog input. -Brightness is changed by a fading function. -Saturation stays constant at 255 - -getRGB() function based on -dim_curve idea by Jims - -created 05-01-2010 by kasperkamperman.com -*/ - -/* -dim_curve 'lookup table' to compensate for the nonlinearity of human vision. -Used in the getRGB function on saturation and brightness to make 'dimming' look more natural. -Exponential function used to create values below : -x from 0 - 255 : y = round(pow( 2.0, x+64/40.0) - 1) -*/ - -// uncomment this line if you use HSV is many projects -#define USE_HSV - -#ifdef USE_HSV -const byte dim_curve[] = { - 0, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, - 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, - 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, - 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, - 15, 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, - 20, 20, 21, 21, 22, 22, 22, 23, 23, 24, 24, 25, 25, 25, 26, 26, - 27, 27, 28, 28, 29, 29, 30, 30, 31, 32, 32, 33, 33, 34, 35, 35, - 36, 36, 37, 38, 38, 39, 40, 40, 41, 42, 43, 43, 44, 45, 46, 47, - 48, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 68, 69, 70, 71, 73, 74, 75, 76, 78, 79, 81, 82, - 83, 85, 86, 88, 90, 91, 93, 94, 96, 98, 99, 101, 103, 105, 107, 109, - 110, 112, 114, 116, 118, 121, 123, 125, 127, 129, 132, 134, 136, 139, 141, 144, - 146, 149, 151, 154, 157, 159, 162, 165, 168, 171, 174, 177, 180, 183, 186, 190, - 193, 196, 200, 203, 207, 211, 214, 218, 222, 226, 230, 234, 238, 242, 248, 255, -}; -#endif - -struct cRGB { - uint8_t g; - uint8_t r; - uint8_t b; - -#ifdef USE_HSV - void SetHSV(int hue, byte sat, byte val) { - /* convert hue, saturation and brightness ( HSB/HSV ) to RGB - The dim_curve is used only on brightness/value and on saturation (inverted). - This looks the most natural. - */ - - val = dim_curve[val]; - sat = 255 - dim_curve[255 - sat]; - - int base; - - if (sat == 0) { // Acromatic color (gray). Hue doesn't mind. - r = val; - g = val; - b = val; - } - else { - base = ((255 - sat) * val) >> 8; - - switch (hue / 60) { - case 0: - r = val; - g = (((val - base)*hue) / 60) + base; - b = base; - break; - - case 1: - r = (((val - base)*(60 - (hue % 60))) / 60) + base; - g = val; - b = base; - break; - - case 2: - r = base; - g = val; - b = (((val - base)*(hue % 60)) / 60) + base; - break; - - case 3: - r = base; - g = (((val - base)*(60 - (hue % 60))) / 60) + base; - b = val; - break; - - case 4: - r = (((val - base)*(hue % 60)) / 60) + base; - g = base; - b = val; - break; - - case 5: - r = val; - g = base; - b = (((val - base)*(60 - (hue % 60))) / 60) + base; - break; - } - } - } -#endif -}; - -#endif \ No newline at end of file diff --git a/light_ws2812.cpp b/light_ws2812.cpp deleted file mode 100644 index 2440d231..00000000 --- a/light_ws2812.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/* -* light weight WS2812 lib V2.1 - Arduino support -* -* Controls WS2811/WS2812/WS2812B RGB-LEDs -* Author: Tim (cpldcpu@gmail.com) -* -* Jan 18th, 2014 v2.0b Initial Version -* March 7th, 2014 v2.1 Added option to retarget the port register during runtime -* Removes inlining to allow compiling with c++ -* -* License: GNU GPL v2 (see License.txt) -*/ - -#include "WS2812.h" - -/* - This routine writes an array of bytes with RGB values to the Dataout pin - using the fast 800kHz clockless WS2811/2812 protocol. -*/ - -// Timing in ns -#define w_zeropulse 350 -#define w_onepulse 900 -#define w_totalperiod 1250 - -// Fixed cycles used by the inner loop -#define w_fixedlow 3 -#define w_fixedhigh 6 -#define w_fixedtotal 10 - -// Insert NOPs to match the timing, if possible -#define w_zerocycles (((F_CPU/1000)*w_zeropulse )/1000000) -#define w_onecycles (((F_CPU/1000)*w_onepulse +500000)/1000000) -#define w_totalcycles (((F_CPU/1000)*w_totalperiod +500000)/1000000) - -// w1 - nops between rising edge and falling edge - low -#define w1 (w_zerocycles-w_fixedlow) -// w2 nops between fe low and fe high -#define w2 (w_onecycles-w_fixedhigh-w1) -// w3 nops to complete loop -#define w3 (w_totalcycles-w_fixedtotal-w1-w2) - -#if w1>0 - #define w1_nops w1 -#else - #define w1_nops 0 -#endif - -// The only critical timing parameter is the minimum pulse length of the "0" -// Warn or throw error if this timing can not be met with current F_CPU settings. -#define w_lowtime ((w1_nops+w_fixedlow)*1000000)/(F_CPU/1000) -#if w_lowtime>550 - #error "Light_ws2812: Sorry, the clock speed is too low. Did you set F_CPU correctly?" -#elif w_lowtime>450 - #warning "Light_ws2812: The timing is critical and may only work on WS2812B, not on WS2812(S)." - #warning "Please consider a higher clockspeed, if possible" -#endif - -#if w2>0 -#define w2_nops w2 -#else -#define w2_nops 0 -#endif - -#if w3>0 -#define w3_nops w3 -#else -#define w3_nops 0 -#endif - -#define w_nop1 "nop \n\t" -#define w_nop2 "rjmp .+0 \n\t" -#define w_nop4 w_nop2 w_nop2 -#define w_nop8 w_nop4 w_nop4 -#define w_nop16 w_nop8 w_nop8 - -void WS2812::ws2812_sendarray_mask(uint8_t *data,uint16_t datlen,uint8_t maskhi,uint8_t *port, uint8_t *portreg) -{ - uint8_t curbyte,ctr,masklo; - uint8_t sreg_prev; - - masklo = ~maskhi & *port; - maskhi |= *port; - sreg_prev=SREG; - cli(); - - while (datlen--) { - curbyte=*data++; - - asm volatile( - " ldi %0,8 \n\t" - "loop%=: \n\t" - " st X,%3 \n\t" // '1' [02] '0' [02] - re -#if (w1_nops&1) -w_nop1 -#endif -#if (w1_nops&2) -w_nop2 -#endif -#if (w1_nops&4) -w_nop4 -#endif -#if (w1_nops&8) -w_nop8 -#endif -#if (w1_nops&16) -w_nop16 -#endif - " sbrs %1,7 \n\t" // '1' [04] '0' [03] - " st X,%4 \n\t" // '1' [--] '0' [05] - fe-low - " lsl %1 \n\t" // '1' [05] '0' [06] -#if (w2_nops&1) - w_nop1 -#endif -#if (w2_nops&2) - w_nop2 -#endif -#if (w2_nops&4) - w_nop4 -#endif -#if (w2_nops&8) - w_nop8 -#endif -#if (w2_nops&16) - w_nop16 -#endif - " brcc skipone%= \n\t" // '1' [+1] '0' [+2] - - " st X,%4 \n\t" // '1' [+3] '0' [--] - fe-high - "skipone%=: " // '1' [+3] '0' [+2] - - -#if (w3_nops&1) -w_nop1 -#endif -#if (w3_nops&2) -w_nop2 -#endif -#if (w3_nops&4) -w_nop4 -#endif -#if (w3_nops&8) -w_nop8 -#endif -#if (w3_nops&16) -w_nop16 -#endif - - " dec %0 \n\t" // '1' [+4] '0' [+3] - " brne loop%=\n\t" // '1' [+5] '0' [+4] - : "=&d" (ctr) -// : "r" (curbyte), "I" (_SFR_IO_ADDR(ws2812_PORTREG)), "r" (maskhi), "r" (masklo) - : "r" (curbyte), "x" (port), "r" (maskhi), "r" (masklo) - ); - } - - SREG=sreg_prev; -}