Hi3519AV100 适配IMX347

Hi3519AV100 适配IMX347 tomato 2024-01-08 17:24:15 423

前言

环境介绍:
1.编译环境
Ubuntu 18.04.5 LTS

2.SDK
Hi3519AV100_SDK_V2.0.1.0

3.单板
Hi3519AV100开发板
IMX347 2688x1520(4M)@30fps master mode i2c id 0x34

一、Sensor i2c寄存器读写

海思默认文件系统是有i2c读写工具的,可以使用这个工具先对Sensor 进行读写,看是否正常。具体操作可以参考我之前的文章。
海思I2C工具读取外设寄存器
不过能读写是sensor供电、复位、时钟能正常提供的情况下操作的,要是复位、时钟需要主芯片提供,还需要做具体寄存器配置,要是嫌麻烦可以跳过这一步。

二、Sensor模板

Hi3519AV100 SDK已经适配有sensor相关驱动例程,可以作为本次适配的模板。
Hi3519AV100_SDK_V2.0.1.0/smp/a53_linux/mpp/component/isp/user/sensor/hi3519av100/
根据海思提供的《Sensor 调试指南》,本次以imx334 8M作为模板,因为两者规格相对来说比较相似。

三、IMX347驱动文件修改

复制imx334文件夹,命名为imx347,并将里面的的文件都重命名为imx347,如下

依次将这4个文件内部imx334全部替换为imx347
其中
Makefile 用于生产sensor库
imx347_cmos.c 为底层驱动文件与上层运用的函数链接
imx347_cmos_ex.h 头文件
imx347_sensor_ctl.c sensor底层驱动
底层适配只要通过修改imx347_cmos.c imx347_sensor_ctl.c 这两个文件进行。

3.1 imx347_sensor_ctl.c

1.sensor i2c地址、地址位宽、数据位宽定义

const unsigned char imx347_i2c_addr     =    0x34;        /* I2C Address of imx347 */
const unsigned int  imx347_addr_byte    =    2;
const unsigned int  imx347_data_byte    =    1;

我这里都跟原来一直,不做改动。

2.sensor初始化模式选择
原先sensor定义了两种功能,通过传入的参数修改,本次适配就只使用一种,另外的就不出修改
imx347_8M_30FPS_12BIT_LINEAR_MODE

...
#define imx347_4M_30FPS_12BIT_LINEAR_MODE      (1)
#define imx347_4M_30FPS_12BIT_2t1_DOL_MODE     (2)
...
void imx347_linear_4M30_12bit_init(VI_PIPE ViPipe);
void imx347_DOL_2t1_4M30_12bit_init(VI_PIPE ViPipe);
...
3.2 imx347_sensor_ctl.c

这文件要修改的不多,主要是sdk的函数调用,并且之前已经进行了全局替换。我这里就只修改了相关函数的命名、ID和分辨率的修改。

...
#define imx347_ID 347
...
//sensor fps mode
#define imx347_4M_30FPS_12BIT_LINEAR_MODE      (1) /* 4M@30fps Linear 12bit*/
#define imx347_4M_30FPS_12BIT_2t1_DOL_MODE     (2)

#define imx347_RES_IS_4M30_12BIT(w, h)    ((2688 == (w)) && (1520 == (h)))

至此imx347底层驱动修改差不多了。

四、添加SENSOR_TYPE

在mpp/sample/Makefile.param添加SENSOR_TYPE,并添加对应的 libsns_xxx.a文件
我这里只有1个sensor,所以修改SENSOR0_TYPE。

################# select sensor type for your sample ###############################
####    SONY_IMX290_MIPI_2M_30FPS_12BIT            #################
####    SONY_IMX290_SLAVE_MIPI_2M_60FPS_10BIT      #################
####    SONY_IMX334_MIPI_8M_30FPS_12BIT            #################
####    NVP6324_MIPI_2M_30FPS_8BIT                 #################
####    SONY_IMX347_MIPI_4M_30FPS_12BIT            #################

SENSOR0_TYPE ?= SONY_IMX347_MIPI_4M_30FPS_12BIT
SENSOR1_TYPE ?= SONY_IMX290_SLAVE_MIPI_2M_60FPS_10BIT
SENSOR2_TYPE ?= SONY_IMX290_SLAVE_MIPI_2M_60FPS_10BIT
SENSOR3_TYPE ?= SONY_IMX290_SLAVE_MIPI_2M_60FPS_10BIT
SENSOR4_TYPE ?= SONY_IMX334_MIPI_8M_30FPS_12BIT

