Skip to content

Commit c47b72d

Browse files
committed
feat(esp_driver_cam): DVP driver supports only initializing the clock and XCLK pin to generate a clock for the external device
1 parent 5590a74 commit c47b72d

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 {
@@ -358,7 +360,7 @@ esp_err_t esp_cam_ctlr_dvp_init(int ctlr_id, cam_clock_source_t clk_src, const e
358360
}
359361

360362
/**
361-
* @brief ESP CAM DVP output hardware clock
363+
* @brief ESP CAM DVP output hardware clock, the function "esp_cam_ctlr_dvp_init" should be called first
362364
*
363365
* @param ctlr_id CAM DVP controller ID
364366
* @param clk_src CAM DVP clock source
@@ -381,15 +383,54 @@ esp_err_t esp_cam_ctlr_dvp_output_clock(int ctlr_id, cam_clock_source_t clk_src,
381383

382384
if ((src_clk_hz % xclk_freq) == 0) {
383385
DVP_CAM_CLK_ATOMIC() {
386+
// The camera sensors require precision without frequency and duty cycle jitter,
387+
// so the fractional divisor can't be used.
384388
cam_ll_set_group_clock_coeff(ctlr_id, src_clk_hz / xclk_freq, 0, 0);
385389
};
386390

387391
ret = ESP_OK;
392+
} else {
393+
ESP_LOGE(TAG, "calculated frequency divider is not integer so clock isn't changed");
388394
}
389395

390396
return ret;
391397
}
392398

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

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)