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
|
|