espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.33k stars 7.2k forks source link

ESP32-P4 APLL/MCLK/WS not working at TDM8 32-bit (IDFGH-13404) #14311

Open ftab opened 1 month ago

ftab commented 1 month ago

Answers checklist.

IDF version.

v5.3

Espressif SoC revision.

ESP32-P4 v0.1

Operating System used.

Linux

How did you build your project?

Command line with idf.py

If you are using Windows, please specify command line type.

None

Development Kit.

ESP32-P4 EV board

Power Supply used.

USB

What is the expected behavior?

Create I2S clock from APLL

What is the actual behavior?

fails to initialize clock

Steps to reproduce.

Using ESP-ADF i2s_stream in a simple audio pipeline to read /usb/test.mp3, split from 2 to 8 channels with our audio DSP code, then play to a PCM1681 (8ch DAC) over I2S TDM

Here is the snippet of code where the i2s stream is set up

#define I2S_STREAM_TDM_CFG_44_1_8CH() {                                          \
    .type = AUDIO_STREAM_WRITER,                                                \
    .transmit_mode = I2S_COMM_MODE_TDM,                                         \
    .chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER),         \
    .tdm_cfg = {                                                                \
        .clk_cfg  = { \
            .sample_rate_hz = 44100, \
            .clk_src = I2S_CLK_SRC_APLL, \
            .mclk_multiple = I2S_MCLK_MULTIPLE_768, \
            .bclk_div = 8, /* only takes effect for slave role */ \
        },                          \
        .slot_cfg = I2S_TDM_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO, \
                                                        I2S_TDM_SLOT0 | I2S_TDM_SLOT1 | I2S_TDM_SLOT2 | I2S_TDM_SLOT3 | \
                                                        I2S_TDM_SLOT4 | I2S_TDM_SLOT5 | I2S_TDM_SLOT6 | I2S_TDM_SLOT7), \
        .gpio_cfg = {                                                           \
            .invert_flags = {                                                   \
                .mclk_inv = false,                                              \
                .bclk_inv = false,                                              \
                .ws_inv   = false,                                              \
            },                                                                  \
        },                                                                      \
    },                                                                          \
    .use_alc = false,                                                           \
    .volume = 0,                                                                \
    .out_rb_size = I2S_STREAM_RINGBUFFER_SIZE,                                  \
    .task_stack = I2S_STREAM_TASK_STACK,                                        \
    .task_core = I2S_STREAM_TASK_CORE,                                          \
    .task_prio = I2S_STREAM_TASK_PRIO,                                          \
    .stack_in_ext = false,                                                      \
    .multi_out_num = 0,                                                         \
    .uninstall_drv = true,                                                      \
    .need_expand = false,                                                       \
    .expand_src_bits = I2S_DATA_BIT_WIDTH_32BIT,                                \
    .buffer_len = I2S_STREAM_BUF_SIZE,                                          \
}

void create_audio_output()
{
    ESP_LOGI(TAG, "[5.0] Create i2s stream to write data to codec chip");
    i2s_stream_cfg_t i2s_cfg = I2S_STREAM_TDM_CFG_44_1_8CH();
    i2s_cfg.chan_cfg.dma_desc_num = 4;
    i2s_cfg.chan_cfg.dma_frame_num = 120;
    stream_writer = i2s_stream_init(&i2s_cfg);
}

Debug Logs.

