diff --git a/embedded8266/0x00000.bin b/embedded8266/0x00000.bin index af948ab..78cc1cd 100644 Binary files a/embedded8266/0x00000.bin and b/embedded8266/0x00000.bin differ diff --git a/embedded8266/0x40000.bin b/embedded8266/0x40000.bin index 6564073..27ace10 100644 Binary files a/embedded8266/0x40000.bin and b/embedded8266/0x40000.bin differ diff --git a/embedded8266/LICENSE b/embedded8266/LICENSE index bf1f4f8..5e01f6c 100644 --- a/embedded8266/LICENSE +++ b/embedded8266/LICENSE @@ -1,14 +1,17 @@ -Portions of this code are under various Espressif licenses. +*Note if you use the ESP8266 port, you are bound to this license as well as +the regular ColorChord license.* (Yes, I'm aware one is a BSD-based license +and the other is a MIT-based license and will consider resolving this if +people want) -Please take not of the individual files. All files that are -written without license, by me are under the MIT license as reads below. -The MIT License (MIT) +ESPRSSIF MIT License -Copyright (c) 2014 Charles Lohr +Copyright (c) 2015 +Portions Copyright (c) 2015 Charles Lohr -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal +Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, +in which case, it is free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is diff --git a/embedded8266/Makefile b/embedded8266/Makefile index 960856d..f551217 100644 --- a/embedded8266/Makefile +++ b/embedded8266/Makefile @@ -3,35 +3,35 @@ FW_FILE_1:=0x00000.bin FW_FILE_2:=0x40000.bin TARGET_OUT:=image.elf -OBJS:=driver/uart.o \ - user/mystuff.o \ - user/ws2812.o \ - user/colorchord.o \ - user/user_main.o + SRCS:=driver/uart.c \ user/mystuff.c \ - user/ws2812.c \ - user/colorchord.c \ + user/ws2812_i2s.c \ + user/hpatimer.c \ + driver/adc.c \ + ../embeddedcommon/DFT32.c \ + ../embeddedcommon/embeddednf.c \ + ../embeddedcommon/embeddedout.c \ user/user_main.c -GCC_FOLDER:=~/esp8266/xtensa-toolchain-build/build-lx106 +GCC_FOLDER:=~/esp8266/esp-open-sdk/xtensa-lx106-elf ESPTOOL_PY:=~/esp8266/esptool/esptool.py FW_TOOL:=~/esp8266/other/esptool/esptool -SDK:=/home/cnlohr/esp8266/esp_iot_sdk_v0.9.3 +SDK:=/home/cnlohr/esp8266/esp_iot_sdk_v1.2.0 PORT:=/dev/ttyUSB0 #PORT:=/dev/ttyACM0 XTLIB:=$(SDK)/lib -XTGCCLIB:=$(GCC_FOLDER)/gcc-4.9.1-elf/xtensa-lx106-elf/libgcc/libgcc.a -FOLDERPREFIX:=$(GCC_FOLDER)/root/bin +XTGCCLIB:=$(GCC_FOLDER)/lib/gcc/xtensa-lx106-elf/4.8.2/libgcc.a +FOLDERPREFIX:=$(GCC_FOLDER)/bin PREFIX:=$(FOLDERPREFIX)/xtensa-lx106-elf- CC:=$(PREFIX)gcc -CFLAGS:=-mlongcalls -I$(SDK)/include -Imyclib -Iinclude -Iuser -Os -I$(SDK)/include/ +CFLAGS:=-mlongcalls -I$(SDK)/include -Imyclib -Iinclude -Iuser -Os -I$(SDK)/include/ -I../embeddedcommon -Dmemcpy=ets_memcpy -Dmemset=ets_memset \ + -DDFREQ=16000 -DCCEMBEDDED -DNUM_LIN_LEDS=24 +#-DFREQ==12500 seems to work well. -# \ -# LDFLAGS_CORE:=\ -nostdlib \ diff --git a/embedded8266/README.md b/embedded8266/README.md index 555f93b..e245930 100644 --- a/embedded8266/README.md +++ b/embedded8266/README.md @@ -1,5 +1,18 @@ -#ESP8266 ColorChord Driver +#ESP8266 ColorChord -Please see the main ws2812esp8266 project for help with setting up your environment and programming, etc. +(based off of ESP8266 I2S WS2812 Driver) +This project is based off of the I2S interface for the mp3 player found here: +https://github.com/espressif/esp8266_mp3_decoder/ + +If you want more information about the build environment, etc. You should +check out the regular WS2812 driver, found here: https://github.com/cnlohr/ws2812esp8266 + +WARNING: This subproject is very jankey! It's about stable, but I don't think it's quite there yet. + +## Hardware Connection + +Unfortunately the I2S Out (WS2812 in) pin is the same as RX1 (pin 25), which means if you are programming via the UART, it'll need to be unplugged any time you're testing. The positive side of this is that it is a pin that is exposed on most ESP8266 breakout boards. + +The audio data is taken from TOUT, but must be kept between 0 and 1V. diff --git a/embedded8266/driver/adc.c b/embedded8266/driver/adc.c new file mode 100644 index 0000000..5a93c77 --- /dev/null +++ b/embedded8266/driver/adc.c @@ -0,0 +1,79 @@ +//I did not write this file, but I don't know where it came from. + +#include "ets_sys.h" +#include "osapi.h" + +#include "driver/adc.h" + +#define i2c_bbpll 0x67 +#define i2c_bbpll_en_audio_clock_out 4 +#define i2c_bbpll_en_audio_clock_out_msb 7 +#define i2c_bbpll_en_audio_clock_out_lsb 7 +#define i2c_bbpll_hostid 4 +#define i2c_saradc 0x6C +#define i2c_saradc_hostid 2 + +#define i2c_saradc_en_test 0 +#define i2c_saradc_en_test_msb 5 +#define i2c_saradc_en_test_lsb 5 + +#define i2c_writeReg_Mask(block, host_id, reg_add, Msb, Lsb, indata) \ + rom_i2c_writeReg_Mask(block, host_id, reg_add, Msb, Lsb, indata) + +#define i2c_readReg_Mask(block, host_id, reg_add, Msb, Lsb) \ + rom_i2c_readReg_Mask_(block, host_id, reg_add, Msb, Lsb) + +#define i2c_writeReg_Mask_def(block, reg_add, indata) \ + i2c_writeReg_Mask(block, block##_hostid, reg_add, reg_add##_msb, reg_add##_lsb, indata) + +#define i2c_readReg_Mask_def(block, reg_add) \ + i2c_readReg_Mask(block, block##_hostid, reg_add, reg_add##_msb, reg_add##_lsb) + + +void ICACHE_FLASH_ATTR hs_adc_start(void) +{ + i2c_writeReg_Mask_def(i2c_saradc, i2c_saradc_en_test, 1); //select test mux + + //PWDET_CAL_EN=0, PKDET_CAL_EN=0 + SET_PERI_REG_MASK(0x60000D5C, 0x200000); + + while (GET_PERI_REG_BITS(0x60000D50, 26, 24) > 0); //wait r_state == 0 + + CLEAR_PERI_REG_MASK(0x60000D50, 0x02); //force_en=0 + SET_PERI_REG_MASK(0x60000D50, 0x02); //force_en=1 +} + +uint16 hs_adc_read(void) +{ + uint8 i; + uint16 sardata[8]; + uint16_t sar_dout = 0; + + while (GET_PERI_REG_BITS(0x60000D50, 26, 24) > 0); //wait r_state == 0 + + read_sar_dout(sardata); + + for (i = 0; i < 8; i++) { + sar_dout += sardata[i]; + } + +#ifdef OLDWAY_NEEDS_RESTART + //tout = (sar_dout + 8) >> 4; //tout is 10 bits fraction +// ??? Why does this exist ??? It didn't start commented out, but now that I did comment it, it still seems happy. +// i2c_writeReg_Mask_def(i2c_saradc, i2c_saradc_en_test, 1); //select test mux +// while (GET_PERI_REG_BITS(0x60000D50, 26, 24) > 0); //wait r_state == 0 + +// CLEAR_PERI_REG_MASK(0x60000D5C, 0x200000); + // SET_PERI_REG_MASK(0x60000D60, 0x1); //force_en=1 + // CLEAR_PERI_REG_MASK(0x60000D60, 0x1); //force_en=1 +#else + + //Start reading a new sample. + CLEAR_PERI_REG_MASK(0x60000D50, 0x02); //force_en=0 + SET_PERI_REG_MASK(0x60000D50, 0x02); //force_en=1 +#endif + + return sar_dout; //tout is 10 bits fraction +} + + diff --git a/embedded8266/driver/uart.c b/embedded8266/driver/uart.c index 049dd88..e6c043a 100644 --- a/embedded8266/driver/uart.c +++ b/embedded8266/driver/uart.c @@ -169,52 +169,30 @@ uart0_sendStr(const char *str) * Parameters : void *para - point to ETS_UART_INTR_ATTACH's arg * Returns : NONE *******************************************************************************/ -extern void at_recvTask(void); + +extern void charrx( uint8_t c ); LOCAL void uart0_rx_intr_handler(void *para) { - /* uart0 and uart1 intr combine togther, when interrupt occur, see reg 0x3ff20020, bit2, bit0 represents - * uart1 and uart0 respectively - */ -// RcvMsgBuff *pRxBuff = (RcvMsgBuff *)para; -// uint8 RcvChar; - uint8 uart_no = UART0;//UartDev.buff_uart_no; + static uint8_t history[4]; + static uint8_t hhead; -// if (UART_RXFIFO_FULL_INT_ST != (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST)) -// { -// return; -// } - if (UART_RXFIFO_FULL_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST)) - { - at_recvTask(); + uint8 uart_no = UART0;//UartDev.buff_uart_no; + volatile uint8_t v = READ_PERI_REG(UART_FIFO(uart_no)) & 0xFF; WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_FULL_INT_CLR); - } -// WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_FULL_INT_CLR); + history[hhead++] = v; + if( hhead > 3 ) hhead = 0; -// if (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) -// { -// RcvChar = READ_PERI_REG(UART_FIFO(uart_no)) & 0xFF; -// at_recvTask(); -// *(pRxBuff->pWritePos) = RcvChar; + //Detect a request to reboot into bootloader. + if( history[hhead&3] == 0xc2 && history[(hhead+1)&3] == 0x42 && history[(hhead+2)&3] == 0x56 && history[(hhead+3)&3] == 0xff ) + { + system_restart(); + } -// system_os_post(at_recvTaskPrio, NULL, RcvChar); + charrx( v ); -// //insert here for get one command line from uart -// if (RcvChar == '\r') -// { -// pRxBuff->BuffState = WRITE_OVER; -// } -// -// pRxBuff->pWritePos++; -// -// if (pRxBuff->pWritePos == (pRxBuff->pRcvMsgBuff + RX_BUFF_SIZE)) -// { -// // overflow ...we may need more error handle here. -// pRxBuff->pWritePos = pRxBuff->pRcvMsgBuff ; -// } -// } } /****************************************************************************** @@ -242,6 +220,4 @@ void ICACHE_FLASH_ATTR uart_reattach() { uart_init(BIT_RATE_74880, BIT_RATE_74880); -// ETS_UART_INTR_ATTACH(uart_rx_intr_handler_ssc, &(UartDev.rcv_buff)); -// ETS_UART_INTR_ENABLE(); } diff --git a/embedded8266/image.elf b/embedded8266/image.elf old mode 100644 new mode 100755 index d7a260c..66c23c4 Binary files a/embedded8266/image.elf and b/embedded8266/image.elf differ diff --git a/embedded8266/include/driver/adc.h b/embedded8266/include/driver/adc.h new file mode 100644 index 0000000..9999162 --- /dev/null +++ b/embedded8266/include/driver/adc.h @@ -0,0 +1,6 @@ +#ifndef __ADC_H__ +#define __ADC_H__ +void hs_adc_start(void); +uint16 hs_adc_read(void); +#endif + diff --git a/embedded8266/include/pin_mux_register.h b/embedded8266/include/pin_mux_register.h new file mode 100644 index 0000000..fc0f403 --- /dev/null +++ b/embedded8266/include/pin_mux_register.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) Espressif System 2010 - 2012 + * + */ + +#ifndef _PIN_MUX_H_ +#define _PIN_MUX_H_ + +#define PERIPHS_IO_MUX 0x60000800 + +#define PERIPHS_IO_MUX_FUNC 0x13 +#define PERIPHS_IO_MUX_FUNC_S 4 +#define PERIPHS_IO_MUX_PULLUP BIT7 +#define PERIPHS_IO_MUX_PULLDWN BIT6 +#define PERIPHS_IO_MUX_SLEEP_PULLUP BIT3 +#define PERIPHS_IO_MUX_SLEEP_PULLDWN BIT2 +#define PERIPHS_IO_MUX_SLEEP_OE BIT1 +#define PERIPHS_IO_MUX_OE BIT0 + +#define PERIPHS_IO_MUX_CONF_U (PERIPHS_IO_MUX + 0x00) +#define SPI0_CLK_EQU_SYS_CLK BIT8 +#define SPI1_CLK_EQU_SYS_CLK BIT9 + +#define PERIPHS_IO_MUX_MTDI_U (PERIPHS_IO_MUX + 0x04) +#define FUNC_MTDI 0 +#define FUNC_I2SI_DATA 1 +#define FUNC_HSPIQ_MISO 2 +#define FUNC_GPIO12 3 +#define FUNC_UART0_DTR 4 + +#define PERIPHS_IO_MUX_MTCK_U (PERIPHS_IO_MUX + 0x08) +#define FUNC_MTCK 0 +#define FUNC_I2SI_BCK 1 +#define FUNC_HSPID_MOSI 2 +#define FUNC_GPIO13 3 +#define FUNC_UART0_CTS 4 + +#define PERIPHS_IO_MUX_MTMS_U (PERIPHS_IO_MUX + 0x0C) +#define FUNC_MTMS 0 +#define FUNC_I2SI_WS 1 +#define FUNC_HSPI_CLK 2 +#define FUNC_GPIO14 3 +#define FUNC_UART0_DSR 4 + +#define PERIPHS_IO_MUX_MTDO_U (PERIPHS_IO_MUX + 0x10) +#define FUNC_MTDO 0 +#define FUNC_I2SO_BCK 1 +#define FUNC_HSPI_CS0 2 +#define FUNC_GPIO15 3 +#define FUNC_U0RTS 4 +#define FUNC_UART0_RTS 4 + +#define PERIPHS_IO_MUX_U0RXD_U (PERIPHS_IO_MUX + 0x14) +#define FUNC_U0RXD 0 +#define FUNC_I2SO_DATA 1 +#define FUNC_GPIO3 3 +#define FUNC_CLK_XTAL_BK 4 + +#define PERIPHS_IO_MUX_U0TXD_U (PERIPHS_IO_MUX + 0x18) +#define FUNC_U0TXD 0 +#define FUNC_SPICS1 1 +#define FUNC_GPIO1 3 +#define FUNC_CLK_RTC_BK 4 + +#define PERIPHS_IO_MUX_SD_CLK_U (PERIPHS_IO_MUX + 0x1c) +#define FUNC_SDCLK 0 +#define FUNC_SPICLK 1 +#define FUNC_GPIO6 3 +#define UART1_CTS 4 + +#define PERIPHS_IO_MUX_SD_DATA0_U (PERIPHS_IO_MUX + 0x20) +#define FUNC_SDDATA0 0 +#define FUNC_SPIQ_MISO 1 +#define FUNC_GPIO7 3 +#define FUNC_U1TXD 4 +#define FUNC_UART1_TXD 4 + +#define PERIPHS_IO_MUX_SD_DATA1_U (PERIPHS_IO_MUX + 0x24) +#define FUNC_SDDATA1 0 +#define FUNC_SPID_MOSI 1 +#define FUNC_GPIO8 3 +#define FUNC_U1RXD 4 +#define FUNC_UART1_RXD 4 + +#define PERIPHS_IO_MUX_SD_DATA2_U (PERIPHS_IO_MUX + 0x28) +#define FUNC_SDDATA2 0 +#define FUNC_SPIHD 1 +#define FUNC_GPIO9 3 +#define UFNC_HSPIHD 4 + +#define PERIPHS_IO_MUX_SD_DATA3_U (PERIPHS_IO_MUX + 0x2c) +#define FUNC_SDDATA3 0 +#define FUNC_SPIWP 1 +#define FUNC_GPIO10 3 +#define FUNC_HSPIWP 4 + +#define PERIPHS_IO_MUX_SD_CMD_U (PERIPHS_IO_MUX + 0x30) +#define FUNC_SDCMD 0 +#define FUNC_SPICS0 1 +#define FUNC_GPIO11 3 +#define U1RTS 4 +#define UART1_RTS 4 + +#define PERIPHS_IO_MUX_GPIO0_U (PERIPHS_IO_MUX + 0x34) +#define FUNC_GPIO0 0 +#define FUNC_SPICS2 1 +#define FUNC_CLK_OUT 4 + +#define PERIPHS_IO_MUX_GPIO2_U (PERIPHS_IO_MUX + 0x38) +#define FUNC_GPIO2 0 +#define FUNC_I2SO_WS 1 +#define FUNC_U1TXD_BK 2 +#define FUNC_UART1_TXD_BK 2 +#define FUNC_U0TXD_BK 4 +#define FUNC_UART0_TXD_BK 4 + +#define PERIPHS_IO_MUX_GPIO4_U (PERIPHS_IO_MUX + 0x3C) +#define FUNC_GPIO4 0 +#define FUNC_CLK_XTAL 1 + +#define PERIPHS_IO_MUX_GPIO5_U (PERIPHS_IO_MUX + 0x40) +#define FUNC_GPIO5 0 +#define FUNC_CLK_RTC 1 + +#define PIN_PULLUP_DIS(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME, PERIPHS_IO_MUX_PULLUP) +#define PIN_PULLUP_EN(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME, PERIPHS_IO_MUX_PULLUP) + +//XXX THIS LOOKS WRONG. + +#undef PIN_FUNC_SELECT + +#define PIN_FUNC_SELECT(PIN_NAME, FUNC) do { \ + CLEAR_PERI_REG_MASK(PIN_NAME, (PERIPHS_IO_MUX_FUNC< +#include "osapi.h" +#include "mem.h" +#include "eagle_soc.h" +#include "user_interface.h" +#include "ets_sys.h" + +//BUFFSIZE must be a power-of-two +volatile uint8_t sounddata[HPABUFFSIZE]; +volatile uint16_t soundhead; + + +#define FRC1_ENABLE_TIMER BIT7 + +typedef enum { + DIVDED_BY_1 = 0, + DIVDED_BY_16 = 4, + DIVDED_BY_256 = 8, +} TIMER_PREDIVED_MODE; + +typedef enum { + TM_LEVEL_INT = 1, + TM_EDGE_INT = 0, +} TIMER_INT_MODE; + +#define FRC1_AUTO_RELOAD 64 + +static void timerhandle( void * v ) +{ + RTC_CLR_REG_MASK(FRC1_INT_ADDRESS, FRC1_INT_CLR_MASK); + uint16_t r = hs_adc_read(); + sounddata[soundhead] = r>>6; + soundhead = (soundhead+1)&(HPABUFFSIZE-1); +} + +void ICACHE_FLASH_ATTR StartHPATimer() +{ + + RTC_REG_WRITE(FRC1_CTRL_ADDRESS, FRC1_AUTO_RELOAD| + DIVDED_BY_16 | //5MHz main clock. + FRC1_ENABLE_TIMER | + TM_EDGE_INT ); + + RTC_REG_WRITE(FRC1_LOAD_ADDRESS, 5000000/DFREQ); + RTC_REG_WRITE(FRC1_COUNT_ADDRESS, 5000000/DFREQ); + + //pwm_set_freq_duty(freq, duty); + //pwm_start(); +// RTC_REG_WRITE(FRC1_LOAD_ADDRESS, local_single[0].h_time); + ETS_FRC_TIMER1_INTR_ATTACH(timerhandle, NULL); + TM1_EDGE_INT_ENABLE(); + ETS_FRC1_INTR_ENABLE(); + system_timer_reinit(); + hs_adc_start(); +} + diff --git a/embedded8266/user/hpatimer.h b/embedded8266/user/hpatimer.h new file mode 100644 index 0000000..46503d9 --- /dev/null +++ b/embedded8266/user/hpatimer.h @@ -0,0 +1,16 @@ +#ifndef _HPATIMER_H +#define _HPATIMER_H + +#include +//Using a system timer on the ESP to poll the ADC in at a regular interval... + +//BUFFSIZE must be a power-of-two +#define HPABUFFSIZE 512 +extern volatile uint8_t sounddata[HPABUFFSIZE]; +extern volatile uint16_t soundhead; + +void StartHPATimer(); + + +#endif + diff --git a/embedded8266/user/mystuff.c b/embedded8266/user/mystuff.c index 78700b6..a4c024c 100644 --- a/embedded8266/user/mystuff.c +++ b/embedded8266/user/mystuff.c @@ -1,3 +1,18 @@ #include "mystuff.h" char generic_print_buffer[384]; + + +void user_rf_pre_init(void) +{ + //nothing. +} + + +char * strcat( char * dest, char * src ) +{ + return strcat(dest, src ); +} + + + diff --git a/embedded8266/user/mystuff.h b/embedded8266/user/mystuff.h index 95756a8..76a3a6b 100644 --- a/embedded8266/user/mystuff.h +++ b/embedded8266/user/mystuff.h @@ -3,6 +3,6 @@ extern char generic_print_buffer[384]; -#define printf( ... ) os_sprintf( generic_print_buffer, __VA_ARGS__ ); uart0_sendStr( generic_print_buffer ); +#define printf( ... ) ets_sprintf( generic_print_buffer, __VA_ARGS__ ); uart0_sendStr( generic_print_buffer ); #endif diff --git a/embedded8266/user/slc_register.h b/embedded8266/user/slc_register.h new file mode 100644 index 0000000..ab578fa --- /dev/null +++ b/embedded8266/user/slc_register.h @@ -0,0 +1,281 @@ +//Generated at 2012-10-23 19:55:03 +/* + * Copyright (c) 2010 - 2011 Espressif System + * + */ + +#ifndef SLC_REGISTER_H_ +#define SLC_REGISTER_H_ + +#define REG_SLC_BASE 0x60000B00 +//version value:32'h091700 + +#define SLC_CONF0 (REG_SLC_BASE + 0x0) +#ifndef ESP_MAC_5 +#define SLC_MODE 0x00000003 +#define SLC_MODE_S 12 +#endif +#define SLC_DATA_BURST_EN (BIT(9)) +#define SLC_DSCR_BURST_EN (BIT(8)) +#define SLC_RX_NO_RESTART_CLR (BIT(7)) +#define SLC_RX_AUTO_WRBACK (BIT(6)) +#define SLC_RX_LOOP_TEST (BIT(5)) +#define SLC_TX_LOOP_TEST (BIT(4)) +#define SLC_AHBM_RST (BIT(3)) +#define SLC_AHBM_FIFO_RST (BIT(2)) +#define SLC_RXLINK_RST (BIT(1)) +#define SLC_TXLINK_RST (BIT(0)) + +#define SLC_INT_RAW (REG_SLC_BASE + 0x4) +#define SLC_TX_DSCR_EMPTY_INT_RAW (BIT(21)) +#define SLC_RX_DSCR_ERR_INT_RAW (BIT(20)) +#define SLC_TX_DSCR_ERR_INT_RAW (BIT(19)) +#define SLC_TOHOST_INT_RAW (BIT(18)) +#define SLC_RX_EOF_INT_RAW (BIT(17)) +#define SLC_RX_DONE_INT_RAW (BIT(16)) +#define SLC_TX_EOF_INT_RAW (BIT(15)) +#define SLC_TX_DONE_INT_RAW (BIT(14)) +#define SLC_TOKEN1_1TO0_INT_RAW (BIT(13)) +#define SLC_TOKEN0_1TO0_INT_RAW (BIT(12)) +#define SLC_TX_OVF_INT_RAW (BIT(11)) +#define SLC_RX_UDF_INT_RAW (BIT(10)) +#define SLC_TX_START_INT_RAW (BIT(9)) +#define SLC_RX_START_INT_RAW (BIT(8)) +#define SLC_FRHOST_BIT7_INT_RAW (BIT(7)) +#define SLC_FRHOST_BIT6_INT_RAW (BIT(6)) +#define SLC_FRHOST_BIT5_INT_RAW (BIT(5)) +#define SLC_FRHOST_BIT4_INT_RAW (BIT(4)) +#define SLC_FRHOST_BIT3_INT_RAW (BIT(3)) +#define SLC_FRHOST_BIT2_INT_RAW (BIT(2)) +#define SLC_FRHOST_BIT1_INT_RAW (BIT(1)) +#define SLC_FRHOST_BIT0_INT_RAW (BIT(0)) + +#define SLC_INT_STATUS (REG_SLC_BASE + 0x8) +#define SLC_TX_DSCR_EMPTY_INT_ST (BIT(21)) +#define SLC_RX_DSCR_ERR_INT_ST (BIT(20)) +#define SLC_TX_DSCR_ERR_INT_ST (BIT(19)) +#define SLC_TOHOST_INT_ST (BIT(18)) +#define SLC_RX_EOF_INT_ST (BIT(17)) +#define SLC_RX_DONE_INT_ST (BIT(16)) +#define SLC_TX_EOF_INT_ST (BIT(15)) +#define SLC_TX_DONE_INT_ST (BIT(14)) +#define SLC_TOKEN1_1TO0_INT_ST (BIT(13)) +#define SLC_TOKEN0_1TO0_INT_ST (BIT(12)) +#define SLC_TX_OVF_INT_ST (BIT(11)) +#define SLC_RX_UDF_INT_ST (BIT(10)) +#define SLC_TX_START_INT_ST (BIT(9)) +#define SLC_RX_START_INT_ST (BIT(8)) +#define SLC_FRHOST_BIT7_INT_ST (BIT(7)) +#define SLC_FRHOST_BIT6_INT_ST (BIT(6)) +#define SLC_FRHOST_BIT5_INT_ST (BIT(5)) +#define SLC_FRHOST_BIT4_INT_ST (BIT(4)) +#define SLC_FRHOST_BIT3_INT_ST (BIT(3)) +#define SLC_FRHOST_BIT2_INT_ST (BIT(2)) +#define SLC_FRHOST_BIT1_INT_ST (BIT(1)) +#define SLC_FRHOST_BIT0_INT_ST (BIT(0)) + +#define SLC_INT_ENA (REG_SLC_BASE + 0xC) +#define SLC_TX_DSCR_EMPTY_INT_ENA (BIT(21)) +#define SLC_RX_DSCR_ERR_INT_ENA (BIT(20)) +#define SLC_TX_DSCR_ERR_INT_ENA (BIT(19)) +#define SLC_TOHOST_INT_ENA (BIT(18)) +#define SLC_RX_EOF_INT_ENA (BIT(17)) +#define SLC_RX_DONE_INT_ENA (BIT(16)) +#define SLC_TX_EOF_INT_ENA (BIT(15)) +#define SLC_TX_DONE_INT_ENA (BIT(14)) +#define SLC_TOKEN1_1TO0_INT_ENA (BIT(13)) +#define SLC_TOKEN0_1TO0_INT_ENA (BIT(12)) +#define SLC_TX_OVF_INT_ENA (BIT(11)) +#define SLC_RX_UDF_INT_ENA (BIT(10)) +#define SLC_TX_START_INT_ENA (BIT(9)) +#define SLC_RX_START_INT_ENA (BIT(8)) +#define SLC_FRHOST_BIT7_INT_ENA (BIT(7)) +#define SLC_FRHOST_BIT6_INT_ENA (BIT(6)) +#define SLC_FRHOST_BIT5_INT_ENA (BIT(5)) +#define SLC_FRHOST_BIT4_INT_ENA (BIT(4)) +#define SLC_FRHOST_BIT3_INT_ENA (BIT(3)) +#define SLC_FRHOST_BIT2_INT_ENA (BIT(2)) +#define SLC_FRHOST_BIT1_INT_ENA (BIT(1)) +#define SLC_FRHOST_BIT0_INT_ENA (BIT(0)) + +#define SLC_FRHOST_BIT_INT_ENA_ALL 0xff + +#define SLC_INT_CLR (REG_SLC_BASE + 0x10) +#define SLC_TX_DSCR_EMPTY_INT_CLR (BIT(21)) +#define SLC_RX_DSCR_ERR_INT_CLR (BIT(20)) +#define SLC_TX_DSCR_ERR_INT_CLR (BIT(19)) +#define SLC_TOHOST_INT_CLR (BIT(18)) +#define SLC_RX_EOF_INT_CLR (BIT(17)) +#define SLC_RX_DONE_INT_CLR (BIT(16)) +#define SLC_TX_EOF_INT_CLR (BIT(15)) +#define SLC_TX_DONE_INT_CLR (BIT(14)) +#define SLC_TOKEN1_1TO0_INT_CLR (BIT(13)) +#define SLC_TOKEN0_1TO0_INT_CLR (BIT(12)) +#define SLC_TX_OVF_INT_CLR (BIT(11)) +#define SLC_RX_UDF_INT_CLR (BIT(10)) +#define SLC_TX_START_INT_CLR (BIT(9)) +#define SLC_RX_START_INT_CLR (BIT(8)) +#define SLC_FRHOST_BIT7_INT_CLR (BIT(7)) +#define SLC_FRHOST_BIT6_INT_CLR (BIT(6)) +#define SLC_FRHOST_BIT5_INT_CLR (BIT(5)) +#define SLC_FRHOST_BIT4_INT_CLR (BIT(4)) +#define SLC_FRHOST_BIT3_INT_CLR (BIT(3)) +#define SLC_FRHOST_BIT2_INT_CLR (BIT(2)) +#define SLC_FRHOST_BIT1_INT_CLR (BIT(1)) +#define SLC_FRHOST_BIT0_INT_CLR (BIT(0)) + +#define SLC_RX_STATUS (REG_SLC_BASE + 0x14) +#define SLC_RX_EMPTY (BIT(1)) +#define SLC_RX_FULL (BIT(0)) + +#define SLC_RX_FIFO_PUSH (REG_SLC_BASE + 0x18) +#define SLC_RXFIFO_PUSH (BIT(16)) +#define SLC_RXFIFO_WDATA 0x000001FF +#define SLC_RXFIFO_WDATA_S 0 + +#define SLC_TX_STATUS (REG_SLC_BASE + 0x1C) +#define SLC_TX_EMPTY (BIT(1)) +#define SLC_TX_FULL (BIT(0)) + +#define SLC_TX_FIFO_POP (REG_SLC_BASE + 0x20) +#define SLC_TXFIFO_POP (BIT(16)) +#define SLC_TXFIFO_RDATA 0x000007FF +#define SLC_TXFIFO_RDATA_S 0 + +#define SLC_RX_LINK (REG_SLC_BASE + 0x24) +#define SLC_RXLINK_PARK (BIT(31)) +#define SLC_RXLINK_RESTART (BIT(30)) +#define SLC_RXLINK_START (BIT(29)) +#define SLC_RXLINK_STOP (BIT(28)) +#define SLC_RXLINK_DESCADDR_MASK 0x000FFFFF +#define SLC_RXLINK_ADDR_S 0 + +#define SLC_TX_LINK (REG_SLC_BASE + 0x28) +#define SLC_TXLINK_PARK (BIT(31)) +#define SLC_TXLINK_RESTART (BIT(30)) +#define SLC_TXLINK_START (BIT(29)) +#define SLC_TXLINK_STOP (BIT(28)) +#define SLC_TXLINK_DESCADDR_MASK 0x000FFFFF +#define SLC_TXLINK_ADDR_S 0 + +#define SLC_INTVEC_TOHOST (REG_SLC_BASE + 0x2C) +#define SLC_TOHOST_INTVEC 0x000000FF +#define SLC_TOHOST_INTVEC_S 0 + +#define SLC_TOKEN0 (REG_SLC_BASE + 0x30) +#define SLC_TOKEN0_MASK 0x00000FFF +#define SLC_TOKEN0_S 16 +#define SLC_TOKEN0_LOCAL_INC_MORE (BIT(14)) +#define SLC_TOKEN0_LOCAL_INC (BIT(13)) +#define SLC_TOKEN0_LOCAL_WR (BIT(12)) +#define SLC_TOKEN0_LOCAL_WDATA_MASK 0x00000FFF +#define SLC_TOKEN0_LOCAL_WDATA_S 0 + +#define SLC_TOKEN1 (REG_SLC_BASE + 0x34) +#define SLC_TOKEN1_MASK 0x00000FFF +#define SLC_TOKEN1_S 16 +#define SLC_TOKEN1_LOCAL_INC_MORE (BIT(14)) +#define SLC_TOKEN1_LOCAL_INC (BIT(13)) +#define SLC_TOKEN1_LOCAL_WR (BIT(12)) +#define SLC_TOKEN1_LOCAL_WDATA 0x00000FFF +#define SLC_TOKEN1_LOCAL_WDATA_S 0 + +#define SLC_CONF1 (REG_SLC_BASE + 0x38) +#define SLC_STATE0 (REG_SLC_BASE + 0x3C) +#define SLC_STATE1 (REG_SLC_BASE + 0x40) + +#define SLC_BRIDGE_CONF (REG_SLC_BASE + 0x44) +#ifndef ESP_MAC_5 +#define SLC_TX_PUSH_IDLE_NUM 0x0000FFFF +#define SLC_TX_PUSH_IDLE_NUM_S 16 +#define SLC_TX_DUMMY_MODE (BIT(12)) +#endif +#define SLC_FIFO_MAP_ENA 0x0000000F +#define SLC_FIFO_MAP_ENA_S 8 +#define SLC_TXEOF_ENA 0x0000003F +#define SLC_TXEOF_ENA_S 0 + +#define SLC_RX_EOF_DES_ADDR (REG_SLC_BASE + 0x48) +#define SLC_TX_EOF_DES_ADDR (REG_SLC_BASE + 0x4C) +#define SLC_FROM_HOST_LAST_DESC SLC_TX_EOF_DES_ADDR +#define SLC_TO_HOST_LAST_DESC SLC_RX_EOF_DES_ADDR + +#define SLC_RX_EOF_BFR_DES_ADDR (REG_SLC_BASE + 0x50) +#define SLC_AHB_TEST (REG_SLC_BASE + 0x54) +#define SLC_AHB_TESTADDR 0x00000003 +#define SLC_AHB_TESTADDR_S 4 +#define SLC_AHB_TESTMODE 0x00000007 +#define SLC_AHB_TESTMODE_S 0 + +#define SLC_SDIO_ST (REG_SLC_BASE + 0x58) +#define SLC_BUS_ST 0x00000007 +#define SLC_BUS_ST_S 12 +#define SLC_SDIO_WAKEUP (BIT(8)) +#define SLC_FUNC_ST 0x0000000F +#define SLC_FUNC_ST_S 4 +#define SLC_CMD_ST 0x00000007 +#define SLC_CMD_ST_S 0 + +#define SLC_RX_DSCR_CONF (REG_SLC_BASE + 0x5C) +#ifdef ESP_MAC_5 +#define SLC_INFOR_NO_REPLACE (BIT(9)) +#define SLC_TOKEN_NO_REPLACE (BIT(8)) +#define SLC_POP_IDLE_CNT 0x000000FF +#else +#define SLC_RX_FILL_EN (BIT(20)) +#define SLC_RX_EOF_MODE (BIT(19)) +#define SLC_RX_FILL_MODE (BIT(18)) +#define SLC_INFOR_NO_REPLACE (BIT(17)) +#define SLC_TOKEN_NO_REPLACE (BIT(16)) +#define SLC_POP_IDLE_CNT 0x0000FFFF +#endif +#define SLC_POP_IDLE_CNT_S 0 + +#define SLC_TXLINK_DSCR (REG_SLC_BASE + 0x60) +#define SLC_TXLINK_DSCR_BF0 (REG_SLC_BASE + 0x64) +#define SLC_TXLINK_DSCR_BF1 (REG_SLC_BASE + 0x68) +#define SLC_RXLINK_DSCR (REG_SLC_BASE + 0x6C) +#define SLC_RXLINK_DSCR_BF0 (REG_SLC_BASE + 0x70) +#define SLC_RXLINK_DSCR_BF1 (REG_SLC_BASE + 0x74) +#define SLC_DATE (REG_SLC_BASE + 0x78) +#define SLC_ID (REG_SLC_BASE + 0x7C) + +#define SLC_HOST_CONF_W0 (REG_SLC_BASE + 0x80 + 0x14) +#define SLC_HOST_CONF_W1 (REG_SLC_BASE + 0x80 + 0x18) +#define SLC_HOST_CONF_W2 (REG_SLC_BASE + 0x80 + 0x20) +#define SLC_HOST_CONF_W3 (REG_SLC_BASE + 0x80 + 0x24) +#define SLC_HOST_CONF_W4 (REG_SLC_BASE + 0x80 + 0x28) + +#define SLC_HOST_INTR_ST (REG_SLC_BASE + 0x80 + 0x1c) +#define SLC_HOST_INTR_CLR (REG_SLC_BASE + 0x80 + 0x30) +#define SLC_HOST_INTR_SOF_BIT (BIT(12)) + +#define SLC_HOST_INTR_ENA (REG_SLC_BASE + 0x80 + 0x34) +#define SLC_RX_NEW_PACKET_INT_ENA (BIT23) +#define SLC_HOST_TOHOST_BIT0_INT_ENA (BIT0) +#define SLC_HOST_CONF_W5 (REG_SLC_BASE + 0x80 + 0x3C) +#define SLC_HOST_INTR_RAW (REG_SLC_BASE + 0x80 + 0x8) +#define SLC_HOST_INTR_ENA_BIT (BIT(23)) +//[15:12]: 0x3ff9xxxx -- 0b01 from_host +// 0x3ffaxxxx -- 0b10 general +// 0x3ffbxxxx -- 0b11 to_host +#define SLC_DATA_ADDR_CLEAR_MASK (~(0xf<<12)) +#define SLC_FROM_HOST_ADDR_MASK (0x1<<12) +#define SLC_TO_HOST_ADDR_MASK (0x3<<12) + +#define SLC_SET_FROM_HOST_ADDR_MASK(v) do { \ + (v) &= SLC_DATA_ADDR_CLEAR_MASK; \ + (v) |= SLC_FROM_HOST_ADDR_MASK; \ +} while(0); + +#define SLC_SET_TO_HOST_ADDR_MASK(v) do { \ + (v) &= SLC_DATA_ADDR_CLEAR_MASK; \ + (v) |= SLC_TO_HOST_ADDR_MASK; \ +} while(0); + + +#define SLC_TX_DESC_DEBUG_REG 0x3ff0002c //[15:0] set to 0xcccc + + +#endif // SLC_REGISTER_H_INCLUDED + diff --git a/embedded8266/user/user_main.c b/embedded8266/user/user_main.c index aa71bac..6277755 100644 --- a/embedded8266/user/user_main.c +++ b/embedded8266/user/user_main.c @@ -6,69 +6,114 @@ #include "osapi.h" #include "espconn.h" #include "mystuff.h" -#include "ws2812.h" +#include "ws2812_i2s.h" +#include "hpatimer.h" +#include +#include +#include + #define PORT 7777 -#define SERVER_TIMEOUT 1000 +#define SERVER_TIMEOUT 1500 #define MAX_CONNS 5 #define MAX_FRAME 2000 #define procTaskPrio 0 #define procTaskQueueLen 1 - static volatile os_timer_t some_timer; static struct espconn *pUdpServer; - -//Note to self. In future consider looking at this: http://pastebin.com/6eLxSrNz - - - +#define HPABUFFSIZE 512 +extern volatile uint8_t sounddata[HPABUFFSIZE]; +extern volatile uint16_t soundhead; +uint16_t soundtail; +//Call this once we've stacked together one full colorchord frame. +static void NewFrame() +{ + //uint8_t led_outs[NUM_LIN_LEDS*3]; + int i; + HandleFrameInfo(); + UpdateLinearLEDs(); + //SendSPI2812( ledOut, NUM_LIN_LEDS ); + ws2812_push( ledOut, NUM_LIN_LEDS * 3 ); +} +os_event_t procTaskQueue[procTaskQueueLen]; +static uint8_t printed_ip = 0; +uint32_t samp_iir = 0; +int wf = 0; //Tasks that happen all the time. -os_event_t procTaskQueue[procTaskQueueLen]; -static void ICACHE_FLASH_ATTR -procTask(os_event_t *events) +static void procTask(os_event_t *events) { system_os_post(procTaskPrio, 0, 0 ); + +// printf( "%d\n", sounddata[soundtail] ); + + while( soundtail != soundhead ) + { + int16_t samp = sounddata[soundtail]; + samp_iir = samp_iir - (samp_iir>>10) + samp; + PushSample32( (samp - (samp_iir>>10))*16 ); + soundtail = (soundtail+1)&(HPABUFFSIZE-1); + + wf++; + if( wf == 128 ) + { + NewFrame(); + wf = 0; + } + } + if( events->sig == 0 && events->par == 0 ) { //Idle Event. + struct station_config wcfg; + char stret[256]; + char *stt = &stret[0]; + struct ip_info ipi; + + int stat = wifi_station_get_connect_status(); + +// printf( "STAT: %d\n", stat ); + + if( stat == STATION_WRONG_PASSWORD || stat == STATION_NO_AP_FOUND || stat == STATION_CONNECT_FAIL ) + { + wifi_set_opmode_current( 2 ); + stt += ets_sprintf( stt, "Connection failed: %d\n", stat ); + uart0_sendStr(stret); + } + + if( stat == STATION_GOT_IP && !printed_ip ) + { + wifi_station_get_config( &wcfg ); + wifi_get_ip_info(0, &ipi); + stt += ets_sprintf( stt, "STAT: %d\n", stat ); + stt += ets_sprintf( stt, "IP: %d.%d.%d.%d\n", (ipi.ip.addr>>0)&0xff,(ipi.ip.addr>>8)&0xff,(ipi.ip.addr>>16)&0xff,(ipi.ip.addr>>24)&0xff ); + stt += ets_sprintf( stt, "NM: %d.%d.%d.%d\n", (ipi.netmask.addr>>0)&0xff,(ipi.netmask.addr>>8)&0xff,(ipi.netmask.addr>>16)&0xff,(ipi.netmask.addr>>24)&0xff ); + stt += ets_sprintf( stt, "GW: %d.%d.%d.%d\n", (ipi.gw.addr>>0)&0xff,(ipi.gw.addr>>8)&0xff,(ipi.gw.addr>>16)&0xff,(ipi.gw.addr>>24)&0xff ); + stt += ets_sprintf( stt, "WCFG: /%s/%s/\n", wcfg.ssid, wcfg.password ); + uart0_sendStr(stret); + printed_ip = 1; + } } + } - //Timer event. -static void ICACHE_FLASH_ATTR - myTimer(void *arg) +static void myTimer(void *arg) { - int i; - uart0_sendStr("."); - SetupConstants(); - -#define GPIO_OUTPUT_SET(gpio_no, bit_value) \ - gpio_output_set(bit_value<proto.udp->local_port = 7777; espconn_regist_recvcb(pUdpServer, udpserver_recv); - wifi_station_dhcpc_start(); - +/* wifi_station_dhcpc_start(); +*/ if( espconn_create( pUdpServer ) ) { while(1) { uart0_sendStr( "\r\nFAULT\r\n" ); } } - //XXX TODO figure out how to safely re-allow this. - ets_wdt_disable(); - - char outbuffer[] = { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,0xff,0xff, 0x00,0xff,0x00 }; - WS2812OutBuffer( outbuffer, 1 ); //Initialize the output. - //Add a process system_os_task(procTask, procTaskPrio, procTaskQueue, procTaskQueueLen); - uart0_sendStr("\r\nCustom Server\r\n"); - WS2812OutBuffer( outbuffer, sizeof(outbuffer) ); - - //Timer example os_timer_disarm(&some_timer); os_timer_setfn(&some_timer, (os_timer_func_t *)myTimer, NULL); - os_timer_arm(&some_timer, 1000, 1); - + os_timer_arm(&some_timer, 100, 1); + + Init(); //Init colorchord + + StartHPATimer(); //Init the high speed ADC timer. + + ws2812_init(); + system_os_post(procTaskPrio, 0, 0 ); } diff --git a/embedded8266/user/ws2812.c b/embedded8266/user/ws2812.c deleted file mode 100644 index 6609723..0000000 --- a/embedded8266/user/ws2812.c +++ /dev/null @@ -1,61 +0,0 @@ -#include "ws2812.h" -#include "ets_sys.h" -#include "mystuff.h" -#include "osapi.h" - -#define GPIO_OUTPUT_SET(gpio_no, bit_value) \ - gpio_output_set(bit_value< +#include "ws2812_i2s.h" +#include "user_interface.h" +#include "pin_mux_register.h" + +//Creates an I2S SR of 93,750 Hz, or 3 MHz Bitclock (.333us/sample) +// 12000000L/(div*bestbck*2) +//It is likely you could speed this up a little. +#define WS_I2S_BCK 16 +#define WS_I2S_DIV 4 + +#ifndef i2c_bbpll +#define i2c_bbpll 0x67 +#define i2c_bbpll_en_audio_clock_out 4 +#define i2c_bbpll_en_audio_clock_out_msb 7 +#define i2c_bbpll_en_audio_clock_out_lsb 7 +#define i2c_bbpll_hostid 4 + +#define i2c_writeReg_Mask(block, host_id, reg_add, Msb, Lsb, indata) rom_i2c_writeReg_Mask(block, host_id, reg_add, Msb, Lsb, indata) +#define i2c_readReg_Mask(block, host_id, reg_add, Msb, Lsb) rom_i2c_readReg_Mask(block, host_id, reg_add, Msb, Lsb) +#define i2c_writeReg_Mask_def(block, reg_add, indata) \ + i2c_writeReg_Mask(block, block##_hostid, reg_add, reg_add##_msb, reg_add##_lsb, indata) +#define i2c_readReg_Mask_def(block, reg_add) \ + i2c_readReg_Mask(block, block##_hostid, reg_add, reg_add##_msb, reg_add##_lsb) +#endif +#ifndef ETS_SLC_INUM +#define ETS_SLC_INUM 1 +#endif + + + +//From i2s_reg.h +#define DR_REG_I2S_BASE (0x60000e00) + +#define I2STXFIFO (DR_REG_I2S_BASE + 0x0000) +#define I2SRXFIFO (DR_REG_I2S_BASE + 0x0004) +#define I2SCONF (DR_REG_I2S_BASE + 0x0008) +#define I2S_BCK_DIV_NUM 0x0000003F +#define I2S_BCK_DIV_NUM_S 22 +#define I2S_CLKM_DIV_NUM 0x0000003F +#define I2S_CLKM_DIV_NUM_S 16 +#define I2S_BITS_MOD 0x0000000F +#define I2S_BITS_MOD_S 12 +#define I2S_RECE_MSB_SHIFT (BIT(11)) +#define I2S_TRANS_MSB_SHIFT (BIT(10)) +#define I2S_I2S_RX_START (BIT(9)) +#define I2S_I2S_TX_START (BIT(8)) +#define I2S_MSB_RIGHT (BIT(7)) +#define I2S_RIGHT_FIRST (BIT(6)) +#define I2S_RECE_SLAVE_MOD (BIT(5)) +#define I2S_TRANS_SLAVE_MOD (BIT(4)) +#define I2S_I2S_RX_FIFO_RESET (BIT(3)) +#define I2S_I2S_TX_FIFO_RESET (BIT(2)) +#define I2S_I2S_RX_RESET (BIT(1)) +#define I2S_I2S_TX_RESET (BIT(0)) +#define I2S_I2S_RESET_MASK 0xf + + #define I2SINT_RAW (DR_REG_I2S_BASE + 0x000c) +#define I2S_I2S_TX_REMPTY_INT_RAW (BIT(5)) +#define I2S_I2S_TX_WFULL_INT_RAW (BIT(4)) +#define I2S_I2S_RX_REMPTY_INT_RAW (BIT(3)) +#define I2S_I2S_RX_WFULL_INT_RAW (BIT(2)) +#define I2S_I2S_TX_PUT_DATA_INT_RAW (BIT(1)) +#define I2S_I2S_RX_TAKE_DATA_INT_RAW (BIT(0)) + + +#define I2SINT_ST (DR_REG_I2S_BASE + 0x0010) +#define I2S_I2S_TX_REMPTY_INT_ST (BIT(5)) +#define I2S_I2S_TX_WFULL_INT_ST (BIT(4)) +#define I2S_I2S_RX_REMPTY_INT_ST (BIT(3)) +#define I2S_I2S_RX_WFULL_INT_ST (BIT(2)) +#define I2S_I2S_TX_PUT_DATA_INT_ST (BIT(1)) +#define I2S_I2S_RX_TAKE_DATA_INT_ST (BIT(0)) + + #define I2SINT_ENA (DR_REG_I2S_BASE + 0x0014) +#define I2S_I2S_TX_REMPTY_INT_ENA (BIT(5)) +#define I2S_I2S_TX_WFULL_INT_ENA (BIT(4)) +#define I2S_I2S_RX_REMPTY_INT_ENA (BIT(3)) +#define I2S_I2S_RX_WFULL_INT_ENA (BIT(2)) +#define I2S_I2S_TX_PUT_DATA_INT_ENA (BIT(1)) +#define I2S_I2S_RX_TAKE_DATA_INT_ENA (BIT(0)) + + #define I2SINT_CLR (DR_REG_I2S_BASE + 0x0018) +#define I2S_I2S_TX_REMPTY_INT_CLR (BIT(5)) +#define I2S_I2S_TX_WFULL_INT_CLR (BIT(4)) +#define I2S_I2S_RX_REMPTY_INT_CLR (BIT(3)) +#define I2S_I2S_RX_WFULL_INT_CLR (BIT(2)) +#define I2S_I2S_PUT_DATA_INT_CLR (BIT(1)) +#define I2S_I2S_TAKE_DATA_INT_CLR (BIT(0)) + +#define I2STIMING (DR_REG_I2S_BASE + 0x001c) +#define I2S_TRANS_BCK_IN_INV (BIT(22)) +#define I2S_RECE_DSYNC_SW (BIT(21)) +#define I2S_TRANS_DSYNC_SW (BIT(20)) +#define I2S_RECE_BCK_OUT_DELAY 0x00000003 +#define I2S_RECE_BCK_OUT_DELAY_S 18 +#define I2S_RECE_WS_OUT_DELAY 0x00000003 +#define I2S_RECE_WS_OUT_DELAY_S 16 +#define I2S_TRANS_SD_OUT_DELAY 0x00000003 +#define I2S_TRANS_SD_OUT_DELAY_S 14 +#define I2S_TRANS_WS_OUT_DELAY 0x00000003 +#define I2S_TRANS_WS_OUT_DELAY_S 12 +#define I2S_TRANS_BCK_OUT_DELAY 0x00000003 +#define I2S_TRANS_BCK_OUT_DELAY_S 10 +#define I2S_RECE_SD_IN_DELAY 0x00000003 +#define I2S_RECE_SD_IN_DELAY_S 8 +#define I2S_RECE_WS_IN_DELAY 0x00000003 +#define I2S_RECE_WS_IN_DELAY_S 6 +#define I2S_RECE_BCK_IN_DELAY 0x00000003 +#define I2S_RECE_BCK_IN_DELAY_S 4 +#define I2S_TRANS_WS_IN_DELAY 0x00000003 +#define I2S_TRANS_WS_IN_DELAY_S 2 +#define I2S_TRANS_BCK_IN_DELAY 0x00000003 +#define I2S_TRANS_BCK_IN_DELAY_S 0 + +#define I2S_FIFO_CONF (DR_REG_I2S_BASE + 0x0020) +#define I2S_I2S_RX_FIFO_MOD 0x00000007 +#define I2S_I2S_RX_FIFO_MOD_S 16 +#define I2S_I2S_TX_FIFO_MOD 0x00000007 +#define I2S_I2S_TX_FIFO_MOD_S 13 +#define I2S_I2S_DSCR_EN (BIT(12)) +#define I2S_I2S_TX_DATA_NUM 0x0000003F +#define I2S_I2S_TX_DATA_NUM_S 6 +#define I2S_I2S_RX_DATA_NUM 0x0000003F +#define I2S_I2S_RX_DATA_NUM_S 0 + + +#define I2SRXEOF_NUM (DR_REG_I2S_BASE + 0x0024) +#define I2S_I2S_RX_EOF_NUM 0xFFFFFFFF +#define I2S_I2S_RX_EOF_NUM_S 0 + +#define I2SCONF_SIGLE_DATA (DR_REG_I2S_BASE + 0x0028) +#define I2S_I2S_SIGLE_DATA 0xFFFFFFFF +#define I2S_I2S_SIGLE_DATA_S 0 + +#define I2SCONF_CHAN (DR_REG_I2S_BASE + 0x002c) +#define I2S_RX_CHAN_MOD 0x00000003 +#define I2S_RX_CHAN_MOD_S 3 +#define I2S_TX_CHAN_MOD 0x00000007 +#define I2S_TX_CHAN_MOD_S 0 + + +//From sdio_slv.h + + +struct sdio_queue +{ + uint32 blocksize:12; + uint32 datalen:12; + uint32 unused:5; + uint32 sub_sof:1; + uint32 eof:1; + uint32 owner:1; + + uint32 buf_ptr; + uint32 next_link_ptr; +}; + +struct sdio_slave_status_element +{ + uint32 wr_busy:1; + uint32 rd_empty :1; + uint32 comm_cnt :3; + uint32 intr_no :3; + uint32 rx_length:16; + uint32 res:8; +}; + +union sdio_slave_status +{ + struct sdio_slave_status_element elm_value; + uint32 word_value; +}; + +#define RX_AVAILIBLE 2 +#define TX_AVAILIBLE 1 +#define INIT_STAGE 0 + +#define SDIO_QUEUE_LEN 8 +#define MOSI 0 +#define MISO 1 +#define SDIO_DATA_ERROR 6 + +#define SLC_INTEREST_EVENT (SLC_TX_EOF_INT_ENA | SLC_RX_EOF_INT_ENA | SLC_RX_UDF_INT_ENA | SLC_TX_DSCR_ERR_INT_ENA) +#define TRIG_TOHOST_INT() SET_PERI_REG_MASK(SLC_INTVEC_TOHOST , BIT0);\ + CLEAR_PERI_REG_MASK(SLC_INTVEC_TOHOST , BIT0) + + +///Rest of program... + +//Pointer to the I2S DMA buffer data +//static unsigned int i2sBuf[I2SDMABUFCNT][I2SDMABUFLEN]; +//I2S DMA buffer descriptors +//static struct sdio_queue i2sBufDesc[I2SDMABUFCNT]; +static struct sdio_queue i2sBufDescOut; +static struct sdio_queue i2sBufDescZeroes; + +static unsigned int i2sZeroes[32]; +static unsigned int i2sBlock[WS_BLOCKSIZE/4]; + +//Queue which contains empty DMA buffers +//DMA underrun counter + + +#ifdef USE_2812_INTERRUPTS + +volatile uint8_t ws2812_dma_complete; + +//This routine is called as soon as the DMA routine has something to tell us. All we +//handle here is the RX_EOF_INT status, which indicate the DMA has sent a buffer whose +//descriptor has the 'EOF' field set to 1. +LOCAL void slc_isr(void) { + //clear all intr flags +// WRITE_PERI_REG(SLC_INT_CLR, 0xffffffff);//slc_intr_status); + +// ws2812_dma_complete = 1; + + //This is a little wacky. This function actually gets called twice. + //Once for the initial transfer, but by the time we tell it to stop + //The other zero transfer's already begun. +// SET_PERI_REG_MASK(SLC_RX_LINK, SLC_RXLINK_STOP); +} + + +#endif + +//Initialize I2S subsystem for DMA circular buffer use +void ICACHE_FLASH_ATTR ws2812_init() +{ + int x, y; + + //Reset DMA + SET_PERI_REG_MASK(SLC_CONF0, SLC_RXLINK_RST);//|SLC_TXLINK_RST); + CLEAR_PERI_REG_MASK(SLC_CONF0, SLC_RXLINK_RST);//|SLC_TXLINK_RST); + + //Clear DMA int flags + SET_PERI_REG_MASK(SLC_INT_CLR, 0xffffffff); + CLEAR_PERI_REG_MASK(SLC_INT_CLR, 0xffffffff); + + //Enable and configure DMA + CLEAR_PERI_REG_MASK(SLC_CONF0, (SLC_MODE< WS_BLOCKSIZE ) return; + + for( place = 0; place < buffersize; place++ ) + { + uint8_t btosend = buffer[place]; + *(bufferpl++) = bitpatterns[(btosend&0x0f)]; + *(bufferpl++) = bitpatterns[(btosend>>4)&0x0f]; + } + +#ifdef USE_2812_INTERRUPTS + + uint16_t leftover = buffersize & 0x1f; + if( leftover ) leftover = 32 - leftover; + for( place = 0; place < leftover; place++ ) + { + *(bufferpl++) = 0; + *(bufferpl++) = 0; + } + + buffersize += leftover; + + 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. + + 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, SLC_RXLINK_START); + +#endif + +} + + + diff --git a/embedded8266/user/ws2812_i2s.h b/embedded8266/user/ws2812_i2s.h new file mode 100644 index 0000000..e20785f --- /dev/null +++ b/embedded8266/user/ws2812_i2s.h @@ -0,0 +1,20 @@ +#ifndef _I2S_TEST +#define _I2S_TEST + +//Stuff that should be for the header: + +#include + +//Parameters for the I2S DMA behaviour +//#define I2SDMABUFCNT (2) //Number of buffers in the I2S circular buffer +//#define I2SDMABUFLEN (32*2) //Length of one buffer, in 32-bit words. + +//NOTE: Blocksize MUST be divisible by 4. Cannot exceed 4092 +//Each LED takes up 12 block bytes. +#define WS_BLOCKSIZE 4000 + +void ICACHE_FLASH_ATTR ws2812_init(); +void ws2812_push( uint8_t * buffer, uint16_t buffersize ); //Buffersize = Nr LEDs * 3 + +#endif +