...
SENSOR_LIBS += $(REL_LIB)/libsns_imx290.a
SENSOR_LIBS += $(REL_LIB)/libsns_imx290_slave.a
SENSOR_LIBS += $(REL_LIB)/libsns_imx334.a
SENSOR_LIBS += $(REL_LIB)/libsns_imx347.a

在mpp/sample/common/sample_comm.h添加宏,该宏要与上面的SENSOR0_TYPE一致

typedef enum hiSAMPLE_SNS_TYPE_E
{
    SONY_IMX290_MIPI_2M_30FPS_12BIT,
    SONY_IMX290_MIPI_2M_30FPS_12BIT_WDR2TO1,
    SONY_IMX290_SLAVE_MIPI_2M_60FPS_10BIT,
    SONY_IMX334_MIPI_8M_30FPS_12BIT,
    SONY_IMX334_MIPI_8M_30FPS_12BIT_WDR2TO1,
    SONY_IMX377_MIPI_8M_30FPS_10BIT,
    SONY_IMX347_MIPI_4M_30FPS_12BIT,
    NVP6324_MIPI_2M_30FPS_8BIT,
    SAMPLE_SNS_TYPE_BUTT,
} SAMPLE_SNS_TYPE_E;

五、sample_comm_vi.c修改

5.1 SAMPLE_COMM_VI_GetSizeBySensor

新加一个case

case SONY_IMX347_MIPI_4M_30FPS_12BIT:
    *penSize = PIC_2688x1520;
    break;

因为PIC_2688x1520没有定义,所以需要在mpp/sample/common/sample_comm.h添加一个枚举如下

typedef enum hiPIC_SIZE_E
{
    PIC_CIF,
    PIC_D1_PAL,    /* 720 * 576 */
    PIC_D1_NTSC,   /* 720 * 480 */
    PIC_720P,       /* 1280 * 720  */
    PIC_1080P,       /* 1920 * 1080 */
    PIC_2592x1520,
    PIC_2592x1944,
    PIC_3840x2160,
    PIC_4096x2160,
    PIC_3000x3000,
    PIC_4000x3000,
    PIC_7680x4320,
    PIC_3840x8640,
    PIC_2688x1520,    
    PIC_BUTT
} PIC_SIZE_E;
5.2 SAMPLE_COMM_VI_GetFrameRateBySensor

新加一个case
因为我这里是30fps,直接添加即可。

switch (enMode)
{
    case SONY_IMX290_MIPI_2M_30FPS_12BIT:
    case SONY_IMX290_MIPI_2M_30FPS_12BIT_WDR2TO1:
    case SONY_IMX334_MIPI_8M_30FPS_12BIT:
    case SONY_IMX334_MIPI_8M_30FPS_12BIT_WDR2TO1:
    case SONY_IMX377_MIPI_8M_30FPS_10BIT:
    case SONY_IMX347_MIPI_4M_30FPS_12BIT:
        *pu32FrameRate = 30;
        break;

    default:
        *pu32FrameRate = 30;
        break;

}
5.3 SAMPLE_COMM_VI_GetChnAttrBySns

新加一个case

case SONY_IMX347_MIPI_4M_30FPS_12BIT:
    hi_memcpy(pstChnAttr, sizeof(VI_CHN_ATTR_S), &CHN_ATTR_2688x1520_420_SDR8_LINEAR, sizeof(VI_CHN_ATTR_S));
    break;

根据其他参数添加CHN_ATTR_2688x1520_420_SDR8_LINEAR结构体

VI_CHN_ATTR_S CHN_ATTR_2688x1520_420_SDR8_LINEAR =
{
    {2688, 1520},
    PIXEL_FORMAT_YVU_SEMIPLANAR_420,
    DYNAMIC_RANGE_SDR8,
    VIDEO_FORMAT_LINEAR,
    COMPRESS_MODE_NONE,
    0,      0,
    0,
    { -1, -1}
};
5.4 SAMPLE_COMM_VI_GetPipeAttrBySns

新加一个case

case SONY_IMX347_MIPI_4M_30FPS_12BIT:
    hi_memcpy(pstPipeAttr, sizeof(VI_PIPE_ATTR_S), &PIPE_ATTR_2688x1520_RAW12_420_3DNR_RFR, sizeof(VI_PIPE_ATTR_S));
    break;

根据其他参数添加PIPE_ATTR_2688x1520_RAW12_420_3DNR_RFR结构体

