From a67517067c733f6de4063d75cfc692b9dc8acc2e Mon Sep 17 00:00:00 2001 From: Chen Jichang Date: Tue, 25 Nov 2025 10:29:22 +0800 Subject: [PATCH] feat(parlio): support parlio on esp32h4 --- components/esp_driver_parlio/linker.lf | 2 +- components/esp_driver_parlio/src/parlio_rx.c | 12 +- components/esp_driver_parlio/src/parlio_tx.c | 16 +- .../test_apps/parlio/README.md | 4 +- .../test_apps/parlio/main/test_board.h | 12 + .../test_apps/parlio/main/test_parlio_rx.c | 6 +- .../esp_hal_parlio/esp32c5/parlio_periph.c | 80 +- .../esp_hal_parlio/esp32c6/parlio_periph.c | 112 ++- .../esp_hal_parlio/esp32h2/parlio_periph.c | 80 +- .../esp32h4/include/hal/parlio_ll.h | 722 ++++++++++++++++++ .../esp_hal_parlio/esp32h4/parlio_periph.c | 79 ++ .../esp_hal_parlio/esp32p4/parlio_periph.c | 112 ++- .../include/hal/parlio_periph.h | 35 +- .../esp_lcd/test_apps/parlio_lcd/README.md | 4 +- .../parlio_lcd/main/test_parlio_board.h | 14 + .../esp32h4/include/soc/Kconfig.soc_caps.in | 36 + .../soc/esp32h4/include/soc/clk_tree_defs.h | 18 + components/soc/esp32h4/include/soc/soc_caps.h | 12 +- .../soc/esp32h4/register/soc/parl_io_struct.h | 296 +++---- .../soc/esp32h4/register/soc/pcr_struct.h | 2 +- docs/docs_not_updated/esp32h4.txt | 1 - .../peripherals/lcd/parlio_simulate/README.md | 4 +- .../sdkconfig.defaults.esp32h4 | 18 + .../parlio/parlio_rx/logic_analyzer/README.md | 4 +- .../parlio_tx/simple_rgb_led_matrix/README.md | 4 +- 25 files changed, 1289 insertions(+), 396 deletions(-) create mode 100644 components/esp_hal_parlio/esp32h4/include/hal/parlio_ll.h create mode 100644 components/esp_hal_parlio/esp32h4/parlio_periph.c create mode 100644 examples/peripherals/lcd/parlio_simulate/sdkconfig.defaults.esp32h4 diff --git a/components/esp_driver_parlio/linker.lf b/components/esp_driver_parlio/linker.lf index a5dbf62783..03b303a963 100644 --- a/components/esp_driver_parlio/linker.lf +++ b/components/esp_driver_parlio/linker.lf @@ -37,4 +37,4 @@ entries: archive: libesp_hal_parlio.a entries: if PARLIO_RX_ISR_HANDLER_IN_IRAM = y: - parlio_periph: parlio_periph_signals (noflash) + parlio_periph: soc_parlio_signals (noflash) diff --git a/components/esp_driver_parlio/src/parlio_rx.c b/components/esp_driver_parlio/src/parlio_rx.c index cfbb1ced59..ebbab78271 100644 --- a/components/esp_driver_parlio/src/parlio_rx.c +++ b/components/esp_driver_parlio/src/parlio_rx.c @@ -263,7 +263,7 @@ static esp_err_t parlio_rx_unit_set_gpio(parlio_rx_unit_handle_t rx_unit, const /* Connect the clock in signal to the GPIO matrix if it is set */ gpio_input_enable(config->clk_in_gpio_num); esp_rom_gpio_connect_in_signal(config->clk_in_gpio_num, - parlio_periph_signals.groups[group_id].rx_units[unit_id].clk_in_sig, false); + soc_parlio_signals[group_id].rx_units[unit_id].clk_in_sig, false); } /* When the source clock comes from internal and supported to output the internal clock, * enable the gpio output direction and connect to the clock output signal */ @@ -272,7 +272,7 @@ static esp_err_t parlio_rx_unit_set_gpio(parlio_rx_unit_handle_t rx_unit, const gpio_func_sel(config->clk_out_gpio_num, PIN_FUNC_GPIO); // connect the signal to the GPIO by matrix, it will also enable the output path properly esp_rom_gpio_connect_out_signal(config->clk_out_gpio_num, - parlio_periph_signals.groups[group_id].rx_units[unit_id].clk_out_sig, false, false); + soc_parlio_signals[group_id].rx_units[unit_id].clk_out_sig, false, false); #else ESP_RETURN_ON_FALSE(false, ESP_ERR_NOT_SUPPORTED, TAG, "this target not support to output the clock"); #endif // PARLIO_LL_SUPPORT(RX_CLK_OUTPUT) @@ -290,7 +290,7 @@ static esp_err_t parlio_rx_unit_set_gpio(parlio_rx_unit_handle_t rx_unit, const if (config->data_gpio_nums[i] >= 0) { gpio_input_enable(config->data_gpio_nums[i]); esp_rom_gpio_connect_in_signal(config->data_gpio_nums[i], - parlio_periph_signals.groups[group_id].rx_units[unit_id].data_sigs[i], false); + soc_parlio_signals[group_id].rx_units[unit_id].data_sigs[i], false); } else { ESP_LOGW(TAG, "data line %d not assigned", i); } @@ -528,7 +528,7 @@ static esp_err_t parlio_select_periph_clock(parlio_rx_unit_handle_t rx_unit, con // use CPU_MAX lock to ensure PSRAM bandwidth and usability during DFS lock_type = ESP_PM_CPU_FREQ_MAX; #endif - esp_err_t ret = esp_pm_lock_create(lock_type, 0, parlio_periph_signals.groups[rx_unit->base.group->group_id].module_name, &rx_unit->pm_lock); + esp_err_t ret = esp_pm_lock_create(lock_type, 0, soc_parlio_signals[rx_unit->base.group->group_id].module_name, &rx_unit->pm_lock); ESP_RETURN_ON_ERROR(ret, TAG, "create pm lock failed"); } #endif @@ -993,7 +993,7 @@ esp_err_t parlio_rx_unit_receive(parlio_rx_unit_handle_t rx_unit, ESP_RETURN_ON_FALSE(recv_cfg->delimiter->valid_sig_line_id >= rx_unit->cfg.data_width, ESP_ERR_INVALID_ARG, TAG, "the valid_sig_line_id of this delimiter is conflict with rx unit data width"); /* Assign the signal here to ensure iram safe */ - recv_cfg->delimiter->valid_sig = parlio_periph_signals.groups[rx_unit->base.group->group_id]. + recv_cfg->delimiter->valid_sig = soc_parlio_signals[rx_unit->base.group->group_id]. rx_units[rx_unit->base.unit_id]. data_sigs[recv_cfg->delimiter->valid_sig_line_id]; } @@ -1058,7 +1058,7 @@ esp_err_t parlio_rx_unit_receive_from_isr(parlio_rx_unit_handle_t rx_unit, * Specifically, level or pulse delimiter requires one data line as valid signal, so these two delimiters can't support PARLIO_RX_UNIT_MAX_DATA_WIDTH */ PARLIO_RX_CHECK_ISR(recv_cfg->delimiter->valid_sig_line_id >= rx_unit->cfg.data_width, ESP_ERR_INVALID_ARG); /* Assign the signal here to ensure iram safe */ - recv_cfg->delimiter->valid_sig = parlio_periph_signals.groups[rx_unit->base.group->group_id]. + recv_cfg->delimiter->valid_sig = soc_parlio_signals[rx_unit->base.group->group_id]. rx_units[rx_unit->base.unit_id]. data_sigs[recv_cfg->delimiter->valid_sig_line_id]; } diff --git a/components/esp_driver_parlio/src/parlio_tx.c b/components/esp_driver_parlio/src/parlio_tx.c index 09f0795021..0e138839bf 100644 --- a/components/esp_driver_parlio/src/parlio_tx.c +++ b/components/esp_driver_parlio/src/parlio_tx.c @@ -95,7 +95,7 @@ static esp_err_t parlio_tx_unit_configure_gpio(parlio_tx_unit_t *tx_unit, const gpio_func_sel(config->data_gpio_nums[i], PIN_FUNC_GPIO); // connect the signal to the GPIO by matrix, it will also enable the output path properly esp_rom_gpio_connect_out_signal(config->data_gpio_nums[i], - parlio_periph_signals.groups[group_id].tx_units[unit_id].data_sigs[i], false, false); + soc_parlio_signals[group_id].tx_units[unit_id].data_sigs[i], false, false); tx_unit->data_gpio_nums[i] = config->data_gpio_nums[i]; } } @@ -108,13 +108,13 @@ static esp_err_t parlio_tx_unit_configure_gpio(parlio_tx_unit_t *tx_unit, const // Note: the default value of CS signal is low, so we need to invert the CS to keep compatible with the default value // connect the signal to the GPIO by matrix, it will also enable the output path properly esp_rom_gpio_connect_out_signal(config->valid_gpio_num, - parlio_periph_signals.groups[group_id].tx_units[unit_id].cs_sig, + soc_parlio_signals[group_id].tx_units[unit_id].cs_sig, !config->flags.invert_valid_out, false); #else // connect the signal to the GPIO by matrix, it will also enable the output path properly // Note: the valid signal will override TXD[PARLIO_LL_TX_DATA_LINE_AS_VALID_SIG] esp_rom_gpio_connect_out_signal(config->valid_gpio_num, - parlio_periph_signals.groups[group_id].tx_units[unit_id].data_sigs[PARLIO_LL_TX_DATA_LINE_AS_VALID_SIG], + soc_parlio_signals[group_id].tx_units[unit_id].data_sigs[PARLIO_LL_TX_DATA_LINE_AS_VALID_SIG], config->flags.invert_valid_out, false); #endif // !PARLIO_LL_TX_DATA_LINE_AS_VALID_SIG tx_unit->valid_gpio_num = config->valid_gpio_num; @@ -123,13 +123,13 @@ static esp_err_t parlio_tx_unit_configure_gpio(parlio_tx_unit_t *tx_unit, const gpio_func_sel(config->clk_out_gpio_num, PIN_FUNC_GPIO); // connect the signal to the GPIO by matrix, it will also enable the output path properly esp_rom_gpio_connect_out_signal(config->clk_out_gpio_num, - parlio_periph_signals.groups[group_id].tx_units[unit_id].clk_out_sig, false, false); + soc_parlio_signals[group_id].tx_units[unit_id].clk_out_sig, false, false); tx_unit->clk_out_gpio_num = config->clk_out_gpio_num; } if (config->clk_in_gpio_num >= 0) { gpio_input_enable(config->clk_in_gpio_num); esp_rom_gpio_connect_in_signal(config->clk_in_gpio_num, - parlio_periph_signals.groups[group_id].tx_units[unit_id].clk_in_sig, false); + soc_parlio_signals[group_id].tx_units[unit_id].clk_in_sig, false); tx_unit->clk_in_gpio_num = config->clk_in_gpio_num; } return ESP_OK; @@ -215,7 +215,7 @@ static esp_err_t parlio_select_periph_clock(parlio_tx_unit_t *tx_unit, const par // use CPU_MAX lock to ensure PSRAM bandwidth and usability during DFS lock_type = ESP_PM_CPU_FREQ_MAX; #endif - esp_err_t ret = esp_pm_lock_create(lock_type, 0, parlio_periph_signals.groups[tx_unit->base.group->group_id].module_name, &tx_unit->pm_lock); + esp_err_t ret = esp_pm_lock_create(lock_type, 0, soc_parlio_signals[tx_unit->base.group->group_id].module_name, &tx_unit->pm_lock); ESP_RETURN_ON_ERROR(ret, TAG, "create pm lock failed"); } #endif @@ -296,7 +296,7 @@ esp_err_t parlio_new_tx_unit(const parlio_tx_unit_config_t *config, parlio_tx_un // install interrupt service int isr_flags = PARLIO_TX_INTR_ALLOC_FLAG; - ret = esp_intr_alloc_intrstatus(parlio_periph_signals.groups[group->group_id].tx_irq_id, isr_flags, + ret = esp_intr_alloc_intrstatus(soc_parlio_signals[group->group_id].tx_irq_id, isr_flags, (uint32_t)parlio_ll_get_interrupt_status_reg(hal->regs), PARLIO_LL_EVENT_TX_MASK, parlio_tx_default_isr, unit, &unit->intr); ESP_GOTO_ON_ERROR(ret, err, TAG, "install interrupt failed"); @@ -390,7 +390,7 @@ esp_err_t parlio_del_tx_unit(parlio_tx_unit_handle_t unit) } if (unit->clk_in_gpio_num >= 0) { esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, - parlio_periph_signals.groups[unit->base.group->group_id].tx_units[unit->base.unit_id].clk_in_sig, + soc_parlio_signals[unit->base.group->group_id].tx_units[unit->base.unit_id].clk_in_sig, false); } return parlio_destroy_tx_unit(unit); diff --git a/components/esp_driver_parlio/test_apps/parlio/README.md b/components/esp_driver_parlio/test_apps/parlio/README.md index 92d72d31c7..1b93f0ab44 100644 --- a/components/esp_driver_parlio/test_apps/parlio/README.md +++ b/components/esp_driver_parlio/test_apps/parlio/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | -| ----------------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-H4 | ESP32-P4 | +| ----------------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/esp_driver_parlio/test_apps/parlio/main/test_board.h b/components/esp_driver_parlio/test_apps/parlio/main/test_board.h index dc8251b599..5203612f8f 100644 --- a/components/esp_driver_parlio/test_apps/parlio/main/test_board.h +++ b/components/esp_driver_parlio/test_apps/parlio/main/test_board.h @@ -56,6 +56,18 @@ extern "C" { #define TEST_DATA5_GPIO 11 #define TEST_DATA6_GPIO 26 #define TEST_DATA7_GPIO 12 +#elif CONFIG_IDF_TARGET_ESP32H4 +#define TEST_CLK_GPIO 15 +#define TEST_EXT_CLK_GPIO 16 +#define TEST_VALID_GPIO 17 +#define TEST_DATA0_GPIO 0 +#define TEST_DATA1_GPIO 1 +#define TEST_DATA2_GPIO 2 +#define TEST_DATA3_GPIO 3 +#define TEST_DATA4_GPIO 4 +#define TEST_DATA5_GPIO 5 +#define TEST_DATA6_GPIO 13 +#define TEST_DATA7_GPIO 14 #elif CONFIG_IDF_TARGET_ESP32P4 #define TEST_CLK_GPIO 33 #define TEST_EXT_CLK_GPIO 34 diff --git a/components/esp_driver_parlio/test_apps/parlio/main/test_parlio_rx.c b/components/esp_driver_parlio/test_apps/parlio/main/test_parlio_rx.c index 91e3a18ae6..e9b24ccf77 100644 --- a/components/esp_driver_parlio/test_apps/parlio/main/test_parlio_rx.c +++ b/components/esp_driver_parlio/test_apps/parlio/main/test_parlio_rx.c @@ -223,13 +223,13 @@ static void level_delimiter_sender_task_spi(void *args) // Connect SPI signals to parlio rx signals connect_signal_internally(TEST_CLK_GPIO, spi_periph_signal[TEST_SPI_HOST].spiclk_out, - parlio_periph_signals.groups[0].rx_units[0].clk_in_sig); + soc_parlio_signals[0].rx_units[0].clk_in_sig); connect_signal_internally(TEST_VALID_GPIO, spi_periph_signal[TEST_SPI_HOST].spics_out[0], - parlio_periph_signals.groups[0].rx_units[0].data_sigs[TEST_VALID_SIG]); + soc_parlio_signals[0].rx_units[0].data_sigs[TEST_VALID_SIG]); connect_signal_internally(TEST_DATA0_GPIO, spi_periph_signal[TEST_SPI_HOST].spid_out, - parlio_periph_signals.groups[0].rx_units[0].data_sigs[0]); + soc_parlio_signals[0].rx_units[0].data_sigs[0]); // Prepare the data the be transmitted uint8_t *data = NULL; diff --git a/components/esp_hal_parlio/esp32c5/parlio_periph.c b/components/esp_hal_parlio/esp32c5/parlio_periph.c index 7e27e9a364..73bd7e51bd 100644 --- a/components/esp_hal_parlio/esp32c5/parlio_periph.c +++ b/components/esp_hal_parlio/esp32c5/parlio_periph.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,47 +7,45 @@ #include "hal/parlio_periph.h" #include "soc/gpio_sig_map.h" -const parlio_signal_conn_t parlio_periph_signals = { - .groups = { - [0] = { - .module_name = "PARLIO0", - .tx_irq_id = ETS_PARL_IO_TX_INTR_SOURCE, - .rx_irq_id = ETS_PARL_IO_RX_INTR_SOURCE, - .tx_units = { - [0] = { - .data_sigs = { - PARL_TX_DATA0_IDX, - PARL_TX_DATA1_IDX, - PARL_TX_DATA2_IDX, - PARL_TX_DATA3_IDX, - PARL_TX_DATA4_IDX, - PARL_TX_DATA5_IDX, - PARL_TX_DATA6_IDX, - PARL_TX_DATA7_IDX, - }, - .clk_out_sig = PARL_TX_CLK_OUT_IDX, - .clk_in_sig = PARL_TX_CLK_IN_IDX, - .cs_sig = PARL_TX_CS_O_IDX, - } - }, - .rx_units = { - [0] = { - .data_sigs = { - PARL_RX_DATA0_IDX, - PARL_RX_DATA1_IDX, - PARL_RX_DATA2_IDX, - PARL_RX_DATA3_IDX, - PARL_RX_DATA4_IDX, - PARL_RX_DATA5_IDX, - PARL_RX_DATA6_IDX, - PARL_RX_DATA7_IDX, - }, - .clk_out_sig = PARL_RX_CLK_OUT_IDX, - .clk_in_sig = PARL_RX_CLK_IN_IDX, - } +const soc_parlio_signal_desc_t soc_parlio_signals[1] = { + [0] = { + .module_name = "PARLIO0", + .tx_irq_id = ETS_PARL_IO_TX_INTR_SOURCE, + .rx_irq_id = ETS_PARL_IO_RX_INTR_SOURCE, + .tx_units = { + [0] = { + .data_sigs = { + PARL_TX_DATA0_IDX, + PARL_TX_DATA1_IDX, + PARL_TX_DATA2_IDX, + PARL_TX_DATA3_IDX, + PARL_TX_DATA4_IDX, + PARL_TX_DATA5_IDX, + PARL_TX_DATA6_IDX, + PARL_TX_DATA7_IDX, + }, + .clk_out_sig = PARL_TX_CLK_OUT_IDX, + .clk_in_sig = PARL_TX_CLK_IN_IDX, + .cs_sig = PARL_TX_CS_O_IDX, } }, - }, + .rx_units = { + [0] = { + .data_sigs = { + PARL_RX_DATA0_IDX, + PARL_RX_DATA1_IDX, + PARL_RX_DATA2_IDX, + PARL_RX_DATA3_IDX, + PARL_RX_DATA4_IDX, + PARL_RX_DATA5_IDX, + PARL_RX_DATA6_IDX, + PARL_RX_DATA7_IDX, + }, + .clk_out_sig = PARL_RX_CLK_OUT_IDX, + .clk_in_sig = PARL_RX_CLK_IN_IDX, + } + } + } }; /** @@ -72,7 +70,7 @@ static const regdma_entries_config_t parlio_regs_retention[] = { .owner = ENTRY(0) | ENTRY(2) }, \ }; -const parlio_reg_retention_info_t parlio_reg_retention_info[PARLIO_LL_GET(INST_NUM)] = { +const parlio_reg_retention_info_t parlio_reg_retention_info[1] = { [0] = { .regdma_entry_array = parlio_regs_retention, .array_size = ARRAY_SIZE(parlio_regs_retention), diff --git a/components/esp_hal_parlio/esp32c6/parlio_periph.c b/components/esp_hal_parlio/esp32c6/parlio_periph.c index fa9d843f9b..182e8b0822 100644 --- a/components/esp_hal_parlio/esp32c6/parlio_periph.c +++ b/components/esp_hal_parlio/esp32c6/parlio_periph.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,63 +7,61 @@ #include "hal/parlio_periph.h" #include "soc/gpio_sig_map.h" -const parlio_signal_conn_t parlio_periph_signals = { - .groups = { - [0] = { - .module_name = "PARLIO0", - .tx_irq_id = ETS_PARL_IO_INTR_SOURCE, - .rx_irq_id = ETS_PARL_IO_INTR_SOURCE, - .tx_units = { - [0] = { - .data_sigs = { - PARL_TX_DATA0_IDX, - PARL_TX_DATA1_IDX, - PARL_TX_DATA2_IDX, - PARL_TX_DATA3_IDX, - PARL_TX_DATA4_IDX, - PARL_TX_DATA5_IDX, - PARL_TX_DATA6_IDX, - PARL_TX_DATA7_IDX, - PARL_TX_DATA8_IDX, - PARL_TX_DATA9_IDX, - PARL_TX_DATA10_IDX, - PARL_TX_DATA11_IDX, - PARL_TX_DATA12_IDX, - PARL_TX_DATA13_IDX, - PARL_TX_DATA14_IDX, - PARL_TX_DATA15_IDX, - }, - .clk_out_sig = PARL_TX_CLK_OUT_IDX, - .clk_in_sig = PARL_TX_CLK_IN_IDX, - .cs_sig = -1, - } - }, - .rx_units = { - [0] = { - .data_sigs = { - PARL_RX_DATA0_IDX, - PARL_RX_DATA1_IDX, - PARL_RX_DATA2_IDX, - PARL_RX_DATA3_IDX, - PARL_RX_DATA4_IDX, - PARL_RX_DATA5_IDX, - PARL_RX_DATA6_IDX, - PARL_RX_DATA7_IDX, - PARL_RX_DATA8_IDX, - PARL_RX_DATA9_IDX, - PARL_RX_DATA10_IDX, - PARL_RX_DATA11_IDX, - PARL_RX_DATA12_IDX, - PARL_RX_DATA13_IDX, - PARL_RX_DATA14_IDX, - PARL_RX_DATA15_IDX, - }, - .clk_out_sig = -1, - .clk_in_sig = PARL_RX_CLK_IN_IDX, - } +const soc_parlio_signal_desc_t soc_parlio_signals[1] = { + [0] = { + .module_name = "PARLIO0", + .tx_irq_id = ETS_PARL_IO_INTR_SOURCE, + .rx_irq_id = ETS_PARL_IO_INTR_SOURCE, + .tx_units = { + [0] = { + .data_sigs = { + PARL_TX_DATA0_IDX, + PARL_TX_DATA1_IDX, + PARL_TX_DATA2_IDX, + PARL_TX_DATA3_IDX, + PARL_TX_DATA4_IDX, + PARL_TX_DATA5_IDX, + PARL_TX_DATA6_IDX, + PARL_TX_DATA7_IDX, + PARL_TX_DATA8_IDX, + PARL_TX_DATA9_IDX, + PARL_TX_DATA10_IDX, + PARL_TX_DATA11_IDX, + PARL_TX_DATA12_IDX, + PARL_TX_DATA13_IDX, + PARL_TX_DATA14_IDX, + PARL_TX_DATA15_IDX, + }, + .clk_out_sig = PARL_TX_CLK_OUT_IDX, + .clk_in_sig = PARL_TX_CLK_IN_IDX, + .cs_sig = -1, } }, - }, + .rx_units = { + [0] = { + .data_sigs = { + PARL_RX_DATA0_IDX, + PARL_RX_DATA1_IDX, + PARL_RX_DATA2_IDX, + PARL_RX_DATA3_IDX, + PARL_RX_DATA4_IDX, + PARL_RX_DATA5_IDX, + PARL_RX_DATA6_IDX, + PARL_RX_DATA7_IDX, + PARL_RX_DATA8_IDX, + PARL_RX_DATA9_IDX, + PARL_RX_DATA10_IDX, + PARL_RX_DATA11_IDX, + PARL_RX_DATA12_IDX, + PARL_RX_DATA13_IDX, + PARL_RX_DATA14_IDX, + PARL_RX_DATA15_IDX, + }, + .clk_out_sig = -1, + .clk_in_sig = PARL_RX_CLK_IN_IDX, + } + } + } }; /** @@ -86,7 +84,7 @@ static const regdma_entries_config_t parlio_regs_retention[] = { .owner = ENTRY(0) | ENTRY(2) }, \ }; -const parlio_reg_retention_info_t parlio_reg_retention_info[PARLIO_LL_GET(INST_NUM)] = { +const parlio_reg_retention_info_t parlio_reg_retention_info[1] = { [0] = { .regdma_entry_array = parlio_regs_retention, .array_size = ARRAY_SIZE(parlio_regs_retention), diff --git a/components/esp_hal_parlio/esp32h2/parlio_periph.c b/components/esp_hal_parlio/esp32h2/parlio_periph.c index 27953dc6da..5d27330c52 100644 --- a/components/esp_hal_parlio/esp32h2/parlio_periph.c +++ b/components/esp_hal_parlio/esp32h2/parlio_periph.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,47 +7,45 @@ #include "hal/parlio_periph.h" #include "soc/gpio_sig_map.h" -const parlio_signal_conn_t parlio_periph_signals = { - .groups = { - [0] = { - .module_name = "PARLIO0", - .tx_irq_id = ETS_PARL_IO_TX_INTR_SOURCE, - .rx_irq_id = ETS_PARL_IO_RX_INTR_SOURCE, - .tx_units = { - [0] = { - .data_sigs = { - PARL_TX_DATA0_IDX, - PARL_TX_DATA1_IDX, - PARL_TX_DATA2_IDX, - PARL_TX_DATA3_IDX, - PARL_TX_DATA4_IDX, - PARL_TX_DATA5_IDX, - PARL_TX_DATA6_IDX, - PARL_TX_DATA7_IDX, - }, - .clk_out_sig = PARL_TX_CLK_OUT_IDX, - .clk_in_sig = PARL_TX_CLK_IN_IDX, - .cs_sig = -1, - } - }, - .rx_units = { - [0] = { - .data_sigs = { - PARL_RX_DATA0_IDX, - PARL_RX_DATA1_IDX, - PARL_RX_DATA2_IDX, - PARL_RX_DATA3_IDX, - PARL_RX_DATA4_IDX, - PARL_RX_DATA5_IDX, - PARL_RX_DATA6_IDX, - PARL_RX_DATA7_IDX, - }, - .clk_out_sig = PARL_RX_CLK_OUT_IDX, - .clk_in_sig = PARL_RX_CLK_IN_IDX, - } +const soc_parlio_signal_desc_t soc_parlio_signals[1] = { + [0] = { + .module_name = "PARLIO0", + .tx_irq_id = ETS_PARL_IO_TX_INTR_SOURCE, + .rx_irq_id = ETS_PARL_IO_RX_INTR_SOURCE, + .tx_units = { + [0] = { + .data_sigs = { + PARL_TX_DATA0_IDX, + PARL_TX_DATA1_IDX, + PARL_TX_DATA2_IDX, + PARL_TX_DATA3_IDX, + PARL_TX_DATA4_IDX, + PARL_TX_DATA5_IDX, + PARL_TX_DATA6_IDX, + PARL_TX_DATA7_IDX, + }, + .clk_out_sig = PARL_TX_CLK_OUT_IDX, + .clk_in_sig = PARL_TX_CLK_IN_IDX, + .cs_sig = -1, } }, - }, + .rx_units = { + [0] = { + .data_sigs = { + PARL_RX_DATA0_IDX, + PARL_RX_DATA1_IDX, + PARL_RX_DATA2_IDX, + PARL_RX_DATA3_IDX, + PARL_RX_DATA4_IDX, + PARL_RX_DATA5_IDX, + PARL_RX_DATA6_IDX, + PARL_RX_DATA7_IDX, + }, + .clk_out_sig = PARL_RX_CLK_OUT_IDX, + .clk_in_sig = PARL_RX_CLK_IN_IDX, + } + } + } }; /** @@ -72,7 +70,7 @@ static const regdma_entries_config_t parlio_regs_retention[] = { .owner = ENTRY(0) | ENTRY(2) }, \ }; -const parlio_reg_retention_info_t parlio_reg_retention_info[PARLIO_LL_GET(INST_NUM)] = { +const parlio_reg_retention_info_t parlio_reg_retention_info[1] = { [0] = { .regdma_entry_array = parlio_regs_retention, .array_size = ARRAY_SIZE(parlio_regs_retention), diff --git a/components/esp_hal_parlio/esp32h4/include/hal/parlio_ll.h b/components/esp_hal_parlio/esp32h4/include/hal/parlio_ll.h new file mode 100644 index 0000000000..d8d08a9a4b --- /dev/null +++ b/components/esp_hal_parlio/esp32h4/include/hal/parlio_ll.h @@ -0,0 +1,722 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// Note that most of the register operations in this layer are non-atomic operations. + +#pragma once + +#include +#include +#include "hal/assert.h" +#include "hal/misc.h" +#include "hal/hal_utils.h" +#include "soc/pcr_struct.h" +#include "soc/parl_io_struct.h" +#include "hal/parlio_types.h" + +#define PARLIO_LL_GET(attr) (PARLIO_LL_ ## attr) +#define PARLIO_LL_SUPPORT(feat) (PARLIO_LL_SUPPORT_ ## feat) +#define PARLIO_LL_INST_NUM 1 /*!< Number of parallel IO peripherals */ +#define PARLIO_LL_TX_UNITS_PER_INST 1 /*!< number of TX units in each instance */ +#define PARLIO_LL_RX_UNITS_PER_INST 1 /*!< number of RX units in each instance */ +#define PARLIO_LL_SUPPORT_RX_CLK_OUTPUT 1 /*!< Support output RX clock to a GPIO */ +#define PARLIO_LL_SUPPORT_TRANS_BIT_ALIGN 1 /*!< Support bit alignment in transaction */ +#define PARLIO_LL_SUPPORT_TX_EOF_FROM_DMA 1 /*!< Support to treat DMA EOF as TX unit EOF */ + +#define PARLIO_LL_RX_MAX_BYTES_PER_FRAME 0xFFFF +#define PARLIO_LL_RX_MAX_CLK_INT_DIV 0x10000 +#define PARLIO_LL_RX_MAX_CLK_FRACT_DIV 0 // Not support fractional divider +#define PARLIO_LL_RX_MAX_TIMEOUT 0xFFFF + +#define PARLIO_LL_TX_MAX_BITS_PER_FRAME 0x7FFFF +#define PARLIO_LL_TX_MAX_CLK_INT_DIV 0x10000 +#define PARLIO_LL_TX_MAX_CLK_FRACT_DIV 0 // Not support fractional divider + +#define PARLIO_LL_EVENT_TX_FIFO_EMPTY (1 << 0) +#define PARLIO_LL_EVENT_RX_FIFO_FULL (1 << 1) +#define PARLIO_LL_EVENT_TX_EOF (1 << 2) +#define PARLIO_LL_EVENT_TX_MASK (PARLIO_LL_EVENT_TX_FIFO_EMPTY | PARLIO_LL_EVENT_TX_EOF) +#define PARLIO_LL_EVENT_RX_MASK (PARLIO_LL_EVENT_RX_FIFO_FULL) + +#define PARLIO_LL_TX_DATA_LINE_AS_CLK_GATE 7 // TXD[7] can be used as clock gate signal +#define PARLIO_LL_TX_VALID_MAX_DELAY 32767 +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PARLIO_LL_RX_EOF_COND_RX_FULL, /*!< RX unit generates EOF event when it receives enough data */ + PARLIO_LL_RX_EOF_COND_EN_INACTIVE, /*!< RX unit generates EOF event when the external enable signal becomes inactive */ +} parlio_ll_rx_eof_cond_t; + +typedef enum { + PARLIO_LL_TX_EOF_COND_DATA_LEN, /*!< TX unit generates EOF event when it transmits particular data bit length that specified in `tx_bitlen`. */ + PARLIO_LL_TX_EOF_COND_DMA_EOF, /*!< TX unit generates EOF event when the DMA EOF takes place */ +} parlio_ll_tx_eof_cond_t; + +/** + * @brief Enable or disable the parlio peripheral APB clock + * + * @param group_id The group id of the parlio module + * @param enable Set true to enable, false to disable + */ +static inline void parlio_ll_enable_bus_clock(int group_id, bool enable) +{ + (void)group_id; + PCR.parl_io_conf.parl_clk_en = enable; +} + +/** + * @brief Reset the parlio module + * + * @param group_id The group id of the parlio module + */ +static inline void parlio_ll_reset_register(int group_id) +{ + (void)group_id; + PCR.parl_io_conf.parl_rst_en = 1; + PCR.parl_io_conf.parl_rst_en = 0; +} + +///////////////////////////////////////RX Unit/////////////////////////////////////// + +/** + * @brief Set the clock source for the RX unit + * + * @param dev Parallel IO register base address + * @param src Clock source + */ +static inline void parlio_ll_rx_set_clock_source(parl_io_dev_t *dev, parlio_clock_source_t src) +{ + (void)dev; + uint32_t clk_sel = 0; + switch (src) { + case PARLIO_CLK_SRC_XTAL: + clk_sel = 0; + break; + case PARLIO_CLK_SRC_RC_FAST: + clk_sel = 1; + break; + case PARLIO_CLK_SRC_PLL_F96M: + clk_sel = 2; + break; + case PARLIO_CLK_SRC_EXTERNAL: + clk_sel = 3; + break; + + default: // unsupported clock source + HAL_ASSERT(false); + break; + } + PCR.parl_clk_rx_conf.parl_clk_rx_sel = clk_sel; +} + +/** + * @brief Set the clock divider for the RX unit + * + * @param dev Parallel IO register base address + * @param clk_div Clock division with integral part, no fractional part on C5 + */ +static inline void parlio_ll_rx_set_clock_div(parl_io_dev_t *dev, const hal_utils_clk_div_t *clk_div) +{ + (void)dev; + HAL_ASSERT(clk_div->integer > 0 && clk_div->integer <= PARLIO_LL_RX_MAX_CLK_INT_DIV); + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.parl_clk_rx_conf, parl_clk_rx_div_num, clk_div->integer - 1); +} + +/** + * @brief Reset the RX unit Core clock domain + * + * @param dev Parallel IO register base address + */ +static inline void parlio_ll_rx_reset_clock(parl_io_dev_t *dev) +{ + (void)dev; + PCR.parl_clk_rx_conf.parl_rx_rst_en = 1; + PCR.parl_clk_rx_conf.parl_rx_rst_en = 0; +} + +/** + * @brief Enable the RX unit Core clock domain + * + * @param dev Parallel IO register base address + * @param en True to enable, False to disable + */ +__attribute__((always_inline)) +static inline void parlio_ll_rx_enable_clock(parl_io_dev_t *dev, bool en) +{ + (void)dev; + PCR.parl_clk_rx_conf.parl_clk_rx_en = en; +} + +/** + * @brief Set the condition to generate the RX EOF event + * + * @param dev Parallel IO register base address + * @param cond RX EOF condition + */ +__attribute__((always_inline)) +static inline void parlio_ll_rx_set_eof_condition(parl_io_dev_t *dev, parlio_ll_rx_eof_cond_t cond) +{ + dev->rx_genrl_cfg.rx_eof_gen_sel = cond; +} + +/** + * @brief Start RX unit to sample the input data + * + * @param dev Parallel IO register base address + * @param en True to start, False to stop + */ +__attribute__((always_inline)) +static inline void parlio_ll_rx_start(parl_io_dev_t *dev, bool en) +{ + dev->rx_start_cfg.rx_start = en; +} + +/** + * @brief Set the receive length + * + * @note The receive length can be used to generate DMA EOF signal, or to work as a frame end delimiter + * + * @param dev Parallel IO register base address + * @param bitlen Number of bits to receive in the next transaction, bitlen must be a multiple of 8 + */ +__attribute__((always_inline)) +static inline void parlio_ll_rx_set_recv_bit_len(parl_io_dev_t *dev, uint32_t bitlen) +{ + dev->rx_data_cfg.rx_bitlen = bitlen; +} + +/** + * @brief Set the sub mode of the level controlled receive mode + * + * @param dev Parallel IO register base address + * @param active_low_en Level of the external enable signal, true for active low, false for active high + */ +__attribute__((always_inline)) +static inline void parlio_ll_rx_set_level_recv_mode(parl_io_dev_t *dev, bool active_low_en) +{ + dev->rx_mode_cfg.rx_smp_mode_sel = 0; + dev->rx_mode_cfg.rx_ext_en_inv = active_low_en; +} + +/** + * @brief Set the sub mode of the pulse controlled receive mode + * + * @param dev Parallel IO register base address + * @param start_inc Whether the start pulse is counted + * @param end_inc Whether the end pulse is counted + * @param end_by_len Whether to use the frame length to determine the end of the frame + * @param pulse_inv Whether the pulse is inverted + */ +__attribute__((always_inline)) +static inline void parlio_ll_rx_set_pulse_recv_mode(parl_io_dev_t *dev, bool start_inc, bool end_inc, bool end_by_len, bool pulse_inv) +{ + uint32_t submode = 0; + uint32_t step = 1; + if (end_by_len) { + submode += 4; + } else { // end by pulse + step = 2; + if (!end_inc) { + submode += 1; + } + } + if (!start_inc) { + submode += step; + } + dev->rx_mode_cfg.rx_smp_mode_sel = 1; + dev->rx_mode_cfg.rx_pulse_submode_sel = submode; + dev->rx_mode_cfg.rx_ext_en_inv = pulse_inv; +} + +/** + * @brief Set the receive mode to software controlled receive mode + * + * @param dev Parallel IO register base address + */ +__attribute__((always_inline)) +static inline void parlio_ll_rx_set_soft_recv_mode(parl_io_dev_t *dev) +{ + dev->rx_mode_cfg.rx_smp_mode_sel = 2; +} + +/** + * @brief Whether to start the software controlled receive mode + * + * @param dev Parallel IO register base address + * @param en True to enable, False to disable + */ +static inline void parlio_ll_rx_start_soft_recv(parl_io_dev_t *dev, bool en) +{ + dev->rx_mode_cfg.rx_sw_en = en; +} + +/** + * @brief Set the sample clock edge + * + * @param dev Parallel IO register base address + * @param edge Sample clock edge + */ +__attribute__((always_inline)) +static inline void parlio_ll_rx_set_sample_clock_edge(parl_io_dev_t *dev, parlio_sample_edge_t edge) +{ + dev->rx_clk_cfg.rx_clk_i_inv = edge; + dev->rx_clk_cfg.rx_clk_o_inv = edge; +} + +/** + * @brief Set the order to pack bits into one byte + * + * @param dev Parallel IO register base address + * @param order Packing order + */ +__attribute__((always_inline)) +static inline void parlio_ll_rx_set_bit_pack_order(parl_io_dev_t *dev, parlio_bit_pack_order_t order) +{ + dev->rx_data_cfg.rx_data_order_inv = order; +} + +/** + * @brief Set the bus width of the RX unit + * + * @param dev Parallel IO register base address + * @param width Bus width + */ +static inline void parlio_ll_rx_set_bus_width(parl_io_dev_t *dev, uint32_t width) +{ + uint32_t width_sel = 0; + switch (width) { + case 8: + width_sel = 3; + break; + case 4: + width_sel = 2; + break; + case 2: + width_sel = 1; + break; + case 1: + width_sel = 0; + break; + default: + HAL_ASSERT(false); + } + dev->rx_data_cfg.rx_bus_wid_sel = width_sel; +} + +/** + * @brief Reset RX Async FIFO + * + * @note During the reset of the asynchronous FIFO, it takes two clock cycles to synchronize within AHB clock domain (GDMA) and Core clock domain. + * The reset synchronization must be performed two clock cycles in advance. + * @note If the next frame transfer needs to be reset, you need to first switch to the internal free-running clock, + * and then switch to the actual clock after the reset is completed. + * + * @param dev Parallel IO register base address + */ +static inline void parlio_ll_rx_reset_fifo(parl_io_dev_t *dev) +{ + dev->fifo_cfg.rx_fifo_srst = 1; + dev->fifo_cfg.rx_fifo_srst = 0; +} + +/** + * @brief Set which data line as the enable signal + * + * @param dev Parallel IO register base address + * @param line_num Data line number (0-15) + */ +__attribute__((always_inline)) +static inline void parlio_ll_rx_treat_data_line_as_en(parl_io_dev_t *dev, uint32_t line_num) +{ + dev->rx_mode_cfg.rx_ext_en_sel = line_num; +} + +/** + * @brief Whether to enable the RX clock gating + * + * @param dev Parallel IO register base address + * @param en True to enable, False to disable + */ +static inline void parlio_ll_rx_enable_clock_gating(parl_io_dev_t *dev, bool en) +{ + dev->rx_genrl_cfg.rx_gating_en = en; +} + +/** + * @brief Enable RX timeout feature + * + * @param dev Parallel IO register base address + * @param en True to enable, False to disable + */ +__attribute__((always_inline)) +static inline void parlio_ll_rx_enable_timeout(parl_io_dev_t *dev, bool en) +{ + dev->rx_genrl_cfg.rx_timeout_en = en; +} + +/** + * @brief Set the threshold of RX timeout + * + * @param dev Parallel IO register base address + * @param thres Threshold of RX timeout + */ +__attribute__((always_inline)) +static inline void parlio_ll_rx_set_timeout_thres(parl_io_dev_t *dev, uint32_t thres) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->rx_genrl_cfg, rx_timeout_thres, thres); +} + +/** + * @brief Update the RX configuration, to make the new configuration take effect + * + * @param dev Parallel IO register base address + */ +__attribute__((always_inline)) +static inline void parlio_ll_rx_update_config(parl_io_dev_t *dev) +{ + dev->reg_update.rx_reg_update = 1; + while (dev->reg_update.rx_reg_update); +} + +/** + * @brief Get the RX fifo cycle count + * + * @param dev Parallel IO register base address + * @return + * - RX fifo cycle count + */ +static inline uint32_t parlio_ll_rx_get_fifo_cycle_cnt(parl_io_dev_t *dev) +{ + return dev->rx_st0.rx_cnt; +} + +///////////////////////////////////TX Unit/////////////////////////////////////// + +/** + * @brief Set the clock source for the TX unit + * + * @param dev Parallel IO register base address + * @param src Clock source + */ +__attribute__((always_inline)) +static inline void parlio_ll_tx_set_clock_source(parl_io_dev_t *dev, parlio_clock_source_t src) +{ + (void)dev; + uint32_t clk_sel = 0; + switch (src) { + case PARLIO_CLK_SRC_XTAL: + clk_sel = 0; + break; + case PARLIO_CLK_SRC_RC_FAST: + clk_sel = 1; + break; + case PARLIO_CLK_SRC_PLL_F96M: + clk_sel = 2; + break; + case PARLIO_CLK_SRC_EXTERNAL: + clk_sel = 3; + break; + + default: // unsupported clock source + HAL_ASSERT(false); + break; + } + PCR.parl_clk_tx_conf.parl_clk_tx_sel = clk_sel; +} + +/** + * @brief Set the clock divider for the TX unit + * + * @param dev Parallel IO register base address + * @param clk_div Clock division with integral part, no fractional part on C5 + */ +static inline void parlio_ll_tx_set_clock_div(parl_io_dev_t *dev, const hal_utils_clk_div_t *clk_div) +{ + (void)dev; + HAL_ASSERT(clk_div->integer > 0 && clk_div->integer <= PARLIO_LL_RX_MAX_CLK_INT_DIV); + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.parl_clk_tx_conf, parl_clk_tx_div_num, clk_div->integer - 1); +} + +/** + * @brief Reset the TX unit Core clock domain + * + * @param dev Parallel IO register base address + */ +__attribute__((always_inline)) +static inline void parlio_ll_tx_reset_clock(parl_io_dev_t *dev) +{ + (void)dev; + PCR.parl_clk_tx_conf.parl_tx_rst_en = 1; + PCR.parl_clk_tx_conf.parl_tx_rst_en = 0; +} + +/** + * @brief Enable the TX unit Core clock domain + * + * @param dev Parallel IO register base address + * @param en True to enable, False to disable + */ +__attribute__((always_inline)) +static inline void parlio_ll_tx_enable_clock(parl_io_dev_t *dev, bool en) +{ + (void)dev; + PCR.parl_clk_tx_conf.parl_clk_tx_en = en; +} + +/** + * @brief Set the data length to be transmitted + * + * @param dev Parallel IO register base address + * @param bitlen Data length in bits, must be a multiple of 8 + */ +__attribute__((always_inline)) +static inline void parlio_ll_tx_set_trans_bit_len(parl_io_dev_t *dev, uint32_t bitlen) +{ + dev->tx_data_cfg.tx_bitlen = bitlen; +} + +/** + * @brief Check if tx size can be determined by DMA + * + * @param dev Parallel IO register base address (not used) + */ +static inline bool parlio_ll_tx_support_dma_eof(parl_io_dev_t *dev) +{ + (void)dev; + return true; +} + +/** + * @brief Set the condition to generate the TX EOF event + * + * @param dev Parallel IO register base address + * @param cond TX EOF condition + */ +__attribute__((always_inline)) +static inline void parlio_ll_tx_set_eof_condition(parl_io_dev_t *dev, parlio_ll_tx_eof_cond_t cond) +{ + dev->tx_genrl_cfg.tx_eof_gen_sel = cond; +} + +/** + * @brief Whether to enable the TX clock gating + * + * @note The MSB of TXD will be taken as the gating enable signal + * + * @param dev Parallel IO register base address + * @param en True to enable, False to disable + */ +static inline void parlio_ll_tx_enable_clock_gating(parl_io_dev_t *dev, bool en) +{ + dev->tx_genrl_cfg.tx_gating_en = en; +} + +/** + * @brief Start TX unit to transmit data + * + * @note The hardware monitors the rising edge of tx_start as the trigger signal. + * Once the transmission starts, it cannot be stopped by clearing tx_start. + * + * @param dev Parallel IO register base address + * @param en True to start, False to reset the reg state (not meaning the TX unit will be stopped) + */ +__attribute__((always_inline)) +static inline void parlio_ll_tx_start(parl_io_dev_t *dev, bool en) +{ + dev->tx_start_cfg.tx_start = en; +} + +/** + * @brief Set the clock gating from the valid signal + * + * @param dev Parallel IO register base address + * @param en If set to true, the clock is gated by the valid signal, otherwise it is gated by the MSB of the data line. + */ +static inline void parlio_ll_tx_clock_gating_from_valid(parl_io_dev_t *dev, bool en) +{ + dev->tx_genrl_cfg.tx_valid_output_en = en; +} + +/** + * @brief Set TX valid signal delay + * + * @param dev Parallel IO register base address + * @param start_delay Number of clock cycles to delay + * @param stop_delay Number of clock cycles to delay + * @return true: success, false: valid delay is not supported + */ +static inline bool parlio_ll_tx_set_valid_delay(parl_io_dev_t *dev, uint32_t start_delay, uint32_t stop_delay) +{ + if (start_delay > PARLIO_LL_TX_VALID_MAX_DELAY || stop_delay > PARLIO_LL_TX_VALID_MAX_DELAY) { + return false; + } + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->tx_cs_cfg, tx_cs_start_delay, start_delay); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->tx_cs_cfg, tx_cs_stop_delay, stop_delay); + return true; +} + +/** + * @brief Set the sample clock edge + * + * @param dev Parallel IO register base address + * @param edge Sample clock edge + */ +static inline void parlio_ll_tx_set_sample_clock_edge(parl_io_dev_t *dev, parlio_sample_edge_t edge) +{ + dev->tx_clk_cfg.tx_clk_i_inv = edge; + dev->tx_clk_cfg.tx_clk_o_inv = edge; +} + +/** + * @brief Set the order to unpack bits from a byte + * + * @param dev Parallel IO register base address + * @param order Packing order + */ +static inline void parlio_ll_tx_set_bit_pack_order(parl_io_dev_t *dev, parlio_bit_pack_order_t order) +{ + dev->tx_data_cfg.tx_data_order_inv = order; +} + +/** + * @brief Set the bus width of the TX unit + * + * @param dev Parallel IO register base address + * @param width Bus width + */ +static inline void parlio_ll_tx_set_bus_width(parl_io_dev_t *dev, uint32_t width) +{ + uint32_t width_sel = 0; + switch (width) { + case 8: + width_sel = 3; + break; + case 4: + width_sel = 2; + break; + case 2: + width_sel = 1; + break; + case 1: + width_sel = 0; + break; + default: + HAL_ASSERT(false); + } + dev->tx_data_cfg.tx_bus_wid_sel = width_sel; +} + +/** + * @brief Reset TX Async FIFO + * + * @note During the reset of the asynchronous FIFO, it takes two clock cycles to synchronize within AHB clock domain (GDMA) and Core clock domain. + * The reset synchronization must be performed two clock cycles in advance. + * @note If the next frame transfer needs to be reset, you need to first switch to the internal free-running clock, + * and then switch to the actual clock after the reset is completed. + * + * @param dev Parallel IO register base address + */ +__attribute__((always_inline)) +static inline void parlio_ll_tx_reset_fifo(parl_io_dev_t *dev) +{ + dev->fifo_cfg.tx_fifo_srst = 1; + dev->fifo_cfg.tx_fifo_srst = 0; +} + +/** + * @brief Set the value to output on the TXD when the TX unit is in IDLE state + * + * @param dev Parallel IO register base address + * @param value Value to output + */ +__attribute__((always_inline)) +static inline void parlio_ll_tx_set_idle_data_value(parl_io_dev_t *dev, uint32_t value) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->tx_genrl_cfg, tx_idle_value, value); +} + +/** + * @brief Check whether the TX unit is ready + * + * @param dev Parallel IO register base address + * @return true: ready, false: busy + */ +__attribute__((always_inline)) +static inline bool parlio_ll_tx_is_ready(parl_io_dev_t *dev) +{ + return dev->st.tx_ready; +} + +////////////////////////////////////Interrupt//////////////////////////////////////////////// + +/** + * @brief Enable Parallel IO interrupt for specific event mask + * + * @param dev Parallel IO register base address + * @param mask Event mask + * @param enable True to enable, False to disable + */ +static inline void parlio_ll_enable_interrupt(parl_io_dev_t *dev, uint32_t mask, bool enable) +{ + if (enable) { + dev->int_ena.val |= mask; + } else { + dev->int_ena.val &= ~mask; + } +} + +/** + * @brief Get interrupt status for TX unit + * + * @param dev Parallel IO register base address + * @return Interrupt status + */ +__attribute__((always_inline)) +static inline uint32_t parlio_ll_tx_get_interrupt_status(parl_io_dev_t *dev) +{ + return dev->int_st.val & PARLIO_LL_EVENT_TX_MASK; +} + +/** + * @brief Get interrupt status for RX unit + * + * @param dev Parallel IO register base address + * @return Interrupt status + */ +__attribute__((always_inline)) +static inline uint32_t parlio_ll_rx_get_interrupt_status(parl_io_dev_t *dev) +{ + return dev->int_st.val & PARLIO_LL_EVENT_RX_MASK; +} + +/** + * @brief Clear Parallel IO interrupt status by mask + * + * @param dev Parallel IO register base address + * @param mask Interrupt status mask + */ +__attribute__((always_inline)) +static inline void parlio_ll_clear_interrupt_status(parl_io_dev_t *dev, uint32_t mask) +{ + dev->int_clr.val = mask; +} + +/** + * @brief Get interrupt status register address + * + * @param dev Parallel IO register base address + * @return Register address + */ +static inline volatile void *parlio_ll_get_interrupt_status_reg(parl_io_dev_t *dev) +{ + return &dev->int_st; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hal_parlio/esp32h4/parlio_periph.c b/components/esp_hal_parlio/esp32h4/parlio_periph.c new file mode 100644 index 0000000000..91c0b2fa0e --- /dev/null +++ b/components/esp_hal_parlio/esp32h4/parlio_periph.c @@ -0,0 +1,79 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "hal/parlio_periph.h" +#include "soc/gpio_sig_map.h" + +const soc_parlio_signal_desc_t soc_parlio_signals[1] = { + [0] = { + .module_name = "PARLIO0", + .tx_irq_id = ETS_PARL_IO_TX_INTR_SOURCE, + .rx_irq_id = ETS_PARL_IO_RX_INTR_SOURCE, + .tx_units = { + [0] = { + .data_sigs = { + PARL_TX_DATA0_IDX, + PARL_TX_DATA1_IDX, + PARL_TX_DATA2_IDX, + PARL_TX_DATA3_IDX, + PARL_TX_DATA4_IDX, + PARL_TX_DATA5_IDX, + PARL_TX_DATA6_IDX, + PARL_TX_DATA7_IDX, + }, + .clk_out_sig = PARL_TX_CLK_OUT_IDX, + .clk_in_sig = PARL_TX_CLK_IN_IDX, + .cs_sig = PARL_TX_CS_IDX, + } + }, + .rx_units = { + [0] = { + .data_sigs = { + PARL_RX_DATA0_IDX, + PARL_RX_DATA1_IDX, + PARL_RX_DATA2_IDX, + PARL_RX_DATA3_IDX, + PARL_RX_DATA4_IDX, + PARL_RX_DATA5_IDX, + PARL_RX_DATA6_IDX, + PARL_RX_DATA7_IDX, + }, + .clk_out_sig = PARL_RX_CLK_OUT_IDX, + .clk_in_sig = PARL_RX_CLK_IN_IDX, + } + } + } +}; + +/** + * PARLIO Registers to be saved during sleep retention + * - Tx Configuration registers, e.g.: PARL_IO_TX_DATA_CFG_REG, PARL_IO_TX_GENRL_CFG_REG + * - Rx Configuration registers, e.g.: PARL_IO_RX_MODE_CFG_REG, PARL_IO_RX_DATA_CFG_REG, PARL_IO_RX_GENRL_CFG_REG + * - CLK Configuration registers, e.g.: PARL_IO_RX_CLK_CFG_REG, PARL_IO_TX_CLK_CFG_REG + * - Interrupt enable registers, e.g.: PARL_IO_INT_ENA_REG +*/ +#define PARLIO_RETENTION_REGS_CNT 8 +#define PARLIO_RETENTION_REGS_BASE (DR_REG_PARL_IO_BASE + 0x0) +static const uint32_t parlio_regs_map[4] = {0x60457, 0x0, 0x0, 0x0}; +static const regdma_entries_config_t parlio_regs_retention[] = { + // backup stage: save configuration registers + // restore stage: restore the configuration registers + [0] = { + .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_PARLIO_LINK(0x00), \ + PARLIO_RETENTION_REGS_BASE, PARLIO_RETENTION_REGS_BASE, \ + PARLIO_RETENTION_REGS_CNT, 0, 0, \ + parlio_regs_map[0], parlio_regs_map[1], \ + parlio_regs_map[2], parlio_regs_map[3]), \ + .owner = ENTRY(0) | ENTRY(2) + }, \ +}; +const parlio_reg_retention_info_t parlio_reg_retention_info[1] = { + [0] = { + .regdma_entry_array = parlio_regs_retention, + .array_size = ARRAY_SIZE(parlio_regs_retention), + .retention_module = SLEEP_RETENTION_MODULE_PARLIO0 + }, +}; diff --git a/components/esp_hal_parlio/esp32p4/parlio_periph.c b/components/esp_hal_parlio/esp32p4/parlio_periph.c index 0049d74990..be359819b0 100644 --- a/components/esp_hal_parlio/esp32p4/parlio_periph.c +++ b/components/esp_hal_parlio/esp32p4/parlio_periph.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,63 +7,61 @@ #include "hal/parlio_periph.h" #include "soc/gpio_sig_map.h" -const parlio_signal_conn_t parlio_periph_signals = { - .groups = { - [0] = { - .module_name = "PARLIO0", - .tx_irq_id = ETS_HP_PARLIO_TX_INTR_SOURCE, - .rx_irq_id = ETS_HP_PARLIO_RX_INTR_SOURCE, - .tx_units = { - [0] = { - .data_sigs = { - PARLIO_TX_DATA0_PAD_OUT_IDX, - PARLIO_TX_DATA1_PAD_OUT_IDX, - PARLIO_TX_DATA2_PAD_OUT_IDX, - PARLIO_TX_DATA3_PAD_OUT_IDX, - PARLIO_TX_DATA4_PAD_OUT_IDX, - PARLIO_TX_DATA5_PAD_OUT_IDX, - PARLIO_TX_DATA6_PAD_OUT_IDX, - PARLIO_TX_DATA7_PAD_OUT_IDX, - PARLIO_TX_DATA8_PAD_OUT_IDX, - PARLIO_TX_DATA9_PAD_OUT_IDX, - PARLIO_TX_DATA10_PAD_OUT_IDX, - PARLIO_TX_DATA11_PAD_OUT_IDX, - PARLIO_TX_DATA12_PAD_OUT_IDX, - PARLIO_TX_DATA13_PAD_OUT_IDX, - PARLIO_TX_DATA14_PAD_OUT_IDX, - PARLIO_TX_DATA15_PAD_OUT_IDX, - }, - .clk_out_sig = PARLIO_TX_CLK_PAD_OUT_IDX, - .clk_in_sig = PARLIO_TX_CLK_PAD_IN_IDX, - .cs_sig = PARLIO_TX_CS_PAD_OUT_IDX, - } - }, - .rx_units = { - [0] = { - .data_sigs = { - PARLIO_RX_DATA0_PAD_IN_IDX, - PARLIO_RX_DATA1_PAD_IN_IDX, - PARLIO_RX_DATA2_PAD_IN_IDX, - PARLIO_RX_DATA3_PAD_IN_IDX, - PARLIO_RX_DATA4_PAD_IN_IDX, - PARLIO_RX_DATA5_PAD_IN_IDX, - PARLIO_RX_DATA6_PAD_IN_IDX, - PARLIO_RX_DATA7_PAD_IN_IDX, - PARLIO_RX_DATA8_PAD_IN_IDX, - PARLIO_RX_DATA9_PAD_IN_IDX, - PARLIO_RX_DATA10_PAD_IN_IDX, - PARLIO_RX_DATA11_PAD_IN_IDX, - PARLIO_RX_DATA12_PAD_IN_IDX, - PARLIO_RX_DATA13_PAD_IN_IDX, - PARLIO_RX_DATA14_PAD_IN_IDX, - PARLIO_RX_DATA15_PAD_IN_IDX, - }, - .clk_out_sig = PARLIO_RX_CLK_PAD_OUT_IDX, - .clk_in_sig = PARLIO_RX_CLK_PAD_IN_IDX, - } +const soc_parlio_signal_desc_t soc_parlio_signals[1] = { + [0] = { + .module_name = "PARLIO0", + .tx_irq_id = ETS_HP_PARLIO_TX_INTR_SOURCE, + .rx_irq_id = ETS_HP_PARLIO_RX_INTR_SOURCE, + .tx_units = { + [0] = { + .data_sigs = { + PARLIO_TX_DATA0_PAD_OUT_IDX, + PARLIO_TX_DATA1_PAD_OUT_IDX, + PARLIO_TX_DATA2_PAD_OUT_IDX, + PARLIO_TX_DATA3_PAD_OUT_IDX, + PARLIO_TX_DATA4_PAD_OUT_IDX, + PARLIO_TX_DATA5_PAD_OUT_IDX, + PARLIO_TX_DATA6_PAD_OUT_IDX, + PARLIO_TX_DATA7_PAD_OUT_IDX, + PARLIO_TX_DATA8_PAD_OUT_IDX, + PARLIO_TX_DATA9_PAD_OUT_IDX, + PARLIO_TX_DATA10_PAD_OUT_IDX, + PARLIO_TX_DATA11_PAD_OUT_IDX, + PARLIO_TX_DATA12_PAD_OUT_IDX, + PARLIO_TX_DATA13_PAD_OUT_IDX, + PARLIO_TX_DATA14_PAD_OUT_IDX, + PARLIO_TX_DATA15_PAD_OUT_IDX, + }, + .clk_out_sig = PARLIO_TX_CLK_PAD_OUT_IDX, + .clk_in_sig = PARLIO_TX_CLK_PAD_IN_IDX, + .cs_sig = PARLIO_TX_CS_PAD_OUT_IDX, } }, - }, + .rx_units = { + [0] = { + .data_sigs = { + PARLIO_RX_DATA0_PAD_IN_IDX, + PARLIO_RX_DATA1_PAD_IN_IDX, + PARLIO_RX_DATA2_PAD_IN_IDX, + PARLIO_RX_DATA3_PAD_IN_IDX, + PARLIO_RX_DATA4_PAD_IN_IDX, + PARLIO_RX_DATA5_PAD_IN_IDX, + PARLIO_RX_DATA6_PAD_IN_IDX, + PARLIO_RX_DATA7_PAD_IN_IDX, + PARLIO_RX_DATA8_PAD_IN_IDX, + PARLIO_RX_DATA9_PAD_IN_IDX, + PARLIO_RX_DATA10_PAD_IN_IDX, + PARLIO_RX_DATA11_PAD_IN_IDX, + PARLIO_RX_DATA12_PAD_IN_IDX, + PARLIO_RX_DATA13_PAD_IN_IDX, + PARLIO_RX_DATA14_PAD_IN_IDX, + PARLIO_RX_DATA15_PAD_IN_IDX, + }, + .clk_out_sig = PARLIO_RX_CLK_PAD_OUT_IDX, + .clk_in_sig = PARLIO_RX_CLK_PAD_IN_IDX, + } + } + } }; /** @@ -88,7 +86,7 @@ static const regdma_entries_config_t parlio_regs_retention[] = { .owner = ENTRY(0) }, }; -const parlio_reg_retention_info_t parlio_reg_retention_info[PARLIO_LL_GET(INST_NUM)] = { +const parlio_reg_retention_info_t parlio_reg_retention_info[1] = { [0] = { .regdma_entry_array = parlio_regs_retention, .array_size = ARRAY_SIZE(parlio_regs_retention), diff --git a/components/esp_hal_parlio/include/hal/parlio_periph.h b/components/esp_hal_parlio/include/hal/parlio_periph.h index 489b33ad9d..1059cae525 100644 --- a/components/esp_hal_parlio/include/hal/parlio_periph.h +++ b/components/esp_hal_parlio/include/hal/parlio_periph.h @@ -23,28 +23,25 @@ extern "C" { #endif -#if SOC_PARLIO_SUPPORTED +#if SOC_HAS(PARLIO) typedef struct { struct { - struct { - const int data_sigs[SOC_PARLIO_TX_UNIT_MAX_DATA_WIDTH]; - const int clk_out_sig; - const int clk_in_sig; - const int cs_sig; - } tx_units[PARLIO_LL_GET(TX_UNITS_PER_INST)]; - struct { - const int data_sigs[SOC_PARLIO_RX_UNIT_MAX_DATA_WIDTH]; - const int clk_out_sig; - const int clk_in_sig; - } rx_units[PARLIO_LL_GET(RX_UNITS_PER_INST)]; - const int tx_irq_id; - const int rx_irq_id; - const shared_periph_module_t module; - const char *module_name; - } groups[PARLIO_LL_GET(INST_NUM)]; -} parlio_signal_conn_t; + const int data_sigs[SOC_PARLIO_TX_UNIT_MAX_DATA_WIDTH]; + const int clk_out_sig; + const int clk_in_sig; + const int cs_sig; + } tx_units[PARLIO_LL_GET(TX_UNITS_PER_INST)]; + struct { + const int data_sigs[SOC_PARLIO_RX_UNIT_MAX_DATA_WIDTH]; + const int clk_out_sig; + const int clk_in_sig; + } rx_units[PARLIO_LL_GET(RX_UNITS_PER_INST)]; + const int tx_irq_id; + const int rx_irq_id; + const char *module_name; +} soc_parlio_signal_desc_t; -extern const parlio_signal_conn_t parlio_periph_signals; +extern const soc_parlio_signal_desc_t soc_parlio_signals[PARLIO_LL_GET(INST_NUM)]; #if SOC_PARLIO_SUPPORT_SLEEP_RETENTION typedef struct { diff --git a/components/esp_lcd/test_apps/parlio_lcd/README.md b/components/esp_lcd/test_apps/parlio_lcd/README.md index 38aff53db8..31bfbd518a 100644 --- a/components/esp_lcd/test_apps/parlio_lcd/README.md +++ b/components/esp_lcd/test_apps/parlio_lcd/README.md @@ -1,4 +1,4 @@ -| Supported Targets | ESP32-C5 | ESP32-H2 | ESP32-P4 | -| ----------------- | -------- | -------- | -------- | +| Supported Targets | ESP32-C5 | ESP32-H2 | ESP32-H4 | ESP32-P4 | +| ----------------- | -------- | -------- | -------- | -------- | This test app is used to test LCDs with intel 8080 interface. diff --git a/components/esp_lcd/test_apps/parlio_lcd/main/test_parlio_board.h b/components/esp_lcd/test_apps/parlio_lcd/main/test_parlio_board.h index 72147b3a75..cfe596f1ce 100644 --- a/components/esp_lcd/test_apps/parlio_lcd/main/test_parlio_board.h +++ b/components/esp_lcd/test_apps/parlio_lcd/main/test_parlio_board.h @@ -47,6 +47,20 @@ extern "C" { #define TEST_LCD_DATA5_GPIO (23) #define TEST_LCD_DATA6_GPIO (13) #define TEST_LCD_DATA7_GPIO (27) +#elif CONFIG_IDF_TARGET_ESP32H4 +#define TEST_LCD_BK_LIGHT_GPIO (13) +#define TEST_LCD_RST_GPIO (39) +#define TEST_LCD_PCLK_GPIO (15) +#define TEST_LCD_CS_GPIO (14) +#define TEST_LCD_DC_GPIO (38) +#define TEST_LCD_DATA0_GPIO (16) +#define TEST_LCD_DATA1_GPIO (37) +#define TEST_LCD_DATA2_GPIO (17) +#define TEST_LCD_DATA3_GPIO (36) +#define TEST_LCD_DATA4_GPIO (18) +#define TEST_LCD_DATA5_GPIO (35) +#define TEST_LCD_DATA6_GPIO (19) +#define TEST_LCD_DATA7_GPIO (34) #endif diff --git a/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in index 4a8a94fe98..72fa57bb3f 100644 --- a/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in @@ -43,6 +43,14 @@ config SOC_ETM_SUPPORTED bool default y +config SOC_PARLIO_SUPPORTED + bool + default y + +config SOC_PARLIO_LCD_SUPPORTED + bool + default y + config SOC_IEEE802154_BLE_ONLY bool default y @@ -619,6 +627,34 @@ config SOC_MCPWM_SUPPORT_SLEEP_RETENTION bool default y +config SOC_PARLIO_TX_UNIT_MAX_DATA_WIDTH + int + default 8 + +config SOC_PARLIO_RX_UNIT_MAX_DATA_WIDTH + int + default 8 + +config SOC_PARLIO_TX_CLK_SUPPORT_GATING + bool + default y + +config SOC_PARLIO_RX_CLK_SUPPORT_GATING + bool + default y + +config SOC_PARLIO_TX_SUPPORT_LOOP_TRANSMISSION + bool + default y + +config SOC_PARLIO_SUPPORT_SLEEP_RETENTION + bool + default y + +config SOC_PARLIO_SUPPORT_I80_LCD + bool + default y + config SOC_ECC_CONSTANT_TIME_POINT_MUL bool default y diff --git a/components/soc/esp32h4/include/soc/clk_tree_defs.h b/components/soc/esp32h4/include/soc/clk_tree_defs.h index 47853cc991..0c1257435d 100644 --- a/components/soc/esp32h4/include/soc/clk_tree_defs.h +++ b/components/soc/esp32h4/include/soc/clk_tree_defs.h @@ -461,6 +461,24 @@ typedef enum { TWAI_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F96M, /*!< Select PLL_96M as the default clock choice */ } soc_periph_twai_clk_src_t; +//////////////////////////////////////////////////PARLIO//////////////////////////////////////////////////////////////// + +/** + * @brief Array initializer for all supported clock sources of PARLIO + */ +#define SOC_PARLIO_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_PLL_F96M} + +/** + * @brief PARLIO clock source + */ +typedef enum { + PARLIO_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ + PARLIO_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */ + PARLIO_CLK_SRC_PLL_F96M = SOC_MOD_CLK_PLL_F96M, /*!< Select PLL_F96M as the source clock */ + PARLIO_CLK_SRC_EXTERNAL = -1, /*!< Select EXTERNAL clock as the source clock */ + PARLIO_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F96M, /*!< Select PLL_F96M as the default clock choice */ +} soc_periph_parlio_clk_src_t; + #ifdef __cplusplus } #endif diff --git a/components/soc/esp32h4/include/soc/soc_caps.h b/components/soc/esp32h4/include/soc/soc_caps.h index 609cbfe4fa..61e2b3baaa 100644 --- a/components/soc/esp32h4/include/soc/soc_caps.h +++ b/components/soc/esp32h4/include/soc/soc_caps.h @@ -43,7 +43,8 @@ #define SOC_TWAI_SUPPORTED 1 #define SOC_TWAI_FD_SUPPORTED 1 #define SOC_ETM_SUPPORTED 1 -// #define SOC_PARLIO_SUPPORTED 1 // TODO: [ESP32H4] IDF-12345 IDF-12347 +#define SOC_PARLIO_SUPPORTED 1 +#define SOC_PARLIO_LCD_SUPPORTED 1 // #define SOC_BT_SUPPORTED 1 #define SOC_IEEE802154_BLE_ONLY 1 #define SOC_PHY_SUPPORTED 1 @@ -335,8 +336,13 @@ // #define SOC_USB_SERIAL_JTAG_SUPPORT_LIGHT_SLEEP (1) /*!< Support to maintain minimum usb communication during light sleep */ // TODO: IDF-6395 /*-------------------------- PARLIO CAPS --------------------------------------*/ -// #define SOC_PARLIO_TX_UNIT_MAX_DATA_WIDTH 8 /*!< Number of data lines of the TX unit */ -// #define SOC_PARLIO_RX_UNIT_MAX_DATA_WIDTH 8 /*!< Number of data lines of the RX unit */ +#define SOC_PARLIO_TX_UNIT_MAX_DATA_WIDTH 8 /*!< Number of data lines of the TX unit */ +#define SOC_PARLIO_RX_UNIT_MAX_DATA_WIDTH 8 /*!< Number of data lines of the RX unit */ +#define SOC_PARLIO_TX_CLK_SUPPORT_GATING 1 /*!< Support gating TX clock */ +#define SOC_PARLIO_RX_CLK_SUPPORT_GATING 1 /*!< Support gating RX clock */ +#define SOC_PARLIO_TX_SUPPORT_LOOP_TRANSMISSION 1 /*!< Support loop transmission */ +#define SOC_PARLIO_SUPPORT_SLEEP_RETENTION 1 /*!< Support back up registers before sleep */ +#define SOC_PARLIO_SUPPORT_I80_LCD 1 /*!< Support to drive I80 interfaced LCD */ /*--------------------------- SHA CAPS ---------------------------------------*/ diff --git a/components/soc/esp32h4/register/soc/parl_io_struct.h b/components/soc/esp32h4/register/soc/parl_io_struct.h index f6a704adbe..d872fc1a68 100644 --- a/components/soc/esp32h4/register/soc/parl_io_struct.h +++ b/components/soc/esp32h4/register/soc/parl_io_struct.h @@ -11,25 +11,25 @@ extern "C" { #endif /** Group: PARL_IO RX Mode Configuration */ -/** Type of io_rx_mode_cfg register +/** Type of rx_mode_cfg register * Parallel RX Sampling mode configuration register. */ typedef union { struct { uint32_t reserved_0:21; - /** io_rx_ext_en_sel : R/W; bitpos: [24:21]; default: 7; + /** rx_ext_en_sel : R/W; bitpos: [24:21]; default: 7; * Configures rx external enable signal selection from IO PAD. */ - uint32_t io_rx_ext_en_sel:4; - /** io_rx_sw_en : R/W; bitpos: [25]; default: 0; + uint32_t rx_ext_en_sel:4; + /** rx_sw_en : R/W; bitpos: [25]; default: 0; * Write 1 to enable data sampling by software. */ - uint32_t io_rx_sw_en:1; - /** io_rx_ext_en_inv : R/W; bitpos: [26]; default: 0; + uint32_t rx_sw_en:1; + /** rx_ext_en_inv : R/W; bitpos: [26]; default: 0; * Write 1 to invert the external enable signal. */ - uint32_t io_rx_ext_en_inv:1; - /** io_rx_pulse_submode_sel : R/W; bitpos: [29:27]; default: 0; + uint32_t rx_ext_en_inv:1; + /** rx_pulse_submode_sel : R/W; bitpos: [29:27]; default: 0; * Configures the rxd pulse sampling submode. * 0: positive pulse start(data bit included) && positive pulse end(data bit included) * 1: positive pulse start(data bit included) && positive pulse end (data bit excluded) @@ -38,71 +38,71 @@ typedef union { * 4: positive pulse start(data bit included) && length end * 5: positive pulse start(data bit excluded) && length end */ - uint32_t io_rx_pulse_submode_sel:3; - /** io_rx_smp_mode_sel : R/W; bitpos: [31:30]; default: 0; + uint32_t rx_pulse_submode_sel:3; + /** rx_smp_mode_sel : R/W; bitpos: [31:30]; default: 0; * Configures the rxd sampling mode. * 0: external level enable mode * 1: external pulse enable mode * 2: internal software enable mode */ - uint32_t io_rx_smp_mode_sel:2; + uint32_t rx_smp_mode_sel:2; }; uint32_t val; } parl_io_rx_mode_cfg_reg_t; /** Group: PARL_IO RX Data Configuration */ -/** Type of io_rx_data_cfg register +/** Type of rx_data_cfg register * Parallel RX data configuration register. */ typedef union { struct { uint32_t reserved_0:9; - /** io_rx_bitlen : R/W; bitpos: [27:9]; default: 0; + /** rx_bitlen : R/W; bitpos: [27:9]; default: 0; * Configures expected byte number of received data. */ - uint32_t io_rx_bitlen:19; - /** io_rx_data_order_inv : R/W; bitpos: [28]; default: 0; + uint32_t rx_bitlen:19; + /** rx_data_order_inv : R/W; bitpos: [28]; default: 0; * Write 1 to invert bit order of one byte sent from RX_FIFO to DMA. */ - uint32_t io_rx_data_order_inv:1; - /** io_rx_bus_wid_sel : R/W; bitpos: [31:29]; default: 3; + uint32_t rx_data_order_inv:1; + /** rx_bus_wid_sel : R/W; bitpos: [31:29]; default: 3; * Configures the rxd bus width. * 0: bus width is 1. * 1: bus width is 2. * 2: bus width is 4. * 3: bus width is 8. */ - uint32_t io_rx_bus_wid_sel:3; + uint32_t rx_bus_wid_sel:3; }; uint32_t val; } parl_io_rx_data_cfg_reg_t; /** Group: PARL_IO RX General Configuration */ -/** Type of io_rx_genrl_cfg register +/** Type of rx_genrl_cfg register * Parallel RX general configuration register. */ typedef union { struct { uint32_t reserved_0:12; - /** io_rx_gating_en : R/W; bitpos: [12]; default: 0; + /** rx_gating_en : R/W; bitpos: [12]; default: 0; * Write 1 to enable the clock gating of output rx clock. */ - uint32_t io_rx_gating_en:1; - /** io_rx_timeout_thres : R/W; bitpos: [28:13]; default: 4095; + uint32_t rx_gating_en:1; + /** rx_timeout_thres : R/W; bitpos: [28:13]; default: 4095; * Configures threshold of timeout counter. */ - uint32_t io_rx_timeout_thres:16; - /** io_rx_timeout_en : R/W; bitpos: [29]; default: 1; + uint32_t rx_timeout_thres:16; + /** rx_timeout_en : R/W; bitpos: [29]; default: 1; * Write 1 to enable timeout function to generate error eof. */ - uint32_t io_rx_timeout_en:1; - /** io_rx_eof_gen_sel : R/W; bitpos: [30]; default: 0; + uint32_t rx_timeout_en:1; + /** rx_eof_gen_sel : R/W; bitpos: [30]; default: 0; * Configures the DMA eof generated mechanism. 1'b0: eof generated by data bit length. * 1'b1: eof generated by external enable signal. */ - uint32_t io_rx_eof_gen_sel:1; + uint32_t rx_eof_gen_sel:1; uint32_t reserved_31:1; }; uint32_t val; @@ -110,230 +110,230 @@ typedef union { /** Group: PARL_IO RX Start Configuration */ -/** Type of io_rx_start_cfg register +/** Type of rx_start_cfg register * Parallel RX Start configuration register. */ typedef union { struct { uint32_t reserved_0:31; - /** io_rx_start : R/W; bitpos: [31]; default: 0; + /** rx_start : R/W; bitpos: [31]; default: 0; * Write 1 to start rx data sampling. */ - uint32_t io_rx_start:1; + uint32_t rx_start:1; }; uint32_t val; } parl_io_rx_start_cfg_reg_t; /** Group: PARL_IO TX Data Configuration */ -/** Type of io_tx_data_cfg register +/** Type of tx_data_cfg register * Parallel TX data configuration register. */ typedef union { struct { uint32_t reserved_0:9; - /** io_tx_bitlen : R/W; bitpos: [27:9]; default: 0; + /** tx_bitlen : R/W; bitpos: [27:9]; default: 0; * Configures expected byte number of sent data. */ - uint32_t io_tx_bitlen:19; - /** io_tx_data_order_inv : R/W; bitpos: [28]; default: 0; + uint32_t tx_bitlen:19; + /** tx_data_order_inv : R/W; bitpos: [28]; default: 0; * Write 1 to invert bit order of one byte sent from TX_FIFO to IO data. */ - uint32_t io_tx_data_order_inv:1; - /** io_tx_bus_wid_sel : R/W; bitpos: [31:29]; default: 3; + uint32_t tx_data_order_inv:1; + /** tx_bus_wid_sel : R/W; bitpos: [31:29]; default: 3; * Configures the txd bus width. * 0: bus width is 1. * 1: bus width is 2. * 2: bus width is 4. * 3: bus width is 8. */ - uint32_t io_tx_bus_wid_sel:3; + uint32_t tx_bus_wid_sel:3; }; uint32_t val; } parl_io_tx_data_cfg_reg_t; /** Group: PARL_IO TX Start Configuration */ -/** Type of io_tx_start_cfg register +/** Type of tx_start_cfg register * Parallel TX Start configuration register. */ typedef union { struct { uint32_t reserved_0:31; - /** io_tx_start : R/W; bitpos: [31]; default: 0; + /** tx_start : R/W; bitpos: [31]; default: 0; * Write 1 to start tx data transmit. */ - uint32_t io_tx_start:1; + uint32_t tx_start:1; }; uint32_t val; } parl_io_tx_start_cfg_reg_t; /** Group: PARL_IO TX General Configuration */ -/** Type of io_tx_genrl_cfg register +/** Type of tx_genrl_cfg register * Parallel TX general configuration register. */ typedef union { struct { uint32_t reserved_0:13; - /** io_tx_eof_gen_sel : R/W; bitpos: [13]; default: 0; + /** tx_eof_gen_sel : R/W; bitpos: [13]; default: 0; * Configures the tx eof generated mechanism. 1'b0: eof generated by data bit length. * 1'b1: eof generated by DMA eof. */ - uint32_t io_tx_eof_gen_sel:1; - /** io_tx_idle_value : R/W; bitpos: [29:14]; default: 0; + uint32_t tx_eof_gen_sel:1; + /** tx_idle_value : R/W; bitpos: [29:14]; default: 0; * Configures bus value of transmitter in IDLE state. */ - uint32_t io_tx_idle_value:16; - /** io_tx_gating_en : R/W; bitpos: [30]; default: 0; + uint32_t tx_idle_value:16; + /** tx_gating_en : R/W; bitpos: [30]; default: 0; * Write 1 to enable the clock gating of output tx clock. */ - uint32_t io_tx_gating_en:1; - /** io_tx_valid_output_en : R/W; bitpos: [31]; default: 0; + uint32_t tx_gating_en:1; + /** tx_valid_output_en : R/W; bitpos: [31]; default: 0; * Write 1 to enable the output of tx data valid signal. */ - uint32_t io_tx_valid_output_en:1; + uint32_t tx_valid_output_en:1; }; uint32_t val; } parl_io_tx_genrl_cfg_reg_t; /** Group: PARL_IO FIFO Configuration */ -/** Type of io_fifo_cfg register +/** Type of fifo_cfg register * Parallel IO FIFO configuration register. */ typedef union { struct { uint32_t reserved_0:30; - /** io_tx_fifo_srst : R/W; bitpos: [30]; default: 0; + /** tx_fifo_srst : R/W; bitpos: [30]; default: 0; * Write 1 to reset async fifo in tx module. */ - uint32_t io_tx_fifo_srst:1; - /** io_rx_fifo_srst : R/W; bitpos: [31]; default: 0; + uint32_t tx_fifo_srst:1; + /** rx_fifo_srst : R/W; bitpos: [31]; default: 0; * Write 1 to reset async fifo in rx module. */ - uint32_t io_rx_fifo_srst:1; + uint32_t rx_fifo_srst:1; }; uint32_t val; } parl_io_fifo_cfg_reg_t; /** Group: PARL_IO Register Update Configuration */ -/** Type of io_reg_update register +/** Type of reg_update register * Parallel IO FIFO configuration register. */ typedef union { struct { uint32_t reserved_0:31; - /** io_rx_reg_update : WT; bitpos: [31]; default: 0; + /** rx_reg_update : WT; bitpos: [31]; default: 0; * Write 1 to update rx register configuration. */ - uint32_t io_rx_reg_update:1; + uint32_t rx_reg_update:1; }; uint32_t val; } parl_io_reg_update_reg_t; /** Group: PARL_IO Status */ -/** Type of io_st register +/** Type of st register * Parallel IO module status register0. */ typedef union { struct { uint32_t reserved_0:31; - /** io_tx_ready : RO; bitpos: [31]; default: 0; + /** tx_ready : RO; bitpos: [31]; default: 0; * Represents the status that tx is ready to transmit. */ - uint32_t io_tx_ready:1; + uint32_t tx_ready:1; }; uint32_t val; } parl_io_st_reg_t; /** Group: PARL_IO Interrupt Configuration and Status */ -/** Type of io_int_ena register +/** Type of int_ena register * Parallel IO interrupt enable signal configuration register. */ typedef union { struct { - /** io_tx_fifo_rempty_int_ena : R/W; bitpos: [0]; default: 0; + /** tx_fifo_rempty_int_ena : R/W; bitpos: [0]; default: 0; * Write 1 to enable TX_FIFO_REMPTY_INT. */ - uint32_t io_tx_fifo_rempty_int_ena:1; - /** io_rx_fifo_wovf_int_ena : R/W; bitpos: [1]; default: 0; + uint32_t tx_fifo_rempty_int_ena:1; + /** rx_fifo_wovf_int_ena : R/W; bitpos: [1]; default: 0; * Write 1 to enable RX_FIFO_WOVF_INT. */ - uint32_t io_rx_fifo_wovf_int_ena:1; - /** io_tx_eof_int_ena : R/W; bitpos: [2]; default: 0; + uint32_t rx_fifo_wovf_int_ena:1; + /** tx_eof_int_ena : R/W; bitpos: [2]; default: 0; * Write 1 to enable TX_EOF_INT. */ - uint32_t io_tx_eof_int_ena:1; + uint32_t tx_eof_int_ena:1; uint32_t reserved_3:29; }; uint32_t val; } parl_io_int_ena_reg_t; -/** Type of io_int_raw register +/** Type of int_raw register * Parallel IO interrupt raw signal status register. */ typedef union { struct { - /** io_tx_fifo_rempty_int_raw : R/SS/WTC; bitpos: [0]; default: 0; + /** tx_fifo_rempty_int_raw : R/SS/WTC; bitpos: [0]; default: 0; * The raw interrupt status of TX_FIFO_REMPTY_INT. */ - uint32_t io_tx_fifo_rempty_int_raw:1; - /** io_rx_fifo_wovf_int_raw : R/SS/WTC; bitpos: [1]; default: 0; + uint32_t tx_fifo_rempty_int_raw:1; + /** rx_fifo_wovf_int_raw : R/SS/WTC; bitpos: [1]; default: 0; * The raw interrupt status of RX_FIFO_WOVF_INT. */ - uint32_t io_rx_fifo_wovf_int_raw:1; - /** io_tx_eof_int_raw : R/SS/WTC; bitpos: [2]; default: 0; + uint32_t rx_fifo_wovf_int_raw:1; + /** tx_eof_int_raw : R/SS/WTC; bitpos: [2]; default: 0; * The raw interrupt status of TX_EOF_INT. */ - uint32_t io_tx_eof_int_raw:1; + uint32_t tx_eof_int_raw:1; uint32_t reserved_3:29; }; uint32_t val; } parl_io_int_raw_reg_t; -/** Type of io_int_st register +/** Type of int_st register * Parallel IO interrupt signal status register. */ typedef union { struct { - /** io_tx_fifo_rempty_int_st : RO; bitpos: [0]; default: 0; + /** tx_fifo_rempty_int_st : RO; bitpos: [0]; default: 0; * The masked interrupt status of TX_FIFO_REMPTY_INT. */ - uint32_t io_tx_fifo_rempty_int_st:1; - /** io_rx_fifo_wovf_int_st : RO; bitpos: [1]; default: 0; + uint32_t tx_fifo_rempty_int_st:1; + /** rx_fifo_wovf_int_st : RO; bitpos: [1]; default: 0; * The masked interrupt status of RX_FIFO_WOVF_INT. */ - uint32_t io_rx_fifo_wovf_int_st:1; - /** io_tx_eof_int_st : RO; bitpos: [2]; default: 0; + uint32_t rx_fifo_wovf_int_st:1; + /** tx_eof_int_st : RO; bitpos: [2]; default: 0; * The masked interrupt status of TX_EOF_INT. */ - uint32_t io_tx_eof_int_st:1; + uint32_t tx_eof_int_st:1; uint32_t reserved_3:29; }; uint32_t val; } parl_io_int_st_reg_t; -/** Type of io_int_clr register +/** Type of int_clr register * Parallel IO interrupt clear signal configuration register. */ typedef union { struct { - /** io_tx_fifo_rempty_int_clr : WT; bitpos: [0]; default: 0; + /** tx_fifo_rempty_int_clr : WT; bitpos: [0]; default: 0; * Write 1 to clear TX_FIFO_REMPTY_INT. */ - uint32_t io_tx_fifo_rempty_int_clr:1; - /** io_rx_fifo_wovf_int_clr : WT; bitpos: [1]; default: 0; + uint32_t tx_fifo_rempty_int_clr:1; + /** rx_fifo_wovf_int_clr : WT; bitpos: [1]; default: 0; * Write 1 to clear RX_FIFO_WOVF_INT. */ - uint32_t io_rx_fifo_wovf_int_clr:1; - /** io_tx_eof_int_clr : WT; bitpos: [2]; default: 0; + uint32_t rx_fifo_wovf_int_clr:1; + /** tx_eof_int_clr : WT; bitpos: [2]; default: 0; * Write 1 to clear TX_EOF_INT. */ - uint32_t io_tx_eof_int_clr:1; + uint32_t tx_eof_int_clr:1; uint32_t reserved_3:29; }; uint32_t val; @@ -341,183 +341,183 @@ typedef union { /** Group: PARL_IO Rx Status0 */ -/** Type of io_rx_st0 register +/** Type of rx_st0 register * Parallel IO RX status register0 */ typedef union { struct { uint32_t reserved_0:8; - /** io_rx_cnt : RO; bitpos: [12:8]; default: 0; + /** rx_cnt : RO; bitpos: [12:8]; default: 0; * Indicates the cycle number of reading Rx FIFO. */ - uint32_t io_rx_cnt:5; - /** io_rx_fifo_wr_bit_cnt : RO; bitpos: [31:13]; default: 0; + uint32_t rx_cnt:5; + /** rx_fifo_wr_bit_cnt : RO; bitpos: [31:13]; default: 0; * Indicates the current written bit number into Rx FIFO. */ - uint32_t io_rx_fifo_wr_bit_cnt:19; + uint32_t rx_fifo_wr_bit_cnt:19; }; uint32_t val; } parl_io_rx_st0_reg_t; /** Group: PARL_IO Rx Status1 */ -/** Type of io_rx_st1 register +/** Type of rx_st1 register * Parallel IO RX status register1 */ typedef union { struct { uint32_t reserved_0:13; - /** io_rx_fifo_rd_bit_cnt : RO; bitpos: [31:13]; default: 0; + /** rx_fifo_rd_bit_cnt : RO; bitpos: [31:13]; default: 0; * Indicates the current read bit number from Rx FIFO. */ - uint32_t io_rx_fifo_rd_bit_cnt:19; + uint32_t rx_fifo_rd_bit_cnt:19; }; uint32_t val; } parl_io_rx_st1_reg_t; /** Group: PARL_IO Tx Status0 */ -/** Type of io_tx_st0 register +/** Type of tx_st0 register * Parallel IO TX status register0 */ typedef union { struct { uint32_t reserved_0:6; - /** io_tx_cnt : RO; bitpos: [12:6]; default: 0; + /** tx_cnt : RO; bitpos: [12:6]; default: 0; * Indicates the cycle number of reading Tx FIFO. */ - uint32_t io_tx_cnt:7; - /** io_tx_fifo_rd_bit_cnt : RO; bitpos: [31:13]; default: 0; + uint32_t tx_cnt:7; + /** tx_fifo_rd_bit_cnt : RO; bitpos: [31:13]; default: 0; * Indicates the current read bit number from Tx FIFO. */ - uint32_t io_tx_fifo_rd_bit_cnt:19; + uint32_t tx_fifo_rd_bit_cnt:19; }; uint32_t val; } parl_io_tx_st0_reg_t; /** Group: PARL_IO Rx Clock Configuration */ -/** Type of io_rx_clk_cfg register +/** Type of rx_clk_cfg register * Parallel IO RX clk configuration register */ typedef union { struct { uint32_t reserved_0:30; - /** io_rx_clk_i_inv : R/W; bitpos: [30]; default: 0; + /** rx_clk_i_inv : R/W; bitpos: [30]; default: 0; * Write 1 to invert the input Rx core clock. */ - uint32_t io_rx_clk_i_inv:1; - /** io_rx_clk_o_inv : R/W; bitpos: [31]; default: 0; + uint32_t rx_clk_i_inv:1; + /** rx_clk_o_inv : R/W; bitpos: [31]; default: 0; * Write 1 to invert the output Rx core clock. */ - uint32_t io_rx_clk_o_inv:1; + uint32_t rx_clk_o_inv:1; }; uint32_t val; } parl_io_rx_clk_cfg_reg_t; /** Group: PARL_IO Tx Clock Configuration */ -/** Type of io_tx_clk_cfg register +/** Type of tx_clk_cfg register * Parallel IO TX clk configuration register */ typedef union { struct { uint32_t reserved_0:30; - /** io_tx_clk_i_inv : R/W; bitpos: [30]; default: 0; + /** tx_clk_i_inv : R/W; bitpos: [30]; default: 0; * Write 1 to invert the input Tx core clock. */ - uint32_t io_tx_clk_i_inv:1; - /** io_tx_clk_o_inv : R/W; bitpos: [31]; default: 0; + uint32_t tx_clk_i_inv:1; + /** tx_clk_o_inv : R/W; bitpos: [31]; default: 0; * Write 1 to invert the output Tx core clock. */ - uint32_t io_tx_clk_o_inv:1; + uint32_t tx_clk_o_inv:1; }; uint32_t val; } parl_io_tx_clk_cfg_reg_t; /** Group: PARL_TX_CS Configuration */ -/** Type of io_tx_cs_cfg register +/** Type of tx_cs_cfg register * Parallel IO tx_cs_o generate configuration */ typedef union { struct { - /** io_tx_cs_stop_delay : R/W; bitpos: [15:0]; default: 0; + /** tx_cs_stop_delay : R/W; bitpos: [15:0]; default: 0; * configure the delay between data tx end and tx_cs_o posedge */ - uint32_t io_tx_cs_stop_delay:16; - /** io_tx_cs_start_delay : R/W; bitpos: [31:16]; default: 0; + uint32_t tx_cs_stop_delay:16; + /** tx_cs_start_delay : R/W; bitpos: [31:16]; default: 0; * configure the delay between tx_cs_o negedge and data tx start */ - uint32_t io_tx_cs_start_delay:16; + uint32_t tx_cs_start_delay:16; }; uint32_t val; } parl_io_tx_cs_cfg_reg_t; /** Group: PARL_IO Clock Configuration */ -/** Type of io_clk register +/** Type of clk register * Parallel IO clk configuration register */ typedef union { struct { uint32_t reserved_0:31; - /** io_clk_en : R/W; bitpos: [31]; default: 0; + /** clk_en : R/W; bitpos: [31]; default: 0; * Force clock on for this register file */ - uint32_t io_clk_en:1; + uint32_t clk_en:1; }; uint32_t val; } parl_io_clk_reg_t; /** Group: PARL_IO Version Register */ -/** Type of io_version register +/** Type of version register * Version register. */ typedef union { struct { - /** io_date : R/W; bitpos: [27:0]; default: 37786160; + /** date : R/W; bitpos: [27:0]; default: 37786160; * Version of this register file */ - uint32_t io_date:28; + uint32_t date:28; uint32_t reserved_28:4; }; uint32_t val; } parl_io_version_reg_t; -typedef struct { - volatile parl_io_rx_mode_cfg_reg_t io_rx_mode_cfg; - volatile parl_io_rx_data_cfg_reg_t io_rx_data_cfg; - volatile parl_io_rx_genrl_cfg_reg_t io_rx_genrl_cfg; - volatile parl_io_rx_start_cfg_reg_t io_rx_start_cfg; - volatile parl_io_tx_data_cfg_reg_t io_tx_data_cfg; - volatile parl_io_tx_start_cfg_reg_t io_tx_start_cfg; - volatile parl_io_tx_genrl_cfg_reg_t io_tx_genrl_cfg; - volatile parl_io_fifo_cfg_reg_t io_fifo_cfg; - volatile parl_io_reg_update_reg_t io_reg_update; - volatile parl_io_st_reg_t io_st; - volatile parl_io_int_ena_reg_t io_int_ena; - volatile parl_io_int_raw_reg_t io_int_raw; - volatile parl_io_int_st_reg_t io_int_st; - volatile parl_io_int_clr_reg_t io_int_clr; - volatile parl_io_rx_st0_reg_t io_rx_st0; - volatile parl_io_rx_st1_reg_t io_rx_st1; - volatile parl_io_tx_st0_reg_t io_tx_st0; - volatile parl_io_rx_clk_cfg_reg_t io_rx_clk_cfg; - volatile parl_io_tx_clk_cfg_reg_t io_tx_clk_cfg; - volatile parl_io_tx_cs_cfg_reg_t io_tx_cs_cfg; +typedef struct parl_io_dev_t { + volatile parl_io_rx_mode_cfg_reg_t rx_mode_cfg; + volatile parl_io_rx_data_cfg_reg_t rx_data_cfg; + volatile parl_io_rx_genrl_cfg_reg_t rx_genrl_cfg; + volatile parl_io_rx_start_cfg_reg_t rx_start_cfg; + volatile parl_io_tx_data_cfg_reg_t tx_data_cfg; + volatile parl_io_tx_start_cfg_reg_t tx_start_cfg; + volatile parl_io_tx_genrl_cfg_reg_t tx_genrl_cfg; + volatile parl_io_fifo_cfg_reg_t fifo_cfg; + volatile parl_io_reg_update_reg_t reg_update; + volatile parl_io_st_reg_t st; + volatile parl_io_int_ena_reg_t int_ena; + volatile parl_io_int_raw_reg_t int_raw; + volatile parl_io_int_st_reg_t int_st; + volatile parl_io_int_clr_reg_t int_clr; + volatile parl_io_rx_st0_reg_t rx_st0; + volatile parl_io_rx_st1_reg_t rx_st1; + volatile parl_io_tx_st0_reg_t tx_st0; + volatile parl_io_rx_clk_cfg_reg_t rx_clk_cfg; + volatile parl_io_tx_clk_cfg_reg_t tx_clk_cfg; + volatile parl_io_tx_cs_cfg_reg_t tx_cs_cfg; uint32_t reserved_050[52]; - volatile parl_io_clk_reg_t io_clk; + volatile parl_io_clk_reg_t clk; uint32_t reserved_124[182]; - volatile parl_io_version_reg_t io_version; -} parl_dev_t; + volatile parl_io_version_reg_t version; +} parl_io_dev_t; -extern parl_dev_t PARL_IO; +extern parl_io_dev_t PARL_IO; #ifndef __cplusplus -_Static_assert(sizeof(parl_dev_t) == 0x400, "Invalid size of parl_dev_t structure"); +_Static_assert(sizeof(parl_io_dev_t) == 0x400, "Invalid size of parl_io_dev_t structure"); #endif #ifdef __cplusplus diff --git a/components/soc/esp32h4/register/soc/pcr_struct.h b/components/soc/esp32h4/register/soc/pcr_struct.h index ca0fcc51ae..f246e6e75c 100644 --- a/components/soc/esp32h4/register/soc/pcr_struct.h +++ b/components/soc/esp32h4/register/soc/pcr_struct.h @@ -1178,7 +1178,7 @@ typedef union { * Configures the clock source of Paraller IO RX * 0 (default): XTAL_CLK * 1: RC_FAST_CLK - * 2: PLL_F240M_CLK + * 2: PLL_F96M_CLK * 3: Use the clock from chip pin */ uint32_t parl_clk_tx_sel:2; diff --git a/docs/docs_not_updated/esp32h4.txt b/docs/docs_not_updated/esp32h4.txt index 6aaaaec88d..0478270ca8 100644 --- a/docs/docs_not_updated/esp32h4.txt +++ b/docs/docs_not_updated/esp32h4.txt @@ -132,7 +132,6 @@ api-reference/peripherals/sdspi_host.rst api-reference/peripherals/vad.rst api-reference/peripherals/i2s.rst api-reference/peripherals/sd_pullup_requirements.rst -api-reference/peripherals/parlio.rst api-reference/peripherals/adc_calibration.rst api-reference/peripherals/lp_i2s.rst api-reference/peripherals/ecdsa.rst diff --git a/examples/peripherals/lcd/parlio_simulate/README.md b/examples/peripherals/lcd/parlio_simulate/README.md index 822d59c982..b92cd23f84 100644 --- a/examples/peripherals/lcd/parlio_simulate/README.md +++ b/examples/peripherals/lcd/parlio_simulate/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32-C5 | ESP32-H2 | ESP32-P4 | -| ----------------- | -------- | -------- | -------- | +| Supported Targets | ESP32-C5 | ESP32-H2 | ESP32-H4 | ESP32-P4 | +| ----------------- | -------- | -------- | -------- | -------- | # Parallel IO simulation of SPI or I80 Interfaced LCD example diff --git a/examples/peripherals/lcd/parlio_simulate/sdkconfig.defaults.esp32h4 b/examples/peripherals/lcd/parlio_simulate/sdkconfig.defaults.esp32h4 new file mode 100644 index 0000000000..1b90d27ea1 --- /dev/null +++ b/examples/peripherals/lcd/parlio_simulate/sdkconfig.defaults.esp32h4 @@ -0,0 +1,18 @@ +CONFIG_SPIRAM=y +# Enabling the following configurations can help increase the PCLK frequency in the case when +# the Frame Buffer is allocated from the PSRAM and fetched by EDMA +CONFIG_SPIRAM_XIP_FROM_PSRAM=y + +CONFIG_EXAMPLE_PIN_NUM_BK_LIGHT=13 +CONFIG_EXAMPLE_PIN_NUM_RST=39 +CONFIG_EXAMPLE_PIN_NUM_PCLK=15 +CONFIG_EXAMPLE_PIN_NUM_CS=14 +CONFIG_EXAMPLE_PIN_NUM_DC=38 +CONFIG_EXAMPLE_PIN_NUM_DATA0=16 +CONFIG_EXAMPLE_PIN_NUM_DATA1=37 +CONFIG_EXAMPLE_PIN_NUM_DATA2=17 +CONFIG_EXAMPLE_PIN_NUM_DATA3=36 +CONFIG_EXAMPLE_PIN_NUM_DATA4=18 +CONFIG_EXAMPLE_PIN_NUM_DATA5=35 +CONFIG_EXAMPLE_PIN_NUM_DATA6=19 +CONFIG_EXAMPLE_PIN_NUM_DATA7=34 diff --git a/examples/peripherals/parlio/parlio_rx/logic_analyzer/README.md b/examples/peripherals/parlio/parlio_rx/logic_analyzer/README.md index 6f52dc95c2..f586368306 100644 --- a/examples/peripherals/parlio/parlio_rx/logic_analyzer/README.md +++ b/examples/peripherals/parlio/parlio_rx/logic_analyzer/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | -| ----------------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-H4 | ESP32-P4 | +| ----------------- | -------- | -------- | -------- | -------- | -------- | # Logic Analyzer Example diff --git a/examples/peripherals/parlio/parlio_tx/simple_rgb_led_matrix/README.md b/examples/peripherals/parlio/parlio_tx/simple_rgb_led_matrix/README.md index bc7137fb0c..39ac38abe4 100644 --- a/examples/peripherals/parlio/parlio_tx/simple_rgb_led_matrix/README.md +++ b/examples/peripherals/parlio/parlio_tx/simple_rgb_led_matrix/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-P4 | -| ----------------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-H4 | ESP32-P4 | +| ----------------- | -------- | -------- | -------- | -------- | -------- | # Parallel IO TX Example: Simple RGB LED Matrix