52 lines
1.9 KiB
C++
52 lines
1.9 KiB
C++
#ifndef WS2812B_H
|
|
#define WS2812B_H
|
|
#include <stdint.h>
|
|
#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<uint8_t> {
|
|
FIFO<uint32_t,8> & ring;
|
|
public:
|
|
explicit ws2812b (FIFO<uint32_t,8> & r) noexcept;
|
|
unsigned int Send (uint8_t * const ptr, const unsigned int len, const bool low = false) override;
|
|
protected:
|
|
};
|
|
|
|
#endif // WS2812B_H
|