Files at this revision

API Documentation at this revision

Comitter:
Suzutomo
Date:
Sat Dec 21 15:33:10 2019 +0000
Parent:
5:62b6ac21c199
Commit message:
change irq

Changed in this revision

WS2812B.cpp Show annotated file Show diff for this revision Revisions of this file
WS2812B.h Show annotated file Show diff for this revision Revisions of this file
diff -r 62b6ac21c199 -r 21a721b31a20 WS2812B.cpp
--- 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;
+}
+
diff -r 62b6ac21c199 -r 21a721b31a20 WS2812B.h
--- a/WS2812B.h	Wed Jul 17 14:06:08 2019 +0000
+++ b/WS2812B.h	Sat Dec 21 15:33:10 2019 +0000
@@ -10,6 +10,8 @@
 #ifndef STM32F4xx_WS2812B_HPP
 #define STM32F4xx_WS2812B_HPP
 
+enum RGB {B,G,R};
+
 class WS2812B
     {
     public:
@@ -26,11 +28,14 @@
         void Reset() { wait_us(50); }
         void Clear(int k);              // k 個の LED を消灯
         void Brightness(double brightness);
+        uint32_t BrightAdjust(uint32_t x,double brightness);
+        void Normalize(bool a = true);
 
     private:
         uint32_t *colors;
         int bufferSize;
         double bright;
+        bool normalize;
     
         SPI spi_;
         SPI_TypeDef *mySpi_;
@@ -40,10 +45,11 @@
         void Send3Bytes(uint16_t x0, uint16_t x1, uint16_t x2);
         void T0HL() { Send3Bytes(0b11111111, 0b0, 0b0); }   // 0 を送る
         void T1HL() { Send3Bytes(0b11111111, 0b11111111, 0b0); }   // 1 を送る
-        //void T0HL() { Send3Bytes(0b11100000); }   // 0 を送る
-        //void T1HL() { Send3Bytes(0b11111000); }   // 1 を送る
         void SendByteNorm(uint8_t x);   // データをそのまま送る
         void SendByteInv(uint8_t x);    // データを反転して送る
+        
+        uint8_t getRGB(uint32_t color,RGB rgb);
+        uint32_t NormalizeAdjust(uint32_t x);
 
         // コピー・コンストラクタと代入演算子は使用禁止
         WS2812B(const WS2812B&);