Add files via upload
Including pull request to use NeoPixelBus
This commit is contained in:
parent
7507cc0be2
commit
eb163b6771
17
ws2812.h
Normal file
17
ws2812.h
Normal file
@ -0,0 +1,17 @@
|
||||
// ws2812.h
|
||||
|
||||
#ifndef __WS2812_H__
|
||||
#define __WS2812_H__
|
||||
|
||||
// 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 (8)
|
||||
|
||||
#define WS2812_USE_INTERRUPT (0) // not supported yet
|
||||
|
||||
#endif
|
||||
|
||||
// end of file
|
79
ws2812_controller.ino
Normal file
79
ws2812_controller.ino
Normal file
@ -0,0 +1,79 @@
|
||||
#include <Arduino.h>
|
||||
#include <ESP8266WiFi.h>
|
||||
//#include <WebSocketsServer.h>
|
||||
//#include <Hash.h>
|
||||
#include <WiFiUdp.h>
|
||||
#include <NeoPixelBus.h>
|
||||
|
||||
// Set to the number of LEDs in your LED strip
|
||||
#define NUM_LEDS 242
|
||||
// Maximum number of packets to hold in the buffer. Don't change this.
|
||||
#define BUFFER_LEN 726
|
||||
// Toggles FPS output (1 = print FPS over serial, 0 = disable output)
|
||||
#define PRINT_FPS 1
|
||||
|
||||
//NeoPixelBus settings
|
||||
const uint8_t PixelPin = 3; // make sure to set this to the correct pin, ignored for Esp8266(set to 3 by default for DMA)
|
||||
|
||||
// Wifi and socket settings
|
||||
const char* ssid = "ASUS_VIVOBOOK";
|
||||
const char* password = "T!PT)Psecret";
|
||||
unsigned int localPort = 7778;
|
||||
byte packetBuffer[BUFFER_LEN];
|
||||
RgbColor ledDataBuffer[NUM_LEDS];
|
||||
|
||||
// LED strip
|
||||
NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> ledstrip(NUM_LEDS, PixelPin);
|
||||
|
||||
WiFiUDP port;
|
||||
|
||||
// Network information
|
||||
// IP must match the IP in config.py
|
||||
IPAddress ip(192, 168, 137, 200);
|
||||
// Set gateway to your router's gateway
|
||||
IPAddress gateway(192, 168, 137, 1);
|
||||
IPAddress subnet(255, 255, 255, 0);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
//WiFi.config(ip, gateway, subnet);
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.begin(ssid, password);
|
||||
Serial.println("");
|
||||
// Connect to wifi and print the IP address over serial
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println("");
|
||||
Serial.print("Connected to ");
|
||||
Serial.println(ssid);
|
||||
Serial.print("IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
port.begin(localPort);
|
||||
ledstrip.Begin();//Begin output
|
||||
ledstrip.Show();//Clear the strip for use
|
||||
}
|
||||
|
||||
uint8_t N = 0;
|
||||
#if PRINT_FPS
|
||||
uint16_t fpsCounter = 0;
|
||||
uint32_t secondTimer = 0;
|
||||
#endif
|
||||
|
||||
void loop() {
|
||||
// Read data over socket
|
||||
int packetSize = port.parsePacket();
|
||||
// If packets have been received, interpret the command
|
||||
if (packetSize) {
|
||||
int len = port.read(packetBuffer, BUFFER_LEN);
|
||||
for(int i = 0; i < len; i+=4) {
|
||||
packetBuffer[len] = 0;
|
||||
N = packetBuffer[i];
|
||||
RgbColor pixel((uint8_t)packetBuffer[i+1], (uint8_t)packetBuffer[i+2], (uint8_t)packetBuffer[i+3]);
|
||||
ledstrip.SetPixelColor(N, pixel);
|
||||
}
|
||||
ledstrip.Show();
|
||||
Serial.print("/");
|
||||
}
|
||||
}
|
172
ws2812_defs.h
Normal file
172
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
ws2812_dma.c
Normal file
102
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
ws2812_dma.h
Normal file
25
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
ws2812_gamma.cpp
Normal file
165
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
ws2812_gamma.h
Normal file
12
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
ws2812_i2s.cpp
Normal file
169
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
ws2812_i2s.h
Normal file
41
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…
Reference in New Issue
Block a user