feat(lcd): support parlio lcd interface

This commit is contained in:
Chen Jichang
2024-12-04 14:50:16 +08:00
committed by Chen Ji Chang
parent b6b0758e42
commit e890b4bd7e
35 changed files with 1119 additions and 59 deletions
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -43,6 +43,7 @@ typedef struct {
uint32_t allow_pd: 1; /*!< Set to allow power down. When this flag set, the driver will backup/restore the PARLIO registers before/after entering/exist sleep mode.
By this approach, the system can power off PARLIO's power domain.
This can save power, but at the expense of more RAM being consumed. */
uint32_t invert_valid_out: 1; /*!< Invert the output valid signal */
} flags; /*!< Extra configuration flags */
} parlio_tx_unit_config_t;
@@ -0,0 +1,30 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "driver/parlio_tx.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Get the alignment constraints for internal and external memory of the GDMA used in parlio_tx unit
*
* @param[in] tx_unit Parallel IO TX unit that created by `parlio_new_tx_unit`
* @param[out] int_mem_align Internal memory alignment
* @param[out] ext_mem_align External memory alignment
* @return
* - ESP_OK: Get alignment constraints successfully
* - ESP_ERR_INVALID_ARG: Get alignment constraints failed because of invalid argument
* - ESP_FAIL: Get alignment constraints failed because of other error
*/
esp_err_t parlio_tx_get_alignment_constraints(parlio_tx_unit_handle_t tx_unit, size_t *int_mem_align, size_t *ext_mem_align);
#ifdef __cplusplus
}
#endif
@@ -68,13 +68,6 @@ typedef dma_descriptor_align8_t parlio_dma_desc_t;
#define PARLIO_MAX_ALIGNED_DMA_BUF_SIZE DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED
#endif
#ifdef CACHE_LL_L2MEM_NON_CACHE_ADDR
/* The descriptor address can be mapped by a fixed offset */
#define PARLIO_GET_NON_CACHED_DESC_ADDR(desc) (desc ? (parlio_dma_desc_t *)(CACHE_LL_L2MEM_NON_CACHE_ADDR(desc)) : NULL)
#else
#define PARLIO_GET_NON_CACHED_DESC_ADDR(desc) (desc)
#endif // CACHE_LL_L2MEM_NON_CACHE_ADDR
#if SOC_PERIPH_CLK_CTRL_SHARED
#define PARLIO_CLOCK_SRC_ATOMIC() PERIPH_RCC_ATOMIC()
#else
+22 -10
View File
@@ -24,6 +24,7 @@
#include "esp_attr.h"
#include "esp_err.h"
#include "esp_rom_gpio.h"
#include "soc/gpio_sig_map.h"
#include "esp_intr_alloc.h"
#include "esp_pm.h"
#include "soc/parlio_periph.h"
@@ -166,7 +167,7 @@ static esp_err_t parlio_tx_unit_configure_gpio(parlio_tx_unit_t *tx_unit, const
// 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);
config->flags.invert_valid_out, false);
}
if (config->clk_out_gpio_num >= 0) {
gpio_func_sel(config->clk_out_gpio_num, PIN_FUNC_GPIO);
@@ -232,6 +233,18 @@ static esp_err_t parlio_tx_unit_init_dma(parlio_tx_unit_t *tx_unit, const parlio
return ESP_OK;
}
esp_err_t parlio_tx_get_alignment_constraints(parlio_tx_unit_t *tx_unit, size_t *int_mem_align, size_t *ext_mem_align)
{
ESP_RETURN_ON_FALSE(tx_unit, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
if (int_mem_align) {
*int_mem_align = tx_unit->int_mem_align;
}
if (ext_mem_align) {
*ext_mem_align = tx_unit->ext_mem_align;
}
return ESP_OK;
}
static esp_err_t parlio_select_periph_clock(parlio_tx_unit_t *tx_unit, const parlio_tx_unit_config_t *config)
{
parlio_hal_context_t *hal = &tx_unit->base.group->hal;
@@ -640,8 +653,15 @@ static void IRAM_ATTR parlio_tx_default_isr(void *args)
parlio_ll_clear_interrupt_status(hal->regs, PARLIO_LL_EVENT_TX_EOF);
parlio_ll_tx_start(hal->regs, false);
parlio_tx_trans_desc_t *trans_desc = NULL;
// invoke callback before sending the transaction to complete queue
parlio_tx_done_callback_t done_cb = tx_unit->on_trans_done;
if (done_cb) {
if (done_cb(tx_unit, NULL, tx_unit->user_data)) {
need_yield = true;
}
}
parlio_tx_trans_desc_t *trans_desc = NULL;
parlio_tx_fsm_t expected_fsm = PARLIO_TX_FSM_RUN;
if (atomic_compare_exchange_strong(&tx_unit->fsm, &expected_fsm, PARLIO_TX_FSM_ENABLE_WAIT)) {
trans_desc = tx_unit->cur_trans;
@@ -654,14 +674,6 @@ static void IRAM_ATTR parlio_tx_default_isr(void *args)
atomic_store(&tx_unit->fsm, PARLIO_TX_FSM_ENABLE);
}
// invoke callback
parlio_tx_done_callback_t done_cb = tx_unit->on_trans_done;
if (done_cb) {
if (done_cb(tx_unit, NULL, tx_unit->user_data)) {
need_yield = true;
}
}
// if the tx unit is till in enable state (i.e. not disabled by user), let's try start the next pending transaction
expected_fsm = PARLIO_TX_FSM_ENABLE;
if (atomic_compare_exchange_strong(&tx_unit->fsm, &expected_fsm, PARLIO_TX_FSM_RUN_WAIT)) {
@@ -43,27 +43,27 @@ extern "C" {
#define TEST_DATA6_GPIO 6
#define TEST_DATA7_GPIO 7
#elif CONFIG_IDF_TARGET_ESP32H2
#define TEST_CLK_GPIO 10
#define TEST_VALID_GPIO 11
#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 8
#define TEST_DATA7_GPIO 9
#define TEST_VALID_GPIO 2
#define TEST_CLK_GPIO 3
#define TEST_DATA0_GPIO 8
#define TEST_DATA1_GPIO 5
#define TEST_DATA2_GPIO 9
#define TEST_DATA3_GPIO 10
#define TEST_DATA4_GPIO 27
#define TEST_DATA5_GPIO 11
#define TEST_DATA6_GPIO 26
#define TEST_DATA7_GPIO 12
#elif CONFIG_IDF_TARGET_ESP32P4
#define TEST_CLK_GPIO 33
#define TEST_VALID_GPIO 36
#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 6
#define TEST_DATA7_GPIO 7
#define TEST_VALID_GPIO 32
#define TEST_DATA0_GPIO 24
#define TEST_DATA1_GPIO 25
#define TEST_DATA2_GPIO 26
#define TEST_DATA3_GPIO 27
#define TEST_DATA4_GPIO 28
#define TEST_DATA5_GPIO 29
#define TEST_DATA6_GPIO 30
#define TEST_DATA7_GPIO 31
#else
#error "Unsupported target"
#endif
@@ -303,7 +303,7 @@ TEST_CASE("parlio can transmit PSRAM buffer", "[parlio_tx]")
.data_gpio_nums = {
TEST_DATA0_GPIO,
},
.output_clk_freq_hz = 20 * 1000 * 1000,
.output_clk_freq_hz = 10 * 1000 * 1000,
.trans_queue_depth = 4,
.max_transfer_size = 65535,
.bit_pack_order = PARLIO_BIT_PACK_ORDER_LSB,