refactor(parlio): make parlio driver as component

pull/12901/merge
laokaiyao 2023-12-31 13:55:10 +08:00
rodzic 83241cab72
commit baccc61482
35 zmienionych plików z 102 dodań i 83 usunięć

Wyświetl plik

@ -10,7 +10,6 @@ set(srcs)
# Always included headers
set(includes "deprecated"
"i2c/include"
"parlio/include"
"touch_sensor/include"
"twai/include"
"usb_serial_jtag/include")
@ -33,13 +32,6 @@ if(CONFIG_SOC_DAC_SUPPORTED)
"deprecated/${target}/dac_legacy.c")
endif()
# Parallel IO related source files
if(CONFIG_SOC_PARLIO_SUPPORTED)
list(APPEND srcs "parlio/parlio_common.c"
"parlio/parlio_tx.c"
"parlio/parlio_rx.c")
endif()
# GPTimer legacy driver
if(CONFIG_SOC_GPTIMER_SUPPORTED)
list(APPEND srcs "deprecated/timer_legacy.c")
@ -121,7 +113,7 @@ else()
esp_driver_gpio esp_driver_pcnt esp_driver_gptimer esp_driver_spi esp_driver_mcpwm
esp_driver_ana_cmpr esp_driver_i2s esp_driver_sdmmc esp_driver_sdspi esp_driver_sdio
esp_driver_dac esp_driver_rmt esp_driver_tsens esp_driver_sdm esp_driver_i2c
esp_driver_uart esp_driver_ledc
esp_driver_uart esp_driver_ledc esp_driver_parlio
LDFRAGMENTS ${ldfragments}
)
endif()

Wyświetl plik

@ -81,24 +81,4 @@ menu "Driver Configurations"
USB Serial/JTAG is in use.
endmenu # USB Serial/JTAG Configuration
menu "Parallel IO Configuration"
depends on SOC_PARLIO_SUPPORTED
config PARLIO_ENABLE_DEBUG_LOG
bool "Enable debug log"
default n
help
Wether to enable the debug log message for parallel IO driver.
Note that, this option only controls the parallel IO driver log, won't affect other drivers.
config PARLIO_ISR_IRAM_SAFE
bool "Parallel IO ISR IRAM-Safe"
default n
select GDMA_CTRL_FUNC_IN_IRAM # the driver needs to start the GDMA in the interrupt
help
Ensure the Parallel IO interrupt is IRAM-Safe by allowing the interrupt handler to be
executable when the cache is disabled (e.g. SPI Flash write).
endmenu # Parallel IO Configuration
endmenu # Driver configurations

Wyświetl plik

@ -78,14 +78,6 @@ components/driver/test_apps/legacy_timer_driver:
depends_filepatterns:
- components/driver/deprecated/**/*timer*
components/driver/test_apps/parlio:
disable:
- if: SOC_PARLIO_SUPPORTED != 1
disable_test:
- if: IDF_TARGET == "esp32p4"
temporary: true
reason: lack of runner
components/driver/test_apps/touch_sensor_v1:
disable:
- if: SOC_TOUCH_SENSOR_VERSION != 1

Wyświetl plik

@ -0,0 +1,12 @@
set(srcs)
set(public_include "include")
if(CONFIG_SOC_PARLIO_SUPPORTED)
list(APPEND srcs "src/parlio_common.c"
"src/parlio_tx.c"
"src/parlio_rx.c")
endif()
idf_component_register(SRCS ${srcs}
INCLUDE_DIRS ${public_include}
PRIV_REQUIRES "esp_pm" "esp_driver_gpio"
)

Wyświetl plik

@ -0,0 +1,19 @@
menu "ESP-Driver:Parallel IO Configurations"
depends on SOC_PARLIO_SUPPORTED
config PARLIO_ENABLE_DEBUG_LOG
bool "Enable debug log"
default n
help
Wether to enable the debug log message for parallel IO driver.
Note that, this option only controls the parallel IO driver log, won't affect other drivers.
config PARLIO_ISR_IRAM_SAFE
bool "Parallel IO ISR IRAM-Safe"
default n
select GDMA_CTRL_FUNC_IN_IRAM # the driver needs to start the GDMA in the interrupt
help
Ensure the Parallel IO interrupt is IRAM-Safe by allowing the interrupt handler to be
executable when the cache is disabled (e.g. SPI Flash write).
endmenu # Parallel IO Configuration

Wyświetl plik

