Skip to content

Commit

Permalink
adding esp32s3 suppport
Browse files Browse the repository at this point in the history
  • Loading branch information
Yves BAZIN authored and Yves BAZIN committed Nov 20, 2024
1 parent 53be7fa commit 7a7a39c
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 19 deletions.
24 changes: 23 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
[![build status](https://github.com/hpwit/I2SClocklessVirtualLedDriver/actions/workflows/testcode.yml/badge.svg)](https://github.com/hpwit/I2SClocklessVirtualLedDriver/actions/workflows/testcode.yml)   [![Badge Version](https://img.shields.io/github/v/release/hpwit/I2SClocklessVirtualLedDriver?label=latest%20release)](https://github.com/hpwit/I2SClocklessVirtualLedDriver/releases/latest)   [![Badge Version](https://img.shields.io/badge/release_note-blue)](Releasenote.md)

# I2SClocklessVirtualLedDriver for esp32
# I2SClocklessVirtualLedDriver for esp32 and esp32S3
## Introduction
Hello led afficionados !! Here is the new version of the Virtual pins library. In reality this version of the library had been sitting more or less finalized on my laptop for a while. I needed to take the time and energy to write the correct examples and of course update the documentation.
I have been writing led drivers for the past couple of years now while I was building [my 123x48 panel](https://hackaday.io/project/158268-5904-leds-panel).
It inspired me to create the I2S driver implemented in FastLED and then the Virtual pins library.
I am also planning to merge all my different led libraries (4 of them in total)

**NB : On the ESP32SS3 you can [overclock the leds](#for-esp32s3-only) up to 1125KHZ instead of 800KHZ**

### What kind of led do you want to drive
This library is a new take on driving ws2812 leds with I2S on an esp32. It allows to drive up to 120 strips !!! leds in parallel of
Expand Down Expand Up @@ -36,6 +37,9 @@ I have rewritten the library out of the FastLED framework to allow easier testin
I am trying to be kinda lenghtly on this readme. I hope to explain the why of some functions and for the user to use the one most suitable for its use case.
Some of the 'maybe most' of the functionailities will never been used be it was fun and intersting to implement.




## Let's start
### How can 120 strips can de driven in parallel with an esp32 !!!
The esp32 has 24 pins that can act as outputs pins. This is far away from 120 pins ...
Expand Down Expand Up @@ -256,11 +260,29 @@ Pixel leds[NUM_STRIPS*NUM_LEDS_PER_STRIP];
```

#### Other initialization functions:


* `void initled(Pixel leds, int *Pinsq, int CLOCK_PIN, int LATCH_PIN)`
* `void initled(CRGB leds, int *Pinsq, int CLOCK_PIN, int LATCH_PIN)`
* `void initled(frameBuffer *leds, int *Pinsq, int CLOCK_PIN, int LATCH_PIN)` this will be explained later on how to use a frameBuffer
* `void initled(int *Pinsq, int CLOCK_PIN, int LATCH_PIN)`: you can initialized the driver without a led buffer.
this is also used in the case of direct pixel calculation

#### For esp32S3 only
Thanks to the ESP32 LCD driver being faster you can overclock the leds output (which is limited on the esp32 to send 8 pixels per pin at 800KHZ you need a 19.2Mhz clock and the esp32 above 20Mhz is not reliable)
* `void initled(Pixel leds, int *Pinsq, int CLOCK_PIN, int LATCH_PIN,clock_speed clock)`
* `void initled(CRGB leds, int *Pinsq, int CLOCK_PIN, int LATCH_PIN,clock_speed clock)`
* `void initled((uint8_t*)leds,pins,CLOCK_PIN,LATCH_PIN,clock_speed clock)`

Here are the possible values
* `clock_800KHZ` : default value
* `clock_1000KHZ` : works really fine
* `clock_1111KHZ` : depending on your boards
* `clock_1123KHZ` : the max I manage to get

example:
`driver.initled(pins,CLOCK_PIN,LATCH_PIN,clock_1111KHZ)`

```C
Pixel led1[NUM_LEDS];
Pixel leds2[NUM_LEDS];
Expand Down
10 changes: 10 additions & 0 deletions examples/colorpalette/colorpalette.ino
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,20 @@
#define _USE_PALETTE
#define USE_FASTLED // to have the CHSV mapping
#include "I2SClocklessVirtualLedDriver.h"
#ifdef CONFIG_IDF_TARGET_ESP32S3
#define LATCH_PIN 46
#define CLOCK_PIN 3
#else

#define LATCH_PIN 27
#define CLOCK_PIN 26
#endif

#ifdef CONFIG_IDF_TARGET_ESP32S3
int Pins[6] = {9, 10,12,8,18,17};
#else
int Pins[6] = {14, 12, 13, 25, 33, 32};
#endif

I2SClocklessVirtualLedDriver driver;
uint8_t leds[NUM_LEDS];
Expand Down
20 changes: 16 additions & 4 deletions examples/framebuffer/framebuffer.ino
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,20 @@
#define NUM_LEDS (NUM_LEDS_PER_STRIP * NBIS2SERIALPINS * 8)
#define NUM_STRIPS (NBIS2SERIALPINS * 8)
#include "I2SClocklessVirtualLedDriver.h"
#define _LATCH_PIN 27
#define _CLOCK_PIN 26
#ifdef CONFIG_IDF_TARGET_ESP32S3
#define LATCH_PIN 46
#define CLOCK_PIN 3
#else

#define LATCH_PIN 27
#define CLOCK_PIN 26
#endif

#ifdef CONFIG_IDF_TARGET_ESP32S3
int Pins[6] = {9, 10,12,8,18,17};
#else
int Pins[6] = {14, 12, 13, 25, 33, 32};
#endif

#if TEST_USE_FRAMEBUFFER == 1
frameBuffer leds = frameBuffer(NUM_LEDS);
Expand All @@ -22,9 +34,9 @@ void setup()
{
Serial.begin(115200);
#if TEST_USE_FRAMEBUFFER == 1
driver.initled(&leds, Pins, _CLOCK_PIN, _LATCH_PIN);
driver.initled(&leds, Pins, CLOCK_PIN, LATCH_PIN);
#else
driver.initled(leds, Pins, _CLOCK_PIN, _LATCH_PIN);
driver.initled(leds, Pins, CLOCK_PIN, LATCH_PIN);
#endif
driver.setBrightness(20);
}
Expand Down
Empty file added for-esp32s3-only
Empty file.
4 changes: 2 additions & 2 deletions library.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"name": "I2SClocklessVirtualLedDriver",
"keywords": "NeoPixel, WS2811, WS2812, WS2813, SK6812, DotStar, RGB, RGBW",
"description": "Supports for Esp32. Support for RGBW pixels. up to 120 stips in full parallel mode.",
"description": "Supports for Esp32 and esp32s3. Support for RGBW pixels. up to 120 stips in full parallel mode.",
"homepage": "ttps://github.com/hpwit/I2SClocklessVirtualLedDriver",
"repository":
{
"type": "git",
"url": "https://github.com/hpwit/I2SClocklessVirtualLedDriver"
},
"version": "2.0.0",
"version": "2.1.0",
"frameworks": "arduino",
"platforms": "*"
}
Expand Down
4 changes: 2 additions & 2 deletions library.properties
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
name=I2SClocklessVirtualLedDriver
version=2.0.0
version=2.1.0
author=Yves BAZIN
maintainer=Yves BAZIN
sentence=A library that makes controlling NeoPixels (WS2811, WS2812, WS2813 & SK6812) in parallel mode for esp32.
paragraph=Supports for Esp32. Support for RGBW pixels. up to 120 stips in full parallel mode.
paragraph=Supports for Esp32 and esp32s3. Support for RGBW pixels. up to 120 stips in full parallel mode.
category=Display
url=https://github.com/hpwit/I2SClocklessVirtualLedDriver
architectures=*
57 changes: 47 additions & 10 deletions src/I2SClocklessVirtualLedDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ struct gdma_channel_t {
uint32_t start_stop_by_etm: 1; // whether the channel is started/stopped by ETM
} flags;
};

#ifdef OVER_CLOCK_MAX
#define CLOCK_DIV_NUM 4
#define CLOCK_DIV_A 20
#define CLOCK_DIV_B 9
#endif
#ifdef OVERCLOCK_1MHZ
#define CLOCK_DIV_NUM 5
#define CLOCK_DIV_A 1
Expand All @@ -53,17 +59,26 @@ struct gdma_channel_t {
#define CLOCK_DIV_A 8
#define CLOCK_DIV_B 4
#endif
#ifdef OVERCLOCK_0_7MHZ
#define CLOCK_DIV_NUM 7
#define CLOCK_DIV_A 1
#define CLOCK_DIV_B 0
#endif
#ifndef CLOCK_DIV_NUM
#define CLOCK_DIV_NUM 6
#define CLOCK_DIV_A 4
#define CLOCK_DIV_B 1
#endif

typedef struct
{
int div_num;
int div_a;
int div_b;
}clock_speed;

clock_speed clock_1123KHZ={4,20,9};
clock_speed clock_1111KHZ={4,2,1};
clock_speed clock_1000KHZ={5,1,0};
clock_speed clock_800KHZ={6,4,1};



#define WS2812_DMA_DESCRIPTOR_BUFFER_MAX_SIZE (576*2)


Expand Down Expand Up @@ -295,7 +310,7 @@ typedef union
} Lines;

#ifdef CONFIG_IDF_TARGET_ESP32S3
uint8_t signalsID[16]={
static uint8_t signalsID[16]={
LCD_DATA_OUT0_IDX,
LCD_DATA_OUT1_IDX,
LCD_DATA_OUT2_IDX,
Expand All @@ -314,7 +329,7 @@ LCD_DATA_OUT14_IDX,
LCD_DATA_OUT15_IDX,

};
gdma_channel_handle_t dma_chan;
static gdma_channel_handle_t dma_chan;

#endif

Expand Down Expand Up @@ -437,6 +452,9 @@ class I2SClocklessVirtualLedDriver
#ifndef CONFIG_IDF_TARGET_ESP32S3
i2s_dev_t *i2s;
#endif
#ifdef CONFIG_IDF_TARGET_ESP32S3
clock_speed _clockspeed=clock_800KHZ;
#endif
int _maxtime;
int _max_pixels_out_of_time;
int _over_frames;
Expand Down Expand Up @@ -673,9 +691,9 @@ class I2SClocklessVirtualLedDriver
LCD_CAM.lcd_clock.lcd_ck_out_edge = 0; // PCLK low in 1st half cycle
LCD_CAM.lcd_clock.lcd_ck_idle_edge = 0; // PCLK low idle
LCD_CAM.lcd_clock.lcd_clk_equ_sysclk = 0; // PCLK = CLK / (CLKCNT_N+1)
LCD_CAM.lcd_clock.lcd_clkm_div_num = CLOCK_DIV_NUM; // 1st stage 1:250 divide
LCD_CAM.lcd_clock.lcd_clkm_div_a = CLOCK_DIV_A; // 0/1 fractional divide
LCD_CAM.lcd_clock.lcd_clkm_div_b = CLOCK_DIV_B;
LCD_CAM.lcd_clock.lcd_clkm_div_num = _clockspeed.div_num; // 1st stage 1:250 divide
LCD_CAM.lcd_clock.lcd_clkm_div_a = _clockspeed.div_a; // 0/1 fractional divide
LCD_CAM.lcd_clock.lcd_clkm_div_b = _clockspeed.div_b;
LCD_CAM.lcd_clock.lcd_clkcnt_n = 1; //

LCD_CAM.lcd_ctrl.lcd_rgb_mode_en = 0; // i8080 mode (not RGB)
Expand Down Expand Up @@ -1731,13 +1749,32 @@ Driver data (overall frames):\n - nb of frames displayed:%d\n - nb of fr
{
initled((uint8_t *)leds, Pinsq, clock_pin, latch_pin);
}
#ifdef CONFIG_IDF_TARGET_ESP32S3
void initled(CRGB *leds, int *Pinsq, int clock_pin, int latch_pin,clock_speed clock)
{
_clockspeed=clock;
initled((uint8_t *)leds, Pinsq, clock_pin, latch_pin);
}
#endif
#endif

void initled(Pixel *leds, int *Pinsq, int clock_pin, int latch_pin)
{
initled((uint8_t *)leds, Pinsq, clock_pin, latch_pin);
}

#ifdef CONFIG_IDF_TARGET_ESP32S3
void initled(Pixel *leds, int *Pinsq, int clock_pin, int latch_pin,clock_speed clock)
{
_clockspeed=clock;
initled((uint8_t *)leds, Pinsq, clock_pin, latch_pin);
}
void initled(uint8_t *leds, int *Pinsq, int clock_pin, int latch_pin,clock_speed clock)
{
_clockspeed=clock;
initled((uint8_t *)leds, Pinsq, clock_pin, latch_pin);
}
#endif
void initled(uint8_t *leds, int *Pinsq, int clock_pin, int latch_pin)
{
this->leds = leds;
Expand Down

0 comments on commit 7a7a39c

Please sign in to comment.