feat(parlio): refactor gpio mode config in parlio

This commit is contained in:
Chen Jichang
2024-10-11 17:25:52 +08:00
parent 6a29351bd0
commit cfdaf3b379
6 changed files with 86 additions and 53 deletions

View File

@@ -40,8 +40,7 @@ typedef struct {
the output clock will be controlled by the valid gpio,
i.e. high level of valid gpio to enable the clock output, low to disable */
uint32_t io_loop_back: 1; /*!< For debug/test, the signal output from the GPIO will be fed to the input path as well */
uint32_t io_no_init: 1; /*!< Set to skip initializing the GPIO, but only attach the pralio rx signals to those GPIOs via IO Matrix.
So that the signals that have attached to those GPIO won't be overwritten. Mainly used for self communication or self monitoring */
uint32_t io_no_init: 1 __attribute__((deprecated)); /*!< Deprecated. Driver won't change the GPIO configuration in inilization. */
} flags; /*!< RX driver flags */
} parlio_rx_unit_config_t;

View File

@@ -25,7 +25,6 @@
#include "soc/parlio_periph.h"
#include "soc/soc_caps.h"
#include "hal/parlio_ll.h"
#include "hal/gpio_hal.h"
#include "hal/dma_types.h"
#include "hal/hal_utils.h"
#include "driver/gpio.h"
@@ -252,24 +251,19 @@ static esp_err_t s_parlio_rx_unit_set_gpio(parlio_rx_unit_handle_t rx_unit, cons
{
int group_id = rx_unit->base.group->group_id;
int unit_id = rx_unit->base.unit_id;
/* Default GPIO configuration */
gpio_config_t gpio_conf = {
.intr_type = GPIO_INTR_DISABLE,
.pull_down_en = false,
.pull_up_en = true,
};
/* When the source clock comes from external, enable the gpio input direction and connect to the clock input signal */
if (config->clk_src == PARLIO_CLK_SRC_EXTERNAL) {
ESP_RETURN_ON_FALSE(config->clk_in_gpio_num >= 0, ESP_ERR_INVALID_ARG, TAG, "clk_in_gpio_num must be set while the clock input from external");
/* Connect the clock in signal to the GPIO matrix if it is set */
if (!config->flags.io_no_init) {
gpio_conf.mode = config->flags.io_loop_back ? GPIO_MODE_INPUT_OUTPUT : GPIO_MODE_INPUT;
gpio_conf.pin_bit_mask = BIT64(config->clk_in_gpio_num);
ESP_RETURN_ON_ERROR(gpio_config(&gpio_conf), TAG, "config clk in GPIO failed");
} else {
gpio_ll_input_enable(&GPIO, config->clk_in_gpio_num);
gpio_func_sel(config->clk_in_gpio_num, PIN_FUNC_GPIO);
gpio_input_enable(config->clk_in_gpio_num);
// deprecated, to be removed in in esp-idf v6.0
if (config->flags.io_loop_back) {
gpio_output_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);
}
@@ -277,9 +271,14 @@ static esp_err_t s_parlio_rx_unit_set_gpio(parlio_rx_unit_handle_t rx_unit, cons
* enable the gpio output direction and connect to the clock output signal */
if (config->clk_out_gpio_num >= 0) {
#if SOC_PARLIO_RX_CLK_SUPPORT_OUTPUT
gpio_conf.mode = config->flags.io_loop_back ? GPIO_MODE_INPUT_OUTPUT : GPIO_MODE_OUTPUT;
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");
gpio_func_sel(config->clk_out_gpio_num, PIN_FUNC_GPIO);
// deprecated, to be removed in in esp-idf v6.0
if (config->flags.io_loop_back) {
gpio_input_enable(config->clk_out_gpio_num);
}
// 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);
#else
@@ -287,15 +286,16 @@ static esp_err_t s_parlio_rx_unit_set_gpio(parlio_rx_unit_handle_t rx_unit, cons
#endif // SOC_PARLIO_RX_CLK_SUPPORT_OUTPUT
}
gpio_conf.mode = config->flags.io_loop_back ? GPIO_MODE_INPUT_OUTPUT : GPIO_MODE_INPUT;
/* Initialize the valid GPIO as input */
if (config->valid_gpio_num >= 0) {
if (!config->flags.io_no_init) {
gpio_conf.pin_bit_mask = BIT64(config->valid_gpio_num);
ESP_RETURN_ON_ERROR(gpio_config(&gpio_conf), TAG, "config data GPIO failed");
} else {
gpio_ll_input_enable(&GPIO, config->valid_gpio_num);
gpio_func_sel(config->valid_gpio_num, PIN_FUNC_GPIO);
gpio_input_enable(config->valid_gpio_num);
// deprecated, to be removed in in esp-idf v6.0
if (config->flags.io_loop_back) {
gpio_output_enable(config->valid_gpio_num);
}
/* Not connect the signal here, the signal is lazy connected until the delimiter takes effect */
}
@@ -303,12 +303,14 @@ static esp_err_t s_parlio_rx_unit_set_gpio(parlio_rx_unit_handle_t rx_unit, cons
for (int i = 0; i < config->data_width; i++) {
/* Loop the data_gpio_nums to connect data and valid signals via GPIO matrix */
if (config->data_gpio_nums[i] >= 0) {
if (!config->flags.io_no_init) {
gpio_conf.pin_bit_mask = BIT64(config->data_gpio_nums[i]);
ESP_RETURN_ON_ERROR(gpio_config(&gpio_conf), TAG, "config data GPIO failed");
} else {
gpio_ll_input_enable(&GPIO, config->data_gpio_nums[i]);
gpio_func_sel(config->data_gpio_nums[i], PIN_FUNC_GPIO);
gpio_input_enable(config->data_gpio_nums[i]);
// deprecated, to be removed in in esp-idf v6.0
if (config->flags.io_loop_back) {
gpio_output_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);
} else {

View File

@@ -138,46 +138,59 @@ static esp_err_t parlio_tx_unit_configure_gpio(parlio_tx_unit_t *tx_unit, const
{
int group_id = tx_unit->base.group->group_id;
int unit_id = tx_unit->base.unit_id;
gpio_config_t gpio_conf = {
.intr_type = GPIO_INTR_DISABLE,
.mode = config->flags.io_loop_back ? GPIO_MODE_INPUT_OUTPUT : GPIO_MODE_OUTPUT,
.pull_down_en = false,
.pull_up_en = true,
};
// connect peripheral signals via GPIO matrix
for (size_t i = 0; i < config->data_width; i++) {
if (config->data_gpio_nums[i] >= 0) {
gpio_conf.pin_bit_mask = BIT64(config->data_gpio_nums[i]);
ESP_RETURN_ON_ERROR(gpio_config(&gpio_conf), TAG, "config data GPIO failed");
gpio_func_sel(config->data_gpio_nums[i], PIN_FUNC_GPIO);
// deprecated, to be removed in in esp-idf v6.0
if (config->flags.io_loop_back) {
gpio_input_enable(config->data_gpio_nums[i]);
}
// 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);
gpio_func_sel(config->data_gpio_nums[i], PIN_FUNC_GPIO);
}
}
// Note: the valid signal will override TXD[PARLIO_LL_TX_DATA_LINE_AS_VALID_SIG]
if (config->valid_gpio_num >= 0) {
gpio_conf.pin_bit_mask = BIT64(config->valid_gpio_num);
ESP_RETURN_ON_ERROR(gpio_config(&gpio_conf), TAG, "config valid GPIO failed");
gpio_func_sel(config->valid_gpio_num, PIN_FUNC_GPIO);
// deprecated, to be removed in in esp-idf v6.0
if (config->flags.io_loop_back) {
gpio_input_enable(config->valid_gpio_num);
}
// 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].data_sigs[PARLIO_LL_TX_DATA_LINE_AS_VALID_SIG],
false, false);
gpio_func_sel(config->valid_gpio_num, PIN_FUNC_GPIO);
}
if (config->clk_out_gpio_num >= 0) {
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");
gpio_func_sel(config->clk_out_gpio_num, PIN_FUNC_GPIO);
// deprecated, to be removed in in esp-idf v6.0
if (config->flags.io_loop_back) {
gpio_input_enable(config->clk_out_gpio_num);
}
// 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);
gpio_func_sel(config->clk_out_gpio_num, PIN_FUNC_GPIO);
}
if (config->clk_in_gpio_num >= 0) {
gpio_conf.mode = config->flags.io_loop_back ? GPIO_MODE_INPUT_OUTPUT : GPIO_MODE_INPUT;
gpio_conf.pin_bit_mask = BIT64(config->clk_in_gpio_num);
ESP_RETURN_ON_ERROR(gpio_config(&gpio_conf), TAG, "config clk in GPIO failed");
gpio_func_sel(config->clk_in_gpio_num, PIN_FUNC_GPIO);
gpio_input_enable(config->clk_in_gpio_num);
// deprecated, to be removed in in esp-idf v6.0
if (config->flags.io_loop_back) {
gpio_output_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);
gpio_func_sel(config->clk_in_gpio_num, PIN_FUNC_GPIO);
}
return ESP_OK;
}

View File

@@ -52,7 +52,6 @@
}, \
.flags = { \
.clk_gate_en = false, \
.io_loop_back = true, \
} \
}
@@ -528,6 +527,13 @@ TEST_CASE("parallel_rx_unit_receive_transaction_test", "[parlio_rx]")
TEST_CASE("parallel_rx_unit_receive_timeout_test", "[parlio_rx]")
{
printf("init a gpio to simulate valid signal\r\n");
gpio_config_t test_gpio_conf = {
.mode = GPIO_MODE_OUTPUT,
.pin_bit_mask = BIT64(TEST_VALID_GPIO),
};
TEST_ESP_OK(gpio_config(&test_gpio_conf));
parlio_rx_unit_handle_t rx_unit = NULL;
parlio_rx_delimiter_handle_t timeout_deli = NULL;
@@ -583,5 +589,6 @@ TEST_CASE("parallel_rx_unit_receive_timeout_test", "[parlio_rx]")
TEST_ESP_OK(parlio_rx_unit_disable(rx_unit));
TEST_ESP_OK(parlio_del_rx_delimiter(timeout_deli));
TEST_ESP_OK(parlio_del_rx_unit(rx_unit));
TEST_ESP_OK(gpio_reset_pin(TEST_VALID_GPIO));
free(payload);
}

View File

@@ -178,6 +178,13 @@ TEST_CASE("parallel_tx_unit_enable_disable", "[parlio_tx]")
TEST_CASE("parallel_tx_unit_idle_value", "[parlio_tx]")
{
printf("init a gpio to read parlio_tx output\r\n");
gpio_config_t test_gpio_conf = {
.mode = GPIO_MODE_INPUT,
.pin_bit_mask = BIT64(TEST_DATA0_GPIO),
};
TEST_ESP_OK(gpio_config(&test_gpio_conf));
printf("install parlio tx unit\r\n");
parlio_tx_unit_handle_t tx_unit = NULL;
parlio_tx_unit_config_t config = {
@@ -201,7 +208,6 @@ TEST_CASE("parallel_tx_unit_idle_value", "[parlio_tx]")
.max_transfer_size = 64,
.bit_pack_order = PARLIO_BIT_PACK_ORDER_LSB,
.sample_edge = PARLIO_SAMPLE_EDGE_POS,
.flags.io_loop_back = 1, // enable loop back by GPIO matrix, so that we can read the level of the data line by gpio driver
};
TEST_ESP_OK(parlio_new_tx_unit(&config, &tx_unit));
TEST_ESP_OK(parlio_tx_unit_enable(tx_unit));
@@ -224,11 +230,19 @@ TEST_CASE("parallel_tx_unit_idle_value", "[parlio_tx]")
TEST_ESP_OK(parlio_tx_unit_disable(tx_unit));
TEST_ESP_OK(parlio_del_tx_unit(tx_unit));
TEST_ESP_OK(gpio_reset_pin(TEST_DATA0_GPIO));
}
#if SOC_PARLIO_TX_CLK_SUPPORT_GATING
TEST_CASE("parallel_tx_clock_gating", "[paralio_tx]")
{
printf("init a gpio to read parlio_tx clk output\r\n");
gpio_config_t test_gpio_conf = {
.mode = GPIO_MODE_INPUT,
.pin_bit_mask = BIT64(TEST_CLK_GPIO),
};
TEST_ESP_OK(gpio_config(&test_gpio_conf));
printf("install parlio tx unit\r\n");
parlio_tx_unit_handle_t tx_unit = NULL;
parlio_tx_unit_config_t config = {
@@ -247,7 +261,6 @@ TEST_CASE("parallel_tx_clock_gating", "[paralio_tx]")
.bit_pack_order = PARLIO_BIT_PACK_ORDER_MSB,
.sample_edge = PARLIO_SAMPLE_EDGE_POS,
.flags.clk_gate_en = true, // enable clock gating, controlled by the level of TEST_DATA7_GPIO
.flags.io_loop_back = true, // for reading the level of the clock line in IDLE state
};
TEST_ESP_OK(parlio_new_tx_unit(&config, &tx_unit));
TEST_ESP_OK(parlio_tx_unit_enable(tx_unit));
@@ -272,5 +285,6 @@ TEST_CASE("parallel_tx_clock_gating", "[paralio_tx]")
TEST_ESP_OK(parlio_tx_unit_disable(tx_unit));
TEST_ESP_OK(parlio_del_tx_unit(tx_unit));
TEST_ESP_OK(gpio_reset_pin(TEST_CLK_GPIO));
}
#endif // SOC_PARLIO_TX_CLK_SUPPORT_GATING

View File

@@ -82,8 +82,6 @@ esp_err_t esp_probe_priv_init_hardware(esp_probe_handle_t handle, esp_probe_conf
.valid_gpio_num = GPIO_NUM_NC, // Does not need valid gpio, all data gpio are used as sampling channel
.flags = {
.clk_gate_en = false,
.io_loop_back = true,
.io_no_init = true,
}
};
memcpy(parlio_rx_cfg.data_gpio_nums, config->probe_gpio, PARLIO_RX_UNIT_MAX_DATA_WIDTH * sizeof(gpio_num_t));