FastLED 3.10.6
Loading...
Searching...
No Matches
my9221.h
Go to the documentation of this file.
1#pragma once
2
25
26#include "pixeltypes.h"
27#include "crgb.h"
28#include "eorder.h"
29#include "fl/stl/noexcept.h"
30#include "fl/system/fastpin.h"
31#include "fl/system/delay.h"
32
34//
35// MY9221 definition - dual-edge (DDR) clocked 12-channel driver
36//
38
45template <int DATA_PIN, fl::u8 CLOCK_PIN, EOrder RGB_ORDER = RGB, fl::u32 SPI_SPEED = DATA_RATE_MHZ(1)>
46class MY9221Controller : public CPixelLEDController<RGB_ORDER> {
47 typedef fl::FastPin<DATA_PIN> DataPin;
48 typedef fl::FastPin<CLOCK_PIN> ClockPin;
49
51 static constexpr fl::u16 kCommandWord = 0x0010;
52
54 static constexpr fl::u32 kLatchDelayUs = 230;
55
57 if (bit) {
58 DataPin::hi();
59 } else {
60 DataPin::lo();
61 }
62 // Dual-edge: one toggle clocks one bit.
63 ClockPin::toggle();
64 }
65
67 void sendWord(fl::u16 data) {
68 for (int i = 0; i < 16; ++i) {
69 writeBit((data & 0x8000) ? 1 : 0);
70 data = static_cast<fl::u16>(data << 1);
71 }
72 }
73
74 void sendLed(fl::u8 c0, fl::u8 c1, fl::u8 c2) {
75 sendWord(c0);
76 sendWord(c1);
77 sendWord(c2);
78 }
79
80 void latch() {
81 ClockPin::lo();
82 DataPin::lo();
84
85 // Four DI pulses while DCKI is held low.
86 for (int i = 0; i < 4; ++i) {
87 DataPin::hi();
88 DataPin::lo();
89 }
90 }
91
92public:
94
95 virtual void init() {
96 DataPin::setOutput();
97 ClockPin::setOutput();
98 DataPin::lo();
99 ClockPin::lo();
100 (void)SPI_SPEED;
101 }
102
103protected:
105 virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
106 // Ensure known idle levels before the first edge.
107 DataPin::lo();
108 ClockPin::lo();
109
110 while (pixels.has(1)) {
111 fl::u8 ch[4][3] = {
112 {0, 0, 0},
113 {0, 0, 0},
114 {0, 0, 0},
115 {0, 0, 0}
116 };
117
118 // Map up to 4 CRGB pixels onto one chip: LED0->OUT0 .. LED3->OUT3.
119 for (int led = 0; led < 4 && pixels.has(1); ++led) {
120 ch[led][0] = pixels.loadAndScale0();
121 ch[led][1] = pixels.loadAndScale1();
122 ch[led][2] = pixels.loadAndScale2();
123 pixels.advanceData();
124 pixels.stepDithering();
125 }
126
128
129 // Hardware shift order is OUT3, OUT2, OUT1, OUT0.
130 for (int out = 3; out >= 0; --out) {
131 sendLed(ch[out][0], ch[out][1], ch[out][2]);
132 }
133 }
134
135 latch();
136 }
137};
CPixelLEDController(RegistrationMode mode)
virtual void showPixels(PixelController< RGB_ORDER > &pixels)
Send the LED data to the strip.
Definition my9221.h:105
fl::FastPin< CLOCK_PIN > ClockPin
Definition my9221.h:48
void sendWord(fl::u16 data)
Shift out one 16-bit word MSB-first, one clock edge per bit.
Definition my9221.h:67
MY9221Controller() FL_NO_EXCEPT
Definition my9221.h:93
static constexpr fl::u32 kLatchDelayUs
Datasheet latch: hold DCKI low for >220 us after last data, then pulse DI 4x.
Definition my9221.h:54
FASTLED_FORCE_INLINE void writeBit(fl::u8 bit)
Definition my9221.h:56
static constexpr fl::u16 kCommandWord
Command word: 8-bit grayscale (CMD[9:8]=00), APDM waveform (CMD[4]=1).
Definition my9221.h:51
void sendLed(fl::u8 c0, fl::u8 c1, fl::u8 c2)
Definition my9221.h:74
void latch()
Definition my9221.h:80
fl::FastPin< DATA_PIN > DataPin
Definition my9221.h:47
virtual void init()
Initialize the LED controller.
Definition my9221.h:95
#define FASTLED_FORCE_INLINE
Delay utilities for FastLED Includes nanosecond-precision delays, cycle counting, and microsecond del...
unsigned char u8
Definition stdint.h:131
void delayMicroseconds(u32 us)
Delay for a given number of microseconds.
Includes defintions for RGB and HSV pixels.
#define FL_NO_EXCEPT
FASTLED_FORCE_INLINE fl::u8 loadAndScale0(int lane, fl::u8 scale)
non-template alias of loadAndScale<0>()
FASTLED_FORCE_INLINE void advanceData()
Advance the data pointer forward, adjust position counter.
FASTLED_FORCE_INLINE fl::u8 loadAndScale1(int lane, fl::u8 scale)
non-template alias of loadAndScale<1>()
FASTLED_FORCE_INLINE bool has(int n)
Do we have n pixels left to process?
FASTLED_FORCE_INLINE void stepDithering()
Step the dithering forward - creates triangular wave that toggles between pixels.
FASTLED_FORCE_INLINE fl::u8 loadAndScale2(int lane, fl::u8 scale)
non-template alias of loadAndScale<2>()
Pixel controller class.