其他分享
首页 > 其他分享> > Qcom平台 TC358840 调试指南

Qcom平台 TC358840 调试指南

作者:互联网

Key-Word:TC358840、MSM8953、Android9.0

简介 : HDMI 转 MIPI(CSI) 芯片

平台 : MSM8953

芯片 : TC358840XBG (最大支持4K 30fps)

Format : rgb 转 Ycbcr422-8bit

软件平台 :Android – P(9.0 )

信号输出源:电脑主机

目前调通的配置:1080p 30fps 4lane (预览30帧、录像30帧)

 

1. 前言:

TC358840 是一个 HDMI 转 CSI 信号的转换,信号由其他设备输入进来。对平台端msm8953 而言,可以当做一个摄像头处理。

在840(TC358840后面简称840)芯片初始化后,其他信号设备会经 HDMI 接口读取芯片的EDID 数据,探测芯片端支持的最大分辨率,探测成功后,

默认输出840芯片最大支持的分辨率。(一个芯片内可同时储存多种EDID数据,即同时支持多种分辨率。)

调试时用电脑主机接上初始化完的芯片(写EDID等数据),电脑上会显示识别到一个新的显示器。

具体的分辨率见电脑显示设置。

 

2. 遇到的问题

  1. 840芯片 寄存器读取ID失败。
  2. 840芯片 寄存器写入不起作用。
  3. 840芯片 识别到后,数据流异常。无法预览、拍照、录像。
  4. 数据出流后颜色异常,颜色发绿。

2.1 解决

  1.  840芯片的从机地址由INT 脚的电平决定,上拉为0x1F,下拉为0x0F。实际使用要两种都尝试一下。 我们实际调试中发现,硬件链接到普通IIC上(非CCI),在kernel中写 一个iic驱动,读取的从机地址为0F,用vendorcam 驱动的方式 slave_addr为1F。
  2.  写入大小端不一致,解决办法见 CCI 写问题。见附录。
  3.  通过底层添加 csid csi等驱动log后,发现并无异常 frame id 会递增说明接收到了帧。最后排查发现是初始化代码中没有设置输出流的帧格式,导致无法正确解析到帧。
  4.  颜色异常修改数据格式后解决。.filter_arrangement = SENSOR_UYVY, 

后续存在问题:

  1.  1080P 60fps的画面输出调试,甚至更高的其他分辨率如4K 30fps。
  2.  外部信号输入需要动态调节的,比如同一个信号输入源分辨率、帧率的改变。不同信号源之间,HDMI 线的插拔切换。

 

3. 达到的功能点

  1. 840 芯片相对主控来说作为一个cam 设备,但信号是从外部信号源输入840后再转化为mipi信号。
  2. 相机要能够正常的打开使用。

功能点的验证和预期结果:

  1.  插入外部1080p、30fps的信号 (插到电脑主机上会自动输出匹配格式的信号)。
  2.  打开qcom相机,电脑能够识别到一个外部显示器(数据格式分辨率、帧率都可以看出来 这里是 RGB 1080p 30fps)
  3.  查看预览、拍照、录像、画面是否正常,颜色是否正常。
  4.  在相机设置中相片尺寸需要调节为 HD 1080P,这样拍照的照片才是 1920x1080的分辨率。
  5.  录像测试: 切到录像模式,录像后,退出。用adb pull sdcard/DCIM/camera 到本地电脑上,查看录像文件信息,可以看到帧率为30帧。

功能点实测:

1、 和预期一致。验证通过。

 

4. kernel drv 配置

首先是一个YUV camera的适配:

第一步就是配置好dts和vendor的驱动,保证 cam 读取ID 匹配正常。

需要注意,这是一个YUV的cam,因此不需要效果 chromatix文件的配置,所以一切和效果相关的配置都需要去掉。

供电:实际的电路供电修改过,因此实际的dts配置以实际应用的为准。

这里简单说明。有三路供电。1V2 1V8和3V3。

dts中把 1V2和1V8 配置上即可。

其他如rst、pwd脚、挂载位置、角度、cci 总线位置,根据硬件接线配置。

 

mclk配置:使用外置晶振提供clk时钟,不使用平台的mclk

4.1 CCI 读问题

经过加log实测发现,840芯片大小端和平台端相反。因此按照默认的写入方式,芯片的初始化是不正确的。需要做修改。

CCI 读取问题:

如840的识别ID寄存器地址是 0xx00,按照CCI 的默认读取方式读出是0x47(0x0047)。

