Removed ws2812b i2s library dependency, updated README
I have added a pre-configured version of the ws2812b i2s library to the Arduino code. This removes the need to download and install the ws2812b i2s library manually. The ws2812b code has been preconfigured to reduce the temporal compared to the default value. The default value was found to cause excessive flickering. The readme has been updated to reflect this change. Also added a note about the maximum number of LEDs (255)
This commit is contained in:
parent
3241e43435
commit
f860922d67
@ -63,10 +63,10 @@ If `pip` is not found try using `python -m pip install` instead.
|
||||
## Arduino dependencies
|
||||
ESP8266 firmare is uploaded using the Arduino IDE. See [this tutorial](https://learn.sparkfun.com/tutorials/esp8266-thing-hookup-guide/installing-the-esp8266-arduino-addon) to setup the Arduino IDE for ESP8266.
|
||||
|
||||
This [ws2812b i2s library](https://github.com/JoDaNl/esp8266_ws2812_i2s) must be downloaded and installed in the Arduino libraries folder.
|
||||
|
||||
<!-- This [ws2812b i2s library](https://github.com/JoDaNl/esp8266_ws2812_i2s) must be downloaded and installed in the Arduino libraries folder.
|
||||
-->
|
||||
# Hardware Connections
|
||||
The ESP8266 has hardware support for [I²S](https://en.wikipedia.org/wiki/I%C2%B2S) and this peripheral is used by the [ws2812b i2s library](https://github.com/JoDaNl/esp8266_ws2812_i2s) to control the ws2812b LED strip. This signficantly improves performance compared to bit-banging the IO pin. Unfortunately, this means that the LED strip **must** be connected to the RX1 pin, which is not accessible in some ESP8266 modules (such as the ESP-01).
|
||||
The ESP8266 has hardware support for [I²S](https://en.wikipedia.org/wiki/I%C2%B2S) and this peripheral is used <!-- by the [ws2812b i2s library](https://github.com/JoDaNl/esp8266_ws2812_i2s) -->to control the ws2812b LED strip. This signficantly improves performance compared to bit-banging the IO pin. Unfortunately, this means that the LED strip **must** be connected to the RX1 pin, which is not accessible in some ESP8266 modules (such as the ESP-01).
|
||||
|
||||
The RX1 pin on the ESP8266 module should be connected to the data input pin of the ws2812b LED strip (often labelled DIN or D0).
|
||||
|
||||
@ -99,5 +99,8 @@ A PyQtGraph GUI will open to display the output of the visualization on the comp
|
||||
|
||||
If you encounter any issues or have questions about this project, feel free to open a new issue.
|
||||
|
||||
# Limitations
|
||||
The visualization code currently supports up to 255 LEDs. Support for additional LEDs will be added in the near future.
|
||||
|
||||
# License
|
||||
All code in this project is released under the MIT License.
|
26
arduino/ws2812_controller/ws2812.h
Normal file
26
arduino/ws2812_controller/ws2812.h
Normal file
@ -0,0 +1,26 @@
|
||||
// ws2812.h
|
||||
|
||||
#ifndef __WS2812_H__
|
||||
#define __WS2812_H__
|
||||
|
||||
// Gamma Correction
|
||||
// Uses a nonlinear lookup table to correct for human perception of light.
|
||||
// When gamma correction is used, a brightness value of 2X should appear twice
|
||||
// as bright as a value of X.
|
||||
// 1 = Enable gamma correction
|
||||
// 0 = Disable gamma correction
|
||||
// Note: There seems to be a bug and you can't actually disable this
|
||||
#define WS2812_GAMMA_CORRECTION (0)
|
||||
|
||||
// Temporal Dithering
|
||||
// Dithering preserves color and light when brightness is low.
|
||||
// Sometimes this can cause undesirable flickering.
|
||||
// 1 = Disable temporal dithering
|
||||
// 2, 6, 8 = Enable temporal dithering (larger values = more dithering)
|
||||
#define WS2812_DITHER_NUM (4)
|
||||
|
||||
#define WS2812_USE_INTERRUPT (0) // not supported yet
|
||||
|
||||
#endif
|
||||
|
||||
// end of file
|
@ -3,10 +3,11 @@
|
||||
#include <WebSocketsServer.h>
|
||||
#include <Hash.h>
|
||||
#include <WiFiUdp.h>
|
||||
#include <ws2812_i2s.h>
|
||||
#include "ws2812_i2s.h"
|
||||
|
||||
// Set this to the number of LEDs in your LED strip
|
||||
#define NUM_LEDS 260
|
||||
#define NUM_LEDS 60
|
||||
// Maximum number of packets to hold in the buffer. Don't change this.
|
||||
#define BUFFER_LEN 1024
|
||||
|
||||
// Wifi and socket settings
|
||||
|
172
arduino/ws2812_controller/ws2812_defs.h
Normal file
172
arduino/ws2812_controller/ws2812_defs.h
Normal file
@ -0,0 +1,172 @@
|
||||
// w2812_defs.h
|
||||
//
|
||||
// contains material from Charles Lohr, but changed by me.
|
||||
|
||||
#ifndef __WS2812_I2S_DEFS_H__
|
||||
#define __WS2812_I2S_DEFS_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// include file from project folder
|
||||
#include "ws2812.h"
|
||||
|
||||
// -----------------------------------------------------
|
||||
|
||||
// Helper macro's
|
||||
|
||||
#define NUM_RGB_BYTES (num_leds * 3)
|
||||
#define NUM_I2S_PIXEL_BYTES (num_leds * 3 * 4) // (#leds) * (RGB) * (4 i2s bits)
|
||||
#define NUM_I2S_PIXEL_WORDS (num_leds * 3)
|
||||
|
||||
// -----------------------------------------------------
|
||||
|
||||
// I2S timing parameters
|
||||
|
||||
// Creates an I2S SR of 93,750 Hz, or 3 MHz Bitclock (.333us/sample)
|
||||
// Measured on scope : 4 bitclock-ticks every 1200ns --> 300ns bitclock ???
|
||||
// 12000000L/(div*bestbck*2)
|
||||
|
||||
#define WS_I2S_BCK (17)
|
||||
#define WS_I2S_DIV (4)
|
||||
#define NUM_I2S_ZERO_BYTES (28) // WS2812 LED Treset = 67us (must be >50us)
|
||||
#define NUM_I2S_ZERO_WORDS (NUM_I2S_ZERO_BYTES / 4)
|
||||
|
||||
// -----------------------------------------------------
|
||||
|
||||
#ifndef i2c_bbpll
|
||||
#define i2c_bbpll 0x67
|
||||
#define i2c_bbpll_en_audio_clock_out 4
|
||||
#define i2c_bbpll_en_audio_clock_out_msb 7
|
||||
#define i2c_bbpll_en_audio_clock_out_lsb 7
|
||||
#define i2c_bbpll_hostid 4
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------
|
||||
|
||||
#define i2c_writeReg_Mask(block, host_id, reg_add, Msb, Lsb, indata) rom_i2c_writeReg_Mask(block, host_id, reg_add, Msb, Lsb, indata)
|
||||
#define i2c_readReg_Mask(block, host_id, reg_add, Msb, Lsb) rom_i2c_readReg_Mask(block, host_id, reg_add, Msb, Lsb)
|
||||
#define i2c_writeReg_Mask_def(block, reg_add, indata) i2c_writeReg_Mask(block, block##_hostid, reg_add, reg_add##_msb, reg_add##_lsb, indata)
|
||||
#define i2c_readReg_Mask_def(block, reg_add) i2c_readReg_Mask(block, block##_hostid, reg_add, reg_add##_msb, reg_add##_lsb)
|
||||
|
||||
// -----------------------------------------------------
|
||||
|
||||
#ifndef ETS_SLC_INUM
|
||||
#define ETS_SLC_INUM 1
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------
|
||||
|
||||
// from i2s_reg.h
|
||||
|
||||
#define DR_REG_I2S_BASE (0x60000e00)
|
||||
|
||||
#define I2STXFIFO (DR_REG_I2S_BASE + 0x0000)
|
||||
#define I2SRXFIFO (DR_REG_I2S_BASE + 0x0004)
|
||||
#define I2SCONF (DR_REG_I2S_BASE + 0x0008)
|
||||
#define I2S_BCK_DIV_NUM 0x0000003F
|
||||
#define I2S_BCK_DIV_NUM_S 22
|
||||
#define I2S_CLKM_DIV_NUM 0x0000003F
|
||||
#define I2S_CLKM_DIV_NUM_S 16
|
||||
#define I2S_BITS_MOD 0x0000000F
|
||||
#define I2S_BITS_MOD_S 12
|
||||
#define I2S_RECE_MSB_SHIFT (BIT(11))
|
||||
#define I2S_TRANS_MSB_SHIFT (BIT(10))
|
||||
#define I2S_I2S_RX_START (BIT(9))
|
||||
#define I2S_I2S_TX_START (BIT(8))
|
||||
#define I2S_MSB_RIGHT (BIT(7))
|
||||
#define I2S_RIGHT_FIRST (BIT(6))
|
||||
#define I2S_RECE_SLAVE_MOD (BIT(5))
|
||||
#define I2S_TRANS_SLAVE_MOD (BIT(4))
|
||||
#define I2S_I2S_RX_FIFO_RESET (BIT(3))
|
||||
#define I2S_I2S_TX_FIFO_RESET (BIT(2))
|
||||
#define I2S_I2S_RX_RESET (BIT(1))
|
||||
#define I2S_I2S_TX_RESET (BIT(0))
|
||||
#define I2S_I2S_RESET_MASK 0xf
|
||||
|
||||
#define I2SINT_RAW (DR_REG_I2S_BASE + 0x000c)
|
||||
#define I2S_I2S_TX_REMPTY_INT_RAW (BIT(5))
|
||||
#define I2S_I2S_TX_WFULL_INT_RAW (BIT(4))
|
||||
#define I2S_I2S_RX_REMPTY_INT_RAW (BIT(3))
|
||||
#define I2S_I2S_RX_WFULL_INT_RAW (BIT(2))
|
||||
#define I2S_I2S_TX_PUT_DATA_INT_RAW (BIT(1))
|
||||
#define I2S_I2S_RX_TAKE_DATA_INT_RAW (BIT(0))
|
||||
|
||||
#define I2SINT_ST (DR_REG_I2S_BASE + 0x0010)
|
||||
#define I2S_I2S_TX_REMPTY_INT_ST (BIT(5))
|
||||
#define I2S_I2S_TX_WFULL_INT_ST (BIT(4))
|
||||
#define I2S_I2S_RX_REMPTY_INT_ST (BIT(3))
|
||||
#define I2S_I2S_RX_WFULL_INT_ST (BIT(2))
|
||||
#define I2S_I2S_TX_PUT_DATA_INT_ST (BIT(1))
|
||||
#define I2S_I2S_RX_TAKE_DATA_INT_ST (BIT(0))
|
||||
|
||||
#define I2SINT_ENA (DR_REG_I2S_BASE + 0x0014)
|
||||
#define I2S_I2S_TX_REMPTY_INT_ENA (BIT(5))
|
||||
#define I2S_I2S_TX_WFULL_INT_ENA (BIT(4))
|
||||
#define I2S_I2S_RX_REMPTY_INT_ENA (BIT(3))
|
||||
#define I2S_I2S_RX_WFULL_INT_ENA (BIT(2))
|
||||
#define I2S_I2S_TX_PUT_DATA_INT_ENA (BIT(1))
|
||||
#define I2S_I2S_RX_TAKE_DATA_INT_ENA (BIT(0))
|
||||
|
||||
#define I2SINT_CLR (DR_REG_I2S_BASE + 0x0018)
|
||||
#define I2S_I2S_TX_REMPTY_INT_CLR (BIT(5))
|
||||
#define I2S_I2S_TX_WFULL_INT_CLR (BIT(4))
|
||||
#define I2S_I2S_RX_REMPTY_INT_CLR (BIT(3))
|
||||
#define I2S_I2S_RX_WFULL_INT_CLR (BIT(2))
|
||||
#define I2S_I2S_PUT_DATA_INT_CLR (BIT(1))
|
||||
#define I2S_I2S_TAKE_DATA_INT_CLR (BIT(0))
|
||||
|
||||
#define I2STIMING (DR_REG_I2S_BASE + 0x001c)
|
||||
#define I2S_TRANS_BCK_IN_INV (BIT(22))
|
||||
#define I2S_RECE_DSYNC_SW (BIT(21))
|
||||
#define I2S_TRANS_DSYNC_SW (BIT(20))
|
||||
#define I2S_RECE_BCK_OUT_DELAY 0x00000003
|
||||
#define I2S_RECE_BCK_OUT_DELAY_S 18
|
||||
#define I2S_RECE_WS_OUT_DELAY 0x00000003
|
||||
#define I2S_RECE_WS_OUT_DELAY_S 16
|
||||
#define I2S_TRANS_SD_OUT_DELAY 0x00000003
|
||||
#define I2S_TRANS_SD_OUT_DELAY_S 14
|
||||
#define I2S_TRANS_WS_OUT_DELAY 0x00000003
|
||||
#define I2S_TRANS_WS_OUT_DELAY_S 12
|
||||
#define I2S_TRANS_BCK_OUT_DELAY 0x00000003
|
||||
#define I2S_TRANS_BCK_OUT_DELAY_S 10
|
||||
#define I2S_RECE_SD_IN_DELAY 0x00000003
|
||||
#define I2S_RECE_SD_IN_DELAY_S 8
|
||||
#define I2S_RECE_WS_IN_DELAY 0x00000003
|
||||
#define I2S_RECE_WS_IN_DELAY_S 6
|
||||
#define I2S_RECE_BCK_IN_DELAY 0x00000003
|
||||
#define I2S_RECE_BCK_IN_DELAY_S 4
|
||||
#define I2S_TRANS_WS_IN_DELAY 0x00000003
|
||||
#define I2S_TRANS_WS_IN_DELAY_S 2
|
||||
#define I2S_TRANS_BCK_IN_DELAY 0x00000003
|
||||
#define I2S_TRANS_BCK_IN_DELAY_S 0
|
||||
|
||||
#define I2S_FIFO_CONF (DR_REG_I2S_BASE + 0x0020)
|
||||
#define I2S_I2S_RX_FIFO_MOD 0x00000007
|
||||
#define I2S_I2S_RX_FIFO_MOD_S 16
|
||||
#define I2S_I2S_TX_FIFO_MOD 0x00000007
|
||||
#define I2S_I2S_TX_FIFO_MOD_S 13
|
||||
#define I2S_I2S_DSCR_EN (BIT(12))
|
||||
#define I2S_I2S_TX_DATA_NUM 0x0000003F
|
||||
#define I2S_I2S_TX_DATA_NUM_S 6
|
||||
#define I2S_I2S_RX_DATA_NUM 0x0000003F
|
||||
#define I2S_I2S_RX_DATA_NUM_S 0
|
||||
|
||||
#define I2SRXEOF_NUM (DR_REG_I2S_BASE + 0x0024)
|
||||
#define I2S_I2S_RX_EOF_NUM 0xFFFFFFFF
|
||||
#define I2S_I2S_RX_EOF_NUM_S 0
|
||||
|
||||
#define I2SCONF_SIGLE_DATA (DR_REG_I2S_BASE + 0x0028)
|
||||
#define I2S_I2S_SIGLE_DATA 0xFFFFFFFF
|
||||
#define I2S_I2S_SIGLE_DATA_S 0
|
||||
|
||||
#define I2SCONF_CHAN (DR_REG_I2S_BASE + 0x002c)
|
||||
#define I2S_RX_CHAN_MOD 0x00000003
|
||||
#define I2S_RX_CHAN_MOD_S 3
|
||||
#define I2S_TX_CHAN_MOD 0x00000007
|
||||
#define I2S_TX_CHAN_MOD_S 0
|
||||
|
||||
// -----------------------------------------------------
|
||||
|
||||
#endif
|
||||
|
||||
// end of file
|
102
arduino/ws2812_controller/ws2812_dma.c
Normal file
102
arduino/ws2812_controller/ws2812_dma.c
Normal file
@ -0,0 +1,102 @@
|
||||
// ws2812_init.c
|
||||
|
||||
// C-based helper function for initilalizing
|
||||
// the I2S system
|
||||
|
||||
#include <string.h>
|
||||
#include "slc_register.h"
|
||||
#include "user_interface.h"
|
||||
#include "ws2812_defs.h"
|
||||
#include "ws2812_dma.h"
|
||||
|
||||
|
||||
#if WS2812_USE_INTERRUPT == 1
|
||||
// for debugging purposes
|
||||
static volatile uint32_t interrupt_count = 0;
|
||||
|
||||
static void ws2812_isr(void)
|
||||
{
|
||||
//clear all intr flags
|
||||
WRITE_PERI_REG(SLC_INT_CLR, 0xffffffff);//slc_intr_status);
|
||||
|
||||
interrupt_count++;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void ws2812_dma(sdio_queue_t *i2s_pixels_queue)
|
||||
{
|
||||
// Reset DMA
|
||||
SET_PERI_REG_MASK(SLC_CONF0, SLC_RXLINK_RST); //|SLC_TXLINK_RST);
|
||||
CLEAR_PERI_REG_MASK(SLC_CONF0, SLC_RXLINK_RST); //|SLC_TXLINK_RST);
|
||||
|
||||
// Clear DMA int flags
|
||||
SET_PERI_REG_MASK(SLC_INT_CLR, 0xffffffff);
|
||||
CLEAR_PERI_REG_MASK(SLC_INT_CLR, 0xffffffff);
|
||||
|
||||
// Enable and configure DMA
|
||||
CLEAR_PERI_REG_MASK(SLC_CONF0,(SLC_MODE<<SLC_MODE_S));
|
||||
SET_PERI_REG_MASK(SLC_CONF0,(1<<SLC_MODE_S));
|
||||
SET_PERI_REG_MASK(SLC_RX_DSCR_CONF,SLC_INFOR_NO_REPLACE|SLC_TOKEN_NO_REPLACE);
|
||||
CLEAR_PERI_REG_MASK(SLC_RX_DSCR_CONF, SLC_RX_FILL_EN|SLC_RX_EOF_MODE | SLC_RX_FILL_MODE);
|
||||
|
||||
// configure DMA descriptor
|
||||
CLEAR_PERI_REG_MASK(SLC_RX_LINK,SLC_RXLINK_DESCADDR_MASK);
|
||||
SET_PERI_REG_MASK(SLC_RX_LINK, ((uint32)i2s_pixels_queue) & SLC_RXLINK_DESCADDR_MASK);
|
||||
|
||||
#if WS2812_USE_INTERRUPT == 1
|
||||
// Attach the DMA interrupt
|
||||
ets_isr_attach(ETS_SLC_INUM, (int_handler_t)ws2812_isr , (void *)0);
|
||||
|
||||
//Enable DMA operation intr
|
||||
// WRITE_PERI_REG(SLC_INT_ENA, SLC_RX_EOF_INT_ENA);
|
||||
//clear any interrupt flags that are set
|
||||
WRITE_PERI_REG(SLC_INT_CLR, 0xffffffff);
|
||||
///enable DMA intr in cpu
|
||||
ets_isr_unmask(1<<ETS_SLC_INUM);
|
||||
#endif
|
||||
|
||||
//Start transmission
|
||||
SET_PERI_REG_MASK(SLC_RX_LINK, SLC_RXLINK_START);
|
||||
|
||||
//Init pins to i2s functions
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_I2SO_DATA);
|
||||
|
||||
//Enable clock to i2s subsystem
|
||||
i2c_writeReg_Mask_def(i2c_bbpll, i2c_bbpll_en_audio_clock_out, 1);
|
||||
|
||||
//Reset I2S subsystem
|
||||
CLEAR_PERI_REG_MASK(I2SCONF,I2S_I2S_RESET_MASK);
|
||||
SET_PERI_REG_MASK(I2SCONF,I2S_I2S_RESET_MASK);
|
||||
CLEAR_PERI_REG_MASK(I2SCONF,I2S_I2S_RESET_MASK);
|
||||
|
||||
//Select 16bits per channel (FIFO_MOD=0), no DMA access (FIFO only)
|
||||
CLEAR_PERI_REG_MASK(I2S_FIFO_CONF, I2S_I2S_DSCR_EN|(I2S_I2S_RX_FIFO_MOD<<I2S_I2S_RX_FIFO_MOD_S)|(I2S_I2S_TX_FIFO_MOD<<I2S_I2S_TX_FIFO_MOD_S));
|
||||
//Enable DMA in i2s subsystem
|
||||
SET_PERI_REG_MASK(I2S_FIFO_CONF, I2S_I2S_DSCR_EN);
|
||||
|
||||
//trans master&rece slave,MSB shift,right_first,msb right
|
||||
CLEAR_PERI_REG_MASK(I2SCONF, I2S_TRANS_SLAVE_MOD|
|
||||
(I2S_BITS_MOD<<I2S_BITS_MOD_S)|
|
||||
(I2S_BCK_DIV_NUM <<I2S_BCK_DIV_NUM_S)|
|
||||
(I2S_CLKM_DIV_NUM<<I2S_CLKM_DIV_NUM_S));
|
||||
SET_PERI_REG_MASK(I2SCONF, I2S_RIGHT_FIRST|I2S_MSB_RIGHT|I2S_RECE_SLAVE_MOD|
|
||||
I2S_RECE_MSB_SHIFT|I2S_TRANS_MSB_SHIFT|
|
||||
(((WS_I2S_BCK-1)&I2S_BCK_DIV_NUM )<<I2S_BCK_DIV_NUM_S)|
|
||||
(((WS_I2S_DIV-1)&I2S_CLKM_DIV_NUM)<<I2S_CLKM_DIV_NUM_S));
|
||||
|
||||
#if WS2812_USE_INTERRUPT == 1
|
||||
//clear int
|
||||
SET_PERI_REG_MASK(I2SINT_CLR, I2S_I2S_RX_WFULL_INT_CLR|I2S_I2S_PUT_DATA_INT_CLR|I2S_I2S_TAKE_DATA_INT_CLR);
|
||||
CLEAR_PERI_REG_MASK(I2SINT_CLR, I2S_I2S_RX_WFULL_INT_CLR|I2S_I2S_PUT_DATA_INT_CLR|I2S_I2S_TAKE_DATA_INT_CLR);
|
||||
//enable int
|
||||
SET_PERI_REG_MASK(I2SINT_ENA, I2S_I2S_RX_REMPTY_INT_ENA|I2S_I2S_RX_TAKE_DATA_INT_ENA);
|
||||
#endif
|
||||
|
||||
//Start transmission
|
||||
SET_PERI_REG_MASK(I2SCONF,I2S_I2S_TX_START);
|
||||
|
||||
}
|
||||
|
||||
// end of file
|
||||
|
25
arduino/ws2812_controller/ws2812_dma.h
Normal file
25
arduino/ws2812_controller/ws2812_dma.h
Normal file
@ -0,0 +1,25 @@
|
||||
// ws2812_dma.h
|
||||
|
||||
#ifndef __WS2812_DMA_H__
|
||||
#define __WS2812_DMA_H__
|
||||
|
||||
// type definition taken from : sdio_slv.h
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t blocksize:12;
|
||||
uint32_t datalen:12;
|
||||
uint32_t unused:5;
|
||||
uint32_t sub_sof:1;
|
||||
uint32_t eof:1;
|
||||
uint32_t owner:1;
|
||||
uint32_t buf_ptr;
|
||||
uint32_t next_link_ptr;
|
||||
} sdio_queue_t;
|
||||
|
||||
// -----------------------------------------------------
|
||||
|
||||
extern void ws2812_dma(sdio_queue_t *);
|
||||
|
||||
#endif
|
||||
|
165
arduino/ws2812_controller/ws2812_gamma.cpp
Normal file
165
arduino/ws2812_controller/ws2812_gamma.cpp
Normal file
@ -0,0 +1,165 @@
|
||||
// ws2812_gamma.cpp
|
||||
//
|
||||
// dithering tables with gamma correction
|
||||
|
||||
#include <stdint.h>
|
||||
#include "ws2812_gamma.h"
|
||||
|
||||
static const uint8_t gamma0[] = {
|
||||
0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4,
|
||||
5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9,
|
||||
10, 10, 10, 11, 11, 12, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16,
|
||||
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 23, 23, 24, 24, 25,
|
||||
26, 26, 27, 28, 28, 29, 30, 30, 31, 32, 32, 33, 34, 34, 35, 36,
|
||||
37, 37, 38, 39, 40, 41, 41, 42, 43, 44, 45, 45, 46, 47, 48, 49,
|
||||
50, 51, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
|
||||
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 80, 81,
|
||||
82, 83, 84, 85, 86, 88, 89, 90, 91, 92, 94, 95, 96, 97, 98, 100,
|
||||
101, 102, 103, 105, 106, 107, 109, 110, 111, 113, 114, 115, 117, 118, 119, 121,
|
||||
122, 123, 125, 126, 128, 129, 130, 132, 133, 135, 136, 138, 139, 141, 142, 144,
|
||||
145, 147, 148, 150, 151, 153, 154, 156, 157, 159, 161, 162, 164, 165, 167, 169,
|
||||
170, 172, 173, 175, 177, 178, 180, 182, 183, 185, 187, 189, 190, 192, 194, 196,
|
||||
197, 199, 201, 203, 204, 206, 208, 210, 212, 213, 215, 217, 219, 221, 223, 225,
|
||||
226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 254, 255 };
|
||||
|
||||
static const uint8_t gamma1[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4,
|
||||
4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9,
|
||||
9, 9, 10, 10, 11, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16,
|
||||
16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 23, 23, 24, 24,
|
||||
25, 26, 26, 27, 28, 28, 29, 30, 30, 31, 32, 32, 33, 34, 35, 35,
|
||||
36, 37, 38, 38, 39, 40, 41, 42, 42, 43, 44, 45, 46, 47, 47, 48,
|
||||
49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||
64, 65, 66, 67, 68, 69, 70, 71, 73, 74, 75, 76, 77, 78, 79, 80,
|
||||
81, 82, 84, 85, 86, 87, 88, 89, 91, 92, 93, 94, 95, 97, 98, 99,
|
||||
100, 102, 103, 104, 105, 107, 108, 109, 111, 112, 113, 115, 116, 117, 119, 120,
|
||||
121, 123, 124, 126, 127, 128, 130, 131, 133, 134, 136, 137, 139, 140, 142, 143,
|
||||
145, 146, 148, 149, 151, 152, 154, 155, 157, 158, 160, 162, 163, 165, 166, 168,
|
||||
170, 171, 173, 175, 176, 178, 180, 181, 183, 185, 186, 188, 190, 192, 193, 195,
|
||||
197, 199, 200, 202, 204, 206, 207, 209, 211, 213, 215, 217, 218, 220, 222, 224,
|
||||
226, 228, 230, 232, 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255 };
|
||||
|
||||
static const uint8_t gamma2[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4,
|
||||
4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9,
|
||||
9, 10, 10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16,
|
||||
16, 17, 17, 18, 18, 19, 19, 20, 21, 21, 22, 22, 23, 24, 24, 25,
|
||||
25, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33, 33, 34, 35, 36,
|
||||
36, 37, 38, 39, 39, 40, 41, 42, 43, 43, 44, 45, 46, 47, 48, 49,
|
||||
49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
|
||||
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
|
||||
82, 83, 84, 85, 86, 87, 88, 90, 91, 92, 93, 94, 96, 97, 98, 99,
|
||||
101, 102, 103, 104, 106, 107, 108, 110, 111, 112, 114, 115, 116, 118, 119, 120,
|
||||
122, 123, 125, 126, 127, 129, 130, 132, 133, 134, 136, 137, 139, 140, 142, 143,
|
||||
145, 146, 148, 149, 151, 152, 154, 156, 157, 159, 160, 162, 163, 165, 167, 168,
|
||||
170, 172, 173, 175, 177, 178, 180, 182, 183, 185, 187, 188, 190, 192, 194, 195,
|
||||
197, 199, 201, 202, 204, 206, 208, 210, 211, 213, 215, 217, 219, 221, 222, 224,
|
||||
226, 228, 230, 232, 234, 236, 238, 240, 241, 243, 245, 247, 249, 251, 253, 255 };
|
||||
|
||||
static const uint8_t gamma3[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4,
|
||||
4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8,
|
||||
9, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 13, 14, 14, 15, 15,
|
||||
16, 16, 17, 17, 18, 18, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24,
|
||||
25, 25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 34, 35,
|
||||
36, 37, 37, 38, 39, 40, 41, 41, 42, 43, 44, 45, 45, 46, 47, 48,
|
||||
49, 50, 51, 52, 53, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 76, 77, 78, 79, 80,
|
||||
81, 82, 83, 84, 86, 87, 88, 89, 90, 92, 93, 94, 95, 96, 98, 99,
|
||||
100, 101, 103, 104, 105, 107, 108, 109, 110, 112, 113, 114, 116, 117, 118, 120,
|
||||
121, 123, 124, 125, 127, 128, 130, 131, 133, 134, 135, 137, 138, 140, 141, 143,
|
||||
144, 146, 147, 149, 150, 152, 153, 155, 157, 158, 160, 161, 163, 165, 166, 168,
|
||||
169, 171, 173, 174, 176, 178, 179, 181, 183, 184, 186, 188, 190, 191, 193, 195,
|
||||
197, 198, 200, 202, 204, 205, 207, 209, 211, 213, 214, 216, 218, 220, 222, 224,
|
||||
226, 228, 229, 231, 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255 };
|
||||
|
||||
static const uint8_t gamma4[] = {
|
||||
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4,
|
||||
4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9,
|
||||
9, 10, 10, 11, 11, 11, 12, 12, 13, 13, 14, 14, 14, 15, 15, 16,
|
||||
16, 17, 17, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
|
||||
25, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33, 34, 34, 35, 36,
|
||||
37, 37, 38, 39, 40, 40, 41, 42, 43, 44, 44, 45, 46, 47, 48, 49,
|
||||
50, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
|
||||
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 81,
|
||||
82, 83, 84, 85, 86, 87, 89, 90, 91, 92, 93, 95, 96, 97, 98, 100,
|
||||
101, 102, 103, 105, 106, 107, 108, 110, 111, 112, 114, 115, 116, 118, 119, 120,
|
||||
122, 123, 125, 126, 127, 129, 130, 132, 133, 135, 136, 138, 139, 140, 142, 143,
|
||||
145, 146, 148, 149, 151, 153, 154, 156, 157, 159, 160, 162, 164, 165, 167, 168,
|
||||
170, 172, 173, 175, 177, 178, 180, 182, 183, 185, 187, 188, 190, 192, 194, 195,
|
||||
197, 199, 201, 202, 204, 206, 208, 210, 211, 213, 215, 217, 219, 221, 223, 224,
|
||||
226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 245, 247, 249, 251, 253, 255 };
|
||||
|
||||
static const uint8_t gamma5[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4,
|
||||
4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 9,
|
||||
9, 9, 10, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 14, 15, 15,
|
||||
16, 16, 17, 17, 18, 19, 19, 20, 20, 21, 21, 22, 23, 23, 24, 24,
|
||||
25, 26, 26, 27, 28, 28, 29, 30, 30, 31, 32, 32, 33, 34, 35, 35,
|
||||
36, 37, 38, 38, 39, 40, 41, 41, 42, 43, 44, 45, 46, 46, 47, 48,
|
||||
49, 50, 51, 52, 53, 54, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 75, 76, 77, 78, 79, 80,
|
||||
81, 82, 83, 85, 86, 87, 88, 89, 90, 92, 93, 94, 95, 97, 98, 99,
|
||||
100, 102, 103, 104, 105, 107, 108, 109, 111, 112, 113, 115, 116, 117, 119, 120,
|
||||
121, 123, 124, 126, 127, 128, 130, 131, 133, 134, 136, 137, 138, 140, 141, 143,
|
||||
144, 146, 147, 149, 151, 152, 154, 155, 157, 158, 160, 161, 163, 165, 166, 168,
|
||||
170, 171, 173, 174, 176, 178, 179, 181, 183, 185, 186, 188, 190, 191, 193, 195,
|
||||
197, 198, 200, 202, 204, 206, 207, 209, 211, 213, 215, 216, 218, 220, 222, 224,
|
||||
226, 228, 230, 231, 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255 };
|
||||
|
||||
static const uint8_t gamma6[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4,
|
||||
4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9,
|
||||
9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 13, 14, 14, 15, 15, 16,
|
||||
16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 22, 22, 23, 23, 24, 25,
|
||||
25, 26, 26, 27, 28, 28, 29, 30, 30, 31, 32, 33, 33, 34, 35, 36,
|
||||
36, 37, 38, 39, 39, 40, 41, 42, 43, 43, 44, 45, 46, 47, 48, 48,
|
||||
49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 58, 59, 60, 61, 62, 63,
|
||||
64, 65, 66, 67, 68, 69, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
|
||||
81, 83, 84, 85, 86, 87, 88, 90, 91, 92, 93, 94, 96, 97, 98, 99,
|
||||
101, 102, 103, 104, 106, 107, 108, 109, 111, 112, 113, 115, 116, 117, 119, 120,
|
||||
122, 123, 124, 126, 127, 129, 130, 131, 133, 134, 136, 137, 139, 140, 142, 143,
|
||||
145, 146, 148, 149, 151, 152, 154, 155, 157, 159, 160, 162, 163, 165, 167, 168,
|
||||
170, 171, 173, 175, 176, 178, 180, 181, 183, 185, 186, 188, 190, 192, 193, 195,
|
||||
197, 199, 200, 202, 204, 206, 208, 209, 211, 213, 215, 217, 219, 220, 222, 224,
|
||||
226, 228, 230, 232, 234, 236, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255 };
|
||||
|
||||
static const uint8_t gamma7[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
|
||||
1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3,
|
||||
4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8,
|
||||
9, 9, 9, 10, 10, 11, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15,
|
||||
16, 16, 17, 17, 18, 18, 19, 19, 20, 21, 21, 22, 22, 23, 23, 24,
|
||||
25, 25, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33, 34, 34, 35,
|
||||
36, 37, 37, 38, 39, 40, 40, 41, 42, 43, 44, 45, 45, 46, 47, 48,
|
||||
49, 50, 51, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 78, 79, 80,
|
||||
81, 82, 83, 84, 86, 87, 88, 89, 90, 91, 93, 94, 95, 96, 98, 99,
|
||||
100, 101, 103, 104, 105, 106, 108, 109, 110, 112, 113, 114, 116, 117, 118, 120,
|
||||
121, 122, 124, 125, 127, 128, 130, 131, 132, 134, 135, 137, 138, 140, 141, 143,
|
||||
144, 146, 147, 149, 150, 152, 153, 155, 156, 158, 160, 161, 163, 164, 166, 168,
|
||||
169, 171, 173, 174, 176, 178, 179, 181, 183, 184, 186, 188, 189, 191, 193, 195,
|
||||
196, 198, 200, 202, 203, 205, 207, 209, 211, 213, 214, 216, 218, 220, 222, 224,
|
||||
226, 227, 229, 231, 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255 };
|
||||
|
||||
|
||||
#if WS2812_DITHER_NUM == 1
|
||||
const uint8_t *gamma_dither[WS2812_DITHER_NUM] = {gamma0};
|
||||
#elif WS2812_DITHER_NUM == 2
|
||||
const uint8_t *gamma_dither[WS2812_DITHER_NUM] = {gamma0,gamma1};
|
||||
#elif WS2812_DITHER_NUM == 4
|
||||
const uint8_t *gamma_dither[WS2812_DITHER_NUM] = {gamma0,gamma1,gamma2,gamma3};
|
||||
#elif WS2812_DITHER_NUM == 8
|
||||
const uint8_t *gamma_dither[WS2812_DITHER_NUM] = {gamma0,gamma1,gamma2,gamma3,gamma4,gamma5,gamma6,gamma7};
|
||||
#else
|
||||
#error Invalid WS2812_DITHER_NUM value. Allowed values are 1, 2, 4, 8
|
||||
#endif
|
||||
|
||||
// end of file
|
12
arduino/ws2812_controller/ws2812_gamma.h
Normal file
12
arduino/ws2812_controller/ws2812_gamma.h
Normal file
@ -0,0 +1,12 @@
|
||||
// ws2812_gamma.h
|
||||
|
||||
#ifndef __WS2812_GAMMA_H__
|
||||
#define __WS2812_GAMMA_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "ws2812.h"
|
||||
|
||||
extern const uint8_t *gamma_dither[WS2812_DITHER_NUM];
|
||||
|
||||
#endif
|
||||
|
169
arduino/ws2812_controller/ws2812_i2s.cpp
Normal file
169
arduino/ws2812_controller/ws2812_i2s.cpp
Normal file
@ -0,0 +1,169 @@
|
||||
// ws2812_lib.cpp
|
||||
//
|
||||
// main library file / contains class implementation
|
||||
//
|
||||
// Need to give credits to Charles Lohr (https://github.com/cnlohr due
|
||||
// to his work on his software for driving ws2812 led-strips using
|
||||
// the i2s interface of the ESP8266.
|
||||
//
|
||||
// This inspired me to create an ESP8266 library for the Arduino IDE
|
||||
// I've added temporal dithering & gamma-correction
|
||||
// for a 'more natural' light intensity profile.
|
||||
//
|
||||
// No pin-definitions/mapings are required/possible as the library used the I2S
|
||||
// output-pin. This pin in it's turn is shared with GPIO3 & RXD0
|
||||
//
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <stdint.h>
|
||||
#include "ws2812_i2s.h"
|
||||
#include "ws2812_defs.h"
|
||||
#include "ws2812_gamma.h"
|
||||
|
||||
// include C-style header
|
||||
extern "C"
|
||||
{
|
||||
#include "ws2812_dma.h"
|
||||
};
|
||||
|
||||
// class constructor
|
||||
WS2812::WS2812(void)
|
||||
{
|
||||
// empty for now
|
||||
}
|
||||
|
||||
// class de-constructor
|
||||
WS2812::~WS2812(void)
|
||||
{
|
||||
// empty for now
|
||||
// TODO : should implement switching of DMA
|
||||
}
|
||||
|
||||
// Init led-string / memory buffers etc.
|
||||
void WS2812::init(uint16_t _num_leds)
|
||||
{
|
||||
uint8_t i;
|
||||
uint16_t j;
|
||||
|
||||
num_leds = _num_leds;
|
||||
|
||||
// clear zero buffer
|
||||
for(j=0; j<NUM_I2S_ZERO_WORDS; j++)
|
||||
{
|
||||
i2s_zeros_buffer[j] = 0;
|
||||
}
|
||||
|
||||
// do memory allocation for i2s buffer(s)
|
||||
for(i=0; i<WS2812_DITHER_NUM; i++)
|
||||
{
|
||||
i2s_pixels_buffer[i] = new uint32_t[NUM_I2S_PIXEL_WORDS];
|
||||
|
||||
// TODO : handle memory allocation error better
|
||||
if (i2s_pixels_buffer[i] == 0)
|
||||
{
|
||||
Serial.println("WS2812_I2S : ERROR ALLOCATING MEMORY");
|
||||
return;
|
||||
}
|
||||
|
||||
for(j=0; j<NUM_I2S_PIXEL_WORDS; j++)
|
||||
{
|
||||
i2s_pixels_buffer[i][j] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// set-up DMA descriptors / 1 pair per dither-factor
|
||||
for(i=0; i<WS2812_DITHER_NUM; i++)
|
||||
{
|
||||
i2s_pixels_queue[i].owner = 1;
|
||||
i2s_pixels_queue[i].eof = 1;
|
||||
i2s_pixels_queue[i].sub_sof = 0;
|
||||
i2s_pixels_queue[i].datalen = NUM_I2S_PIXEL_BYTES; // Size in bytes
|
||||
i2s_pixels_queue[i].blocksize = NUM_I2S_PIXEL_BYTES; // Size in bytes
|
||||
i2s_pixels_queue[i].buf_ptr = (uint32_t)i2s_pixels_buffer[i];
|
||||
i2s_pixels_queue[i].unused = 0;
|
||||
i2s_pixels_queue[i].next_link_ptr = (uint32_t)&i2s_zeros_queue[i]; // always link to zeros-buffer
|
||||
|
||||
i2s_zeros_queue[i].owner = 1;
|
||||
i2s_zeros_queue[i].eof = 1;
|
||||
i2s_zeros_queue[i].sub_sof = 0;
|
||||
i2s_zeros_queue[i].datalen = NUM_I2S_ZERO_BYTES; // Size in bytes)
|
||||
i2s_zeros_queue[i].blocksize = NUM_I2S_ZERO_BYTES; // Size in bytes
|
||||
i2s_zeros_queue[i].buf_ptr = (uint32_t)i2s_zeros_buffer;
|
||||
i2s_zeros_queue[i].unused = 0;
|
||||
|
||||
if (i == (WS2812_DITHER_NUM-1)) // last DMA descriptor in linked list ?
|
||||
{
|
||||
// yes : link to first DMA descriptor
|
||||
i2s_zeros_queue[i].next_link_ptr = (uint32_t)&i2s_pixels_queue[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
// no : link to next DMA descriptor
|
||||
i2s_zeros_queue[i].next_link_ptr = (uint32_t)&i2s_pixels_queue[i+1];
|
||||
}
|
||||
}
|
||||
|
||||
// call C based helper function
|
||||
// I did not really succeed in putting the code from the helper
|
||||
// funtion directly into this constructor...has something to do
|
||||
// with C vs. C++
|
||||
// the i2c_writeReg_Mask macro (+ others) failed.. see ws2812_defs.h
|
||||
// may be I solve this later
|
||||
|
||||
// parameter = first entry in DMA descriptor list, i.e the descriptor list
|
||||
ws2812_dma(i2s_pixels_queue);
|
||||
|
||||
}
|
||||
|
||||
// left this comment in tact....credit to Charles
|
||||
|
||||
// All functions below this line are Public Domain 2015 Charles Lohr.
|
||||
// this code may be used by anyone in any way without restriction or limitation.
|
||||
|
||||
// Send out WS2812 bits with coded pulses, one nibble, then the other.
|
||||
static const uint16_t bitpatterns[16] =
|
||||
{
|
||||
0b1000100010001000, 0b1000100010001110, 0b1000100011101000, 0b1000100011101110,
|
||||
0b1000111010001000, 0b1000111010001110, 0b1000111011101000, 0b1000111011101110,
|
||||
0b1110100010001000, 0b1110100010001110, 0b1110100011101000, 0b1110100011101110,
|
||||
0b1110111010001000, 0b1110111010001110, 0b1110111011101000, 0b1110111011101110,
|
||||
};
|
||||
|
||||
// display the pixels
|
||||
void WS2812::show(Pixel_t *pixels)
|
||||
{
|
||||
uint8_t *buffer;
|
||||
uint8_t pixelbyte;
|
||||
uint8_t gammabyte;
|
||||
uint16_t i,b;
|
||||
uint16_t *i2s_ptr[WS2812_DITHER_NUM];
|
||||
|
||||
buffer = (uint8_t *)pixels;
|
||||
|
||||
// set-up pointers into the i2s-pixel-buffers
|
||||
for(i=0; i<WS2812_DITHER_NUM; i++)
|
||||
{
|
||||
i2s_ptr[i] = (uint16_t *)i2s_pixels_buffer[i];
|
||||
}
|
||||
|
||||
// for every pixel in the input-array
|
||||
// - get the pixel value (either R,G, or B)
|
||||
// - for every dithered buffer
|
||||
// get the gamma-corrected output value
|
||||
// - and transform into i2s nibble
|
||||
|
||||
for(b=0; b<NUM_RGB_BYTES; b++)
|
||||
{
|
||||
pixelbyte = *buffer++;
|
||||
|
||||
for(i=0; i<WS2812_DITHER_NUM; i++)
|
||||
{
|
||||
gammabyte = gamma_dither[i][pixelbyte];
|
||||
*(i2s_ptr[i]++) = bitpatterns[ (gammabyte & 0x0f) ];
|
||||
*(i2s_ptr[i]++) = bitpatterns[ (gammabyte>>4) & 0x0f ];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// end of file
|
41
arduino/ws2812_controller/ws2812_i2s.h
Normal file
41
arduino/ws2812_controller/ws2812_i2s.h
Normal file
@ -0,0 +1,41 @@
|
||||
// ws2812_lib.h
|
||||
|
||||
#ifndef __WS2812_I2S_H__
|
||||
#define __WS2812_I2S_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "ws2812_defs.h"
|
||||
|
||||
// include C-style header
|
||||
extern "C"
|
||||
{
|
||||
#include "ws2812_dma.h"
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t G; // G,R,B order is determined by WS2812B
|
||||
uint8_t R;
|
||||
uint8_t B;
|
||||
} Pixel_t;
|
||||
|
||||
|
||||
class WS2812
|
||||
{
|
||||
public:
|
||||
WS2812(void);
|
||||
~WS2812(void);
|
||||
void init(uint16_t num_leds);
|
||||
void show(Pixel_t *);
|
||||
|
||||
private:
|
||||
uint16_t num_leds;
|
||||
uint32_t *i2s_pixels_buffer[WS2812_DITHER_NUM];
|
||||
uint32_t i2s_zeros_buffer[NUM_I2S_ZERO_WORDS];
|
||||
sdio_queue_t i2s_zeros_queue[WS2812_DITHER_NUM];
|
||||
sdio_queue_t i2s_pixels_queue[WS2812_DITHER_NUM];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// end of file
|
Loading…
x
Reference in New Issue
Block a user