美文网首页
MTK pdaf bring up

MTK pdaf bring up

作者: 窝窝蜗牛 | 来源:发表于2021-09-12 11:28 被阅读0次

    一、开发环境

    平台:mt6833

    主摄sensor: s5kjn1sq

    模组厂:qtech

    马达:dw9800

    二、前期准备工作

    1. 在MOL上download 官方bring up文档,01_02_Driver_Check-PDAF_Driver_Porting_Guide_release_V1.4.pdf(最新).
    2. 问模组厂提供.ini文档,该文档记录了pdaf的相关参数,我们参考该文档配置sensor驱动
    3. OTP map,需要确认otp烧录了af和pdaf的数据
    4. 问sensor原厂提供pdaf PDMAP guide文档,该文档记录了PD Tail数据的存储格式,后续做pd buf的L,R分离时需要参考该文档
    5. pd_s5kjn1sqmipiraw.cpp文件,如果有现成的就问供应商拿现成的,如果没有则需要自己coding

    三、前期需确认事项

    1. 确认af是正常工作的,找相关bringup人员确认或在main log中搜索关键字"MoveLensTo"

    image.png

    2. 确认otp数据读取正常,日志搜索关键字"CamCalCamCal"

    09-08 03:39:48.696 12049 31376 D CamCalCamCal: ver0923 ======================AWB CAM_CAL==================
    09-08 03:39:48.696 12049 31376 D CamCalHelper: CamCalHelper Read data from memory[0]
    09-08 03:39:48.696 12049 31413 D IspDrv_CAM: IspDrv_CAM[CQ_Allocate_method1] [0x0][21_0]:virtIspAddr:virt[0x79eb9e3000]/phy[0x2fcb90000]
    09-08 03:39:48.696 12049 31376 D CamCalHelper: CamCalHelper Read data from memory[0]
    09-08 03:39:48.696 12049 31414 D awb_mgr : [AWBInit()][AI NVRAM] AISAindex(0) revision(0) enable(0) , AIMAindex(0) revision(0) enable(0) [AWB NVRAM] index(1), SEGenable(0) SEGisothr(0) SEGcnt(0), E2Eenable(0) E2Eisothr(0) E2Ecnt(0)
    09-08 03:39:48.696 12049 31376 D CamCalCamCal: ver0923 ======================AF CAM_CAL==================
    09-08 03:39:48.696 12049 31376 D CamCalCamCal: ver0923 [AF] Inf=488 Marco=758
    09-08 03:39:48.696 12049 31376 D CamCalCamCal: ver0923 ======================AF CAM_CAL==================

    pdaf的数据我们需要看解析后的数据,porting的时候确认,需要确保pdaf是support状态,然后搜索关键字"parseStep3"


    image.png

    确保otp数据跟模组厂提供的ini文档中的参数应该是一致的。

    3. 找sensor vendor确认pdaf type


    image.png

    4. 确认mirror filp

    1.确认模组厂ini文档中烧录坐标点是否mirrorfilp

    2. 确认preview(pdaf的使用场景)出图的mirrorflip

    如果preview方向与模组厂烧录方向一致,则imgsensor_pd_info.iMirrorFlip = 0,如果preview方向为mirrorflip,模组厂烧录方向为normal,则imgsensor_pd_info.iMirrorFlip = 3,这块最好找供应商确认。

    四、对应pd type走官方文档porting工作

    五、debug问题

    1.检索关键字"SensorModeSupport("

    image.png
    发现BufType为0(NOTDEF),需要走查代码vendor/mediatek/proprietary/hardware/mtkcam/aaa/source/isp_6s/af_assist_mgr/af_assist_mgr.cpp的AFAssisMgr::config实现: image.png

    看实际走了哪条else分支导致的BufType为0,

    如果打印"Instance is not ready"表示pd_s5kjn1sqmipiraw.cpp中IsSupport函数返回值为false

    如果打印"set PD calibration and tuning data fail"表示未成功设置好校准数据,可能是由于otp未导通

    2. pd_s5kjn1sqmipiraw.cpp文件中ConvertPDBufFormat修改。当camsv收到sensor传输过来的tail数据后,经过ConvertPDBufFormat函数转换,生成一张pd L,R组成的raw图。

    抓取转换后的图片如下:


    image.png image.png

    转换后的图像上下应该是亮度一致,并且图案相同的。拍摄的pd图并不是跟原图案一样的,会有拉伸效果,因为pd的tail数据只是部分raw点,如上图,单看L的tail点,X方向是每2个像素取一个pd点,Y方向上是每8个像素取一个pd点,所以pd tail buf可看作是部分typical pixel组成的图,由于XY方向取点数量不同,会造成图像有拉伸的效果,这是正常的。

    MUINT16* PD_S5KJN1SQMIPIRAW::ConvertPDBufFormat( MUINT32 /*i4Size*/, MUINT32 i4Stride, MUINT8 *ptrBufAddr, MUINT32 u4BitDepth, PD_AREA_T* /*ptrPDRegion*/)
    {
    if (m_eBufType == EPDBUF_VC) {
    MUINT32 xSz = m_PDXSz ; // pixel
    MUINT32 ySz = m_PDYSz ; // line
    MUINT16 **ptr = NULL;
    MUINT16 *ptrL = m_PDBuf;
    MUINT16 *ptrR =m_PDBuf + m_PDBufSz/2 ;
    MUINT32 xSzInByte = xSz * 10 / 8;
    MUINT32 i, j;
    
    AAA_LOGE("----------------------k19a------ConvertPDBufFormat------");
    
    #if NEON_OPT
    MUINT8 ucTbl0[5][8] = { { 4,0,1,2,3,5,6,7 },{ 0,1,6,2,3,4,5,7 },{ 0,1,2,3,4,5,6,7 },{ 1,2,3,4,0,5,6,7 },{ 0,1,3,4,5,6,2,7 } };
    MUINT8 ucTbl1[2][8] = { { 0,9,10,19,0xFF,0xFF,0xFF,0xFF } ,{ 0xFF,0xFF,0xFF,0xFF,4,5,14,15 } };
    MUINT8 ucTblShfit[16] = { 6,4,2,0, 6,4,2,0, 6,4,2,0, 6,4,2,0 };
    
    uint8x8_t vu1x8Tbl0_0 = vld1_u8(ucTbl0[0]);
    uint8x8_t vu1x8Tbl0_1 = vld1_u8(ucTbl0[1]);
    uint8x8_t vu1x8Tbl0_3 = vld1_u8(ucTbl0[3]);
    uint8x8_t vu1x8Tbl0_4 = vld1_u8(ucTbl0[4]);
    
    uint8x8_t vu1x8Tbl1_0 = vld1_u8(ucTbl1[0]);
    uint8x8_t vu1x8Tbl1_1 = vld1_u8(ucTbl1[1]);
    
    uint8x16_t vu1x16TblShift = vld1q_u8(ucTblShfit);
    #endif
    
    for( j=0; j<ySz; j++)
    {
    MUINT32 idx = j * i4Stride;//Stride=width from raw file
    
    if (j % 2 == 1)
    ptr = &ptrL;
    else
    ptr = &ptrR;
    i = 0;
    #if NEON_OPT
    unsigned char *ptr_src = (unsigned char *)(ptrBufAddr + idx);
    
    uint8x8x3_t vu1x8x3Buf0;
    uint8x8x2_t vu1x8x2Buf1, vu1x8x2TmpBuf;
    uint8x8_t vu1x8LL, vu1x8LH, vu1x8HL, vu1x8HH, vu1x8LSB;
    uint16x8_t vu2x8x1Buf3;
    uint16x8_t vu2x8x1Buf4;
    
    //uint16x8x2_t vu2x8x2Buf5;
    
    uint8x16_t vu1x16Low2BitL, vu1x16Low2BitH;
    
    for (; i <= xSzInByte - 40; i += 40, (*ptr) += 32, ptr_src += 40)
    {
    //if(j == 0)
    // AAA_LOGD("ConvertPDBufFormat with neon");
    
    //Step.1 Loading data from memory to register
    vu1x8x3Buf0.val[0] = vld1_u8(ptr_src); //[M0 0, N0 1, M1 2, N1 3, D01 4, M2 5, N2 6, M3 7]
    vu1x8x3Buf0.val[1] = vld1_u8(ptr_src + 8); //[N3 8, D23 9, M4 10, N4 11, M5 12, N5 13, D45 14, M6 15]
    vu1x8x3Buf0.val[2] = vld1_u8(ptr_src + 16); //[N6 16, M7 17, N7 18, D67 19, M8 20, N8 21, M9 22, N9 23]
    vu1x8x2Buf1.val[0] = vld1_u8(ptr_src + 24); //[D89 24, M10 25, N10 26, M11 27, N11 28, D1011 29, M12 30, N12 31]
    vu1x8x2Buf1.val[1] = vld1_u8(ptr_src + 32); //[M13 32, N13 33, D1213 34, M14 35, N14 36, M15 37, N15 38, D1415 39]
    
    vu1x8x3Buf0.val[0] = vtbl1_u8(vu1x8x3Buf0.val[0], vu1x8Tbl0_0); //[D01 4, 0, 1, 2, 3, 5, 6, 7]
    vu1x8x3Buf0.val[1] = vtbl1_u8(vu1x8x3Buf0.val[1], vu1x8Tbl0_1); //[ 8,D23 9,D45 14, 10, 11, 12, 13, 15]
    //vu1x8x3Buf0.val[2] [ 16, 17, 18,D67 19, 20, 21, 22, 23]
    vu1x8x2Buf1.val[0] = vtbl1_u8(vu1x8x2Buf1.val[0], vu1x8Tbl0_3); //[ 25, 26, 27, 28,D89 24,D1011 29, 30, 31]
    vu1x8x2Buf1.val[1] = vtbl1_u8(vu1x8x2Buf1.val[1], vu1x8Tbl0_4); //[ 32, 33, 35, 36, 37, 38,D1213 34,D1415 39]
    
    //Step.2 Separate the upper 8-bit data
    vu1x8LL = vext_u8(vu1x8x3Buf0.val[0], vu1x8x3Buf0.val[1], 1); //[M0 0,N0 1,M1 2,N1 3,M2 5,N2 6,M3 7,N3 8]
    vu1x8LH = vext_u8(vu1x8x3Buf0.val[1], vu1x8x3Buf0.val[2], 3); //[M4 10,N4 11,M5 12,N5 13,M6 15,N6 16,M7 17,N7 18]
    vu1x8HL = vext_u8(vu1x8x3Buf0.val[2], vu1x8x2Buf1.val[0], 4); //[M8 20,N8 21,M9 22,N9 23,M10 25,N10 26,M11 27,N11 28]
    vu1x8HH = vext_u8(vu1x8x2Buf1.val[0], vu1x8x2Buf1.val[1], 6); //[M12 30,N12 31,M13 32,N13 33,M14 35,N14 36,M15 37,N15 38]
    
    //Step.3 Separate the lower 2-bit data
    // [4,9,14,19, 24,29,34,39] == [D01,D23,D45,D67,D89,D1011,D1213,D1415]
    vu1x8LSB = vorr_u8(vtbl3_u8(vu1x8x3Buf0, vu1x8Tbl1_0), vtbl2_u8(vu1x8x2Buf1, vu1x8Tbl1_1));
    // [D01,D23,D45,D67,D89,D1011,D1213,D1415] => val[0]: [D01,D01, D23,D23, D45,D45, D67,D67], val[1]: [D89,D89, D1011,D1011, D1213,D1213, D1415,D1415]
    vu1x8x2Buf1 = vzip_u8(vu1x8LSB, vu1x8LSB);
    
    // Low: [D01,D01, D23,D23, D45,D45, D67,D67]
    // => val[0]: [D01,D01,D01,D01, D23,D23,D23,D23], val[1]: [D45,D45,D45,D45, D67,D67,D67,D67]
    vu1x8x2TmpBuf = vzip_u8(vu1x8x2Buf1.val[0], vu1x8x2Buf1.val[0]);
    // [(D01<<6)>>6, (D01<<4)>>6, (D01<<2)>>6, (D01<<0)>>6, (D23<<6)>>6 ,(D23<<4)>>6,(D23<<2)>>6,(D23<<0)>>6,
    // (D45<<6)>>6, (D45<<4)>>6, (D45<<2)>>6, (D45<<0)>>6, (D67<<6)>>6 ,(D67<<4)>>6,(D67<<2)>>6,(D67<<0)>>6]
    vu1x16Low2BitL = vshrq_n_u8(vshlq_u8(vcombine_u8(vu1x8x2TmpBuf.val[0], vu1x8x2TmpBuf.val[1]), vu1x16TblShift), 6);
    
    // High: [D89,D89, D1011,D1011, D1213,D1213, D1415,D1415]
    // Same as low
    vu1x8x2TmpBuf = vzip_u8(vu1x8x2Buf1.val[1], vu1x8x2Buf1.val[1]);
    vu1x16Low2BitH = vshrq_n_u8(vshlq_u8(vcombine_u8(vu1x8x2TmpBuf.val[0], vu1x8x2TmpBuf.val[1]), vu1x16TblShift), 6);
    
    //Step.4 upper 8-bit data + lower 2-bit data
    vu2x8x1Buf3 = vorrq_u16(vshlq_n_u16(vmovl_u8(vu1x8LL), 2), vmovl_u8(vget_low_u8(vu1x16Low2BitL))); //[M0,N0,M1,N1,M2,N2,M3,N3]
    vu2x8x1Buf4 = vorrq_u16(vshlq_n_u16(vmovl_u8(vu1x8LH), 2), vmovl_u8(vget_high_u8(vu1x16Low2BitL))); //[M4,N4,M5,N5,M6,N6,M7,N7]
    
    // unzip MNMNMNMN data => val[0]: [M0,M1,M2,M3,M4,M5,M6,M7] val[1]: [N0,N1,N2,N3,N4,N5,N6,N7]
    //vu2x8x2Buf5 = vuzpq_u16(vu2x8x1Buf3, vu2x8x1Buf4);
    
    vst1q_u16((*ptr), vu2x8x1Buf3);
    vst1q_u16((*ptr) + 8, vu2x8x1Buf4);
    
    vu2x8x1Buf3 = vorrq_u16(vshlq_n_u16(vmovl_u8(vu1x8HL), 2), vmovl_u8(vget_low_u8(vu1x16Low2BitH))); //[M8,N8,M9,N9,M10,N10,M11,N11]
    vu2x8x1Buf4 = vorrq_u16(vshlq_n_u16(vmovl_u8(vu1x8HH), 2), vmovl_u8(vget_high_u8(vu1x16Low2BitH)));//[M12,N12,M13,N13,M14,N14,M15,N15]
    
    // unzip MNMNMNMN data => val[0]: [M8,M9,M10,M11,M12,M13,M14,M15] val[1]: [N8,N9,N10,N11,N12,N13,N14,N15]
    //vu2x8x2Buf5 = vuzpq_u16(vu2x8x1Buf3, vu2x8x1Buf4);
    
    vst1q_u16((*ptr) + 16, vu2x8x1Buf3);
    vst1q_u16((*ptr) + 24, vu2x8x1Buf4);
    }
    #endif
    for(;i<xSzInByte;i+=5)
    {
    char val0 = ptrBufAddr[ idx + (i )];
    char val1 = ptrBufAddr[ idx + (i+1)];
    char val2 = ptrBufAddr[ idx + (i+2)];
    char val3 = ptrBufAddr[ idx + (i+3)];
    char val4 = ptrBufAddr[ idx + (i+4)];
    
    if(j%2==1)
    {
    *ptrL++ =((val0 << 2)&0x3FC) | ((val4 >> 0) & 0x3);
    *ptrL++ =((val1 << 2)&0x3FC) | ((val4 >> 2) & 0x3);
    *ptrL++ =((val2 << 2)&0x3FC) | ((val4 >> 4) & 0x3);
    *ptrL++ =((val3 << 2)&0x3FC) | ((val4 >> 6) & 0x3);
    }
    else
    {
    *ptrR++ =((val0 << 2)&0x3FC) | ((val4 >> 0) & 0x3);
    *ptrR++ =((val1 << 2)&0x3FC) | ((val4 >> 2) & 0x3);
    *ptrR++ =((val2 << 2)&0x3FC) | ((val4 >> 4) & 0x3);
    *ptrR++ =((val3 << 2)&0x3FC) | ((val4 >> 6) & 0x3);
    }
    }
    }
    //ALOGD("m_PDBufSz %d, Stride %d\n", m_PDBufSz, i4Stride);
    }
    else
    {
    m_PDBuf = NULL;
    }
    return m_PDBuf;
    }
    

    NEON_OPT宏开启后有节省功耗的作用,为便于分析,可以只看NEON_OPT未定义情况。函数的主要功能有两个,一个是将原始的raw数据由原先的10bit存储转换为2byte存储,第二个是将L跟R的buf分开存储,需要注意的是DT=0x2b时L在前R在后,DT/=0x2b时R在前L在后。

    image.png

    ptrBufAddr即是tail数据的buffer地址,mode3下,sensor输出binning的预览数据,vc传输tail数据,所以tail数据的提取已经在sensor端做好了。

    image.png

    i4Stride表示tail一行数据的字节数,因为存在字节对齐,所以实际存储长度比xSzInByte大,buffer的偏移量计算应以实际为准。

    image.png

    3.曲线拉取线性度异常

    拉取曲线步骤:

    1.下载好菱形图并打印

    2. 下载录入数据的表格

    3. 读取otp中af的远近焦值,得出镜头手动停留的位置

    4. 按指令跑一遍fullscan,然后求peak平均值

    5. 再手动推动镜头到上述计算位置,抓取日志

    6. 搜索关键字”handleAFS“

    image.png

    依次录入block0-8的数据,算法将图像分割为九块区域,分别计算相位差值,录入pd值需要*1000.

    相关文章

      网友评论

          本文标题:MTK pdaf bring up

          本文链接:https://www.haomeiwen.com/subject/sfozwltx.html