diff --git a/components/esp_hw_support/test_apps/dma/main/test_gdma_crc.c b/components/esp_hw_support/test_apps/dma/main/test_gdma_crc.c index c8c83b879c9..405873a6568 100644 --- a/components/esp_hw_support/test_apps/dma/main/test_gdma_crc.c +++ b/components/esp_hw_support/test_apps/dma/main/test_gdma_crc.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -33,33 +33,43 @@ static test_crc_case_t crc_test_cases[] = { .crc_bit_width = 8, .init_value = 0x00, .poly_hex = 0x07, - .expected_result = 0x1C, + .expected_result = 0x08, }, [1] = { .crc_bit_width = 8, .init_value = 0x00, .poly_hex = 0x07, .reverse_data_mask = true, // refin = true - .expected_result = 0xB9, + .expected_result = 0xCE, }, // CRC16, x^16+x^12+x^5+1 [2] = { .crc_bit_width = 16, .init_value = 0xFFFF, .poly_hex = 0x1021, - .expected_result = 0x7563, + .expected_result = 0x0ED7, }, // CRC32, x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1 [3] = { .crc_bit_width = 32, .init_value = 0xFFFFFFFF, .poly_hex = 0x04C11DB7, - .expected_result = 0x069A43E6, + .expected_result = 0x6D9BD7D5, } }; +static bool test_gdma_crc_calculation_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data) +{ + BaseType_t high_task_wakeup = pdFALSE; + SemaphoreHandle_t semaphore = (SemaphoreHandle_t)user_data; + if (event_data->flags.normal_eof) { + xSemaphoreGiveFromISR(semaphore, &high_task_wakeup); + } + return high_task_wakeup; +} + // CRC online: https://www.lddgo.net/en/encrypt/crc -static void test_gdma_crc_calculation(gdma_channel_handle_t tx_chan, int test_num_crc_algorithm) +static void test_gdma_crc_calculation(gdma_channel_handle_t tx_chan, gdma_channel_handle_t rx_chan, int test_num_crc_algorithm) { // Note, burst size should be at least 16 when accessing encrypted external memory gdma_transfer_config_t transfer_cfg = { @@ -67,30 +77,41 @@ static void test_gdma_crc_calculation(gdma_channel_handle_t tx_chan, int test_nu .access_ext_mem = true, }; TEST_ESP_OK(gdma_config_transfer(tx_chan, &transfer_cfg)); + TEST_ESP_OK(gdma_config_transfer(rx_chan, &transfer_cfg)); + SemaphoreHandle_t semaphore = xSemaphoreCreateBinary(); uint32_t crc_result = 0; - static const char test_input_string[] __attribute__((aligned(GDMA_LL_ACCESS_ENCRYPTION_MEM_ALIGNMENT))) = "GDMACRC::TEST::X"; + static const char test_input_string[] __attribute__((aligned(SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT))) = "GDMACRC::TEST::LONGSTRING::REPEAT::GDMACRC::TEST::LONGSTRING::REPEAT::GDMACRC::TEST::LONGSTRING::REPEAT::GDMACRC::TEST::LONGSTRING::REPEAT::END!"; size_t input_data_size = strlen(test_input_string); - - TEST_ASSERT_EQUAL((uintptr_t)test_input_string % GDMA_LL_ACCESS_ENCRYPTION_MEM_ALIGNMENT, 0); + TEST_ASSERT_EQUAL((uintptr_t)test_input_string % SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT, 0); // this test case also test the GDMA can fetch data from MSPI Flash TEST_ASSERT_TRUE(esp_ptr_in_drom(test_input_string)); printf("Calculate CRC value for string: \"%s\"\r\n", test_input_string); + uint8_t *rx_buffer = NULL; + rx_buffer = heap_caps_calloc(1, strlen(test_input_string), MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + TEST_ASSERT_NOT_NULL(rx_buffer); + gdma_trigger_t m2m_trigger = GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_M2M, 0); // get a free DMA trigger ID uint32_t free_m2m_id_mask = 0; gdma_get_free_m2m_trig_id_mask(tx_chan, &free_m2m_id_mask); + m2m_trigger.instance_id = __builtin_ctz(free_m2m_id_mask); TEST_ESP_OK(gdma_connect(tx_chan, m2m_trigger)); + TEST_ESP_OK(gdma_connect(rx_chan, m2m_trigger)); + + gdma_tx_event_callbacks_t tx_cbs = { + .on_trans_eof = test_gdma_crc_calculation_callback, + }; + TEST_ESP_OK(gdma_register_tx_event_callbacks(tx_chan, &tx_cbs, semaphore)); size_t sram_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA); size_t alignment = MAX(sram_cache_line_size, 8); dma_descriptor_align8_t *tx_descs = heap_caps_aligned_calloc(alignment, 1, sizeof(dma_descriptor_align8_t), MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); TEST_ASSERT_NOT_NULL(tx_descs); - tx_descs->buffer = (void *)test_input_string; tx_descs->dw0.size = input_data_size + 1; // +1 for '\0' tx_descs->dw0.length = input_data_size; @@ -98,9 +119,18 @@ static void test_gdma_crc_calculation(gdma_channel_handle_t tx_chan, int test_nu tx_descs->dw0.suc_eof = 1; tx_descs->next = NULL; + dma_descriptor_align8_t *rx_descs = heap_caps_aligned_calloc(alignment, 1, sizeof(dma_descriptor_align8_t), + MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + TEST_ASSERT_NOT_NULL(rx_descs); + rx_descs->buffer = (void *)rx_buffer; + rx_descs->dw0.size = input_data_size; + rx_descs->dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; + rx_descs->next = NULL; + if (sram_cache_line_size) { // do write-back for the buffer because it's in the cache TEST_ESP_OK(esp_cache_msync((void *)tx_descs, sizeof(dma_descriptor_align8_t), ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED)); + TEST_ESP_OK(esp_cache_msync((void *)rx_descs, sizeof(dma_descriptor_align8_t), ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED)); } for (int i = 0; i < test_num_crc_algorithm; i++) { @@ -111,35 +141,48 @@ static void test_gdma_crc_calculation(gdma_channel_handle_t tx_chan, int test_nu .reverse_data_mask = crc_test_cases[i].reverse_data_mask, }; TEST_ESP_OK(gdma_config_crc_calculator(tx_chan, &crc_config)); + TEST_ESP_OK(gdma_reset(rx_chan)); + TEST_ESP_OK(gdma_start(rx_chan, (intptr_t)rx_descs)); TEST_ESP_OK(gdma_reset(tx_chan)); TEST_ESP_OK(gdma_start(tx_chan, (intptr_t)tx_descs)); - // simply wait for the transfer done - vTaskDelay(pdMS_TO_TICKS(100)); + // wait for the transfer done + xSemaphoreTake(semaphore, pdMS_TO_TICKS(100)); TEST_ESP_OK(gdma_crc_get_result(tx_chan, &crc_result)); printf("CRC Result: 0x%"PRIx32"\r\n", crc_result); TEST_ASSERT_EQUAL(crc_test_cases[i].expected_result, crc_result); } free(tx_descs); + free(rx_descs); + free(rx_buffer); + vSemaphoreDelete(semaphore); } TEST_CASE("GDMA CRC Calculation", "[GDMA][CRC]") { gdma_channel_handle_t tx_chan = NULL; + gdma_channel_handle_t rx_chan = NULL; gdma_channel_alloc_config_t tx_chan_alloc_config = { .direction = GDMA_CHANNEL_DIRECTION_TX, }; + gdma_channel_alloc_config_t rx_chan_alloc_config = { + .direction = GDMA_CHANNEL_DIRECTION_RX, + }; #if SOC_AHB_GDMA_SUPPORTED printf("Test CRC calculation for AHB GDMA\r\n"); TEST_ESP_OK(gdma_new_ahb_channel(&tx_chan_alloc_config, &tx_chan)); - test_gdma_crc_calculation(tx_chan, 4); + TEST_ESP_OK(gdma_new_ahb_channel(&rx_chan_alloc_config, &rx_chan)); + test_gdma_crc_calculation(tx_chan, rx_chan, 4); TEST_ESP_OK(gdma_del_channel(tx_chan)); + TEST_ESP_OK(gdma_del_channel(rx_chan)); #endif // SOC_AHB_GDMA_SUPPORTED #if SOC_AXI_GDMA_SUPPORTED printf("Test CRC calculation for AXI GDMA\r\n"); TEST_ESP_OK(gdma_new_axi_channel(&tx_chan_alloc_config, &tx_chan)); - test_gdma_crc_calculation(tx_chan, 3); + TEST_ESP_OK(gdma_new_axi_channel(&rx_chan_alloc_config, &rx_chan)); + test_gdma_crc_calculation(tx_chan, rx_chan, 3); TEST_ESP_OK(gdma_del_channel(tx_chan)); + TEST_ESP_OK(gdma_del_channel(rx_chan)); #endif // SOC_AXI_GDMA_SUPPORTED }