WS2812B Liblary this use SPI

Committer:
Suzutomo
Date:
Sat Dec 21 15:33:10 2019 +0000
Revision:
6:21a721b31a20
Parent:
5:62b6ac21c199
change irq

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Suzutomo 0:6a2dcf5cd545 1 //--------------------------------------------------------
Suzutomo 0:6a2dcf5cd545 2 // SPI を使って WS2812B を点灯するためのクラス
Suzutomo 6:21a721b31a20 3 // サポートするボード: Nucleo-F446RE
Suzutomo 0:6a2dcf5cd545 4 //--------------------------------------------------------
Suzutomo 0:6a2dcf5cd545 5
Suzutomo 0:6a2dcf5cd545 6 #include "WS2812B.h"
Suzutomo 0:6a2dcf5cd545 7 #include "PeripheralPins.h" // for pinmap_peripheral()
Suzutomo 0:6a2dcf5cd545 8
Suzutomo 3:c0a82b9775e6 9 WS2812B::WS2812B(PinName pin, int num, bool inv)
Suzutomo 0:6a2dcf5cd545 10 : spi_(pin, NC, NC),
Suzutomo 0:6a2dcf5cd545 11 mySpi_((SPI_TypeDef *)pinmap_peripheral(pin, PinMap_SPI_MOSI))
Suzutomo 0:6a2dcf5cd545 12 {
Suzutomo 5:62b6ac21c199 13 spi_.format(8, 0);
Suzutomo 0:6a2dcf5cd545 14 #if defined(STM32F446xx)
Suzutomo 1:c7bb475f0022 15 spi_.frequency(22500000);
Suzutomo 0:6a2dcf5cd545 16 #else
Suzutomo 0:6a2dcf5cd545 17 #error This code is not move this board.
Suzutomo 0:6a2dcf5cd545 18 #endif
Suzutomo 0:6a2dcf5cd545 19 if (!inv) fp = &WS2812B::SendByteNorm;
Suzutomo 0:6a2dcf5cd545 20 else fp = &WS2812B::SendByteInv;
Suzutomo 3:c0a82b9775e6 21
Suzutomo 6:21a721b31a20 22 bright = 1.0;
Suzutomo 6:21a721b31a20 23 Normalize();
Suzutomo 6:21a721b31a20 24
Suzutomo 6:21a721b31a20 25 bufferSize = num;
Suzutomo 6:21a721b31a20 26 colors = (uint32_t *)calloc(bufferSize,sizeof(uint32_t));
Suzutomo 3:c0a82b9775e6 27 if (colors == NULL) printf("can not reserve memory\n");
Suzutomo 3:c0a82b9775e6 28 }
Suzutomo 3:c0a82b9775e6 29
Suzutomo 6:21a721b31a20 30 uint8_t WS2812B::getRGB(uint32_t x,RGB rgb)
Suzutomo 3:c0a82b9775e6 31 {
Suzutomo 6:21a721b31a20 32 return (uint8_t)((x >> (rgb * 8)) & 0xFF);
Suzutomo 6:21a721b31a20 33 }
Suzutomo 6:21a721b31a20 34
Suzutomo 6:21a721b31a20 35 uint32_t WS2812B::BrightAdjust(uint32_t x,double brightness)
Suzutomo 6:21a721b31a20 36 {
Suzutomo 6:21a721b31a20 37 uint8_t r = getRGB(x,R) * brightness;
Suzutomo 6:21a721b31a20 38 uint8_t g = getRGB(x,G) * brightness;
Suzutomo 6:21a721b31a20 39 uint8_t b = getRGB(x,B) * brightness;
Suzutomo 3:c0a82b9775e6 40 x = (r << 16) | (g << 8) | b;
Suzutomo 3:c0a82b9775e6 41 return x;
Suzutomo 3:c0a82b9775e6 42 }
Suzutomo 3:c0a82b9775e6 43
Suzutomo 6:21a721b31a20 44 uint32_t WS2812B::NormalizeAdjust(uint32_t x) {
Suzutomo 6:21a721b31a20 45 double m = 0;
Suzutomo 6:21a721b31a20 46 for (int i = 0;i < 3;i++) m += (double)getRGB(x,(RGB)i);
Suzutomo 6:21a721b31a20 47 return BrightAdjust(x,(0xFF / m) * (m / (0xFF * 3)));
Suzutomo 6:21a721b31a20 48 }
Suzutomo 6:21a721b31a20 49
Suzutomo 6:21a721b31a20 50 // 特定の位置の色を変更する
Suzutomo 3:c0a82b9775e6 51 void WS2812B::Write(int index,uint32_t x,double brightness)
Suzutomo 3:c0a82b9775e6 52 {
Suzutomo 3:c0a82b9775e6 53 if (index >= 0 && index < bufferSize) colors[index] = BrightAdjust(x,brightness);
Suzutomo 0:6a2dcf5cd545 54 }
Suzutomo 0:6a2dcf5cd545 55
Suzutomo 6:21a721b31a20 56 // すべての色を変更する
Suzutomo 3:c0a82b9775e6 57 void WS2812B::Write(uint32_t x,double brightness)
Suzutomo 0:6a2dcf5cd545 58 {
Suzutomo 3:c0a82b9775e6 59 for (int i = 0; i < bufferSize; i++) colors[i] = BrightAdjust(x,brightness);
Suzutomo 0:6a2dcf5cd545 60 }
Suzutomo 0:6a2dcf5cd545 61
Suzutomo 6:21a721b31a20 62 // バッファの色情報を送る
Suzutomo 3:c0a82b9775e6 63 void WS2812B::Send()
Suzutomo 0:6a2dcf5cd545 64 {
Suzutomo 6:21a721b31a20 65 static const uint32_t bit23 = 0x800000;
Suzutomo 6:21a721b31a20 66 SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
Suzutomo 6:21a721b31a20 67 // SysTick_CTRL_TICKINT_Msk | ←割り込みを無効
Suzutomo 6:21a721b31a20 68 SysTick_CTRL_ENABLE_Msk;
Suzutomo 3:c0a82b9775e6 69 for (int i = 0; i < bufferSize; i++) {
Suzutomo 6:21a721b31a20 70 uint32_t x_rgb;
Suzutomo 6:21a721b31a20 71 if (normalize) x_rgb = NormalizeAdjust(colors[i]);
Suzutomo 6:21a721b31a20 72 else x_rgb = colors[i];
Suzutomo 6:21a721b31a20 73 x_rgb = BrightAdjust(x_rgb,bright);
Suzutomo 6:21a721b31a20 74 uint32_t x_grb = getRGB(x_rgb,G) << 16 | getRGB(x_rgb,R) << 8 | getRGB(x_rgb,B);
Suzutomo 6:21a721b31a20 75
Suzutomo 3:c0a82b9775e6 76 for (int n=0; n<24; n++) {
Suzutomo 6:21a721b31a20 77 if ((x_grb & bit23) == bit23) T1HL();
Suzutomo 3:c0a82b9775e6 78 else T0HL();
Suzutomo 6:21a721b31a20 79 x_grb <<= 1;
Suzutomo 3:c0a82b9775e6 80 }
Suzutomo 3:c0a82b9775e6 81 }
Suzutomo 6:21a721b31a20 82 SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; // enable interrupt
Suzutomo 3:c0a82b9775e6 83 Reset();
Suzutomo 3:c0a82b9775e6 84 }
Suzutomo 0:6a2dcf5cd545 85
Suzutomo 0:6a2dcf5cd545 86 void WS2812B::Clear(int k)
Suzutomo 0:6a2dcf5cd545 87 {
Suzutomo 3:c0a82b9775e6 88 for (int n=0; n<k; n++) colors[n] = 0;
Suzutomo 3:c0a82b9775e6 89 Send();
Suzutomo 0:6a2dcf5cd545 90 Reset();
Suzutomo 0:6a2dcf5cd545 91 }
Suzutomo 0:6a2dcf5cd545 92
Suzutomo 4:02e88df0ae2d 93 void WS2812B::Send3Bytes(uint16_t x0, uint16_t x1, uint16_t x2)
Suzutomo 0:6a2dcf5cd545 94 {
Suzutomo 0:6a2dcf5cd545 95 SendByte(x0);
Suzutomo 0:6a2dcf5cd545 96 SendByte(x1);
Suzutomo 0:6a2dcf5cd545 97 SendByte(x2);
Suzutomo 0:6a2dcf5cd545 98 }
Suzutomo 0:6a2dcf5cd545 99
Suzutomo 0:6a2dcf5cd545 100 void WS2812B::SendByteNorm(uint8_t x)
Suzutomo 0:6a2dcf5cd545 101 {
Suzutomo 0:6a2dcf5cd545 102 while ((mySpi_->SR & SPI_SR_TXE) != SPI_SR_TXE) {}
Suzutomo 0:6a2dcf5cd545 103 mySpi_->DR = x;
Suzutomo 0:6a2dcf5cd545 104 }
Suzutomo 0:6a2dcf5cd545 105
Suzutomo 0:6a2dcf5cd545 106 void WS2812B::SendByteInv(uint8_t x)
Suzutomo 0:6a2dcf5cd545 107 {
Suzutomo 0:6a2dcf5cd545 108 while ((mySpi_->SR & SPI_SR_TXE) != SPI_SR_TXE) {}
Suzutomo 0:6a2dcf5cd545 109 mySpi_->DR = ~x;
Suzutomo 0:6a2dcf5cd545 110 }
Suzutomo 0:6a2dcf5cd545 111
Suzutomo 3:c0a82b9775e6 112 void WS2812B::Brightness(double brightness)
Suzutomo 3:c0a82b9775e6 113 {
Suzutomo 3:c0a82b9775e6 114 bright = brightness;
Suzutomo 3:c0a82b9775e6 115 }
Suzutomo 3:c0a82b9775e6 116
Suzutomo 6:21a721b31a20 117 void WS2812B::Normalize(bool a) {
Suzutomo 6:21a721b31a20 118 normalize = a;
Suzutomo 6:21a721b31a20 119 }
Suzutomo 6:21a721b31a20 120