WS2812B Liblary this use SPI
WS2812B.cpp
- Committer:
- Suzutomo
- Date:
- 2019-12-21
- Revision:
- 6:21a721b31a20
- Parent:
- 5:62b6ac21c199
File content as of revision 6:21a721b31a20:
//-------------------------------------------------------- // SPI を使って WS2812B を点灯するためのクラス // サポートするボード: Nucleo-F446RE //-------------------------------------------------------- #include "WS2812B.h" #include "PeripheralPins.h" // for pinmap_peripheral() WS2812B::WS2812B(PinName pin, int num, bool inv) : spi_(pin, NC, NC), mySpi_((SPI_TypeDef *)pinmap_peripheral(pin, PinMap_SPI_MOSI)) { spi_.format(8, 0); #if defined(STM32F446xx) spi_.frequency(22500000); #else #error This code is not move this board. #endif if (!inv) fp = &WS2812B::SendByteNorm; else fp = &WS2812B::SendByteInv; bright = 1.0; Normalize(); bufferSize = num; colors = (uint32_t *)calloc(bufferSize,sizeof(uint32_t)); if (colors == NULL) printf("can not reserve memory\n"); } uint8_t WS2812B::getRGB(uint32_t x,RGB rgb) { 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() { 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_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 ((x_grb & bit23) == bit23) T1HL(); else T0HL(); x_grb <<= 1; } } SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; // enable interrupt Reset(); } void WS2812B::Clear(int k) { for (int n=0; n<k; n++) colors[n] = 0; Send(); Reset(); } void WS2812B::Send3Bytes(uint16_t x0, uint16_t x1, uint16_t x2) { SendByte(x0); SendByte(x1); SendByte(x2); } void WS2812B::SendByteNorm(uint8_t x) { while ((mySpi_->SR & SPI_SR_TXE) != SPI_SR_TXE) {} mySpi_->DR = x; } void WS2812B::SendByteInv(uint8_t x) { while ((mySpi_->SR & SPI_SR_TXE) != SPI_SR_TXE) {} mySpi_->DR = ~x; } void WS2812B::Brightness(double brightness) { bright = brightness; } void WS2812B::Normalize(bool a) { normalize = a; }