diff --git a/ws2812.h b/ws2812.h new file mode 100644 index 0000000..5dddc9f --- /dev/null +++ b/ws2812.h @@ -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 diff --git a/ws2812_controller.ino b/ws2812_controller.ino new file mode 100644 index 0000000..0316838 --- /dev/null +++ b/ws2812_controller.ino @@ -0,0 +1,79 @@ +#include +#include +//#include +//#include +#include +#include + +// 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 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("/"); + } +} diff --git a/ws2812_defs.h b/ws2812_defs.h new file mode 100644 index 0000000..6a4a08d --- /dev/null +++ b/ws2812_defs.h @@ -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 + +// 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 diff --git a/ws2812_dma.c b/ws2812_dma.c new file mode 100644 index 0000000..d2aa497 --- /dev/null +++ b/ws2812_dma.c @@ -0,0 +1,102 @@ +// ws2812_init.c + +// C-based helper function for initilalizing +// the I2S system + +#include +#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< +#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 diff --git a/ws2812_gamma.h b/ws2812_gamma.h new file mode 100644 index 0000000..84353a2 --- /dev/null +++ b/ws2812_gamma.h @@ -0,0 +1,12 @@ +// ws2812_gamma.h + +#ifndef __WS2812_GAMMA_H__ +#define __WS2812_GAMMA_H__ + +#include +#include "ws2812.h" + +extern const uint8_t *gamma_dither[WS2812_DITHER_NUM]; + +#endif + diff --git a/ws2812_i2s.cpp b/ws2812_i2s.cpp new file mode 100644 index 0000000..c0658e7 --- /dev/null +++ b/ws2812_i2s.cpp @@ -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 +#include +#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>4) & 0x0f ]; + } + } + +} + +// end of file diff --git a/ws2812_i2s.h b/ws2812_i2s.h new file mode 100644 index 0000000..e40c8ba --- /dev/null +++ b/ws2812_i2s.h @@ -0,0 +1,41 @@ +// ws2812_lib.h + +#ifndef __WS2812_I2S_H__ +#define __WS2812_I2S_H__ + +#include +#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