因为时间的原因,这次点亮摄像头的时间特别短,昨天下午模组到公司,今天下午点亮。

几个人一起调试,发现的问题也很多,今天下午发现有一个怀疑的问题,我马上驱车几十公里去模组厂调试,回来的时候,同事已经把摄像头点亮了。时间虽然很短,但是我觉得应该把排查的问题点总结一下,避免下次调试摄像头的时候遇到同样的问题。

也希望大家看了我的文章后,如果遇到调试摄像头相关的工作,可以迎刃而解。

#模组供电电压

  • 模拟供电电源可以理解为里面有ADC转换相关的电路,需要一个基准电压,这个就是模拟电源电压。

  • IOVDD ,这个是I2C通信的GPIO口电压,有的GPIO口电压是3.3V,而摄像头芯片的IOVDD是1.8V,就需要转换电路把电压转换成1.8V。

  • DVDD 是数字电压这个需要按照模组规格书提供正确供电。

这三路电压是供电要求,一定要按照摄像头模组设计要求。

3.3V转1.8V的电路复位脚和PWDN脚电平转换电路

#时钟MCLK

摄像头模组里面是有芯片的,有芯片就需要有时钟,没有时钟的芯片是不能工作的。就好像一个人,没了心跳的话也是不能正常工作的。

时钟这个问题非常关键,我们刚开始有点忽略时钟的问题。实话说,我也很长时间没有调试摄像头了。我2013年在ZTE调过摄像头,到现在也已经很长时间了,经验这个东西还是很有必要的。但是排除经验的话,就是基础的问题了。没有基础的话,根本就不知道其中的原因,只知道需要这个,却不知道为什么需要这个,知所以,但不知所以然。

但是这个时钟是什么时候产生也是很有必要说明的,我跟硬件沟通,这个时钟硬件是直接从CPU连接出来的,中间就加了一个电阻。但是我们开机后还是量不到MCLK。所以这部分应该是软件问题。

从软件流程上可以看出,在开机的时候,我们会打开MCLK,然后去读CHIP ID,如果读到ID,就保持MCLK打开状态,如果读不到,就退出关闭MCLK。所以在开机后去测量MCLK是有可能量不到的。

MCLK在dts里面设置如下

gc5025: gc5025@37 {status = "okay";compatible = "galaxycore,gc5025";reg = <0x37>;clock-frequency = <400000>;pinctrl-names = "default";pinctrl-0 = <&cif_clkout_m0>;clocks = <&cru SCLK_CIF_OUT>;clock-names = "xvclk";avdd-supply = <&vcc2v8_dvp>;dovdd-supply = <&vcc1v8_dvp>;dvdd-supply = <&vdd1v2_dvp>;reset-gpios = <&gpio3 RK_PA3 GPIO_ACTIVE_LOW>;pwdn-gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;rockchip,camera-module-index = <0>;rockchip,camera-module-facing = "front";rockchip,camera-module-name = "CMK-CW4191-FG1";rockchip,camera-module-lens-name = "CK5502";port {ucam_out: endpoint {remote-endpoint = <&mipi_in_ucam>;data-lanes = <1 2>;};};};

对应的dts位置

         cif_clkout_m0: cif-clkout-m0 {rockchip,pins = <2 RK_PB3 RK_FUNC_1 &pcfg_pull_none_12ma>;/* cif_clkout */};

这个GPIO口对应原理图我们开机后会打开MCLK,然后读取CHIP ID。如果读不到呢?就会关闭MCLK。看看代码 获取DTS里面的配置设置MCLK

   gc5025->xvclk = devm_clk_get(dev, "xvclk");if (IS_ERR(gc5025->xvclk)) {dev_err(dev, "Failed to get xvclk\n");return -EINVAL;}ret = clk_set_rate(gc5025->xvclk, GC5025_XVCLK_FREQ);if (ret < 0) {dev_err(dev, "Failed to set xvclk rate (24MHz)\n");return ret;}if (clk_get_rate(gc5025->xvclk) != GC5025_XVCLK_FREQ)dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");

如果没有读到CHIP ID 会进入这里


static void __gc5025_power_off(struct gc5025 *gc5025)
{int ret;if (!IS_ERR(gc5025->pwdn_gpio))gpiod_set_value_cansleep(gc5025->pwdn_gpio, 1);clk_disable_unprepare(gc5025->xvclk);if (!IS_ERR(gc5025->reset_gpio))gpiod_set_value_cansleep(gc5025->reset_gpio, 1);if (!IS_ERR_OR_NULL(gc5025->pins_sleep)) {ret = pinctrl_select_state(gc5025->pinctrl,gc5025->pins_sleep);if (ret < 0)dev_dbg(&gc5025->client->dev, "could not set pins\n");}regulator_bulk_disable(GC5025_NUM_SUPPLIES, gc5025->supplies);
}

里面有一句

clk_disable_unprepare(gc5025->xvclk);

就是用来关闭时钟的。

如果时钟不是问题,那就是其他的问题了,我们开机后,打开时钟,读取CHIP ID,读不到后,就关闭时钟。读不到的原因就应该从其他地方排查了。

#上电时序

上电时序是很重要的,做单片机的同学应该都有调时序的经验。每个芯片都有自己的脾气,有的芯片对时序严格,有的对时序不够严格。但是如果通信不成功。就需要排查这方面的问题。

GC5025要求的上电时序是。三路电开启后,MCLK开启后,需要先拉高PWDN,再拉高reset脚。我们正好在这个问题上做错了。修改后的代码如下

#异常问题

还没调通前,我们摄像头在开机后,我使用命令「如下图」读写I2C寄存器0x37 是手册上写的 GC5025 的器件地址。但是用这个地址是读不出内容的。但是我把器件地址修改成0x24,却能看到应答信号,而且读寄存器都能正常成功。

