WS2812B Liblary this use SPI

Revision:
6:21a721b31a20
Parent:
5:62b6ac21c199
--- a/WS2812B.cpp	Wed Jul 17 14:06:08 2019 +0000
+++ b/WS2812B.cpp	Sat Dec 21 15:33:10 2019 +0000
@@ -1,8 +1,6 @@
 //--------------------------------------------------------
 //  SPI を使って WS2812B を点灯するためのクラス
-//      サポートするボード: Nucleo-F401RE, Nucleo-F446RE
-//
-//  2016/11/21, Copyright (c) 2016 MIKAMI, Naoki
+//      サポートするボード: Nucleo-F446RE
 //--------------------------------------------------------
 
 #include "WS2812B.h"
@@ -21,56 +19,68 @@
     if (!inv) fp = &WS2812B::SendByteNorm;
     else      fp = &WS2812B::SendByteInv;
 
-
-    colors = (uint32_t *)calloc(num,sizeof(uint32_t));
+    bright = 1.0;
+    Normalize();
+    
+    bufferSize = num;
+    colors = (uint32_t *)calloc(bufferSize,sizeof(uint32_t));
     if (colors == NULL) printf("can not reserve memory\n");
-    bufferSize = num;
-    bright = 1.0;
 }
 
-uint32_t BrightAdjust(uint32_t x,double brightness)
+uint8_t WS2812B::getRGB(uint32_t x,RGB rgb)
 {
-    uint8_t r = ((x >> 16) & 0xFF) * brightness;
-    uint8_t g = ((x >> 8) & 0xFF) * brightness;
-    uint8_t b = ((x >> 0) & 0xFF) * brightness;
+    return (uint8_t)((x >> (rgb * 8)) & 0xFF);
+}
+
+uint32_t WS2812B::BrightAdjust(uint32_t x,double brightness)
+{
+    uint8_t r = getRGB(x,R) * brightness;
+    uint8_t g = getRGB(x,G) * brightness;
+    uint8_t b = getRGB(x,B) * brightness;
     x = (r << 16) | (g << 8) | b;
     return x;
 }
 
+uint32_t WS2812B::NormalizeAdjust(uint32_t x) {
+    double m = 0;
+    for (int i = 0;i < 3;i++) m += (double)getRGB(x,(RGB)i);
+    return BrightAdjust(x,(0xFF / m) * (m / (0xFF * 3)));
+}
+
+// 特定の位置の色を変更する
 void WS2812B::Write(int index,uint32_t x,double brightness)
 {
     if (index >= 0 && index < bufferSize) colors[index] = BrightAdjust(x,brightness);
 }
 
+// すべての色を変更する
 void WS2812B::Write(uint32_t x,double brightness)
 {
     for (int i = 0; i < bufferSize; i++) colors[i] = BrightAdjust(x,brightness);
 }
 
+// バッファの色情報を送る
 void WS2812B::Send()
 {
-    uint32_t *colors_m;
-    colors_m = (uint32_t *)calloc(bufferSize,sizeof(uint32_t));
+    static const uint32_t bit23 = 0x800000;
+    SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
+                 // SysTick_CTRL_TICKINT_Msk   |  ←割り込みを無効
+                    SysTick_CTRL_ENABLE_Msk; 
     for (int i = 0; i < bufferSize; i++) {
-        uint32_t x = colors[i];
-        x = BrightAdjust(x,bright);
-        colors_m[i] = 0;
-        colors_m[i] |= ((x >> 8) & 0xFF00);
-        colors_m[i] |= ((x << 8) & 0xFF0000);
-        colors_m[i] |= (x & 0xFF);
-    }
-    static const uint32_t bit23 = 0x800000;
-    __disable_irq();
-    for (int i = 0; i < bufferSize; i++) {
+        uint32_t x_rgb;
+        if (normalize) x_rgb = NormalizeAdjust(colors[i]);
+        else x_rgb = colors[i];
+        x_rgb = BrightAdjust(x_rgb,bright);
+        uint32_t x_grb = getRGB(x_rgb,G) << 16 | getRGB(x_rgb,R) << 8 | getRGB(x_rgb,B);
+        
         for (int n=0; n<24; n++) {
-            if ((colors_m[i] & bit23) == bit23) T1HL();
+            if ((x_grb & bit23) == bit23) T1HL();
             else                      T0HL();
-            colors_m[i] <<= 1;
+            x_grb <<= 1;
         }
     }
+    SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; // enable interrupt
     Reset();
-    __enable_irq();
-    free(colors_m);
 }
 
 void WS2812B::Clear(int k)
@@ -104,3 +114,7 @@
     bright = brightness;
 }
 
+void WS2812B::Normalize(bool a) {
+    normalize = a;
+}
+