WS2812B Liblary this use SPI
WS2812B.cpp@6:21a721b31a20, 2019-12-21 (annotated)
- 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?
User | Revision | Line number | New 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 |