你们可能想知道我是如何找到这个0x24的,因为我写了一个脚本。

@echo off
setlocal ENABLEDELAYEDEXPANSION
set /a ii=3
for /l %%i in (1,1,116) do (
echo "adb shell i2cget -y -f 2 !ii! 0xf0 w"
adb shell "i2cget -y -f 2 !ii! 0xf0 w"
set /a ii+=1
)
pause

还有i2c-tools的链接 https://github.com/weiqifa0/i2c-tool

今天去模组厂的一个原因就是因为这个问题,为什么我写0x37的器件地址,芯片没有应答。但是我写0x24的器件地址,芯片有应答信号。这真的是百思不得姐啊。

正常I2C有应答的波形

调通后,我想了下,这个现象刚好说明了。因为没有正常的上电时序,芯片里面也没有正常工作了。而且这个不正常工作还让我怀疑这个芯片是不是坏掉了。

#总结

看看深圳的夜景

回复「 篮球的大肚子」进入技术群聊

回复「1024」获取1000G学习资料

记一次和摄像头的摩擦经历相关推荐

  1. 记一次jenkins 构建go项目经历

    记一次jenkins 构建 go项目经历.为什么要用jenkins 去构建go项目,方便正式.测试等环境发布.简化发布流程. 1.首先安装jenkins jenkins官方文档, 我使用的是docke ...

  2. 记一个转行程序员的工作经历与感想(一)

    前言 随着科技的发展,现代人生活的节奏是越来越快,个人觉得程序员的生活节奏更快(个人观点),在忙碌的生活中总是很难找到一点点的空闲时间(就算有,估计也是用来睡眠,不知道为什么总是感觉程序员是一种睡眠不 ...

  3. 记一次 Onedrive 丢文件的经历

    记一次 Onedrive 丢文件的经历 入坑 Onedrive 一直以来我还是比较刻意培养自己的正版意识的,但是自己实在是财力有限,所以再三考虑这下,通过 酷安社区 和另外四个人组了一个车队,合买了 ...

  4. 记一次内存溢出的分析经历

    作者:Janti https://www.cnblogs.com/superfj/p/8474288.html 说在前面的话 朋友,你经历过部署好的服务突然内存溢出吗? 你经历过没有看过Java虚拟机 ...

  5. 记一次Java多线程程序调试经历:HttpClient 死锁

    我自己写了一个爬虫程序,跑了半天后程序就卡死了,没有任何输出和动静. 先是使用jstatd和VisualVM,参考这篇文章:jstatd,VisualVM使用和报错解决 结果如下图: 看到内存毫无变化 ...

  6. 记一次libfreenect2安装配置的经历

    libfreenect2是一个Kinect for Windows v2设备的开源跨平台驱动程序.因为接下来需要通过kinect(微软旗下的一款应用于xbox的体感设备)来获取深度信息,以及物体轮廓框 ...

  7. 【面经】记一次字节跳动前端面试经历

    文章来自公号粉丝,本文转载自他的博客. 博主找我修改简历,给他提了一些建议,不久他就收到了字节跳动面试.(不知道是不是提的建议有效果--) PS:文中加了一些我的注释. 正文如下: 太长不看版 对于实 ...

  8. 设置好网络协议了为何网络还是不通_记一次菜鸟网络的面试经历

    我是一个不太爱折腾的人,因此在一个公司待久了,就不太会轻易跳槽.正因为如此,我在上家公司待了整整三年,在这里,认识了一群可爱的人,便更不舍得离去. 但因为公司属于传统企业,技术上并没有太大挑战,个人也 ...

  9. 【面经】记一次字节跳动后端面试经历

    太长不看版 对于实习招聘(甚至校招)来说,项目经历可能是获得面试的敲门砖,但是基础绝对是赢得面试的通天索. 即使是实习招聘,白板写代码也很可能逐渐成为主流面试的标配,平时要有意识地锻炼这方面能力,要不 ...

最新文章

  1. android平台水波效果 源码
  2. react ui框架_顶级React组件库推荐
  3. c++数据结构代码整理_抄代码对自己编程提高有用嘛
  4. 什么东西都要用一句话总结出来:这是最重要的
  5. 结对-贪吃蛇游戏-开发过程
  6. C++11:右值引用和转移赋值
  7. Effective Java~3. 私有Constructor 或Enum 强化单例
  8. 设置PL/SQL工具SQL窗口的字体大小及颜色
  9. navicate将远程数据库导入到本地数据库
  10. 基于JAVA+SpringBoot+Mybatis+MYSQL的在线点餐系统
  11. 《Linux命令行大全》:1-6:重定向和管道(很精彩)
  12. 2-36进制,可以任意进制互转的类
  13. Ubuntu1604上使用Qt远程调试arm开发板
  14. matlab处理多光谱,多光谱数据处理教程
  15. 1068 万绿丛中一点红 Python实现
  16. 001案例分析、常见项目管理名词
  17. 刷主板bios改变机器码_主板BIOS升级超完整教程,一学就会!
  18. 什么是restful?说说你对restful的理解
  19. python缩写月份单词_Python替换月份为英文缩写的实现方法
  20. 实验三 字符类型及其操作(新)

热门文章

  1. 【原创】uC/OS 中LES BX,DWORD PTR DS:_OSTCBCur的作用及原理
  2. Linux文件、目录权限及常用命令
  3. Oracle的列转行问题
  4. 后端DTO(数据传输对象)与DAO(数据库数据源对象)解耦的好处
  5. java中list()和listfile()
  6. 套接字(socket)基本知识与工作原理
  7. JavaScript中的运算符
  8. sprintf用法详解
  9. Perforce使用指南_forP4V
  10. C++中int *p[4]和 int (*q)[4]的区别