dunno, changes and stuff
This commit is contained in:
@@ -6,19 +6,22 @@
|
||||
#include "../../Debug.h"
|
||||
#include "../../io/GPIO.h"
|
||||
|
||||
#include <xtensa/xtruntime.h>
|
||||
|
||||
|
||||
#if ESP8266
|
||||
#if IS_ESP8266
|
||||
|
||||
#include "../../io/fastGPIO.h"
|
||||
// https://github.com/FastLED/FastLED/tree/master/src/platforms/esp/8266
|
||||
|
||||
#include "../../io/GPIO.h"
|
||||
|
||||
template <int numLEDs> class WS2812B {
|
||||
|
||||
static constexpr const char* NAME = "WS2812B";
|
||||
|
||||
#define LED_SET_PIN_TO_OUTPUT GPIO5_OUTPUT_SET
|
||||
#define LED_SET_PIN_H GPIO5_H
|
||||
#define LED_SET_PIN_L GPIO5_L
|
||||
#define LED_SET_PIN_TO_OUTPUT MyGPIO::setOutput(5) //GPIO5_OUTPUT_SET
|
||||
#define LED_SET_PIN_H MyGPIO::set(5) //GPIO5_H
|
||||
#define LED_SET_PIN_L MyGPIO::clear(5) //GPIO5_L
|
||||
|
||||
//#define NS_PER_TICK ( (1000ul*1000ul*1000ul) / (80ul*1000ul*1000ul) )
|
||||
|
||||
@@ -37,7 +40,7 @@
|
||||
|
||||
void init() {
|
||||
LED_SET_PIN_TO_OUTPUT;
|
||||
debugMod1(NAME, "init with %d leds", numLEDs);
|
||||
Log::addInfo(NAME, "init with %d leds", numLEDs);
|
||||
}
|
||||
|
||||
/** set the color for the given LED */
|
||||
@@ -74,12 +77,16 @@
|
||||
}
|
||||
|
||||
/** flush configured changes */
|
||||
void flush() {
|
||||
IRAM_ATTR void flush() {
|
||||
|
||||
LED_SET_PIN_TO_OUTPUT;
|
||||
|
||||
ets_intr_lock();
|
||||
//LED_SET_PIN_TO_OUTPUT;
|
||||
|
||||
//ets_intr_lock();
|
||||
//taskENTER_CRITICAL();
|
||||
//taskDISABLE_INTERRUPTS();
|
||||
//const uint32_t saved = XTOS_DISABLE_ALL_INTERRUPTS;
|
||||
vPortETSIntrLock();
|
||||
|
||||
// process each LED
|
||||
for (int i = 0; i < numLEDs; ++i) {
|
||||
|
||||
@@ -97,19 +104,29 @@
|
||||
|
||||
}
|
||||
|
||||
ets_intr_unlock();
|
||||
|
||||
//ets_intr_unlock();
|
||||
//taskEXIT_CRITICAL();
|
||||
//XTOS_RESTORE_INTLEVEL(saved);
|
||||
vPortETSIntrUnlock();
|
||||
//taskENABLE_INTERRUPTS();
|
||||
|
||||
reset();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/** flush configured changes, including global brightness */
|
||||
void flushBrightness(const uint8_t brightness) {
|
||||
IRAM_ATTR void flushBrightness(const uint8_t brightness) {
|
||||
|
||||
LED_SET_PIN_TO_OUTPUT;
|
||||
|
||||
ets_intr_lock();
|
||||
//LED_SET_PIN_TO_OUTPUT;
|
||||
|
||||
//ets_intr_lock();
|
||||
//taskENTER_CRITICAL();
|
||||
taskDISABLE_INTERRUPTS();
|
||||
//const uint32_t saved = XTOS_DISABLE_ALL_INTERRUPTS;
|
||||
//vPortETSIntrLock();
|
||||
|
||||
// process each LED
|
||||
for (int i = 0; i < numLEDs; ++i) {
|
||||
|
||||
@@ -127,122 +144,79 @@
|
||||
|
||||
}
|
||||
|
||||
ets_intr_unlock();
|
||||
|
||||
//ets_intr_unlock();
|
||||
taskENABLE_INTERRUPTS();
|
||||
//taskEXIT_CRITICAL();
|
||||
//XTOS_RESTORE_INTLEVEL(saved);
|
||||
//vPortETSIntrUnlock();
|
||||
|
||||
reset();
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
inline void sendByte(uint8_t b) {
|
||||
// for (uint8_t i = 0; i < 8; ++i) {
|
||||
// if (b & 0b10000000) {
|
||||
// send1();
|
||||
// } else {
|
||||
// send0();
|
||||
// }
|
||||
// b <<= 1;
|
||||
// }
|
||||
if (b & 0b10000000) {send1();} else {send0();}
|
||||
if (b & 0b01000000) {send1();} else {send0();}
|
||||
if (b & 0b00100000) {send1();} else {send0();}
|
||||
if (b & 0b00010000) {send1();} else {send0();}
|
||||
if (b & 0b00001000) {send1();} else {send0();}
|
||||
if (b & 0b00000100) {send1();} else {send0();}
|
||||
if (b & 0b00000010) {send1();} else {send0();}
|
||||
if (b & 0b00000001) {send1();} else {send0();}
|
||||
IRAM_ATTR void sendByte(uint8_t b) {
|
||||
//if (b & 0b10000000) {send1();} else {send0();}
|
||||
//if (b & 0b01000000) {send1();} else {send0();}
|
||||
//if (b & 0b00100000) {send1();} else {send0();}
|
||||
//if (b & 0b00010000) {send1();} else {send0();}
|
||||
//if (b & 0b00001000) {send1();} else {send0();}
|
||||
//if (b & 0b00000100) {send1();} else {send0();}
|
||||
//if (b & 0b00000010) {send1();} else {send0();}
|
||||
//if (b & 0b00000001) {send1();} else {send0();}
|
||||
for (uint8_t i = 0; i < 8; ++i) {
|
||||
if (b & 0b10000000) {send1();} else {send0();}
|
||||
b <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) inline void send1() { // 800ns high, 450ns low
|
||||
// @80 MHz one instruction = 12.5ns
|
||||
// @160 MHz one instruction = 6.25ns
|
||||
|
||||
__attribute__((always_inline)) void send1() { // 800ns high, 450ns low
|
||||
LED_SET_PIN_H;
|
||||
delay800();
|
||||
delayL();
|
||||
LED_SET_PIN_L;
|
||||
delay100();
|
||||
delayS();
|
||||
//const uint32_t tmp = soc_get_ccount();
|
||||
//LED_SET_PIN_H;
|
||||
//while(soc_get_ccount() - tmp < 144) {}
|
||||
//LED_SET_PIN_L;
|
||||
//while(soc_get_ccount() - tmp < 192-24) {}
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) inline void send0() { // 400ns high, 850ns low
|
||||
__attribute__((always_inline)) void send0() { // 400ns high, 850ns low
|
||||
LED_SET_PIN_H;
|
||||
delay100();
|
||||
delayS();
|
||||
LED_SET_PIN_L;
|
||||
delay800();
|
||||
delayL();
|
||||
//const uint32_t tmp = soc_get_ccount();
|
||||
//LED_SET_PIN_H;
|
||||
//while(soc_get_ccount() - tmp < 48) {}
|
||||
//LED_SET_PIN_L;
|
||||
//while(soc_get_ccount() - tmp < 192-24) {}
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) inline void reset() {
|
||||
LED_SET_PIN_L;
|
||||
os_delay_us(50);
|
||||
__attribute__((always_inline)) void reset() {
|
||||
LED_SET_PIN_L; // low for more than 50 us
|
||||
//const uint32_t tmp = soc_get_ccount();
|
||||
//while(soc_get_ccount() - tmp < 9999) {}
|
||||
//os_delay_us(100);
|
||||
//LED_SET_PIN_H;
|
||||
//asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
|
||||
//LED_SET_PIN_L;
|
||||
//delayMicroseconds(50);
|
||||
}
|
||||
|
||||
|
||||
//#pragma GCC optimize 0
|
||||
|
||||
__attribute__((always_inline)) inline void delay50() {
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
asm volatile("nop");
|
||||
|
||||
__attribute__((always_inline)) void delayS() {
|
||||
for(uint8_t i = 0; i < (9*1); ++i) {asm("nop");}
|
||||
}
|
||||
|
||||
|
||||
// 100 ns delay. @80 MHz one nop = 12,5ns
|
||||
__attribute__((always_inline)) inline void delay100() {
|
||||
delay50();
|
||||
delay50();
|
||||
|
||||
__attribute__((always_inline)) void delayL() {
|
||||
for(uint8_t i = 0; i < (9*2); ++i) {asm("nop");}
|
||||
}
|
||||
|
||||
/*
|
||||
__attribute__((always_inline)) inline void delay200() {
|
||||
delay100();
|
||||
delay100();
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) inline void delay400() {
|
||||
delay100();
|
||||
delay100();
|
||||
delay100();
|
||||
delay100();
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) inline void delay500() {
|
||||
delay100();
|
||||
delay100();
|
||||
delay100();
|
||||
delay100();
|
||||
delay100();
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) inline void delay600() {
|
||||
delay100();
|
||||
delay100();
|
||||
delay100();
|
||||
delay100();
|
||||
delay100();
|
||||
delay100();
|
||||
}
|
||||
*/
|
||||
|
||||
__attribute__((always_inline)) inline void delay800() {
|
||||
delay100();
|
||||
delay100();
|
||||
delay100();
|
||||
delay100();
|
||||
delay100();
|
||||
delay100();
|
||||
delay100();
|
||||
delay100();
|
||||
}
|
||||
|
||||
|
||||
// #pragma GCC reset_options
|
||||
|
||||
|
||||
|
||||
// inline void delayNS(const uint16_t ns) {
|
||||
// const uint16_t ticks = ns / NS_PER_TICK / 2;
|
||||
// for (uint16_t i = 0; i < ticks; ++i) {asm("nop");}
|
||||
// }
|
||||
|
||||
};
|
||||
|
||||
#elif false// ESP32aaa
|
||||
@@ -452,7 +426,7 @@
|
||||
|
||||
};
|
||||
|
||||
#elif ESP32
|
||||
#elif IS_ESP32
|
||||
|
||||
#include "../../io/I2S.h"
|
||||
|
||||
@@ -474,7 +448,7 @@
|
||||
}
|
||||
|
||||
void init() {
|
||||
debugMod1(TAG, "init with %d leds", NUM_LEDS);
|
||||
Log::addInfo(TAG, "init with %d leds", NUM_LEDS);
|
||||
cfg();
|
||||
}
|
||||
|
||||
|
||||
228
ext/led/WS2812B_v2.h
Normal file
228
ext/led/WS2812B_v2.h
Normal file
@@ -0,0 +1,228 @@
|
||||
#ifndef WS2812B_H
|
||||
#define WS2812B_H
|
||||
|
||||
#include "../../data/Color.h"
|
||||
#include "../../Platforms.h"
|
||||
#include "../../Debug.h"
|
||||
#include "../../io/GPIO.h"
|
||||
|
||||
#include <xtensa/xtruntime.h>
|
||||
|
||||
|
||||
#if IS_ESP8266
|
||||
|
||||
// https://github.com/FastLED/FastLED/tree/master/src/platforms/esp/8266
|
||||
|
||||
//#include "../../io/fastGPIO.h"
|
||||
#include "../../io/GPIO.h"
|
||||
#include "driver/i2s.h"
|
||||
#include <string.h>
|
||||
|
||||
template <int numLEDs> class WS2812B {
|
||||
|
||||
static constexpr const char* NAME = "WS2812B";
|
||||
|
||||
#define LED_SET_PIN_TO_OUTPUT MyGPIO::setOutput(5) //GPIO5_OUTPUT_SET
|
||||
#define LED_SET_PIN_H MyGPIO::set(5) //GPIO5_H
|
||||
#define LED_SET_PIN_L MyGPIO::clear(5) //GPIO5_L
|
||||
|
||||
//#define NS_PER_TICK ( (1000ul*1000ul*1000ul) / (80ul*1000ul*1000ul) )
|
||||
|
||||
/** color-value for each attached LED */
|
||||
Color colors[numLEDs];
|
||||
|
||||
/** enable/disable each led */
|
||||
bool enabled[numLEDs] = {true};
|
||||
|
||||
static constexpr const int bits = 16;
|
||||
static constexpr const i2s_port_t I2S_NUM = (i2s_port_t)0;
|
||||
static constexpr const int SAMPLE_RATE = 44100; // 100000
|
||||
|
||||
class SendBuffer {
|
||||
|
||||
uint32_t buf[numLEDs * 3 + 32];
|
||||
int idx = 0;
|
||||
|
||||
i2s_config_t i2s_config;
|
||||
i2s_pin_config_t pin_config;
|
||||
|
||||
public:
|
||||
|
||||
SendBuffer() {
|
||||
|
||||
}
|
||||
|
||||
void init() {
|
||||
|
||||
Log::addInfo("i2s", "init()");
|
||||
memset(&i2s_config, 0, sizeof(i2s_config));
|
||||
i2s_config.mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_TX); // Only TX
|
||||
i2s_config.sample_rate = SAMPLE_RATE;
|
||||
i2s_config.bits_per_sample = (i2s_bits_per_sample_t)16; // 16 bit
|
||||
i2s_config.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT; // 2-channels
|
||||
i2s_config.communication_format = (i2s_comm_format_t) (I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB);
|
||||
i2s_config.dma_buf_count = 6;
|
||||
i2s_config.dma_buf_len = 256;
|
||||
|
||||
memset(&pin_config, 0, sizeof(pin_config));
|
||||
pin_config.bck_o_en = 1;
|
||||
pin_config.ws_o_en = 2;
|
||||
pin_config.data_out_en = 15; // 5
|
||||
|
||||
ESP_ERROR_CHECK(i2s_driver_install(I2S_NUM, &i2s_config, 0, nullptr));
|
||||
ESP_ERROR_CHECK(i2s_set_pin(I2S_NUM, &pin_config));
|
||||
//ESP_ERROR_CHECK(i2s_set_clk(I2S_NUM, SAMPLE_RATE, (i2s_bits_per_sample_t)16, (i2s_channel_t)2));
|
||||
|
||||
}
|
||||
|
||||
|
||||
void reset() {
|
||||
idx = 0;
|
||||
}
|
||||
|
||||
void add(uint8_t b) {
|
||||
buf[idx] = encode(b);
|
||||
++idx;
|
||||
}
|
||||
|
||||
void transmit() {
|
||||
|
||||
size_t written = 0;
|
||||
size_t bytes = 512;//sizeof(uint32_t) * idx + 20+512;
|
||||
ESP_ERROR_CHECK(i2s_write(I2S_NUM, buf, bytes, &written, 100));
|
||||
Log::addInfo("I2s", "transmit %d %d", bytes, written);
|
||||
}
|
||||
|
||||
/** byte -> i2s transmission pattern */
|
||||
uint32_t encode(uint8_t b) {
|
||||
|
||||
#define _LO 0b1000
|
||||
#define _HI 0b1110
|
||||
uint32_t res;
|
||||
uint8_t* tmp = (uint8_t*) &res;
|
||||
tmp[0] = (((b & (1<<7)) ? (_HI) : (_LO)) << 4) | (((b & (1<<6)) ? (_HI) : (_LO)) << 0);
|
||||
tmp[1] = (((b & (1<<5)) ? (_HI) : (_LO)) << 4) | (((b & (1<<4)) ? (_HI) : (_LO)) << 0);
|
||||
tmp[2] = (((b & (1<<3)) ? (_HI) : (_LO)) << 4) | (((b & (1<<2)) ? (_HI) : (_LO)) << 0);
|
||||
tmp[3] = (((b & (1<<1)) ? (_HI) : (_LO)) << 4) | (((b & (1<<0)) ? (_HI) : (_LO)) << 0);
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
} sendBuf;
|
||||
|
||||
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/** ctor */
|
||||
WS2812B() {
|
||||
init();
|
||||
}
|
||||
|
||||
void init() {
|
||||
LED_SET_PIN_TO_OUTPUT;
|
||||
Log::addInfo(NAME, "init with %d leds", numLEDs);
|
||||
}
|
||||
|
||||
void init2() {
|
||||
sendBuf.init();
|
||||
}
|
||||
|
||||
/** set the color for the given LED */
|
||||
void setColor(const uint8_t idx, const Color rgb) {
|
||||
colors[idx] = rgb;
|
||||
}
|
||||
|
||||
/** set the color for all LEDs */
|
||||
void setColor(const Color rgb) {
|
||||
for (int idx = 0; idx < numLEDs; ++idx) {
|
||||
colors[idx] = rgb;
|
||||
}
|
||||
}
|
||||
|
||||
/** enable/disable the given LED */
|
||||
void setEnabled(const uint8_t idx, const bool en) {
|
||||
enabled[idx] = en;
|
||||
}
|
||||
|
||||
/** enable/disable all LEDs */
|
||||
void setEnabled(const bool en) {
|
||||
for (int idx = 0; idx < numLEDs; ++idx) {
|
||||
enabled[idx] = en;
|
||||
}
|
||||
}
|
||||
|
||||
/** is the given LED enabled? */
|
||||
bool isEnabled(const uint8_t idx) const {
|
||||
return enabled[idx];
|
||||
}
|
||||
|
||||
Color& getColor(const uint8_t idx) {
|
||||
return colors[idx];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** flush configured changes */
|
||||
IRAM_ATTR void flush() {
|
||||
|
||||
sendBuf.reset();
|
||||
|
||||
// process each LED
|
||||
for (uint16_t i = 0; i < numLEDs; ++i) {
|
||||
|
||||
// send each LEDs 24-bit GRB data
|
||||
if (enabled[i]) {
|
||||
const Color rgb = colors[i];
|
||||
sendBuf.add(rgb.g);
|
||||
sendBuf.add(rgb.r);
|
||||
sendBuf.add(rgb.b);
|
||||
} else {
|
||||
sendBuf.add(0);
|
||||
sendBuf.add(0);
|
||||
sendBuf.add(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sendBuf.transmit();
|
||||
|
||||
}
|
||||
|
||||
/** flush configured changes, including global brightness */
|
||||
IRAM_ATTR void flushBrightness(const uint8_t brightness) {
|
||||
|
||||
sendBuf.reset();
|
||||
|
||||
// process each LED
|
||||
for (uint16_t i = 0; i < numLEDs; ++i) {
|
||||
|
||||
// send each LEDs 24-bit GRB data
|
||||
if (enabled[i]) {
|
||||
const Color rgb = colors[i].brightness(brightness);
|
||||
sendBuf.add(rgb.g);
|
||||
sendBuf.add(rgb.r);
|
||||
sendBuf.add(rgb.b);
|
||||
} else {
|
||||
sendBuf.add(0);
|
||||
sendBuf.add(0);
|
||||
sendBuf.add(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sendBuf.transmit();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif // WS2812B_H
|
||||
Reference in New Issue
Block a user