RISC-V/V203R6/ws2812b/ws2812b.h
2025-01-25 10:55:11 +01:00

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