调试扫描头

Android版本:4.4


前前后后调试了快一个月,最后调试到产品稳定。

扫描头本质是摄像头,遵循Camera架构.


第一阶段:

驱动挂上了,i2c读写不稳定,用系统前置预览,没有图像。

示波器量mipi,没有波形,查看手册才发现扫描头支持并口和mipi接口,需要手动配置成mipi接口,0x86寄存器写入0x3。

static int32_t scan_sensor_start_stream(struct msm_sensor_ctrl_t *s_ctrl)
{
    ..........
    reg_addr = 0x86;
    data = 0x03;
    rc = scan_i2c_write(this_client, reg_addr, &data, 1);
    ........
    return rc;
}


配置完mipi接口输出后,前置预览还是出不了图像,mipi已经出波形了,电平1.2V也符合要求,说明扫描头已经有传输数据,高通平台这层出了问题。

按照以往经验,Vendor 配置是YUV图像输出,

{0, CSI_YUV422_8, CSI_DECODE_8BIT},

刚开始以为mipi通路问题,试了一个调试过的前置,预览正常,证明mipi通路是正确的。联系了FAE才知道是RAW8格式。修改成RAW8后,系统前置预览图像出来了。

{0, CSI_RAW8, CSI_DECODE_8BIT},
格式设置错了,能预览但是没提示又错误,framebuff也一直有,格式错了应该也会花屏,这个地方纠结了一阵子。


第二阶段:

demo应用预览图像有条纹或者显示不全,图像可以看得不清晰,无法解码。FAE强调分辨率是1280 * 720。后面几番尝试,修改分辨率为1360 * 800,应用demo预览正常了。这有一部分原因是i2c不稳定而导致误判,FAE demo和我用也不一样。

Kernel层代码:

	reg_addr = 0x84;
	data = 0x01;
	rc = scan_i2c_write(this_client, reg_addr, &data, 1);

Vendor层代码:

	
	.x_output = 1360,
	.y_output = 800,
	.line_length_pclk = 1688,
	.frame_length_lines = 832,

第三阶段:

扫描头I2c不稳定,偶尔能正常出图像,代码上优化也不能避免i2c读写出错。

扫描头命令协议是cmd + data + checksum,大部分命令长度是3个。

I2C Command Format:
    <I2C-Start Bit> <SLA-W> <Cmd-Opcode> <[Cmd-Data]> <Checksum> <I2C-Stop-Bit>

调试以来,使用的都是高通i2c接口i2c_write_seq和i2c_read_seq接口。

i2c_write_seq(s_ctrl->sensor_i2c_client, reg_addr,txdata, tx_len);
i2c_read_seq(s_ctrl->sensor_i2c_client, reg_addr,rxdata, rx_len);

高通架构i2c为发送命令4字节对齐,和扫描头通信协议冲突,校验值计算错误,造成i2c错乱。扫描头i2c电路上飞线到其他路i2c,驱动在扫描头加载的时候加入新的i2c挂载.

static int32_t scan_platform_probe(struct platform_device *pdev)
{
    ..........
    i2c_add_driver(&real_i2c_driver);
    rc = msm_sensor_platform_probe(pdev, match->data);
    return rc;
}

注册一个i2c设备,实际使用到i2c的地方,就用这个新注册的i2c读写,使用i2c_transfer接口,i2c就此稳定。

static int scan_i2c_write(struct i2c_client *client, u8 reg, u8 *val, u8 len) 
{
    struct i2c_msg msg; 
    u8 data[4];
    int i = 0;
    int rc = -1, cnt = 0;
    
    data[0] = reg; 
    for ( i = 0; i < len; i++)
    {
        data[i+1] = val[i];
    }
    data[i+1] = scan_calc_checksum(data, len+1);
    msg.addr = client->addr;
    msg.flags = 0; 
    msg.len = len + 2; 
    msg.buf = data;
    do {
        rc = i2c_transfer(client->adapter, &msg, 1);
        msleep(1);
    }while(cnt++ < 3 && rc < 0);
    return  rc;
}
使用普通i2c读写接口

第四阶段:

优化代码,单个命令不会出错,写多个命令经常会i2c出错,实际调试发现,每个写命令之间最好要有1ms间隔,读字符串命令需要等待5ms。


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值