但是按照IIC的读取方式和我们的一般认知应该是0x4700。

为了保证对比方便(后续会把写入的寄存器值再读出来做对比)和认知一致,我们在读取函数中作如下修改。

kernel\msm-4.9\drivers\media\platform\msm\
camera_v2\sensor\io\msm_camera_cci_i2c.c  54
int32_t msm_camera_cci_i2c_read
===>
	rc = cci_ctrl.status;
	if (data_type == MSM_CAMERA_I2C_BYTE_DATA)
		*data = buf[0];
	else {
		*data = buf[0] << 8 | buf[1];
===> 修改为
	rc = cci_ctrl.status;
	if (data_type == MSM_CAMERA_I2C_BYTE_DATA)
		*data = buf[0];
	else {
	//	*data = buf[0] << 8 | buf[1];
		*data = buf[1] << 8 | buf[0];
	}

这样修改后,读取出的 0x00 就是0x4700了。和平台大小端一致,而且是按照我们的阅读顺序,高位在左,低位在右。

 

4.2 CCI 写问题

写寄存器比较麻烦,需要修改多处。有以下几个问题。

  1.  840的初始化数组,有三种不同的类型,有8bit、16bit、32bit、的寄存器。
  2. 咨询芯片厂商,8bit的要按照8bit的去写,16bit的按照16bit的去写,32bit可以拆分为两个 16bit的去写入,且数据的写入顺序不能修改。因此至少要按照两种类型去写入。
  3.  vendor的cam驱动中,初始化数组res0中,数据类型是固定的,只能设置为 byte(8bit)或者word(16bit)类型,不能为每个数据设置类型。

这里通过修改vemdor的cam驱动和底层的写函数来实现。

  1. 区分不同的数据类型。在cam的初始化数组中,通过添加延时,来区分8bit或者16bit的数据类型。通过观察,默认数据有三种 8bit无延时,16bit无延时,16bit有延时(这类保持默认延时,不做修改)。因此,在每个16bit的后面都加0x01(1us)的延时,通过判断延时时间是否>0就可以把8bit和16bit的数据类型区分开。默认设置初始化数据类型为 word 类型。

 

2.  修改底层驱动,根据延时判断数据类型。

查看驱动流程,所有的读写都是通过队列来完成的,最终都会调用到这个函数。

msm_cci.c kernel\msm-4.9\drivers\media\platform\msm\camera_v2\sensor\cci
int32_t msm_cci_data_queue(...)

默认写函数关键代码如下:

/* max of 10 data bytes */
		do {
			if (i2c_msg->data_type == MSM_CAMERA_I2C_BYTE_DATA) {
				data[i++] = i2c_cmd->reg_data;
				reg_addr++;
			} else {
				if ((i + 1) <= cci_dev->payload_size) {
					data[i++] = (i2c_cmd->reg_data &
						0xFF00) >> 8; /* MSB */
					data[i++] = i2c_cmd->reg_data &
						0x00FF; /* LSB */
					reg_addr++;
				} else
					break;
			}
			i2c_cmd++;
			--cmd_size;
		} while (((c_ctrl->cmd == MSM_CCI_I2C_WRITE_SEQ) || pack--) &&
				(cmd_size > 0) && (i <= cci_dev->payload_size));

可以看到这里判断了数据类型,并且若是word类型,data数组中分别放置高8bit和低8bit。

这里做两个修改:

  1. 通过延时区分8bit、16bit 数据类型。

添加如下内容

+#if 1
+		if (i2c_cmd->delay > 0)
+			i2c_msg->data_type = MSM_CAMERA_I2C_WORD_DATA;
+		else
+			i2c_msg->data_type = MSM_CAMERA_I2C_BYTE_DATA;
+#endif
		i = 0;
		data[i++] = CCI_I2C_WRITE_CMD;

2. 由于大小端相反,交换高低8bit数据。

data[i++] = (i2c_cmd->reg_data &
						0xFF00) >> 8; /* MSB */
					data[i++] = i2c_cmd->reg_data &
						0x00FF; /* LSB */
					reg_addr++;
===> 修改为
					data[i++] = i2c_cmd->reg_data &
						0x00FF; /* LSB */
					data[i++] = (i2c_cmd->reg_data &
						0xFF00) >> 8; /* MSB */

 

5. vendor drv 配置

TC358840的驱动是在 gc5025的驱动上修改的,只是名字还是用的gc5025,实际驱动和gc5025毫无关系。

1.  修改device-vendor.mk 

\vendor\qcom\proprietary\common\config 

由于是YUV cam,去掉所有效果相关的 lib。只保留 MM_CAMERA += libmmcamera_gc5025

2. 修改 cam config 配置文件。

msm8953_camera.xml vendor\qcom\proprietary\
mm-camera\mm-camera2\media-controller\modules\sensors\configs\	

  <CameraModuleConfig>
    <CameraId>0</CameraId>
    <SensorName>gc5025</SensorName>
    <ModesSupported>1</ModesSupported>
    <Position>BACK</Position>
    <MountAngle>90</MountAngle>
    <CSIInfo>
      <CSIDCore>0</CSIDCore>
      <LaneMask>0x1F</LaneMask>
      <LaneAssign>0x4320</LaneAssign>
      <ComboMode>0</ComboMode>
    </CSIInfo>
    <LensInfo>
      <FocalLength>5.24</FocalLength>
      <FNumber>1.05</FNumber>
      <TotalFocusDistance>47</TotalFocusDistance>
      <HorizontalViewAngle>94</HorizontalViewAngle>
      <VerticalViewAngle>49.5</VerticalViewAngle>
      <MinFocusDistance>0.1</MinFocusDistance>
    </LensInfo>
  </CameraModuleConfig>

3.  去除 charomatix 配置文件的链接

vendor/qcom/proprietary/mm-camera/
mm-camera2/mediacontroller/modules/sensors/configs/project.mk
去除 gc5025的效果文件的编译。
+# include $(CLEAR_VARS)
+# LOCAL_MODULE:= gc5025_chromatix.xml
+# LOCAL_MODULE_CLASS := EXECUTABLES
+# LOCAL_SRC_FILES := gc5025_chromatix.xml
+# LOCAL_MODULE_TAGS := optional
+# LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/camera
+# LOCAL_MODULE_OWNER := qti
+# include $(BUILD_PREBUILT)

4.  去除 charomatix 配置文件的编译

vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/modules/sensors/chromatix/0310/chromatix_gc5025/Android.mk
ifeq ($(call is-vendor-board-platform,QCOM),true)
- include $(call all-subdir-makefiles)
+ # include $(call all-subdir-makefiles)
endif

5.  延长帧检测时间。由于在840的初始化代码中,有很多必要且很长的延时,因此为了避免帧检测时间过短,导致还没初始化完成的时候就误判退出,加长了帧检测时间的设置。

vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/mct/bus/mct_bus.c
-#define MCT_BUS_NANOSECOND_SCALER 1000000000
+//#define MCT_BUS_NANOSECOND_SCALER 1000000000
+#define MCT_BUS_NANOSECOND_SCALER   3000000000 // 3s
 #define MAX_MCT_BUS_QUEUE_LENGTH 1000

 

补充:

EDID :

       EDID,Extended display identification data,中文名称扩展显示器识别数据,是VESA在制定DDC显示器数据通道通信协议时,制定的有关显示器识别数据的标准。EDID存储在显示器中的DDC存储器中,当电脑主机与显示器连接后,电脑主机会通道DDC通道读取显示器DDC存储器中的存储的EDID。

      EDID其中包含有关显示器及其性能的参数,包括供应商信息、最大图像大小、颜色设置、厂商预设置、频率范围的限制以及显示器名和序列号的字符串等等。形象地说,EDID就是显示器的身份证、户口本、技能证书等证件的集合,目的就是告诉别人我是谁,我从哪来,我能干什么。

说人话:就是电脑主机输出端,读取到 EDID 信息,获取到芯片端最大支持的信息,然后是输出对应的数据流。

      对我们来说,我们关心的,就是芯片中对自身支持的最大分辨率、帧率的一个信息。EDID 在成功写入芯片后,就代表了芯片对外界的一个回应信息,在电脑主机插入芯片的HDMI接口的时候,主机会读取芯片的EDID数据,从而明白主机本身应该输出多大分辨率和帧率的数据流。

     840芯片同时可储存多组EDID信息,即同时支持多种分辨率。如同时支持1080P@60fps、1080P@30fps、720P@60fps、720P@60fps等等。

 

你再快,也永远有人比你快!Come On ~~

 

标签:840,芯片,TC358840,camera,Qcom,EDID,i2c,data,调试
来源: https://blog.csdn.net/FANG_YISHAO/article/details/113356523