8686
8787#pragma once
8888
89- #pragma message "NOTE: ESP32 support using I2S parallel driver. All strips must use the same chipset"
89+ // This is way too noisy. Is output a LARGE NUMBER of times.
90+ // #pragma message "NOTE: ESP32 support using I2S parallel driver. All strips must use the same chipset"
9091
9192FASTLED_NAMESPACE_BEGIN
9293
@@ -95,15 +96,19 @@ extern "C" {
9596#endif
9697
9798#include " esp_heap_caps.h"
99+ #include " esp_intr_alloc.h"
100+ #include " freertos/task.h"
101+ #include " freertos/semphr.h"
102+
98103#include " soc/soc.h"
99104#include " soc/gpio_sig_map.h"
100105#include " soc/i2s_reg.h"
101106#include " soc/i2s_struct.h"
102107#include " soc/io_mux_reg.h"
103108#include " driver/gpio.h"
104109#include " driver/periph_ctrl.h"
105- #include " rom/lldesc.h"
106- # include " esp_intr_alloc.h "
110+ #include " esp32/ rom/lldesc.h"
111+
107112#include " esp_log.h"
108113
109114#ifdef __cplusplus
@@ -131,7 +136,7 @@ __attribute__ ((always_inline)) inline static uint32_t __clock_cycles() {
131136
132137// -- I2S clock
133138#define I2S_BASE_CLK (80000000L )
134- #define I2S_MAX_CLK (20000000L ) // more tha a certain speed and the I2s looses some bits
139+ #define I2S_MAX_CLK (20000000L ) // more tha a certain speed and the I2s loses some bits
135140#define I2S_MAX_PULSE_PER_BIT 20 // put it higher to get more accuracy but it could decrease the refresh rate without real improvement
136141// -- Convert ESP32 cycles back into nanoseconds
137142#define ESPCLKS_TO_NS (_CLKS ) (((long )(_CLKS) * 1000L ) / F_CPU_MHZ)
@@ -262,16 +267,16 @@ class ClocklessController : public CPixelLEDController<RGB_ORDER>
262267 static void initBitPatterns ()
263268 {
264269 // Precompute the bit patterns based on the I2S sample rate
265- // Serial. println("Setting up fastled using I2S");
270+ // println("Setting up fastled using I2S");
266271
267272 // -- First, convert back to ns from CPU clocks
268273 uint32_t T1ns = ESPCLKS_TO_NS (T1);
269274 uint32_t T2ns = ESPCLKS_TO_NS (T2);
270275 uint32_t T3ns = ESPCLKS_TO_NS (T3);
271276
272- // Serial. print("T1 = "); Serial. print(T1); Serial. print(" ns "); Serial. println(T1ns);
273- // Serial. print("T2 = "); Serial. print(T2); Serial. print(" ns "); Serial. println(T2ns);
274- // Serial. print("T3 = "); Serial. print(T3); Serial. print(" ns "); Serial. println(T3ns);
277+ // print("T1 = "); print(T1); print(" ns "); println(T1ns);
278+ // print("T2 = "); print(T2); print(" ns "); println(T2ns);
279+ // print("T3 = "); print(T3); print(" ns "); println(T3ns);
275280
276281 /*
277282 We calculate the best pcgd to the timing
@@ -287,21 +292,21 @@ class ClocklessController : public CPixelLEDController<RGB_ORDER>
287292 if (smallest>T3)
288293 smallest=T3;
289294 double freq=(double )1 /(double )(T1ns + T2ns + T3ns);
290- // Serial. printf("chipset frequency:%f Khz\n", 1000000L*freq);
291- // Serial. printf("smallest %d\n",smallest);
295+ // printf("chipset frequency:%f Khz\n", 1000000L*freq);
296+ // printf("smallest %d\n",smallest);
292297 int pgc_=1 ;
293298 int precision=0 ;
294299 pgc_=pgcd (smallest,precision,T1,T2,T3);
295- // Serial. printf("%f\n",I2S_MAX_CLK/(1000000000L*freq));
300+ // printf("%f\n",I2S_MAX_CLK/(1000000000L*freq));
296301 while (pgc_==1 || (T1/pgc_ +T2/pgc_ +T3/pgc_)>I2S_MAX_PULSE_PER_BIT) // while(pgc_==1 || (T1/pgc_ +T2/pgc_ +T3/pgc_)>I2S_MAX_CLK/(1000000000L*freq))
297302 {
298303 precision++;
299304 pgc_=pgcd (smallest,precision,T1,T2,T3);
300- // Serial. printf("%d %d\n",pgc_,(a+b+c)/pgc_);
305+ // printf("%d %d\n",pgc_,(a+b+c)/pgc_);
301306 }
302307 pgc_=pgcd (smallest,precision,T1,T2,T3);
303- // Serial. printf("pgcd %d precision:%d\n",pgc_,precision);
304- // Serial. printf("nb pulse per bit:%d\n",T1/pgc_ +T2/pgc_ +T3/pgc_);
308+ // printf("pgcd %d precision:%d\n",pgc_,precision);
309+ // printf("nb pulse per bit:%d\n",T1/pgc_ +T2/pgc_ +T3/pgc_);
305310 gPulsesPerBit =(int )T1/pgc_ +(int )T2/pgc_ +(int )T3/pgc_;
306311 /*
307312 we calculate the duration of one pulse nd htre base frequency of the led
@@ -312,7 +317,7 @@ class ClocklessController : public CPixelLEDController<RGB_ORDER>
312317 */
313318
314319 freq=1000000000L *freq*gPulsesPerBit ;
315- // Serial. printf("needed frequency (nbpiulse per bit)*(chispset frequency):%f Mhz\n",freq/1000000);
320+ // printf("needed frequency (nbpiulse per bit)*(chispset frequency):%f Mhz\n",freq/1000000);
316321
317322 /*
318323 we do calculate the needed N a and b
@@ -321,7 +326,7 @@ class ClocklessController : public CPixelLEDController<RGB_ORDER>
321326
322327 */
323328
324- CLOCK_DIVIDER_N=(int )((double )I2S_BASE_CLK/freq);
329+ CLOCK_DIVIDER_N=(int )((double )I2S_BASE_CLK/freq);
325330 double v=I2S_BASE_CLK/freq-CLOCK_DIVIDER_N;
326331
327332 double prec=(double )1 /63 ;
@@ -362,23 +367,23 @@ class ClocklessController : public CPixelLEDController<RGB_ORDER>
362367 }
363368
364369 // printf("%d %d %f %f %d\n",CLOCK_DIVIDER_B,CLOCK_DIVIDER_A,(double)CLOCK_DIVIDER_B/CLOCK_DIVIDER_A,v,CLOCK_DIVIDER_N);
365- // Serial. printf("freq %f %f\n",freq,I2S_BASE_CLK/(CLOCK_DIVIDER_N+(double)CLOCK_DIVIDER_B/CLOCK_DIVIDER_A));
370+ // printf("freq %f %f\n",freq,I2S_BASE_CLK/(CLOCK_DIVIDER_N+(double)CLOCK_DIVIDER_B/CLOCK_DIVIDER_A));
366371 freq=1 /(CLOCK_DIVIDER_N+(double )CLOCK_DIVIDER_B/CLOCK_DIVIDER_A);
367372 freq=freq*I2S_BASE_CLK;
368- // Serial. printf("calculted for i2s frequency:%f Mhz N:%d B:%d A:%d\n",freq/1000000,CLOCK_DIVIDER_N,CLOCK_DIVIDER_B,CLOCK_DIVIDER_A);
373+ // printf("calculted for i2s frequency:%f Mhz N:%d B:%d A:%d\n",freq/1000000,CLOCK_DIVIDER_N,CLOCK_DIVIDER_B,CLOCK_DIVIDER_A);
369374 // double pulseduration=1000000000/freq;
370- // Serial. printf("Pulse duration: %f ns\n",pulseduration);
375+ // printf("Pulse duration: %f ns\n",pulseduration);
371376 // gPulsesPerBit = (T1ns + T2ns + T3ns)/FASTLED_I2S_NS_PER_PULSE;
372377
373- // Serial. print("Pulses per bit: "); Serial. println(gPulsesPerBit);
378+ // print("Pulses per bit: "); println(gPulsesPerBit);
374379
375380 // int ones_for_one = ((T1ns + T2ns - 1)/FASTLED_I2S_NS_PER_PULSE) + 1;
376381 ones_for_one = T1/pgc_ +T2/pgc_;
377- // Serial. print("One bit: target ");
378- // Serial. print(T1ns+T2ns); Serial. print("ns --- ");
379- // Serial. print(ones_for_one); Serial. print(" 1 bits");
380- // Serial. print(" = "); Serial. print(ones_for_one * FASTLED_I2S_NS_PER_PULSE); Serial. println("ns");
381- // Serial. printf("one bit : target %d ns --- %d pulses 1 bit = %f ns\n",T1ns+T2ns,ones_for_one ,ones_for_one*pulseduration);
382+ // print("One bit: target ");
383+ // print(T1ns+T2ns); print("ns --- ");
384+ // print(ones_for_one); print(" 1 bits");
385+ // print(" = "); print(ones_for_one * FASTLED_I2S_NS_PER_PULSE); println("ns");
386+ // printf("one bit : target %d ns --- %d pulses 1 bit = %f ns\n",T1ns+T2ns,ones_for_one ,ones_for_one*pulseduration);
382387
383388
384389 int i = 0 ;
@@ -393,11 +398,11 @@ class ClocklessController : public CPixelLEDController<RGB_ORDER>
393398
394399 // int ones_for_zero = ((T1ns - 1)/FASTLED_I2S_NS_PER_PULSE) + 1;
395400 ones_for_zero =T1/pgc_ ;
396- // Serial. print("Zero bit: target ");
397- // Serial. print(T1ns); Serial. print("ns --- ");
398- // Serial. print(ones_for_zero); Serial. print(" 1 bits");
399- // Serial. print(" = "); Serial. print(ones_for_zero * FASTLED_I2S_NS_PER_PULSE); Serial. println("ns");
400- // Serial. printf("Zero bit : target %d ns --- %d pulses 1 bit = %f ns\n",T1ns,ones_for_zero ,ones_for_zero*pulseduration);
401+ // print("Zero bit: target ");
402+ // print(T1ns); print("ns --- ");
403+ // print(ones_for_zero); print(" 1 bits");
404+ // print(" = "); print(ones_for_zero * FASTLED_I2S_NS_PER_PULSE); println("ns");
405+ // printf("Zero bit : target %d ns --- %d pulses 1 bit = %f ns\n",T1ns,ones_for_zero ,ones_for_zero*pulseduration);
401406 i = 0 ;
402407 while ( i < ones_for_zero ) {
403408 gZeroBit [i] = 0xFFFFFF00 ;
@@ -513,16 +518,18 @@ class ClocklessController : public CPixelLEDController<RGB_ORDER>
513518
514519 // -- Allocate i2s interrupt
515520 SET_PERI_REG_BITS (I2S_INT_ENA_REG (I2S_DEVICE), I2S_OUT_EOF_INT_ENA_V, 1 , I2S_OUT_EOF_INT_ENA_S);
516- esp_intr_alloc (interruptSource, 0 , // ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_LEVEL3,
517- &interruptHandler, 0 , &gI2S_intr_handle );
521+ ESP_ERROR_CHECK (
522+ esp_intr_alloc (interruptSource, 0 /* ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_LEVEL3*/ ,
523+ &interruptHandler, 0 , &gI2S_intr_handle )
524+ );
518525
519526 // -- Create a semaphore to block execution until all the controllers are done
520527 if (gTX_sem == NULL ) {
521528 gTX_sem = xSemaphoreCreateBinary ();
522529 xSemaphoreGive (gTX_sem );
523530 }
524531
525- // Serial. println("Init I2S");
532+ // println("Init I2S");
526533 gInitialized = true ;
527534 }
528535
@@ -562,8 +569,8 @@ class ClocklessController : public CPixelLEDController<RGB_ORDER>
562569 // -- Keep track of the number of strips we've seen
563570 gNumStarted ++;
564571
565- // Serial. print("Show pixels ");
566- // Serial. println(gNumStarted);
572+ // print("Show pixels ");
573+ // println(gNumStarted);
567574
568575 // -- The last call to showPixels is the one responsible for doing
569576 // all of the actual work
@@ -619,7 +626,7 @@ class ClocklessController : public CPixelLEDController<RGB_ORDER>
619626 * from each strip), transpose and encode the bits, and store
620627 * them in the DMA buffer for the I2S peripheral to read.
621628 */
622- static void fillBuffer ()
629+ static IRAM_ATTR void fillBuffer ()
623630 {
624631 // -- Alternate between buffers
625632 volatile uint32_t * buf = (uint32_t *) dmaBuffers[gCurBuffer ]->buffer ;
@@ -659,7 +666,7 @@ class ClocklessController : public CPixelLEDController<RGB_ORDER>
659666 // -- Tranpose each array: all the bit 7's, then all the bit 6's, ...
660667 transpose32 (gPixelRow [channel], gPixelBits [channel][0 ] );
661668
662- // Serial. print("Channel: "); Serial. print(channel); Serial. print(" ");
669+ // print("Channel: "); print(channel); print(" ");
663670 for (int bitnum = 0 ; bitnum < 8 ; bitnum++) {
664671 uint8_t * row = (uint8_t *) (gPixelBits [channel][bitnum]);
665672 uint32_t bit = (row[0 ] << 24 ) | (row[1 ] << 16 ) | (row[2 ] << 8 ) | row[3 ];
@@ -717,9 +724,9 @@ class ClocklessController : public CPixelLEDController<RGB_ORDER>
717724 static void i2sStart ()
718725 {
719726 // esp_intr_disable(gI2S_intr_handle);
720- // Serial. println("I2S start");
727+ // println("I2S start");
721728 i2sReset ();
722- // Serial. println(dmaBuffers[0]->sampleCount());
729+ // println(dmaBuffers[0]->sampleCount());
723730 i2s->lc_conf .val =I2S_OUT_DATA_BURST_EN | I2S_OUTDSCR_BURST_EN | I2S_OUT_DATA_BURST_EN;
724731 i2s->out_link .addr = (uint32_t ) & (dmaBuffers[0 ]->descriptor );
725732 i2s->out_link .start = 1 ;
@@ -740,7 +747,7 @@ class ClocklessController : public CPixelLEDController<RGB_ORDER>
740747
741748 static void i2sReset ()
742749 {
743- // Serial. println("I2S reset");
750+ // println("I2S reset");
744751 const unsigned long lc_conf_reset_flags = I2S_IN_RST_M | I2S_OUT_RST_M | I2S_AHBM_RST_M | I2S_AHBM_FIFO_RST_M;
745752 i2s->lc_conf .val |= lc_conf_reset_flags;
746753 i2s->lc_conf .val &= ~lc_conf_reset_flags;
@@ -764,7 +771,7 @@ class ClocklessController : public CPixelLEDController<RGB_ORDER>
764771
765772 static void i2sStop ()
766773 {
767- // Serial. println("I2S stop");
774+ // println("I2S stop");
768775 esp_intr_disable (gI2S_intr_handle );
769776 i2sReset ();
770777 i2s->conf .rx_start = 0 ;
0 commit comments