RISC-V/V203F6P6/ws2812b/ws2812b.h

56 lines
2.1 KiB
C
Raw Normal View History

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 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