VI_PIPE_ATTR_S PIPE_ATTR_2688x1520_RAW12_420_3DNR_RFR =
{
    VI_PIPE_BYPASS_NONE, HI_FALSE,HI_FALSE,
    2688, 1520,
    PIXEL_FORMAT_RGB_BAYER_12BPP,
    COMPRESS_MODE_LINE,
    DATA_BITWIDTH_12,
    HI_TRUE,
    {
        PIXEL_FORMAT_YVU_SEMIPLANAR_420,
        DATA_BITWIDTH_8,
        VI_NR_REF_FROM_RFR,
        COMPRESS_MODE_NONE
    },
    HI_FALSE,
    { -1, -1}
};
5.5 SAMPLE_COMM_VI_GetDevAttrBySns

新加一个case

case SONY_IMX347_MIPI_4M_30FPS_12BIT:
    hi_memcpy(pstViDevAttr, sizeof(VI_DEV_ATTR_S), &DEV_ATTR_IMX347_4M_BASE, sizeof(VI_DEV_ATTR_S));
    break;

根据其他参数添加DEV_ATTR_IMX347_4M_BASE 结构体

VI_DEV_ATTR_S DEV_ATTR_IMX347_4M_BASE =
{
    VI_MODE_MIPI,
    VI_WORK_MODE_1Multiplex,
    {0xFFF00000,    0x0},
    VI_SCAN_PROGRESSIVE,
    {-1, -1, -1, -1},
    VI_DATA_SEQ_YUYV,

    {
    /*port_vsync   port_vsync_neg     port_hsync        port_hsync_neg        */
    VI_VSYNC_PULSE, VI_VSYNC_NEG_LOW, VI_HSYNC_VALID_SINGNAL,VI_HSYNC_NEG_HIGH,VI_VSYNC_VALID_SINGAL,VI_VSYNC_VALID_NEG_HIGH,

    /*hsync_hfb    hsync_act    hsync_hhb*/
    {0,            1280,        0,
    /*vsync0_vhb vsync0_act vsync0_hhb*/
     0,            1520,        0,
    /*vsync1_vhb vsync1_act vsync1_hhb*/
     0,            0,            0}
    },
    VI_DATA_TYPE_RGB,
    HI_FALSE,
    {2688 , 1520},
    {
        {
            {2688 , 1520},
        },
        {
            VI_REPHASE_MODE_NONE,
            VI_REPHASE_MODE_NONE
        }
    },
    {
        WDR_MODE_NONE,
        2160
    },
    DATA_RATE_X1
};
5.6 SAMPLE_COMM_VI_GetComboAttrBySns

新加一个case

case SONY_IMX347_MIPI_4M_30FPS_12BIT:
     hi_memcpy(pstComboAttr, sizeof(combo_dev_attr_t), &MIPI_4lane_CHN0_SENSOR_IMX347_12BIT_4M_NOWDR_ATTR, sizeof(combo_dev_attr_t));
     break;

根据其他参数添加MIPI_4lane_CHN0_SENSOR_IMX347_12BIT_4M_NOWDR_ATTR结构体

combo_dev_attr_t MIPI_4lane_CHN0_SENSOR_IMX347_12BIT_4M_NOWDR_ATTR =
{
    .devno = 0,
    .input_mode = INPUT_MODE_MIPI,
    .data_rate = MIPI_DATA_RATE_X1,
    .img_rect = {0, 0, 2688, 1520},

    {
        .mipi_attr =
        {
            DATA_TYPE_RAW_12BIT,
            HI_MIPI_WDR_MODE_NONE,
            {0, 1, 2, 3, -1, -1, -1, -1}
        }
    }
};

以上是对mpp/sample/common/sample_comm_vi.c的修改,接下来修改mpp/sample/common/sample_comm_isp.c

六、sample_comm_isp.c修改

6.1 SAMPLE_COMM_ISP_GetSnsObj

新加一个case

case SONY_IMX347_MIPI_4M_30FPS_12BIT:
    return &stSnsimx347Obj;

在mpp/include/hi_sns_ctrl.h添加obj。

...
extern ISP_SNS_OBJ_S stSnsImx334SlaveObj;
extern ISP_SNS_OBJ_S stSnsImx226Obj;
extern ISP_SNS_OBJ_S stSnsImx335Obj;
extern ISP_SNS_OBJ_S stSnsImx458Obj;
extern ISP_SNS_OBJ_S stSnsOv2735Obj;
extern ISP_SNS_OBJ_S stSnsimx347Obj;

此obj要与mpp/component/isp/user/sensor/hi3519av100/sony_imx347/imx347_cmos.c里面的obj一直

