硬件使用正点原子的阿尔法开发板,摄像头原理图如下:
OV2640是淘宝上买的0v2640模组,如下:
添加设备树节点如下:
&i2c2 {
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c2>;
status = "okay";
ov2640: camera@30 {
compatible = "ovti,ov2640";
reg = <0x30>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_csi1
&csi_pwn_rst>;
resetb-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
pwdn-gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
clocks = <&clks IMX6UL_CLK_CSI>;
clock-names = "xvclk";
assigned-clocks = <&clks IMX6UL_CLK_CSI>;
assigned-clock-rates = <24000000>;
status = "okay";
port {
ov2640_ep: endpoint {
remote-endpoint = <&csi1_ep>;
bus-width = <8>;
};
};
};
};
&csi {
status = "okay";
port {
csi1_ep: endpoint {
remote-endpoint = <&ov2640_ep>;
};
};
};
引脚定义如下:
pinctrl_csi1: csi1grp {
fsl,pins = <
MX6UL_PAD_CSI_MCLK__CSI_MCLK 0x1b088
MX6UL_PAD_CSI_PIXCLK__CSI_PIXCLK 0x1b088
MX6UL_PAD_CSI_VSYNC__CSI_VSYNC 0x1b088
MX6UL_PAD_CSI_HSYNC__CSI_HSYNC 0x1b088
MX6UL_PAD_CSI_DATA00__CSI_DATA02 0x1b088
MX6UL_PAD_CSI_DATA01__CSI_DATA03 0x1b088
MX6UL_PAD_CSI_DATA02__CSI_DATA04 0x1b088
MX6UL_PAD_CSI_DATA03__CSI_DATA05 0x1b088
MX6UL_PAD_CSI_DATA04__CSI_DATA06 0x1b088
MX6UL_PAD_CSI_DATA05__CSI_DATA07 0x1b088
MX6UL_PAD_CSI_DATA06__CSI_DATA08 0x1b088
MX6UL_PAD_CSI_DATA07__CSI_DATA09 0x1b088
>;
};
csi_pwn_rst: csi_pwn_rstgrp {
fsl,pins = <
MX6UL_PAD_GPIO1_IO02__GPIO1_IO02 0x10b0
MX6UL_PAD_GPIO1_IO04__GPIO1_IO04 0x10b0
>;
};
配置内核如下:
上图中红框内的设置比较重要,要不编译内核时会报各种函数未定义。
按照如上配置内核后,编译内核会报错如下:
解决方法就时修改头文件包含路径,涉及的文件(ipu_prp_vf_sdc.c和ipu_prp_vf_sdc_bg.c)如下:
头文件路径是通过find命令在内核代码中找到的,重新编译就不会有错误了。
使用编译好的内核及设备树启动后有如下信息表示驱动加载完成
进入系统后查看/dev目录下有video0节点,如下:
使用原子的应用测试程序报错如下:
需要修改mx6s_capture.c中static struct mx6s_fmt formats[]内容如下:
static struct mx6s_fmt formats[] = {
{
.name = "UYVY-16",
.fourcc = V4L2_PIX_FMT_UYVY,
.pixelformat = V4L2_PIX_FMT_UYVY,
.mbus_code = MEDIA_BUS_FMT_UYVY8_2X8,
.bpp = 2,
}, {
.name = "YUYV-16",
.fourcc = V4L2_PIX_FMT_YUYV,
.pixelformat = V4L2_PIX_FMT_YUYV,
.mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
.bpp = 2,
}, {
.name = "YUV32 (X-Y-U-V)",
.fourcc = V4L2_PIX_FMT_YUV32,
.pixelformat = V4L2_PIX_FMT_YUV32,
.mbus_code = MEDIA_BUS_FMT_AYUV8_1X32,
.bpp = 4,
}, {
.name = "RAWRGB8 (SBGGR8)",
.fourcc = V4L2_PIX_FMT_SBGGR8,
.pixelformat = V4L2_PIX_FMT_SBGGR8,
.mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,
.bpp = 1,
}, {
.name = "RGB565_LE",
.fourcc = V4L2_PIX_FMT_RGB565,
.pixelformat = V4L2_PIX_FMT_RGB565,
.mbus_code = MEDIA_BUS_FMT_RGB565_2X8_LE,
.bpp = 2,
}, {
.name = "RGB565_BE",
.fourcc = V4L2_PIX_FMT_RGB565,
.pixelformat = V4L2_PIX_FMT_RGB565,
.mbus_code = MEDIA_BUS_FMT_RGB565_2X8_BE,
.bpp = 2,
}, {
.name = "JPEG",
.fourcc = V4L2_PIX_FMT_JPEG,
.pixelformat = V4L2_PIX_FMT_JPEG,
.mbus_code = MEDIA_BUS_FMT_JPEG_1X8,
.bpp = 2,
}
};
重新编译后使用新内核启动后测试发现播放尺寸不对,修改原子的测试程序,测试信息如下:
有一个报错,并且画面全是条纹, 到此,驱动应该是好了,为啥图像画面异常还需进一步研究,找到解决方法。