接前一篇文章:ESP32-S3模组上跑通esp32-camera(14)
本文内容参考:
esp32-camera入门(基于ESP-IDF)_esp32 camera-CSDN博客
ESP32_CAM CameraWebServer例程源码解析笔记(一)_void startcameraserver();-CSDN博客
特此致谢!
一、OV5640初始化
2. 相机初始化及图像传感器配置
上一回讲解到cam_init函数中的ll_cam_set_pin函数,讲解了其整体功能,本回对其进行详细解析。为了便于理解和回顾,再次贴出cam_init和ll_cam_set_pin函数代码。cam_init函数在components\esp32-camera\driver\cam_hal.c中,如下:
esp_err_t cam_init(const camera_config_t *config)
{
CAM_CHECK(NULL != config, "config pointer is invalid", ESP_ERR_INVALID_ARG);
esp_err_t ret = ESP_OK;
cam_obj = (cam_obj_t *)heap_caps_calloc(1, sizeof(cam_obj_t), MALLOC_CAP_DMA);
CAM_CHECK(NULL != cam_obj, "lcd_cam object malloc error", ESP_ERR_NO_MEM);
cam_obj->swap_data = 0;
cam_obj->vsync_pin = config->pin_vsync;
cam_obj->vsync_invert = true;
ll_cam_set_pin(cam_obj, config);
ret = ll_cam_config(cam_obj, config);
CAM_CHECK_GOTO(ret == ESP_OK, "ll_cam initialize failed", err);
#if CAMERA_DBG_PIN_ENABLE
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[DBG_PIN_NUM], PIN_FUNC_GPIO);
gpio_set_direction(DBG_PIN_NUM, GPIO_MODE_OUTPUT);
gpio_set_pull_mode(DBG_PIN_NUM, GPIO_FLOATING);
#endif
ESP_LOGI(TAG, "cam init ok");
return ESP_OK;
err:
free(cam_obj);
cam_obj = NULL;
return ESP_FAIL;
}
ll_cam_set_pin函数在components\esp32-camera\target\esp32s3\ll_cam.c中,代码如下:
esp_err_t ll_cam_set_pin(cam_obj_t *cam, const camera_config_t *config)
{
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[config->pin_pclk], PIN_FUNC_GPIO);
gpio_set_direction(config->pin_pclk, GPIO_MODE_INPUT);
gpio_set_pull_mode(config->pin_pclk, GPIO_FLOATING);
gpio_matrix_in(config->pin_pclk, CAM_PCLK_IDX, false);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[config->pin_vsync], PIN_FUNC_GPIO);
gpio_set_direction(config->pin_vsync, GPIO_MODE_INPUT);
gpio_set_pull_mode(config->pin_vsync, GPIO_FLOATING);
gpio_matrix_in(config->pin_vsync, CAM_V_SYNC_IDX, cam->vsync_invert);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[config->pin_href], PIN_FUNC_GPIO);
gpio_set_direction(config->pin_href, GPIO_MODE_INPUT);
gpio_set_pull_mode(config->pin_href, GPIO_FLOATING);
gpio_matrix_in(config->pin_href, CAM_H_ENABLE_IDX, false);
int data_pins[8] = {
config->pin_d0, config->pin_d1, config->pin_d2, config->pin_d3, config->pin_d4, config->pin_d5, config->pin_d6, config->pin_d7,
};
for (int i = 0; i < 8; i++) {
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[data_pins[i]], PIN_FUNC_GPIO);
gpio_set_direction(data_pins[i], GPIO_MODE_INPUT);
gpio_set_pull_mode(data_pins[i], GPIO_FLOATING);
gpio_matrix_in(data_pins[i], CAM_DATA_IN0_IDX + i, false);
}
if (config->pin_xclk >= 0) {
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[config->pin_xclk], PIN_FUNC_GPIO);
gpio_set_direction(config->pin_xclk, GPIO_MODE_OUTPUT);
gpio_set_pull_mode(config->pin_xclk, GPIO_FLOATING);
gpio_matrix_out(config->pin_xclk, CAM_CLK_IDX, false, false);
}
return ESP_OK;
}
上一回讲了,ll_cam_set_pin函数的整体功能是:依次对于pin_pclk、pin_vsync、pin_href、pin_d0~d7、pin_xclk(如果使能)所对应的GPIO引脚进行设置。本回一段一段来看具体代码。
1)pin_pclk
代码片段如下:
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[config->pin_pclk], PIN_FUNC_GPIO);
gpio_set_direction(config->pin_pclk, GPIO_MODE_INPUT);
gpio_set_pull_mode(config->pin_pclk, GPIO_FLOATING);
gpio_matrix_in(config->pin_pclk, CAM_PCLK_IDX, false);
设置与OV5640的PCLK相连接的GPIO引脚为GPIO、输入模式(OV5640的输出就是ESP32-S3的输入),上下拉模式设置为GPIO_FLOATING。
2)pin_vsync
代码片段如下:
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[config->pin_vsync], PIN_FUNC_GPIO);
gpio_set_direction(config->pin_vsync, GPIO_MODE_INPUT);
gpio_set_pull_mode(config->pin_vsync, GPIO_FLOATING);
gpio_matrix_in(config->pin_vsync, CAM_V_SYNC_IDX, cam->vsync_invert);
设置与OV5640的VSYNC相连接的GPIO引脚为GPIO、输入模式(OV5640的输出就是ESP32-S3的输入),上下拉模式设置为GPIO_FLOATING。
3)pin_href
代码片段如下:
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[config->pin_href], PIN_FUNC_GPIO);
gpio_set_direction(config->pin_href, GPIO_MODE_INPUT);
gpio_set_pull_mode(config->pin_href, GPIO_FLOATING);
gpio_matrix_in(config->pin_href, CAM_H_ENABLE_IDX, false);
设置与OV5640的HREF相连接的GPIO引脚为GPIO、输入模式(OV5640的输出就是ESP32-S3的输入),上下拉模式设置为GPIO_FLOATING。
4)pin_d0~pin_d7
代码片段如下:
int data_pins[8] = {
config->pin_d0, config->pin_d1, config->pin_d2, config->pin_d3, config->pin_d4, config->pin_d5, config->pin_d6, config->pin_d7,
};
for (int i = 0; i < 8; i++) {
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[data_pins[i]], PIN_FUNC_GPIO);
gpio_set_direction(data_pins[i], GPIO_MODE_INPUT);
gpio_set_pull_mode(data_pins[i], GPIO_FLOATING);
gpio_matrix_in(data_pins[i], CAM_DATA_IN0_IDX + i, false);
}
设置与OV5640的D[9:0](D[7:0])相连接的GPIO引脚为GPIO、输入模式(OV5640的输出就是ESP32-S3的输入),上下拉模式设置为GPIO_FLOATING。
5)pin_xclk
代码片段如下:
if (config->pin_xclk >= 0) {
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[config->pin_xclk], PIN_FUNC_GPIO);
gpio_set_direction(config->pin_xclk, GPIO_MODE_OUTPUT);
gpio_set_pull_mode(config->pin_xclk, GPIO_FLOATING);
gpio_matrix_out(config->pin_xclk, CAM_CLK_IDX, false, false);
}
设置与OV5640的XCLK相连接的GPIO引脚为GPIO、输出模式(OV5640的输入就是ESP32-S3的输出),上下拉模式设置为GPIO_FLOATING。
注意,这个pin_xclk是可选的,如果之前在static camera_config_t camera_config中设置了其值为-1,则此处并不会进入判断体进行设置。
- XCLK引脚
摄像头的外部时钟引脚。
至此,ll_cam_set_pin函数解析完了。下一回回到cam_init函数中,继续解析后续代码。
标签:15,PIN,pin,S3,esp32,cam,gpio,GPIO,config From: https://blog.csdn.net/phmatthaus/article/details/143652297