From 758a5cc39dfd13f9cf645798a1f55f3f3f6eb317 Mon Sep 17 00:00:00 2001 From: cnlohr Date: Fri, 30 Nov 2018 07:01:36 -0500 Subject: [PATCH] stab at the esp8266 port --- embedded8266/ccconfig.h | 4 +- embedded8266/esp82xx | 2 +- embedded8266/image.elf-0x00000.bin | Bin 33904 -> 34256 bytes embedded8266/user.cfg | 3 +- embedded8266/user/custom_commands.c | 12 +- embedded8266/user/user_main.c | 10 +- embedded8266/user/ws2812_i2s.c | 187 +++++++++++++++++++++++----- embedded8266/user/ws2812_i2s.h | 8 +- 8 files changed, 182 insertions(+), 44 deletions(-) diff --git a/embedded8266/ccconfig.h b/embedded8266/ccconfig.h index 299949e..b32d2a6 100644 --- a/embedded8266/ccconfig.h +++ b/embedded8266/ccconfig.h @@ -6,7 +6,7 @@ #define HPABUFFSIZE 512 #define CCEMBEDDED -#define NUM_LIN_LEDS 255 +#define NUM_LIN_LEDS 541 #define DFREQ 16000 #define memcpy ets_memcpy @@ -30,6 +30,7 @@ #define COLORCHORD_OUTPUT_DRIVER CCS.gCOLORCHORD_OUTPUT_DRIVER #define COLORCHORD_ACTIVE CCS.gCOLORCHORD_ACTIVE #define INITIAL_AMP CCS.gINITIAL_AMP +#define LED_DRIVER_MODE CCS.gLED_DRIVER_MODE //We are not enabling these for the ESP8266 port. #define LIN_WRAPAROUND 0 @@ -55,6 +56,7 @@ struct CCSettings uint16_t gUSE_NUM_LIN_LEDS; // = NUM_LIN_LEDS uint16_t gCOLORCHORD_ACTIVE; uint16_t gCOLORCHORD_OUTPUT_DRIVER; + uint16_t gLED_DRIVER_MODE; uint16_t gINITIAL_AMP; }; diff --git a/embedded8266/esp82xx b/embedded8266/esp82xx index b0c4a01..a08b471 160000 --- a/embedded8266/esp82xx +++ b/embedded8266/esp82xx @@ -1 +1 @@ -Subproject commit b0c4a01a4a344054f70b936d448fd0fd6c15ad20 +Subproject commit a08b47184b3fcf04172ecc0b6a1aee9c90e5d92d diff --git a/embedded8266/image.elf-0x00000.bin b/embedded8266/image.elf-0x00000.bin index cc74d6ca5de2b1e12529b7247544d3c4ca6d4ebb..fcf1e8d2a0357a807f52d27f6423a53b3358d6bd 100644 GIT binary patch delta 3612 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 WS_BLOCKSIZE ) return; - for( place = 0; place < buffersize; place++ ) + if( driver_mode ) { - uint8_t btosend = buffer[place]; - *(bufferpl++) = bitpatterns[(btosend&0x0f)]; - *(bufferpl++) = bitpatterns[(btosend>>4)&0x0f]; + uint16_t * bufferpl = (uint16_t*)&i2sBlock[0]; + int strips = (buffersize / 3) / 18; + int strip; + int led; + int side; + for( side = 0; side < 2; side++ ) + for( strip = 0; strip < strips; strip++ ) + { + int byte = (side | (strip<<1)) + 2; + *(bufferpl++) = bitpatterns[(byte&0x0f)]; + *(bufferpl++) = 0xffff; + *(bufferpl++) = 0xffff; + *(bufferpl++) = bitpatterns[(byte>>4)&0x0f]; + + + for( led = 0; led < 9; led++ ) + { + int inled; + if( side == 0 ) + { + inled = strip * 18 + led + 9; + } + else + { + inled = strip * 18 + 8 - led; + } + + + int g = buffer[inled*3+0]; + int r = buffer[inled*3+1]; + int b = buffer[inled*3+2]; + + int y = 0; //R G R B + + *(bufferpl++) = bitpatterns[(y&0x0f)]; + *(bufferpl++) = bitpatterns[(y>>4)&0x0f]; + *(bufferpl++) = bitpatterns[(g&0x0f)]; + *(bufferpl++) = bitpatterns[(g>>4)&0x0f]; + *(bufferpl++) = bitpatterns[(r&0x0f)]; + *(bufferpl++) = bitpatterns[(r>>4)&0x0f]; + *(bufferpl++) = bitpatterns[(b&0x0f)]; + *(bufferpl++) = bitpatterns[(b>>4)&0x0f]; + } + *(bufferpl++) = 0x0000; + *(bufferpl++) = 0xffff; + } + while( bufferpl != (uint16_t*)&i2sBlock[(WS_BLOCKSIZE0+WS_BLOCKSIZE1+WS_BLOCKSIZE2)/4] ) + *(bufferpl++) = 0xffff; } + else + { + uint16_t * bufferpl = (uint16_t*)&i2sBlock[0]; + + if( buffersize * 4 > WS_BLOCKSIZE0 + WS_BLOCKSIZE1 + WS_BLOCKSIZE2 ) return; + + for( place = 0; place < buffersize; place++ ) + { + uint8_t btosend = buffer[place]; + *(bufferpl++) = bitpatterns[(btosend&0x0f)]; + *(bufferpl++) = bitpatterns[(btosend>>4)&0x0f]; + } + } + #endif #if USE_2812_INTERRUPTS - uint16_t leftover = buffersize & 0x1f; if( leftover ) leftover = 32 - leftover; for( place = 0; place < leftover; place++ ) @@ -510,18 +613,42 @@ void ws2812_push( uint8_t * buffer, uint16_t buffersize ) uint16_t sizeout_words = buffersize * 2; - i2sBufDescOut.owner = 1; - i2sBufDescOut.eof = 1; - i2sBufDescOut.sub_sof = 0; - i2sBufDescOut.datalen = sizeout_words*2; //Size (in bytes) - i2sBufDescOut.blocksize = sizeout_words*2; //Size (in bytes) - i2sBufDescOut.buf_ptr = (uint32_t)&i2sBlock[0]; - i2sBufDescOut.unused = 0; - i2sBufDescOut.next_link_ptr=(uint32_t)&i2sBufDescZeroes; //At the end, just redirect the DMA to the zero buffer. + int firstsize = sizeout_words, secondsize = 0; + if( sizeout_words > WS_BLOCKSIZE0 ) + { + secondsize = firstsize - (WS_BLOCKSIZE0/4); + firstsize = WS_BLOCKSIZE0/4; + } + i2sBufDescOut0.owner = 1; + i2sBufDescOut0.eof = 1; + i2sBufDescOut0.sub_sof = 0; + i2sBufDescOut0.datalen = sizeout_words*2; //Size (in bytes) + i2sBufDescOut0.blocksize = sizeout_words*2; //Size (in bytes) + i2sBufDescOut0.buf_ptr = (uint32_t)&i2sBlock[0]; + i2sBufDescOut0.unused = 0; + i2sBufDescOut0.next_link_ptr=(uint32_t)&i2sBufDescOut1; //At the end, just redirect the DMA to the zero buffer. + + i2sBufDescOut1.owner = 1; + i2sBufDescOut1.eof = 1; + i2sBufDescOut1.sub_sof = 0; + i2sBufDescOut1.datalen = sizeout_words*2; //Size (in bytes) + i2sBufDescOut1.blocksize = sizeout_words*2; //Size (in bytes) + i2sBufDescOut1.buf_ptr = (uint32_t)&i2sBlock[WS_BLOCKSIZE0/4]; + i2sBufDescOut1.unused = 0; + i2sBufDescOut1.next_link_ptr=(uint32_t)&i2sBufDescOut2; //At the end, just redirect the DMA to the zero buffer. + + i2sBufDescOut2.owner = 1; + i2sBufDescOut2.eof = 1; + i2sBufDescOut2.sub_sof = 0; + i2sBufDescOut2.datalen = sizeout_words*2; //Size (in bytes) + i2sBufDescOut2.blocksize = sizeout_words*2; //Size (in bytes) + i2sBufDescOut2.buf_ptr = (uint32_t)&i2sBlock[(WS_BLOCKSIZE0+WS_BLOCKSIZE1)/4]; + i2sBufDescOut2.unused = 0; + i2sBufDescOut2.next_link_ptr=(uint32_t)&i2sBufDescZeroes; //At the end, just redirect the DMA to the zero buffer. SET_PERI_REG_MASK(SLC_RX_LINK, SLC_RXLINK_STOP); CLEAR_PERI_REG_MASK(SLC_RX_LINK,SLC_RXLINK_DESCADDR_MASK); - SET_PERI_REG_MASK(SLC_RX_LINK, ((uint32)&i2sBufDescOut) & SLC_RXLINK_DESCADDR_MASK); + SET_PERI_REG_MASK(SLC_RX_LINK, ((uint32)&i2sBufDescOut0) & SLC_RXLINK_DESCADDR_MASK); SET_PERI_REG_MASK(SLC_RX_LINK, SLC_RXLINK_START); #endif diff --git a/embedded8266/user/ws2812_i2s.h b/embedded8266/user/ws2812_i2s.h index c0276e6..0115a6e 100644 --- a/embedded8266/user/ws2812_i2s.h +++ b/embedded8266/user/ws2812_i2s.h @@ -15,7 +15,9 @@ //NOTE: Blocksize MUST be divisible by 4. Cannot exceed 4092 //Each LED takes up 12 block bytes in WS2812_FOUR_SAMPLE //Or 9 block bytes in WS2812_THREE_SAMPLE -#define WS_BLOCKSIZE 4000 +#define WS_BLOCKSIZE0 4000 +#define WS_BLOCKSIZE1 4000 +#define WS_BLOCKSIZE2 4000 //You can either have 3 or 4 samples per bit for WS2812s. //3 sample can't go quite as fast as 4. @@ -28,7 +30,9 @@ //#define WS2812_FOUR_SAMPLE void ICACHE_FLASH_ATTR ws2812_init(); -void ws2812_push( uint8_t * buffer, uint16_t buffersize ); //Buffersize = Nr LEDs * 3 +void ws2812_push( uint8_t * buffer, uint16_t buffersize, int led_mode ); //Buffersize = Nr LEDs * 3 +//led_mode = 0 for WS2812B +//led_mode = 1 for luxehedron #endif