海思Hi3531DV100/V200上多片6158C踩坑记录

goodman 2020-09-12 17:58:14 9862

前言

项目上使用了2片NVP6158C来接8路AHD是视频输入,从FAE那边拿到了驱动的源码,自适应的的应用代码后,就开始画板调试了,因为之前有使用NVP6124B及NVP6134,觉着这货还不是小菜一点,交给了同事去搞,毕竟我们还是要提高整体团队的战斗力的。。。小伙伴搞了几天没整完,今天刚好又是周六。。。所以祖国需要我。。。

问题现象

芯片都能通过I2C配置,2颗同时用的时候,有2个问题:

  • 问题现象1.接8路摄像头:
    第一颗芯片上接的4个摄像头,海思端无法采集,第二颗芯片能正常。

  • 问题现象2.插拔摄像头
    拔插摄像头的时候,有些通道出现摄像头loss信号检测正常,format检测不出来。

奇怪的是单独使用第一颗芯片(把第二颗新片去了)是正常的,单独使用第二颗(把第一颗去掉)也是正常,按照正常的思路怀疑同时上8路,供电跟不上了,硬件查电路,量电压,后来发现不是,问题依旧。后面还试了各种更可能的情况,将2个芯片分别挂到2个I2C总线上,供电分别单独供,各种折腾,还是不行。

排查问题

后来联系了FAE,他给了2组进寄存器还是很有用的

bank5678 0x2c == 0x08
bank0 0x78/0x79 == 0xaa  #colorbar

用这个组参数,默认不接摄像头就是可以出彩条的,海思端采集使用1080P。彩条如下:

配置后启动程序,发现8个通道全部有数据,都能正常采集到图像,证明物理连接是没有问题的,那么问题到底出在哪里呢?怀疑驱动,单颗又是好的。后面就一步一步排查,将海思的DEMO重新写了下,确保没有问题。最后只能去分析6158C驱动代码了。应为我们使用的是自适应分辨率,需要动态获取视频格式来初始化VI属性。看到驱动里面这么个线程:

static int nvp6158_kernel_thread(void *data)
{
    //int ch;
    //nvp6158_input_videofmt videofmt;
    NVP6158_INFORMATION_S s_nvp6158_vfmts;
    video_equalizer_info_s s_eq_info;
    unsigned char prefmt=0, curfmt=0, chvloss=0;
    unsigned char ch = 0;
    while(!kthread_should_stop())
    {
        #if 1  //standard rutine of a process
        down(&nvp6158_lock);
        ch = ch % (nvp6158_cnt*4);
        nvp6158_getvideoloss();
        video_fmt_det(ch, &s_nvp6158_vfmts);
        curfmt = s_nvp6158_vfmts.curvideofmt[ch];
        prefmt = s_nvp6158_vfmts.prevideofmt[ch];
        chvloss = s_nvp6158_vfmts.curvideoloss[ch];
        printk(">>>>>>%s CH[%d] chvloss = %d curfmt = %x prefmt = %x\n", __func__, ch, chvloss, curfmt, prefmt);

        if(chvloss == 0x00)
        {   
            if(ch_mode_status[ch] != prefmt)
            {
                nvp6158_set_chnmode(ch, curfmt);
                //nvp6158_set_portmode(0, ch%4, NVP6158_OUTMODE_1MUX_FHD, ch%4);

                // 不明白为什么写死是0,多个芯片的话就不对了啊,而且第二个参数也是不对,严重怀疑写这个驱动的人没有在6158C上验证过
                nvp6158_set_portmode(0, ch%2, NVP6158_OUTMODE_2MUX_SD, ch%2);
                s_eq_info.Ch = ch%4;
                s_eq_info.devnum = ch/4;
                s_eq_info.FmtDef = curfmt;
                nvp6158_get_eq_dist(&s_eq_info);
                s_nvp6158_vfmts.prevideofmt[ch] = curfmt;
                printk(">>>>>>%s CH[%d] s_eq_info.distance = %d\n", __func__, ch, s_eq_info.distance);
                nvp6158_set_equalizer(&s_eq_info);
            }
        }
        else
        {   
            if(ch_mode_status[ch] != NC_VIVO_CH_FORMATDEF_UNKNOWN)
            {
                nvp6158_set_chnmode(ch, NC_VIVO_CH_FORMATDEF_UNKNOWN);
                nvp6158_set_portmode(0, ch%4, NVP6158_OUTMODE_1MUX_FHD, ch%4);
            }
        }   
        ch ++;
        up(&nvp6158_lock);
        #endif
        schedule_timeout_interruptible(msecs_to_jiffies(2000));
//      printk("nvp6158_kernel_thread running\n");
    }

    return 0;
}

