#ifndef WS2812B_H #define WS2812B_H #include #include "oneway.h" #include "fifo.h" static constexpr int BWW = 3; struct OneColor { uint32_t b0 : BWW; uint32_t b1 : BWW; uint32_t b2 : BWW; uint32_t b3 : BWW; uint32_t b4 : BWW; uint32_t b5 : BWW; uint32_t b6 : BWW; uint32_t b7 : BWW; explicit OneColor (const uint8_t c) noexcept; unsigned to_string (char * ptr, const int m = BWW); }__attribute__((packed)); struct Color { OneColor g,r,b; }__attribute__((packed)); union Entry { struct _ws { uint8_t g,r,b; uint8_t order; // určuje pořadí LED } ws; uint32_t number; explicit Entry (const uint32_t e) noexcept { number = e; } }; /*************************************************************************************/ static constexpr unsigned NUMLEDS = 4u; static constexpr unsigned FIFOLEN = 8u; // min. depth je 8, jinak mocnina 2 >= NUMLEDS /*************************************************************************************/ /** @class ws2812b * @brief Driver pro WS2812B * On ten driver je trochu divný. Běží nad SPI s použitím pinu MOSI, 1 bit barvy * jsou 3 bity SPI. Funguje to tak, že SPI běží přes DMA v cirkulárním módu, tedy * pořád, v 1. části dělá "reset", tedy časování rámce (vysílá nuly). * V 2. části si vybere z fronty ring data a uloží je do buferu ve správném * tvaru. Využívá se toho, že přerušení přijde až na konci a naplnění daty * netrvá dlouho, takže se přepisuje jen část, která se právě nevysílá. * Fronta byla použita (celkem zbytečně) protože zatím netuším jaká data posílat. * NOTE * Protože WS2812B je 5V záležitost a procesor je napájen jen 3.3V, funguje to * na hraně a je dobré zapojit mezi MOSI a +5V rezistor 1k. Je to pak stabilnější. * */ class ws2812b : public OneWay { FIFO & ring; public: explicit ws2812b (FIFO & r) noexcept : OneWay (), ring(r) {} unsigned int Send (uint8_t * const ptr, const unsigned int len) override; protected: }; #endif // WS2812B_H