From 188864bcbdb82c3ba43b975df972f838607ac8b8 Mon Sep 17 00:00:00 2001 From: morris Date: Wed, 1 Mar 2023 17:22:39 +0800 Subject: [PATCH] feat(parlio_rx): add parallel IO RX driver --- .../driver/parlio/include/driver/parlio_rx.h | 99 +++++++++++++++++++ .../parlio/include/driver/parlio_types.h | 10 ++ components/hal/include/hal/parlio_types.h | 3 + 3 files changed, 112 insertions(+) create mode 100644 components/driver/parlio/include/driver/parlio_rx.h diff --git a/components/driver/parlio/include/driver/parlio_rx.h b/components/driver/parlio/include/driver/parlio_rx.h new file mode 100644 index 0000000000..ff8b73754c --- /dev/null +++ b/components/driver/parlio/include/driver/parlio_rx.h @@ -0,0 +1,99 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "esp_err.h" +#include "driver/parlio_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Parallel IO RX unit configuration + */ +typedef struct { + parlio_clock_source_t clk_src; /*!< Parallel IO clock source */ + size_t data_width; /*!< Parallel IO data width */ + int data_gpio_nums[PARLIO_RX_UNIT_MAX_DATA_WIDTH]; /*!< Parallel IO data GPIO numbers, set to `-1` if it's not used */ + int clk_gpio_num; /*!< Parallel IO clock GPIO number, set to `-1` if the clock is not clocked from gpio pad*/ + uint32_t clk_freq_hz; /*!< Parallel IO clock frequency in Hz */ +} parlio_rx_unit_config_t; + +esp_err_t parlio_new_rx_unit(const parlio_rx_unit_config_t *config, parlio_rx_unit_handle_t *ret_unit); + +esp_err_t parlio_del_rx_unit(parlio_rx_unit_handle_t unit); + +esp_err_t parlio_rx_unit_enable(parlio_rx_unit_handle_t unit); + +esp_err_t parlio_rx_unit_disable(parlio_rx_unit_handle_t unit); + +typedef struct { + uint32_t data_line_as_enable; /*!< Which IO data line will be used as data enable/valid signal */ + struct { + uint32_t active_level: 1; /*!< Which level indicates the validation of the transmitting data */ + } flags; /*!< Extra flags */ +} parlio_rx_level_delimiter_config_t; + +/** + * @brief + * + * @note The enable signal must be aligned with the valid data. + * @note There're at most `SOC_PARLIO_RX_UNIT_MAX_DATA_WIDTH - 1` IO pins left for RXD + * + * @param config + * @param ret_delimiter + * @return esp_err_t + */ +esp_err_t parlio_new_rx_level_delimiter(const parlio_rx_level_delimiter_config_t *config, parlio_rx_delimiter_handle_t *ret_delimiter); + +typedef struct { + uint32_t data_line_as_enable; /*!< Which IO data line will be used as data enable signal */ + struct { + uint32_t active_level: 1; /*!< On which level the pulse is considered active */ + uint32_t start_bit_included: 1; /*!< Whether data bit is included in the start pulse */ + uint32_t has_end_pulse: 1; /*!< Whether there's an end pulse to terminate the transaction, + if no, the transaction will be terminated by user configured transcation length */ + uint32_t end_bit_included: 1; /*!< Whether data bit is included in the end pulse, only valid when `has_end_pulse` is true */ + uint32_t gen_eof_by_end_pulse: 1; /*!< Whether the DMA EOF event is generated by the end pulse instead of data length, + only valid when `end_bit_included` is true */ + } flags; /*!< Extra flags */ +} parlio_rx_pulse_delimiter_config_t; + +/** + * @brief + * + * @note There're at most `SOC_PARLIO_RX_UNIT_MAX_DATA_WIDTH - 1` IO pins left for RXD + * + * @param config + * @param ret_delimiter + * @return esp_err_t + */ +esp_err_t parlio_new_rx_pulse_delimiter(const parlio_rx_pulse_delimiter_config_t *config, parlio_rx_delimiter_handle_t *ret_delimiter); + +typedef struct { +} parlio_rx_soft_delimiter_config_t; + +esp_err_t parlio_new_rx_soft_delimiter(const parlio_rx_soft_delimiter_config_t *config, parlio_rx_delimiter_handle_t *ret_delimiter); +esp_err_t parlio_rx_soft_delimiter_begin_end(parlio_rx_delimiter_handle_t delimiter, bool begin_end); + +typedef struct { + parlio_sample_edge_t sample_edge; /*!< Parallel IO sample edge */ + parlio_bit_pack_endian_t bit_pack_endian; /*!< Set how we pack the bits into one bytes */ + parlio_rx_delimiter_handle_t delimiter; /*!< Specify the frame delimiter, either from software or external signal (level or pulse) */ + uint32_t timeout_us; /*!< Timeout in us, 0 means no timeout */ + struct { + } flags; /*!< Extra flags */ +} parlio_receive_config_t; + +esp_err_t parlio_rx_unit_receive(parlio_rx_unit_handle_t rx_unit, void *buffer, size_t buffer_size, const parlio_receive_config_t *config); + +#ifdef __cplusplus +} +#endif diff --git a/components/driver/parlio/include/driver/parlio_types.h b/components/driver/parlio/include/driver/parlio_types.h index c6dbff9b2a..b909d54895 100644 --- a/components/driver/parlio/include/driver/parlio_types.h +++ b/components/driver/parlio/include/driver/parlio_types.h @@ -21,6 +21,16 @@ extern "C" { */ typedef struct parlio_tx_unit_t *parlio_tx_unit_handle_t; +/** + * @brief Type of Parallel IO RX unit handle + */ +typedef struct parlio_rx_unit_t *parlio_rx_unit_handle_t; + +/** + * @brief Type of Parallel IO RX frame delimiter handle + */ +typedef struct parlio_rx_delimiter_t *parlio_rx_delimiter_handle_t; + #ifdef __cplusplus } #endif diff --git a/components/hal/include/hal/parlio_types.h b/components/hal/include/hal/parlio_types.h index 53b99c59ab..41358a8334 100644 --- a/components/hal/include/hal/parlio_types.h +++ b/components/hal/include/hal/parlio_types.h @@ -58,9 +58,12 @@ typedef soc_periph_parlio_clk_src_t parlio_clock_source_t; /// Maximum data width of TX unit #define PARLIO_TX_UNIT_MAX_DATA_WIDTH SOC_PARLIO_TX_UNIT_MAX_DATA_WIDTH +/// Maximum data width of RX unit +#define PARLIO_RX_UNIT_MAX_DATA_WIDTH SOC_PARLIO_RX_UNIT_MAX_DATA_WIDTH #else typedef int parlio_clock_source_t; #define PARLIO_TX_UNIT_MAX_DATA_WIDTH 0 +#define PARLIO_RX_UNIT_MAX_DATA_WIDTH 0 #endif // SOC_PARLIO_SUPPORTED #ifdef __cplusplus