test(parlio): fix sleep test issue
This commit is contained in:
@@ -13,17 +13,27 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Force to trigger the EOF interrupt
|
||||
* @brief Trigger the fake EOF interrupt
|
||||
* @note This function is a workaround for the case that level delimiter needs to receive more than 64KB data in one transaction.
|
||||
* The hardware can't generate the EOF interrupt when the data length is greater than 64KB due to the limitation of the hardware,
|
||||
* so this function is used to trigger the fake EOF interrupt.
|
||||
* @note This function will reset the whole parlio module,
|
||||
* If the pair tx unit is in using,
|
||||
* the reset operation will affect the TX unit and lead to unknown behavior
|
||||
* @usage If the application needs to receive more than 64KB data in one transaction, you can follow the steps below:
|
||||
* 1. Create a level delimiter with a length greater than 64KB
|
||||
* 2. Register the interrupt of the end edge on the valid GPIO
|
||||
* 3. Call this function to trigger the fake EOF interrupt in the GPIO interrupt handler
|
||||
* 4. Receive the transaction that is greater than 64KB
|
||||
*
|
||||
* @param rx_unit Parallel IO RX unit that created by `parlio_new_rx_unit`
|
||||
* @param need_yield Pointer to a status flag to record whether a task switch is needed if this API is being called in an ISR
|
||||
* @return
|
||||
* - ESP_OK: Force to trigger the EOF interrupt successfully
|
||||
* - ESP_OK: Trigger the fake EOF interrupt successfully
|
||||
* - ESP_ERR_INVALID_ARG: Invalid argument like NULL pointer
|
||||
* - ESP_ERR_INVALID_STATE: Tx unit is in using, can't be called when pair tx unit is in using
|
||||
*/
|
||||
esp_err_t parlio_rx_unit_force_trigger_eof(parlio_rx_unit_handle_t rx_unit, bool *need_yield);
|
||||
esp_err_t parlio_rx_unit_trigger_fake_eof(parlio_rx_unit_handle_t rx_unit, bool *need_yield);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -68,7 +68,8 @@ typedef struct parlio_rx_unit_t {
|
||||
size_t dma_burst_size; /*!< DMA burst size, in bytes */
|
||||
gdma_link_list_handle_t dma_link; /*!< DMA link list handle */
|
||||
uint32_t node_num; /*!< The number of nodes in the DMA link list */
|
||||
size_t dma_mem_align; /*!< Alignment for DMA memory */
|
||||
size_t int_mem_align; /*!< Alignment for internal memory */
|
||||
size_t ext_mem_align; /*!< Alignment for external memory */
|
||||
uint32_t curr_node_id; /*!< The index of the current node in the DMA link list */
|
||||
void *usr_recv_buf; /*!< The point to the user's receiving buffer */
|
||||
/* Infinite transaction specific */
|
||||
@@ -164,7 +165,7 @@ size_t parlio_rx_mount_transaction_buffer(parlio_rx_unit_handle_t rx_unit, parli
|
||||
if (rest_size >= 2 * PARLIO_MAX_ALIGNED_DMA_BUF_SIZE) {
|
||||
mount_size = PARLIO_MAX_ALIGNED_DMA_BUF_SIZE;
|
||||
} else if (rest_size <= PARLIO_MAX_ALIGNED_DMA_BUF_SIZE) {
|
||||
mount_size = (required_node_num - tail_node_num == 2) && (i == 0) ? PARLIO_RX_MOUNT_SIZE_CALC(rest_size, 2, trans->alignment) : rest_size;
|
||||
mount_size = ((required_node_num - tail_node_num) == 2) && (i == 0) ? PARLIO_RX_MOUNT_SIZE_CALC(rest_size, 2, trans->alignment) : rest_size;
|
||||
} else {
|
||||
mount_size = PARLIO_RX_MOUNT_SIZE_CALC(rest_size, 2, trans->alignment);
|
||||
}
|
||||
@@ -406,7 +407,7 @@ static bool parlio_rx_default_desc_done_callback(gdma_channel_handle_t dma_chan,
|
||||
/* The sych length should be the cache line size for the un-aligned head and tail part */
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (finished_buffer == rx_unit->stash_buf[i]) {
|
||||
sync_size = rx_unit->dma_mem_align;
|
||||
sync_size = rx_unit->int_mem_align;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -451,7 +452,7 @@ static esp_err_t parlio_rx_create_dma_link(parlio_rx_unit_handle_t rx_unit, uint
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
// calculated the total node number, add 2 for the aligned stash buffer
|
||||
size_t tot_node_num = esp_dma_calculate_node_count(max_recv_size, rx_unit->dma_mem_align, PARLIO_DMA_DESCRIPTOR_BUFFER_MAX_SIZE) + 2;
|
||||
size_t tot_node_num = esp_dma_calculate_node_count(max_recv_size, rx_unit->int_mem_align, PARLIO_DMA_DESCRIPTOR_BUFFER_MAX_SIZE) + 2;
|
||||
gdma_link_list_config_t dma_link_config = {
|
||||
.num_items = tot_node_num,
|
||||
.item_alignment = PARLIO_DMA_DESC_ALIGNMENT,
|
||||
@@ -487,13 +488,16 @@ static esp_err_t parlio_rx_unit_init_dma(parlio_rx_unit_handle_t rx_unit, size_t
|
||||
rx_unit->dma_burst_size = dma_burst_size ? dma_burst_size : 16;
|
||||
gdma_transfer_config_t trans_cfg = {
|
||||
.max_data_burst_size = rx_unit->dma_burst_size, // Enable DMA burst transfer for better performance,
|
||||
.access_ext_mem = true,
|
||||
};
|
||||
ESP_RETURN_ON_ERROR(gdma_config_transfer(rx_unit->dma_chan, &trans_cfg), TAG, "config DMA transfer failed");
|
||||
ESP_RETURN_ON_ERROR(gdma_get_alignment_constraints(rx_unit->dma_chan, &rx_unit->dma_mem_align, NULL), TAG, "get alignment constraints failed");
|
||||
ESP_RETURN_ON_ERROR(gdma_get_alignment_constraints(rx_unit->dma_chan, &rx_unit->int_mem_align, &rx_unit->ext_mem_align), TAG, "get alignment constraints failed");
|
||||
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||
uint32_t cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA);
|
||||
rx_unit->dma_mem_align = rx_unit->dma_mem_align > cache_line_size ? rx_unit->dma_mem_align : cache_line_size;
|
||||
rx_unit->int_mem_align = rx_unit->int_mem_align > cache_line_size ? rx_unit->int_mem_align : cache_line_size;
|
||||
#endif
|
||||
uint32_t ext_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA);
|
||||
rx_unit->ext_mem_align = rx_unit->ext_mem_align > ext_cache_line_size ? rx_unit->ext_mem_align : ext_cache_line_size;
|
||||
|
||||
/* Register callbacks */
|
||||
gdma_rx_event_callbacks_t cbs = {
|
||||
@@ -674,7 +678,8 @@ esp_err_t parlio_new_rx_unit(const parlio_rx_unit_config_t *config, parlio_rx_un
|
||||
ESP_GOTO_ON_ERROR(parlio_rx_create_dma_link(unit, config->max_recv_size), err, TAG, "create dma link list failed");
|
||||
|
||||
for (uint8_t i = 0; i < 2; i++) {
|
||||
unit->stash_buf[i] = heap_caps_aligned_calloc(unit->dma_mem_align, 2, unit->dma_mem_align, PARLIO_MEM_ALLOC_CAPS | MALLOC_CAP_DMA);
|
||||
uint32_t max_alignment = unit->int_mem_align > unit->ext_mem_align ? unit->int_mem_align : unit->ext_mem_align;
|
||||
unit->stash_buf[i] = heap_caps_aligned_calloc(max_alignment, 2, max_alignment, PARLIO_MEM_ALLOC_CAPS | MALLOC_CAP_DMA);
|
||||
ESP_GOTO_ON_FALSE(unit->stash_buf[i], ESP_ERR_NO_MEM, err, TAG, "no memory for stash buffer");
|
||||
}
|
||||
|
||||
@@ -767,7 +772,7 @@ esp_err_t parlio_rx_unit_enable(parlio_rx_unit_handle_t rx_unit, bool reset_queu
|
||||
assert(res == pdTRUE);
|
||||
|
||||
if (trans.flags.indirect_mount && trans.flags.infinite && rx_unit->dma_buf == NULL) {
|
||||
rx_unit->dma_buf = heap_caps_aligned_calloc(rx_unit->dma_mem_align, 1, trans.aligned_payload.buf.body.length, PARLIO_DMA_MEM_ALLOC_CAPS);
|
||||
rx_unit->dma_buf = heap_caps_aligned_calloc(rx_unit->int_mem_align, 1, trans.aligned_payload.buf.body.length, PARLIO_DMA_MEM_ALLOC_CAPS);
|
||||
ESP_GOTO_ON_FALSE(rx_unit->dma_buf, ESP_ERR_NO_MEM, err, TAG, "No memory for the internal DMA buffer");
|
||||
trans.aligned_payload.buf.body.aligned_buffer = rx_unit->dma_buf;
|
||||
trans.aligned_payload.buf.body.recovery_address = rx_unit->dma_buf;
|
||||
@@ -992,7 +997,7 @@ esp_err_t parlio_rx_unit_receive(parlio_rx_unit_handle_t rx_unit,
|
||||
ESP_RETURN_ON_FALSE(rx_unit && payload && recv_cfg, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||
ESP_RETURN_ON_FALSE(recv_cfg->delimiter, ESP_ERR_INVALID_ARG, TAG, "no delimiter specified");
|
||||
ESP_RETURN_ON_FALSE(payload_size <= rx_unit->max_recv_size, ESP_ERR_INVALID_ARG, TAG, "trans length too large");
|
||||
size_t alignment = rx_unit->dma_mem_align;
|
||||
size_t alignment = rx_unit->int_mem_align;
|
||||
if (recv_cfg->flags.partial_rx_en) {
|
||||
ESP_RETURN_ON_FALSE(payload_size >= 2 * alignment, ESP_ERR_INVALID_ARG, TAG, "The payload size should greater than %"PRIu32, 2 * alignment);
|
||||
}
|
||||
@@ -1088,7 +1093,7 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t parlio_rx_unit_force_trigger_eof(parlio_rx_unit_handle_t rx_unit, bool *need_yield)
|
||||
esp_err_t parlio_rx_unit_trigger_fake_eof(parlio_rx_unit_handle_t rx_unit, bool *need_yield)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE_ISR(rx_unit, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||
|
||||
@@ -1104,6 +1109,7 @@ esp_err_t parlio_rx_unit_force_trigger_eof(parlio_rx_unit_handle_t rx_unit, bool
|
||||
ESP_RETURN_ON_ERROR_ISR(gdma_reset(rx_unit->dma_chan), TAG, "reset DMA channel failed");
|
||||
|
||||
parlio_hal_context_t *hal = &rx_unit->base.group->hal;
|
||||
portENTER_CRITICAL_SAFE(&s_rx_spinlock);
|
||||
/* Save the current register values */
|
||||
parl_io_dev_t save_curr_regs = *(parl_io_dev_t *)hal->regs;
|
||||
/* Reset the hardware FSM of the parlio module */
|
||||
@@ -1114,6 +1120,7 @@ esp_err_t parlio_rx_unit_force_trigger_eof(parlio_rx_unit_handle_t rx_unit, bool
|
||||
PARLIO_CLOCK_SRC_ATOMIC() {
|
||||
parlio_ll_rx_set_clock_source(hal->regs, PARLIO_CLK_SRC_DEFAULT);
|
||||
}
|
||||
portEXIT_CRITICAL_SAFE(&s_rx_spinlock);
|
||||
/* Restore the register values and clock source*/
|
||||
memcpy(hal->regs, &save_curr_regs, sizeof(parl_io_dev_t));
|
||||
parlio_ll_rx_update_config(hal->regs);
|
||||
|
||||
@@ -548,6 +548,7 @@ TEST_CASE("parallel_rx_unit_receive_transaction_test", "[parlio_rx]")
|
||||
free(payload);
|
||||
};
|
||||
|
||||
#if SOC_PSRAM_DMA_CAPABLE
|
||||
TEST_CASE("parallel_rx_unit_receive_external_memory_test", "[parlio_rx]")
|
||||
{
|
||||
parlio_rx_unit_handle_t rx_unit = NULL;
|
||||
@@ -588,6 +589,7 @@ TEST_CASE("parallel_rx_unit_receive_external_memory_test", "[parlio_rx]")
|
||||
TEST_ESP_OK(parlio_del_rx_unit(rx_unit));
|
||||
free(payload);
|
||||
}
|
||||
#endif // SOC_PSRAM_DMA_CAPABLE
|
||||
|
||||
TEST_CASE("parallel_rx_unit_receive_timeout_test", "[parlio_rx]")
|
||||
{
|
||||
@@ -677,7 +679,7 @@ static void test_gpio_neg_edge_intr(void *arg)
|
||||
{
|
||||
parlio_rx_unit_handle_t rx_unit = (parlio_rx_unit_handle_t)arg;
|
||||
bool need_yield = false;
|
||||
parlio_rx_unit_force_trigger_eof(rx_unit, &need_yield);
|
||||
parlio_rx_unit_trigger_fake_eof(rx_unit, &need_yield);
|
||||
if (need_yield) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
@@ -730,7 +732,7 @@ TEST_CASE("parallel_rx_unit_force_trigger_eof_test", "[parlio_rx]")
|
||||
uint32_t alignment = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA);
|
||||
alignment = alignment < 4 ? 4 : alignment;
|
||||
size_t buff_size = ALIGN_UP(TEST_TASK_LARGE_TRANS_SIZE, alignment);
|
||||
recv_buff = heap_caps_aligned_calloc(alignment, 1, buff_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_DMA);
|
||||
recv_buff = heap_caps_aligned_calloc(alignment, 1, buff_size, TEST_PARLIO_DMA_MEM_ALLOC_CAPS);
|
||||
TEST_ASSERT_NOT_NULL(recv_buff);
|
||||
|
||||
gpio_set_intr_type(TEST_VALID_GPIO, GPIO_INTR_NEGEDGE);
|
||||
|
||||
@@ -94,7 +94,7 @@ static void test_parlio_sleep_retention(bool allow_pd)
|
||||
|
||||
parlio_rx_level_delimiter_config_t lvl_deli_cfg = {
|
||||
.valid_sig_line_id = PARLIO_RX_UNIT_MAX_DATA_WIDTH - 1,
|
||||
.sample_edge = PARLIO_SAMPLE_EDGE_POS,
|
||||
.sample_edge = PARLIO_SAMPLE_EDGE_NEG, // opposite to tx unit in case of timing issue
|
||||
.bit_pack_order = PARLIO_BIT_PACK_ORDER_MSB,
|
||||
.eof_data_len = TEST_PAYLOAD_SIZE,
|
||||
.timeout_ticks = 0,
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#include "driver/parlio_tx.h"
|
||||
#include "driver/parlio_types.h"
|
||||
#include "esp_private/gpio.h"
|
||||
#include "esp_private/parlio_private.h"
|
||||
#include "esp_private/parlio_tx_private.h"
|
||||
#include "esp_lcd_panel_io_interface.h"
|
||||
#include "esp_lcd_panel_io.h"
|
||||
#include "esp_lcd_common.h"
|
||||
|
||||
Reference in New Issue
Block a user