記一次和攝像頭的摩擦經歷

因為時間的原因,這次點亮攝像頭的時間特別短,昨天下午模組到公司,今天下午點亮。

幾個人一起調試,發現的問題也很多,今天下午發現有一個懷疑的問題,我馬上驅車幾十公里去模組廠調試,回來的時候,同事已經把攝像頭點亮了。時間雖然很短,但是我覺得應該把排查的問題點總結一下,避免下次調試攝像頭的時候遇到同樣的問題。

也希望大家看了我的文章后,如果遇到調試攝像頭相關的工作,可以迎刃而解。

#模組供電電壓

記一次和攝像頭的摩擦經歷

  • 模擬供電電源可以理解為里面有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 offsetlocal ENABLEDELAYEDEXPANSIONset /a ii=3for /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有應答的波形

調通后,我想了下,這個現象剛好說明了。因為沒有正常的上電時序,芯片里面也沒有正常工作了。而且這個不正常工作還讓我懷疑這個芯片是不是壞掉了。

#總結

看看深圳的夜景

記一次和攝像頭的摩擦經歷

來源:嵌入式Linux,本文觀點不代表自營銷立場,網址:http://www.wfapiao.com/p/16037

發表評論

登錄后才能評論
侵權聯系
返回頂部
AV天堂日本AV天堂欧美AV天堂