mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-03 20:54:32 +02:00
Merge branch 'feature/lcd_cam_dvp_driver_only_gen_clock' into 'master'
feat(esp_driver_cam): DVP driver supports only initializing the clock and XCLK pin to generate a clock for the external device Closes IDF-13385 See merge request espressif/esp-idf!39837
This commit is contained in:
@@ -26,7 +26,7 @@ extern "C" {
|
|||||||
esp_err_t esp_cam_ctlr_dvp_init(int ctlr_id, cam_clock_source_t clk_src, const esp_cam_ctlr_dvp_pin_config_t *pin);
|
esp_err_t esp_cam_ctlr_dvp_init(int ctlr_id, cam_clock_source_t clk_src, const esp_cam_ctlr_dvp_pin_config_t *pin);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief ESP CAM DVP output hardware clock
|
* @brief ESP CAM DVP output hardware clock, the function "esp_cam_ctlr_dvp_init" should be called first
|
||||||
*
|
*
|
||||||
* @param ctlr_id CAM DVP controller ID
|
* @param ctlr_id CAM DVP controller ID
|
||||||
* @param clk_src CAM DVP clock source
|
* @param clk_src CAM DVP clock source
|
||||||
@@ -38,6 +38,24 @@ esp_err_t esp_cam_ctlr_dvp_init(int ctlr_id, cam_clock_source_t clk_src, const e
|
|||||||
*/
|
*/
|
||||||
esp_err_t esp_cam_ctlr_dvp_output_clock(int ctlr_id, cam_clock_source_t clk_src, uint32_t xclk_freq);
|
esp_err_t esp_cam_ctlr_dvp_output_clock(int ctlr_id, cam_clock_source_t clk_src, uint32_t xclk_freq);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize ESP CAM DVP clock pin (other DVP GPIO pins excluded the clock pins will not be initialized)
|
||||||
|
* and hardware clock, then output clock signal with given frequency
|
||||||
|
*
|
||||||
|
* @note The function is implemented based on "esp_cam_ctlr_dvp_init" and "esp_cam_ctlr_dvp_output_clock",
|
||||||
|
* so calling "esp_cam_ctlr_dvp_init" and "esp_cam_ctlr_dvp_output_clock" is not required
|
||||||
|
*
|
||||||
|
* @param ctlr_id DVP controller ID
|
||||||
|
* @param pin DVP clock pin
|
||||||
|
* @param clk_src DVP clock source
|
||||||
|
* @param xclk_freq DVP clock frequency
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK on success
|
||||||
|
* - Others if failed
|
||||||
|
*/
|
||||||
|
esp_err_t esp_cam_ctlr_dvp_start_clock(int ctlr_id, gpio_num_t pin, cam_clock_source_t clk_src, uint32_t xclk_freq);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief ESP CAM DVP de-initialzie.
|
* @brief ESP CAM DVP de-initialzie.
|
||||||
*
|
*
|
||||||
|
@@ -47,12 +47,14 @@
|
|||||||
|
|
||||||
#define DVP_CAM_CONFIG_INPUT_PIN(pin, sig, inv) \
|
#define DVP_CAM_CONFIG_INPUT_PIN(pin, sig, inv) \
|
||||||
{ \
|
{ \
|
||||||
|
if (pin != GPIO_NUM_NC) { \
|
||||||
ret = esp_cam_ctlr_dvp_config_input_gpio(pin, sig, inv); \
|
ret = esp_cam_ctlr_dvp_config_input_gpio(pin, sig, inv); \
|
||||||
if (ret != ESP_OK) { \
|
if (ret != ESP_OK) { \
|
||||||
ESP_LOGE(TAG, "failed to configure pin=%d sig=%d", \
|
ESP_LOGE(TAG, "failed to configure pin=%d sig=%d", \
|
||||||
pin, sig); \
|
pin, sig); \
|
||||||
return ret; \
|
return ret; \
|
||||||
} \
|
} \
|
||||||
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct dvp_platform {
|
typedef struct dvp_platform {
|
||||||
@@ -360,7 +362,7 @@ esp_err_t esp_cam_ctlr_dvp_init(int ctlr_id, cam_clock_source_t clk_src, const e
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief ESP CAM DVP output hardware clock
|
* @brief ESP CAM DVP output hardware clock, the function "esp_cam_ctlr_dvp_init" should be called first
|
||||||
*
|
*
|
||||||
* @param ctlr_id CAM DVP controller ID
|
* @param ctlr_id CAM DVP controller ID
|
||||||
* @param clk_src CAM DVP clock source
|
* @param clk_src CAM DVP clock source
|
||||||
@@ -383,15 +385,54 @@ esp_err_t esp_cam_ctlr_dvp_output_clock(int ctlr_id, cam_clock_source_t clk_src,
|
|||||||
|
|
||||||
if ((src_clk_hz % xclk_freq) == 0) {
|
if ((src_clk_hz % xclk_freq) == 0) {
|
||||||
DVP_CAM_CLK_ATOMIC() {
|
DVP_CAM_CLK_ATOMIC() {
|
||||||
|
// The camera sensors require precision without frequency and duty cycle jitter,
|
||||||
|
// so the fractional divisor can't be used.
|
||||||
cam_ll_set_group_clock_coeff(ctlr_id, src_clk_hz / xclk_freq, 0, 0);
|
cam_ll_set_group_clock_coeff(ctlr_id, src_clk_hz / xclk_freq, 0, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
ret = ESP_OK;
|
ret = ESP_OK;
|
||||||
|
} else {
|
||||||
|
ESP_LOGE(TAG, "calculated frequency divider is not integer so clock isn't changed");
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize ESP CAM DVP clock pin (other DVP GPIO pins excluded the clock pins will not be initialized)
|
||||||
|
* and hardware clock, then output clock signal with given frequency
|
||||||
|
*
|
||||||
|
* @note The function is implemented based on "esp_cam_ctlr_dvp_init" and "esp_cam_ctlr_dvp_output_clock",
|
||||||
|
* so calling "esp_cam_ctlr_dvp_init" and "esp_cam_ctlr_dvp_output_clock" is not required
|
||||||
|
*
|
||||||
|
* @param ctlr_id DVP controller ID
|
||||||
|
* @param pin DVP clock pin
|
||||||
|
* @param clk_src DVP clock source
|
||||||
|
* @param xclk_freq DVP clock frequency
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK on success
|
||||||
|
* - Others if failed
|
||||||
|
*/
|
||||||
|
esp_err_t esp_cam_ctlr_dvp_start_clock(int ctlr_id, gpio_num_t pin, cam_clock_source_t clk_src, uint32_t xclk_freq)
|
||||||
|
{
|
||||||
|
esp_cam_ctlr_dvp_pin_config_t pin_config = {0};
|
||||||
|
|
||||||
|
pin_config.data_width = CAM_CTLR_DATA_WIDTH_8;
|
||||||
|
pin_config.vsync_io = GPIO_NUM_NC;
|
||||||
|
pin_config.de_io = GPIO_NUM_NC;
|
||||||
|
pin_config.pclk_io = GPIO_NUM_NC;
|
||||||
|
for (int i = 0; i < CAM_DVP_DATA_SIG_NUM; i++) {
|
||||||
|
pin_config.data_io[i] = GPIO_NUM_NC;
|
||||||
|
}
|
||||||
|
pin_config.xclk_io = pin;
|
||||||
|
|
||||||
|
ESP_RETURN_ON_ERROR(esp_cam_ctlr_dvp_init(ctlr_id, clk_src, &pin_config), TAG, "failed to initialize DVP controller");
|
||||||
|
ESP_RETURN_ON_ERROR(esp_cam_ctlr_dvp_output_clock(ctlr_id, clk_src, xclk_freq), TAG, "failed to output clock");
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief ESP CAM DVP de-initialzie.
|
* @brief ESP CAM DVP de-initialzie.
|
||||||
*
|
*
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#include "unity.h"
|
#include "unity.h"
|
||||||
#include "esp_cam_ctlr_dvp.h"
|
#include "esp_cam_ctlr_dvp.h"
|
||||||
|
#include "esp_private/esp_cam_dvp.h"
|
||||||
#include "esp_cam_ctlr.h"
|
#include "esp_cam_ctlr.h"
|
||||||
|
|
||||||
TEST_CASE("TEST DVP driver allocation", "[DVP]")
|
TEST_CASE("TEST DVP driver allocation", "[DVP]")
|
||||||
@@ -171,3 +172,14 @@ TEST_CASE("TEST DVP driver intern/extern generate xclk", "[DVP]")
|
|||||||
TEST_ESP_OK(esp_cam_new_dvp_ctlr(&dvp_config, &handle));
|
TEST_ESP_OK(esp_cam_new_dvp_ctlr(&dvp_config, &handle));
|
||||||
TEST_ESP_OK(esp_cam_ctlr_del(handle));
|
TEST_ESP_OK(esp_cam_ctlr_del(handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("TEST DVP driver only output xclk signal", "[DVP]")
|
||||||
|
{
|
||||||
|
TEST_ESP_OK(esp_cam_ctlr_dvp_start_clock(0, 20, CAM_CLK_SRC_DEFAULT, 20000000));
|
||||||
|
TEST_ESP_OK(esp_cam_ctlr_dvp_deinit(0));
|
||||||
|
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32S3
|
||||||
|
TEST_ESP_OK(esp_cam_ctlr_dvp_start_clock(0, 20, CAM_CLK_SRC_PLL240M, 24000000));
|
||||||
|
TEST_ESP_OK(esp_cam_ctlr_dvp_deinit(0));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user