#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 = 8u; /***************************************************************************/ /** @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. polovině si vybere z fronty ring data a uloží je do buferu ve správném * tvaru, 2. polovina dělá "reset", tedy časování rámce (vysílá nuly). * Fronta byla použita (celkem zbytečně) protože zatím netuším jaká data posílat. * To, že celá 2. polovina je zabrána pro reset je také volovina, ale ničemu to nevadí * a je to jednoduché. Šlo by dát reset na začátek a v přerušení na konci do buferu * nasypat data - nebude to trvat tak dlouho aby DMA už začalo posílat data pro LED. * */ class ws2812b : public OneWay { FIFO & ring; public: explicit ws2812b (FIFO & r) noexcept; unsigned int Send (uint8_t * const ptr, const unsigned int len, const bool low = false) override; protected: }; #endif // WS2812B_H