解决问题

根据上面线程的流程,自己改写了从FAE哪边拿过来的代码,发现这个NVP的驱动写的贼乱,通道号和设备号使用不统一,有的外部算,有的内部算。为了方便配合海思动态检测前端分辨率,我们将线程代码抽取了出来,放在APP层,这个部分代码同时解决了好几个坑,自己看代码把,就不细说了,修改过的8路检测关键代码代码如下:

    while(1) {
        for(i=0; i<8 ;i++) {
            info.ch = i;
            ioctl(fd, IOC_VDEC_GET_INPUT_VIDEO_FMT, &info);
            usleep(200*1000);
            printf("ch:%d curvideofmt = %d prevideofmt=%d, curvideoloss=%d\n", i, info.curvideofmt[i],info.prevideofmt[i], info.curvideoloss[i]);
            if(info.curvideoloss[i] == VIDEO_LOSS_ON) {
                if(info.prevideofmt[i] != chFormats[i]) {
                        chmode.ch = i;
                        chmode.chmode = info.curvideofmt[i];
                        ioctl(fd, IOC_VDEC_SET_CHNMODE, &chmode);

                        mode.chipsel =i/4;
                        if((i%4) <2) {
                            mode.portsel  = 1;
                            mode.chid = 0;
                        }
                        else {
                            mode.portsel  = 2;
                            mode.chid = 1;
                        }
                        mode.portmode = NVP6158_OUTMODE_2MUX_FHD;
                        ioctl(fd, IOC_VDEC_SET_OUTPORTMODE, &mode);

                        info.prevideofmt[i] =  info.curvideofmt[i];
                        chFormats[i] = info.curvideofmt[i];
                        printf("set ch:%d into %d mode\n",i, chFormats[i]);

                        video_info.Ch = i%4;
                        video_info.devnum = i/4;
                        video_info.FmtDef = info.curvideofmt[i];
                        ioctl(fd, IOC_VDEC_GET_EQ_DIST, &video_info);

                        printf("APP get CH[%d] EQ stage is %d\n", i, video_info.distance);
                        ioctl(fd, IOC_VDEC_SET_EQUALIZER, &video_info);

                }
            }
            else {
                if(NC_VIVO_CH_FORMATDEF_UNKNOWN != chFormats[i]) {
                        chmode.ch = i;
                        chmode.chmode = NC_VIVO_CH_FORMATDEF_UNKNOWN;
                        ioctl(fd, IOC_VDEC_SET_CHNMODE, &chmode);
                        chFormats[i] = NC_VIVO_CH_FORMATDEF_UNKNOWN;
                        printf("========NC_VIVO_CH_FORMATDEF_UNKNOWN set ch:%d into %d mode\n",i, chFormats[i]);
                        mode.chipsel =i/4;
                        if((i%4) <2) {
                            mode.portsel  = 1;
                            mode.chid = 0;
                        }
                        else {
                            mode.portsel  = 2;
                            mode.chid = 1;
                        }
                        mode.portmode = NVP6158_OUTMODE_2MUX_FHD;
                        ioctl(fd, IOC_VDEC_SET_OUTPORTMODE, &mode);
                }               
            }

        }
        sleep(1);
    }

完整的代码下载地址:https://www.ebaina.com/resources/240000028628

声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
goodman
红包 6 7 评论 打赏
评论
3个
内容存在敏感词
手气红包
  • 素心aaa 2023-10-09 19:14:46
    回复
    大佬,新手刚注册没有积分下载不了,能给我免费发一份吗?3405180950@qq.com
  • fatcat 2023-05-23 09:08:30
    回复
    支持700TVL摄像机输入吗?
  • 追风Austin 2021-01-13 14:53:05
    回复

    最近在调试,头大,第一路只有2路视频,莫名中,参考下,谢谢!

相关专栏
关于作者
goodman

goodman

wooshang@126.com

原创18
阅读9w
收藏6
点赞23
评论12
打赏用户 1
我要创作
分享技术经验,可获取创作收益
分类专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
goodman
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
拼手气红包 红包规则
祝福语
恭喜发财,大吉大利!
红包金额
红包最小金额不能低于5元
红包数量
红包数量范围10~50个
余额支付
当前余额:
可前往问答、专栏板块获取收益 去获取
取 消 确 定

小包子的红包

恭喜发财,大吉大利

已领取20/40,共1.6元 红包规则

    易百纳技术社区