diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index f77dc4de4..2a8e4712d 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -12,6 +12,21 @@ } }, + // To give the container access to a device serial port, you can uncomment one of the following lines. + // Note: If running on Windows, you will have to do some additional steps: + // https://stackoverflow.com/questions/68527888/how-can-i-use-a-usb-com-port-inside-of-a-vscode-development-container + // + // You can explicitly just forward the port you want to connect to. Replace `/dev/ttyACM0` with the serial port for + // your device. This will only work if the device is plugged in from the start without reconnecting. Adding the + // `dialout` group is needed if read/write permisions for the port are limitted to the dialout user. + // "runArgs": ["--device=/dev/ttyACM0", "--group-add", "dialout"], + // + // Alternatively, you can give more comprehensive access to the host system. This will expose all the host devices to + // the container. Adding the `dialout` group is needed if read/write permisions for the port are limitted to the + // dialout user. This could allow the container to modify unrelated serial devices, which would be a similar level of + // risk to running the build directly on the host. + // "runArgs": ["--privileged", "-v", "/dev/bus/usb:/dev/bus/usb", "--group-add", "dialout"], + // Set *default* container specific settings.json values on container create. "settings": { "terminal.integrated.shell.linux": "/bin/bash", diff --git a/wled00/FX.cpp b/wled00/FX.cpp index cce3098e1..bded21060 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -2106,14 +2106,17 @@ uint16_t mode_fire_2012() { for (unsigned stripNr=0; stripNr> 2; + SEGMENT.blur(blurAmount); + } if (it != SEGENV.step) SEGENV.step = it; return FRAMETIME; } -static const char _data_FX_MODE_FIRE_2012[] PROGMEM = "Fire 2012@Cooling,Spark rate,,,Boost;;!;1;sx=64,ix=160,m12=1"; // bars +static const char _data_FX_MODE_FIRE_2012[] PROGMEM = "Fire 2012@Cooling,Spark rate,,2D Blur,Boost;;!;1;sx=64,ix=160,m12=1,c2=128"; // bars // ColorWavesWithPalettes by Mark Kriegsman: https://gist.github.com/kriegsman/8281905786e8b2632aeb @@ -7456,7 +7459,7 @@ uint16_t mode_2DGEQ(void) { // By Will Tatam. Code reduction by Ewoud Wijma. if ((fadeoutDelay <= 1 ) || ((SEGENV.call % fadeoutDelay) == 0)) SEGMENT.fadeToBlackBy(SEGMENT.speed); for (int x=0; x < cols; x++) { - uint8_t band = map(x, 0, cols-1, 0, NUM_BANDS - 1); + uint8_t band = map(x, 0, cols, 0, NUM_BANDS); if (NUM_BANDS < 16) band = map(band, 0, NUM_BANDS - 1, 0, 15); // always use full range. comment out this line to get the previous behaviour. band = constrain(band, 0, 15); unsigned colorIndex = band * 17; diff --git a/wled00/bus_manager.cpp b/wled00/bus_manager.cpp index 1696b37ee..14ede756f 100644 --- a/wled00/bus_manager.cpp +++ b/wled00/bus_manager.cpp @@ -355,18 +355,41 @@ void BusDigital::cleanup() { } +#ifdef ESP8266 + // 1 MHz clock + #define CLOCK_FREQUENCY 1000000UL +#else + // Use XTAL clock if possible to avoid timer frequency error when setting APB clock < 80 Mhz + // https://github.com/espressif/arduino-esp32/blob/2.0.2/cores/esp32/esp32-hal-ledc.c + #ifdef SOC_LEDC_SUPPORT_XTAL_CLOCK + #define CLOCK_FREQUENCY 40000000UL + #else + #define CLOCK_FREQUENCY 80000000UL + #endif +#endif + +#ifdef ESP8266 + #define MAX_BIT_WIDTH 10 +#else + #ifdef SOC_LEDC_TIMER_BIT_WIDE_NUM + // C6/H2/P4: 20 bit, S2/S3/C2/C3: 14 bit + #define MAX_BIT_WIDTH SOC_LEDC_TIMER_BIT_WIDE_NUM + #else + // ESP32: 20 bit (but in reality we would never go beyond 16 bit as the frequency would be to low) + #define MAX_BIT_WIDTH 20 + #endif +#endif + BusPwm::BusPwm(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWhite, 1, bc.reversed) { if (!IS_PWM(bc.type)) return; unsigned numPins = NUM_PWM_PINS(bc.type); _frequency = bc.frequency ? bc.frequency : WLED_PWM_FREQ; + // duty cycle resolution (_depth) can be extracted from this formula: CLOCK_FREQUENCY > _frequency * 2^_depth + for (_depth = MAX_BIT_WIDTH; _depth > 8; _depth--) if (((CLOCK_FREQUENCY/_frequency) >> _depth) > 0) break; #ifdef ESP8266 - // duty cycle resolution (_depth) can be extracted from this formula: 1MHz > _frequency * 2^_depth - if (_frequency > 1760) _depth = 8; - else if (_frequency > 880) _depth = 9; - else _depth = 10; // WLED_PWM_FREQ <= 880Hz analogWriteRange((1<<_depth)-1); analogWriteFreq(_frequency); #else @@ -374,11 +397,6 @@ BusPwm::BusPwm(BusConfig &bc) if (_ledcStart == 255) { //no more free LEDC channels deallocatePins(); return; } - // duty cycle resolution (_depth) can be extracted from this formula: 80MHz > _frequency * 2^_depth - if (_frequency > 78124) _depth = 9; - else if (_frequency > 39062) _depth = 10; - else if (_frequency > 19531) _depth = 11; - else _depth = 12; // WLED_PWM_FREQ <= 19531Hz #endif for (unsigned i = 0; i < numPins; i++) { @@ -396,7 +414,7 @@ BusPwm::BusPwm(BusConfig &bc) } _data = _pwmdata; // avoid malloc() and use stack _valid = true; - DEBUGBUS_PRINTF_P(PSTR("%successfully inited PWM strip with type %u and pins %u,%u,%u,%u,%u\n"), _valid?"S":"Uns", bc.type, _pins[0], _pins[1], _pins[2], _pins[3], _pins[4]); + DEBUGBUS_PRINTF_P(PSTR("%successfully inited PWM strip with type %u, frequency %u, bit depth %u and pins %u,%u,%u,%u,%u\n"), _valid?"S":"Uns", bc.type, _frequency, _depth, _pins[0], _pins[1], _pins[2], _pins[3], _pins[4]); } void BusPwm::setPixelColor(uint16_t pix, uint32_t c) {