Simple neopixel (WS2812) library, tuned for stm32 (L432) at 80 MHz Should be compatible with any stm32, different clock speed may require timing adjustments in neopixel.c

Dependents:   NEOPIXEL_SAMPLE

Committer:
tichise
Date:
Thu Jan 02 07:56:44 2020 +0000
Revision:
1:415459e3f93b
Parent:
0:a81364d9a67b
Fixed __nop from lowercase to uppercase to work with PlatformIO

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MightyPork 0:a81364d9a67b 1 #include "mbed.h"
MightyPork 0:a81364d9a67b 2 #include "colorspace.h"
MightyPork 0:a81364d9a67b 3 #include "math.h"
MightyPork 0:a81364d9a67b 4
MightyPork 0:a81364d9a67b 5 #define max(a,b) ((a)>(b)?(a):(b))
MightyPork 0:a81364d9a67b 6 #define min(a,b) ((a)>(b)?(b):(a))
MightyPork 0:a81364d9a67b 7
MightyPork 0:a81364d9a67b 8 static float threeway_max(float a, float b, float c) {
MightyPork 0:a81364d9a67b 9 return max(a, max(b, c));
MightyPork 0:a81364d9a67b 10 }
MightyPork 0:a81364d9a67b 11
MightyPork 0:a81364d9a67b 12
MightyPork 0:a81364d9a67b 13 static float threeway_min(float a, float b, float c) {
MightyPork 0:a81364d9a67b 14 return min(a, min(b, c));
MightyPork 0:a81364d9a67b 15 }
MightyPork 0:a81364d9a67b 16
MightyPork 0:a81364d9a67b 17
MightyPork 0:a81364d9a67b 18 static float hue2rgb(float p, float q, float t) {
MightyPork 0:a81364d9a67b 19 if(t < 0) t += 1;
MightyPork 0:a81364d9a67b 20 if(t > 1) t -= 1;
MightyPork 0:a81364d9a67b 21 if(t < 1/6.0f) return p + (q - p) * 6 * t;
MightyPork 0:a81364d9a67b 22 if(t < 1/2.0f) return q;
MightyPork 0:a81364d9a67b 23 if(t < 2/3.0f) return p + (q - p) * (2/3.0f - t) * 6;
MightyPork 0:a81364d9a67b 24 return p;
MightyPork 0:a81364d9a67b 25 }
MightyPork 0:a81364d9a67b 26
MightyPork 0:a81364d9a67b 27
MightyPork 0:a81364d9a67b 28 void hsl2rgb(const FloatHSL *hsl, FloatRGB *rgb)
MightyPork 0:a81364d9a67b 29 {
MightyPork 0:a81364d9a67b 30 float h = hsl->h;
MightyPork 0:a81364d9a67b 31 float s = hsl->s;
MightyPork 0:a81364d9a67b 32 float l = hsl->l;
MightyPork 0:a81364d9a67b 33
MightyPork 0:a81364d9a67b 34 if (s == 0) {
MightyPork 0:a81364d9a67b 35 rgb->r = rgb->g = rgb->b = l; // achromatic
MightyPork 0:a81364d9a67b 36 } else {
MightyPork 0:a81364d9a67b 37 float q = l < 0.5f ? l * (1 + s) : l + s - l * s;
MightyPork 0:a81364d9a67b 38 float p = 2 * l - q;
MightyPork 0:a81364d9a67b 39 rgb->r = hue2rgb(p, q, h + 1/3.0f);
MightyPork 0:a81364d9a67b 40 rgb->g = hue2rgb(p, q, h);
MightyPork 0:a81364d9a67b 41 rgb->b = hue2rgb(p, q, h - 1/3.0f);
MightyPork 0:a81364d9a67b 42 }
MightyPork 0:a81364d9a67b 43 }
MightyPork 0:a81364d9a67b 44
MightyPork 0:a81364d9a67b 45
MightyPork 0:a81364d9a67b 46 void hsv2rgb(const FloatHSV *hsv, FloatRGB *rgb)
MightyPork 0:a81364d9a67b 47 {
MightyPork 0:a81364d9a67b 48 float r, g, b;
MightyPork 0:a81364d9a67b 49
MightyPork 0:a81364d9a67b 50 int i = floor(hsv->h * 6);
MightyPork 0:a81364d9a67b 51 float f = hsv->h * 6 - i;
MightyPork 0:a81364d9a67b 52 float p = hsv->v * (1 - hsv->s);
MightyPork 0:a81364d9a67b 53 float q = hsv->v * (1 - f * hsv->s);
MightyPork 0:a81364d9a67b 54 float t = hsv->v * (1 - (1 - f) * hsv->s);
MightyPork 0:a81364d9a67b 55
MightyPork 0:a81364d9a67b 56 switch(i % 6) {
MightyPork 0:a81364d9a67b 57 case 0:
MightyPork 0:a81364d9a67b 58 r = hsv->v;
MightyPork 0:a81364d9a67b 59 g = t;
MightyPork 0:a81364d9a67b 60 b = p;
MightyPork 0:a81364d9a67b 61 break;
MightyPork 0:a81364d9a67b 62 case 1:
MightyPork 0:a81364d9a67b 63 r = q;
MightyPork 0:a81364d9a67b 64 g = hsv->v;
MightyPork 0:a81364d9a67b 65 b = p;
MightyPork 0:a81364d9a67b 66 break;
MightyPork 0:a81364d9a67b 67 case 2:
MightyPork 0:a81364d9a67b 68 r = p;
MightyPork 0:a81364d9a67b 69 g = hsv->v;
MightyPork 0:a81364d9a67b 70 b = t;
MightyPork 0:a81364d9a67b 71 break;
MightyPork 0:a81364d9a67b 72 case 3:
MightyPork 0:a81364d9a67b 73 r = p;
MightyPork 0:a81364d9a67b 74 g = q;
MightyPork 0:a81364d9a67b 75 b = hsv->v;
MightyPork 0:a81364d9a67b 76 break;
MightyPork 0:a81364d9a67b 77 case 4:
MightyPork 0:a81364d9a67b 78 r = t;
MightyPork 0:a81364d9a67b 79 g = p;
MightyPork 0:a81364d9a67b 80 b = hsv->v;
MightyPork 0:a81364d9a67b 81 break;
MightyPork 0:a81364d9a67b 82 case 5:
MightyPork 0:a81364d9a67b 83 r = hsv->v;
MightyPork 0:a81364d9a67b 84 g = p;
MightyPork 0:a81364d9a67b 85 b = q;
MightyPork 0:a81364d9a67b 86 break;
MightyPork 0:a81364d9a67b 87 }
MightyPork 0:a81364d9a67b 88
MightyPork 0:a81364d9a67b 89 rgb->r = r;
MightyPork 0:a81364d9a67b 90 rgb->g = g;
MightyPork 0:a81364d9a67b 91 rgb->b = b;
MightyPork 0:a81364d9a67b 92 }
MightyPork 0:a81364d9a67b 93
MightyPork 0:a81364d9a67b 94 void rgb2hsl(const FloatRGB *rgb, FloatHSL *hsl)
MightyPork 0:a81364d9a67b 95 {
MightyPork 0:a81364d9a67b 96 float rd = rgb->r;
MightyPork 0:a81364d9a67b 97 float gd = rgb->g;
MightyPork 0:a81364d9a67b 98 float bd = rgb->b;
MightyPork 0:a81364d9a67b 99 float max = threeway_max(rd, gd, bd);
MightyPork 0:a81364d9a67b 100 float min = threeway_min(rd, gd, bd);
MightyPork 0:a81364d9a67b 101 float h, s, l = (max + min) / 2.0f;
MightyPork 0:a81364d9a67b 102
MightyPork 0:a81364d9a67b 103 if (max == min) {
MightyPork 0:a81364d9a67b 104 h = s = 0; // achromatic
MightyPork 0:a81364d9a67b 105 } else {
MightyPork 0:a81364d9a67b 106 float d = max - min;
MightyPork 0:a81364d9a67b 107 s = l > 0.5f ? d / (2 - max - min) : d / (max + min);
MightyPork 0:a81364d9a67b 108 if (max == rd) {
MightyPork 0:a81364d9a67b 109 h = (gd - bd) / d + (gd < bd ? 6 : 0);
MightyPork 0:a81364d9a67b 110 } else if (max == gd) {
MightyPork 0:a81364d9a67b 111 h = (bd - rd) / d + 2;
MightyPork 0:a81364d9a67b 112 } else if (max == bd) {
MightyPork 0:a81364d9a67b 113 h = (rd - gd) / d + 4;
MightyPork 0:a81364d9a67b 114 }
MightyPork 0:a81364d9a67b 115 h /= 6;
MightyPork 0:a81364d9a67b 116 }
MightyPork 0:a81364d9a67b 117 hsl->h = h;
MightyPork 0:a81364d9a67b 118 hsl->s = s;
MightyPork 0:a81364d9a67b 119 hsl->l = l;
MightyPork 0:a81364d9a67b 120 }
MightyPork 0:a81364d9a67b 121
MightyPork 0:a81364d9a67b 122
MightyPork 0:a81364d9a67b 123
MightyPork 0:a81364d9a67b 124 /** Convert from HSV to HSL (this is possibly wrong) */
MightyPork 0:a81364d9a67b 125 void hsv2hsl(const FloatHSV *hsv, FloatHSL *hsl)
MightyPork 0:a81364d9a67b 126 {
MightyPork 0:a81364d9a67b 127 float l = (2 - hsv->s) * hsv->v / 2.0f;
MightyPork 0:a81364d9a67b 128 float s = hsv->s;
MightyPork 0:a81364d9a67b 129
MightyPork 0:a81364d9a67b 130 if (l != 0) {
MightyPork 0:a81364d9a67b 131 if (l == 1) {
MightyPork 0:a81364d9a67b 132 s = 0;
MightyPork 0:a81364d9a67b 133 } else if (l < 0.5f) {
MightyPork 0:a81364d9a67b 134 s = s * hsv->v / (l * 2);
MightyPork 0:a81364d9a67b 135 } else {
MightyPork 0:a81364d9a67b 136 s = s * hsv->v / (2 - l * 2);
MightyPork 0:a81364d9a67b 137 }
MightyPork 0:a81364d9a67b 138 }
MightyPork 0:a81364d9a67b 139
MightyPork 0:a81364d9a67b 140 hsl->h = hsv->h;
MightyPork 0:a81364d9a67b 141 hsl->s = s;
MightyPork 0:a81364d9a67b 142 hsl->l = l;
MightyPork 0:a81364d9a67b 143 }
MightyPork 0:a81364d9a67b 144
MightyPork 0:a81364d9a67b 145 /** Convert from HSL to HSV */
MightyPork 0:a81364d9a67b 146 void hsl2hsv(const FloatHSL *hsl, FloatHSV *hsv)
MightyPork 0:a81364d9a67b 147 {
MightyPork 0:a81364d9a67b 148 float sat = hsv->s * ((hsl->l < 0.5f) ? hsl->l : (1 - hsl->l));
MightyPork 0:a81364d9a67b 149 hsv->s = 2*sat / (hsl->l + sat);
MightyPork 0:a81364d9a67b 150 hsv->h = hsl->h;
MightyPork 0:a81364d9a67b 151 hsv->v = hsl->l + sat;
MightyPork 0:a81364d9a67b 152 }
MightyPork 0:a81364d9a67b 153
MightyPork 0:a81364d9a67b 154
MightyPork 0:a81364d9a67b 155 uint32_t hsl2hex(const FloatHSL *hsl)
MightyPork 0:a81364d9a67b 156 {
MightyPork 0:a81364d9a67b 157 FloatRGB rgb;
MightyPork 0:a81364d9a67b 158 hsl2rgb(hsl, &rgb);
MightyPork 0:a81364d9a67b 159 return rgb2hex(&rgb);
MightyPork 0:a81364d9a67b 160 }
MightyPork 0:a81364d9a67b 161
MightyPork 0:a81364d9a67b 162 uint32_t hsv2hex(const FloatHSV *hsv)
MightyPork 0:a81364d9a67b 163 {
MightyPork 0:a81364d9a67b 164 FloatRGB rgb;
MightyPork 0:a81364d9a67b 165 hsv2rgb(hsv, &rgb);
MightyPork 0:a81364d9a67b 166 return rgb2hex(&rgb);
MightyPork 0:a81364d9a67b 167 }
MightyPork 0:a81364d9a67b 168
MightyPork 0:a81364d9a67b 169
MightyPork 0:a81364d9a67b 170 uint32_t rgb2hex(FloatRGB *rgb)
MightyPork 0:a81364d9a67b 171 {
MightyPork 0:a81364d9a67b 172 return ((int)floor(rgb->r*255 + 0.5f) << 16) | ((int)floor(rgb->g*255 + 0.5f) << 8) | ((int)floor(rgb->b*255 + 0.5f));
MightyPork 0:a81364d9a67b 173 }
MightyPork 0:a81364d9a67b 174