2025-01-25 10:55:11 +01:00
|
|
|
#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; }
|
|
|
|
};
|
2025-01-25 12:21:08 +01:00
|
|
|
/*************************************************************************************/
|
|
|
|
static constexpr unsigned NUMLEDS = 4u;
|
|
|
|
static constexpr unsigned FIFOLEN = 8u; // min. depth je 8, jinak mocnina 2 >= NUMLEDS
|
|
|
|
/*************************************************************************************/
|
2025-01-25 10:55:11 +01:00
|
|
|
/** @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
|
2025-01-25 12:21:08 +01:00
|
|
|
* 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
|
2025-01-25 15:08:53 +01:00
|
|
|
* netrvá dlouho, takže se přepisuje jen část, která se právě nevysílá.
|
2025-01-25 10:55:11 +01:00
|
|
|
* Fronta byla použita (celkem zbytečně) protože zatím netuším jaká data posílat.
|
2025-01-25 15:08:53 +01:00
|
|
|
* 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ší.
|
2025-01-25 10:55:11 +01:00
|
|
|
* */
|
|
|
|
class ws2812b : public OneWay<uint8_t> {
|
2025-01-25 12:21:08 +01:00
|
|
|
FIFO<uint32_t,FIFOLEN> & ring;
|
2025-01-25 10:55:11 +01:00
|
|
|
public:
|
2025-01-25 13:59:00 +01:00
|
|
|
explicit ws2812b (FIFO<uint32_t,FIFOLEN> & r) noexcept : OneWay (), ring(r) {}
|
2025-01-25 12:21:08 +01:00
|
|
|
unsigned int Send (uint8_t * const ptr, const unsigned int len) override;
|
2025-01-25 10:55:11 +01:00
|
|
|
protected:
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif // WS2812B_H
|