Skip to content

Commit 20f1700

Browse files
committed
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
2 parents 8cc7116 + c47b72d commit 20f1700

File tree

3 files changed

+81
-10
lines changed

3 files changed

+81
-10
lines changed

components/esp_driver_cam/dvp/include/esp_private/esp_cam_dvp.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ extern "C" {
2626
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);
2727

2828
/**
29-
* @brief ESP CAM DVP output hardware clock
29+
* @brief ESP CAM DVP output hardware clock, the function "esp_cam_ctlr_dvp_init" should be called first
3030
*
3131
* @param ctlr_id CAM DVP controller ID
3232
* @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
3838
*/
3939
esp_err_t esp_cam_ctlr_dvp_output_clock(int ctlr_id, cam_clock_source_t clk_src, uint32_t xclk_freq);
4040

41+
/**
42+
* @brief Initialize ESP CAM DVP clock pin (other DVP GPIO pins excluded the clock pins will not be initialized)
43+
* and hardware clock, then output clock signal with given frequency
44+
*
45+
* @note The function is implemented based on "esp_cam_ctlr_dvp_init" and "esp_cam_ctlr_dvp_output_clock",
46+
* so calling "esp_cam_ctlr_dvp_init" and "esp_cam_ctlr_dvp_output_clock" is not required
47+
*
48+
* @param ctlr_id DVP controller ID
49+
* @param pin DVP clock pin
50+
* @param clk_src DVP clock source
51+
* @param xclk_freq DVP clock frequency
52+
*
53+
* @return
54+
* - ESP_OK on success
55+
* - Others if failed
56+
*/
57+
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);
58+
4159
/**
4260
* @brief ESP CAM DVP de-initialzie.
4361
*

components/esp_driver_cam/dvp/src/esp_cam_ctlr_dvp_cam.c

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,16 @@
4545

4646
#define ALIGN_UP_BY(num, align) ((align) == 0 ? (num) : (((num) + ((align) - 1)) & ~((align) - 1)))
4747

48-
#define DVP_CAM_CONFIG_INPUT_PIN(pin, sig, inv) \
49-
{ \
50-
ret = esp_cam_ctlr_dvp_config_input_gpio(pin, sig, inv); \
51-
if (ret != ESP_OK) { \
52-
ESP_LOGE(TAG, "failed to configure pin=%d sig=%d", \
53-
pin, sig); \
54-
return ret; \
55-
} \
48+
#define DVP_CAM_CONFIG_INPUT_PIN(pin, sig, inv) \
49+
{ \
50+
if (pin != GPIO_NUM_NC) { \
51+
ret = esp_cam_ctlr_dvp_config_input_gpio(pin, sig, inv); \
52+
if (ret != ESP_OK) { \
53+
ESP_LOGE(TAG, "failed to configure pin=%d sig=%d", \
54+
pin, sig); \
55+
return ret; \
56+
} \
57+
} \
5658
}
5759

5860
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
360362
}
361363

362364
/**
363-
* @brief ESP CAM DVP output hardware clock
365+
* @brief ESP CAM DVP output hardware clock, the function "esp_cam_ctlr_dvp_init" should be called first
364366
*
365367
* @param ctlr_id CAM DVP controller ID
366368
* @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,
383385

384386
if ((src_clk_hz % xclk_freq) == 0) {
385387
DVP_CAM_CLK_ATOMIC() {
388+
// The camera sensors require precision without frequency and duty cycle jitter,
389+
// so the fractional divisor can't be used.
386390
cam_ll_set_group_clock_coeff(ctlr_id, src_clk_hz / xclk_freq, 0, 0);
387391
};
388392

389393
ret = ESP_OK;
394+
} else {
395+
ESP_LOGE(TAG, "calculated frequency divider is not integer so clock isn't changed");
390396
}
391397

392398
return ret;
393399
}
394400

401+
/**
402+
* @brief Initialize ESP CAM DVP clock pin (other DVP GPIO pins excluded the clock pins will not be initialized)
403+
* and hardware clock, then output clock signal with given frequency
404+
*
405+
* @note The function is implemented based on "esp_cam_ctlr_dvp_init" and "esp_cam_ctlr_dvp_output_clock",
406+
* so calling "esp_cam_ctlr_dvp_init" and "esp_cam_ctlr_dvp_output_clock" is not required
407+
*
408+
* @param ctlr_id DVP controller ID
409+
* @param pin DVP clock pin
410+
* @param clk_src DVP clock source
411+
* @param xclk_freq DVP clock frequency
412+
*
413+
* @return
414+
* - ESP_OK on success
415+
* - Others if failed
416+
*/
417+
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)
418+
{
419+
esp_cam_ctlr_dvp_pin_config_t pin_config = {0};
420+
421+
pin_config.data_width = CAM_CTLR_DATA_WIDTH_8;
422+
pin_config.vsync_io = GPIO_NUM_NC;
423+
pin_config.de_io = GPIO_NUM_NC;
424+
pin_config.pclk_io = GPIO_NUM_NC;
425+
for (int i = 0; i < CAM_DVP_DATA_SIG_NUM; i++) {
426+
pin_config.data_io[i] = GPIO_NUM_NC;
427+
}
428+
pin_config.xclk_io = pin;
429+
430+
ESP_RETURN_ON_ERROR(esp_cam_ctlr_dvp_init(ctlr_id, clk_src, &pin_config), TAG, "failed to initialize DVP controller");
431+
ESP_RETURN_ON_ERROR(esp_cam_ctlr_dvp_output_clock(ctlr_id, clk_src, xclk_freq), TAG, "failed to output clock");
432+
433+
return ESP_OK;
434+
}
435+
395436
/**
396437
* @brief ESP CAM DVP de-initialzie.
397438
*

components/esp_driver_cam/test_apps/dvp/main/test_dvp_driver.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "sdkconfig.h"
88
#include "unity.h"
99
#include "esp_cam_ctlr_dvp.h"
10+
#include "esp_private/esp_cam_dvp.h"
1011
#include "esp_cam_ctlr.h"
1112

1213
TEST_CASE("TEST DVP driver allocation", "[DVP]")
@@ -171,3 +172,14 @@ TEST_CASE("TEST DVP driver intern/extern generate xclk", "[DVP]")
171172
TEST_ESP_OK(esp_cam_new_dvp_ctlr(&dvp_config, &handle));
172173
TEST_ESP_OK(esp_cam_ctlr_del(handle));
173174
}
175+
176+
TEST_CASE("TEST DVP driver only output xclk signal", "[DVP]")
177+
{
178+
TEST_ESP_OK(esp_cam_ctlr_dvp_start_clock(0, 20, CAM_CLK_SRC_DEFAULT, 20000000));
179+
TEST_ESP_OK(esp_cam_ctlr_dvp_deinit(0));
180+
181+
#if CONFIG_IDF_TARGET_ESP32S3
182+
TEST_ESP_OK(esp_cam_ctlr_dvp_start_clock(0, 20, CAM_CLK_SRC_PLL240M, 24000000));
183+
TEST_ESP_OK(esp_cam_ctlr_dvp_deinit(0));
184+
#endif
185+
}

0 commit comments

Comments
 (0)