ISP_SNS_OBJ_S stSnsimx347Obj =
{
    .pfnRegisterCallback    = sensor_register_callback,
    .pfnUnRegisterCallback  = sensor_unregister_callback,
    .pfnStandby             = imx347_standby,
    .pfnRestart             = imx347_restart,
    .pfnMirrorFlip          = HI_NULL,
    .pfnWriteReg            = imx347_write_register,
    .pfnReadReg             = imx347_read_register,
    .pfnSetBusInfo          = imx347_set_bus_info,
    .pfnSetInit             = sensor_set_init
};
6.2 SAMPLE_COMM_ISP_GetIspAttrBySns

新加一个case

case SONY_IMX347_MIPI_4M_30FPS_12BIT:
    memcpy(pstPubAttr, &ISP_PUB_ATTR_IMX347_4M_30FPS, sizeof(ISP_PUB_ATTR_S));
    break;

在mpp/include/hi_sns_ctrl.h添加obj。

...
extern ISP_SNS_OBJ_S stSnsImx334SlaveObj;
extern ISP_SNS_OBJ_S stSnsImx226Obj;
extern ISP_SNS_OBJ_S stSnsImx335Obj;
extern ISP_SNS_OBJ_S stSnsImx458Obj;
extern ISP_SNS_OBJ_S stSnsOv2735Obj;
extern ISP_SNS_OBJ_S stSnsimx347Obj;

根据其他参数添加ISP_PUB_ATTR_IMX347_4M_30FPS 结构体

ISP_PUB_ATTR_S ISP_PUB_ATTR_IMX347_4M_30FPS =
{
    {0, 0, 2688, 1520},
    {2688, 1520},
    30,
    BAYER_RGGB,
    WDR_MODE_NONE,
    0,
};

以上对于mpp的修改完成了,可以在sample目录进行make编译,可以在mpp/lib文件夹里面生成相关的xxx.o、xxx.a文件。

七、sys_config.c修改

文件 drv/interdrv/sysconfig/sys_config.c主要是进行sensor复位、时钟、i2c和行场同步信号复用配置。

7.1 sensor列表名称修改

我这边把所有都修改为imx347

static char sensor_list[SENSOR_LIST_CMDLINE_LEN]= "sns0=imx347,sns1=imx347,sns2=imx347,sns3=imx347,sns4=imx347";

module_param(g_bt1120_flag, int, S_IRUGO);

module_param_string(sensors, sensor_list, SENSOR_LIST_CMDLINE_LEN, 0600);

MODULE_PARM_DESC(sensors,"sns0=imx347,sns1=imx347,sns2=imx347,sns3=imx347,sns4=imx347");
7.2 clock

sensor clock为24M,这里直接添加即可。

if ( (0 == strncmp("imx377", name, len))
      || (0 == strncmp("imx334", name, len))
      || (0 == strncmp("imx477", name, len))
      || (0 == strncmp("imx299", name, len))
      || (0 == strncmp("imx347", name, len))
      || (0 == strncmp("cmv50000", name, len)))
 {
     clock = 0x4;
 }

数值对应多少频率有备注说明

/*
0x0: 74.25MHz; 0x1: 72MHz;0x2: 54MHz;0x3: 50MHz;0x4: 24MHz;0x6: 32.4MHz;
0x8: 37.125MHz;0x9: 36MHz;0xA: 27MHz;0xB: 25MHz;0xC: 12MHz;
*/
7.3 BUS_TYPE

imx347为i2c,这里直接添加即可。

if (   (0 == strncmp("imx377", name, len))
    || (0 == strncmp("imx334", name, len))
    || (0 == strncmp("imx477", name, len))
    || (0 == strncmp("imx290", name, len))
    || (0 == strncmp("imx290_slave", name, len))
    || (0 == strncmp("imx299", name, len))
    || (0 == strncmp("imx347", name, len))
    || (0 == strncmp("imx117", name, len)))
{
    bus_type = BUS_TYPE_I2C;
}

以上修改完之后在drv/interdrv/sysconfig路径下make重新生成sys_config.ko

八、上板测试

上述修改完之后,可以根据我之前其他文章进行测试。

声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
tomato
红包 点赞 收藏 评论 打赏
评论
0个
内容存在敏感词
手气红包
    易百纳技术社区暂无数据
相关专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
tomato
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

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

举报反馈

举报类型

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

详细说明

审核成功

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

审核失败

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

小包子的红包

恭喜发财,大吉大利

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

    易百纳技术社区