全志v3s mipi ov5640 摄像头驱动
在网上找了很久 很难找到比较完善针对性的案例 尤其是v3s 的 mipi 驱动 和 ov5640 驱动的案例 做为记录 也希望帮到正在寻找的人
这是我在淘宝买的 开发板 你也可以选其它的
这开发板 一般般 配套的linux是全志内部的linux系统 并非现在主流的设备树配置系统 不习惯 而且其配套的摄像头太贵了(坑) 被迫寻求其它方案 就想到了 ov5640 算是淘宝比较便宜和好找的 mipi 兼容 dvp的摄像头 大概长这样:
由于开发板不是配套 ov5640 供电的 还需要个 供电板:
再来个 杜邦线 2.54 转 0.5mm的FFC/FPC 软排线 24pin 的转接头:
当然少不了 24pin 的排线:
看看我优美的连线图
开始干正事
干正事之前 先确定几件事:
- 编译环境是 ubuntu 20.04
- 你已经装好 linux 并且开发板启动成功 linux 系统是用了 linux-zero-5.2.0
最好看一下这篇文章 https://blog.csdn.net/qq_28877125/article/details/132916992
文章里面有系统下载 - 文件系统是 buildroot 因为下面测试摄像头用到 v4l-utils tools 工具
开始摄像头驱动----------------------------------------------------------------------------------------------------------
下载 sun6i-mipi-csi 源码
下载地址: https://gitee.com/prtemly/sun6i-mipi-csi
我的源码之前在 github 下载的 叫 sun6i-mipi-csi-master 你们也可以去找找 上面 gitee 的源码我对比过文件名 应该没问题
说明一下 在github 或 gitee 里面都有编译说明 但不能完整正确跑得通 我就根据自己的摸索记录下来补充一下
我下载回来时的压缩包名为 sun6i-mipi-csi-master.zip 你的可能不一样 有如下文件:
Kconfig
Makefile
README.md
sun6i_csi.c
sun6i_csi.h
sun6i_csi_reg.h
sun6i_dphy.c
sun6i_dphy.h
sun6i_dphy_reg.h
sun6i_mipi.c
sun6i_mipi.h
sun6i_mipi_reg.h
sun6i_video.c
sun6i_video.h
1.将源码放进 ubuntu 并改写文件代码
我的linux系统源码路径为 : /home/linux/v3s/linux-zero-5.2.y
1.解压 sun6i-mipi-csi 到系统源码里面
命令:
unzip sun6i-mipi-csi-master.zip -d /home/linux/v3s/linux-zero-5.2.y/drivers/staging/media/sunxi
解压后得出文件夹 sun6i-mipi-csi-master
重命名解压后的文件夹名字为 sun6i-csi:
mv sun6i-mipi-csi-master sun6i-csi
2.编辑drivers/staging/media/sunxi文件夹里的 Kconfig 文件
添加如下
if VIDEO_SUNXI
.......
source "drivers/staging/media/sunxi/sun6i-csi/Kconfig"
endif
目的是让上层Kconfig找到我们的文件夹sun6i-csi
3.编辑drivers/staging/media/sunxi文件夹里的 Makefile 文件
添加整体结果如下:
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_VIDEO_SUNXI_CEDRUS) += cedrus/
obj-$(CONFIG_VIDEO_SUN6I_MIPI_CSI) += sun6i-csi/
4.编辑设备树文件 arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts
命令:
gedit sun8i-v3s-licheepi-zero.dts
在根节点 注意是根节点 添加设备如下:
//-------------------------在根目录添加csi---------------------------------------------
csi0: csi@01cb0000 {
compatible = "allwinner,sun8i-v3s-csi";
reg = <0x01cb0000 0x3000>;
interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu CLK_BUS_CSI>, <&ccu CLK_CSI1_SCLK>, <&ccu CLK_DRAM_CSI>, <&ccu CLK_MIPI_CSI>;
clock-names = "bus", "mod", "ram", "dphy";
resets = <&ccu RST_BUS_CSI>;
status = "disabled";
};
csi1: csi@1cb4000 {
compatible = "allwinner,sun8i-v3s-csi";
reg = <0x01cb4000 0x3000>;
interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu CLK_BUS_CSI>, <&ccu CLK_CSI1_SCLK>, <&ccu CLK_DRAM_CSI>;
clock-names = "bus", "mod", "ram";
resets = <&ccu RST_BUS_CSI>;
status = "disabled";
};
//-------------------------在根目录添加ov5640电源管理------------------------------------
dovdd: regulator-dovdd {
compatible = "regulator-fixed";
regulator-name = "DOVDD";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
enable-active-high;
};
dvdd: regulator-dvdd {
compatible = "regulator-fixed";
regulator-name = "DVDD";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
enable-active-high;
};
avdd: regulator-avdd {
compatible = "regulator-fixed";
regulator-name = "AVDD";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
enable-active-high;
};
<2>在非根节点 追加设备如下------------------------------------------------------------------------------:
&csi0 {
status = "okay";
allwinner,mipi-csi-bps = <400000000>;
port {
csi0_ep: endpoint {
remote-endpoint = <&ov5640_0>;
clock-lanes = <0>;
data-lanes = <1 2>;
};
};
};
&i2c1 {
status = "okay";
ov5640: camera@3c {
compatible = "ovti,ov5640";
reg = <0x3c>; //ov5640作为i2c从机时的地址
vmmc-supply = <&dovdd>, <&dvdd>, <&avdd>;//电源管理
pinctrl-names = "default";
pinctrl-0 = <&csi0_mclk>;
clocks = <&ccu CLK_CSI0_MCLK>;
clock-names = "xclk";
assigned-clocks = <&ccu CLK_CSI0_MCLK>;
assigned-clock-rates = <24000000>;
powerdown-gpios = <&pio 1 0 GPIO_ACTIVE_HIGH>; //PB0 默认输出高电平
reset-gpios = <&pio 1 5 GPIO_ACTIVE_LOW>; //PB5 默认输出低电平
port {
ov5640_0: endpoint {
remote-endpoint = <&csi0_ep>;
clock-lanes = <0>;
data-lanes = <1 2>;
};
};
};
};
&pio {
csi0_mclk: csi0-mclk@0 {
pins = "PE20";
function = "csi_mipi";
};
};
5.编辑设备树文件 arch/arm/boot/dts/sun8i-v3s.dtsi
在根目录下的soc 下添加如下 注意对比 多出来的才添加 不要直接复制进去:
/{
soc
{
pio: pinctrl@1c20800
{
//追加如下
i2c1_pins: i2c1-pins
{
pins = "PE21", "PE22"; //i2c1 用到端口为 PE21 和 PE22
function = "i2c1";
};
};
i2c1: i2c@1c2b000
{
compatible = "allwinner,sun6i-a31-i2c";
reg = <0x01c2b000 0x400>;
interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu CLK_BUS_I2C1>;
resets = <&ccu RST_BUS_I2C1>;
pinctrl-names = "default"; //追加项
pinctrl-0 = <&i2c1_pins>; //追加项
clock-frequency = <100000>;//追加项 设置i2c速度为 100kHz 好像默认也是这个值
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
};
};
};
//好了 到此要添加的代码就完成了 接下来就将驱动编译进内核
2.配置系统 准备编译
1.配置系统源码 添加刚放进系统源码的 mipi csi 驱动
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
配置如下:
> Device Drivers
> Staging drivers
[*] Media staging drivers --->
[*] Allwinner sunXi family Video Devices
<*> Allwinner V3s Camera Sensor Interface driver with MIPI-CSI2 support
2.配置ov5640摄像头驱动
配置如下:
Device Drivers --->
<*> Multimedia support --->
必须先禁用此项
[ ] Autoselect ancillary drivers (tuners, sensors, i2c, spi, frontends)
不然无法显示下面项
I2C Encoders, decoders, sensors and other helper chips
<*> OmniVision OV5640 sensor support
3.编译
这应该不用教了吧
4.调试摄像头
如果编译成功 系统启动成功 理论上在 /dev 下会有video0 还有个 subdev
1.列出摄像头的设备 命令:
v4l2-ctl --list-devices
会弹出一些参数
2.话不多说 拍个照 命令:
v4l2-ctl --device=/dev/video0 --set-fmt-video=width=640,height=480,pixelformat=NV12 --stream-mmap --stream-to=output.yuv --stream-count=1
此时会在当前目录生成 output.yuv 文件 把它放进 电脑的 ubuntu 查看 可以通过网络 nfs 连接ubuntu 至于网络驱动就不教了
下次有机会吧 自己看着办
4.在ubuntu下看看效果
ubuntu需要安装 ffmpeg 命令:
apt-get install ffmpeg
现在来看看刚才从开发板拍照 然后放进ubuntu的图片吧 命令:
ffplay -video_size 640x480 -pixel_format nv12 -framerate 10 -i output.yuv
有图有真相 你们搞不搞得定我就没办法啦