From ca17b599c45d774e2815188a5a46e2fd1f2ff267 Mon Sep 17 00:00:00 2001 From: morris Date: Thu, 26 Feb 2026 00:12:07 +0800 Subject: [PATCH] feat(crc): added async crc console example --- .../api-reference/peripherals/async_crc.rst | 5 + .../api-reference/peripherals/async_crc.rst | 5 + examples/peripherals/.build-test-rules.yml | 7 + examples/peripherals/camera/dvp_dsi/README.md | 4 +- .../peripherals/camera/dvp_isp_dsi/README.md | 4 +- .../peripherals/camera/dvp_spi_lcd/README.md | 4 +- .../peripherals/camera/mipi_isp_dsi/README.md | 4 +- .../peripherals/dma/async_crc/CMakeLists.txt | 5 + examples/peripherals/dma/async_crc/README.md | 69 +++++++++ .../dma/async_crc/main/CMakeLists.txt | 4 + .../async_crc/main/async_crc_example_main.c | 34 +++++ .../peripherals/dma/async_crc/main/cmd_crc.c | 140 ++++++++++++++++++ .../peripherals/dma/async_crc/main/cmd_crc.h | 17 +++ .../dma/async_crc/pytest_async_crc.py | 75 ++++++++++ .../peripherals/isp/multi_pipelines/README.md | 6 +- examples/peripherals/ppa/ppa_dsi/README.md | 4 +- .../requirements.test-specific.txt | 3 + 17 files changed, 371 insertions(+), 19 deletions(-) create mode 100644 examples/peripherals/dma/async_crc/CMakeLists.txt create mode 100644 examples/peripherals/dma/async_crc/README.md create mode 100644 examples/peripherals/dma/async_crc/main/CMakeLists.txt create mode 100644 examples/peripherals/dma/async_crc/main/async_crc_example_main.c create mode 100644 examples/peripherals/dma/async_crc/main/cmd_crc.c create mode 100644 examples/peripherals/dma/async_crc/main/cmd_crc.h create mode 100644 examples/peripherals/dma/async_crc/pytest_async_crc.py diff --git a/docs/en/api-reference/peripherals/async_crc.rst b/docs/en/api-reference/peripherals/async_crc.rst index 275aa27ad2..f440c305e6 100644 --- a/docs/en/api-reference/peripherals/async_crc.rst +++ b/docs/en/api-reference/peripherals/async_crc.rst @@ -332,6 +332,11 @@ The ``dma_burst_size`` affects DMA transfer efficiency: The optimal value depends on your chip's DMA controller capabilities. +Application Examples +==================== + +- :example:`peripherals/dma/async_crc` demonstrates how to use the Async CRC driver through an interactive console CLI. + API Reference ============= diff --git a/docs/zh_CN/api-reference/peripherals/async_crc.rst b/docs/zh_CN/api-reference/peripherals/async_crc.rst index adfb011296..7d06d4a5f2 100644 --- a/docs/zh_CN/api-reference/peripherals/async_crc.rst +++ b/docs/zh_CN/api-reference/peripherals/async_crc.rst @@ -332,6 +332,11 @@ DMA 突发大小 最佳值取决于芯片的 DMA 控制器功能。 +应用示例 +======== + +- :example:`peripherals/dma/async_crc` 演示了如何通过交互式控制台 CLI 使用异步 CRC 驱动程序。 + API 参考 ======== diff --git a/examples/peripherals/.build-test-rules.yml b/examples/peripherals/.build-test-rules.yml index aa7da3d8cd..914bc63235 100644 --- a/examples/peripherals/.build-test-rules.yml +++ b/examples/peripherals/.build-test-rules.yml @@ -95,6 +95,13 @@ examples/peripherals/dac/dac_cosine_wave: - esp_driver_dac - soc +examples/peripherals/dma/async_crc: + disable: + - if: SOC_GDMA_SUPPORT_CRC != 1 + depends_components: + - esp_driver_dma + - esp_console + examples/peripherals/gpio: depends_components: - esp_driver_gpio diff --git a/examples/peripherals/camera/dvp_dsi/README.md b/examples/peripherals/camera/dvp_dsi/README.md index f6408ca4f2..d2bdbcd1f6 100644 --- a/examples/peripherals/camera/dvp_dsi/README.md +++ b/examples/peripherals/camera/dvp_dsi/README.md @@ -151,6 +151,4 @@ I (8291) sensor_init: Format in use:DVP_8bit_20Minput_RGB565_640x480_6fps ## Reference -- Link to the ESP-IDF feature's API reference, for example [ESP-IDF: Camera Controller Driver](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/camera_driver.html) -- [ESP-IDF Getting Started](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html#get-started) -- [Project Configuration](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/kconfig.html) (Kconfig Options) +- [ESP-IDF: Camera Controller Driver](https://docs.espressif.com/projects/esp-idf/en/latest/esp32p4/api-reference/peripherals/camera_driver.html) diff --git a/examples/peripherals/camera/dvp_isp_dsi/README.md b/examples/peripherals/camera/dvp_isp_dsi/README.md index 73e97a3662..aafc38da83 100644 --- a/examples/peripherals/camera/dvp_isp_dsi/README.md +++ b/examples/peripherals/camera/dvp_isp_dsi/README.md @@ -151,6 +151,4 @@ I (2609) sensor_init: Format in use:DVP_8bit_20Minput_RAW8_1024x600_15fps ## Reference -- Link to the ESP-IDF feature's API reference, for example [ESP-IDF: Camera Controller Driver](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/camera_driver.html) -- [ESP-IDF Getting Started](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html#get-started) -- [Project Configuration](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/kconfig.html) (Kconfig Options) +- [ESP-IDF: Camera Controller Driver](https://docs.espressif.com/projects/esp-idf/en/latest/esp32p4/api-reference/peripherals/camera_driver.html) diff --git a/examples/peripherals/camera/dvp_spi_lcd/README.md b/examples/peripherals/camera/dvp_spi_lcd/README.md index 6a69880dc2..8c28c8e365 100644 --- a/examples/peripherals/camera/dvp_spi_lcd/README.md +++ b/examples/peripherals/camera/dvp_spi_lcd/README.md @@ -134,6 +134,4 @@ I (408) dvp_spi_lcd: Screen lit up now! ## Reference -- Link to the ESP-IDF feature's API reference, for example [ESP-IDF: Camera Controller Driver](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/camera_driver.html) -- [ESP-IDF Getting Started](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html#get-started) -- [Project Configuration](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/kconfig.html) (Kconfig Options) +- [ESP-IDF: Camera Controller Driver](https://docs.espressif.com/projects/esp-idf/en/latest/esp32p4/api-reference/peripherals/camera_driver.html) diff --git a/examples/peripherals/camera/mipi_isp_dsi/README.md b/examples/peripherals/camera/mipi_isp_dsi/README.md index 67cc416780..8d07b7252d 100644 --- a/examples/peripherals/camera/mipi_isp_dsi/README.md +++ b/examples/peripherals/camera/mipi_isp_dsi/README.md @@ -152,6 +152,4 @@ This image is also used as a reference, you can check output image after ISP aut ## Reference -- Link to the ESP-IDF feature's API reference, for example [ESP-IDF: Camera Controller Driver](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/camera_driver.html) -- [ESP-IDF Getting Started](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html#get-started) -- [Project Configuration](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/kconfig.html) (Kconfig Options) +- [ESP-IDF: Camera Controller Driver](https://docs.espressif.com/projects/esp-idf/en/latest/esp32p4/api-reference/peripherals/camera_driver.html) diff --git a/examples/peripherals/dma/async_crc/CMakeLists.txt b/examples/peripherals/dma/async_crc/CMakeLists.txt new file mode 100644 index 0000000000..f4edc1d81b --- /dev/null +++ b/examples/peripherals/dma/async_crc/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.22) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +idf_build_set_property(MINIMAL_BUILD ON) +project(async_crc) diff --git a/examples/peripherals/dma/async_crc/README.md b/examples/peripherals/dma/async_crc/README.md new file mode 100644 index 0000000000..7feaa98fdb --- /dev/null +++ b/examples/peripherals/dma/async_crc/README.md @@ -0,0 +1,69 @@ +| Supported Targets | ESP32-P4 | +| ----------------- | -------- | + +# Async CRC Console Example + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +## Overview + +This example demonstrates how to use the Async CRC driver (`esp_async_crc.h`) through an interactive console CLI. The Async CRC driver provides hardware-accelerated CRC calculation using the General DMA (GDMA) peripheral. + +The example provides a `crc` command that allows users to: +- Calculate CRC-8, CRC-16, and CRC-32 checksums +- Customize CRC parameters (polynomial, initial value, final XOR, bit reversal) +- Test various CRC algorithms interactively + +## Hardware Required + +Any board with a supported ESP target that mentioned in the above table can be used. + +## Build and Flash + +Run `idf.py -p PORT flash monitor` to build and flash the project. + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +### Check help + +```bash +crc> help +crc [--width=] [--poly=] [--init=] [--xor=] [--reverse-input=<0|1>] [--reverse-output=<0|1>] + Calculate CRC checksum using hardware async CRC driver + --width= CRC width (8, 16, or 32). Default: 8 + --poly= CRC polynomial in hex. Default: 0x07 + --init= Initial CRC value in hex. Default: 0x00 + --xor= Final XOR value in hex. Default: 0x00 + --reverse-input=<0|1> Reverse input bits (0 or 1). Default: 0 + --reverse-output=<0|1> Reverse output bits (0 or 1). Default: 0 + Input data string +``` + +### Calculate CRC-8 (default) + +```bash +crc> crc "test" +CRC result: 0xB9 +``` + +### Calculate CRC-16/CCITT + +```bash +crc> crc --width 16 --poly 0x1021 "test" +CRC result: 0x9B06 +``` + +### Calculate CRC-32 + +```bash +crc> crc --width 32 --poly 0x04C11DB7 --init 0xFFFFFFFF --xor 0xFFFFFFFF --reverse-input 1 --reverse-output 1 "test" +CRC result: 0xD87F7E0C +``` + +## Troubleshooting + +(For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you as soon as possible.) diff --git a/examples/peripherals/dma/async_crc/main/CMakeLists.txt b/examples/peripherals/dma/async_crc/main/CMakeLists.txt new file mode 100644 index 0000000000..56580aee13 --- /dev/null +++ b/examples/peripherals/dma/async_crc/main/CMakeLists.txt @@ -0,0 +1,4 @@ +idf_component_register(SRCS "async_crc_example_main.c" + "cmd_crc.c" + PRIV_REQUIRES console esp_driver_dma + INCLUDE_DIRS ".") diff --git a/examples/peripherals/dma/async_crc/main/async_crc_example_main.c b/examples/peripherals/dma/async_crc/main/async_crc_example_main.c new file mode 100644 index 0000000000..021c1b7fc8 --- /dev/null +++ b/examples/peripherals/dma/async_crc/main/async_crc_example_main.c @@ -0,0 +1,34 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "esp_console.h" +#include "cmd_crc.h" + +void app_main(void) +{ + esp_console_repl_t *repl = NULL; + esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT(); + repl_config.prompt = "crc>"; + + esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &repl)); + + // initialize the CRC engine and register the CRC command + register_crc(); + + printf("\n ==============================================================\n"); + printf(" Steps to Use CRC \n"); + printf(" \n"); + printf(" 1. Try 'help', check all supported commands \n"); + printf(" 2. Try 'crc \"test\"' to calculate the default 8-bit CRC \n"); + printf(" 3. Or customize: 'crc --width=16 --poly=0x1021 \"test\"' \n"); + printf(" \n"); + printf(" ==============================================================\n\n"); + + ESP_ERROR_CHECK(esp_console_start_repl(repl)); +} diff --git a/examples/peripherals/dma/async_crc/main/cmd_crc.c b/examples/peripherals/dma/async_crc/main/cmd_crc.c new file mode 100644 index 0000000000..526c231afa --- /dev/null +++ b/examples/peripherals/dma/async_crc/main/cmd_crc.c @@ -0,0 +1,140 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include "argtable3/argtable3.h" +#include "esp_console.h" +#include "esp_log.h" +#include "esp_async_crc.h" +#include "cmd_crc.h" + +static const char *TAG = "crc"; + +static async_crc_handle_t s_crc_handle = NULL; + +static struct { + struct arg_int *width; /*!< CRC width (8, 16, or 32) */ + struct arg_str *poly; /*!< CRC polynomial (hex string) */ + struct arg_str *init; /*!< Initial CRC value (hex string) */ + struct arg_str *xor; /*!< Final XOR value (hex string) */ + struct arg_int *reverse_input; /*!< Reverse input bits */ + struct arg_int *reverse_output; /*!< Reverse output bits */ + struct arg_str *data; /*!< Input data string */ + struct arg_end *end; /*!< argtable end marker */ +} crc_args; + +static uint32_t parse_hex_value(const char *str) +{ + uint32_t value = 0; + if (str && str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) { + value = (uint32_t)strtoul(str, NULL, 16); + } else { + value = (uint32_t)strtoul(str, NULL, 0); + } + return value; +} + +static int do_crc_cmd(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **)&crc_args); + if (nerrors != 0) { + arg_print_errors(stderr, crc_args.end, argv[0]); + return ESP_ERR_INVALID_ARG; + } + + if (!s_crc_handle) { + ESP_LOGE(TAG, "CRC driver not initialized"); + return ESP_ERR_INVALID_STATE; + } + + // By default, calculate an 8-bit CRC with polynomial 0x07, initial value 0x00, and final XOR value 0x00, without bit reversal + async_crc_params_t params = { + .width = 8, + .polynomial = 0x07, + .init_value = 0x00, + .final_xor_value = 0x00, + .reverse_input = false, + .reverse_output = false, + }; + + if (crc_args.width->count) { + int width = crc_args.width->ival[0]; + if (width != 8 && width != 16 && width != 32) { + ESP_LOGE(TAG, "Invalid width %d. Must be 8, 16, or 32", width); + return ESP_ERR_INVALID_ARG; + } + params.width = width; + } + + if (crc_args.poly->count) { + params.polynomial = parse_hex_value(crc_args.poly->sval[0]); + } + + if (crc_args.init->count) { + params.init_value = parse_hex_value(crc_args.init->sval[0]); + } + + if (crc_args.xor->count) { + params.final_xor_value = parse_hex_value(crc_args.xor->sval[0]); + } + + if (crc_args.reverse_input->count) { + params.reverse_input = crc_args.reverse_input->ival[0] ? true : false; + } + + if (crc_args.reverse_output->count) { + params.reverse_output = crc_args.reverse_output->ival[0] ? true : false; + } + + const char *data_str = crc_args.data->sval[0]; + size_t data_len = strlen(data_str); + + uint32_t result = 0; + esp_err_t err = esp_crc_calc_blocking(s_crc_handle, data_str, data_len, ¶ms, -1, &result); + if (err != ESP_OK) { + ESP_LOGE(TAG, "CRC calculation failed: %s", esp_err_to_name(err)); + return err; + } + + if (params.width == 8) { + printf("CRC result: 0x%02" PRIX32 "\n", result); + } else if (params.width == 16) { + printf("CRC result: 0x%04" PRIX32 "\n", result); + } else { + printf("CRC result: 0x%08" PRIX32 "\n", result); + } + return ESP_OK; +} + +void register_crc(void) +{ + async_crc_config_t config = { + .backlog = 1, // backlog of 1 is sufficient since we wait for each calculation to finish before starting the next one + .dma_burst_size = 32, + }; + ESP_ERROR_CHECK(esp_async_crc_install_gdma_ahb(&config, &s_crc_handle)); + + crc_args.width = arg_int0(NULL, "width", "", "CRC width (8, 16, or 32). Default: 8"); + crc_args.poly = arg_str0(NULL, "poly", "", "CRC polynomial in hex. Default: 0x07"); + crc_args.init = arg_str0(NULL, "init", "", "Initial CRC value in hex. Default: 0x00"); + crc_args.xor = arg_str0(NULL, "xor", "", "Final XOR value in hex. Default: 0x00"); + crc_args.reverse_input = arg_int0(NULL, "reverse-input", "<0|1>", "Reverse input bits (0 or 1). Default: 0"); + crc_args.reverse_output = arg_int0(NULL, "reverse-output", "<0|1>", "Reverse output bits (0 or 1). Default: 0"); + crc_args.data = arg_str1(NULL, NULL, "", "Input data string"); + crc_args.end = arg_end(7); + + const esp_console_cmd_t crc_cmd = { + .command = "crc", + .help = "Calculate CRC checksum using hardware async CRC driver", + .hint = NULL, + .func = &do_crc_cmd, + .argtable = &crc_args + }; + ESP_ERROR_CHECK(esp_console_cmd_register(&crc_cmd)); +} diff --git a/examples/peripherals/dma/async_crc/main/cmd_crc.h b/examples/peripherals/dma/async_crc/main/cmd_crc.h new file mode 100644 index 0000000000..f2c92f5194 --- /dev/null +++ b/examples/peripherals/dma/async_crc/main/cmd_crc.h @@ -0,0 +1,17 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +void register_crc(void); + +#ifdef __cplusplus +} +#endif diff --git a/examples/peripherals/dma/async_crc/pytest_async_crc.py b/examples/peripherals/dma/async_crc/pytest_async_crc.py new file mode 100644 index 0000000000..643b54acaa --- /dev/null +++ b/examples/peripherals/dma/async_crc/pytest_async_crc.py @@ -0,0 +1,75 @@ +# SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Unlicense OR CC0-1.0 + +import pytest +from crc import Calculator +from crc import Configuration +from pytest_embedded_idf import IdfDut +from pytest_embedded_idf.utils import idf_parametrize +from pytest_embedded_idf.utils import soc_filtered_targets + +EXPECT_TIMEOUT = 20 + + +def calculate_crc8(data: str) -> int: + config = Configuration(8, 0x07, init_value=0x00, final_xor_value=0x00, reverse_input=False, reverse_output=False) + calculator = Calculator(config) + return int(calculator.checksum(data.encode('utf-8'))) + + +def calculate_crc16_ccitt(data: str) -> int: + config = Configuration( + 16, 0x1021, init_value=0x0000, final_xor_value=0x0000, reverse_input=False, reverse_output=False + ) + calculator = Calculator(config) + return int(calculator.checksum(data.encode('utf-8'))) + + +def calculate_crc32(data: str) -> int: + config = Configuration( + 32, 0x04C11DB7, init_value=0xFFFFFFFF, final_xor_value=0xFFFFFFFF, reverse_input=True, reverse_output=True + ) + calculator = Calculator(config) + return int(calculator.checksum(data.encode('utf-8'))) + + +def calculate_crc32_no_reflect(data: str) -> int: + config = Configuration( + 32, 0x04C11DB7, init_value=0x00000000, final_xor_value=0x0000, reverse_input=False, reverse_output=False + ) + calculator = Calculator(config) + return int(calculator.checksum(data.encode('utf-8'))) + + +@pytest.mark.generic +@idf_parametrize('target', soc_filtered_targets('SOC_GDMA_SUPPORT_CRC == 1'), indirect=['target']) +def test_async_crc_example(dut: IdfDut) -> None: + dut.expect_exact('crc>', timeout=EXPECT_TIMEOUT) + + # Test CRC-8 (default) + dut.write('crc "test"') + expected_crc8 = calculate_crc8('test') + dut.expect(f'CRC result: 0x{expected_crc8:02X}', timeout=EXPECT_TIMEOUT) + + # Test CRC-8 with explicit polynomial + dut.write('crc --width 8 --poly 0x07 "test"') + expected_crc8 = calculate_crc8('test') + dut.expect(f'CRC result: 0x{expected_crc8:02X}', timeout=EXPECT_TIMEOUT) + + # Test CRC-16/CCITT + dut.write('crc --width 16 --poly 0x1021 "test"') + expected_crc16 = calculate_crc16_ccitt('test') + dut.expect(f'CRC result: 0x{expected_crc16:04X}', timeout=EXPECT_TIMEOUT) + + # Test CRC-32 without reflection + dut.write('crc --width 32 --poly 0x04C11DB7 --init 0 --xor 0 --reverse-input 0 --reverse-output 0 "test"') + expected_crc32 = calculate_crc32_no_reflect('test') + dut.expect(f'CRC result: 0x{expected_crc32:08X}', timeout=EXPECT_TIMEOUT) + + # Test CRC-32 with reflection (standard CRC-32) + dut.write( + 'crc --width 32 --poly 0x04C11DB7 --init 0xFFFFFFFF --xor 0xFFFFFFFF ' + '--reverse-input 1 --reverse-output 1 "test"' + ) + expected_crc32 = calculate_crc32('test') + dut.expect(f'CRC result: 0x{expected_crc32:08X}', timeout=EXPECT_TIMEOUT) diff --git a/examples/peripherals/isp/multi_pipelines/README.md b/examples/peripherals/isp/multi_pipelines/README.md index 4e11e4159d..f5ab58329b 100644 --- a/examples/peripherals/isp/multi_pipelines/README.md +++ b/examples/peripherals/isp/multi_pipelines/README.md @@ -203,7 +203,5 @@ This image is also used as a reference, you can check output image without ISP a ## Reference -- Link to the ESP-IDF camera controller driver API reference, [ESP-IDF: Camera Controller Driver](https://docs.espressif.com/projects/esp-idf/en/latest/esp32p4/api-reference/peripherals/camera_driver.html) -- Link to the ESP-IDF ISP driver API reference, [ESP-IDF: Image Signal Processor](https://docs.espressif.com/projects/esp-idf/en/latest/esp32p4/api-reference/peripherals/isp.html) -- [ESP-IDF Getting Started](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html#get-started) -- [Project Configuration](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/kconfig.html) (Kconfig Options) +- [ESP-IDF: Camera Controller Driver](https://docs.espressif.com/projects/esp-idf/en/latest/esp32p4/api-reference/peripherals/camera_driver.html) +- [ESP-IDF: Image Signal Processor](https://docs.espressif.com/projects/esp-idf/en/latest/esp32p4/api-reference/peripherals/isp.html) diff --git a/examples/peripherals/ppa/ppa_dsi/README.md b/examples/peripherals/ppa/ppa_dsi/README.md index 45cb9bac53..c02f404be7 100644 --- a/examples/peripherals/ppa/ppa_dsi/README.md +++ b/examples/peripherals/ppa/ppa_dsi/README.md @@ -123,6 +123,4 @@ I (10085) main_task: Returned from app_main() ## Reference -- Link to the ESP-IDF feature's API reference, for example [ESP-IDF: Pixel-Processing Accelerator](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/ppa.html) -- [ESP-IDF Getting Started](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html#get-started) -- [Project Configuration](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/kconfig.html) (Kconfig Options) +- [ESP-IDF: Pixel-Processing Accelerator](https://docs.espressif.com/projects/esp-idf/en/latest/esp32p4/api-reference/peripherals/ppa.html) diff --git a/tools/requirements/requirements.test-specific.txt b/tools/requirements/requirements.test-specific.txt index 5f8745716a..0e5c2efdcf 100644 --- a/tools/requirements/requirements.test-specific.txt +++ b/tools/requirements/requirements.test-specific.txt @@ -18,3 +18,6 @@ pyecharts # for twai tests, communicate with socket can device (e.g. Canable) python-can + +# Calculate CRC checksums +crc