相机自动对焦电机驱动
概述
相机自动对焦电机设备是用于实现自动对焦功能的专用设备,通常通过 I2C 接口进行控制。如下图所示,ISP 负责统计每帧数据的清晰度信息,并将统计数据上报给 IPA;然后,IPA 对统计数据进行分析,控制对焦电机移动,完成对焦。

camera motor 数据流
驱动代码结构
camera motor 的驱动代码结构可以描述如下:
├── include
│ └── dw9714_types.h
│ └── dw9714.h
├── private_include
│ └── dw9714_regs.h
│ └── dw9714_settings.h Initialize settings of the motor driver
└── Kconfig.dw9714
└── dw9714.c Implementation of the motor driver
注意
如需新增对焦电机的驱动程序,可以基于一款规格相近的对焦电机驱动进行修改。
对焦电机与相机模组的硬件连接方式有很多种,驱动人员根据实际的硬件需求编写驱动程序。建议尽量使用相机传感器上的管脚、并与相机传感器共用 SCCB 总线,以节省 SOC 的管脚。
功能概览
camera motor 的驱动程序提供下述功能:
设备发现 - 包括对电机设备进行读写检查,以及如何在完成工作后回收资源。
参数控制 - 包括查询设备支持的参数信息,设置和查询参数值等信息。
IO 控制 - 包括控制设备的重启、休眠等功能。
格式控制 - 描述了如何枚举该对焦电机支持的格式,以及设置和查询格式。
查询名称 - 描述了在使用中查询当前设备的名称。
Kconfig 选项 - 列出了支持的 Kconfig 选项,这些选项可以对驱动程序产生不同影响。
设备发现
若电机设备已正确连接到 SOC 上,并且驱动程序正常,驱动程序将自动对传感器进行 SCCB 读写检查,并返回 esp_cam_motor_device_t 来表示该设备。在调用任何其他 esp_cam_motor_ API 之前必须先生成该设备的描述符。
通过电机设备命名的接口探测指定设备
以 DW9714 为例,在应用代码中包含 dw9714.h 头文件,然后通过 dw9714_detect() 函数探测该总线上是否连接了该设备。
探测指定 sccb 总线上的所有设备
camera motor 驱动提供了一个数组,以供用户探测指定的 sccb 上连接的所有对焦电机设备。
for (esp_cam_motor_detect_fn_t *p = &__esp_cam_motor_detect_fn_array_start; p < &__esp_cam_motor_detect_fn_array_end; p++) {
esp_cam_motor_config_t cfg = {0};
esp_cam_motor_device_t *motor_dev;
const esp_video_init_cam_motor_config_t *cm = config->cam_motor;
cfg.sccb_handle = create_sccb_device(sccb_mark, ESP_VIDEO_INIT_MOTOR_SCCB, &cm->sccb_config, p->sccb_addr);
if (!cfg.sccb_handle) {
return ESP_FAIL;
}
cfg.reset_pin = cm->reset_pin,
cfg.pwdn_pin = cm->pwdn_pin,
cfg.signal_pin = cm->signal_pin,
motor_dev = (*(p->detect))((void *)&cfg);
if (!motor_dev) {
destroy_sccb_device(cfg.sccb_handle, sccb_mark, &config->csi->sccb_config);
ESP_LOGE(TAG, "failed to detect sensor motor with address=%x", p->sccb_addr);
continue;
}
break;
}
删除设备
如果不再需要使用相机设备,可以调用 esp_cam_motor_del_dev() 来回收资源。
参数控制
camera motor 设备的参数可以被查询和设置:
esp_cam_motor_query_para_desc() 用于查询参数的类型、取值范围。
esp_cam_motor_get_para_value() 用于查询参数的当前值。
esp_cam_motor_set_para_value() 用于设置参数的值。
IO 控制
相机设备的输入输出控制可以通过调用 esp_cam_motor_ioctl() 来实现。
格式控制
camera motor 设备的格式信息包括:工作模式、步进信息、默认位置等信息。所有由初始化寄存器列表决定的信息均通过 esp_cam_motor_format_t 结构体来描述。通过设置和查询该结构体的信息,IPA 可以更加清楚地控制对焦电机完成对焦功能。
esp_cam_motor_query_format() 用于查询支持的格式信息。
esp_cam_motor_get_format() 用于查询正在使用的格式信息。
esp_cam_motor_set_format() 用于设置使用的格式信息。
注意
如需调整对焦电机的工作模式,需要注意以下问题:
振铃效应:移动马达时由于有惯性,会存在惯性振动。通常对焦电机驱动 IC 上带有抑制振动的控制模式,如 DW9714 的 DLC (Dual Level Control) 模式。
Border control:移动马达时由于有惯性,接近边缘的时候要有边缘控制,否则可能撞到边缘。若默认设备上电后,将马达移动到距离感光矩阵最远处的地方,设备断电将可能导致马达迅速向初始化位置移动,从而触碰边缘,发出异响,此为正常现象。
步长控制:不要一次移动太大的步长,而是分多次以平滑的小步长逐步移动到目标位置。开发人员编写完驱动后,可以启动一个定时器,在定时器回调中控制步长递增或递减,然后通过可预览图像的示例程序,观察马达的移动是否平滑。
考虑到马达的重力,其在水平、垂直朝上、垂直朝下等不同的方向上的重力不一样,需要的步进值也不一样。若有方向传感器,可以参考方向作优化。
查询名称
通过调用 esp_cam_motor_get_name() 接口来查询当前设备的名称。
Kconfig 选项
每一个对焦电机都有一个配置文件,以 DW9714 为例,对应的是 sensors/dw9714/Kconfig.dw9714 文件。通过该文件可以配置设备默认加载的格式、是否启用自动探测功能等。
API 参考
Header File
Functions
-
esp_err_t esp_cam_motor_query_para_desc(esp_cam_motor_device_t *dev, esp_cam_motor_param_desc_t *qdesc)
Query the supported data types of extended control parameters.
- 参数:
dev – [in] Camera motor device handle that was created by
motor_detect.qdesc – [out] The pointer to hold the extended control parameters.
- 返回:
ESP_OK: Success
ESP_ERR_INVALID_ARG: Error in the passed arguments.
ESP_ERR_NOT_SUPPORTED: The motor driver does not support this operation.
-
esp_err_t esp_cam_motor_get_para_value(esp_cam_motor_device_t *dev, uint32_t id, void *arg, size_t size)
Get the current value of the control parameter.
- 参数:
dev – [in] Camera motor device handle that was created by
motor_detect.id – [in] Camera motor parameter ID.
arg – [out] Camera motor parameter setting data pointer.
size – [in] Camera motor parameter setting data size.
- 返回:
ESP_OK: Success
ESP_ERR_INVALID_ARG: Error in the passed arguments.
ESP_ERR_NOT_SUPPORTED: The motor driver does not support this operation.
-
esp_err_t esp_cam_motor_set_para_value(esp_cam_motor_device_t *dev, uint32_t id, const void *arg, size_t size)
Set the value of the control parameter.
- 参数:
dev – [in] Camera motor device handle that was created by
motor_detect.id – [in] Camera motor parameter ID.
arg – [in] Camera motor parameter setting data pointer.
size – [in] Camera motor parameter setting data size.
- 返回:
ESP_OK: Success
ESP_ERR_INVALID_ARG: Error in the passed arguments.
ESP_ERR_NOT_SUPPORTED: The motor driver does not support this operation.
-
esp_err_t esp_cam_motor_query_formats(esp_cam_motor_device_t *dev, esp_cam_motor_fmt_array_t *format_array)
Get driver information supported by the motor driver.
- 参数:
dev – [in] Camera motor device handle that was created by
motor_detect.format_array – [out] The pointer to hold the description of the currently supported formats(configurations).
- 返回:
ESP_OK: Success
ESP_ERR_INVALID_ARG: Error in the passed arguments.
ESP_ERR_NOT_SUPPORTED: The motor driver does not support this operation.
-
esp_err_t esp_cam_motor_set_format(esp_cam_motor_device_t *dev, const esp_cam_motor_format_t *format)
Set the working format of the camera motor.
备注
If format is NULL, the camera motor will load the default format.
备注
Query the currently supported formats by calling esp_cam_motor_query_format.
- 参数:
dev – [in] Camera motor device handle that was created by
motor_detect.format – [in] The pointer to hold the description of the currently supported format.
- 返回:
ESP_OK: Success
ESP_ERR_INVALID_ARG: Error in the passed arguments.
ESP_ERR_NOT_SUPPORTED: The motor driver does not support this operation.
ESP_CAM_MOTOR_ERR_FAILED_SET_FORMAT: An error occurred while writing data over the SCCB bus
-
esp_err_t esp_cam_motor_get_format(esp_cam_motor_device_t *dev, esp_cam_motor_format_t *format)
Get the current camera motor Working format.
- 参数:
dev – [in] Camera motor device handle that was created by
motor_detect.format – [out] The pointer to hold the description of the currently format.
- 返回:
ESP_OK: Success
ESP_FAIL: The motor driver has not been formatured the working format yet.
ESP_ERR_INVALID_ARG: Error in the passed arguments.
ESP_ERR_NOT_SUPPORTED: The motor driver does not support this operation.
-
esp_err_t esp_cam_motor_ioctl(esp_cam_motor_device_t *dev, uint32_t cmd, void *arg)
Perform an ioctl request on the camera motor.
- 参数:
dev – [in] Camera motor device handle that was created by
motor_detect.cmd – [in] The ioctl command, see esp_cam_motor_types.h.
arg – [in] The argument accompanying the ioctl command.
- 返回:
ESP_OK: Success
ESP_ERR_INVALID_ARG: Error in the passed arguments.
ESP_ERR_NOT_SUPPORTED: The motor driver does not support this cmd or arg.
-
const char *esp_cam_motor_get_name(esp_cam_motor_device_t *dev)
Get the module name of the current camera device.
- 参数:
dev – [in] Camera motor device handle that was created by
motor_detect.- 返回:
Camera module name on success, or “NULL”
-
esp_err_t esp_cam_motor_del_dev(esp_cam_motor_device_t *dev)
Delete camera device.
- 参数:
dev – [in] Camera motor device handle that was created by
motor_detect.- 返回:
ESP_OK: If Camera motor is successfully deleted.