4#ifndef __INC_FASTSPI_BITBANG_H
5#define __INC_FASTSPI_BITBANG_H
23template <u
int8_t DATA_PIN, u
int8_t CLOCK_PIN, u
int32_t SPI_SPEED>
61 static void wait() __attribute__((always_inline)) { }
105 writeBit<7>(b, datapin, hival, loval, hiclock, loclock);
106 writeBit<6>(b, datapin, hival, loval, hiclock, loclock);
107 writeBit<5>(b, datapin, hival, loval, hiclock, loclock);
108 writeBit<4>(b, datapin, hival, loval, hiclock, loclock);
109 writeBit<3>(b, datapin, hival, loval, hiclock, loclock);
110 writeBit<2>(b, datapin, hival, loval, hiclock, loclock);
111 writeBit<1>(b, datapin, hival, loval, hiclock, loclock);
112 writeBit<0>(b, datapin, hival, loval, hiclock, loclock);
122 writeBit<7>(b, clockpin, datapin, hival, loval, hiclock, loclock);
123 writeBit<6>(b, clockpin, datapin, hival, loval, hiclock, loclock);
124 writeBit<5>(b, clockpin, datapin, hival, loval, hiclock, loclock);
125 writeBit<4>(b, clockpin, datapin, hival, loval, hiclock, loclock);
126 writeBit<3>(b, clockpin, datapin, hival, loval, hiclock, loclock);
127 writeBit<2>(b, clockpin, datapin, hival, loval, hiclock, loclock);
128 writeBit<1>(b, clockpin, datapin, hival, loval, hiclock, loclock);
129 writeBit<0>(b, clockpin, datapin, hival, loval, hiclock, loclock);
134#if defined(FASTLED_TEENSY4)
135 #define DELAY_NS (1000 / (SPI_SPEED/1000000))
136 #define CLOCK_HI_DELAY do { delayNanoseconds((DELAY_NS/4)); } while(0);
137 #define CLOCK_LO_DELAY do { delayNanoseconds((DELAY_NS/4)); } while(0);
140 #define MIN_DELAY ((NS(35)>3) ? (NS(35) - 3) : 1)
143 #define CLOCK_HI_DELAY do { delaycycles<MIN_DELAY>(); delaycycles<((SPI_SPEED > 10) ? (((SPI_SPEED-6) / 2) - MIN_DELAY) : (SPI_SPEED))>(); } while(0);
145 #define CLOCK_LO_DELAY do { delaycycles<((SPI_SPEED > 10) ? ((SPI_SPEED-6) / 2) : (SPI_SPEED))>(); } while(0);
151 template <u
int8_t BIT> __attribute__((always_inline, hot))
inline static void writeBit(uint8_t b) {
255#ifdef FAST_SPI_INTERRUPTS_WRITE_PINS
274 writeByte(value, clockpin, datapin, datahi, datalo, clockhi, clocklo);
285 writeByte(value, datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo);
298#ifdef FAST_SPI_INTERRUPTS_WRITE_PINS
299 uint8_t *end = data + len;
314 uint8_t *end = data + len;
317 writeByte(D::adjust(*data++), clockpin, datapin, datahi, datalo, clockhi, clocklo);
328 uint8_t *end = data + len;
331 writeByte(D::adjust(*data++), datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo);
355 int len = pixels.
mLen;
357#ifdef FAST_SPI_INTERRUPTS_WRITE_PINS
360 while(pixels.
has(1)) {
384 while(pixels.
has(1)) {
386 writeBit<0>(1, clockpin, datapin, datahi, datalo, clockhi, clocklo);
402 while(pixels.
has(1)) {
404 writeBit<0>(1, datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo);
406 writeByte(D::adjust(pixels.
loadAndScale0()), datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo);
407 writeByte(D::adjust(pixels.
loadAndScale1()), datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo);
408 writeByte(D::adjust(pixels.
loadAndScale2()), datapin, datahi_clockhi, datalo_clockhi, datahi_clocklo, datalo_clocklo);
central include file for FastLED, defines the CFastLED class/object
static void writeByte(uint8_t b, clock_ptr_t clockpin, data_ptr_t datapin)
writeByte() implementation with data/clock registers passed in.
void select()
Select the SPI output (chip select)
static void wait()
Wait until the SPI subsystem is ready for more data to write.
void writePixels(PixelController< RGB_ORDER > pixels, void *context=NULL)
Write LED pixel data to the SPI interface.
void setSelect(Selectable *pSelect)
Set the pointer for the SPI chip select.
static void writeWord(uint16_t w)
Write a word (two bytes) over SPI.
AVRSoftwareSPIOutput(Selectable *pSelect)
Constructor with selectable for SPI chip select.
static void writeByte(uint8_t b, data_ptr_t datapin, data_t hival, data_t loval, clock_t hiclock, clock_t loclock)
writeByte() implementation with the data register passed in and prebaked values for data hi w/clock h...
static FASTLED_FORCE_INLINE void writeBit(uint8_t b, data_ptr_t clockdatapin, data_t datahiclockhi, data_t dataloclockhi, data_t datahiclocklo, data_t dataloclocklo)
The version of writeBit() to use when clock and data are on the same port with precomputed values for...
static void writeByte(uint8_t b)
Write a single byte over SPI.
void release()
Release the SPI chip select line.
static void writeBytePostWait(uint8_t b)
Write a single byte over SPI and wait afterwards.
void writeBytes(FASTLED_REGISTER uint8_t *data, int len)
Write an array of data to the SPI interface.
static void stop()
Stop the SPI output.
static void writeByte(uint8_t b, clock_ptr_t clockpin, data_ptr_t datapin, data_t hival, data_t loval, clock_t hiclock, clock_t loclock)
writeByte() implementation with not just registers passed in, but pre-baked values for said registers...
Selectable * m_pSelect
SPI chip select.
static FASTLED_FORCE_INLINE void writeBit(uint8_t b, clock_ptr_t clockpin, data_ptr_t datapin, data_t hival, data_t loval, clock_t hiclock, clock_t loclock)
The version of writeBit() to use when clock and data are on separate pins with precomputed values for...
static void writeBytesValueRaw(uint8_t value, int len)
Write multiple bytes of the given value over SPI, without selecting the interface.
static void waitFully()
Wait until the SPI subsystem is ready for more data to write.
void writeBytesValue(uint8_t value, int len)
Write multiple bytes of the given value over SPI.
FastPin< CLOCK_PIN >::port_t clock_t
static void writeBit(uint8_t b)
Write the BIT'th bit out via SPI, setting the data pin then strobing the clock.
FastPin< DATA_PIN >::port_t data_t
static void writeByteNoWait(uint8_t b)
Write a single byte over SPI without waiting.
FastPin< DATA_PIN >::port_ptr_t data_ptr_t
FastPin< CLOCK_PIN >::port_ptr_t clock_ptr_t
void init()
Set the clock/data pins to output and make sure the chip select is released.
void writeBytes(FASTLED_REGISTER uint8_t *data, int len)
Write an array of data to the SPI interface.
AVRSoftwareSPIOutput()
Default constructor.
static FASTLED_FORCE_INLINE void writeBit(uint8_t b, clock_ptr_t clockpin, data_ptr_t datapin)
Write the BIT'th bit out via SPI, setting the data pin then strobing the clock, using the passed in p...
static port_t hival()
Gets the state of the port with this pin HIGH
RwReg port_t
type for a pin read/write register, non-volatile
static void toggle()
Toggle the pin.
static port_t loval()
Gets the state of the port with this pin LOW
static port_t mask()
Get the pin mask.
volatile RwReg * port_ptr_t
type for a pin read/write register, volatile
static void lo()
Set the pin state to LOW
static port_ptr_t port()
Get the output state of the port.
static void setOutput()
Set the pin mode as OUTPUT
static void fastset(FASTLED_REGISTER port_ptr_t port, FASTLED_REGISTER port_t val)
Set the state of a port.
static void hi()
Set the pin state to HIGH
Abstract class for "selectable" things.
Utility functions and classes for managing delay cycles.
#define CLOCK_HI_DELAY
Delay for the clock signal 'high' period.
#define CLOCK_LO_DELAY
Delay for the clock signal 'low' period.
#define FLAG_START_BIT
Flag for the start of an SPI transaction.
#define FASTLED_FORCE_INLINE
#define FASTLED_REGISTER
Helper macro to replace the deprecated 'register' keyword if we're using modern C++ where it's been r...
#define FASTLED_NAMESPACE_END
FASTLED_FORCE_INLINE uint8_t loadAndScale1(int lane, uint8_t scale)
non-template alias of loadAndScale<1>()
FASTLED_FORCE_INLINE uint8_t loadAndScale2(int lane, uint8_t scale)
non-template alias of loadAndScale<2>()
FASTLED_FORCE_INLINE uint8_t loadAndScale0(int lane, uint8_t scale)
non-template alias of loadAndScale<0>()
int mLen
number of LEDs in the data for one lane
FASTLED_FORCE_INLINE void advanceData()
Advance the data pointer forward, adjust position counter.
FASTLED_FORCE_INLINE bool has(int n)
Do we have n pixels left to process?
FASTLED_FORCE_INLINE void stepDithering()
Step the dithering forward.
#define FASTLED_UNUSED(x)