Environment
Development Kit: ESP32-S3-DevKitC-1
Kit version : v1
IDF version : v4.4
Build System: idf.py
Compiler version : (crosstool-NG esp-2022r1-RC1) 11.2.0
Operating System: Windows 10
Using an IDE?: NO
Power Supply: USB
Problem Description
If I2S is configured as TDM8 Master, WS is correctly. But if I2S is configured as TDM9 to TDM16 Master, WS is not correctly.
Expected Behavior
If I2S is configured as TDM16 Master, The sample rate is configured 8000 Hz, WS output 8000 Hz.
Actual Behavior
If I2S is configured as TDM16 Master, The sample rate is configured 8000 Hz, WS output 16000 Hz.
Soure code:
#include <stdint.h>
#include <string.h>
#include <sys/time.h>
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "tinyusb.h"
#include "tusb_cdc_acm.h"
#include "sdkconfig.h"
#include "driver/i2c.h"
#include "driver/i2s.h"
#include "esp_task_wdt.h"
#include "esp_system.h"
#include "esp_check.h"
#define APP_VERSION "0.11"
#define TWDT_TIMEOUT_S 30 // task watchdog time
// TDM0
// GPIO11: TDM0_RX_MCLK
// GPIO12: TDM0_RX_BCLK
// GPIO13: TDM0_RX_LRCK
// GPIO14: TDM0_RX_DI
// GPIO17: TDM0_RX_IN
/* I2S port and GPIOs */
#define I2S_NUM (0)
#define I2S_MCK_IO (GPIO_NUM_11)
#define I2S_BCK_IO (GPIO_NUM_12)
#define I2S_WS_IO (GPIO_NUM_13)
//#define I2S_DO_IO (GPIO_NUM_14)
#define I2S_DI_IO (GPIO_NUM_14)
/* Example configurations */
#define I2S_RECV_BUF_SIZE (4000) // 4096
static const char *TAG = "GX I2S:";
static const char err_reason[][30] = {"input param is invalid",
"operation timeout"
};
static uint8_t buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE + 1];
// I2S0 register address: 0x6000_F000 - 0x6000_FFFF
i2s_config_t i2s_config = {
.mode = I2S_MODE_MASTER | I2S_MODE_RX,
.sample_rate = 8000,
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
.channel_format = I2S_CHANNEL_FMT_MULTIPLE,
.communication_format = I2S_COMM_FORMAT_STAND_PCM_SHORT,
.tx_desc_auto_clear = false,
.use_apll = true,
.fixed_mclk = 4096000, //12288000,
.mclk_multiple = 256,
.dma_buf_count = 64,
.dma_buf_len = 32, // 16
.total_chan = 16, //10, //16, // 8
.chan_mask = I2S_TDM_ACTIVE_CH0 | I2S_TDM_ACTIVE_CH1 | I2S_TDM_ACTIVE_CH2 | I2S_TDM_ACTIVE_CH3 | I2S_TDM_ACTIVE_CH4 | I2S_TDM_ACTIVE_CH5 | I2S_TDM_ACTIVE_CH6 | I2S_TDM_ACTIVE_CH7 | I2S_TDM_ACTIVE_CH8 | I2S_TDM_ACTIVE_CH9 | I2S_TDM_ACTIVE_CH10 | I2S_TDM_ACTIVE_CH11 | I2S_TDM_ACTIVE_CH12 | I2S_TDM_ACTIVE_CH13 | I2S_TDM_ACTIVE_CH14 | I2S_TDM_ACTIVE_CH15
//.total_chan = 10, //9, // 8
//.chan_mask = I2S_TDM_ACTIVE_CH0 | I2S_TDM_ACTIVE_CH1 | I2S_TDM_ACTIVE_CH2 | I2S_TDM_ACTIVE_CH3 | I2S_TDM_ACTIVE_CH4 | I2S_TDM_ACTIVE_CH5 | I2S_TDM_ACTIVE_CH6 | I2S_TDM_ACTIVE_CH7 | I2S_TDM_ACTIVE_CH8 | I2S_TDM_ACTIVE_CH9
};
#if 1
static const i2s_pin_config_t pin_config = {
.mck_io_num = I2S_MCK_IO,
.bck_io_num = I2S_BCK_IO,
.ws_io_num = I2S_WS_IO,
.data_out_num = I2S_PIN_NO_CHANGE,
.data_in_num = I2S_DI_IO
};
#endif
int16_t *mic_data;
void tinyusb_cdc_rx_callback(int itf, cdcacm_event_t *event)
{
/* initialization */
size_t rx_size = 0;
/* read */
esp_err_t ret = tinyusb_cdcacm_read(itf, buf, CONFIG_TINYUSB_CDC_RX_BUFSIZE, &rx_size);
if (ret == ESP_OK) {
buf[rx_size] = '\0';
} else {
//ESP_LOGE(TAG, "Read error");
}
/* write back */
//tinyusb_cdcacm_write_queue(itf, buf, rx_size);
//tinyusb_cdcacm_write_flush(itf, 0);
}
void tinyusb_cdc_line_state_changed_callback(int itf, cdcacm_event_t *event)
{
int dtr = event->line_state_changed_data.dtr;
int rts = event->line_state_changed_data.rts;
ESP_LOGI(TAG, "Line state changed! dtr:%d, rts:%d", dtr, rts);
}
void app_main(void)
{
int i;
size_t bytes_read = 0;
esp_err_t ret;
uint32_t ret_num = 0;
struct timeval tv_now;
int64_t time_us, time_us1;
time_t time1, time2, time3;
uint32_t send_pkg_cnt = 0;
gettimeofday(&tv_now, NULL);
time_us = (int64_t)tv_now.tv_sec * 1000000L + (int64_t)tv_now.tv_usec;
printf("Delay for 100 milliseconds\n");
vTaskDelay(pdMS_TO_TICKS(100)); //Delay for 100 ms
ESP_ERROR_CHECK(i2s_driver_install(I2S_NUM, &i2s_config, 0, NULL)); //install and start i2s driver
ESP_LOGI(TAG, "i2s_driver_install successfully");
ESP_ERROR_CHECK(i2s_set_pin(I2S_NUM, &pin_config));
ESP_LOGI(TAG, "i2s_set_pin successfully");
#if 1
ESP_LOGI(TAG, "USB initialization");
tinyusb_config_t tusb_cfg = {}; // the configuration using default values
ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));
tinyusb_config_cdcacm_t amc_cfg = {
.usb_dev = TINYUSB_USBDEV_0,
.cdc_port = TINYUSB_CDC_ACM_0,
.rx_unread_buf_sz = 64, //CONFIG_TINYUSB_CDC_RX_BUFSIZE, // 64
.callback_rx = &tinyusb_cdc_rx_callback, // the first way to register a callback
.callback_rx_wanted_char = NULL,
.callback_line_state_changed = NULL,
.callback_line_coding_changed = NULL
};
ESP_ERROR_CHECK(tusb_cdc_acm_init(&amc_cfg));
/* the second way to register a callback */
ESP_ERROR_CHECK(tinyusb_cdcacm_register_callback(
TINYUSB_CDC_ACM_0,
CDC_EVENT_LINE_STATE_CHANGED,
&tinyusb_cdc_line_state_changed_callback));
ESP_LOGI(TAG, "USB initialization DONE");
#endif
unsigned int cnt = 0;
mic_data = malloc(I2S_RECV_BUF_SIZE);
if (!mic_data) {
ESP_LOGE(TAG, "[i2s_to_usb] No memory for read data buffer");
abort();
}
ret = ESP_OK;
ESP_LOGI(TAG, "Running ......");
time(&time1);
time3 = time1;
while(1) {
#if 1
//size_t bytes_read = 0;
//bytes_write = 0;
ret = i2s_read(I2S_NUM, &mic_data[0], I2S_RECV_BUF_SIZE, &bytes_read, 100);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "[i2s_to_usb] i2s read failed, %s", err_reason[ret == ESP_ERR_TIMEOUT]);
abort();
}
if(bytes_read != I2S_RECV_BUF_SIZE) {
printf("%s\n", "bytes_read != I2S_RECV_BUF_SIZE");
}
else {
send_pkg_cnt ++;
}
#endif
#if 1
tinyusb_cdcacm_write_queue(TINYUSB_CDC_ACM_0, (uint8_t *)mic_data, bytes_read); //CONFIG_TINYUSB_CDC_RX_BUFSIZE);
esp_err_t retU1;
retU1 = tinyusb_cdcacm_write_flush(TINYUSB_CDC_ACM_0, 0);
//if(retU1 != ESP_OK) {
// printf("retU1 = %d\n", retU1);
//}
#endif
time(&time2);
if(time2 - time1 >= 10) {
time1 = time2;
ESP_LOGI(TAG, "Running ......");
}
}
}
About Esp32-S3 I2S 16 channnel TDM
Return to “General Discussion”
Jump to
- English Forum
- Explore
- News
- General Discussion
- FAQ
- Documentation
- Documentation
- Sample Code
- Discussion Forum
- Hardware
- ESP-IDF
- ESP-BOX
- ESP-ADF
- ESP-MDF
- ESP-WHO
- ESP-SkaiNet
- ESP32 Arduino
- IDEs for ESP-IDF
- ESP-AT
- ESP IoT Solution
- ESP RainMaker
- Rust
- ESP8266
- Report Bugs
- Showcase
- Chinese Forum 中文社区
- 活动区
- 乐鑫活动专区
- 讨论区
- 全国大学生物联网设计竞赛乐鑫答疑专区
- ESP-IDF 中文讨论版
- 《ESP32-C3 物联网工程开发实战》书籍讨论版
- 中文文档讨论版
- ESP-AT 中文讨论版
- ESP-BOX 中文讨论版
- ESP IoT Solution 中文讨论版
- ESP-ADF 中文讨论版
- ESP Mesh 中文讨论版
- ESP Cloud 中文讨论版
- ESP-WHO 中文讨论版
- ESP-SkaiNet 中文讨论版
- ESP 生产支持讨论版
- 硬件问题讨论
- 项目展示
Who is online
Users browsing this forum: Baidu [Spider] and 85 guests
- All times are UTC
- Top
- Delete cookies
About Us
Espressif Systems is a fabless semiconductor company providing cutting-edge low power WiFi SoCs and wireless solutions for wireless communications and Internet of Things applications. ESP8266EX and ESP32 are some of our products.