From 458acb5e6706bcfd2f54cc4564efe5035c31bcbc Mon Sep 17 00:00:00 2001 From: Sven Weidauer Date: Tue, 28 Jan 2025 21:33:53 +0100 Subject: [PATCH] Import modified example project --- .gitignore | 2 + CMakeLists.txt | 8 ++ main/CMakeLists.txt | 5 ++ main/i2s_main.c | 173 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 188 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 main/CMakeLists.txt create mode 100644 main/i2s_main.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..99acd7b --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/build/ +sdkconfig* \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..647b8fb --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,8 @@ +# The following lines of boilerplate have to be in your project's CMakeLists +# in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(COMPONENTS main) + +project(i2stest) diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt new file mode 100644 index 0000000..fe20242 --- /dev/null +++ b/main/CMakeLists.txt @@ -0,0 +1,5 @@ +idf_component_register( + SRCS "i2s_main.c" + PRIV_REQUIRES esp_driver_i2s esp_driver_gpio esp_driver_i2c + INCLUDE_DIRS "." +) diff --git a/main/i2s_main.c b/main/i2s_main.c new file mode 100644 index 0000000..3b253d5 --- /dev/null +++ b/main/i2s_main.c @@ -0,0 +1,173 @@ +/* + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "driver/i2s_std.h" +#include "driver/gpio.h" +#include "esp_check.h" +#include "sdkconfig.h" +#include "driver/i2c_master.h" + +#define EXAMPLE_BUFF_SIZE 2048 + +static i2s_chan_handle_t tx_chan; // I2S tx channel handler +static i2s_chan_handle_t rx_chan; // I2S rx channel handler + +i2c_master_bus_config_t i2c_bus_config = { + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = -1, + .scl_io_num = GPIO_NUM_17, + .sda_io_num = GPIO_NUM_18, + .glitch_ignore_cnt = 7, + }; + i2c_master_bus_handle_t bus_handle; + +i2c_device_config_t chipconfig = { + .scl_speed_hz = 100000, + .device_address = 0b00100010 >> 1, +}; +static const char TAG[] = "i2c-eeprom"; +static void i2s_example_read_task(void *args) +{ + uint8_t *r_buf = (uint8_t *)calloc(1, EXAMPLE_BUFF_SIZE); + assert(r_buf); // Check if r_buf allocation success + size_t r_bytes = 0; + + /* Enable the RX channel */ + ESP_ERROR_CHECK(i2s_channel_enable(rx_chan)); + + /* ATTENTION: The print and delay in the read task only for monitoring the data by human, + * Normally there shouldn't be any delays to ensure a short polling time, + * Otherwise the dma buffer will overflow and lead to the data lost */ + while (1) { + /* Read i2s data */ + if (i2s_channel_read(rx_chan, r_buf, EXAMPLE_BUFF_SIZE, &r_bytes, 1000) == ESP_OK) { + printf("Read Task: i2s read %d bytes\n-----------------------------------\n", r_bytes); + printf("[0] %x [1] %x [2] %x [3] %x\n[4] %x [5] %x [6] %x [7] %x\n\n", + r_buf[0], r_buf[1], r_buf[2], r_buf[3], r_buf[4], r_buf[5], r_buf[6], r_buf[7]); + } else { + printf("Read Task: i2s read failed\n"); + } + vTaskDelay(pdMS_TO_TICKS(200)); + } + free(r_buf); + vTaskDelete(NULL); +} + +static void i2s_example_write_task(void *args) +{ + uint8_t *w_buf = (uint8_t *)calloc(1, EXAMPLE_BUFF_SIZE); + assert(w_buf); // Check if w_buf allocation success + + /* Assign w_buf */ + for (int i = 0; i < EXAMPLE_BUFF_SIZE; i += 8) { + w_buf[i] = 170; // 0x12; + w_buf[i + 1] = 170; // 0x34; + w_buf[i + 2] = 170; // 0x56; + w_buf[i + 3] = 170; // 0x78; + w_buf[i + 4] = 170; // 0x9A; + w_buf[i + 5] = 170; // 0xBC; + w_buf[i + 6] = 170; // 0xDE; + w_buf[i + 7] = 170; // 0xF0; + } + + size_t w_bytes = EXAMPLE_BUFF_SIZE; + + /* (Optional) Preload the data before enabling the TX channel, so that the valid data can be transmitted immediately */ + while (w_bytes == EXAMPLE_BUFF_SIZE) { + /* Here we load the target buffer repeatedly, until all the DMA buffers are preloaded */ + ESP_ERROR_CHECK(i2s_channel_preload_data(tx_chan, w_buf, EXAMPLE_BUFF_SIZE, &w_bytes)); + } + + /* Enable the TX channel */ + ESP_ERROR_CHECK(i2s_channel_enable(tx_chan)); + while (1) { + /* Write i2s data */ + if (i2s_channel_write(tx_chan, w_buf, EXAMPLE_BUFF_SIZE, &w_bytes, 1000) == ESP_OK) { + printf("Write Task: i2s write %d bytes\n", w_bytes); + } else { + printf("Write Task: i2s write failed\n"); + } + vTaskDelay(pdMS_TO_TICKS(200)); + } + free(w_buf); + vTaskDelete(NULL); +} + +static void i2s_example_init_std_duplex(void) +{ + /* Setp 1: Determine the I2S channel configuration and allocate both channels + * The default configuration can be generated by the helper macro, + * it only requires the I2S controller id and I2S role */ + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER); + ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_chan, &rx_chan)); + + /* Step 2: Setting the configurations of standard mode, and initialize rx & tx channels + * The slot configuration and clock configuration can be generated by the macros + * These two helper macros is defined in 'i2s_std.h' which can only be used in STD mode. + * They can help to specify the slot and clock configurations for initialization or re-configuring */ + i2s_std_config_t std_cfg = { + .clk_cfg = { + .sample_rate_hz = 16000, + .clk_src = I2S_CLK_SRC_DEFAULT, + .mclk_multiple = I2S_MCLK_MULTIPLE_512, + }, + .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO), + .gpio_cfg = { + .mclk = GPIO_NUM_21, + .bclk = GPIO_NUM_2, + .ws = GPIO_NUM_3, + .dout = GPIO_NUM_4, + .din = GPIO_NUM_5, + .invert_flags = { + .mclk_inv = false, + .bclk_inv = false, + .ws_inv = false, + }, + }, + }; + /* Initialize the channels */ + ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_chan, &std_cfg)); + ESP_ERROR_CHECK(i2s_channel_init_std_mode(rx_chan, &std_cfg)); +} + +i2c_master_dev_handle_t i2c_dev; + +void app_main(void) +{ + i2s_example_init_std_duplex(); + ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_config, &bus_handle)); + int ret; + + gpio_set_pull_mode(GPIO_NUM_17, GPIO_PULLUP_ONLY); + gpio_set_pull_mode(GPIO_NUM_18, GPIO_PULLUP_ONLY); + + ESP_GOTO_ON_ERROR(i2c_master_bus_add_device(bus_handle, &chipconfig, &i2c_dev), err, TAG, "i2c new bus failed"); + + while (1) { + for (int i = 0; i < 256; i++) { + if (i2c_master_probe(bus_handle, i, 1000) == ESP_OK) { + printf("Found %d\n", i); + } + } + } + + return; + + // Talk to configure dings + + + /* Step 3: Create writing and reading task, enable and start the channels */ + xTaskCreate(i2s_example_read_task, "i2s_example_read_task", 4096, NULL, 5, NULL); + xTaskCreate(i2s_example_write_task, "i2s_example_write_task", 4096, NULL, 5, NULL); + +err: + printf("Error\n"); + return; +}