mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
refactor(isp): read DMA input directly from flash
Avoid the PSRAM copy for unencrypted flash
This commit is contained in:
@@ -17,14 +17,15 @@ extern "C" {
|
||||
/**
|
||||
* @brief Process one ISP DMA frame: feed the input buffer through the ISP and wait for completion
|
||||
*
|
||||
* @note Input buffer content should be ready before calling this function. If the buffers are in
|
||||
* cacheable memory, the caller should synchronize them around DMA access. Buffer sizes are
|
||||
* derived from the ISP processor resolution and pixel formats. Both buffers must be 8-byte
|
||||
* aligned. This function blocks until both input and output DMA channels finish.
|
||||
* @note The driver synchronizes cacheable buffers before and after DMA access. Input buffers use
|
||||
* an unaligned cache write-back, while cacheable output buffers and their derived frame
|
||||
* sizes must be aligned to the cache line size.
|
||||
* @note This function blocks until both input and output DMA channels finish. On timeout,
|
||||
* the output buffer may still be owned by DMA and must not be accessed.
|
||||
*
|
||||
* @param[in] proc Processor handle
|
||||
* @param[in] output_buffer Destination buffer for ISP output (8-byte aligned)
|
||||
* @param[in] input_buffer Source input buffer for RAW frame data (8-byte aligned)
|
||||
* @param[in] output_buffer Destination buffer for ISP output
|
||||
* @param[in] input_buffer Source input buffer for RAW frame data
|
||||
* @param[in] timeout_ms Timeout in milliseconds for waiting transfer completion
|
||||
*
|
||||
* @return
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_cache.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
@@ -56,6 +57,17 @@ static dw_gdma_burst_items_t s_isp_dma_burst_len_to_items(uint32_t burst_len)
|
||||
}
|
||||
}
|
||||
|
||||
static esp_err_t s_isp_dma_sync_cacheable_buffer(void *buffer, size_t size, int flags, const char *buffer_name)
|
||||
{
|
||||
size_t cache_line_size = esp_cache_get_line_size_by_addr(buffer);
|
||||
if (cache_line_size == 0) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
ESP_RETURN_ON_ERROR(esp_cache_msync(buffer, size, flags), TAG, "sync %s buffer cache failed", buffer_name);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void s_isp_dma_frame_ctx_destroy(struct esp_isp_dma_frame_ctx_t *ctx)
|
||||
{
|
||||
if (!ctx) {
|
||||
@@ -243,6 +255,21 @@ esp_err_t esp_isp_dma_process_frame(isp_proc_handle_t proc, void *output_buffer,
|
||||
ESP_RETURN_ON_FALSE((((uintptr_t)input_buffer) % 8) == 0, ESP_ERR_INVALID_ARG, TAG, "input buffer not 8-byte aligned");
|
||||
|
||||
esp_isp_dma_frame_ctx_t *ctx = proc->dma_frame_ctx;
|
||||
size_t input_frame_size = ctx->input_frame_size_64bit * sizeof(uint64_t);
|
||||
size_t output_frame_size = ctx->output_frame_size_64bit * sizeof(uint64_t);
|
||||
|
||||
ESP_RETURN_ON_ERROR(s_isp_dma_sync_cacheable_buffer((void *)input_buffer, input_frame_size,
|
||||
ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED,
|
||||
"input"),
|
||||
TAG, "sync input buffer cache failed");
|
||||
/*
|
||||
* Discard dirty CPU cache lines before DMA writes the frame. Otherwise a
|
||||
* later cache write-back could overwrite data produced by the ISP.
|
||||
*/
|
||||
ESP_RETURN_ON_ERROR(s_isp_dma_sync_cacheable_buffer(output_buffer, output_frame_size,
|
||||
ESP_CACHE_MSYNC_FLAG_DIR_M2C, "output"),
|
||||
TAG, "sync output buffer cache failed");
|
||||
|
||||
ctx->dma_out_trans.dst.addr = (uint32_t)output_buffer;
|
||||
ctx->dma_in_trans.src.addr = (uint32_t)input_buffer;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user