WS2812B Liblary this use SPI
Diff: WS2812B.cpp
- 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; +} +