├── Makefile ├── README.md ├── main ├── app_main.c ├── asm_test.S ├── component.mk ├── i2s_stream_fast.c ├── i2s_stream_fast.h ├── i2s_stream_in.c ├── i2s_stream_in.h ├── i2s_stream_out.c └── i2s_stream_out.h ├── sdkconfig └── trunky ├── app_main.c ├── asm_test.S ├── component.mk ├── i2s_stream_fast.c ├── i2s_stream_fast.h ├── i2s_stream_in.c ├── i2s_stream_in.h ├── i2s_stream_out.c └── i2s_stream_out.h /Makefile: -------------------------------------------------------------------------------- 1 | PROJECT_NAME := esp32-cnlohr-demo 2 | 3 | include $(IDF_PATH)/make/project.mk 4 | 5 | CPPFLAGS += -DXT_INTEXC_HOOKS -DXCHAL_HAVE_NMI 6 | 7 | program.lst : build/$(PROJECT_NAME).elf 8 | xtensa-esp32-elf-objdump -S build/$(PROJECT_NAME).elf > program.lst 9 | 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # esp32-cnlohr-demo 2 | My always-incomplete ESP32 fun zone 3 | -------------------------------------------------------------------------------- /main/app_main.c: -------------------------------------------------------------------------------- 1 | 2 | // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include "freertos/FreeRTOS.h" 22 | #include "freertos/task.h" 23 | #include "freertos/semphr.h" 24 | 25 | #include "driver/gpio.h" 26 | 27 | #include "esp_err.h" 28 | #include "esp_log.h" 29 | 30 | #include "i2s_stream_out.h" 31 | 32 | 33 | #include "freertos/FreeRTOS.h" 34 | #include "esp_wifi.h" 35 | #include "esp_system.h" 36 | #include "esp_event.h" 37 | #include "esp_event_loop.h" 38 | #include "nvs_flash.h" 39 | 40 | #include "i2s_stream_fast.h" 41 | //#include "i2s_stream_in_for_usb.h" 42 | #include 43 | 44 | #include 45 | 46 | void asmtest(); 47 | int test_fast_gpio(); 48 | 49 | #define XT_INTEXC_HOOK_NUM (1 + XCHAL_NUM_INTLEVELS + XCHAL_HAVE_NMI) 50 | extern volatile void * _xt_intexc_hooks[XT_INTEXC_HOOK_NUM]; 51 | 52 | void _my_xt_nmi(); 53 | uint32_t mydata; 54 | 55 | 56 | esp_err_t event_handler(void *ctx, system_event_t *event) 57 | { 58 | return ESP_OK; 59 | } 60 | 61 | 62 | volatile int ok2go = 0; 63 | volatile int running2go = 0; 64 | 65 | void introo() 66 | { 67 | write code here to test. 68 | } 69 | 70 | void start_cpu1() 71 | { 72 | while(!ok2go); 73 | running2go = 1; 74 | while(1) 75 | { 76 | asm volatile( "nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n" ); 77 | GPIO.out_w1ts = 1<<16; 78 | asm volatile( "nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n" ); 79 | GPIO.out_w1tc = 1<<16; 80 | } 81 | 82 | } 83 | 84 | void app_main() 85 | { 86 | //#define DO_WIFI 87 | #ifdef DO_WIFI 88 | 89 | nvs_flash_init(); 90 | tcpip_adapter_init(); 91 | ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); 92 | wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); 93 | ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); 94 | ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); 95 | ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); 96 | wifi_config_t sta_config = { 97 | .sta = { 98 | .ssid = "charles", 99 | .password = "thisiswifi", 100 | .bssid_set = false 101 | } 102 | }; 103 | ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &sta_config) ); 104 | ESP_ERROR_CHECK( esp_wifi_start() ); 105 | ESP_ERROR_CHECK( esp_wifi_connect() ); 106 | #endif 107 | 108 | 109 | #if 0 110 | #define HIGH_PERF_I2S_IN 111 | #ifdef HIGH_PERF_I2S_IN 112 | SetupI2SInUSB(); 113 | TickI2SInUSB(); 114 | 115 | { 116 | uint32_t lastcount = 0; 117 | while(true) 118 | { 119 | vTaskDelay(1000 / portTICK_RATE_MS); 120 | printf( "%d %08x\n", isr_countInUSB-lastcount, i2sbufferInUSB[0][0] ); 121 | lastcount = isr_countInUSB; 122 | } 123 | } 124 | 125 | #endif 126 | 127 | //#define TEST_ASM_RET_CALL 128 | #ifdef TEST_ASM_RET_CALL 129 | int test_asm_call(int i); 130 | uint8_t re = 0; 131 | while(1) 132 | { 133 | re++; 134 | 135 | //((uint8_t*)test_asm_call)[4] = 177; 136 | int ret = test_asm_call(re); 137 | //printf( "%08x\n", ((uint32_t)&test_asm_call) ); 138 | printf( "%d %d\n", re, ret ); 139 | } 140 | #endif 141 | 142 | //#define GPIO_ASM_TEST 143 | #ifdef GPIO_ASM_TEST 144 | GPIO.enable_w1ts = 1<<17; 145 | GPIO.out_w1ts = 1<<17; 146 | GPIO.out_w1tc = 1<<17; 147 | GPIO.out_w1ts = 1<<17; 148 | GPIO.out_w1tc = 1<<17; 149 | int rr = test_fast_gpio(); 150 | //printf( "TFGPIO: %08x\n", ); 151 | while(1) 152 | { 153 | 154 | GPIO.out_w1ts = 1<<17; 155 | GPIO.out_w1tc = 1<<17; 156 | } 157 | #endif 158 | 159 | #define NMI_TEST 160 | #ifdef NMI_TEST 161 | 162 | printf( "NMI TEST\n" ); 163 | 164 | gpio_config_t conf_gp = { 165 | .mode = GPIO_MODE_OUTPUT, 166 | .pull_up_en = GPIO_PULLUP_DISABLE, 167 | .pull_down_en = GPIO_PULLDOWN_DISABLE, 168 | .intr_type = GPIO_INTR_DISABLE, 169 | .pin_bit_mask = 1LL << 18 | 1LL<<16 | 1LL<<17 170 | }; 171 | gpio_config(&conf_gp); 172 | 173 | /* 174 | GPIO.func_out_sel_cfg[18].func_sel = 256; 175 | WRITE_PERI_REG( DR_REG_IO_MUX_BASE +0x54, 0x1b00 ); //GPIO 18 GPIO. 176 | GPIO.func_out_sel_cfg[16].func_sel = 256; 177 | WRITE_PERI_REG( DR_REG_IO_MUX_BASE +0x4c, 0x2800 ); //GPIO 16 GPIO. 178 | 179 | */ 180 | /* 181 | char *Buf = pvPortMallocCaps(1000, MALLOC_CAP_8BIT); 182 | typedef struct { 183 | char *BufStartAdress; 184 | }paramSet; 185 | paramSet *ParamPTR = pvPortMallocCaps(8, MALLOC_CAP_32BIT); 186 | ParamPTR->BufStartAdress = Buf; 187 | int xReturned2= xTaskCreatePinnedToCore(&run_on_core_2, "RealTimeThread", 2048, ParamPTR, 25, NULL, 1); 188 | */ 189 | 190 | printf( "%08x %08x %d %d\n", READ_PERI_REG( DR_REG_IO_MUX_BASE +0x4c ), READ_PERI_REG( DR_REG_IO_MUX_BASE +0x50 ), GPIO.func_out_sel_cfg[16].val, GPIO.func_out_sel_cfg[17].val ); 191 | // GPIO.enable_w1ts = 1<<18; 192 | // GPIO.enable_w1ts = 1<<17; 193 | // GPIO.enable_w1ts = 1<<16; 194 | 195 | GPIO.out_w1ts = 1<<16; 196 | GPIO.out_w1tc = 1<<16; 197 | GPIO.out_w1ts = 1<<16; 198 | GPIO.out_w1tc = 1<<16; 199 | 200 | _xt_intexc_hooks[XCHAL_NMILEVEL] = &_my_xt_nmi; 201 | 202 | GPIO.pin[0].int_ena = GPIO_PRO_CPU_NMI_INTR_ENA; ///Why can't I set the app CPU? 203 | GPIO.pin[0].int_type = 3; //Level-change trigger. 204 | 205 | #define ETS_GPIO_INUM 14 //Actually NMI vector. 206 | intr_matrix_set( 0, ETS_GPIO_NMI_SOURCE, ETS_GPIO_INUM ); 207 | ESP_INTR_ENABLE( ETS_GPIO_INUM ); 208 | 209 | ok2go = 1; 210 | printf( "Attached\n" ); 211 | 212 | while(1) 213 | { 214 | asm volatile( "nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n" ); 215 | GPIO.out_w1ts = 1<<17; 216 | asm volatile( "nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n" ); 217 | GPIO.out_w1tc = 1<<17; 218 | //printf( "Running2go: %d\n", running2go ); 219 | } 220 | #endif 221 | 222 | 223 | //#define I2SOTEST_FAST 224 | 225 | #ifdef I2SOTEST_FAST 226 | printf( "!!!!!!!!!!!!!!!!!!!!!!1\n" ); 227 | SetupI2SOut_fast(); 228 | printf( "!!!!!!!!!!!!!!!!!!!!!!2\n" ); 229 | TickI2SOut_fast(); 230 | printf( "!!!!!!!!!!!!!!!!!!!!!!3\n" ); 231 | 232 | while(true) 233 | { 234 | printf( "%d %08x\n", isr_countOut_fast, i2sbufferOut_fast[0][3] ); 235 | vTaskDelay(1000 / portTICK_RATE_MS); 236 | } 237 | 238 | #endif 239 | #ifdef I2SOTEST 240 | SetupI2SOut(); 241 | TickI2SOut(); 242 | 243 | while(true) 244 | { 245 | printf( "%d %08x\n", isr_countOut, i2sbufferOut[0][3] ); 246 | vTaskDelay(1000 / portTICK_RATE_MS); 247 | } 248 | 249 | #endif 250 | 251 | #define GPIOASMTEST 252 | #ifdef GPIOASMTEST 253 | 254 | gpio_config_t conf = { 255 | .mode = GPIO_MODE_OUTPUT, 256 | .pull_up_en = GPIO_PULLUP_DISABLE, 257 | .pull_down_en = GPIO_PULLDOWN_DISABLE, 258 | .intr_type = GPIO_INTR_DISABLE, 259 | .pin_bit_mask = 1LL << 18 | 1LL<<16 260 | }; 261 | gpio_config(&conf); 262 | printf( "GPIO ASM TEST\n" ); 263 | printf( "%08x %08x %d %d\n", READ_PERI_REG( DR_REG_IO_MUX_BASE +0x4c ), READ_PERI_REG( DR_REG_IO_MUX_BASE +0x54 ), GPIO.func_out_sel_cfg[16].val, GPIO.func_out_sel_cfg[18].val ); 264 | 265 | 266 | while(true) 267 | { 268 | //gpio_set_level( 18, 0 ); 269 | //gpio_set_level( 18, 1 ); 270 | GPIO.out_w1ts = (1 << 18); 271 | asmtest(); 272 | GPIO.out_w1tc = (1 << 18); 273 | asmtest(); 274 | // GPIO.out1_w1ts.data = (1 << (gpio_num - 32)); 275 | 276 | 277 | // printf( "%d %08x\n", isr_countOut, i2sbufferOut[0][3] ); 278 | // vTaskDelay(1000 / portTICK_RATE_MS); 279 | } 280 | 281 | #endif 282 | #endif 283 | 284 | introo(); 285 | 286 | } 287 | 288 | -------------------------------------------------------------------------------- /main/asm_test.S: -------------------------------------------------------------------------------- 1 | #define XCHAL_NMILEVEL 7/* NMI "level" (for use with */ 2 | 3 | 4 | 5 | .global test_asm_call 6 | .section .iram1,"ax" 7 | .align 4 8 | test_asm_call: 9 | entry a1, 32 10 | // rsr a2, 177 11 | // wsr a2, MISC0 12 | // rur a2, 0 13 | // .byte 0x20, 0x00, 0xe3 14 | // .byte 0x22, 0x22, 0xe3 //RUR (Doesn't work) 15 | .byte 0x20, 234, 0x03 //RSR 16 | 17 | retw 18 | 19 | 20 | .global asmtest 21 | .align 4 22 | 23 | asmtest: 24 | entry a1, 32 25 | 26 | // addi a1, a1, -68 27 | s32i.n a0, a1, 0 // Working reg 28 | s32i.n a2, a1, 4 // Running byte 29 | s32i.n a3, a1, 8 // Running CRC 30 | s32i.n a4, a1, 12 // Anding mask 31 | 32 | movi a0,160000 33 | movi a2, GPIO //Will take 10 cycles to read (at 240 MHz) 5 at 80. and 7 at 160, 1 to write. 34 | // movi a2, mydata //Will take 1 cycle 35 | 36 | // l32i a3, a2, 0 37 | keep_going: 38 | l32i a3, a2, 0 39 | // s32i a3, a2, 0 40 | addi a0, a0, -1 41 | bnez a0, keep_going 42 | 43 | 44 | 45 | l32i.n a0, a1, 0 46 | l32i.n a2, a1, 4 47 | l32i.n a3, a1, 8 48 | l32i.n a4, a1, 12 49 | // addi a1, a1, 68 50 | retw 51 | 52 | 53 | .align 4 54 | .global test_fast_gpio 55 | test_fast_gpio: 56 | entry a1, 32 57 | addi a1, a1, -68 58 | 59 | s32i.n a0, a1, 0 60 | s32i.n a3, a1, 4 61 | s32i.n a4, a1, 8 62 | movi a4, 10000 63 | 64 | tg: 65 | movi a2, GPIO 66 | movi a3, 1<<17 67 | s32i a3, a2, 8 //W1TS 68 | s32i a3, a2, 12 //W1TC 69 | addi a4, a4, -1 70 | bnez a4, tg 71 | 72 | l32i.n a4, a1, 8 73 | l32i.n a3, a1, 4 74 | movi a2, GPIO 75 | l32i.n a0, a1, 0 76 | addi a1, a1, 68 77 | retw 78 | //j test_fast_gpio 79 | 80 | 81 | 82 | 83 | 84 | //My terrible ISR WORKS! 85 | 86 | .global _my_xt_nmi 87 | .section .iram1,"ax" 88 | .type _my_xt_nmi,@function 89 | .align 4 90 | 91 | _my_xt_nmi: 92 | 93 | addi a1, a1, -68 94 | s32i a2, a1, 4 95 | s32i a3, a1, 8 96 | s32i a4, a1, 12 97 | 98 | nop 99 | nop 100 | nop 101 | nop 102 | nop 103 | nop 104 | nop 105 | nop 106 | nop 107 | nop 108 | nop 109 | nop 110 | nop 111 | nop 112 | nop 113 | nop 114 | nop 115 | nop 116 | nop 117 | nop 118 | nop 119 | nop 120 | nop 121 | nop 122 | nop 123 | nop 124 | nop 125 | nop 126 | nop 127 | nop 128 | nop 129 | nop 130 | nop 131 | nop 132 | nop 133 | nop 134 | nop 135 | nop 136 | nop 137 | nop 138 | nop 139 | nop 140 | nop 141 | nop 142 | nop 143 | nop 144 | nop 145 | nop 146 | nop 147 | nop 148 | nop 149 | nop 150 | nop 151 | nop 152 | nop 153 | nop 154 | nop 155 | nop 156 | nop 157 | nop 158 | nop 159 | nop 160 | nop 161 | nop 162 | nop 163 | nop 164 | nop 165 | nop 166 | nop 167 | nop 168 | nop 169 | nop 170 | nop 171 | nop 172 | nop 173 | nop 174 | 175 | 176 | movi a2, GPIO 177 | movi a3, 1<<18 178 | movi a4, 200 179 | _xt_loop: 180 | s32i a3, a2, 8 //W1TS 181 | nop 182 | nop 183 | nop 184 | nop 185 | nop 186 | nop 187 | nop 188 | nop 189 | nop 190 | nop 191 | s32i a3, a2, 12 //W1TC 192 | nop 193 | nop 194 | nop 195 | nop 196 | nop 197 | nop 198 | nop 199 | nop 200 | nop 201 | nop 202 | nop 203 | nop 204 | nop 205 | nop 206 | addi a4, a4, -1 207 | bnez a4, _xt_loop 208 | 209 | movi a3, 1 210 | s32i a3, a2, 0x4c //Status w1tc 211 | 212 | l32i a4, a1, 12 213 | l32i a3, a1, 8 214 | l32i a2, a1, 4 215 | addi a1, a1, 68 216 | rsr a0, EXCSAVE7 /* restore a0 */ 217 | rfi XCHAL_NMILEVEL 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | //USB in stream test 256 | .global _my_usb_stream_xt_nmi 257 | .section .iram1,"ax" 258 | .type _my_usb_stream_xt_nmi,@function 259 | .align 4 260 | 261 | _my_usb_stream_xt_nmi: 262 | addi a1, a1, -68 263 | s32i a2, a1, 4 264 | s32i a3, a1, 8 265 | s32i a4, a1, 12 266 | 267 | //TODO: 268 | // (0) Clear I2S Data 269 | // (1) Start I2S engine 270 | // (1.5) Start timer 271 | // (2) Monitor output for when it's complete 272 | // (3) Stop I2S Engine 273 | // (4) Stop timer. 274 | movi a2, GPIO 275 | movi a3, 1<<18 276 | movi a4, 200 277 | _uxt_loop: 278 | s32i a3, a2, 8 //W1TS 279 | s32i a3, a2, 12 //W1TC 280 | addi a4, a4, -1 281 | bnez a4, _uxt_loop 282 | 283 | movi a3, 1 284 | s32i a3, a2, 0x4c //Status w1tc 285 | 286 | l32i a4, a1, 12 287 | l32i a3, a1, 8 288 | l32i a2, a1, 4 289 | addi a1, a1, 68 290 | rsr a0, EXCSAVE7 /* restore a0 */ 291 | rfi XCHAL_NMILEVEL 292 | 293 | -------------------------------------------------------------------------------- /main/component.mk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnlohr/esp32-cnlohr-demo/f6f253139b2df1818203241642175ff270d23189/main/component.mk -------------------------------------------------------------------------------- /main/i2s_stream_fast.c: -------------------------------------------------------------------------------- 1 | //This is for ONE BIT SHIFT REGISTER OUTPUT 2 | 3 | //Parts from: from https://github.com/pewit-tech/esp32-i2s/blob/master/i2s_freertos.c 4 | 5 | 6 | //Almost entirelly lifted directly from https://github.com/igrr/esp32-cam-demo 7 | //Just clocked a little differently and has chained buffers. 8 | //This totes works with the I2S bus on the ESP32 for READING 16 wires simultaneously. 9 | //Can be clocked off of I2S's internal controller or an external clock. 10 | 11 | 12 | 13 | #include "esp_intr.h" 14 | #include "i2s_stream_out.h" 15 | #include "driver/gpio.h" 16 | #include "soc/gpio_sig_map.h" 17 | #include "soc/i2s_reg.h" 18 | #include "soc/io_mux_reg.h" 19 | #include "driver/gpio.h" 20 | #include "driver/periph_ctrl.h" 21 | #include "rom/lldesc.h" 22 | #include "esp_log.h" 23 | #include "driver/ledc.h" 24 | #include 25 | #include "soc/rtc_cntl_reg.h" 26 | #include "soc/rtc.h" 27 | 28 | #define ETS_I2S0_INUM 13 29 | 30 | static void IRAM_ATTR i2s_isr_fast(void* arg); 31 | static esp_err_t dma_desc_init_fast(); 32 | static void i2s_init_fast(); 33 | static void i2s_run_fast(); 34 | 35 | 36 | uint32_t * i2sbufferOut_fast[3] __attribute__((aligned(128))); 37 | static lldesc_t s_dma_desc[3]; 38 | static int i2s_running; 39 | volatile unsigned isr_countOut_fast; 40 | 41 | 42 | void SetupI2SOut_fast() 43 | { 44 | // enable_out_clock(); 45 | i2s_init_fast(); 46 | dma_desc_init_fast(); 47 | i2s_run_fast(); 48 | } 49 | 50 | 51 | static esp_err_t dma_desc_init_fast() 52 | { 53 | for (int i = 0; i < 3; ++i) { 54 | i2sbufferOut_fast[i] = malloc( BUFF_SIZE_BYTES ); 55 | s_dma_desc[i].length = BUFF_SIZE_BYTES; // size of a single DMA buf 56 | s_dma_desc[i].size = BUFF_SIZE_BYTES; // total size of the chain 57 | s_dma_desc[i].owner = 1; 58 | s_dma_desc[i].sosf = 1; 59 | s_dma_desc[i].buf = (uint8_t*) i2sbufferOut_fast[i]; 60 | s_dma_desc[i].offset = i; 61 | s_dma_desc[i].empty = 0; 62 | s_dma_desc[i].eof = 1; 63 | s_dma_desc[i].qe.stqe_next = &s_dma_desc[(i+1)%3]; 64 | int k; 65 | for( k = 0; k < BUFF_SIZE_BYTES/4; k++ ) 66 | { 67 | // i2sbufferOut[i][k] = (k&1)?0x0000FfFF:0xaaaaaaaa; 68 | i2sbufferOut_fast[i][k] = 0xaaaaaaaa; 69 | } 70 | } 71 | return ESP_OK; 72 | } 73 | 74 | /* 75 | static void enable_out_clock() { 76 | periph_module_enable(PERIPH_LEDC_MODULE); 77 | 78 | ledc_timer_config_t timer_conf; 79 | timer_conf.bit_num = 3; 80 | timer_conf.freq_hz = I2S_HZ; 81 | timer_conf.speed_mode = LEDC_HIGH_SPEED_MODE; 82 | timer_conf.timer_num = LEDC_TIMER_0; 83 | esp_err_t err = ledc_timer_config(&timer_conf); 84 | if (err != ESP_OK) { 85 | //ESP_LOGE(TAG, "ledc_timer_config failed, rc=%x", err); 86 | } 87 | 88 | ledc_channel_config_t ch_conf; 89 | ch_conf.channel = LEDC_CHANNEL_0; 90 | ch_conf.timer_sel = LEDC_TIMER_0; 91 | ch_conf.intr_type = LEDC_INTR_DISABLE; 92 | ch_conf.duty = 4; 93 | ch_conf.speed_mode = LEDC_HIGH_SPEED_MODE; 94 | ch_conf.gpio_num = 17; //s_config.pin_xclk; 95 | err = ledc_channel_config(&ch_conf); 96 | if (err != ESP_OK) { 97 | //ESP_LOGE(TAG, "ledc_channel_config failed, rc=%x", err); 98 | } 99 | 100 | } 101 | */ 102 | 103 | static void i2s_init_fast() 104 | { 105 | xt_set_interrupt_handler(ETS_I2S0_INUM, &i2s_isr_fast, NULL); 106 | intr_matrix_set(0, ETS_I2S0_INTR_SOURCE, ETS_I2S0_INUM); 107 | 108 | 109 | gpio_num_t pins[] = { 110 | 17, 111 | 18, 112 | 19, 113 | }; 114 | 115 | 116 | gpio_config_t conf = { 117 | .mode = GPIO_MODE_OUTPUT, 118 | .pull_up_en = GPIO_PULLUP_DISABLE, 119 | .pull_down_en = GPIO_PULLDOWN_DISABLE, 120 | .intr_type = GPIO_INTR_DISABLE 121 | }; 122 | for (int i = 0; i < sizeof(pins)/sizeof(gpio_num_t); ++i) { 123 | conf.pin_bit_mask = 1LL << pins[i]; 124 | gpio_config(&conf); 125 | } 126 | 127 | gpio_matrix_out(GPIO_NUM_17, I2S0O_DATA_OUT23_IDX, 0, 0); 128 | // gpio_matrix_out(GPIO_NUM_19, I2S0O_BCK_OUT_IDX, 0, 0); 129 | // gpio_matrix_out(GPIO_NUM_18, I2S0O_WS_OUT_IDX, 0, 0); 130 | 131 | 132 | periph_module_enable(PERIPH_I2S0_MODULE); 133 | 134 | 135 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 1, I2S_IN_RST_S); 136 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 0, I2S_IN_RST_S); 137 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 1, I2S_AHBM_RST_S); 138 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 0, I2S_AHBM_RST_S); 139 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 1, I2S_AHBM_FIFO_RST_S); 140 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 0, I2S_AHBM_FIFO_RST_S); 141 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_RESET_S); 142 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_TX_RESET_S); 143 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_FIFO_RESET_S); 144 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_TX_FIFO_RESET_S); 145 | 146 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_TX_SLAVE_MOD_S); //Needed, otherwise it waits for a clock. 147 | // SET_PERI_REG_MASK(I2S_CONF_REG(0), I2S_TX_MSB_SHIFT); 148 | // WRITE_PERI_REG(I2S_CONF2_REG(0), 0); 149 | 150 | #if 0 151 | 152 | #ifdef MANYBITS 153 | SET_PERI_REG_BITS(I2S_CONF2_REG(0), I2S_LCD_EN, 1, I2S_LCD_EN_S); 154 | SET_PERI_REG_BITS(I2S_CONF1_REG(0), I2S_TX_PCM_BYPASS, 1, I2S_TX_PCM_BYPASS_S); //Breaks everything 155 | // SET_PERI_REG_BITS(I2S_CONF2_REG(0), 0x1, 1, I2S_CAMERA_EN_S); 156 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_A, 0, I2S_CLKM_DIV_A_S); 157 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_B, 0, I2S_CLKM_DIV_B_S); 158 | 159 | #else 160 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_A, 1, I2S_CLKM_DIV_A_S); 161 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_B, 0, I2S_CLKM_DIV_B_S); 162 | 163 | #endif 164 | 165 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_NUM, 15, I2S_CLKM_DIV_NUM_S); //Setting to 0 wrecks it up. 166 | 167 | 168 | //This seems ignored in slave mode. 169 | // WRITE_PERI_REG( I2S_TIMING_REG(0), 0xffffffff ); 170 | // WRITE_PERI_REG( I2S_CONF_SIGLE_DATA_REG(0), 0xffffffff ); 171 | // SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_RX_SHORT_SYNC_S); // 172 | // SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_RX_BCK_DIV_NUM, 1, I2S_RX_BCK_DIV_NUM_S); 173 | 174 | #ifdef MANYBITS 175 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_TX_MONO_S); 176 | #else 177 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_RIGHT_FIRST_S); //Seem ignored in parallel mode 178 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_MSB_RIGHT_S);//Seem ignored in parallel mode 179 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_MSB_SHIFT_S);//Seem ignored in parallel mode 180 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_MONO_S); 181 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_SHORT_SYNC_S); //Seem ignored in parallel mode 182 | 183 | #endif 184 | // SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_MONO_S); 185 | // SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_TX_RIGHT_FIRST_S); //Seem ignored in parallel mode 186 | // SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_SHORT_SYNC_S); //Seem ignored in parallel mode 187 | 188 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), 0x1, 1, I2S_DSCR_EN_S); 189 | 190 | #ifdef MANYBITS 191 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_TX_FIFO_MOD, 1, I2S_TX_FIFO_MOD_S); 192 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), 0x1, 1, I2S_TX_FIFO_MOD_FORCE_EN_S); 193 | SET_PERI_REG_BITS(I2S_CONF_CHAN_REG(0), I2S_TX_CHAN_MOD, 1, I2S_TX_CHAN_MOD_S); 194 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_TX_BITS_MOD, 8, I2S_TX_BITS_MOD_S); 195 | #else 196 | //I think is needed? I don't know!!! 197 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_TX_FIFO_MOD, 1, I2S_TX_FIFO_MOD_S); 198 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), 0x1, 1, I2S_TX_FIFO_MOD_FORCE_EN_S); 199 | SET_PERI_REG_BITS(I2S_CONF_CHAN_REG(0), I2S_TX_CHAN_MOD, 1, I2S_TX_CHAN_MOD_S); 200 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_TX_BITS_MOD, 16, I2S_TX_BITS_MOD_S); 201 | #endif 202 | 203 | //If you don't do this, BCK will be limited to 13.3333 MHz. 204 | 205 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_TX_BCK_DIV_NUM, 4, I2S_TX_BCK_DIV_NUM_S); 206 | //Once set, 1 = you can read all 8 bits at 40 MHz. 207 | //Once set, 2 = you can read all 8 bits at 20 MHz. 208 | // 3 = 13.33333 MHz 209 | // 4 = 10.0MHz 210 | 211 | 212 | //When self-clocked, seem to make BCK rate ~13.3333 MHz. 213 | #endif 214 | 215 | WRITE_PERI_REG(I2S_CONF2_REG(0), 0 ); 216 | 217 | 218 | // SET_PERI_REG_BITS(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PU_V, 1, RTC_CNTL_PLLA_FORCE_PU_S); 219 | rtc_clk_apll_enable(1, 0, 0, 8, 0); 220 | 221 | 222 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_TX_BITS_MOD_V, 32, I2S_TX_BITS_MOD_S); 223 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_TX_BCK_DIV_NUM_V, 1, I2S_TX_BCK_DIV_NUM_S); 224 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_RX_BITS_MOD_V, 32, I2S_RX_BITS_MOD_S); 225 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_RX_BCK_DIV_NUM_V, 1, I2S_RX_BCK_DIV_NUM_S); 226 | 227 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKA_ENA_V, 0, I2S_CLKA_ENA_S); 228 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLK_EN_V, 1, I2S_CLK_EN_S); 229 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_A_V, 3, I2S_CLKM_DIV_A_S); 230 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_B_V, 0, I2S_CLKM_DIV_B_S); //160 / ((13 1/3) ) 231 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_NUM_V, 2, I2S_CLKM_DIV_NUM_S); 232 | 233 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_TX_FIFO_MOD_V, 2, I2S_TX_FIFO_MOD_S); 234 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_TX_DATA_NUM_V, 1, I2S_TX_DATA_NUM_S); 235 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_RX_FIFO_MOD_V, 2, I2S_RX_FIFO_MOD_S); 236 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_RX_DATA_NUM_V, 1, I2S_RX_DATA_NUM_S); 237 | 238 | SET_PERI_REG_BITS(I2S_CONF_CHAN_REG(0), I2S_TX_CHAN_MOD_V, 1, I2S_TX_CHAN_MOD_S); //DDR (dual-channel) mode 239 | SET_PERI_REG_BITS(I2S_CONF_CHAN_REG(0), I2S_RX_CHAN_MOD_V, 1, I2S_RX_CHAN_MOD_S); 240 | 241 | SET_PERI_REG_BITS(I2S_CONF1_REG(0), I2S_TX_STOP_EN_V, 1, I2S_TX_STOP_EN_S); 242 | SET_PERI_REG_BITS(I2S_CONF1_REG(0), I2S_TX_PCM_BYPASS_V, 1, I2S_TX_PCM_BYPASS_S); 243 | 244 | SET_PERI_REG_BITS(I2S_CONF_REG(0), I2S_TX_RIGHT_FIRST_V, 1, I2S_TX_RIGHT_FIRST_S); 245 | SET_PERI_REG_BITS(I2S_CONF_REG(0), I2S_RX_RIGHT_FIRST_V, 1, I2S_RX_RIGHT_FIRST_S); 246 | 247 | WRITE_PERI_REG( I2S_TIMING_REG(0), 0 ); 248 | // I2S0.TIMING.val=0; 249 | 250 | } 251 | 252 | static void i2s_fill_buf_fast() { 253 | #if 1 254 | ESP_INTR_DISABLE(ETS_I2S0_INUM); 255 | 256 | SET_PERI_REG_BITS(I2S_OUT_LINK_REG(0), I2S_OUTLINK_ADDR_V, ((uint32_t) &s_dma_desc), I2S_OUTLINK_ADDR_S); 257 | SET_PERI_REG_BITS(I2S_OUT_LINK_REG(0), I2S_OUTLINK_START_V, 1, I2S_OUTLINK_START_S); 258 | 259 | REG_WRITE(I2S_INT_CLR_REG(0), (REG_READ(I2S_INT_RAW_REG(0)) & 0xffffffc0) | 0x3f); 260 | 261 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_DSCR_EN_V, 1, I2S_DSCR_EN_S); 262 | 263 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), I2S_OUT_DATA_BURST_EN_V, 1, I2S_OUT_DATA_BURST_EN_S); 264 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), I2S_CHECK_OWNER_V, 1, I2S_CHECK_OWNER_S); 265 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), I2S_OUT_EOF_MODE_V, 1, I2S_OUT_EOF_MODE_S); 266 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), I2S_OUTDSCR_BURST_EN_V, 1, I2S_OUTDSCR_BURST_EN_S); 267 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), I2S_OUT_DATA_BURST_EN_V, 1, I2S_OUT_DATA_BURST_EN_S); 268 | 269 | 270 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 271 | (void) REG_READ(I2S_CONF_REG(0)); 272 | REG_WRITE(I2S_CONF_REG(0), (REG_READ(I2S_CONF_REG(0)) & 0xfffffff0) | 0xf); 273 | (void) REG_READ(I2S_CONF_REG(0)); 274 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 275 | while (GET_PERI_REG_BITS2(I2S_STATE_REG(0), 0x1, I2S_TX_FIFO_RESET_BACK_S)); 276 | 277 | 278 | SET_PERI_REG_BITS(I2S_INT_ENA_REG(0), I2S_OUT_DONE_INT_ENA_V, 1, I2S_OUT_DONE_INT_ENA_S); 279 | // ESP_INTR_ENABLE(ETS_I2S0_INUM); 280 | 281 | SET_PERI_REG_BITS(I2S_CONF_REG(0), I2S_TX_START_V, 1,I2S_TX_START_S); 282 | 283 | #else 284 | ESP_INTR_DISABLE(ETS_I2S0_INUM); 285 | 286 | SET_PERI_REG_BITS(I2S_OUT_LINK_REG(0), I2S_OUTLINK_ADDR_V, ((uint32_t) &s_dma_desc), I2S_OUTLINK_ADDR_S); 287 | SET_PERI_REG_BITS(I2S_OUT_LINK_REG(0), I2S_OUTLINK_START_V, 1, I2S_OUTLINK_START_S); 288 | 289 | REG_WRITE(I2S_INT_CLR_REG(0), (REG_READ(I2S_INT_RAW_REG(0)) & 0xffffffc0) | 0x3f); 290 | 291 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 292 | (void) REG_READ(I2S_CONF_REG(0)); 293 | REG_WRITE(I2S_CONF_REG(0), (REG_READ(I2S_CONF_REG(0)) & 0xfffffff0) | 0xf); 294 | (void) REG_READ(I2S_CONF_REG(0)); 295 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 296 | while (GET_PERI_REG_BITS2(I2S_STATE_REG(0), 0x1, I2S_TX_FIFO_RESET_BACK_S)); 297 | 298 | SET_PERI_REG_BITS(I2S_INT_ENA_REG(0), 0x1, 1, I2S_OUT_DONE_INT_ENA_S); 299 | ESP_INTR_ENABLE(ETS_I2S0_INUM); 300 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_START_S); 301 | #endif 302 | } 303 | 304 | /* 305 | static void i2s_stop() { 306 | ESP_INTR_DISABLE(ETS_I2S0_INUM); 307 | 308 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 309 | (void) REG_READ(I2S_CONF_REG(0)); 310 | REG_WRITE(I2S_CONF_REG(0), (REG_READ(I2S_CONF_REG(0)) & 0xfffffff0) | 0xf); 311 | (void) REG_READ(I2S_CONF_REG(0)); 312 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 313 | 314 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_RX_START_S); 315 | i2s_running = false; 316 | } 317 | */ 318 | 319 | void TickI2SOut_fast() 320 | { 321 | i2s_run_fast(); 322 | } 323 | 324 | static void i2s_run_fast() 325 | { 326 | // wait for vsync 327 | //ESP_LOGD(TAG, "Waiting for VSYNC"); 328 | //while(gpio_get_level(s_config.pin_vsync) != 0); 329 | //while(gpio_get_level(s_config.pin_vsync) == 0); 330 | ///ESP_LOGD(TAG, "Got VSYNC"); 331 | // wait a bit 332 | //delay(2); 333 | 334 | // start RX 335 | // line_count = 0; 336 | isr_countOut = 0; 337 | i2s_running = true; 338 | i2s_fill_buf_fast(0); 339 | } 340 | 341 | static void IRAM_ATTR i2s_isr_fast(void* arg) { 342 | REG_WRITE(I2S_INT_CLR_REG(0), (REG_READ(I2S_INT_RAW_REG(0)) & 0xffffffc0) | 0x3f); 343 | ++isr_countOut; 344 | } 345 | 346 | -------------------------------------------------------------------------------- /main/i2s_stream_fast.h: -------------------------------------------------------------------------------- 1 | #ifndef _I2S_STREAM_FAST_H 2 | #define _I2S_STREAM_FAST_H 3 | 4 | 5 | #define BUFF_SIZE_BYTES 2048 6 | 7 | extern volatile unsigned isr_countOut_fast; 8 | extern uint32_t * i2sbufferOut_fast[3]; 9 | 10 | void SetupI2SOut_fast(); 11 | void TickI2SOut_fast(); 12 | 13 | #endif 14 | 15 | -------------------------------------------------------------------------------- /main/i2s_stream_in.c: -------------------------------------------------------------------------------- 1 | //Almost entirelly lifted directly from https://github.com/igrr/esp32-cam-demo 2 | //Just clocked a little differently and has chained buffers. 3 | //This totes works with the I2S bus on the ESP32 for READING 16 wires simultaneously. 4 | //Can be clocked off of I2S's internal controller or an external clock. 5 | 6 | #define I2S_D0 4 7 | #define I2S_D1 5 8 | #define I2S_D2 18 9 | #define I2S_D3 19 10 | #define I2S_D4 36 11 | #define I2S_D5 39 12 | #define I2S_D6 34 13 | #define I2S_D7 35 14 | 15 | #define I2S_D8 32 16 | #define I2S_D9 33 17 | #define I2S_D10 25 18 | #define I2S_D11 26 19 | #define I2S_D12 27 20 | #define I2S_D13 14 21 | #define I2S_D14 12 22 | #define I2S_D15 13 23 | 24 | #define I2S_CLK 22 25 | //#define I2S_CLKO 13 26 | //#define I2S_CLKOWS 2 27 | 28 | #define I2S_HZ 10000000 29 | //#define I2S_HZ 1000000 30 | 31 | 32 | 33 | #include "esp_intr.h" 34 | #include "i2s_stream_in.h" 35 | #include "driver/gpio.h" 36 | #include "soc/gpio_sig_map.h" 37 | #include "soc/i2s_reg.h" 38 | #include "soc/io_mux_reg.h" 39 | #include "driver/gpio.h" 40 | #include "driver/periph_ctrl.h" 41 | #include "rom/lldesc.h" 42 | #include "esp_log.h" 43 | #include "driver/ledc.h" 44 | #include 45 | 46 | #define ETS_I2S0_INUM 13 47 | 48 | static void IRAM_ATTR i2s_isr(void* arg); 49 | static esp_err_t dma_desc_init(); 50 | static void i2s_init(); 51 | static void i2s_run(); 52 | static void enable_out_clock(); 53 | 54 | 55 | uint16_t * i2sbufferIn[2] __attribute__((aligned(128))); 56 | static lldesc_t s_dma_desc[2]; 57 | static int i2s_running; 58 | volatile unsigned isr_countIn; 59 | 60 | 61 | void SetupI2SIn() 62 | { 63 | enable_out_clock(); 64 | i2s_init(); 65 | dma_desc_init(); 66 | i2s_run(); 67 | } 68 | 69 | 70 | static esp_err_t dma_desc_init() 71 | { 72 | for (int i = 0; i < 2; ++i) { 73 | i2sbufferIn[i] = malloc( BUFF_SIZE_BYTES ); 74 | s_dma_desc[i].length = BUFF_SIZE_BYTES; // size of a single DMA buf 75 | s_dma_desc[i].size = BUFF_SIZE_BYTES; // total size of the chain 76 | s_dma_desc[i].owner = 1; 77 | s_dma_desc[i].sosf = 1; 78 | s_dma_desc[i].buf = (uint8_t*) i2sbufferIn[i]; 79 | s_dma_desc[i].offset = i; 80 | s_dma_desc[i].empty = 0; 81 | s_dma_desc[i].eof = 1; 82 | s_dma_desc[i].qe.stqe_next = &s_dma_desc[(i+1)&1]; 83 | } 84 | return ESP_OK; 85 | } 86 | 87 | 88 | static void enable_out_clock() { 89 | periph_module_enable(PERIPH_LEDC_MODULE); 90 | 91 | ledc_timer_config_t timer_conf; 92 | timer_conf.bit_num = 3; 93 | timer_conf.freq_hz = I2S_HZ; 94 | timer_conf.speed_mode = LEDC_HIGH_SPEED_MODE; 95 | timer_conf.timer_num = LEDC_TIMER_0; 96 | esp_err_t err = ledc_timer_config(&timer_conf); 97 | if (err != ESP_OK) { 98 | //ESP_LOGE(TAG, "ledc_timer_config failed, rc=%x", err); 99 | } 100 | 101 | ledc_channel_config_t ch_conf; 102 | ch_conf.channel = LEDC_CHANNEL_0; 103 | ch_conf.timer_sel = LEDC_TIMER_0; 104 | ch_conf.intr_type = LEDC_INTR_DISABLE; 105 | ch_conf.duty = 4; 106 | ch_conf.speed_mode = LEDC_HIGH_SPEED_MODE; 107 | ch_conf.gpio_num = 17; //s_config.pin_xclk; 108 | err = ledc_channel_config(&ch_conf); 109 | if (err != ESP_OK) { 110 | //ESP_LOGE(TAG, "ledc_channel_config failed, rc=%x", err); 111 | } 112 | 113 | } 114 | 115 | 116 | static void i2s_init() 117 | { 118 | xt_set_interrupt_handler(ETS_I2S0_INUM, &i2s_isr, NULL); 119 | intr_matrix_set(0, ETS_I2S0_INTR_SOURCE, ETS_I2S0_INUM); 120 | 121 | gpio_num_t pins[] = { 122 | I2S_D15, 123 | I2S_D14, 124 | I2S_D13, 125 | I2S_D12, 126 | I2S_D11, 127 | I2S_D10, 128 | I2S_D9, 129 | I2S_D8, 130 | 131 | I2S_D7, 132 | I2S_D6, 133 | I2S_D5, 134 | I2S_D4, 135 | I2S_D3, 136 | I2S_D2, 137 | I2S_D1, 138 | I2S_D0, 139 | I2S_CLK, 140 | }; 141 | 142 | gpio_config_t conf = { 143 | .mode = GPIO_MODE_INPUT, 144 | .pull_up_en = GPIO_PULLUP_DISABLE, 145 | .pull_down_en = GPIO_PULLDOWN_DISABLE, 146 | .intr_type = GPIO_INTR_DISABLE 147 | }; 148 | for (int i = 0; i < sizeof(pins)/sizeof(gpio_num_t); ++i) { 149 | conf.pin_bit_mask = 1LL << pins[i]; 150 | gpio_config(&conf); 151 | } 152 | 153 | gpio_matrix_in(I2S_D0, I2S0I_DATA_IN0_IDX, false); 154 | gpio_matrix_in(I2S_D1, I2S0I_DATA_IN1_IDX, false); 155 | gpio_matrix_in(I2S_D2, I2S0I_DATA_IN2_IDX, false); 156 | gpio_matrix_in(I2S_D3, I2S0I_DATA_IN3_IDX, false); 157 | gpio_matrix_in(I2S_D4, I2S0I_DATA_IN4_IDX, false); 158 | gpio_matrix_in(I2S_D5, I2S0I_DATA_IN5_IDX, false); 159 | gpio_matrix_in(I2S_D6, I2S0I_DATA_IN6_IDX, false); 160 | gpio_matrix_in(I2S_D7, I2S0I_DATA_IN7_IDX, false); 161 | 162 | gpio_matrix_in(I2S_D8, I2S0I_DATA_IN8_IDX, false); 163 | gpio_matrix_in(I2S_D9, I2S0I_DATA_IN9_IDX, false); 164 | gpio_matrix_in(I2S_D10, I2S0I_DATA_IN10_IDX, false); 165 | gpio_matrix_in(I2S_D11, I2S0I_DATA_IN11_IDX, false); 166 | gpio_matrix_in(I2S_D12, I2S0I_DATA_IN12_IDX, false); 167 | gpio_matrix_in(I2S_D13, I2S0I_DATA_IN13_IDX, false); 168 | gpio_matrix_in(I2S_D14, I2S0I_DATA_IN14_IDX, false); 169 | gpio_matrix_in(I2S_D15, I2S0I_DATA_IN15_IDX, false); 170 | 171 | //This magic is needed to enable the bus! 172 | gpio_matrix_in(0x38, I2S0I_V_SYNC_IDX, false); 173 | gpio_matrix_in(0x38, I2S0I_H_SYNC_IDX, false); 174 | gpio_matrix_in(0x38, I2S0I_H_ENABLE_IDX, false); 175 | 176 | //Whether the bus is self-clocking, or accepting an external clock. 177 | #define SLAVE_MOD 0 178 | 179 | #if SLAVE_MOD 180 | gpio_matrix_in(I2S_CLK, I2S0I_WS_IN_IDX, false); 181 | 182 | // gpio_matrix_in(I2S_CLKO, I2S0O_BCK_OUT_IDX, false); 183 | // gpio_matrix_in(I2S_CLKOWS, I2S0O_WS_OUT_IDX, false); 184 | 185 | #else 186 | 187 | conf.mode = GPIO_MODE_OUTPUT; 188 | conf.pin_bit_mask = 1LL << I2S_CLK; 189 | gpio_config(&conf); 190 | gpio_matrix_out(I2S_CLK, I2S0I_BCK_OUT_IDX, false, 0 ); 191 | 192 | #endif 193 | periph_module_enable(PERIPH_I2S0_MODULE); 194 | 195 | 196 | 197 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 1, I2S_IN_RST_S); 198 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 0, I2S_IN_RST_S); 199 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 1, I2S_AHBM_RST_S); 200 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 0, I2S_AHBM_RST_S); 201 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 1, I2S_AHBM_FIFO_RST_S); 202 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 0, I2S_AHBM_FIFO_RST_S); 203 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_RX_RESET_S); 204 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_RX_RESET_S); 205 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_RX_FIFO_RESET_S); 206 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_RX_FIFO_RESET_S); 207 | 208 | 209 | #if SLAVE_MOD 210 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_RX_SLAVE_MOD_S); 211 | #else 212 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_RX_SLAVE_MOD_S); 213 | #endif 214 | SET_PERI_REG_BITS(I2S_CONF2_REG(0), 0x1, 1, I2S_LCD_EN_S); 215 | SET_PERI_REG_BITS(I2S_CONF2_REG(0), 0x1, 1, I2S_CAMERA_EN_S); 216 | 217 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_A, 0, I2S_CLKM_DIV_A_S); 218 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_B, 0, I2S_CLKM_DIV_B_S); 219 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_NUM, 1, I2S_CLKM_DIV_NUM_S); //Setting to 0 wrecks it up. 220 | 221 | 222 | 223 | //This seems ignored in slave mode. 224 | // WRITE_PERI_REG( I2S_TIMING_REG(0), 0xffffffff ); 225 | // WRITE_PERI_REG( I2S_CONF_SIGLE_DATA_REG(0), 0xffffffff ); 226 | // SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_RX_SHORT_SYNC_S); // 227 | // SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_RX_BCK_DIV_NUM, 1, I2S_RX_BCK_DIV_NUM_S); 228 | 229 | 230 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), 0x1, 1, I2S_DSCR_EN_S); 231 | 232 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_RX_RIGHT_FIRST_S); //Seem ignored in parallel mode 233 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_RX_MSB_RIGHT_S);//Seem ignored in parallel mode 234 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_RX_MSB_SHIFT_S);//Seem ignored in parallel mode 235 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_RX_MONO_S); 236 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_RX_SHORT_SYNC_S); //Seem ignored in parallel mode 237 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_RX_FIFO_MOD, 1, I2S_RX_FIFO_MOD_S); 238 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), 0x1, 1, I2S_RX_FIFO_MOD_FORCE_EN_S); 239 | SET_PERI_REG_BITS(I2S_CONF_CHAN_REG(0), I2S_RX_CHAN_MOD, 1, I2S_RX_CHAN_MOD_S); 240 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_RX_BITS_MOD, 8, I2S_RX_BITS_MOD_S); 241 | 242 | //If you don't do this, BCK will be limited to 13.3333 MHz. 243 | 244 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_RX_BCK_DIV_NUM, 1, I2S_RX_BCK_DIV_NUM_S); 245 | //Once set, 1 = you can read all 8 bits at 40 MHz. 246 | //Once set, 2 = you can read all 8 bits at 20 MHz. 247 | // 3 = 13.33333 MHz 248 | // 4 = 10.0MHz 249 | 250 | 251 | //When self-clocked, seem to make BCK rate ~13.3333 MHz. 252 | 253 | 254 | } 255 | 256 | static void i2s_fill_buf() { 257 | ESP_INTR_DISABLE(ETS_I2S0_INUM); 258 | 259 | SET_PERI_REG_BITS(I2S_RXEOF_NUM_REG(0), I2S_RX_EOF_NUM, (BUFF_SIZE_BYTES - 8) / 2, I2S_RX_EOF_NUM_S); 260 | SET_PERI_REG_BITS(I2S_IN_LINK_REG(0), I2S_INLINK_ADDR, ((uint32_t) &s_dma_desc), I2S_INLINK_ADDR_S); 261 | SET_PERI_REG_BITS(I2S_IN_LINK_REG(0), 0x1, 1, I2S_INLINK_START_S); 262 | 263 | REG_WRITE(I2S_INT_CLR_REG(0), (REG_READ(I2S_INT_RAW_REG(0)) & 0xffffffc0) | 0x3f); 264 | 265 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 266 | (void) REG_READ(I2S_CONF_REG(0)); 267 | REG_WRITE(I2S_CONF_REG(0), (REG_READ(I2S_CONF_REG(0)) & 0xfffffff0) | 0xf); 268 | (void) REG_READ(I2S_CONF_REG(0)); 269 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 270 | while (GET_PERI_REG_BITS2(I2S_STATE_REG(0), 0x1, I2S_TX_FIFO_RESET_BACK_S)); 271 | 272 | SET_PERI_REG_BITS(I2S_INT_ENA_REG(0), 0x1, 1, I2S_IN_DONE_INT_ENA_S); 273 | ESP_INTR_ENABLE(ETS_I2S0_INUM); 274 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_RX_START_S); 275 | } 276 | 277 | /* 278 | static void i2s_stop() { 279 | ESP_INTR_DISABLE(ETS_I2S0_INUM); 280 | 281 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 282 | (void) REG_READ(I2S_CONF_REG(0)); 283 | REG_WRITE(I2S_CONF_REG(0), (REG_READ(I2S_CONF_REG(0)) & 0xfffffff0) | 0xf); 284 | (void) REG_READ(I2S_CONF_REG(0)); 285 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 286 | 287 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_RX_START_S); 288 | i2s_running = false; 289 | } 290 | */ 291 | 292 | void TickI2SIn() 293 | { 294 | i2s_run(); 295 | } 296 | 297 | static void i2s_run() 298 | { 299 | // wait for vsync 300 | //ESP_LOGD(TAG, "Waiting for VSYNC"); 301 | //while(gpio_get_level(s_config.pin_vsync) != 0); 302 | //while(gpio_get_level(s_config.pin_vsync) == 0); 303 | ///ESP_LOGD(TAG, "Got VSYNC"); 304 | // wait a bit 305 | //delay(2); 306 | 307 | // start RX 308 | // line_count = 0; 309 | isr_countIn = 0; 310 | i2s_running = true; 311 | i2s_fill_buf(0); 312 | } 313 | 314 | static void IRAM_ATTR i2s_isr(void* arg) { 315 | REG_WRITE(I2S_INT_CLR_REG(0), (REG_READ(I2S_INT_RAW_REG(0)) & 0xffffffc0) | 0x3f); 316 | ++isr_countIn; 317 | } 318 | 319 | -------------------------------------------------------------------------------- /main/i2s_stream_in.h: -------------------------------------------------------------------------------- 1 | #ifndef _I2S_STREAM_H 2 | #define _I2S_STREAM_H 3 | 4 | 5 | #define BUFF_SIZE_BYTES 2048 6 | 7 | extern volatile unsigned isr_countIn; 8 | extern uint16_t * i2sbufferIn[2] __attribute__((aligned(128))); 9 | 10 | void SetupI2SIn(); 11 | void TickI2SIn(); 12 | 13 | #endif 14 | 15 | -------------------------------------------------------------------------------- /main/i2s_stream_out.c: -------------------------------------------------------------------------------- 1 | //This is for ONE BIT SHIFT REGISTER OUTPUT 2 | 3 | //Parts from: from https://github.com/pewit-tech/esp32-i2s/blob/master/i2s_freertos.c 4 | 5 | 6 | //Almost entirelly lifted directly from https://github.com/igrr/esp32-cam-demo 7 | //Just clocked a little differently and has chained buffers. 8 | //This totes works with the I2S bus on the ESP32 for READING 16 wires simultaneously. 9 | //Can be clocked off of I2S's internal controller or an external clock. 10 | 11 | 12 | #define I2S_CLK 22 13 | //#define I2S_CLKO 13 14 | //#define I2S_CLKOWS 2 15 | 16 | #define MANYBITS 17 | 18 | #ifdef MANYBITS 19 | 20 | #define I2S_D0 4 21 | #define I2S_D1 5 22 | #define I2S_D2 15 23 | #define I2S_D3 14 24 | #define I2S_D4 15 25 | #define I2S_D5 3 26 | #define I2S_D6 14 27 | #define I2S_D7 12 28 | 29 | #define I2S_D8 18 30 | #define I2S_D9 19 31 | #define I2S_D10 25 32 | #define I2S_D11 26 33 | #define I2S_D12 27 34 | #define I2S_D13 10 35 | #define I2S_D14 12 36 | #define I2S_D15 13 37 | 38 | #define I2S_D23 20 39 | #endif 40 | 41 | 42 | 43 | #include "esp_intr.h" 44 | #include "i2s_stream_out.h" 45 | #include "driver/gpio.h" 46 | #include "soc/gpio_sig_map.h" 47 | #include "soc/i2s_reg.h" 48 | #include "soc/io_mux_reg.h" 49 | #include "driver/gpio.h" 50 | #include "driver/periph_ctrl.h" 51 | #include "rom/lldesc.h" 52 | #include "esp_log.h" 53 | #include "driver/ledc.h" 54 | #include 55 | 56 | #define ETS_I2S0_INUM 13 57 | 58 | static void IRAM_ATTR i2s_isr(void* arg); 59 | static esp_err_t dma_desc_init(); 60 | static void i2s_init(); 61 | static void i2s_run(); 62 | static void enable_out_clock(); 63 | 64 | 65 | uint32_t * i2sbufferOut[3] __attribute__((aligned(128))); 66 | static lldesc_t s_dma_desc[3]; 67 | static int i2s_running; 68 | volatile unsigned isr_countOut; 69 | 70 | 71 | void SetupI2SOut() 72 | { 73 | // enable_out_clock(); 74 | i2s_init(); 75 | dma_desc_init(); 76 | i2s_run(); 77 | } 78 | 79 | 80 | static esp_err_t dma_desc_init() 81 | { 82 | for (int i = 0; i < 3; ++i) { 83 | i2sbufferOut[i] = malloc( BUFF_SIZE_BYTES ); 84 | s_dma_desc[i].length = BUFF_SIZE_BYTES; // size of a single DMA buf 85 | s_dma_desc[i].size = BUFF_SIZE_BYTES; // total size of the chain 86 | s_dma_desc[i].owner = 1; 87 | s_dma_desc[i].sosf = 1; 88 | s_dma_desc[i].buf = (uint8_t*) i2sbufferOut[i]; 89 | s_dma_desc[i].offset = i; 90 | s_dma_desc[i].empty = 0; 91 | s_dma_desc[i].eof = 1; 92 | s_dma_desc[i].qe.stqe_next = &s_dma_desc[(i+1)%3]; 93 | int k; 94 | for( k = 0; k < BUFF_SIZE_BYTES/4; k++ ) 95 | { 96 | // i2sbufferOut[i][k] = (k&1)?0x0000FfFF:0xaaaaaaaa; 97 | i2sbufferOut[i][k] = (k&1)?0x0001fffe:0x0001fffe; 98 | } 99 | } 100 | return ESP_OK; 101 | } 102 | 103 | /* 104 | static void enable_out_clock() { 105 | periph_module_enable(PERIPH_LEDC_MODULE); 106 | 107 | ledc_timer_config_t timer_conf; 108 | timer_conf.bit_num = 3; 109 | timer_conf.freq_hz = I2S_HZ; 110 | timer_conf.speed_mode = LEDC_HIGH_SPEED_MODE; 111 | timer_conf.timer_num = LEDC_TIMER_0; 112 | esp_err_t err = ledc_timer_config(&timer_conf); 113 | if (err != ESP_OK) { 114 | //ESP_LOGE(TAG, "ledc_timer_config failed, rc=%x", err); 115 | } 116 | 117 | ledc_channel_config_t ch_conf; 118 | ch_conf.channel = LEDC_CHANNEL_0; 119 | ch_conf.timer_sel = LEDC_TIMER_0; 120 | ch_conf.intr_type = LEDC_INTR_DISABLE; 121 | ch_conf.duty = 4; 122 | ch_conf.speed_mode = LEDC_HIGH_SPEED_MODE; 123 | ch_conf.gpio_num = 17; //s_config.pin_xclk; 124 | err = ledc_channel_config(&ch_conf); 125 | if (err != ESP_OK) { 126 | //ESP_LOGE(TAG, "ledc_channel_config failed, rc=%x", err); 127 | } 128 | 129 | } 130 | */ 131 | 132 | static void i2s_init() 133 | { 134 | xt_set_interrupt_handler(ETS_I2S0_INUM, &i2s_isr, NULL); 135 | intr_matrix_set(0, ETS_I2S0_INTR_SOURCE, ETS_I2S0_INUM); 136 | 137 | #ifdef MANYBITS 138 | 139 | gpio_num_t pins[] = { 140 | I2S_D15, 141 | I2S_D14, 142 | I2S_D13, 143 | I2S_D12, 144 | I2S_D11, 145 | I2S_D10, 146 | I2S_D9, 147 | I2S_D8, 148 | 149 | I2S_D7, 150 | I2S_D6, 151 | I2S_D5, 152 | I2S_D4, 153 | I2S_D3, 154 | I2S_D2, 155 | I2S_D1, 156 | I2S_D0, 157 | 16,17 158 | }; 159 | 160 | #else 161 | gpio_num_t pins[] = { 162 | 17, 163 | 18, 164 | 19, 165 | }; 166 | #endif 167 | 168 | gpio_config_t conf = { 169 | .mode = GPIO_MODE_OUTPUT, 170 | .pull_up_en = GPIO_PULLUP_DISABLE, 171 | .pull_down_en = GPIO_PULLDOWN_DISABLE, 172 | .intr_type = GPIO_INTR_DISABLE 173 | }; 174 | for (int i = 0; i < sizeof(pins)/sizeof(gpio_num_t); ++i) { 175 | conf.pin_bit_mask = 1LL << pins[i]; 176 | gpio_config(&conf); 177 | } 178 | 179 | #ifdef MANYBITS 180 | gpio_matrix_out(I2S_D0, I2S0O_DATA_OUT0_IDX, false,false); 181 | gpio_matrix_out(I2S_D1, I2S0O_DATA_OUT1_IDX, false,false); 182 | gpio_matrix_out(I2S_D2, I2S0O_DATA_OUT2_IDX, false,false); 183 | gpio_matrix_out(I2S_D3, I2S0O_DATA_OUT3_IDX, false,false); 184 | gpio_matrix_out(I2S_D4, I2S0O_DATA_OUT4_IDX, false,false); 185 | gpio_matrix_out(I2S_D5, I2S0O_DATA_OUT5_IDX, false,false); 186 | gpio_matrix_out(I2S_D6, I2S0O_DATA_OUT6_IDX, false,false); 187 | gpio_matrix_out(I2S_D7, I2S0O_DATA_OUT7_IDX, false,false); 188 | 189 | gpio_matrix_out(I2S_D8, I2S0O_DATA_OUT8_IDX, false,false); 190 | gpio_matrix_out(I2S_D9, I2S0O_DATA_OUT9_IDX, false,false); 191 | gpio_matrix_out(I2S_D10, I2S0O_DATA_OUT10_IDX, false,false); 192 | gpio_matrix_out(I2S_D11, I2S0O_DATA_OUT11_IDX, false,false); 193 | gpio_matrix_out(I2S_D12, I2S0O_DATA_OUT12_IDX, false,false); 194 | gpio_matrix_out(I2S_D13, I2S0O_DATA_OUT13_IDX, false,false); 195 | gpio_matrix_out(I2S_D14, I2S0O_DATA_OUT14_IDX, false,false); 196 | gpio_matrix_out(I2S_D15, I2S0O_DATA_OUT15_IDX, false,false); 197 | gpio_matrix_out(GPIO_NUM_16, I2S0O_BCK_OUT_IDX, 0, 0); 198 | gpio_matrix_out(I2S_D23, I2S0O_DATA_OUT23_IDX, false,false); 199 | gpio_matrix_out(GPIO_NUM_17, I2S0O_WS_OUT_IDX, 0, 0); 200 | #else 201 | gpio_matrix_out(GPIO_NUM_17, I2S0O_DATA_OUT23_IDX, 0, 0); 202 | gpio_matrix_out(GPIO_NUM_19, I2S0O_BCK_OUT_IDX, 0, 0); 203 | gpio_matrix_out(GPIO_NUM_18, I2S0O_WS_OUT_IDX, 0, 0); 204 | #endif 205 | 206 | 207 | //This magic is needed to enable the bus! 208 | // gpio_matrix_in(0x38, I2S0I_V_SYNC_IDX, false); 209 | // gpio_matrix_in(0x38, I2S0I_H_SYNC_IDX, false); 210 | // gpio_matrix_in(0x38, I2S0I_H_ENABLE_IDX, false); 211 | 212 | //Whether the bus is self-clocking, or accepting an external clock. 213 | periph_module_enable(PERIPH_I2S0_MODULE); 214 | 215 | 216 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 1, I2S_IN_RST_S); 217 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 0, I2S_IN_RST_S); 218 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 1, I2S_AHBM_RST_S); 219 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 0, I2S_AHBM_RST_S); 220 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 1, I2S_AHBM_FIFO_RST_S); 221 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 0, I2S_AHBM_FIFO_RST_S); 222 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_RESET_S); 223 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_TX_RESET_S); 224 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_FIFO_RESET_S); 225 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_TX_FIFO_RESET_S); 226 | 227 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_TX_SLAVE_MOD_S); //Needed, otherwise it waits for a clock. 228 | // SET_PERI_REG_MASK(I2S_CONF_REG(0), I2S_TX_MSB_SHIFT); 229 | // WRITE_PERI_REG(I2S_CONF2_REG(0), 0); 230 | 231 | #if 0 232 | 233 | #ifdef MANYBITS 234 | SET_PERI_REG_BITS(I2S_CONF2_REG(0), I2S_LCD_EN, 1, I2S_LCD_EN_S); 235 | SET_PERI_REG_BITS(I2S_CONF1_REG(0), I2S_TX_PCM_BYPASS, 1, I2S_TX_PCM_BYPASS_S); //Breaks everything 236 | // SET_PERI_REG_BITS(I2S_CONF2_REG(0), 0x1, 1, I2S_CAMERA_EN_S); 237 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_A, 0, I2S_CLKM_DIV_A_S); 238 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_B, 0, I2S_CLKM_DIV_B_S); 239 | 240 | #else 241 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_A, 1, I2S_CLKM_DIV_A_S); 242 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_B, 0, I2S_CLKM_DIV_B_S); 243 | 244 | #endif 245 | 246 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_NUM, 15, I2S_CLKM_DIV_NUM_S); //Setting to 0 wrecks it up. 247 | 248 | 249 | //This seems ignored in slave mode. 250 | // WRITE_PERI_REG( I2S_TIMING_REG(0), 0xffffffff ); 251 | // WRITE_PERI_REG( I2S_CONF_SIGLE_DATA_REG(0), 0xffffffff ); 252 | // SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_RX_SHORT_SYNC_S); // 253 | // SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_RX_BCK_DIV_NUM, 1, I2S_RX_BCK_DIV_NUM_S); 254 | 255 | #ifdef MANYBITS 256 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_TX_MONO_S); 257 | #else 258 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_RIGHT_FIRST_S); //Seem ignored in parallel mode 259 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_MSB_RIGHT_S);//Seem ignored in parallel mode 260 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_MSB_SHIFT_S);//Seem ignored in parallel mode 261 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_MONO_S); 262 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_SHORT_SYNC_S); //Seem ignored in parallel mode 263 | 264 | #endif 265 | // SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_MONO_S); 266 | // SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_TX_RIGHT_FIRST_S); //Seem ignored in parallel mode 267 | // SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_SHORT_SYNC_S); //Seem ignored in parallel mode 268 | 269 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), 0x1, 1, I2S_DSCR_EN_S); 270 | 271 | #ifdef MANYBITS 272 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_TX_FIFO_MOD, 1, I2S_TX_FIFO_MOD_S); 273 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), 0x1, 1, I2S_TX_FIFO_MOD_FORCE_EN_S); 274 | SET_PERI_REG_BITS(I2S_CONF_CHAN_REG(0), I2S_TX_CHAN_MOD, 1, I2S_TX_CHAN_MOD_S); 275 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_TX_BITS_MOD, 8, I2S_TX_BITS_MOD_S); 276 | #else 277 | //I think is needed? I don't know!!! 278 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_TX_FIFO_MOD, 1, I2S_TX_FIFO_MOD_S); 279 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), 0x1, 1, I2S_TX_FIFO_MOD_FORCE_EN_S); 280 | SET_PERI_REG_BITS(I2S_CONF_CHAN_REG(0), I2S_TX_CHAN_MOD, 1, I2S_TX_CHAN_MOD_S); 281 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_TX_BITS_MOD, 16, I2S_TX_BITS_MOD_S); 282 | #endif 283 | 284 | //If you don't do this, BCK will be limited to 13.3333 MHz. 285 | 286 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_TX_BCK_DIV_NUM, 4, I2S_TX_BCK_DIV_NUM_S); 287 | //Once set, 1 = you can read all 8 bits at 40 MHz. 288 | //Once set, 2 = you can read all 8 bits at 20 MHz. 289 | // 3 = 13.33333 MHz 290 | // 4 = 10.0MHz 291 | 292 | 293 | //When self-clocked, seem to make BCK rate ~13.3333 MHz. 294 | #endif 295 | 296 | WRITE_PERI_REG(I2S_CONF2_REG(0), 0 ); 297 | SET_PERI_REG_BITS(I2S_CONF2_REG(0), I2S_LCD_EN_V, 1, I2S_LCD_EN_S); 298 | 299 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_TX_BITS_MOD_V, 16, I2S_TX_BITS_MOD_S); 300 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_TX_BCK_DIV_NUM_V, 1, I2S_TX_BCK_DIV_NUM_S); 301 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_RX_BITS_MOD_V, 16, I2S_RX_BITS_MOD_S); 302 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_RX_BCK_DIV_NUM_V, 1, I2S_RX_BCK_DIV_NUM_S); 303 | 304 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKA_ENA_V, 1, I2S_CLKA_ENA_S); 305 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLK_EN_V, 1, I2S_CLK_EN_S); 306 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_A_V, 3, I2S_CLKM_DIV_A_S); 307 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_B_V, 1, I2S_CLKM_DIV_B_S); //160 / ((13 1/3) ) 308 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_NUM_V, 13, I2S_CLKM_DIV_NUM_S); 309 | 310 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_TX_FIFO_MOD_V, 0, I2S_TX_FIFO_MOD_S); 311 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_TX_DATA_NUM_V, 1, I2S_TX_DATA_NUM_S); 312 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_RX_FIFO_MOD_V, 0, I2S_RX_FIFO_MOD_S); 313 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_RX_DATA_NUM_V, 1, I2S_RX_DATA_NUM_S); 314 | 315 | SET_PERI_REG_BITS(I2S_CONF_CHAN_REG(0), I2S_TX_CHAN_MOD_V, 0, I2S_TX_CHAN_MOD_S); //DDR (dual-channel) mode 316 | SET_PERI_REG_BITS(I2S_CONF_CHAN_REG(0), I2S_RX_CHAN_MOD_V, 0, I2S_RX_CHAN_MOD_S); 317 | 318 | SET_PERI_REG_BITS(I2S_CONF1_REG(0), I2S_TX_STOP_EN_V, 1, I2S_TX_STOP_EN_S); 319 | SET_PERI_REG_BITS(I2S_CONF1_REG(0), I2S_TX_PCM_BYPASS_V, 1, I2S_TX_PCM_BYPASS_S); 320 | 321 | SET_PERI_REG_BITS(I2S_CONF_REG(0), I2S_TX_RIGHT_FIRST_V, 1, I2S_TX_RIGHT_FIRST_S); 322 | SET_PERI_REG_BITS(I2S_CONF_REG(0), I2S_RX_RIGHT_FIRST_V, 1, I2S_RX_RIGHT_FIRST_S); 323 | 324 | WRITE_PERI_REG( I2S_TIMING_REG(0), 0 ); 325 | // I2S0.TIMING.val=0; 326 | 327 | } 328 | 329 | static void i2s_fill_buf() { 330 | #if 1 331 | ESP_INTR_DISABLE(ETS_I2S0_INUM); 332 | 333 | SET_PERI_REG_BITS(I2S_OUT_LINK_REG(0), I2S_OUTLINK_ADDR_V, ((uint32_t) &s_dma_desc), I2S_OUTLINK_ADDR_S); 334 | SET_PERI_REG_BITS(I2S_OUT_LINK_REG(0), I2S_OUTLINK_START_V, 1, I2S_OUTLINK_START_S); 335 | 336 | REG_WRITE(I2S_INT_CLR_REG(0), (REG_READ(I2S_INT_RAW_REG(0)) & 0xffffffc0) | 0x3f); 337 | 338 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_DSCR_EN_V, 1, I2S_DSCR_EN_S); 339 | 340 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), I2S_OUT_DATA_BURST_EN_V, 1, I2S_OUT_DATA_BURST_EN_S); 341 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), I2S_CHECK_OWNER_V, 1, I2S_CHECK_OWNER_S); 342 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), I2S_OUT_EOF_MODE_V, 1, I2S_OUT_EOF_MODE_S); 343 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), I2S_OUTDSCR_BURST_EN_V, 1, I2S_OUTDSCR_BURST_EN_S); 344 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), I2S_OUT_DATA_BURST_EN_V, 1, I2S_OUT_DATA_BURST_EN_S); 345 | 346 | 347 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 348 | (void) REG_READ(I2S_CONF_REG(0)); 349 | REG_WRITE(I2S_CONF_REG(0), (REG_READ(I2S_CONF_REG(0)) & 0xfffffff0) | 0xf); 350 | (void) REG_READ(I2S_CONF_REG(0)); 351 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 352 | while (GET_PERI_REG_BITS2(I2S_STATE_REG(0), 0x1, I2S_TX_FIFO_RESET_BACK_S)); 353 | 354 | 355 | SET_PERI_REG_BITS(I2S_INT_ENA_REG(0), I2S_OUT_DONE_INT_ENA_V, 1, I2S_OUT_DONE_INT_ENA_S); 356 | // ESP_INTR_ENABLE(ETS_I2S0_INUM); 357 | 358 | SET_PERI_REG_BITS(I2S_CONF_REG(0), I2S_TX_START_V, 1,I2S_TX_START_S); 359 | 360 | #else 361 | ESP_INTR_DISABLE(ETS_I2S0_INUM); 362 | 363 | SET_PERI_REG_BITS(I2S_OUT_LINK_REG(0), I2S_OUTLINK_ADDR_V, ((uint32_t) &s_dma_desc), I2S_OUTLINK_ADDR_S); 364 | SET_PERI_REG_BITS(I2S_OUT_LINK_REG(0), I2S_OUTLINK_START_V, 1, I2S_OUTLINK_START_S); 365 | 366 | REG_WRITE(I2S_INT_CLR_REG(0), (REG_READ(I2S_INT_RAW_REG(0)) & 0xffffffc0) | 0x3f); 367 | 368 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 369 | (void) REG_READ(I2S_CONF_REG(0)); 370 | REG_WRITE(I2S_CONF_REG(0), (REG_READ(I2S_CONF_REG(0)) & 0xfffffff0) | 0xf); 371 | (void) REG_READ(I2S_CONF_REG(0)); 372 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 373 | while (GET_PERI_REG_BITS2(I2S_STATE_REG(0), 0x1, I2S_TX_FIFO_RESET_BACK_S)); 374 | 375 | SET_PERI_REG_BITS(I2S_INT_ENA_REG(0), 0x1, 1, I2S_OUT_DONE_INT_ENA_S); 376 | ESP_INTR_ENABLE(ETS_I2S0_INUM); 377 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_START_S); 378 | #endif 379 | } 380 | 381 | /* 382 | static void i2s_stop() { 383 | ESP_INTR_DISABLE(ETS_I2S0_INUM); 384 | 385 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 386 | (void) REG_READ(I2S_CONF_REG(0)); 387 | REG_WRITE(I2S_CONF_REG(0), (REG_READ(I2S_CONF_REG(0)) & 0xfffffff0) | 0xf); 388 | (void) REG_READ(I2S_CONF_REG(0)); 389 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 390 | 391 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_RX_START_S); 392 | i2s_running = false; 393 | } 394 | */ 395 | 396 | void TickI2SOut() 397 | { 398 | i2s_run(); 399 | } 400 | 401 | static void i2s_run() 402 | { 403 | // wait for vsync 404 | //ESP_LOGD(TAG, "Waiting for VSYNC"); 405 | //while(gpio_get_level(s_config.pin_vsync) != 0); 406 | //while(gpio_get_level(s_config.pin_vsync) == 0); 407 | ///ESP_LOGD(TAG, "Got VSYNC"); 408 | // wait a bit 409 | //delay(2); 410 | 411 | // start RX 412 | // line_count = 0; 413 | isr_countOut = 0; 414 | i2s_running = true; 415 | i2s_fill_buf(0); 416 | } 417 | 418 | static void IRAM_ATTR i2s_isr(void* arg) { 419 | REG_WRITE(I2S_INT_CLR_REG(0), (REG_READ(I2S_INT_RAW_REG(0)) & 0xffffffc0) | 0x3f); 420 | ++isr_countOut; 421 | } 422 | 423 | -------------------------------------------------------------------------------- /main/i2s_stream_out.h: -------------------------------------------------------------------------------- 1 | #ifndef _I2S_STREAM_H 2 | #define _I2S_STREAM_H 3 | 4 | 5 | #define BUFF_SIZE_BYTES 2048 6 | 7 | extern volatile unsigned isr_countOut; 8 | extern uint32_t * i2sbufferOut[3]; 9 | 10 | void SetupI2SOut(); 11 | void TickI2SOut(); 12 | 13 | #endif 14 | 15 | -------------------------------------------------------------------------------- /sdkconfig: -------------------------------------------------------------------------------- 1 | # 2 | # Automatically generated file; DO NOT EDIT. 3 | # Espressif IoT Development Framework Configuration 4 | # 5 | 6 | # 7 | # SDK tool configuration 8 | # 9 | CONFIG_TOOLPREFIX="xtensa-esp32-elf-" 10 | CONFIG_PYTHON="python" 11 | CONFIG_MAKE_WARN_UNDEFINED_VARIABLES=y 12 | 13 | # 14 | # Bootloader config 15 | # 16 | CONFIG_LOG_BOOTLOADER_LEVEL_NONE= 17 | CONFIG_LOG_BOOTLOADER_LEVEL_ERROR=y 18 | CONFIG_LOG_BOOTLOADER_LEVEL_WARN= 19 | CONFIG_LOG_BOOTLOADER_LEVEL_INFO= 20 | CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG= 21 | CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE= 22 | CONFIG_LOG_BOOTLOADER_LEVEL=1 23 | CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V= 24 | CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y 25 | CONFIG_BOOTLOADER_FACTORY_RESET= 26 | CONFIG_BOOTLOADER_APP_TEST= 27 | CONFIG_BOOTLOADER_WDT_ENABLE=y 28 | CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE= 29 | CONFIG_BOOTLOADER_WDT_TIME_MS=9000 30 | 31 | # 32 | # Security features 33 | # 34 | CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT= 35 | CONFIG_SECURE_BOOT_ENABLED= 36 | CONFIG_FLASH_ENCRYPTION_ENABLED= 37 | 38 | # 39 | # Serial flasher config 40 | # 41 | CONFIG_ESPTOOLPY_PORT="/dev/ttyUSB0" 42 | CONFIG_ESPTOOLPY_BAUD_115200B= 43 | CONFIG_ESPTOOLPY_BAUD_230400B= 44 | CONFIG_ESPTOOLPY_BAUD_921600B= 45 | CONFIG_ESPTOOLPY_BAUD_2MB= 46 | CONFIG_ESPTOOLPY_BAUD_OTHER=y 47 | CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=1500000 48 | CONFIG_ESPTOOLPY_BAUD=1500000 49 | CONFIG_ESPTOOLPY_COMPRESSED=y 50 | CONFIG_FLASHMODE_QIO= 51 | CONFIG_FLASHMODE_QOUT= 52 | CONFIG_FLASHMODE_DIO=y 53 | CONFIG_FLASHMODE_DOUT= 54 | CONFIG_ESPTOOLPY_FLASHMODE="dio" 55 | CONFIG_ESPTOOLPY_FLASHFREQ_80M= 56 | CONFIG_ESPTOOLPY_FLASHFREQ_40M=y 57 | CONFIG_ESPTOOLPY_FLASHFREQ_26M= 58 | CONFIG_ESPTOOLPY_FLASHFREQ_20M= 59 | CONFIG_ESPTOOLPY_FLASHFREQ="40m" 60 | CONFIG_ESPTOOLPY_FLASHSIZE_1MB= 61 | CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y 62 | CONFIG_ESPTOOLPY_FLASHSIZE_4MB= 63 | CONFIG_ESPTOOLPY_FLASHSIZE_8MB= 64 | CONFIG_ESPTOOLPY_FLASHSIZE_16MB= 65 | CONFIG_ESPTOOLPY_FLASHSIZE="2MB" 66 | CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y 67 | CONFIG_ESPTOOLPY_BEFORE_RESET=y 68 | CONFIG_ESPTOOLPY_BEFORE_NORESET= 69 | CONFIG_ESPTOOLPY_BEFORE="default_reset" 70 | CONFIG_ESPTOOLPY_AFTER_RESET=y 71 | CONFIG_ESPTOOLPY_AFTER_NORESET= 72 | CONFIG_ESPTOOLPY_AFTER="hard_reset" 73 | CONFIG_MONITOR_BAUD_9600B= 74 | CONFIG_MONITOR_BAUD_57600B= 75 | CONFIG_MONITOR_BAUD_115200B=y 76 | CONFIG_MONITOR_BAUD_230400B= 77 | CONFIG_MONITOR_BAUD_921600B= 78 | CONFIG_MONITOR_BAUD_2MB= 79 | CONFIG_MONITOR_BAUD_OTHER= 80 | CONFIG_MONITOR_BAUD_OTHER_VAL=115200 81 | CONFIG_MONITOR_BAUD=115200 82 | 83 | # 84 | # Partition Table 85 | # 86 | CONFIG_PARTITION_TABLE_SINGLE_APP=y 87 | CONFIG_PARTITION_TABLE_TWO_OTA= 88 | CONFIG_PARTITION_TABLE_CUSTOM= 89 | CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" 90 | CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" 91 | CONFIG_PARTITION_TABLE_OFFSET=0x8000 92 | CONFIG_PARTITION_TABLE_MD5=y 93 | 94 | # 95 | # Compiler options 96 | # 97 | CONFIG_OPTIMIZATION_LEVEL_DEBUG= 98 | CONFIG_OPTIMIZATION_LEVEL_RELEASE=y 99 | CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y 100 | CONFIG_OPTIMIZATION_ASSERTIONS_SILENT= 101 | CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED= 102 | CONFIG_CXX_EXCEPTIONS= 103 | CONFIG_STACK_CHECK_NONE=y 104 | CONFIG_STACK_CHECK_NORM= 105 | CONFIG_STACK_CHECK_STRONG= 106 | CONFIG_STACK_CHECK_ALL= 107 | CONFIG_STACK_CHECK= 108 | CONFIG_WARN_WRITE_STRINGS= 109 | CONFIG_DISABLE_GCC8_WARNINGS= 110 | 111 | # 112 | # Component config 113 | # 114 | 115 | # 116 | # Application Level Tracing 117 | # 118 | CONFIG_ESP32_APPTRACE_DEST_TRAX= 119 | CONFIG_ESP32_APPTRACE_DEST_NONE=y 120 | CONFIG_ESP32_APPTRACE_ENABLE= 121 | CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y 122 | CONFIG_AWS_IOT_SDK= 123 | 124 | # 125 | # Bluetooth 126 | # 127 | CONFIG_BT_ENABLED= 128 | CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF=0 129 | CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF=0 130 | CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF=0 131 | CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE=0 132 | CONFIG_BT_RESERVE_DRAM=0 133 | 134 | # 135 | # Driver configurations 136 | # 137 | 138 | # 139 | # ADC configuration 140 | # 141 | CONFIG_ADC_FORCE_XPD_FSM= 142 | CONFIG_ADC2_DISABLE_DAC=y 143 | 144 | # 145 | # SPI configuration 146 | # 147 | CONFIG_SPI_MASTER_IN_IRAM= 148 | CONFIG_SPI_MASTER_ISR_IN_IRAM=y 149 | CONFIG_SPI_SLAVE_IN_IRAM= 150 | CONFIG_SPI_SLAVE_ISR_IN_IRAM=y 151 | 152 | # 153 | # ESP32-specific 154 | # 155 | CONFIG_ESP32_DEFAULT_CPU_FREQ_80= 156 | CONFIG_ESP32_DEFAULT_CPU_FREQ_160= 157 | CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y 158 | CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=240 159 | CONFIG_SPIRAM_SUPPORT= 160 | CONFIG_MEMMAP_TRACEMEM= 161 | CONFIG_MEMMAP_TRACEMEM_TWOBANKS= 162 | CONFIG_ESP32_TRAX= 163 | CONFIG_TRACEMEM_RESERVE_DRAM=0x0 164 | CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH= 165 | CONFIG_ESP32_ENABLE_COREDUMP_TO_UART= 166 | CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y 167 | CONFIG_ESP32_ENABLE_COREDUMP= 168 | CONFIG_TWO_UNIVERSAL_MAC_ADDRESS= 169 | CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y 170 | CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 171 | CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 172 | CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2048 173 | CONFIG_MAIN_TASK_STACK_SIZE=4096 174 | CONFIG_IPC_TASK_STACK_SIZE=1024 175 | CONFIG_TIMER_TASK_STACK_SIZE=3584 176 | CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y 177 | CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF= 178 | CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR= 179 | CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF= 180 | CONFIG_NEWLIB_STDIN_LINE_ENDING_LF= 181 | CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y 182 | CONFIG_NEWLIB_NANO_FORMAT= 183 | CONFIG_CONSOLE_UART_DEFAULT=y 184 | CONFIG_CONSOLE_UART_CUSTOM= 185 | CONFIG_CONSOLE_UART_NONE= 186 | CONFIG_CONSOLE_UART_NUM=0 187 | CONFIG_CONSOLE_UART_BAUDRATE=115200 188 | CONFIG_ULP_COPROC_ENABLED= 189 | CONFIG_ULP_COPROC_RESERVE_MEM=0 190 | CONFIG_ESP32_PANIC_PRINT_HALT= 191 | CONFIG_ESP32_PANIC_PRINT_REBOOT=y 192 | CONFIG_ESP32_PANIC_SILENT_REBOOT= 193 | CONFIG_ESP32_PANIC_GDBSTUB= 194 | CONFIG_ESP32_DEBUG_OCDAWARE=y 195 | CONFIG_ESP32_DEBUG_STUBS_ENABLE=y 196 | CONFIG_INT_WDT=y 197 | CONFIG_INT_WDT_TIMEOUT_MS=300 198 | CONFIG_INT_WDT_CHECK_CPU1=y 199 | CONFIG_TASK_WDT= 200 | CONFIG_BROWNOUT_DET=y 201 | CONFIG_BROWNOUT_DET_LVL_SEL_0=y 202 | CONFIG_BROWNOUT_DET_LVL_SEL_1= 203 | CONFIG_BROWNOUT_DET_LVL_SEL_2= 204 | CONFIG_BROWNOUT_DET_LVL_SEL_3= 205 | CONFIG_BROWNOUT_DET_LVL_SEL_4= 206 | CONFIG_BROWNOUT_DET_LVL_SEL_5= 207 | CONFIG_BROWNOUT_DET_LVL_SEL_6= 208 | CONFIG_BROWNOUT_DET_LVL_SEL_7= 209 | CONFIG_BROWNOUT_DET_LVL=0 210 | CONFIG_REDUCE_PHY_TX_POWER=y 211 | CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y 212 | CONFIG_ESP32_TIME_SYSCALL_USE_RTC= 213 | CONFIG_ESP32_TIME_SYSCALL_USE_FRC1= 214 | CONFIG_ESP32_TIME_SYSCALL_USE_NONE= 215 | CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y 216 | CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL= 217 | CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC= 218 | CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256= 219 | CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024 220 | CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 221 | CONFIG_ESP32_XTAL_FREQ_40= 222 | CONFIG_ESP32_XTAL_FREQ_26= 223 | CONFIG_ESP32_XTAL_FREQ_AUTO=y 224 | CONFIG_ESP32_XTAL_FREQ=0 225 | CONFIG_DISABLE_BASIC_ROM_CONSOLE= 226 | CONFIG_NO_BLOBS= 227 | CONFIG_ESP_TIMER_PROFILING= 228 | CONFIG_COMPATIBLE_PRE_V2_1_BOOTLOADERS= 229 | CONFIG_ESP_ERR_TO_NAME_LOOKUP=y 230 | 231 | # 232 | # Wi-Fi 233 | # 234 | CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 235 | CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 236 | CONFIG_ESP32_WIFI_STATIC_TX_BUFFER= 237 | CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y 238 | CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 239 | CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 240 | CONFIG_ESP32_WIFI_CSI_ENABLED= 241 | CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y 242 | CONFIG_ESP32_WIFI_TX_BA_WIN=6 243 | CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y 244 | CONFIG_ESP32_WIFI_RX_BA_WIN=6 245 | CONFIG_ESP32_WIFI_NVS_ENABLED=y 246 | CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y 247 | CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1= 248 | CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 249 | 250 | # 251 | # PHY 252 | # 253 | CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y 254 | CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION= 255 | CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 256 | CONFIG_ESP32_PHY_MAX_TX_POWER=20 257 | 258 | # 259 | # Power Management 260 | # 261 | CONFIG_PM_ENABLE= 262 | 263 | # 264 | # ADC-Calibration 265 | # 266 | CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y 267 | CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y 268 | CONFIG_ADC_CAL_LUT_ENABLE=y 269 | 270 | # 271 | # Event Loop Library 272 | # 273 | CONFIG_EVENT_LOOP_PROFILING= 274 | 275 | # 276 | # ESP HTTP client 277 | # 278 | CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y 279 | 280 | # 281 | # HTTP Server 282 | # 283 | CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 284 | CONFIG_HTTPD_MAX_URI_LEN=512 285 | 286 | # 287 | # Ethernet 288 | # 289 | CONFIG_DMA_RX_BUF_NUM=10 290 | CONFIG_DMA_TX_BUF_NUM=10 291 | CONFIG_EMAC_L2_TO_L3_RX_BUF_MODE= 292 | CONFIG_EMAC_CHECK_LINK_PERIOD_MS=2000 293 | CONFIG_EMAC_TASK_PRIORITY=20 294 | CONFIG_EMAC_TASK_STACK_SIZE=3072 295 | 296 | # 297 | # FAT Filesystem support 298 | # 299 | CONFIG_FATFS_CODEPAGE_DYNAMIC= 300 | CONFIG_FATFS_CODEPAGE_437=y 301 | CONFIG_FATFS_CODEPAGE_720= 302 | CONFIG_FATFS_CODEPAGE_737= 303 | CONFIG_FATFS_CODEPAGE_771= 304 | CONFIG_FATFS_CODEPAGE_775= 305 | CONFIG_FATFS_CODEPAGE_850= 306 | CONFIG_FATFS_CODEPAGE_852= 307 | CONFIG_FATFS_CODEPAGE_855= 308 | CONFIG_FATFS_CODEPAGE_857= 309 | CONFIG_FATFS_CODEPAGE_860= 310 | CONFIG_FATFS_CODEPAGE_861= 311 | CONFIG_FATFS_CODEPAGE_862= 312 | CONFIG_FATFS_CODEPAGE_863= 313 | CONFIG_FATFS_CODEPAGE_864= 314 | CONFIG_FATFS_CODEPAGE_865= 315 | CONFIG_FATFS_CODEPAGE_866= 316 | CONFIG_FATFS_CODEPAGE_869= 317 | CONFIG_FATFS_CODEPAGE_932= 318 | CONFIG_FATFS_CODEPAGE_936= 319 | CONFIG_FATFS_CODEPAGE_949= 320 | CONFIG_FATFS_CODEPAGE_950= 321 | CONFIG_FATFS_CODEPAGE=437 322 | CONFIG_FATFS_LFN_NONE=y 323 | CONFIG_FATFS_LFN_HEAP= 324 | CONFIG_FATFS_LFN_STACK= 325 | CONFIG_FATFS_FS_LOCK=0 326 | CONFIG_FATFS_TIMEOUT_MS=10000 327 | CONFIG_FATFS_PER_FILE_CACHE=y 328 | 329 | # 330 | # Modbus configuration 331 | # 332 | CONFIG_MB_UART_RXD=22 333 | CONFIG_MB_UART_TXD=23 334 | CONFIG_MB_UART_RTS=18 335 | CONFIG_MB_QUEUE_LENGTH=20 336 | CONFIG_MB_SERIAL_TASK_STACK_SIZE=2048 337 | CONFIG_MB_SERIAL_BUF_SIZE=256 338 | CONFIG_MB_SERIAL_TASK_PRIO=10 339 | CONFIG_MB_CONTROLLER_SLAVE_ID_SUPPORT= 340 | CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT=20 341 | CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 342 | CONFIG_MB_CONTROLLER_STACK_SIZE=4096 343 | CONFIG_MB_EVENT_QUEUE_TIMEOUT=20 344 | CONFIG_MB_TIMER_PORT_ENABLED=y 345 | CONFIG_MB_TIMER_GROUP=0 346 | CONFIG_MB_TIMER_INDEX=0 347 | 348 | # 349 | # FreeRTOS 350 | # 351 | CONFIG_FREERTOS_UNICORE= 352 | CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF 353 | CONFIG_FREERTOS_CORETIMER_0=y 354 | CONFIG_FREERTOS_CORETIMER_1= 355 | CONFIG_FREERTOS_HZ=100 356 | CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION= 357 | CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE=y 358 | CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL= 359 | CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY= 360 | CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK= 361 | CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y 362 | CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=4 363 | CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y 364 | CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE= 365 | CONFIG_FREERTOS_ASSERT_DISABLE= 366 | CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 367 | CONFIG_FREERTOS_ISR_STACKSIZE=1536 368 | CONFIG_FREERTOS_LEGACY_HOOKS= 369 | CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 370 | CONFIG_SUPPORT_STATIC_ALLOCATION= 371 | CONFIG_TIMER_TASK_PRIORITY=1 372 | CONFIG_TIMER_TASK_STACK_DEPTH=2048 373 | CONFIG_TIMER_QUEUE_LENGTH=10 374 | CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 375 | CONFIG_FREERTOS_USE_TRACE_FACILITY= 376 | CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS= 377 | CONFIG_FREERTOS_DEBUG_INTERNALS= 378 | 379 | # 380 | # Heap memory debugging 381 | # 382 | CONFIG_HEAP_POISONING_DISABLED=y 383 | CONFIG_HEAP_POISONING_LIGHT= 384 | CONFIG_HEAP_POISONING_COMPREHENSIVE= 385 | CONFIG_HEAP_TRACING= 386 | 387 | # 388 | # libsodium 389 | # 390 | 391 | # 392 | # Log output 393 | # 394 | CONFIG_LOG_DEFAULT_LEVEL_NONE= 395 | CONFIG_LOG_DEFAULT_LEVEL_ERROR= 396 | CONFIG_LOG_DEFAULT_LEVEL_WARN= 397 | CONFIG_LOG_DEFAULT_LEVEL_INFO= 398 | CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y 399 | CONFIG_LOG_DEFAULT_LEVEL_VERBOSE= 400 | CONFIG_LOG_DEFAULT_LEVEL=4 401 | CONFIG_LOG_COLORS= 402 | 403 | # 404 | # LWIP 405 | # 406 | CONFIG_L2_TO_L3_COPY= 407 | CONFIG_LWIP_IRAM_OPTIMIZATION= 408 | CONFIG_LWIP_MAX_SOCKETS=4 409 | CONFIG_USE_ONLY_LWIP_SELECT= 410 | CONFIG_LWIP_SO_REUSE= 411 | CONFIG_LWIP_SO_RCVBUF= 412 | CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1 413 | CONFIG_LWIP_IP_FRAG= 414 | CONFIG_LWIP_IP_REASSEMBLY= 415 | CONFIG_LWIP_STATS= 416 | CONFIG_LWIP_ETHARP_TRUST_IP_MAC= 417 | CONFIG_ESP_GRATUITOUS_ARP=y 418 | CONFIG_GARP_TMR_INTERVAL=60 419 | CONFIG_TCPIP_RECVMBOX_SIZE=32 420 | CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y 421 | CONFIG_LWIP_DHCP_RESTORE_LAST_IP= 422 | 423 | # 424 | # DHCP server 425 | # 426 | CONFIG_LWIP_DHCPS_LEASE_UNIT=60 427 | CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 428 | CONFIG_LWIP_AUTOIP= 429 | CONFIG_LWIP_NETIF_LOOPBACK=y 430 | CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 431 | 432 | # 433 | # TCP 434 | # 435 | CONFIG_LWIP_MAX_ACTIVE_TCP=16 436 | CONFIG_LWIP_MAX_LISTENING_TCP=16 437 | CONFIG_TCP_MAXRTX=12 438 | CONFIG_TCP_SYNMAXRTX=6 439 | CONFIG_TCP_MSS=1436 440 | CONFIG_TCP_MSL=60000 441 | CONFIG_TCP_SND_BUF_DEFAULT=5744 442 | CONFIG_TCP_WND_DEFAULT=5744 443 | CONFIG_TCP_RECVMBOX_SIZE=6 444 | CONFIG_TCP_QUEUE_OOSEQ=y 445 | CONFIG_ESP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES= 446 | CONFIG_TCP_OVERSIZE_MSS=y 447 | CONFIG_TCP_OVERSIZE_QUARTER_MSS= 448 | CONFIG_TCP_OVERSIZE_DISABLE= 449 | 450 | # 451 | # UDP 452 | # 453 | CONFIG_LWIP_MAX_UDP_PCBS=16 454 | CONFIG_UDP_RECVMBOX_SIZE=6 455 | CONFIG_TCPIP_TASK_STACK_SIZE=2560 456 | CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y 457 | CONFIG_TCPIP_TASK_AFFINITY_CPU0= 458 | CONFIG_TCPIP_TASK_AFFINITY_CPU1= 459 | CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF 460 | CONFIG_PPP_SUPPORT= 461 | 462 | # 463 | # ICMP 464 | # 465 | CONFIG_LWIP_MULTICAST_PING= 466 | CONFIG_LWIP_BROADCAST_PING= 467 | 468 | # 469 | # LWIP RAW API 470 | # 471 | CONFIG_LWIP_MAX_RAW_PCBS=16 472 | 473 | # 474 | # mbedTLS 475 | # 476 | CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y 477 | CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC= 478 | CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC= 479 | CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=16384 480 | CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN= 481 | CONFIG_MBEDTLS_DEBUG= 482 | CONFIG_MBEDTLS_HARDWARE_AES=y 483 | CONFIG_MBEDTLS_HARDWARE_MPI=y 484 | CONFIG_MBEDTLS_MPI_USE_INTERRUPT=y 485 | CONFIG_MBEDTLS_HARDWARE_SHA=y 486 | CONFIG_MBEDTLS_HAVE_TIME=y 487 | CONFIG_MBEDTLS_HAVE_TIME_DATE= 488 | CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y 489 | CONFIG_MBEDTLS_TLS_SERVER_ONLY= 490 | CONFIG_MBEDTLS_TLS_CLIENT_ONLY= 491 | CONFIG_MBEDTLS_TLS_DISABLED= 492 | CONFIG_MBEDTLS_TLS_SERVER=y 493 | CONFIG_MBEDTLS_TLS_CLIENT=y 494 | CONFIG_MBEDTLS_TLS_ENABLED=y 495 | 496 | # 497 | # TLS Key Exchange Methods 498 | # 499 | CONFIG_MBEDTLS_PSK_MODES= 500 | CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y 501 | CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA=y 502 | CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y 503 | CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y 504 | CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y 505 | CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y 506 | CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y 507 | CONFIG_MBEDTLS_SSL_RENEGOTIATION=y 508 | CONFIG_MBEDTLS_SSL_PROTO_SSL3= 509 | CONFIG_MBEDTLS_SSL_PROTO_TLS1=y 510 | CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=y 511 | CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y 512 | CONFIG_MBEDTLS_SSL_PROTO_DTLS= 513 | CONFIG_MBEDTLS_SSL_ALPN=y 514 | CONFIG_MBEDTLS_SSL_SESSION_TICKETS=y 515 | 516 | # 517 | # Symmetric Ciphers 518 | # 519 | CONFIG_MBEDTLS_AES_C=y 520 | CONFIG_MBEDTLS_CAMELLIA_C= 521 | CONFIG_MBEDTLS_DES_C= 522 | CONFIG_MBEDTLS_RC4_DISABLED=y 523 | CONFIG_MBEDTLS_RC4_ENABLED_NO_DEFAULT= 524 | CONFIG_MBEDTLS_RC4_ENABLED= 525 | CONFIG_MBEDTLS_BLOWFISH_C= 526 | CONFIG_MBEDTLS_XTEA_C= 527 | CONFIG_MBEDTLS_CCM_C=y 528 | CONFIG_MBEDTLS_GCM_C=y 529 | CONFIG_MBEDTLS_RIPEMD160_C= 530 | 531 | # 532 | # Certificates 533 | # 534 | CONFIG_MBEDTLS_PEM_PARSE_C=y 535 | CONFIG_MBEDTLS_PEM_WRITE_C=y 536 | CONFIG_MBEDTLS_X509_CRL_PARSE_C=y 537 | CONFIG_MBEDTLS_X509_CSR_PARSE_C=y 538 | CONFIG_MBEDTLS_ECP_C=y 539 | CONFIG_MBEDTLS_ECDH_C=y 540 | CONFIG_MBEDTLS_ECDSA_C=y 541 | CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y 542 | CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y 543 | CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y 544 | CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y 545 | CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y 546 | CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y 547 | CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y 548 | CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y 549 | CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y 550 | CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y 551 | CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y 552 | CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y 553 | CONFIG_MBEDTLS_ECP_NIST_OPTIM=y 554 | 555 | # 556 | # mDNS 557 | # 558 | CONFIG_MDNS_MAX_SERVICES=10 559 | 560 | # 561 | # ESP-MQTT Configurations 562 | # 563 | CONFIG_MQTT_PROTOCOL_311=y 564 | CONFIG_MQTT_TRANSPORT_SSL=y 565 | CONFIG_MQTT_TRANSPORT_WEBSOCKET=y 566 | CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y 567 | CONFIG_MQTT_USE_CUSTOM_CONFIG= 568 | CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED= 569 | CONFIG_MQTT_CUSTOM_OUTBOX= 570 | 571 | # 572 | # NVS 573 | # 574 | 575 | # 576 | # OpenSSL 577 | # 578 | CONFIG_OPENSSL_DEBUG= 579 | CONFIG_OPENSSL_ASSERT_DO_NOTHING=y 580 | CONFIG_OPENSSL_ASSERT_EXIT= 581 | 582 | # 583 | # PThreads 584 | # 585 | CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 586 | CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 587 | CONFIG_PTHREAD_STACK_MIN=768 588 | 589 | # 590 | # SPI Flash driver 591 | # 592 | CONFIG_SPI_FLASH_VERIFY_WRITE= 593 | CONFIG_SPI_FLASH_ENABLE_COUNTERS= 594 | CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y 595 | CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y 596 | CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS= 597 | CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED= 598 | 599 | # 600 | # SPIFFS Configuration 601 | # 602 | CONFIG_SPIFFS_MAX_PARTITIONS=3 603 | 604 | # 605 | # SPIFFS Cache Configuration 606 | # 607 | CONFIG_SPIFFS_CACHE=y 608 | CONFIG_SPIFFS_CACHE_WR=y 609 | CONFIG_SPIFFS_CACHE_STATS= 610 | CONFIG_SPIFFS_PAGE_CHECK=y 611 | CONFIG_SPIFFS_GC_MAX_RUNS=10 612 | CONFIG_SPIFFS_GC_STATS= 613 | CONFIG_SPIFFS_PAGE_SIZE=256 614 | CONFIG_SPIFFS_OBJ_NAME_LEN=32 615 | CONFIG_SPIFFS_USE_MAGIC=y 616 | CONFIG_SPIFFS_USE_MAGIC_LENGTH=y 617 | CONFIG_SPIFFS_META_LENGTH=4 618 | CONFIG_SPIFFS_USE_MTIME=y 619 | 620 | # 621 | # Debug Configuration 622 | # 623 | CONFIG_SPIFFS_DBG= 624 | CONFIG_SPIFFS_API_DBG= 625 | CONFIG_SPIFFS_GC_DBG= 626 | CONFIG_SPIFFS_CACHE_DBG= 627 | CONFIG_SPIFFS_CHECK_DBG= 628 | CONFIG_SPIFFS_TEST_VISUALISATION= 629 | 630 | # 631 | # TCP/IP Adapter 632 | # 633 | CONFIG_IP_LOST_TIMER_INTERVAL=120 634 | CONFIG_TCPIP_LWIP=y 635 | 636 | # 637 | # Virtual file system 638 | # 639 | CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y 640 | CONFIG_SUPPORT_TERMIOS=y 641 | 642 | # 643 | # Wear Levelling 644 | # 645 | CONFIG_WL_SECTOR_SIZE_512= 646 | CONFIG_WL_SECTOR_SIZE_4096=y 647 | CONFIG_WL_SECTOR_SIZE=4096 648 | -------------------------------------------------------------------------------- /trunky/app_main.c: -------------------------------------------------------------------------------- 1 | 2 | // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include "freertos/FreeRTOS.h" 22 | #include "freertos/task.h" 23 | #include "freertos/semphr.h" 24 | 25 | #include "driver/gpio.h" 26 | 27 | #include "esp_err.h" 28 | #include "esp_log.h" 29 | 30 | #include "i2s_stream_out.h" 31 | 32 | 33 | #include "freertos/FreeRTOS.h" 34 | #include "esp_wifi.h" 35 | #include "esp_system.h" 36 | #include "esp_event.h" 37 | #include "esp_event_loop.h" 38 | #include "nvs_flash.h" 39 | 40 | #include "i2s_stream_fast.h" 41 | //#include "i2s_stream_in_for_usb.h" 42 | #include 43 | 44 | #include 45 | 46 | void asmtest(); 47 | int test_fast_gpio(); 48 | 49 | #define XT_INTEXC_HOOK_NUM (1 + XCHAL_NUM_INTLEVELS + XCHAL_HAVE_NMI) 50 | extern volatile void * _xt_intexc_hooks[XT_INTEXC_HOOK_NUM]; 51 | 52 | void _my_xt_nmi(); 53 | uint32_t mydata; 54 | 55 | 56 | esp_err_t event_handler(void *ctx, system_event_t *event) 57 | { 58 | return ESP_OK; 59 | } 60 | 61 | 62 | volatile int ok2go = 0; 63 | volatile int running2go = 0; 64 | 65 | void introo() 66 | { 67 | write code here to test. 68 | } 69 | 70 | void start_cpu1() 71 | { 72 | while(!ok2go); 73 | running2go = 1; 74 | while(1) 75 | { 76 | asm volatile( "nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n" ); 77 | GPIO.out_w1ts = 1<<16; 78 | asm volatile( "nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n" ); 79 | GPIO.out_w1tc = 1<<16; 80 | } 81 | 82 | } 83 | 84 | void app_main() 85 | { 86 | //#define DO_WIFI 87 | #ifdef DO_WIFI 88 | 89 | nvs_flash_init(); 90 | tcpip_adapter_init(); 91 | ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); 92 | wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); 93 | ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); 94 | ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); 95 | ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); 96 | wifi_config_t sta_config = { 97 | .sta = { 98 | .ssid = "charles", 99 | .password = "thisiswifi", 100 | .bssid_set = false 101 | } 102 | }; 103 | ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &sta_config) ); 104 | ESP_ERROR_CHECK( esp_wifi_start() ); 105 | ESP_ERROR_CHECK( esp_wifi_connect() ); 106 | #endif 107 | 108 | 109 | #if 0 110 | #define HIGH_PERF_I2S_IN 111 | #ifdef HIGH_PERF_I2S_IN 112 | SetupI2SInUSB(); 113 | TickI2SInUSB(); 114 | 115 | { 116 | uint32_t lastcount = 0; 117 | while(true) 118 | { 119 | vTaskDelay(1000 / portTICK_RATE_MS); 120 | printf( "%d %08x\n", isr_countInUSB-lastcount, i2sbufferInUSB[0][0] ); 121 | lastcount = isr_countInUSB; 122 | } 123 | } 124 | 125 | #endif 126 | 127 | //#define TEST_ASM_RET_CALL 128 | #ifdef TEST_ASM_RET_CALL 129 | int test_asm_call(int i); 130 | uint8_t re = 0; 131 | while(1) 132 | { 133 | re++; 134 | 135 | //((uint8_t*)test_asm_call)[4] = 177; 136 | int ret = test_asm_call(re); 137 | //printf( "%08x\n", ((uint32_t)&test_asm_call) ); 138 | printf( "%d %d\n", re, ret ); 139 | } 140 | #endif 141 | 142 | //#define GPIO_ASM_TEST 143 | #ifdef GPIO_ASM_TEST 144 | GPIO.enable_w1ts = 1<<17; 145 | GPIO.out_w1ts = 1<<17; 146 | GPIO.out_w1tc = 1<<17; 147 | GPIO.out_w1ts = 1<<17; 148 | GPIO.out_w1tc = 1<<17; 149 | int rr = test_fast_gpio(); 150 | //printf( "TFGPIO: %08x\n", ); 151 | while(1) 152 | { 153 | 154 | GPIO.out_w1ts = 1<<17; 155 | GPIO.out_w1tc = 1<<17; 156 | } 157 | #endif 158 | 159 | #define NMI_TEST 160 | #ifdef NMI_TEST 161 | 162 | printf( "NMI TEST\n" ); 163 | 164 | gpio_config_t conf_gp = { 165 | .mode = GPIO_MODE_OUTPUT, 166 | .pull_up_en = GPIO_PULLUP_DISABLE, 167 | .pull_down_en = GPIO_PULLDOWN_DISABLE, 168 | .intr_type = GPIO_INTR_DISABLE, 169 | .pin_bit_mask = 1LL << 18 | 1LL<<16 | 1LL<<17 170 | }; 171 | gpio_config(&conf_gp); 172 | 173 | /* 174 | GPIO.func_out_sel_cfg[18].func_sel = 256; 175 | WRITE_PERI_REG( DR_REG_IO_MUX_BASE +0x54, 0x1b00 ); //GPIO 18 GPIO. 176 | GPIO.func_out_sel_cfg[16].func_sel = 256; 177 | WRITE_PERI_REG( DR_REG_IO_MUX_BASE +0x4c, 0x2800 ); //GPIO 16 GPIO. 178 | 179 | */ 180 | /* 181 | char *Buf = pvPortMallocCaps(1000, MALLOC_CAP_8BIT); 182 | typedef struct { 183 | char *BufStartAdress; 184 | }paramSet; 185 | paramSet *ParamPTR = pvPortMallocCaps(8, MALLOC_CAP_32BIT); 186 | ParamPTR->BufStartAdress = Buf; 187 | int xReturned2= xTaskCreatePinnedToCore(&run_on_core_2, "RealTimeThread", 2048, ParamPTR, 25, NULL, 1); 188 | */ 189 | 190 | printf( "%08x %08x %d %d\n", READ_PERI_REG( DR_REG_IO_MUX_BASE +0x4c ), READ_PERI_REG( DR_REG_IO_MUX_BASE +0x50 ), GPIO.func_out_sel_cfg[16].val, GPIO.func_out_sel_cfg[17].val ); 191 | // GPIO.enable_w1ts = 1<<18; 192 | // GPIO.enable_w1ts = 1<<17; 193 | // GPIO.enable_w1ts = 1<<16; 194 | 195 | GPIO.out_w1ts = 1<<16; 196 | GPIO.out_w1tc = 1<<16; 197 | GPIO.out_w1ts = 1<<16; 198 | GPIO.out_w1tc = 1<<16; 199 | 200 | _xt_intexc_hooks[XCHAL_NMILEVEL] = &_my_xt_nmi; 201 | 202 | GPIO.pin[0].int_ena = GPIO_PRO_CPU_NMI_INTR_ENA; ///Why can't I set the app CPU? 203 | GPIO.pin[0].int_type = 3; //Level-change trigger. 204 | 205 | #define ETS_GPIO_INUM 14 //Actually NMI vector. 206 | intr_matrix_set( 0, ETS_GPIO_NMI_SOURCE, ETS_GPIO_INUM ); 207 | ESP_INTR_ENABLE( ETS_GPIO_INUM ); 208 | 209 | ok2go = 1; 210 | printf( "Attached\n" ); 211 | 212 | while(1) 213 | { 214 | asm volatile( "nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n" ); 215 | GPIO.out_w1ts = 1<<17; 216 | asm volatile( "nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n" ); 217 | GPIO.out_w1tc = 1<<17; 218 | //printf( "Running2go: %d\n", running2go ); 219 | } 220 | #endif 221 | 222 | 223 | //#define I2SOTEST_FAST 224 | 225 | #ifdef I2SOTEST_FAST 226 | printf( "!!!!!!!!!!!!!!!!!!!!!!1\n" ); 227 | SetupI2SOut_fast(); 228 | printf( "!!!!!!!!!!!!!!!!!!!!!!2\n" ); 229 | TickI2SOut_fast(); 230 | printf( "!!!!!!!!!!!!!!!!!!!!!!3\n" ); 231 | 232 | while(true) 233 | { 234 | printf( "%d %08x\n", isr_countOut_fast, i2sbufferOut_fast[0][3] ); 235 | vTaskDelay(1000 / portTICK_RATE_MS); 236 | } 237 | 238 | #endif 239 | #ifdef I2SOTEST 240 | SetupI2SOut(); 241 | TickI2SOut(); 242 | 243 | while(true) 244 | { 245 | printf( "%d %08x\n", isr_countOut, i2sbufferOut[0][3] ); 246 | vTaskDelay(1000 / portTICK_RATE_MS); 247 | } 248 | 249 | #endif 250 | 251 | #define GPIOASMTEST 252 | #ifdef GPIOASMTEST 253 | 254 | gpio_config_t conf = { 255 | .mode = GPIO_MODE_OUTPUT, 256 | .pull_up_en = GPIO_PULLUP_DISABLE, 257 | .pull_down_en = GPIO_PULLDOWN_DISABLE, 258 | .intr_type = GPIO_INTR_DISABLE, 259 | .pin_bit_mask = 1LL << 18 | 1LL<<16 260 | }; 261 | gpio_config(&conf); 262 | printf( "GPIO ASM TEST\n" ); 263 | printf( "%08x %08x %d %d\n", READ_PERI_REG( DR_REG_IO_MUX_BASE +0x4c ), READ_PERI_REG( DR_REG_IO_MUX_BASE +0x54 ), GPIO.func_out_sel_cfg[16].val, GPIO.func_out_sel_cfg[18].val ); 264 | 265 | 266 | while(true) 267 | { 268 | //gpio_set_level( 18, 0 ); 269 | //gpio_set_level( 18, 1 ); 270 | GPIO.out_w1ts = (1 << 18); 271 | asmtest(); 272 | GPIO.out_w1tc = (1 << 18); 273 | asmtest(); 274 | // GPIO.out1_w1ts.data = (1 << (gpio_num - 32)); 275 | 276 | 277 | // printf( "%d %08x\n", isr_countOut, i2sbufferOut[0][3] ); 278 | // vTaskDelay(1000 / portTICK_RATE_MS); 279 | } 280 | 281 | #endif 282 | #endif 283 | 284 | introo(); 285 | 286 | } 287 | 288 | -------------------------------------------------------------------------------- /trunky/asm_test.S: -------------------------------------------------------------------------------- 1 | #define XCHAL_NMILEVEL 7/* NMI "level" (for use with */ 2 | 3 | 4 | 5 | .global test_asm_call 6 | .section .iram1,"ax" 7 | .align 4 8 | test_asm_call: 9 | entry a1, 32 10 | // rsr a2, 177 11 | // wsr a2, MISC0 12 | // rur a2, 0 13 | // .byte 0x20, 0x00, 0xe3 14 | // .byte 0x22, 0x22, 0xe3 //RUR (Doesn't work) 15 | .byte 0x20, 234, 0x03 //RSR 16 | 17 | retw 18 | 19 | 20 | .global asmtest 21 | .align 4 22 | 23 | asmtest: 24 | entry a1, 32 25 | 26 | // addi a1, a1, -68 27 | s32i.n a0, a1, 0 // Working reg 28 | s32i.n a2, a1, 4 // Running byte 29 | s32i.n a3, a1, 8 // Running CRC 30 | s32i.n a4, a1, 12 // Anding mask 31 | 32 | movi a0,160000 33 | movi a2, GPIO //Will take 10 cycles to read (at 240 MHz) 5 at 80. and 7 at 160, 1 to write. 34 | // movi a2, mydata //Will take 1 cycle 35 | 36 | // l32i a3, a2, 0 37 | keep_going: 38 | l32i a3, a2, 0 39 | // s32i a3, a2, 0 40 | addi a0, a0, -1 41 | bnez a0, keep_going 42 | 43 | 44 | 45 | l32i.n a0, a1, 0 46 | l32i.n a2, a1, 4 47 | l32i.n a3, a1, 8 48 | l32i.n a4, a1, 12 49 | // addi a1, a1, 68 50 | retw 51 | 52 | 53 | .align 4 54 | .global test_fast_gpio 55 | test_fast_gpio: 56 | entry a1, 32 57 | addi a1, a1, -68 58 | 59 | s32i.n a0, a1, 0 60 | s32i.n a3, a1, 4 61 | s32i.n a4, a1, 8 62 | movi a4, 10000 63 | 64 | tg: 65 | movi a2, GPIO 66 | movi a3, 1<<17 67 | s32i a3, a2, 8 //W1TS 68 | s32i a3, a2, 12 //W1TC 69 | addi a4, a4, -1 70 | bnez a4, tg 71 | 72 | l32i.n a4, a1, 8 73 | l32i.n a3, a1, 4 74 | movi a2, GPIO 75 | l32i.n a0, a1, 0 76 | addi a1, a1, 68 77 | retw 78 | //j test_fast_gpio 79 | 80 | 81 | 82 | 83 | 84 | //My terrible ISR WORKS! 85 | 86 | .global _my_xt_nmi 87 | .section .iram1,"ax" 88 | .type _my_xt_nmi,@function 89 | .align 4 90 | 91 | _my_xt_nmi: 92 | 93 | addi a1, a1, -68 94 | s32i a2, a1, 4 95 | s32i a3, a1, 8 96 | s32i a4, a1, 12 97 | 98 | nop 99 | nop 100 | nop 101 | nop 102 | nop 103 | nop 104 | nop 105 | nop 106 | nop 107 | nop 108 | nop 109 | nop 110 | nop 111 | nop 112 | nop 113 | nop 114 | nop 115 | nop 116 | nop 117 | nop 118 | nop 119 | nop 120 | nop 121 | nop 122 | nop 123 | nop 124 | nop 125 | nop 126 | nop 127 | nop 128 | nop 129 | nop 130 | nop 131 | nop 132 | nop 133 | nop 134 | nop 135 | nop 136 | nop 137 | nop 138 | nop 139 | nop 140 | nop 141 | nop 142 | nop 143 | nop 144 | nop 145 | nop 146 | nop 147 | nop 148 | nop 149 | nop 150 | nop 151 | nop 152 | nop 153 | nop 154 | nop 155 | nop 156 | nop 157 | nop 158 | nop 159 | nop 160 | nop 161 | nop 162 | nop 163 | nop 164 | nop 165 | nop 166 | nop 167 | nop 168 | nop 169 | nop 170 | nop 171 | nop 172 | nop 173 | nop 174 | 175 | 176 | movi a2, GPIO 177 | movi a3, 1<<18 178 | movi a4, 200 179 | _xt_loop: 180 | s32i a3, a2, 8 //W1TS 181 | nop 182 | nop 183 | nop 184 | nop 185 | nop 186 | nop 187 | nop 188 | nop 189 | nop 190 | nop 191 | s32i a3, a2, 12 //W1TC 192 | nop 193 | nop 194 | nop 195 | nop 196 | nop 197 | nop 198 | nop 199 | nop 200 | nop 201 | nop 202 | nop 203 | nop 204 | nop 205 | nop 206 | addi a4, a4, -1 207 | bnez a4, _xt_loop 208 | 209 | movi a3, 1 210 | s32i a3, a2, 0x4c //Status w1tc 211 | 212 | l32i a4, a1, 12 213 | l32i a3, a1, 8 214 | l32i a2, a1, 4 215 | addi a1, a1, 68 216 | rsr a0, EXCSAVE7 /* restore a0 */ 217 | rfi XCHAL_NMILEVEL 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | //USB in stream test 256 | .global _my_usb_stream_xt_nmi 257 | .section .iram1,"ax" 258 | .type _my_usb_stream_xt_nmi,@function 259 | .align 4 260 | 261 | _my_usb_stream_xt_nmi: 262 | addi a1, a1, -68 263 | s32i a2, a1, 4 264 | s32i a3, a1, 8 265 | s32i a4, a1, 12 266 | 267 | //TODO: 268 | // (0) Clear I2S Data 269 | // (1) Start I2S engine 270 | // (1.5) Start timer 271 | // (2) Monitor output for when it's complete 272 | // (3) Stop I2S Engine 273 | // (4) Stop timer. 274 | movi a2, GPIO 275 | movi a3, 1<<18 276 | movi a4, 200 277 | _uxt_loop: 278 | s32i a3, a2, 8 //W1TS 279 | s32i a3, a2, 12 //W1TC 280 | addi a4, a4, -1 281 | bnez a4, _uxt_loop 282 | 283 | movi a3, 1 284 | s32i a3, a2, 0x4c //Status w1tc 285 | 286 | l32i a4, a1, 12 287 | l32i a3, a1, 8 288 | l32i a2, a1, 4 289 | addi a1, a1, 68 290 | rsr a0, EXCSAVE7 /* restore a0 */ 291 | rfi XCHAL_NMILEVEL 292 | 293 | -------------------------------------------------------------------------------- /trunky/component.mk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnlohr/esp32-cnlohr-demo/f6f253139b2df1818203241642175ff270d23189/trunky/component.mk -------------------------------------------------------------------------------- /trunky/i2s_stream_fast.c: -------------------------------------------------------------------------------- 1 | //This is for ONE BIT SHIFT REGISTER OUTPUT 2 | 3 | //Parts from: from https://github.com/pewit-tech/esp32-i2s/blob/master/i2s_freertos.c 4 | 5 | 6 | //Almost entirelly lifted directly from https://github.com/igrr/esp32-cam-demo 7 | //Just clocked a little differently and has chained buffers. 8 | //This totes works with the I2S bus on the ESP32 for READING 16 wires simultaneously. 9 | //Can be clocked off of I2S's internal controller or an external clock. 10 | 11 | 12 | 13 | #include "esp_intr.h" 14 | #include "i2s_stream_out.h" 15 | #include "driver/gpio.h" 16 | #include "soc/gpio_sig_map.h" 17 | #include "soc/i2s_reg.h" 18 | #include "soc/io_mux_reg.h" 19 | #include "driver/gpio.h" 20 | #include "driver/periph_ctrl.h" 21 | #include "rom/lldesc.h" 22 | #include "esp_log.h" 23 | #include "driver/ledc.h" 24 | #include 25 | #include "soc/rtc_cntl_reg.h" 26 | #include "soc/rtc.h" 27 | 28 | #define ETS_I2S0_INUM 13 29 | 30 | static void IRAM_ATTR i2s_isr_fast(void* arg); 31 | static esp_err_t dma_desc_init_fast(); 32 | static void i2s_init_fast(); 33 | static void i2s_run_fast(); 34 | 35 | 36 | uint32_t * i2sbufferOut_fast[3] __attribute__((aligned(128))); 37 | static lldesc_t s_dma_desc[3]; 38 | static int i2s_running; 39 | volatile unsigned isr_countOut_fast; 40 | 41 | 42 | void SetupI2SOut_fast() 43 | { 44 | // enable_out_clock(); 45 | i2s_init_fast(); 46 | dma_desc_init_fast(); 47 | i2s_run_fast(); 48 | } 49 | 50 | 51 | static esp_err_t dma_desc_init_fast() 52 | { 53 | for (int i = 0; i < 3; ++i) { 54 | i2sbufferOut_fast[i] = malloc( BUFF_SIZE_BYTES ); 55 | s_dma_desc[i].length = BUFF_SIZE_BYTES; // size of a single DMA buf 56 | s_dma_desc[i].size = BUFF_SIZE_BYTES; // total size of the chain 57 | s_dma_desc[i].owner = 1; 58 | s_dma_desc[i].sosf = 1; 59 | s_dma_desc[i].buf = (uint8_t*) i2sbufferOut_fast[i]; 60 | s_dma_desc[i].offset = i; 61 | s_dma_desc[i].empty = 0; 62 | s_dma_desc[i].eof = 1; 63 | s_dma_desc[i].qe.stqe_next = &s_dma_desc[(i+1)%3]; 64 | int k; 65 | for( k = 0; k < BUFF_SIZE_BYTES/4; k++ ) 66 | { 67 | // i2sbufferOut[i][k] = (k&1)?0x0000FfFF:0xaaaaaaaa; 68 | i2sbufferOut_fast[i][k] = 0xaaaaaaaa; 69 | } 70 | } 71 | return ESP_OK; 72 | } 73 | 74 | /* 75 | static void enable_out_clock() { 76 | periph_module_enable(PERIPH_LEDC_MODULE); 77 | 78 | ledc_timer_config_t timer_conf; 79 | timer_conf.bit_num = 3; 80 | timer_conf.freq_hz = I2S_HZ; 81 | timer_conf.speed_mode = LEDC_HIGH_SPEED_MODE; 82 | timer_conf.timer_num = LEDC_TIMER_0; 83 | esp_err_t err = ledc_timer_config(&timer_conf); 84 | if (err != ESP_OK) { 85 | //ESP_LOGE(TAG, "ledc_timer_config failed, rc=%x", err); 86 | } 87 | 88 | ledc_channel_config_t ch_conf; 89 | ch_conf.channel = LEDC_CHANNEL_0; 90 | ch_conf.timer_sel = LEDC_TIMER_0; 91 | ch_conf.intr_type = LEDC_INTR_DISABLE; 92 | ch_conf.duty = 4; 93 | ch_conf.speed_mode = LEDC_HIGH_SPEED_MODE; 94 | ch_conf.gpio_num = 17; //s_config.pin_xclk; 95 | err = ledc_channel_config(&ch_conf); 96 | if (err != ESP_OK) { 97 | //ESP_LOGE(TAG, "ledc_channel_config failed, rc=%x", err); 98 | } 99 | 100 | } 101 | */ 102 | 103 | static void i2s_init_fast() 104 | { 105 | xt_set_interrupt_handler(ETS_I2S0_INUM, &i2s_isr_fast, NULL); 106 | intr_matrix_set(0, ETS_I2S0_INTR_SOURCE, ETS_I2S0_INUM); 107 | 108 | 109 | gpio_num_t pins[] = { 110 | 17, 111 | 18, 112 | 19, 113 | }; 114 | 115 | 116 | gpio_config_t conf = { 117 | .mode = GPIO_MODE_OUTPUT, 118 | .pull_up_en = GPIO_PULLUP_DISABLE, 119 | .pull_down_en = GPIO_PULLDOWN_DISABLE, 120 | .intr_type = GPIO_INTR_DISABLE 121 | }; 122 | for (int i = 0; i < sizeof(pins)/sizeof(gpio_num_t); ++i) { 123 | conf.pin_bit_mask = 1LL << pins[i]; 124 | gpio_config(&conf); 125 | } 126 | 127 | gpio_matrix_out(GPIO_NUM_17, I2S0O_DATA_OUT23_IDX, 0, 0); 128 | // gpio_matrix_out(GPIO_NUM_19, I2S0O_BCK_OUT_IDX, 0, 0); 129 | // gpio_matrix_out(GPIO_NUM_18, I2S0O_WS_OUT_IDX, 0, 0); 130 | 131 | 132 | periph_module_enable(PERIPH_I2S0_MODULE); 133 | 134 | 135 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 1, I2S_IN_RST_S); 136 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 0, I2S_IN_RST_S); 137 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 1, I2S_AHBM_RST_S); 138 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 0, I2S_AHBM_RST_S); 139 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 1, I2S_AHBM_FIFO_RST_S); 140 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 0, I2S_AHBM_FIFO_RST_S); 141 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_RESET_S); 142 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_TX_RESET_S); 143 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_FIFO_RESET_S); 144 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_TX_FIFO_RESET_S); 145 | 146 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_TX_SLAVE_MOD_S); //Needed, otherwise it waits for a clock. 147 | // SET_PERI_REG_MASK(I2S_CONF_REG(0), I2S_TX_MSB_SHIFT); 148 | // WRITE_PERI_REG(I2S_CONF2_REG(0), 0); 149 | 150 | #if 0 151 | 152 | #ifdef MANYBITS 153 | SET_PERI_REG_BITS(I2S_CONF2_REG(0), I2S_LCD_EN, 1, I2S_LCD_EN_S); 154 | SET_PERI_REG_BITS(I2S_CONF1_REG(0), I2S_TX_PCM_BYPASS, 1, I2S_TX_PCM_BYPASS_S); //Breaks everything 155 | // SET_PERI_REG_BITS(I2S_CONF2_REG(0), 0x1, 1, I2S_CAMERA_EN_S); 156 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_A, 0, I2S_CLKM_DIV_A_S); 157 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_B, 0, I2S_CLKM_DIV_B_S); 158 | 159 | #else 160 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_A, 1, I2S_CLKM_DIV_A_S); 161 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_B, 0, I2S_CLKM_DIV_B_S); 162 | 163 | #endif 164 | 165 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_NUM, 15, I2S_CLKM_DIV_NUM_S); //Setting to 0 wrecks it up. 166 | 167 | 168 | //This seems ignored in slave mode. 169 | // WRITE_PERI_REG( I2S_TIMING_REG(0), 0xffffffff ); 170 | // WRITE_PERI_REG( I2S_CONF_SIGLE_DATA_REG(0), 0xffffffff ); 171 | // SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_RX_SHORT_SYNC_S); // 172 | // SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_RX_BCK_DIV_NUM, 1, I2S_RX_BCK_DIV_NUM_S); 173 | 174 | #ifdef MANYBITS 175 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_TX_MONO_S); 176 | #else 177 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_RIGHT_FIRST_S); //Seem ignored in parallel mode 178 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_MSB_RIGHT_S);//Seem ignored in parallel mode 179 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_MSB_SHIFT_S);//Seem ignored in parallel mode 180 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_MONO_S); 181 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_SHORT_SYNC_S); //Seem ignored in parallel mode 182 | 183 | #endif 184 | // SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_MONO_S); 185 | // SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_TX_RIGHT_FIRST_S); //Seem ignored in parallel mode 186 | // SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_SHORT_SYNC_S); //Seem ignored in parallel mode 187 | 188 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), 0x1, 1, I2S_DSCR_EN_S); 189 | 190 | #ifdef MANYBITS 191 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_TX_FIFO_MOD, 1, I2S_TX_FIFO_MOD_S); 192 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), 0x1, 1, I2S_TX_FIFO_MOD_FORCE_EN_S); 193 | SET_PERI_REG_BITS(I2S_CONF_CHAN_REG(0), I2S_TX_CHAN_MOD, 1, I2S_TX_CHAN_MOD_S); 194 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_TX_BITS_MOD, 8, I2S_TX_BITS_MOD_S); 195 | #else 196 | //I think is needed? I don't know!!! 197 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_TX_FIFO_MOD, 1, I2S_TX_FIFO_MOD_S); 198 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), 0x1, 1, I2S_TX_FIFO_MOD_FORCE_EN_S); 199 | SET_PERI_REG_BITS(I2S_CONF_CHAN_REG(0), I2S_TX_CHAN_MOD, 1, I2S_TX_CHAN_MOD_S); 200 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_TX_BITS_MOD, 16, I2S_TX_BITS_MOD_S); 201 | #endif 202 | 203 | //If you don't do this, BCK will be limited to 13.3333 MHz. 204 | 205 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_TX_BCK_DIV_NUM, 4, I2S_TX_BCK_DIV_NUM_S); 206 | //Once set, 1 = you can read all 8 bits at 40 MHz. 207 | //Once set, 2 = you can read all 8 bits at 20 MHz. 208 | // 3 = 13.33333 MHz 209 | // 4 = 10.0MHz 210 | 211 | 212 | //When self-clocked, seem to make BCK rate ~13.3333 MHz. 213 | #endif 214 | 215 | WRITE_PERI_REG(I2S_CONF2_REG(0), 0 ); 216 | 217 | 218 | // SET_PERI_REG_BITS(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PU_V, 1, RTC_CNTL_PLLA_FORCE_PU_S); 219 | rtc_clk_apll_enable(1, 0, 0, 8, 0); 220 | 221 | 222 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_TX_BITS_MOD_V, 32, I2S_TX_BITS_MOD_S); 223 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_TX_BCK_DIV_NUM_V, 1, I2S_TX_BCK_DIV_NUM_S); 224 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_RX_BITS_MOD_V, 32, I2S_RX_BITS_MOD_S); 225 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_RX_BCK_DIV_NUM_V, 1, I2S_RX_BCK_DIV_NUM_S); 226 | 227 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKA_ENA_V, 0, I2S_CLKA_ENA_S); 228 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLK_EN_V, 1, I2S_CLK_EN_S); 229 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_A_V, 3, I2S_CLKM_DIV_A_S); 230 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_B_V, 0, I2S_CLKM_DIV_B_S); //160 / ((13 1/3) ) 231 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_NUM_V, 2, I2S_CLKM_DIV_NUM_S); 232 | 233 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_TX_FIFO_MOD_V, 2, I2S_TX_FIFO_MOD_S); 234 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_TX_DATA_NUM_V, 1, I2S_TX_DATA_NUM_S); 235 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_RX_FIFO_MOD_V, 2, I2S_RX_FIFO_MOD_S); 236 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_RX_DATA_NUM_V, 1, I2S_RX_DATA_NUM_S); 237 | 238 | SET_PERI_REG_BITS(I2S_CONF_CHAN_REG(0), I2S_TX_CHAN_MOD_V, 1, I2S_TX_CHAN_MOD_S); //DDR (dual-channel) mode 239 | SET_PERI_REG_BITS(I2S_CONF_CHAN_REG(0), I2S_RX_CHAN_MOD_V, 1, I2S_RX_CHAN_MOD_S); 240 | 241 | SET_PERI_REG_BITS(I2S_CONF1_REG(0), I2S_TX_STOP_EN_V, 1, I2S_TX_STOP_EN_S); 242 | SET_PERI_REG_BITS(I2S_CONF1_REG(0), I2S_TX_PCM_BYPASS_V, 1, I2S_TX_PCM_BYPASS_S); 243 | 244 | SET_PERI_REG_BITS(I2S_CONF_REG(0), I2S_TX_RIGHT_FIRST_V, 1, I2S_TX_RIGHT_FIRST_S); 245 | SET_PERI_REG_BITS(I2S_CONF_REG(0), I2S_RX_RIGHT_FIRST_V, 1, I2S_RX_RIGHT_FIRST_S); 246 | 247 | WRITE_PERI_REG( I2S_TIMING_REG(0), 0 ); 248 | // I2S0.TIMING.val=0; 249 | 250 | } 251 | 252 | static void i2s_fill_buf_fast() { 253 | #if 1 254 | ESP_INTR_DISABLE(ETS_I2S0_INUM); 255 | 256 | SET_PERI_REG_BITS(I2S_OUT_LINK_REG(0), I2S_OUTLINK_ADDR_V, ((uint32_t) &s_dma_desc), I2S_OUTLINK_ADDR_S); 257 | SET_PERI_REG_BITS(I2S_OUT_LINK_REG(0), I2S_OUTLINK_START_V, 1, I2S_OUTLINK_START_S); 258 | 259 | REG_WRITE(I2S_INT_CLR_REG(0), (REG_READ(I2S_INT_RAW_REG(0)) & 0xffffffc0) | 0x3f); 260 | 261 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_DSCR_EN_V, 1, I2S_DSCR_EN_S); 262 | 263 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), I2S_OUT_DATA_BURST_EN_V, 1, I2S_OUT_DATA_BURST_EN_S); 264 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), I2S_CHECK_OWNER_V, 1, I2S_CHECK_OWNER_S); 265 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), I2S_OUT_EOF_MODE_V, 1, I2S_OUT_EOF_MODE_S); 266 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), I2S_OUTDSCR_BURST_EN_V, 1, I2S_OUTDSCR_BURST_EN_S); 267 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), I2S_OUT_DATA_BURST_EN_V, 1, I2S_OUT_DATA_BURST_EN_S); 268 | 269 | 270 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 271 | (void) REG_READ(I2S_CONF_REG(0)); 272 | REG_WRITE(I2S_CONF_REG(0), (REG_READ(I2S_CONF_REG(0)) & 0xfffffff0) | 0xf); 273 | (void) REG_READ(I2S_CONF_REG(0)); 274 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 275 | while (GET_PERI_REG_BITS2(I2S_STATE_REG(0), 0x1, I2S_TX_FIFO_RESET_BACK_S)); 276 | 277 | 278 | SET_PERI_REG_BITS(I2S_INT_ENA_REG(0), I2S_OUT_DONE_INT_ENA_V, 1, I2S_OUT_DONE_INT_ENA_S); 279 | // ESP_INTR_ENABLE(ETS_I2S0_INUM); 280 | 281 | SET_PERI_REG_BITS(I2S_CONF_REG(0), I2S_TX_START_V, 1,I2S_TX_START_S); 282 | 283 | #else 284 | ESP_INTR_DISABLE(ETS_I2S0_INUM); 285 | 286 | SET_PERI_REG_BITS(I2S_OUT_LINK_REG(0), I2S_OUTLINK_ADDR_V, ((uint32_t) &s_dma_desc), I2S_OUTLINK_ADDR_S); 287 | SET_PERI_REG_BITS(I2S_OUT_LINK_REG(0), I2S_OUTLINK_START_V, 1, I2S_OUTLINK_START_S); 288 | 289 | REG_WRITE(I2S_INT_CLR_REG(0), (REG_READ(I2S_INT_RAW_REG(0)) & 0xffffffc0) | 0x3f); 290 | 291 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 292 | (void) REG_READ(I2S_CONF_REG(0)); 293 | REG_WRITE(I2S_CONF_REG(0), (REG_READ(I2S_CONF_REG(0)) & 0xfffffff0) | 0xf); 294 | (void) REG_READ(I2S_CONF_REG(0)); 295 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 296 | while (GET_PERI_REG_BITS2(I2S_STATE_REG(0), 0x1, I2S_TX_FIFO_RESET_BACK_S)); 297 | 298 | SET_PERI_REG_BITS(I2S_INT_ENA_REG(0), 0x1, 1, I2S_OUT_DONE_INT_ENA_S); 299 | ESP_INTR_ENABLE(ETS_I2S0_INUM); 300 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_START_S); 301 | #endif 302 | } 303 | 304 | /* 305 | static void i2s_stop() { 306 | ESP_INTR_DISABLE(ETS_I2S0_INUM); 307 | 308 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 309 | (void) REG_READ(I2S_CONF_REG(0)); 310 | REG_WRITE(I2S_CONF_REG(0), (REG_READ(I2S_CONF_REG(0)) & 0xfffffff0) | 0xf); 311 | (void) REG_READ(I2S_CONF_REG(0)); 312 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 313 | 314 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_RX_START_S); 315 | i2s_running = false; 316 | } 317 | */ 318 | 319 | void TickI2SOut_fast() 320 | { 321 | i2s_run_fast(); 322 | } 323 | 324 | static void i2s_run_fast() 325 | { 326 | // wait for vsync 327 | //ESP_LOGD(TAG, "Waiting for VSYNC"); 328 | //while(gpio_get_level(s_config.pin_vsync) != 0); 329 | //while(gpio_get_level(s_config.pin_vsync) == 0); 330 | ///ESP_LOGD(TAG, "Got VSYNC"); 331 | // wait a bit 332 | //delay(2); 333 | 334 | // start RX 335 | // line_count = 0; 336 | isr_countOut = 0; 337 | i2s_running = true; 338 | i2s_fill_buf_fast(0); 339 | } 340 | 341 | static void IRAM_ATTR i2s_isr_fast(void* arg) { 342 | REG_WRITE(I2S_INT_CLR_REG(0), (REG_READ(I2S_INT_RAW_REG(0)) & 0xffffffc0) | 0x3f); 343 | ++isr_countOut; 344 | } 345 | 346 | -------------------------------------------------------------------------------- /trunky/i2s_stream_fast.h: -------------------------------------------------------------------------------- 1 | #ifndef _I2S_STREAM_FAST_H 2 | #define _I2S_STREAM_FAST_H 3 | 4 | 5 | #define BUFF_SIZE_BYTES 2048 6 | 7 | extern volatile unsigned isr_countOut_fast; 8 | extern uint32_t * i2sbufferOut_fast[3]; 9 | 10 | void SetupI2SOut_fast(); 11 | void TickI2SOut_fast(); 12 | 13 | #endif 14 | 15 | -------------------------------------------------------------------------------- /trunky/i2s_stream_in.c: -------------------------------------------------------------------------------- 1 | //Almost entirelly lifted directly from https://github.com/igrr/esp32-cam-demo 2 | //Just clocked a little differently and has chained buffers. 3 | //This totes works with the I2S bus on the ESP32 for READING 16 wires simultaneously. 4 | //Can be clocked off of I2S's internal controller or an external clock. 5 | 6 | #define I2S_D0 4 7 | #define I2S_D1 5 8 | #define I2S_D2 18 9 | #define I2S_D3 19 10 | #define I2S_D4 36 11 | #define I2S_D5 39 12 | #define I2S_D6 34 13 | #define I2S_D7 35 14 | 15 | #define I2S_D8 32 16 | #define I2S_D9 33 17 | #define I2S_D10 25 18 | #define I2S_D11 26 19 | #define I2S_D12 27 20 | #define I2S_D13 14 21 | #define I2S_D14 12 22 | #define I2S_D15 13 23 | 24 | #define I2S_CLK 22 25 | //#define I2S_CLKO 13 26 | //#define I2S_CLKOWS 2 27 | 28 | #define I2S_HZ 10000000 29 | //#define I2S_HZ 1000000 30 | 31 | 32 | 33 | #include "esp_intr.h" 34 | #include "i2s_stream_in.h" 35 | #include "driver/gpio.h" 36 | #include "soc/gpio_sig_map.h" 37 | #include "soc/i2s_reg.h" 38 | #include "soc/io_mux_reg.h" 39 | #include "driver/gpio.h" 40 | #include "driver/periph_ctrl.h" 41 | #include "rom/lldesc.h" 42 | #include "esp_log.h" 43 | #include "driver/ledc.h" 44 | #include 45 | 46 | #define ETS_I2S0_INUM 13 47 | 48 | static void IRAM_ATTR i2s_isr(void* arg); 49 | static esp_err_t dma_desc_init(); 50 | static void i2s_init(); 51 | static void i2s_run(); 52 | static void enable_out_clock(); 53 | 54 | 55 | uint16_t * i2sbufferIn[2] __attribute__((aligned(128))); 56 | static lldesc_t s_dma_desc[2]; 57 | static int i2s_running; 58 | volatile unsigned isr_countIn; 59 | 60 | 61 | void SetupI2SIn() 62 | { 63 | enable_out_clock(); 64 | i2s_init(); 65 | dma_desc_init(); 66 | i2s_run(); 67 | } 68 | 69 | 70 | static esp_err_t dma_desc_init() 71 | { 72 | for (int i = 0; i < 2; ++i) { 73 | i2sbufferIn[i] = malloc( BUFF_SIZE_BYTES ); 74 | s_dma_desc[i].length = BUFF_SIZE_BYTES; // size of a single DMA buf 75 | s_dma_desc[i].size = BUFF_SIZE_BYTES; // total size of the chain 76 | s_dma_desc[i].owner = 1; 77 | s_dma_desc[i].sosf = 1; 78 | s_dma_desc[i].buf = (uint8_t*) i2sbufferIn[i]; 79 | s_dma_desc[i].offset = i; 80 | s_dma_desc[i].empty = 0; 81 | s_dma_desc[i].eof = 1; 82 | s_dma_desc[i].qe.stqe_next = &s_dma_desc[(i+1)&1]; 83 | } 84 | return ESP_OK; 85 | } 86 | 87 | 88 | static void enable_out_clock() { 89 | periph_module_enable(PERIPH_LEDC_MODULE); 90 | 91 | ledc_timer_config_t timer_conf; 92 | timer_conf.bit_num = 3; 93 | timer_conf.freq_hz = I2S_HZ; 94 | timer_conf.speed_mode = LEDC_HIGH_SPEED_MODE; 95 | timer_conf.timer_num = LEDC_TIMER_0; 96 | esp_err_t err = ledc_timer_config(&timer_conf); 97 | if (err != ESP_OK) { 98 | //ESP_LOGE(TAG, "ledc_timer_config failed, rc=%x", err); 99 | } 100 | 101 | ledc_channel_config_t ch_conf; 102 | ch_conf.channel = LEDC_CHANNEL_0; 103 | ch_conf.timer_sel = LEDC_TIMER_0; 104 | ch_conf.intr_type = LEDC_INTR_DISABLE; 105 | ch_conf.duty = 4; 106 | ch_conf.speed_mode = LEDC_HIGH_SPEED_MODE; 107 | ch_conf.gpio_num = 17; //s_config.pin_xclk; 108 | err = ledc_channel_config(&ch_conf); 109 | if (err != ESP_OK) { 110 | //ESP_LOGE(TAG, "ledc_channel_config failed, rc=%x", err); 111 | } 112 | 113 | } 114 | 115 | 116 | static void i2s_init() 117 | { 118 | xt_set_interrupt_handler(ETS_I2S0_INUM, &i2s_isr, NULL); 119 | intr_matrix_set(0, ETS_I2S0_INTR_SOURCE, ETS_I2S0_INUM); 120 | 121 | gpio_num_t pins[] = { 122 | I2S_D15, 123 | I2S_D14, 124 | I2S_D13, 125 | I2S_D12, 126 | I2S_D11, 127 | I2S_D10, 128 | I2S_D9, 129 | I2S_D8, 130 | 131 | I2S_D7, 132 | I2S_D6, 133 | I2S_D5, 134 | I2S_D4, 135 | I2S_D3, 136 | I2S_D2, 137 | I2S_D1, 138 | I2S_D0, 139 | I2S_CLK, 140 | }; 141 | 142 | gpio_config_t conf = { 143 | .mode = GPIO_MODE_INPUT, 144 | .pull_up_en = GPIO_PULLUP_DISABLE, 145 | .pull_down_en = GPIO_PULLDOWN_DISABLE, 146 | .intr_type = GPIO_INTR_DISABLE 147 | }; 148 | for (int i = 0; i < sizeof(pins)/sizeof(gpio_num_t); ++i) { 149 | conf.pin_bit_mask = 1LL << pins[i]; 150 | gpio_config(&conf); 151 | } 152 | 153 | gpio_matrix_in(I2S_D0, I2S0I_DATA_IN0_IDX, false); 154 | gpio_matrix_in(I2S_D1, I2S0I_DATA_IN1_IDX, false); 155 | gpio_matrix_in(I2S_D2, I2S0I_DATA_IN2_IDX, false); 156 | gpio_matrix_in(I2S_D3, I2S0I_DATA_IN3_IDX, false); 157 | gpio_matrix_in(I2S_D4, I2S0I_DATA_IN4_IDX, false); 158 | gpio_matrix_in(I2S_D5, I2S0I_DATA_IN5_IDX, false); 159 | gpio_matrix_in(I2S_D6, I2S0I_DATA_IN6_IDX, false); 160 | gpio_matrix_in(I2S_D7, I2S0I_DATA_IN7_IDX, false); 161 | 162 | gpio_matrix_in(I2S_D8, I2S0I_DATA_IN8_IDX, false); 163 | gpio_matrix_in(I2S_D9, I2S0I_DATA_IN9_IDX, false); 164 | gpio_matrix_in(I2S_D10, I2S0I_DATA_IN10_IDX, false); 165 | gpio_matrix_in(I2S_D11, I2S0I_DATA_IN11_IDX, false); 166 | gpio_matrix_in(I2S_D12, I2S0I_DATA_IN12_IDX, false); 167 | gpio_matrix_in(I2S_D13, I2S0I_DATA_IN13_IDX, false); 168 | gpio_matrix_in(I2S_D14, I2S0I_DATA_IN14_IDX, false); 169 | gpio_matrix_in(I2S_D15, I2S0I_DATA_IN15_IDX, false); 170 | 171 | //This magic is needed to enable the bus! 172 | gpio_matrix_in(0x38, I2S0I_V_SYNC_IDX, false); 173 | gpio_matrix_in(0x38, I2S0I_H_SYNC_IDX, false); 174 | gpio_matrix_in(0x38, I2S0I_H_ENABLE_IDX, false); 175 | 176 | //Whether the bus is self-clocking, or accepting an external clock. 177 | #define SLAVE_MOD 0 178 | 179 | #if SLAVE_MOD 180 | gpio_matrix_in(I2S_CLK, I2S0I_WS_IN_IDX, false); 181 | 182 | // gpio_matrix_in(I2S_CLKO, I2S0O_BCK_OUT_IDX, false); 183 | // gpio_matrix_in(I2S_CLKOWS, I2S0O_WS_OUT_IDX, false); 184 | 185 | #else 186 | 187 | conf.mode = GPIO_MODE_OUTPUT; 188 | conf.pin_bit_mask = 1LL << I2S_CLK; 189 | gpio_config(&conf); 190 | gpio_matrix_out(I2S_CLK, I2S0I_BCK_OUT_IDX, false, 0 ); 191 | 192 | #endif 193 | periph_module_enable(PERIPH_I2S0_MODULE); 194 | 195 | 196 | 197 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 1, I2S_IN_RST_S); 198 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 0, I2S_IN_RST_S); 199 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 1, I2S_AHBM_RST_S); 200 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 0, I2S_AHBM_RST_S); 201 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 1, I2S_AHBM_FIFO_RST_S); 202 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 0, I2S_AHBM_FIFO_RST_S); 203 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_RX_RESET_S); 204 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_RX_RESET_S); 205 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_RX_FIFO_RESET_S); 206 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_RX_FIFO_RESET_S); 207 | 208 | 209 | #if SLAVE_MOD 210 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_RX_SLAVE_MOD_S); 211 | #else 212 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_RX_SLAVE_MOD_S); 213 | #endif 214 | SET_PERI_REG_BITS(I2S_CONF2_REG(0), 0x1, 1, I2S_LCD_EN_S); 215 | SET_PERI_REG_BITS(I2S_CONF2_REG(0), 0x1, 1, I2S_CAMERA_EN_S); 216 | 217 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_A, 0, I2S_CLKM_DIV_A_S); 218 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_B, 0, I2S_CLKM_DIV_B_S); 219 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_NUM, 1, I2S_CLKM_DIV_NUM_S); //Setting to 0 wrecks it up. 220 | 221 | 222 | 223 | //This seems ignored in slave mode. 224 | // WRITE_PERI_REG( I2S_TIMING_REG(0), 0xffffffff ); 225 | // WRITE_PERI_REG( I2S_CONF_SIGLE_DATA_REG(0), 0xffffffff ); 226 | // SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_RX_SHORT_SYNC_S); // 227 | // SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_RX_BCK_DIV_NUM, 1, I2S_RX_BCK_DIV_NUM_S); 228 | 229 | 230 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), 0x1, 1, I2S_DSCR_EN_S); 231 | 232 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_RX_RIGHT_FIRST_S); //Seem ignored in parallel mode 233 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_RX_MSB_RIGHT_S);//Seem ignored in parallel mode 234 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_RX_MSB_SHIFT_S);//Seem ignored in parallel mode 235 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_RX_MONO_S); 236 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_RX_SHORT_SYNC_S); //Seem ignored in parallel mode 237 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_RX_FIFO_MOD, 1, I2S_RX_FIFO_MOD_S); 238 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), 0x1, 1, I2S_RX_FIFO_MOD_FORCE_EN_S); 239 | SET_PERI_REG_BITS(I2S_CONF_CHAN_REG(0), I2S_RX_CHAN_MOD, 1, I2S_RX_CHAN_MOD_S); 240 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_RX_BITS_MOD, 8, I2S_RX_BITS_MOD_S); 241 | 242 | //If you don't do this, BCK will be limited to 13.3333 MHz. 243 | 244 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_RX_BCK_DIV_NUM, 1, I2S_RX_BCK_DIV_NUM_S); 245 | //Once set, 1 = you can read all 8 bits at 40 MHz. 246 | //Once set, 2 = you can read all 8 bits at 20 MHz. 247 | // 3 = 13.33333 MHz 248 | // 4 = 10.0MHz 249 | 250 | 251 | //When self-clocked, seem to make BCK rate ~13.3333 MHz. 252 | 253 | 254 | } 255 | 256 | static void i2s_fill_buf() { 257 | ESP_INTR_DISABLE(ETS_I2S0_INUM); 258 | 259 | SET_PERI_REG_BITS(I2S_RXEOF_NUM_REG(0), I2S_RX_EOF_NUM, (BUFF_SIZE_BYTES - 8) / 2, I2S_RX_EOF_NUM_S); 260 | SET_PERI_REG_BITS(I2S_IN_LINK_REG(0), I2S_INLINK_ADDR, ((uint32_t) &s_dma_desc), I2S_INLINK_ADDR_S); 261 | SET_PERI_REG_BITS(I2S_IN_LINK_REG(0), 0x1, 1, I2S_INLINK_START_S); 262 | 263 | REG_WRITE(I2S_INT_CLR_REG(0), (REG_READ(I2S_INT_RAW_REG(0)) & 0xffffffc0) | 0x3f); 264 | 265 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 266 | (void) REG_READ(I2S_CONF_REG(0)); 267 | REG_WRITE(I2S_CONF_REG(0), (REG_READ(I2S_CONF_REG(0)) & 0xfffffff0) | 0xf); 268 | (void) REG_READ(I2S_CONF_REG(0)); 269 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 270 | while (GET_PERI_REG_BITS2(I2S_STATE_REG(0), 0x1, I2S_TX_FIFO_RESET_BACK_S)); 271 | 272 | SET_PERI_REG_BITS(I2S_INT_ENA_REG(0), 0x1, 1, I2S_IN_DONE_INT_ENA_S); 273 | ESP_INTR_ENABLE(ETS_I2S0_INUM); 274 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_RX_START_S); 275 | } 276 | 277 | /* 278 | static void i2s_stop() { 279 | ESP_INTR_DISABLE(ETS_I2S0_INUM); 280 | 281 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 282 | (void) REG_READ(I2S_CONF_REG(0)); 283 | REG_WRITE(I2S_CONF_REG(0), (REG_READ(I2S_CONF_REG(0)) & 0xfffffff0) | 0xf); 284 | (void) REG_READ(I2S_CONF_REG(0)); 285 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 286 | 287 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_RX_START_S); 288 | i2s_running = false; 289 | } 290 | */ 291 | 292 | void TickI2SIn() 293 | { 294 | i2s_run(); 295 | } 296 | 297 | static void i2s_run() 298 | { 299 | // wait for vsync 300 | //ESP_LOGD(TAG, "Waiting for VSYNC"); 301 | //while(gpio_get_level(s_config.pin_vsync) != 0); 302 | //while(gpio_get_level(s_config.pin_vsync) == 0); 303 | ///ESP_LOGD(TAG, "Got VSYNC"); 304 | // wait a bit 305 | //delay(2); 306 | 307 | // start RX 308 | // line_count = 0; 309 | isr_countIn = 0; 310 | i2s_running = true; 311 | i2s_fill_buf(0); 312 | } 313 | 314 | static void IRAM_ATTR i2s_isr(void* arg) { 315 | REG_WRITE(I2S_INT_CLR_REG(0), (REG_READ(I2S_INT_RAW_REG(0)) & 0xffffffc0) | 0x3f); 316 | ++isr_countIn; 317 | } 318 | 319 | -------------------------------------------------------------------------------- /trunky/i2s_stream_in.h: -------------------------------------------------------------------------------- 1 | #ifndef _I2S_STREAM_H 2 | #define _I2S_STREAM_H 3 | 4 | 5 | #define BUFF_SIZE_BYTES 2048 6 | 7 | extern volatile unsigned isr_countIn; 8 | extern uint16_t * i2sbufferIn[2] __attribute__((aligned(128))); 9 | 10 | void SetupI2SIn(); 11 | void TickI2SIn(); 12 | 13 | #endif 14 | 15 | -------------------------------------------------------------------------------- /trunky/i2s_stream_out.c: -------------------------------------------------------------------------------- 1 | //This is for ONE BIT SHIFT REGISTER OUTPUT 2 | 3 | //Parts from: from https://github.com/pewit-tech/esp32-i2s/blob/master/i2s_freertos.c 4 | 5 | 6 | //Almost entirelly lifted directly from https://github.com/igrr/esp32-cam-demo 7 | //Just clocked a little differently and has chained buffers. 8 | //This totes works with the I2S bus on the ESP32 for READING 16 wires simultaneously. 9 | //Can be clocked off of I2S's internal controller or an external clock. 10 | 11 | 12 | #define I2S_CLK 22 13 | //#define I2S_CLKO 13 14 | //#define I2S_CLKOWS 2 15 | 16 | #define MANYBITS 17 | 18 | #ifdef MANYBITS 19 | 20 | #define I2S_D0 4 21 | #define I2S_D1 5 22 | #define I2S_D2 15 23 | #define I2S_D3 14 24 | #define I2S_D4 15 25 | #define I2S_D5 3 26 | #define I2S_D6 14 27 | #define I2S_D7 12 28 | 29 | #define I2S_D8 18 30 | #define I2S_D9 19 31 | #define I2S_D10 25 32 | #define I2S_D11 26 33 | #define I2S_D12 27 34 | #define I2S_D13 10 35 | #define I2S_D14 12 36 | #define I2S_D15 13 37 | 38 | #define I2S_D23 20 39 | #endif 40 | 41 | 42 | 43 | #include "esp_intr.h" 44 | #include "i2s_stream_out.h" 45 | #include "driver/gpio.h" 46 | #include "soc/gpio_sig_map.h" 47 | #include "soc/i2s_reg.h" 48 | #include "soc/io_mux_reg.h" 49 | #include "driver/gpio.h" 50 | #include "driver/periph_ctrl.h" 51 | #include "rom/lldesc.h" 52 | #include "esp_log.h" 53 | #include "driver/ledc.h" 54 | #include 55 | 56 | #define ETS_I2S0_INUM 13 57 | 58 | static void IRAM_ATTR i2s_isr(void* arg); 59 | static esp_err_t dma_desc_init(); 60 | static void i2s_init(); 61 | static void i2s_run(); 62 | static void enable_out_clock(); 63 | 64 | 65 | uint32_t * i2sbufferOut[3] __attribute__((aligned(128))); 66 | static lldesc_t s_dma_desc[3]; 67 | static int i2s_running; 68 | volatile unsigned isr_countOut; 69 | 70 | 71 | void SetupI2SOut() 72 | { 73 | // enable_out_clock(); 74 | i2s_init(); 75 | dma_desc_init(); 76 | i2s_run(); 77 | } 78 | 79 | 80 | static esp_err_t dma_desc_init() 81 | { 82 | for (int i = 0; i < 3; ++i) { 83 | i2sbufferOut[i] = malloc( BUFF_SIZE_BYTES ); 84 | s_dma_desc[i].length = BUFF_SIZE_BYTES; // size of a single DMA buf 85 | s_dma_desc[i].size = BUFF_SIZE_BYTES; // total size of the chain 86 | s_dma_desc[i].owner = 1; 87 | s_dma_desc[i].sosf = 1; 88 | s_dma_desc[i].buf = (uint8_t*) i2sbufferOut[i]; 89 | s_dma_desc[i].offset = i; 90 | s_dma_desc[i].empty = 0; 91 | s_dma_desc[i].eof = 1; 92 | s_dma_desc[i].qe.stqe_next = &s_dma_desc[(i+1)%3]; 93 | int k; 94 | for( k = 0; k < BUFF_SIZE_BYTES/4; k++ ) 95 | { 96 | // i2sbufferOut[i][k] = (k&1)?0x0000FfFF:0xaaaaaaaa; 97 | i2sbufferOut[i][k] = (k&1)?0x0001fffe:0x0001fffe; 98 | } 99 | } 100 | return ESP_OK; 101 | } 102 | 103 | /* 104 | static void enable_out_clock() { 105 | periph_module_enable(PERIPH_LEDC_MODULE); 106 | 107 | ledc_timer_config_t timer_conf; 108 | timer_conf.bit_num = 3; 109 | timer_conf.freq_hz = I2S_HZ; 110 | timer_conf.speed_mode = LEDC_HIGH_SPEED_MODE; 111 | timer_conf.timer_num = LEDC_TIMER_0; 112 | esp_err_t err = ledc_timer_config(&timer_conf); 113 | if (err != ESP_OK) { 114 | //ESP_LOGE(TAG, "ledc_timer_config failed, rc=%x", err); 115 | } 116 | 117 | ledc_channel_config_t ch_conf; 118 | ch_conf.channel = LEDC_CHANNEL_0; 119 | ch_conf.timer_sel = LEDC_TIMER_0; 120 | ch_conf.intr_type = LEDC_INTR_DISABLE; 121 | ch_conf.duty = 4; 122 | ch_conf.speed_mode = LEDC_HIGH_SPEED_MODE; 123 | ch_conf.gpio_num = 17; //s_config.pin_xclk; 124 | err = ledc_channel_config(&ch_conf); 125 | if (err != ESP_OK) { 126 | //ESP_LOGE(TAG, "ledc_channel_config failed, rc=%x", err); 127 | } 128 | 129 | } 130 | */ 131 | 132 | static void i2s_init() 133 | { 134 | xt_set_interrupt_handler(ETS_I2S0_INUM, &i2s_isr, NULL); 135 | intr_matrix_set(0, ETS_I2S0_INTR_SOURCE, ETS_I2S0_INUM); 136 | 137 | #ifdef MANYBITS 138 | 139 | gpio_num_t pins[] = { 140 | I2S_D15, 141 | I2S_D14, 142 | I2S_D13, 143 | I2S_D12, 144 | I2S_D11, 145 | I2S_D10, 146 | I2S_D9, 147 | I2S_D8, 148 | 149 | I2S_D7, 150 | I2S_D6, 151 | I2S_D5, 152 | I2S_D4, 153 | I2S_D3, 154 | I2S_D2, 155 | I2S_D1, 156 | I2S_D0, 157 | 16,17 158 | }; 159 | 160 | #else 161 | gpio_num_t pins[] = { 162 | 17, 163 | 18, 164 | 19, 165 | }; 166 | #endif 167 | 168 | gpio_config_t conf = { 169 | .mode = GPIO_MODE_OUTPUT, 170 | .pull_up_en = GPIO_PULLUP_DISABLE, 171 | .pull_down_en = GPIO_PULLDOWN_DISABLE, 172 | .intr_type = GPIO_INTR_DISABLE 173 | }; 174 | for (int i = 0; i < sizeof(pins)/sizeof(gpio_num_t); ++i) { 175 | conf.pin_bit_mask = 1LL << pins[i]; 176 | gpio_config(&conf); 177 | } 178 | 179 | #ifdef MANYBITS 180 | gpio_matrix_out(I2S_D0, I2S0O_DATA_OUT0_IDX, false,false); 181 | gpio_matrix_out(I2S_D1, I2S0O_DATA_OUT1_IDX, false,false); 182 | gpio_matrix_out(I2S_D2, I2S0O_DATA_OUT2_IDX, false,false); 183 | gpio_matrix_out(I2S_D3, I2S0O_DATA_OUT3_IDX, false,false); 184 | gpio_matrix_out(I2S_D4, I2S0O_DATA_OUT4_IDX, false,false); 185 | gpio_matrix_out(I2S_D5, I2S0O_DATA_OUT5_IDX, false,false); 186 | gpio_matrix_out(I2S_D6, I2S0O_DATA_OUT6_IDX, false,false); 187 | gpio_matrix_out(I2S_D7, I2S0O_DATA_OUT7_IDX, false,false); 188 | 189 | gpio_matrix_out(I2S_D8, I2S0O_DATA_OUT8_IDX, false,false); 190 | gpio_matrix_out(I2S_D9, I2S0O_DATA_OUT9_IDX, false,false); 191 | gpio_matrix_out(I2S_D10, I2S0O_DATA_OUT10_IDX, false,false); 192 | gpio_matrix_out(I2S_D11, I2S0O_DATA_OUT11_IDX, false,false); 193 | gpio_matrix_out(I2S_D12, I2S0O_DATA_OUT12_IDX, false,false); 194 | gpio_matrix_out(I2S_D13, I2S0O_DATA_OUT13_IDX, false,false); 195 | gpio_matrix_out(I2S_D14, I2S0O_DATA_OUT14_IDX, false,false); 196 | gpio_matrix_out(I2S_D15, I2S0O_DATA_OUT15_IDX, false,false); 197 | gpio_matrix_out(GPIO_NUM_16, I2S0O_BCK_OUT_IDX, 0, 0); 198 | gpio_matrix_out(I2S_D23, I2S0O_DATA_OUT23_IDX, false,false); 199 | gpio_matrix_out(GPIO_NUM_17, I2S0O_WS_OUT_IDX, 0, 0); 200 | #else 201 | gpio_matrix_out(GPIO_NUM_17, I2S0O_DATA_OUT23_IDX, 0, 0); 202 | gpio_matrix_out(GPIO_NUM_19, I2S0O_BCK_OUT_IDX, 0, 0); 203 | gpio_matrix_out(GPIO_NUM_18, I2S0O_WS_OUT_IDX, 0, 0); 204 | #endif 205 | 206 | 207 | //This magic is needed to enable the bus! 208 | // gpio_matrix_in(0x38, I2S0I_V_SYNC_IDX, false); 209 | // gpio_matrix_in(0x38, I2S0I_H_SYNC_IDX, false); 210 | // gpio_matrix_in(0x38, I2S0I_H_ENABLE_IDX, false); 211 | 212 | //Whether the bus is self-clocking, or accepting an external clock. 213 | periph_module_enable(PERIPH_I2S0_MODULE); 214 | 215 | 216 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 1, I2S_IN_RST_S); 217 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 0, I2S_IN_RST_S); 218 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 1, I2S_AHBM_RST_S); 219 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 0, I2S_AHBM_RST_S); 220 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 1, I2S_AHBM_FIFO_RST_S); 221 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), 0x1, 0, I2S_AHBM_FIFO_RST_S); 222 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_RESET_S); 223 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_TX_RESET_S); 224 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_FIFO_RESET_S); 225 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_TX_FIFO_RESET_S); 226 | 227 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_TX_SLAVE_MOD_S); //Needed, otherwise it waits for a clock. 228 | // SET_PERI_REG_MASK(I2S_CONF_REG(0), I2S_TX_MSB_SHIFT); 229 | // WRITE_PERI_REG(I2S_CONF2_REG(0), 0); 230 | 231 | #if 0 232 | 233 | #ifdef MANYBITS 234 | SET_PERI_REG_BITS(I2S_CONF2_REG(0), I2S_LCD_EN, 1, I2S_LCD_EN_S); 235 | SET_PERI_REG_BITS(I2S_CONF1_REG(0), I2S_TX_PCM_BYPASS, 1, I2S_TX_PCM_BYPASS_S); //Breaks everything 236 | // SET_PERI_REG_BITS(I2S_CONF2_REG(0), 0x1, 1, I2S_CAMERA_EN_S); 237 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_A, 0, I2S_CLKM_DIV_A_S); 238 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_B, 0, I2S_CLKM_DIV_B_S); 239 | 240 | #else 241 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_A, 1, I2S_CLKM_DIV_A_S); 242 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_B, 0, I2S_CLKM_DIV_B_S); 243 | 244 | #endif 245 | 246 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_NUM, 15, I2S_CLKM_DIV_NUM_S); //Setting to 0 wrecks it up. 247 | 248 | 249 | //This seems ignored in slave mode. 250 | // WRITE_PERI_REG( I2S_TIMING_REG(0), 0xffffffff ); 251 | // WRITE_PERI_REG( I2S_CONF_SIGLE_DATA_REG(0), 0xffffffff ); 252 | // SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_RX_SHORT_SYNC_S); // 253 | // SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_RX_BCK_DIV_NUM, 1, I2S_RX_BCK_DIV_NUM_S); 254 | 255 | #ifdef MANYBITS 256 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_TX_MONO_S); 257 | #else 258 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_RIGHT_FIRST_S); //Seem ignored in parallel mode 259 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_MSB_RIGHT_S);//Seem ignored in parallel mode 260 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_MSB_SHIFT_S);//Seem ignored in parallel mode 261 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_MONO_S); 262 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_SHORT_SYNC_S); //Seem ignored in parallel mode 263 | 264 | #endif 265 | // SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_MONO_S); 266 | // SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_TX_RIGHT_FIRST_S); //Seem ignored in parallel mode 267 | // SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_SHORT_SYNC_S); //Seem ignored in parallel mode 268 | 269 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), 0x1, 1, I2S_DSCR_EN_S); 270 | 271 | #ifdef MANYBITS 272 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_TX_FIFO_MOD, 1, I2S_TX_FIFO_MOD_S); 273 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), 0x1, 1, I2S_TX_FIFO_MOD_FORCE_EN_S); 274 | SET_PERI_REG_BITS(I2S_CONF_CHAN_REG(0), I2S_TX_CHAN_MOD, 1, I2S_TX_CHAN_MOD_S); 275 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_TX_BITS_MOD, 8, I2S_TX_BITS_MOD_S); 276 | #else 277 | //I think is needed? I don't know!!! 278 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_TX_FIFO_MOD, 1, I2S_TX_FIFO_MOD_S); 279 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), 0x1, 1, I2S_TX_FIFO_MOD_FORCE_EN_S); 280 | SET_PERI_REG_BITS(I2S_CONF_CHAN_REG(0), I2S_TX_CHAN_MOD, 1, I2S_TX_CHAN_MOD_S); 281 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_TX_BITS_MOD, 16, I2S_TX_BITS_MOD_S); 282 | #endif 283 | 284 | //If you don't do this, BCK will be limited to 13.3333 MHz. 285 | 286 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_TX_BCK_DIV_NUM, 4, I2S_TX_BCK_DIV_NUM_S); 287 | //Once set, 1 = you can read all 8 bits at 40 MHz. 288 | //Once set, 2 = you can read all 8 bits at 20 MHz. 289 | // 3 = 13.33333 MHz 290 | // 4 = 10.0MHz 291 | 292 | 293 | //When self-clocked, seem to make BCK rate ~13.3333 MHz. 294 | #endif 295 | 296 | WRITE_PERI_REG(I2S_CONF2_REG(0), 0 ); 297 | SET_PERI_REG_BITS(I2S_CONF2_REG(0), I2S_LCD_EN_V, 1, I2S_LCD_EN_S); 298 | 299 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_TX_BITS_MOD_V, 16, I2S_TX_BITS_MOD_S); 300 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_TX_BCK_DIV_NUM_V, 1, I2S_TX_BCK_DIV_NUM_S); 301 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_RX_BITS_MOD_V, 16, I2S_RX_BITS_MOD_S); 302 | SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_RX_BCK_DIV_NUM_V, 1, I2S_RX_BCK_DIV_NUM_S); 303 | 304 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKA_ENA_V, 1, I2S_CLKA_ENA_S); 305 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLK_EN_V, 1, I2S_CLK_EN_S); 306 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_A_V, 3, I2S_CLKM_DIV_A_S); 307 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_B_V, 1, I2S_CLKM_DIV_B_S); //160 / ((13 1/3) ) 308 | SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_NUM_V, 13, I2S_CLKM_DIV_NUM_S); 309 | 310 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_TX_FIFO_MOD_V, 0, I2S_TX_FIFO_MOD_S); 311 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_TX_DATA_NUM_V, 1, I2S_TX_DATA_NUM_S); 312 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_RX_FIFO_MOD_V, 0, I2S_RX_FIFO_MOD_S); 313 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_RX_DATA_NUM_V, 1, I2S_RX_DATA_NUM_S); 314 | 315 | SET_PERI_REG_BITS(I2S_CONF_CHAN_REG(0), I2S_TX_CHAN_MOD_V, 0, I2S_TX_CHAN_MOD_S); //DDR (dual-channel) mode 316 | SET_PERI_REG_BITS(I2S_CONF_CHAN_REG(0), I2S_RX_CHAN_MOD_V, 0, I2S_RX_CHAN_MOD_S); 317 | 318 | SET_PERI_REG_BITS(I2S_CONF1_REG(0), I2S_TX_STOP_EN_V, 1, I2S_TX_STOP_EN_S); 319 | SET_PERI_REG_BITS(I2S_CONF1_REG(0), I2S_TX_PCM_BYPASS_V, 1, I2S_TX_PCM_BYPASS_S); 320 | 321 | SET_PERI_REG_BITS(I2S_CONF_REG(0), I2S_TX_RIGHT_FIRST_V, 1, I2S_TX_RIGHT_FIRST_S); 322 | SET_PERI_REG_BITS(I2S_CONF_REG(0), I2S_RX_RIGHT_FIRST_V, 1, I2S_RX_RIGHT_FIRST_S); 323 | 324 | WRITE_PERI_REG( I2S_TIMING_REG(0), 0 ); 325 | // I2S0.TIMING.val=0; 326 | 327 | } 328 | 329 | static void i2s_fill_buf() { 330 | #if 1 331 | ESP_INTR_DISABLE(ETS_I2S0_INUM); 332 | 333 | SET_PERI_REG_BITS(I2S_OUT_LINK_REG(0), I2S_OUTLINK_ADDR_V, ((uint32_t) &s_dma_desc), I2S_OUTLINK_ADDR_S); 334 | SET_PERI_REG_BITS(I2S_OUT_LINK_REG(0), I2S_OUTLINK_START_V, 1, I2S_OUTLINK_START_S); 335 | 336 | REG_WRITE(I2S_INT_CLR_REG(0), (REG_READ(I2S_INT_RAW_REG(0)) & 0xffffffc0) | 0x3f); 337 | 338 | SET_PERI_REG_BITS(I2S_FIFO_CONF_REG(0), I2S_DSCR_EN_V, 1, I2S_DSCR_EN_S); 339 | 340 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), I2S_OUT_DATA_BURST_EN_V, 1, I2S_OUT_DATA_BURST_EN_S); 341 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), I2S_CHECK_OWNER_V, 1, I2S_CHECK_OWNER_S); 342 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), I2S_OUT_EOF_MODE_V, 1, I2S_OUT_EOF_MODE_S); 343 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), I2S_OUTDSCR_BURST_EN_V, 1, I2S_OUTDSCR_BURST_EN_S); 344 | SET_PERI_REG_BITS(I2S_LC_CONF_REG(0), I2S_OUT_DATA_BURST_EN_V, 1, I2S_OUT_DATA_BURST_EN_S); 345 | 346 | 347 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 348 | (void) REG_READ(I2S_CONF_REG(0)); 349 | REG_WRITE(I2S_CONF_REG(0), (REG_READ(I2S_CONF_REG(0)) & 0xfffffff0) | 0xf); 350 | (void) REG_READ(I2S_CONF_REG(0)); 351 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 352 | while (GET_PERI_REG_BITS2(I2S_STATE_REG(0), 0x1, I2S_TX_FIFO_RESET_BACK_S)); 353 | 354 | 355 | SET_PERI_REG_BITS(I2S_INT_ENA_REG(0), I2S_OUT_DONE_INT_ENA_V, 1, I2S_OUT_DONE_INT_ENA_S); 356 | // ESP_INTR_ENABLE(ETS_I2S0_INUM); 357 | 358 | SET_PERI_REG_BITS(I2S_CONF_REG(0), I2S_TX_START_V, 1,I2S_TX_START_S); 359 | 360 | #else 361 | ESP_INTR_DISABLE(ETS_I2S0_INUM); 362 | 363 | SET_PERI_REG_BITS(I2S_OUT_LINK_REG(0), I2S_OUTLINK_ADDR_V, ((uint32_t) &s_dma_desc), I2S_OUTLINK_ADDR_S); 364 | SET_PERI_REG_BITS(I2S_OUT_LINK_REG(0), I2S_OUTLINK_START_V, 1, I2S_OUTLINK_START_S); 365 | 366 | REG_WRITE(I2S_INT_CLR_REG(0), (REG_READ(I2S_INT_RAW_REG(0)) & 0xffffffc0) | 0x3f); 367 | 368 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 369 | (void) REG_READ(I2S_CONF_REG(0)); 370 | REG_WRITE(I2S_CONF_REG(0), (REG_READ(I2S_CONF_REG(0)) & 0xfffffff0) | 0xf); 371 | (void) REG_READ(I2S_CONF_REG(0)); 372 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 373 | while (GET_PERI_REG_BITS2(I2S_STATE_REG(0), 0x1, I2S_TX_FIFO_RESET_BACK_S)); 374 | 375 | SET_PERI_REG_BITS(I2S_INT_ENA_REG(0), 0x1, 1, I2S_OUT_DONE_INT_ENA_S); 376 | ESP_INTR_ENABLE(ETS_I2S0_INUM); 377 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 1, I2S_TX_START_S); 378 | #endif 379 | } 380 | 381 | /* 382 | static void i2s_stop() { 383 | ESP_INTR_DISABLE(ETS_I2S0_INUM); 384 | 385 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 386 | (void) REG_READ(I2S_CONF_REG(0)); 387 | REG_WRITE(I2S_CONF_REG(0), (REG_READ(I2S_CONF_REG(0)) & 0xfffffff0) | 0xf); 388 | (void) REG_READ(I2S_CONF_REG(0)); 389 | REG_WRITE(I2S_CONF_REG(0), REG_READ(I2S_CONF_REG(0)) & 0xfffffff0); 390 | 391 | SET_PERI_REG_BITS(I2S_CONF_REG(0), 0x1, 0, I2S_RX_START_S); 392 | i2s_running = false; 393 | } 394 | */ 395 | 396 | void TickI2SOut() 397 | { 398 | i2s_run(); 399 | } 400 | 401 | static void i2s_run() 402 | { 403 | // wait for vsync 404 | //ESP_LOGD(TAG, "Waiting for VSYNC"); 405 | //while(gpio_get_level(s_config.pin_vsync) != 0); 406 | //while(gpio_get_level(s_config.pin_vsync) == 0); 407 | ///ESP_LOGD(TAG, "Got VSYNC"); 408 | // wait a bit 409 | //delay(2); 410 | 411 | // start RX 412 | // line_count = 0; 413 | isr_countOut = 0; 414 | i2s_running = true; 415 | i2s_fill_buf(0); 416 | } 417 | 418 | static void IRAM_ATTR i2s_isr(void* arg) { 419 | REG_WRITE(I2S_INT_CLR_REG(0), (REG_READ(I2S_INT_RAW_REG(0)) & 0xffffffc0) | 0x3f); 420 | ++isr_countOut; 421 | } 422 | 423 | -------------------------------------------------------------------------------- /trunky/i2s_stream_out.h: -------------------------------------------------------------------------------- 1 | #ifndef _I2S_STREAM_H 2 | #define _I2S_STREAM_H 3 | 4 | 5 | #define BUFF_SIZE_BYTES 2048 6 | 7 | extern volatile unsigned isr_countOut; 8 | extern uint32_t * i2sbufferOut[3]; 9 | 10 | void SetupI2SOut(); 11 | void TickI2SOut(); 12 | 13 | #endif 14 | 15 | --------------------------------------------------------------------------------