@ -151,11 +151,9 @@ static IRAM_ATTR size_t s_parlio_mount_transaction_buffer(parlio_rx_unit_handle_
size_t rest_size = trans->size - offset;
if (rest_size >= 2 * DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED) {
mount_size = trans->size / desc_num;
}
else if (rest_size <= DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED) {
} else if (rest_size <= DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED) {
mount_size = (desc_num == 2) && (i == 0) ? rest_size / 2 : rest_size;
}
else {
} else {
mount_size = rest_size / 2;
}
p_desc[i].buffer = (void *)((uint8_t *)trans->payload + offset);
@ -186,23 +184,23 @@ static IRAM_ATTR void s_parlio_set_delimiter_config(parlio_rx_unit_handle_t rx_u
/* Set receive mode according to the delimiter */
switch (deli->mode) {
case PARLIO_RX_LEVEL_MODE:
/* Select the level receive mode */
parlio_ll_rx_set_level_recv_mode(hal->regs, deli->flags.active_low_en);
parlio_ll_rx_treat_data_line_as_en(hal->regs, deli->valid_sig_line_id);
break;
case PARLIO_RX_PULSE_MODE:
/* Select the pulse receive mode */
parlio_ll_rx_set_pulse_recv_mode(hal->regs, deli->flags.start_bit_included,
deli->flags.end_bit_included,
!deli->flags.has_end_pulse,
deli->flags.pulse_invert);
parlio_ll_rx_treat_data_line_as_en(hal->regs, deli->valid_sig_line_id);
break;
default:
/* Select the soft receive mode */
parlio_ll_rx_set_soft_recv_mode(hal->regs);
break;
case PARLIO_RX_LEVEL_MODE:
/* Select the level receive mode */
parlio_ll_rx_set_level_recv_mode(hal->regs, deli->flags.active_low_en);
parlio_ll_rx_treat_data_line_as_en(hal->regs, deli->valid_sig_line_id);
break;
case PARLIO_RX_PULSE_MODE:
/* Select the pulse receive mode */
parlio_ll_rx_set_pulse_recv_mode(hal->regs, deli->flags.start_bit_included,
deli->flags.end_bit_included,
!deli->flags.has_end_pulse,
deli->flags.pulse_invert);
parlio_ll_rx_treat_data_line_as_en(hal->regs, deli->valid_sig_line_id);
break;
default:
/* Select the soft receive mode */
parlio_ll_rx_set_soft_recv_mode(hal->regs);
break;
}
/* Set EOF configuration */
@ -265,7 +263,7 @@ static esp_err_t s_parlio_rx_unit_set_gpio(parlio_rx_unit_handle_t rx_unit, cons
gpio_conf.pin_bit_mask = BIT64(config->clk_out_gpio_num);
ESP_RETURN_ON_ERROR(gpio_config(&gpio_conf), TAG, "config clk out GPIO failed");
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);
parlio_periph_signals.groups[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 // SOC_PARLIO_RX_CLK_SUPPORT_OUTPUT
@ -291,7 +289,7 @@ static esp_err_t s_parlio_rx_unit_set_gpio(parlio_rx_unit_handle_t rx_unit, cons
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[config->data_gpio_nums[i]], PIN_FUNC_GPIO);
}
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);
parlio_periph_signals.groups[group_id].rx_units[unit_id].data_sigs[i], false);
} else {
ESP_LOGW(TAG, "data line %d not assigned", i);
}
@ -302,7 +300,7 @@ static esp_err_t s_parlio_rx_unit_set_gpio(parlio_rx_unit_handle_t rx_unit, cons
static IRAM_ATTR bool s_parlio_rx_default_eof_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data)
{
parlio_rx_unit_handle_t rx_unit = (parlio_rx_unit_handle_t )user_data;
parlio_rx_unit_handle_t rx_unit = (parlio_rx_unit_handle_t)user_data;
BaseType_t high_task_woken = pdFALSE;
bool need_yield = false;
@ -362,7 +360,7 @@ static IRAM_ATTR bool s_parlio_rx_default_eof_callback(gdma_channel_handle_t dma
static IRAM_ATTR bool s_parlio_rx_default_desc_done_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data)
{
parlio_rx_unit_handle_t rx_unit = (parlio_rx_unit_handle_t )user_data;
parlio_rx_unit_handle_t rx_unit = (parlio_rx_unit_handle_t)user_data;
bool need_yield = false;
/* No need to process the data if error EOF (i.e. timeout) happened */
if (event_data->flags.abnormal_eof) {
@ -495,8 +493,8 @@ static esp_err_t s_parlio_select_periph_clock(parlio_rx_unit_handle_t rx_unit, c
rx_unit->clk_src = clk_src;
/* warning if precision lost due to division */
if ((clk_src != PARLIO_CLK_SRC_EXTERNAL) &&
(config->exp_clk_freq_hz != rx_unit->cfg.exp_clk_freq_hz )) {
ESP_LOGW(TAG, "precision loss, real output frequency: %"PRIu32, rx_unit->cfg.exp_clk_freq_hz );
(config->exp_clk_freq_hz != rx_unit->cfg.exp_clk_freq_hz)) {
ESP_LOGW(TAG, "precision loss, real output frequency: %"PRIu32, rx_unit->cfg.exp_clk_freq_hz);
}
return ESP_OK;
@ -535,7 +533,7 @@ static esp_err_t s_parlio_destroy_rx_unit(parlio_rx_unit_handle_t rx_unit)
}
/* Unregister the RX unit from the PARLIO group */
if (rx_unit->base.group) {
parlio_unregister_unit_from_group((parlio_unit_base_handle_t)rx_unit);
parlio_unregister_unit_from_group(&rx_unit->base);
}
/* Free the RX unit */
free(rx_unit);
@ -579,7 +577,7 @@ esp_err_t parlio_new_rx_unit(const parlio_rx_unit_config_t *config, parlio_rx_un
ESP_GOTO_ON_ERROR(s_parlio_rx_create_dma_descriptors(unit, config->max_recv_size), err, TAG, "create dma descriptor failed");
/* Register and attach the rx unit to the group */
ESP_GOTO_ON_ERROR(parlio_register_unit_to_group((parlio_unit_base_handle_t)unit), err, TAG, "failed to register the rx unit to the group");
ESP_GOTO_ON_ERROR(parlio_register_unit_to_group(&unit->base), err, TAG, "failed to register the rx unit to the group");
memcpy(&unit->cfg, config, sizeof(parlio_rx_unit_config_t));
/* If not using external clock source, the internal clock is always a free running clock */
if (config->clk_src != PARLIO_CLK_SRC_EXTERNAL) {
@ -885,7 +883,7 @@ esp_err_t parlio_rx_unit_receive(parlio_rx_unit_handle_t rx_unit,
/* Check if the valid_sig_line_id is equal or greater than data width, otherwise valid_sig_line_id is conflict with data signal.
* 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 */
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");
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].
rx_units[rx_unit->base.unit_id].

Wyświetl plik

@ -120,7 +120,7 @@ static esp_err_t parlio_destroy_tx_unit(parlio_tx_unit_t *tx_unit)
}
if (tx_unit->base.group) {
// de-register from group
parlio_unregister_unit_from_group((parlio_unit_base_handle_t)&(tx_unit->base));
parlio_unregister_unit_from_group(&tx_unit->base);
}
free(tx_unit->dma_nodes);
free(tx_unit);
@ -275,7 +275,7 @@ esp_err_t parlio_new_tx_unit(const parlio_tx_unit_config_t *config, parlio_tx_un
ESP_GOTO_ON_FALSE(unit->dma_nodes, ESP_ERR_NO_MEM, err, TAG, "no memory for DMA nodes");
// Link the descriptors
for (int i = 0; i < dma_nodes_num; i++) {
unit->dma_nodes[i].next = (i == dma_nodes_num - 1) ? NULL : &(unit->dma_nodes[i+1]);
unit->dma_nodes[i].next = (i == dma_nodes_num - 1) ? NULL : &(unit->dma_nodes[i + 1]);
}
unit->max_transfer_bits = config->max_transfer_size * 8;
unit->base.dir = PARLIO_DIR_TX;
@ -284,7 +284,7 @@ esp_err_t parlio_new_tx_unit(const parlio_tx_unit_config_t *config, parlio_tx_un
ESP_GOTO_ON_ERROR(parlio_tx_create_trans_queue(unit, config), err, TAG, "create transaction queue failed");
// register the unit to a group
ESP_GOTO_ON_ERROR(parlio_register_unit_to_group((parlio_unit_base_handle_t)&(unit->base)), err, TAG, "register unit to group failed");
ESP_GOTO_ON_ERROR(parlio_register_unit_to_group(&unit->base), err, TAG, "register unit to group failed");
parlio_group_t *group = unit->base.group;
parlio_hal_context_t *hal = &group->hal;
// select the clock source

Wyświetl plik

@ -0,0 +1,11 @@
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
components/esp_driver_parlio/test_apps/parlio:
disable:
- if: SOC_PARLIO_SUPPORTED != 1
disable_test:
- if: IDF_TARGET == "esp32p4"
temporary: true
reason: lack of runner
depends_components:
- esp_driver_parlio

Wyświetl plik

@ -10,7 +10,7 @@ project(parlio_test)
if(CONFIG_COMPILER_DUMP_RTL_FILES)
add_custom_target(check_test_app_sections ALL
COMMAND ${PYTHON} $ENV{IDF_PATH}/tools/ci/check_callgraph.py
--rtl-dirs ${CMAKE_BINARY_DIR}/esp-idf/driver/,${CMAKE_BINARY_DIR}/esp-idf/hal/
--rtl-dirs ${CMAKE_BINARY_DIR}/esp-idf/esp_driver_parlio/,${CMAKE_BINARY_DIR}/esp-idf/hal/
--elf-file ${CMAKE_BINARY_DIR}/parlio_test.elf
find-refs
--from-sections=.iram0.text

Wyświetl plik

@ -4,11 +4,12 @@ set(srcs "test_app_main.c"
# TODO: IDF-7840, semaphore in 'spi_bus_lock.c' is not IRAM safe
if(CONFIG_PARLIO_ISR_IRAM_SAFE)
list(REMOVE_ITEM srcs "test_parlio_rx")
list(REMOVE_ITEM srcs "test_parlio_rx.c")
endif()
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
# the component can be registered as WHOLE_ARCHIVE
idf_component_register(SRCS ${srcs}
PRIV_REQUIRES unity driver
PRIV_REQUIRES unity esp_driver_parlio esp_driver_gpio
esp_driver_i2s esp_driver_spi
WHOLE_ARCHIVE)

Wyświetl plik

@ -300,8 +300,8 @@ static bool test_delimiter(parlio_rx_delimiter_handle_t deli, bool free_running_
printf("\n");
for (int j = 0; j < TEST_EOF_DATA_LEN; j++) {
// Check if 0x12 0x34 0x56 0x78 appeared in the buffer
if (recv_buff[j] == 0x12 && recv_buff[j+1] == 0x34 &&
recv_buff[j+2] == 0x56 && recv_buff[j+3] == 0x78) {
if (recv_buff[j] == 0x12 && recv_buff[j + 1] == 0x34 &&
recv_buff[j + 2] == 0x56 && recv_buff[j + 3] == 0x78) {
is_success = true;
break;
}

Wyświetl plik

@ -73,9 +73,6 @@ INPUT = \
$(PROJECT_PATH)/components/bt/host/bluedroid/api/include/api/esp_spp_api.h \
$(PROJECT_PATH)/components/bt/host/nimble/esp-hci/include/esp_nimble_hci.h \
$(PROJECT_PATH)/components/console/esp_console.h \
$(PROJECT_PATH)/components/driver/parlio/include/driver/parlio_tx.h \
$(PROJECT_PATH)/components/driver/parlio/include/driver/parlio_rx.h \
$(PROJECT_PATH)/components/driver/parlio/include/driver/parlio_types.h \
$(PROJECT_PATH)/components/driver/touch_sensor/include/driver/touch_sensor_common.h \
$(PROJECT_PATH)/components/driver/twai/include/driver/twai.h \
$(PROJECT_PATH)/components/driver/test_apps/components/esp_serial_slave_link/include/esp_serial_slave_link/essl_sdio.h \
@ -118,6 +115,9 @@ INPUT = \
$(PROJECT_PATH)/components/esp_driver_mcpwm/include/driver/mcpwm_sync.h \
$(PROJECT_PATH)/components/esp_driver_mcpwm/include/driver/mcpwm_timer.h \
$(PROJECT_PATH)/components/esp_driver_mcpwm/include/driver/mcpwm_types.h \
$(PROJECT_PATH)/components/esp_driver_parlio/include/driver/parlio_rx.h \
$(PROJECT_PATH)/components/esp_driver_parlio/include/driver/parlio_tx.h \
$(PROJECT_PATH)/components/esp_driver_parlio/include/driver/parlio_types.h \
$(PROJECT_PATH)/components/esp_driver_i2c/include/driver/i2c_master.h \
$(PROJECT_PATH)/components/esp_driver_i2c/include/driver/i2c_slave.h \
$(PROJECT_PATH)/components/esp_driver_i2c/include/driver/i2c_types.h \

Wyświetl plik

@ -20,7 +20,7 @@ API Reference
.. include-build-file:: inc/parlio_tx.inc
.. include-build-file:: inc/parlio_rx.inc
.. include-build-file:: inc/components/driver/parlio/include/driver/parlio_types.inc
.. include-build-file:: inc/components/esp_driver_parlio/include/driver/parlio_types.inc
.. include-build-file:: inc/components/hal/include/hal/parlio_types.inc
.. [1]

Wyświetl plik

@ -25,6 +25,7 @@ In order to control the dependence of other components on drivers at a smaller g
- `esp_driver_i2c` - Driver for I2C
- `esp_driver_uart` - Driver for UART
- `esp_driver_ledc` - Driver for LEDC
- `esp_driver_parlio` - Driver for Parallel IO
For compatibility, the original `driver`` component is still treated as an all-in-one component by registering these `esp_driver_xyz`` components as its public dependencies. In other words, you do not need to modify the CMake file of an existing project, but you now have a way to specify the specific peripheral driver that your project depends on.

Wyświetl plik

@ -25,6 +25,7 @@
- `esp_driver_i2c` - I2C 驱动
- `esp_driver_uart` - UART 驱动
- `esp_driver_ledc` - LEDC 驱动
- `esp_driver_parlio` - 并行 IO 驱动
为了兼容性,原来的 `driver` 组件仍然存在,并作为一个 “all-in-one" 的组件,将以上这些 `esp_driver_xyz` 组件注册成自己的公共依赖。换句话说,你无需修改既有项目的 CMake 文件,但是你现在多了一个途径去指定你项目依赖的具体的外设驱动。

Wyświetl plik

@ -29,7 +29,7 @@ endif()
idf_component_register(SRCS "${srcs}"
INCLUDE_DIRS "include"
PRIV_REQUIRES esp_netif driver esp_wifi vfs)
PRIV_REQUIRES esp_netif driver esp_wifi vfs console esp_eth)
if(CONFIG_EXAMPLE_PROVIDE_WIFI_CONSOLE_CMD)
idf_component_optional_requires(PRIVATE console)

Wyświetl plik

@ -251,12 +251,16 @@ examples/peripherals/parlio:
- if: IDF_TARGET == "esp32p4"
temporary: true
reason: lack of runner
depends_components:
- esp_driver_parlio
examples/peripherals/parlio/parlio_rx:
disable:
- if: SOC_PARLIO_SUPPORTED != 1 or IDF_TARGET == "esp32p4"
temporary: true
reason: not support esp32p4 yet (IDF-7471)
depends_components:
- esp_driver_parlio
examples/peripherals/parlio/parlio_tx/simple_rgb_led_matrix:
disable:
@ -265,6 +269,8 @@ examples/peripherals/parlio/parlio_tx/simple_rgb_led_matrix:
- if: IDF_TARGET != "esp32c6"
temporary: true
reason: lack of runners
depends_components:
- esp_driver_parlio
examples/peripherals/pcnt:
disable:

Wyświetl plik

@ -5,4 +5,6 @@
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
set(COMPONENTS main)
project(logic_analyzer)

Wyświetl plik

@ -8,5 +8,5 @@ endif()
idf_component_register(SRCS ${src}
INCLUDE_DIRS "./include"
PRIV_INCLUDE_DIRS "."
PRIV_REQUIRES driver hal fatfs esp_partition esp_netif
lwip)
PRIV_REQUIRES fatfs esp_partition esp_netif
lwip esp_driver_parlio)

Wyświetl plik

@ -1,3 +1,4 @@
idf_component_register(SRCS "logic_analyzer_example_main.c"
PRIV_REQUIRES esp_probe driver nvs_flash esp_netif protocol_examples_common
PRIV_REQUIRES esp_probe nvs_flash esp_netif protocol_examples_common
esp_driver_parlio esp_driver_gpio
INCLUDE_DIRS ".")

Wyświetl plik

@ -5,4 +5,6 @@
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
set(COMPONENTS main)
project(rgb_led_matrix)

Wyświetl plik

@ -1,2 +1,3 @@
idf_component_register(SRCS "rgb_led_matrix_example_main.c" "lvgl_demo_ui.c"
PRIV_REQUIRES esp_driver_parlio esp_driver_gpio esp_driver_gptimer
INCLUDE_DIRS ".")