1 #ifndef __INC_FASTSPI_BITBANG_H
2 #define __INC_FASTSPI_BITBANG_H
8 FASTLED_NAMESPACE_BEGIN
18 template <u
int8_t DATA_PIN, u
int8_t CLOCK_PIN, u
int8_t SPI_SPEED>
22 typedef typename FastPin<DATA_PIN>::port_ptr_t data_ptr_t;
27 typedef typename FastPin<DATA_PIN>::port_t data_t;
34 void setSelect(
Selectable *pSelect) { m_pSelect = pSelect; }
45 static void stop() { }
48 static void wait() __attribute__((always_inline)) { }
49 static void waitFully() __attribute__((always_inline)) { wait(); }
51 static void writeByteNoWait(uint8_t b) __attribute__((always_inline)) { writeByte(b); }
52 static void writeBytePostWait(uint8_t b) __attribute__((always_inline)) { writeByte(b); wait(); }
54 static void writeWord(uint16_t w) __attribute__((always_inline)) { writeByte(w>>8); writeByte(w&0xFF); }
57 static void writeByte(uint8_t b) {
70 static void writeByte(uint8_t b, clock_ptr_t clockpin, data_ptr_t datapin) {
71 writeBit<7>(b, clockpin, datapin);
72 writeBit<6>(b, clockpin, datapin);
73 writeBit<5>(b, clockpin, datapin);
74 writeBit<4>(b, clockpin, datapin);
75 writeBit<3>(b, clockpin, datapin);
76 writeBit<2>(b, clockpin, datapin);
77 writeBit<1>(b, clockpin, datapin);
78 writeBit<0>(b, clockpin, datapin);
84 static void writeByte(uint8_t b, data_ptr_t datapin,
85 data_t hival, data_t loval,
86 clock_t hiclock, clock_t loclock) {
87 writeBit<7>(b, datapin, hival, loval, hiclock, loclock);
88 writeBit<6>(b, datapin, hival, loval, hiclock, loclock);
89 writeBit<5>(b, datapin, hival, loval, hiclock, loclock);
90 writeBit<4>(b, datapin, hival, loval, hiclock, loclock);
91 writeBit<3>(b, datapin, hival, loval, hiclock, loclock);
92 writeBit<2>(b, datapin, hival, loval, hiclock, loclock);
93 writeBit<1>(b, datapin, hival, loval, hiclock, loclock);
94 writeBit<0>(b, datapin, hival, loval, hiclock, loclock);
100 static void writeByte(uint8_t b, clock_ptr_t clockpin, data_ptr_t datapin,
101 data_t hival, data_t loval,
102 clock_t hiclock, clock_t loclock) {
103 writeBit<7>(b, clockpin, datapin, hival, loval, hiclock, loclock);
104 writeBit<6>(b, clockpin, datapin, hival, loval, hiclock, loclock);
105 writeBit<5>(b, clockpin, datapin, hival, loval, hiclock, loclock);
106 writeBit<4>(b, clockpin, datapin, hival, loval, hiclock, loclock);
107 writeBit<3>(b, clockpin, datapin, hival, loval, hiclock, loclock);
108 writeBit<2>(b, clockpin, datapin, hival, loval, hiclock, loclock);
109 writeBit<1>(b, clockpin, datapin, hival, loval, hiclock, loclock);
110 writeBit<0>(b, clockpin, datapin, hival, loval, hiclock, loclock);
116 #define MIN_DELAY (NS(35) - 3)
118 #define CLOCK_HI_DELAY delaycycles<MIN_DELAY>(); delaycycles<(((SPI_SPEED-6) / 2) - MIN_DELAY)>();
119 #define CLOCK_LO_DELAY delaycycles<(((SPI_SPEED-6) / 4))>();
122 template <u
int8_t BIT> __attribute__((always_inline, hot))
inline static void writeBit(uint8_t b) {
138 template <u
int8_t BIT> __attribute__((always_inline))
inline static void writeBit(uint8_t b, clock_ptr_t clockpin, data_ptr_t datapin) {
153 template <u
int8_t BIT> __attribute__((always_inline))
inline static void writeBit(uint8_t b, clock_ptr_t clockpin, data_ptr_t datapin,
154 data_t hival, data_t loval, clock_t hiclock, clock_t loclock) {
170 template <u
int8_t BIT> __attribute__((always_inline))
inline static void writeBit(uint8_t b, data_ptr_t clockdatapin,
171 data_t datahiclockhi, data_t dataloclockhi,
172 data_t datahiclocklo, data_t dataloclocklo) {
192 void select() {
if(m_pSelect != NULL) { m_pSelect->select(); } }
195 void release() {
if(m_pSelect != NULL) { m_pSelect->release(); } }
198 void writeBytesValue(uint8_t value,
int len) {
200 writeBytesValueRaw(value, len);
204 static void writeBytesValueRaw(uint8_t value,
int len) {
205 #ifdef FAST_SPI_INTERRUPTS_WRITE_PINS
224 writeByte(value, clockpin, datapin, datahi, datalo, clockhi, clocklo);
235 writeByte(value, datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo);
243 template <
class D>
void writeBytes(
register uint8_t *data,
int len) {
245 #ifdef FAST_SPI_INTERRUPTS_WRITE_PINS
246 uint8_t *end = data + len;
248 writeByte(D::adjust(*data++));
261 uint8_t *end = data + len;
264 writeByte(D::adjust(*data++), clockpin, datapin, datahi, datalo, clockhi, clocklo);
275 uint8_t *end = data + len;
278 writeByte(D::adjust(*data++), datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo);
288 void writeBytes(
register uint8_t *data,
int len) { writeBytes<DATA_NOP>(data, len); }
294 template <u
int8_t FLAGS,
class D, EOrder RGB_ORDER> __attribute__((noinline))
void writePixels(
PixelController<RGB_ORDER> pixels) {
296 int len = pixels.mLen;
298 #ifdef FAST_SPI_INTERRUPTS_WRITE_PINS
301 while(pixels.has(1)) {
302 if(FLAGS & FLAG_START_BIT) {
305 writeByte(D::adjust(pixels.loadAndScale0()));
306 writeByte(D::adjust(pixels.loadAndScale1()));
307 writeByte(D::adjust(pixels.loadAndScale2()));
308 pixels.advanceData();
309 pixels.stepDithering();
325 while(pixels.has(1)) {
326 if(FLAGS & FLAG_START_BIT) {
327 writeBit<0>(1, clockpin, datapin, datahi, datalo, clockhi, clocklo);
329 writeByte(D::adjust(pixels.loadAndScale0()), clockpin, datapin, datahi, datalo, clockhi, clocklo);
330 writeByte(D::adjust(pixels.loadAndScale1()), clockpin, datapin, datahi, datalo, clockhi, clocklo);
331 writeByte(D::adjust(pixels.loadAndScale2()), clockpin, datapin, datahi, datalo, clockhi, clocklo);
332 pixels.advanceData();
333 pixels.stepDithering();
343 while(pixels.has(1)) {
344 if(FLAGS & FLAG_START_BIT) {
345 writeBit<0>(1, datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo);
347 writeByte(D::adjust(pixels.loadAndScale0()), datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo);
348 writeByte(D::adjust(pixels.loadAndScale1()), datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo);
349 writeByte(D::adjust(pixels.loadAndScale2()), datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo);
350 pixels.advanceData();
351 pixels.stepDithering();
360 FASTLED_NAMESPACE_END
central include file for FastLED, defines the CFastLED class/object
Utility functions and classes for managing delaycycles.
The simplest level of Pin class.