--- esp-idf-monitor 1.4.0 on /dev/ttyUSB1 2000000 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
I (25) boot: ESP-IDF v5.3-3-ge8ae8f1399-dirty 2nd stage bootloader
I (26) boot: compile time Aug  5 2024 19:02:28
I (26) boot: Multicore bootloader
I (28) boot: chip revision: v0.1
I (28) qio_mode: Enabling default flash chip QIO
I (28) boot.esp32p4: SPI Speed      : 80MHz
I (29) boot.esp32p4: SPI Mode       : QIO
I (29) boot.esp32p4: SPI Flash Size : 16MB
I (29) boot: Enabling RNG early entropy source...
I (30) boot: Partition Table:
I (30) boot: ## Label            Usage          Type ST Offset   Length
I (30) boot:  0 nvs              WiFi data        01 02 00009000 00004000
I (31) boot:  1 otadata          OTA data         01 00 0000d000 00002000
I (31) boot:  2 ota_0            OTA app          00 10 00010000 00380000
I (32) boot:  3 ota_1            OTA app          00 11 00390000 00380000
I (32) boot:  4 storage          Unknown data     01 82 00710000 00080000
I (33) boot:  5 fctry            WiFi data        01 02 00790000 00006000
I (33) boot:  6 coredump         Unknown data     01 03 00796000 00013000
I (35) boot: End of partition table
I (37) esp_image: segment 0: paddr=00010020 vaddr=400a0020 size=207d0h (133072) map
I (62) esp_image: segment 1: paddr=000307f8 vaddr=30100000 size=0000ch (    12) load
I (64) esp_image: segment 2: paddr=0003080c vaddr=3010000c size=00038h (    56) load
I (66) esp_image: segment 3: paddr=0003084c vaddr=4ff00000 size=0f7cch ( 63436) load
I (81) esp_image: segment 4: paddr=00040020 vaddr=40000020 size=93a14h (604692) map
I (188) esp_image: segment 5: paddr=000d3a3c vaddr=4ff0f7cc size=015f8h (  5624) load
I (191) esp_image: segment 6: paddr=000d503c vaddr=4ff10e00 size=01d60h (  7520) load
I (198) boot: Loaded app from partition at offset 0x10000
I (198) boot: Disabling RNG early entropy source...
I (200) cpu_start: Multicore app
W (211) clk: esp_perip_clk_init() has not been implemented yet
I (212) cpu_start: Pro cpu start user code
I (212) cpu_start: cpu freq: 360000000 Hz
I (212) app_init: Application information:
I (212) app_init: Project name:     p4-test
I (212) app_init: App version:      359f8f2-dirty
I (213) app_init: Compile time:     Aug  6 2024 11:06:53
I (213) app_init: ELF file SHA256:  4eb463848...
I (213) app_init: ESP-IDF:          v5.3-3-ge8ae8f1399-dirty
I (213) efuse_init: Min chip rev:     v0.1
I (214) efuse_init: Max chip rev:     v0.99 
I (214) efuse_init: Chip rev:         v0.1
I (214) heap_init: Initializing. RAM available for dynamic allocation:
I (215) heap_init: At 4FF159C0 len 00025600 (149 KiB): RAM
I (215) heap_init: At 4FF3AFC0 len 00004BF0 (18 KiB): RAM
I (215) heap_init: At 4FF40000 len 00060000 (384 KiB): RAM
I (216) heap_init: At 50108080 len 00007F80 (31 KiB): RTCRAM
I (216) heap_init: At 30100044 len 00001FBC (7 KiB): TCM
I (217) spi_flash: detected chip: generic
I (218) spi_flash: flash io: qio
W (218) i2c: This driver is an old driver, please migrate your application code to adapt `driver/i2c_master.h`
I (219) main_task: Started on CPU0
I (267) main_task: Calling app_main()
E (273) p4-test: ESP-ADF:   v2.6-158-gadc656b0-dirty
I (274) spiffs: Initializing SPIFFS
I (297) spiffs: Partition size: total: 474641, used: 5271
I (299) dsp: [57][processConfigFile:149]   Reading config file '/spiffs/8ch.dspcfg'
...snip...
I (442) dsp: [e6][processConfigFile:379]   DSP is ready to rumble
I (442) AUD: [ 2.1 ] Start USB host
W (442) UsbHostTask: in UsbHostInit
I (473) AUD: [2.2] Create fatfs stream to read data from usb
W (473) UsbHostTask: in UsbHostTask
I (473) AUD: [2.3] Create mp3 decoder
I (473) MP3_DECODER: MP3 init
I (473) AUD: [2.4] Register stream_reader to audio pipeline
I (474) AUD: [2.5] Waiting for USB file system to be ready
W (473) UsbHostTask: in UsbHostTask's while loop
W (475) UsbHostTask: in HandleMscDevice
W (473) UsbHostTask: in handle_usb_events
W (475) UsbHostTask: in handle_usb_events's while loop
I (476) UsbHostTask: Waiting for USB stick to be connected
W (476) UsbHostTask: in wait_for_msc_device_condition
W (990) UsbHostTask: in msc_event_cb
I (990) UsbHostTask: MSC device connected
*** Device descriptor ***
...snip...
I (1242) AUD: [2.6] Playing file: /usb/test.mp3
I (1242) AUD: [5.0] Create i2s stream to write data to codec chip
E (1243) esp_clk_tree: esp_clk_tree_src_get_freq_hz(82): freq shouldn't be 0, calibration failed
E (1243) i2s_tdm: i2s_tdm_calculate_clock(64): sample rate is too large for the current clock source
E (1243) i2s_tdm: i2s_tdm_set_clock(76): clock calculate failed
E (1244) i2s_tdm: i2s_channel_init_tdm_mode(231): initialize channel failed while setting clock
E (1244) I2S_STREAM_IDF5.x: I2S stream init failed

More Information.

Using my fork of ESP-ADF that hacks some stuff out to work on the P4 as ESP-ADF v2.7 is not released yet: https://github.com/radiosound-com/esp-adf/tree/radiosound-modded-v2.6-141-g218cf614-idf-v5.3-modded

When I change I2S_CLK_SRC_APLL to I2S_CLK_SRC_DEFAULT, i2s does initialize, but MCLK is running at 20mhz (expected: 44,100 x 768 = 33,868,800) and WS runs at 26khz instead of 44.1khz

ftab commented 1 month ago

Just spotted in esp-idf/components/esp_hw_support/port/esp32p4/esp_clk_tree.c:

// case SOC_MOD_CLK_APLL: TODO: IDF-8884

That explains the APLL not working. How can I stay apprised of the status of IDF-8884? Any word on when it's planned to be implemented?

DatanoiseTV commented 4 weeks ago

Same issue here - trying to work with TDM16. It is partially working at 22050Hz, but not properly.

L-KAYA commented 2 weeks ago

Hi @ftab @DatanoiseTV , thanks for your reporting! I2S on P4 only has XTAL and APLL two internal clock sources (the PLL clock source is not supported). As APLL support has not merged yet, I2S can only use XTAL clock for now, which is up to 40MHz.

See the similar issue #14448. And the APLL support patch is uploaded there for testing.

ftab commented 2 weeks ago

Hi @ftab @DatanoiseTV , thanks for your reporting!

I2S on P4 only has XTAL and APLL two internal clock sources (the PLL clock source is not supported). As APLL support has not merged yet, I2S can only use XTAL clock for now, which is up to 40MHz.

See the similar issue #14448. And the APLL support patch is uploaded there for testing.

I can confirm the patch works. Thanks!

L-KAYA commented 1 week ago

FYI, APLL has been supported on the master in this commit

You can rebase on the master to use APLL as well