diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..e1b8c1b --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,26 @@ +{ + // 使用 IntelliSense 了解相关属性。 + // 悬停以查看现有属性的描述。 + // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + "name": "gdb 启动", + "type": "cppdbg", + "request": "launch", + "program": "/home/nihao/w2T/axera/StackFlow/projects/test_kit_demo3/dist/test_kit_demo3", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "miDebuggerPath": "/opt/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-gdb", + "miDebuggerServerAddress": "localhost:1234", + "environment": [], + "externalConsole": true, + "MIMode": "gdb", + "setupCommands":[{ + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }] + + ] +} \ No newline at end of file diff --git a/README_zh.md b/README_zh.md index c7cd7ef..2b62fa2 100644 --- a/README_zh.md +++ b/README_zh.md @@ -1,100 +1,93 @@ -# Module-LLM +# StackFlow -
+

basic

-## 描述 -**Module LLM**是一款集成化的离线大语言模型 (LLM) 推理模块,专为需要高效,智能交互的终端设备设计,无论是在智能家居,语音助手,还是在工业控制中,Module LLM 都能为您带来流畅,自然的 AI 体验,无需依赖云端,确保隐私安全与稳定性。集成 **StackFlow** 框架,配合 **Arduino/UiFlow** 库,几行代码就可轻松实现端侧智能。
-搭载爱芯 **AX630C** SoC 先进处理器,集成 3.2 TOPs 高能效 NPU,原生支持 Transformer 模型,轻松应对复杂 AI 任务。配备 **4GB LPDDR4** 内存(其中1GB供用户使用,3GB专用于硬件加速)和**32GB eMMC**存储,支持多模型并行加载与串联推理,确保多任务处理流畅无阻。运行功耗仅约 1.5W,远低于同类产品,节能高效,适合长时间运行。
-集成麦克风,扬声器,TF存储卡,**USB OTG** 及 RGB状态灯,满足多样化应用需求,轻松实现语音交互与数据传输。灵活扩展:板载 SD 卡槽支持固件冷/热升级,**UART** 通信接口简化连接与调试,确保模块功能持续优化与扩展。USB 口支持主从自动切换,既可以做调试口,也可以外接更多 USB 设备如摄像头。搭配 LLM 调试套件,用于扩展百兆以太网口,及内核串口,作为 SBC 使用。
-多模型兼容,出厂预装 **Qwen2.5-0.5B** 大语言模型,内置**KWS**(唤醒词),**ASR**(语音识别),**LLM**(大语言模型)及**TTS**(文本转语音)功能,且支持分开调用或 **pipeline** 自动流转,方便开发。后续将支持Qwen2.5-1.5B、Llama3.2-1B及InternVL2-1B等多种端侧LLM/VLM模型,支持热更新模型,紧跟社区潮流,适应不同复杂度的AI任务;视觉识别能力:支持CLIP、YoloWorld等Open world模型,未来将持续更新DepthAnything、SegmentAnything等先进模型,赋能智能识别与分析;
-即插即用,搭配**M5主机**,Module LLM 实现即插即用的AI交互体验。用户无需繁琐设置,即可将其集成到现有智能设备中,快速启用智能化功能,提升设备智能水平。该产品适用于离线语音助手,文本语音转换,智能家居控制,互动机器人等领域。 +

+ StackFlow 是一个简单、疾速、优雅的面向嵌入式开发者一站式 AI 服务基础设施项目,目的是让 Maker 和 Haker 们能够快速的在当前的嵌入式设备中获取到强大的 AI 加速能力。StackFlow 能够为各类人机交互设备注入智慧的灵魂。 +

+ +

+ +

+## Table of Contents -## 产品特性 - -- 离线推理,3.2T@INT8精度算力 - -- 集成KWS(唤醒词),ASR(语音识别),LLM(大语言模型),TTS(文本生成语音) - -- 多模型并行 - -- 板载32GB eMMC存储和4GB LPDDR4内存 - -- 板载麦克风及扬声器 - -- 串口通信 - -- SD卡固件升级 - -- 支持ADB调试 - -- RGB提示灯 - -- 内置ubuntu系统 - -- 支持OTG功能 - -- 支持Arduino/UIFlow - - +* [特性](#特性) +* [Demo](#demo) +* [环境要求](#环境要求) +* [安装](#安装) +* [升级](#升级) +* [运行](#运行) +* [配置](#配置) +* [API接口](#api-接口) +* [贡献](#贡献) -## 应用 +## 特性 +![](doc/assets/network.png) +* 分布式通信架构。每个单元都能够单独工作或者和其他单元配合工作。 +* 多模型支持。包括但不限于语音识别、语音合成、图像识别、自然语言处理、LLM 大模型助手推理等。 +* 数据内部流转。可根据需求配置不同单元协同工作,避免复杂的数据处理流程。 +* 简单易用。通过标准 json 交换数据,快速实现 AI 服务。 +* 离线化运行。无需联网即可实现本地 AI 服务。 +* 多平台支持。包括但不限于 Module LLM、LLM630 Compute Kit 等。 +* 灵活配置。所有单元均可完全配置运行参数,在相同的数据流处理情况下,随意更换模型和修改模型运行参数。 +* 简单易用。开发者只需关注模型和硬件平台,无需关注底层通信和数据处理细节,即可快速实现 AI 服务。 +* 高效稳定。通过 ZMQ 信道传输,数据传输效率高,延迟低,稳定性强。 +* 开源免费。StackFlow 采用 MIT 许可证,开发者可以自由使用和修改。 +* 多语言支持。单元主体由 C++ 实现,性能极致优化,可扩展至多变成语言支持。(需要支持 ZMQ 编程) -- 离线语音助手 -- 文本语音转换 -- 智能家居控制 -- 互动机器人 +StackFlow 还在不断优化和迭代,在框架更加完善的同时,会持续增加更多功能,敬请期待。 -## 规格参数 - -| 规格 | 参数 | -| ------------ | --------------------------------------------------------------------------- | -| 处理器SoC | AX630C@Dual Cortex A53 1.2 GHz
MAX.12.8 TOPS @INT4,and 3.2 TOPS @INT8 | -| 内存 | 4GB LPDDR4(1GB系统内存 + 3GB 硬件加速专用内存) | -| 存储 | 32GB eMMC5.1 | -| 通信接口 | 串口通信 波特率默认 115200@8N1(可调) | -| 麦克风 | MSM421A | -| 音频驱动 | AW8737 | -| 扬声器 | 8Ω@1W,尺寸:2014 腔体喇叭 | -| 内置功能单元 | KWS(唤醒词),ASR(语音识别),LLM(大语言模型),TTS(文本生成语音) | -| RGB灯 | 3x RGB LED@2020 由LP5562驱动 (状态指示) | -| 功耗 | 空载:5V@0.5W,满载:5V@1.5W | -| 按键 | 用于升级固件进入下载模式 | -| 升级接口 | SD卡/Type C口 | -| 工作温度 | 0-40°C | -| 产品尺寸 | 54x54x13mm | -| 包装尺寸 | 133x95x16mm | -| 产品重量 | 17.4g | -| 包装重量 | 32.0g | - -## 相关链接 - -- [AX630C](https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/docs/products/module/Module%20LLM/AX630C.pdf) - -## PinMap - -| Module LLM | RXD | TXD | -| ------------ | --- | --- | -| Core (Basic) | G16 | G17 | -| Core2 | G13 | G14 | -| CoreS3 | G18 | G17 | - ->LLM Module引脚切换| LLM Module预留了引脚切换焊盘, 一些出现引脚复用冲突的情况下, 可以通过切割PCB线路然后跳线连接至其他组引脚。 - -module size - -> 以`CoreS3`为例子,第一列(左绿色框)是串口通讯的TX引脚,用户根据需要四选一,(从上到下分别代表引脚G18 G7 G14 G10),默认是IO18引脚,如需要切换其他引脚,切断焊盘连接线(红线处)(建议使用刀片切割),然后连接下面三个引脚之间的一个即可;第二列(右绿色框)是RX引脚切换,如上所述,也是四选一操作。 +StackFlow 语音助手的主要工作模式: +开机后,KWS、ASR、LLM、TTS、AUDIO 被配置成协同工作状态。当 KWS 从 AUDIO 单元获取的音频中检测出关键词后,发出唤醒信号。此时,ASR 开始工作,识别 AUDIO 的音频数据,并将结果发布到自己的输出信道中。LLM 接收到 ASR 转换后的文本数据后,开始进行推理,并将结果发布到自己的输出信道中。TTS 接收到 LLM 的结果后,开始进行语音合成,合成完成后根据配置来播放合成好的音频数据。 -## 视频 -- Module LLM 产品介绍以及例子展示 [Module_LLM_Video.mp4](https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/docs/products/module/Module%20LLM/Module_LLM_Video.mp4) +## Demo +- [StackFlow 连续语音识别]() +- [StackFlow LLM 大模型唤醒对话]() +- [StackFlow TTS 语音合成播放]() +- [StackFlow yolo 视觉检测]() +- [StackFlow VLM 图片描述]() -## AI Benchmark 对比 +## 环境要求 ## +当前 StackFlow 的 AI 单元是建立在 AXERA 加速平台之上的,主要的芯片平台为 ax630c、ax650n。系统要求为 ubuntu。 -compare +## 安装 ## +StackFlow 的程序和模型数据是分开的,程序安装完成后,需要单独下载模型数据,并配置到程序中。安装是先安装程序包,然后再安装模型包。 +裸机环境安装见[StackFlow 安装教程]() 。 + +## 升级 +升级时可单独升级 AI 单元,或者升级整个 StackFlow 框架。 +升级单个单元时可通过 SD 卡升级或者手动 `dpkg` 命令进行安装。 +## 运行 ## +相关 AI 服务会在开机时自动运行,也可以通过手动命令启动。 +sys 单元运行状态查询: +```bash +systemctl status llm-sys +``` +相关命令可参考 systemd 服务命令。 + +## 配置 ## +StackFlow 的配置分为两类,一类是单元工作参数配置,一类是模型工作参数配置。 +两类配置文件均采用 json 格式,配置文件位于多个目录下,目录如下: +``` +/opt/m5stack/data/models/ +/opt/m5stack/share/ +``` +## API 接口 ## +StackFlow 可通过 UART 和 TCP 端口进行访问。 +## 贡献 + +* 喜欢本项目请先打一颗星; +* 提 bug 请到 [issue 页面](https://github.com/m5stack/StackFlow/issues); +* 要贡献代码,欢迎 fork 之后再提 pull request; + +## Star 历史 + +[![Star History Chart](https://api.star-history.com/svg?repos=m5stack/StackFlow&type=Date)](https://star-history.com/#m5stack/StackFlow&Date) diff --git a/doc/assets/StackFlow_unit.dot b/doc/assets/StackFlow_unit.dot new file mode 100644 index 0000000..4ade435 --- /dev/null +++ b/doc/assets/StackFlow_unit.dot @@ -0,0 +1,36 @@ +digraph G { + SYS -> KWS [color="purple"]; + SYS -> ASR [color="purple"]; + SYS -> LLM [color="purple"]; + SYS -> TTS [color="purple"]; + SYS -> AUDIO [color="purple"]; + SYS -> CAMERA [color="purple"]; + SYS -> VAD [color="purple"]; + SYS -> VLM [color="purple"]; + SYS -> YOLO [color="purple"]; + SYS -> DEPTH [color="purple"]; + KWS -> SYS [color="green"]; + ASR -> SYS [color="green"]; + LLM -> SYS [color="green"]; + TTS -> SYS [color="green"]; + AUDIO -> SYS [color="green"]; + CAMERA -> SYS [color="green"]; + VAD -> SYS [color="green"]; + VLM -> SYS [color="green"]; + YOLO -> SYS [color="green"]; + DEPTH -> SYS [color="green"]; + AUDIO -> KWS [color="blue"]; + AUDIO -> ASR [color="blue"]; + AUDIO -> VAD [color="blue"]; + CAMERA -> YOLO [color="blue"]; + CAMERA -> DEPTH [color="blue"]; + CAMERA -> VLM [color="blue"]; + ASR -> VLM [color="blue"]; + VLM -> TTS [color="blue"]; + KWS -> ASR [color="blue"]; + KWS -> LLM [color="blue"]; + KWS -> AUDIO [color="blue"]; + ASR -> LLM [color="blue"]; + LLM -> TTS [color="blue"]; + TTS -> AUDIO [color="blue"]; +} \ No newline at end of file diff --git a/doc/assets/network.png b/doc/assets/network.png new file mode 100644 index 0000000..248b9b6 Binary files /dev/null and b/doc/assets/network.png differ diff --git a/doc/projects_llm_framework_doc/llm_sys_en.md b/doc/projects_llm_framework_doc/llm_sys_en.md index 56232d4..2469fbe 100644 --- a/doc/projects_llm_framework_doc/llm_sys_en.md +++ b/doc/projects_llm_framework_doc/llm_sys_en.md @@ -6,13 +6,82 @@ internally handling port resource allocation and a simple in-memory database. ## External API - sys.ping: Test if communication with the LLM is possible. +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "ping" +} +``` - sys.lsmode: Models that have existed in the system in the past. +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "lsmode" +} +``` - sys.bashexec: Execute bash commands. +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "bashexec", + "object": "sys.utf-8.stream", + "data" : { + "index": 0, + "delta": "ls", + "finish": true + } +} +``` - sys.hwinfo: Retrieve onboard CPU, memory, and temperature parameters of the LLM. +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "hwinfo" +} +``` - sys.uartsetup: Set serial port parameters, effective for a single session. +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "uartsetup", + "object": "sys.uartsetup", + "data" : { + "baud": 115200, + "data_bits": 8, + "stop_bits": 1, + "parity": 110 + } +} +``` - sys.reset: Reset the entire LLM framework application. +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "reset" +} +``` - sys.reboot: Restart the system. +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "reboot" +} +``` - sys.version: Get the version of the LLM framework program. +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "version" +} +``` ## Internal API diff --git a/doc/projects_llm_framework_doc/llm_sys_zh.md b/doc/projects_llm_framework_doc/llm_sys_zh.md index e51de20..73c41c0 100644 --- a/doc/projects_llm_framework_doc/llm_sys_zh.md +++ b/doc/projects_llm_framework_doc/llm_sys_zh.md @@ -5,13 +5,82 @@ StackFlow 的基本服务单元,对外提供串口和 TCP 外部信道和一 ## 外部 API - sys.ping:测试是否能够和 LLM 进行通信。 +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "ping" +} +``` - sys.lsmode:过去系统中存在的模型。 +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "lsmode" +} +``` - sys.bashexec:执行 bash 命令。 +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "bashexec", + "object": "sys.utf-8.stream", + "data" : { + "index": 0, + "delta": "ls", + "finish": true + } +} +``` - sys.hwinfo:获取 LLM 板载 cpu、内存、温度参数。 +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "hwinfo" +} +``` - sys.uartsetup:设置串口参数,单次生效。 +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "uartsetup", + "object": "sys.uartsetup", + "data" : { + "baud": 115200, + "data_bits": 8, + "stop_bits": 1, + "parity": 110 + } +} +``` - sys.reset:复位整个 LLM 框架的应用程序。 +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "reset" +} +``` - sys.reboot:重启系统。 +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "reboot" +} +``` - sys.version:获取 LLM 框架程序版本。 +```json +{ + "request_id": "2", + "work_id": "sys", + "action": "version" +} +``` ## 内部 API: diff --git a/ext_components/ax_msp/Kconfig b/ext_components/ax_msp/Kconfig index 88d6048..ba264e3 100644 --- a/ext_components/ax_msp/Kconfig +++ b/ext_components/ax_msp/Kconfig @@ -16,4 +16,26 @@ menuconfig AX_MSP_ENABLED bool "enable ax520 bsp" help build by AXERA! - endchoice \ No newline at end of file + endchoice + + choice + prompt "choice common version" + default MSP_V2_0_0_ENABLED + depends on AX_MSP_ENABLED + config MSP_V3_0_0_ENABLED + bool "enable v3.0.0 bsp" + help + build by m5stack! + config MSP_V2_0_0_ENABLED + bool "enable v2.0.0 bsp" + help + build by m5stack! + endchoice + + config SAMPLE_COMMON_ENABLED + bool "Enable sample common" + default n + depends on AX_MSP_ENABLED + help + enable sample common + diff --git a/ext_components/ax_msp/SConstruct b/ext_components/ax_msp/SConstruct index f8cdcae..a77c7d4 100644 --- a/ext_components/ax_msp/SConstruct +++ b/ext_components/ax_msp/SConstruct @@ -5,7 +5,10 @@ with open(env['PROJECT_TOOL_S']) as f: exec(f.read()) if 'CONFIG_AX_620E_MSP_ENABLED' in os.environ: - MSP_PATH = os.environ.get('EXT_MSP_PATH', check_wget_down("https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/linux/llm/m5stack_msp.tar.gz", 'm5stack_msp.tar.gz')) + MSP_PATH = '' + if 'CONFIG_MSP_V2_0_0_ENABLED' in os.environ: + MSP_PATH = os.environ.get('EXT_MSP_PATH', check_wget_down("https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/linux/llm/m5stack_msp.tar.gz", 'm5stack_msp.tar.gz')) + SRCS=[] INCLUDE=[] PRIVATE_INCLUDE=[] @@ -18,7 +21,8 @@ if 'CONFIG_AX_620E_MSP_ENABLED' in os.environ: LINK_SEARCH_PATH=[] env["MSP_PATH"] = MSP_PATH - INCLUDE += [os.path.join(MSP_PATH, 'out/arm64_glibc/include'), os.path.join(MSP_PATH, 'sample'), os.path.join(MSP_PATH, 'sample/common'), os.path.join(MSP_PATH, 'sample/rtsp')] + # , os.path.join(MSP_PATH, 'sample/common') + INCLUDE += [os.path.join(MSP_PATH, 'out/arm64_glibc/include'), os.path.join(MSP_PATH, 'sample'), os.path.join(MSP_PATH, 'sample/rtsp')] LINK_SEARCH_PATH += [os.path.join(MSP_PATH, 'out/arm64_glibc/lib')] REQUIREMENTS += ['dl', 'm', 'pthread'] third_party = ['drm','faac','fdk-aac','ffmpeg','libsamplerate','mp4','opencv','opus','tinyalsa'] @@ -31,6 +35,11 @@ if 'CONFIG_AX_620E_MSP_ENABLED' in os.environ: LINK_SEARCH_PATH.append(os.path.join(MSP_PATH,'third-party/openssl/arm64/glibc/lib')) LINK_SEARCH_PATH.append(os.path.join(MSP_PATH,'app/lib')) + if 'CONFIG_SAMPLE_COMMON_ENABLED' in os.environ: + if 'CONFIG_MSP_V2_0_0_ENABLED' in os.environ: + INCLUDE.append(os.path.join(MSP_PATH,'sample/common')) + SRCS += AGlob(os.path.join(MSP_PATH,'sample/common/*.c*')) + env['COMPONENTS'].append({'target':os.path.basename(env['component_dir']), 'SRCS':SRCS, 'INCLUDE':INCLUDE, diff --git a/projects/llm_framework/config_defaults.mk b/projects/llm_framework/config_defaults.mk index a61fc04..5517ada 100644 --- a/projects/llm_framework/config_defaults.mk +++ b/projects/llm_framework/config_defaults.mk @@ -23,3 +23,4 @@ CONFIG_UTILITIES_BASE64_ENABLED=y CONFIG_SINGLE_HEADER_LIBS_ENABLED=y CONFIG_AX_SAMPLES_ENABLED=y CONFIG_SIMDJSON_COMPENENT_ENABLED=y +CONFIG_SAMPLE_COMMON_ENABLED=y diff --git a/projects/llm_framework/main_camera/SConstruct b/projects/llm_framework/main_camera/SConstruct index 8de268d..2f1758a 100644 --- a/projects/llm_framework/main_camera/SConstruct +++ b/projects/llm_framework/main_camera/SConstruct @@ -22,7 +22,17 @@ LDFLAGS+=['-Wl,-rpath=/opt/m5stack/lib', '-Wl,-rpath=/usr/local/m5stack/lib', '- # INCLUDE += [ADir('../include'), ADir('../include/cppzmq'), ADir('../include/libzmq')] LINK_SEARCH_PATH += [ADir('../static_lib')] + +# INCLUDE.append(ADir('ax_sample')) +# SRCS += Glob('ax_sample/*.c*') + REQUIREMENTS += ['ax_sys', 'ax_interpreter'] +REQUIREMENTS += ['ax_engine', 'ax_interpreter', 'ax_sys', 'ax_vo'] +REQUIREMENTS += ['ax_opal', 'ax_ae', 'ax_skel', 'ax_opal', 'ax_venc', 'ax_mipi', 'ax_ives', 'ax_ivps', 'ax_proton', 'ax_audio', 'mpr', 'tinyalsa'] +REQUIREMENTS += ['ax_audio_3a','samplerate', 'ax_fdk', 'fdk-aac', 'ax_awb', 'ax_af', 'ax_nt_stream', 'ax_nt_ctrl'] + + + INCLUDE += [ADir('../include/opencv4')] static_file = [] diff --git a/projects/llm_framework/main_camera/src/axera_camera.c b/projects/llm_framework/main_camera/src/axera_camera.c new file mode 100644 index 0000000..d929a21 --- /dev/null +++ b/projects/llm_framework/main_camera/src/axera_camera.c @@ -0,0 +1,1373 @@ +/* + * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD + * + * SPDX-License-Identifier: MIT + */ +#include "camera.h" +#include "axera_camera.h" +#include +#include +#include +#include +#include "../../../../SDK/components/utilities/include/sample_log.h" +#include +#include +#include +#include +#include +#include + +#include "ax_global_type.h" +#include "common_isp.h" +#include "common_sys.h" +#include "common_cam.h" +#include "common_isp.h" +#include "common_nt.h" +#include "common_vin.h" +#include "ax_sys_api.h" +#include "ax_ivps_api.h" + +#ifndef ALIGN_UP +#define ALIGN_UP(x, a) ((((x) + ((a) - 1)) / a) * a) +#endif + +AX_MIPI_RX_ATTR_T gSc850slMipiAttr = { + .ePhyMode = AX_MIPI_PHY_TYPE_DPHY, + .eLaneNum = AX_MIPI_DATA_LANE_4, + .nDataRate = 80, + .nDataLaneMap[0] = 0, + .nDataLaneMap[1] = 1, + .nDataLaneMap[2] = 3, + .nDataLaneMap[3] = 4, + .nClkLane[0] = 2, + .nClkLane[1] = 5, +}; + +AX_SNS_ATTR_T gSc850slSnsAttr = { + .nWidth = 3840, + .nHeight = 2160, + .fFrameRate = 30, + .eSnsMode = AX_SNS_LINEAR_MODE, + .eRawType = AX_RT_RAW10, + .eBayerPattern = AX_BP_RGGB, + .bTestPatternEnable = AX_FALSE, + // .nSettingIndex = 12, +}; + +AX_SNS_CLK_ATTR_T gSc850slSnsClkAttr = { + .nSnsClkIdx = 0, + .eSnsClkRate = AX_SNS_CLK_24M, +}; + +AX_VIN_DEV_ATTR_T gSc850slDevAttr = { + .bImgDataEnable = AX_TRUE, + .bNonImgDataEnable = AX_FALSE, + .eDevMode = AX_VIN_DEV_ONLINE, + .eSnsIntfType = AX_SNS_INTF_TYPE_MIPI_RAW, + .tDevImgRgn[0] = {0, 0, 3840, 2160}, + .tDevImgRgn[1] = {0, 0, 3840, 2160}, + .tDevImgRgn[2] = {0, 0, 3840, 2160}, + .tDevImgRgn[3] = {0, 0, 3840, 2160}, + + /* When users transfer special data, they need to configure VC&DT for szImgVc/szImgDt/szInfoVc/szInfoDt */ + //.tMipiIntfAttr.szImgVc[0] = 0, + //.tMipiIntfAttr.szImgVc[1] = 1, + //.tMipiIntfAttr.szImgDt[0] = 43, + //.tMipiIntfAttr.szImgDt[1] = 43, + //.tMipiIntfAttr.szInfoVc[0] = 31, + //.tMipiIntfAttr.szInfoVc[1] = 31, + //.tMipiIntfAttr.szInfoDt[0] = 63, + //.tMipiIntfAttr.szInfoDt[1] = 63, + + .ePixelFmt = AX_FORMAT_BAYER_RAW_10BPP_PACKED, + .eBayerPattern = AX_BP_RGGB, + .eSnsMode = AX_SNS_LINEAR_MODE, + .eSnsOutputMode = AX_SNS_NORMAL, + .tCompressInfo = {AX_COMPRESS_MODE_NONE, 0}, + .tFrameRateCtrl= {AX_INVALID_FRMRATE, AX_INVALID_FRMRATE}, +}; + +AX_VIN_PIPE_ATTR_T gSc850slPipeAttr = { + .ePipeWorkMode = AX_VIN_PIPE_NORMAL_MODE1, + .tPipeImgRgn = {0, 0, 3840, 2160}, + .nWidthStride = 3840, + .eBayerPattern = AX_BP_RGGB, + .ePixelFmt = AX_FORMAT_BAYER_RAW_10BPP_PACKED, + .eSnsMode = AX_SNS_LINEAR_MODE, + .tCompressInfo = {AX_COMPRESS_MODE_LOSSY, 0}, + .tNrAttr = {{0, {AX_COMPRESS_MODE_LOSSLESS, 0}}, {0, {AX_COMPRESS_MODE_NONE, 0}}}, + .tFrameRateCtrl = {AX_INVALID_FRMRATE, AX_INVALID_FRMRATE}, +}; + +AX_VIN_CHN_ATTR_T gSc850slChn0Attr = { + .nWidth = 3840, + .nHeight = 2160, + .nWidthStride = 3840, + .eImgFormat = AX_FORMAT_YUV420_SEMIPLANAR, + .nDepth = 1, + .tCompressInfo = {AX_COMPRESS_MODE_LOSSY, 4}, + .tFrameRateCtrl = {AX_INVALID_FRMRATE, AX_INVALID_FRMRATE}, +}; + +typedef enum { + SAMPLE_VIN_NONE = -1, + SAMPLE_VIN_SINGLE_DUMMY = 0, + SAMPLE_VIN_SINGLE_OS04A10 = 1, + SAMPLE_VIN_DOUBLE_OS04A10 = 2, + SAMPLE_VIN_SINGLE_SC450AI = 3, + SAMPLE_VIN_DOUBLE_SC450AI = 4, + SAMPLE_VIN_DOUBLE_OS04A10_AND_BT656 = 5, + SAMPLE_VIN_SINGLE_S5KJN1SQ03 = 6, + SAMPLE_VIN_SINGLE_OS04A10_DCG_HDR = 7, + SAMPLE_VIN_SINGLE_OS04A10_DCG_VS_HDR = 8, + SYS_CASE_SINGLE_DVP = 20, + SYS_CASE_SINGLE_BT601 = 21, + SYS_CASE_SINGLE_BT656 = 22, + SYS_CASE_SINGLE_BT1120 = 23, + SYS_CASE_SINGLE_LVDS = 24, + SYS_CASE_SINGLE_OS04A10_ONLINE = 25, + SMARTSENS_SC850SL = 13, + SAMPLE_VIN_SINGLE_SC850SL = 26, + SAMPLE_VIN_BUTT +} SAMPLE_VIN_CASE_E; + +struct axera_camera_index_t +{ + char name[48]; + SAMPLE_VIN_CASE_E index; +}axera_camera_index[] = { + {"axera_single_dummy", SAMPLE_VIN_SINGLE_DUMMY}, + {"axera_single_os04a10", SAMPLE_VIN_SINGLE_OS04A10}, + {"axera_double_os04a10", SAMPLE_VIN_DOUBLE_OS04A10}, + {"axera_single_sc450ai", SAMPLE_VIN_SINGLE_SC450AI}, + {"axera_double_sc450ai", SAMPLE_VIN_DOUBLE_SC450AI}, + {"axera_double_os04a10_and_bt656", SAMPLE_VIN_DOUBLE_OS04A10_AND_BT656}, + {"axera_single_s5kjn1sq03", SAMPLE_VIN_SINGLE_S5KJN1SQ03}, + {"axera_single_os04a10_dcg_hdr", SAMPLE_VIN_SINGLE_OS04A10_DCG_HDR}, + {"axera_single_os04a10_dcg_vs_hdr", SAMPLE_VIN_SINGLE_OS04A10_DCG_VS_HDR}, + {"axera_single_dvp", SYS_CASE_SINGLE_DVP}, + {"axera_single_bt601", SYS_CASE_SINGLE_BT601}, + {"axera_single_bt656", SYS_CASE_SINGLE_BT656}, + {"axera_single_bt1120", SYS_CASE_SINGLE_BT1120}, + {"axera_single_lvds", SYS_CASE_SINGLE_LVDS}, + {"axera_single_os04a10_online", SYS_CASE_SINGLE_OS04A10_ONLINE}, + {"axera_single_sc850sl", SAMPLE_VIN_SINGLE_SC850SL} +}; + +typedef struct { + SAMPLE_VIN_CASE_E eSysCase; + COMMON_VIN_MODE_E eSysMode; + AX_SNS_HDR_MODE_E eHdrMode; + SAMPLE_LOAD_RAW_NODE_E eLoadRawNode; + AX_BOOL bAiispEnable; + AX_S32 nDumpFrameNum; +} SAMPLE_VIN_PARAM_T; + +/* comm pool */ +COMMON_SYS_POOL_CFG_T gtSysCommPoolSingleDummySdr[] = { + {2688, 1520, 2688, AX_FORMAT_BAYER_RAW_16BPP, 6}, /*vin raw16 use */ + {2688, 1520, 2688, AX_FORMAT_YUV420_SEMIPLANAR, 4, AX_COMPRESS_MODE_LOSSY, 4}, /*vin nv21/nv21 use */ +}; + +COMMON_SYS_POOL_CFG_T gtSysCommPoolSingleDVPSdr[] = { + {2560, 1440, 2560, AX_FORMAT_YUV420_SEMIPLANAR, 10}, /* vin nv21/nv21 use */ +}; + +COMMON_SYS_POOL_CFG_T gtSysCommPoolSingleBTSdr[] = { + {720, 480, 720, AX_FORMAT_YUV422_INTERLEAVED_UYVY, 25 * 2}, /*vin yuv422 uyvy use */ +}; + +COMMON_SYS_POOL_CFG_T gtSysCommPoolSingleLVDSSdr[] = { + {1600, 1200, 1600, AX_FORMAT_YUV420_SEMIPLANAR, 10}, /* vin nv21/nv21 use */ +}; + +/* private pool */ +COMMON_SYS_POOL_CFG_T gtPrivatePoolSingleDummySdr[] = { + {2688, 1520, 2688, AX_FORMAT_BAYER_RAW_16BPP, 10, AX_COMPRESS_MODE_LOSSY, 4}, +}; + +COMMON_SYS_POOL_CFG_T gtSysPrivatePoolSingleDVPSdr[] = { + {2560, 1440, 2560, AX_FORMAT_BAYER_RAW_10BPP, 25 * 2}, /*vin raw10 use */ +}; + +COMMON_SYS_POOL_CFG_T gtSysPrivatePoolSingleBTSdr[] = { + {720, 480, 720, AX_FORMAT_YUV422_INTERLEAVED_UYVY, 25 * 2}, /*vin yuv422 uyvy use */ +}; + +COMMON_SYS_POOL_CFG_T gtSysPrivatePoolSingleLVDSSdr[] = { + {1600, 1200, 1600, AX_FORMAT_BAYER_RAW_10BPP, 25 * 2}, /*vin raw10 use */ +}; + +COMMON_SYS_POOL_CFG_T gtSysCommPoolSingleOs04a10Sdr[] = { + {2688, 1520, 2688, AX_FORMAT_YUV420_SEMIPLANAR, 3, AX_COMPRESS_MODE_LOSSY, 4}, /* vin nv21/nv21 use */ + {2688, 1520, 2688, AX_FORMAT_YUV420_SEMIPLANAR, 4}, /* vin nv21/nv21 use */ + {1920, 1080, 1920, AX_FORMAT_YUV420_SEMIPLANAR, 3}, /* vin nv21/nv21 use */ + {720, 576, 720, AX_FORMAT_YUV420_SEMIPLANAR, 3}, /* vin nv21/nv21 use */ +}; + +COMMON_SYS_POOL_CFG_T gtPrivatePoolSingleOs04a10Sdr[] = { + {2688, 1520, 2688, AX_FORMAT_BAYER_RAW_10BPP_PACKED, 12, AX_COMPRESS_MODE_LOSSY, 4}, /* vin raw16 use */ +}; + +COMMON_SYS_POOL_CFG_T gtSysCommPoolDoubleOs04a10Bt656Sdr[] = { + {2688, 1520, 2688, AX_FORMAT_YUV420_SEMIPLANAR, 7, AX_COMPRESS_MODE_LOSSY, 4}, /* vin nv21/nv21 use */ + {720, 480, 720, AX_FORMAT_YUV422_SEMIPLANAR, 6, AX_COMPRESS_MODE_NONE, 0}, /* vin nv21/nv21 use */ +}; + +COMMON_SYS_POOL_CFG_T gtPrivatePoolDoubleOs04a10Bt656Sdr[] = { + {2688, 1520, 2688, AX_FORMAT_BAYER_RAW_10BPP_PACKED, 7, AX_COMPRESS_MODE_LOSSY, 4}, /* vin raw10 use */ + {720, 480, 720, AX_FORMAT_YUV422_SEMIPLANAR, 5, AX_COMPRESS_MODE_NONE, 0}, /* vin nv21/nv21 use */ +}; + +COMMON_SYS_POOL_CFG_T gtSysCommPoolDoubleOs04a10Bt656Hdr[] = { + {2688, 1520, 2688, AX_FORMAT_YUV420_SEMIPLANAR, 7, AX_COMPRESS_MODE_LOSSY, 4}, /* vin nv21/nv21 use */ + {720, 480, 720, AX_FORMAT_YUV422_SEMIPLANAR, 7, AX_COMPRESS_MODE_NONE, 0}, /* vin nv21/nv21 use */ +}; + +COMMON_SYS_POOL_CFG_T gtPrivatePoolDoubleOs04a10Bt656Hdr[] = { + {2688, 1520, 2688, AX_FORMAT_BAYER_RAW_10BPP_PACKED, 13, AX_COMPRESS_MODE_LOSSY, 4}, /* vin raw10 use */ + {720, 480, 720, AX_FORMAT_YUV422_SEMIPLANAR, 5, AX_COMPRESS_MODE_NONE, 0}, /* vin nv21/nv21 use */ +}; + +COMMON_SYS_POOL_CFG_T gtSysCommPoolDoubleOs04a10Sdr[] = { + {2688, 1520, 2688, AX_FORMAT_YUV420_SEMIPLANAR, 6, AX_COMPRESS_MODE_LOSSY, 4}, /* vin nv21/nv21 use */ +}; + +COMMON_SYS_POOL_CFG_T gtPrivatePoolDoubleOs04a10Sdr[] = { + {2688, 1520, 2688, AX_FORMAT_BAYER_RAW_10BPP_PACKED, 14, AX_COMPRESS_MODE_LOSSY, 4}, /* vin raw10 use */ +}; + +COMMON_SYS_POOL_CFG_T gtPrivatePoolDoubleOs04a10SdrOnly[] = { + {2688, 1520, 2688, AX_FORMAT_BAYER_RAW_10BPP_PACKED, 8, AX_COMPRESS_MODE_LOSSY, 4}, /* vin raw10 use */ +}; + +COMMON_SYS_POOL_CFG_T gtSysCommPoolDoubleOs04a10Hdr[] = { + {2688, 1520, 2688, AX_FORMAT_YUV420_SEMIPLANAR, 6, AX_COMPRESS_MODE_LOSSY, 4}, /* vin nv21/nv21 use */ +}; + +COMMON_SYS_POOL_CFG_T gtPrivatePoolDoubleOs04a10Hdr[] = { + {2688, 1520, 2688, AX_FORMAT_BAYER_RAW_10BPP_PACKED, 7, AX_COMPRESS_MODE_NONE, 0}, /* vin raw10 use */ + {2688, 1520, 2688, AX_FORMAT_BAYER_RAW_10BPP_PACKED, 7, AX_COMPRESS_MODE_LOSSY, 4}, /* vin raw10 use */ +}; + +COMMON_SYS_POOL_CFG_T gtSysCommPoolSingleOs450aiSdr[] = { + {2688, 1520, 2688, AX_FORMAT_YUV420_SEMIPLANAR, 3, AX_COMPRESS_MODE_LOSSY, 4}, /* vin nv21/nv21 use */ +}; + +COMMON_SYS_POOL_CFG_T gtPrivatePoolSingleOs450aiSdr[] = { + {2688, 1520, 2688, AX_FORMAT_BAYER_RAW_10BPP_PACKED, 8, AX_COMPRESS_MODE_LOSSY, 4}, /* vin raw10 use */ +}; + +/*************************************/ +COMMON_SYS_POOL_CFG_T gtSysCommPoolSingleSc850SlSdr[] = { + {3840, 2160, 3840, AX_FORMAT_YUV420_SEMIPLANAR, 4, AX_COMPRESS_MODE_LOSSY, 4}, /* vin nv21/nv21 use */ + {2688, 1520, 2688, AX_FORMAT_YUV420_SEMIPLANAR, 4}, /* vin nv21/nv21 use */ + {1920, 1080, 1920, AX_FORMAT_YUV420_SEMIPLANAR, 3}, /* vin nv21/nv21 use */ + {720, 576, 720, AX_FORMAT_YUV420_SEMIPLANAR, 3}, /* vin nv21/nv21 use */ +}; + +COMMON_SYS_POOL_CFG_T gtPrivatePoolSingleSc850SlSdr[] = { + {3840, 2160, 3840, AX_FORMAT_BAYER_RAW_10BPP_PACKED, 8, AX_COMPRESS_MODE_LOSSY, 4}, /* vin raw10 use */ +}; +/*************************************/ + +COMMON_SYS_POOL_CFG_T gtSysCommPoolDoubleSc450aiSdr[] = { + {2688, 1520, 2688, AX_FORMAT_YUV420_SEMIPLANAR, 6, AX_COMPRESS_MODE_LOSSY, 4}, /* vin nv21/nv21 use */ +}; + +COMMON_SYS_POOL_CFG_T gtPrivatePoolDoubleSc450aiSdr[] = { + {2688, 1520, 2688, AX_FORMAT_BAYER_RAW_10BPP_PACKED, 7, AX_COMPRESS_MODE_LOSSY, 4}, /* vin raw10 use */ +}; + +COMMON_SYS_POOL_CFG_T gtSysCommPoolDoubleSc450aiHdr[] = { + {2688, 1520, 2688, AX_FORMAT_YUV420_SEMIPLANAR, 6, AX_COMPRESS_MODE_LOSSY, 4}, /* vin nv21/nv21 use */ +}; + +COMMON_SYS_POOL_CFG_T gtPrivatePoolDoubleSc450aiHdr[] = { + {2688, 1520, 2688, AX_FORMAT_BAYER_RAW_10BPP_PACKED, 7, AX_COMPRESS_MODE_NONE, 0}, /* vin raw10 use */ + {2688, 1520, 2688, AX_FORMAT_BAYER_RAW_10BPP_PACKED, 7, AX_COMPRESS_MODE_LOSSY, 4}, /* vin raw10 use */ +}; + +COMMON_SYS_POOL_CFG_T gtSysCommPoolSingles5kjn1sq03Sdr[] = { + {1920, 1080, 1920, AX_FORMAT_YUV420_SEMIPLANAR, 3, AX_COMPRESS_MODE_LOSSY, 4}, /* vin nv21/nv21 use */ +}; + +COMMON_SYS_POOL_CFG_T gtPrivatePoolSingles5kjn1sq03Sdr[] = { + {1920, 1080, 1920, AX_FORMAT_BAYER_RAW_10BPP_PACKED, 8, AX_COMPRESS_MODE_LOSSY, 4}, /* vin raw10 use */ +}; + +static AX_VOID __cal_dump_pool(COMMON_SYS_POOL_CFG_T pool[], AX_SNS_HDR_MODE_E eHdrMode, AX_S32 nFrameNum) +{ + if (NULL == pool) { + return; + } + if (nFrameNum > 0) { + switch (eHdrMode) { + case AX_SNS_LINEAR_MODE: + pool[0].nBlkCnt += nFrameNum; + break; + + case AX_SNS_HDR_2X_MODE: + pool[0].nBlkCnt += nFrameNum * 2; + break; + + case AX_SNS_HDR_3X_MODE: + pool[0].nBlkCnt += nFrameNum * 3; + break; + + case AX_SNS_HDR_4X_MODE: + pool[0].nBlkCnt += nFrameNum * 4; + break; + + default: + pool[0].nBlkCnt += nFrameNum; + break; + } + } +} + +static AX_VOID __set_pipe_hdr_mode(AX_U32 *pHdrSel, AX_SNS_HDR_MODE_E eHdrMode) +{ + if (NULL == pHdrSel) { + return; + } + + switch (eHdrMode) { + case AX_SNS_LINEAR_MODE: + *pHdrSel = 0x1; + break; + + case AX_SNS_HDR_2X_MODE: + *pHdrSel = 0x1 | 0x2; + break; + + case AX_SNS_HDR_3X_MODE: + *pHdrSel = 0x1 | 0x2 | 0x4; + break; + + case AX_SNS_HDR_4X_MODE: + *pHdrSel = 0x1 | 0x2 | 0x4 | 0x8; + break; + + default: + *pHdrSel = 0x1; + break; + } +} + +static AX_VOID __set_vin_attr(AX_CAMERA_T *pCam, SAMPLE_SNS_TYPE_E eSnsType, AX_SNS_HDR_MODE_E eHdrMode, + COMMON_VIN_MODE_E eSysMode, AX_BOOL bAiispEnable) +{ + pCam->eSnsType = eSnsType; + pCam->tSnsAttr.eSnsMode = eHdrMode; + pCam->tDevAttr.eSnsMode = eHdrMode; + pCam->eHdrMode = eHdrMode; + pCam->eSysMode = eSysMode; + pCam->tPipeAttr[pCam->nPipeId].eSnsMode = eHdrMode; + pCam->tPipeAttr[pCam->nPipeId].bAiIspEnable = bAiispEnable; + + if (eHdrMode > AX_SNS_LINEAR_MODE) { + pCam->tDevAttr.eSnsOutputMode = AX_SNS_DOL_HDR; + } + + if (COMMON_VIN_TPG == eSysMode) { + pCam->tDevAttr.eSnsIntfType = AX_SNS_INTF_TYPE_TPG; + } + + if (COMMON_VIN_LOADRAW == eSysMode) { + pCam->bEnableDev = AX_FALSE; + } else { + pCam->bEnableDev = AX_TRUE; + } + pCam->bChnEn[0] = AX_TRUE; + pCam->bRegisterSns = AX_TRUE; + + return; +} + + +AX_S32 CUSTOM_COMMON_VIN_GetSnsConfig(SAMPLE_SNS_TYPE_E eSnsType, + AX_MIPI_RX_ATTR_T *ptMipiAttr, AX_SNS_ATTR_T *ptSnsAttr, + AX_SNS_CLK_ATTR_T *ptSnsClkAttr, AX_VIN_DEV_ATTR_T *pDevAttr, + AX_VIN_PIPE_ATTR_T *pPipeAttr, AX_VIN_CHN_ATTR_T *pChnAttr) { + if(eSnsType == SMARTSENS_SC850SL) + { + memcpy(ptMipiAttr, &gSc850slMipiAttr, sizeof(AX_MIPI_RX_ATTR_T)); + memcpy(ptSnsAttr, &gSc850slSnsAttr, sizeof(AX_SNS_ATTR_T)); + memcpy(ptSnsClkAttr, &gSc850slSnsClkAttr, sizeof(AX_SNS_CLK_ATTR_T)); + memcpy(pDevAttr, &gSc850slDevAttr, sizeof(AX_VIN_DEV_ATTR_T)); + memcpy(pPipeAttr, &gSc850slPipeAttr, sizeof(AX_VIN_PIPE_ATTR_T)); + memcpy(&pChnAttr[0], &gSc850slChn0Attr, sizeof(AX_VIN_CHN_ATTR_T)); + } + return COMMON_VIN_GetSnsConfig(eSnsType, ptMipiAttr, ptSnsAttr, + ptSnsClkAttr, pDevAttr, pPipeAttr, pChnAttr); +} + + +static AX_U32 __sample_case_single_dummy(AX_CAMERA_T *pCamList, SAMPLE_SNS_TYPE_E eSnsType, + SAMPLE_VIN_PARAM_T *pVinParam, COMMON_SYS_ARGS_T *pCommonArgs) +{ + AX_S32 i = 0; + AX_CAMERA_T *pCam = NULL; + COMMON_VIN_MODE_E eSysMode = pVinParam->eSysMode; + AX_SNS_HDR_MODE_E eHdrMode = pVinParam->eHdrMode; + SAMPLE_LOAD_RAW_NODE_E eLoadRawNode = pVinParam->eLoadRawNode; + pCam = &pCamList[0]; + pCommonArgs->nCamCnt = 1; + + for (i = 0; i < pCommonArgs->nCamCnt; i++) { + pCam = &pCamList[i]; + pCam->nPipeId = 0; + CUSTOM_COMMON_VIN_GetSnsConfig(eSnsType, &pCam->tMipiAttr, &pCam->tSnsAttr, &pCam->tSnsClkAttr, &pCam->tDevAttr, + &pCam->tPipeAttr[pCam->nPipeId], pCam->tChnAttr); + + pCam->nDevId = 0; + pCam->nRxDev = 0; + pCam->tSnsClkAttr.nSnsClkIdx = 0; + pCam->tDevBindPipe.nNum = 1; + pCam->tDevBindPipe.nPipeId[0] = pCam->nPipeId; + pCam->ptSnsHdl[pCam->nPipeId] = COMMON_ISP_GetSnsObj(eSnsType); + pCam->eBusType = COMMON_ISP_GetSnsBusType(eSnsType); + pCam->eLoadRawNode = eLoadRawNode; + pCam->eInputMode = AX_INPUT_MODE_MIPI; + __set_pipe_hdr_mode(&pCam->tDevBindPipe.nHDRSel[0], eHdrMode); + __set_vin_attr(pCam, eSnsType, eHdrMode, eSysMode, pVinParam->bAiispEnable); + for (AX_S32 j = 0; j < AX_VIN_MAX_PIPE_NUM; j++) { + pCam->tPipeInfo[j].ePipeMode = SAMPLE_PIPE_MODE_VIDEO; + pCam->tPipeInfo[j].bAiispEnable = pVinParam->bAiispEnable; + strncpy(pCam->tPipeInfo[j].szBinPath, "null.bin", sizeof(pCam->tPipeInfo[j].szBinPath)); + } + } + + return 0; +} + +static AX_U32 __sample_case_single_dvp(AX_CAMERA_T *pCamList, SAMPLE_SNS_TYPE_E eSnsType, SAMPLE_VIN_PARAM_T *pVinParam, + COMMON_SYS_ARGS_T *pCommonArgs) +{ + AX_CAMERA_T *pCam = NULL; + COMMON_VIN_MODE_E eSysMode = pVinParam->eSysMode; + AX_SNS_HDR_MODE_E eHdrMode = pVinParam->eHdrMode; + pCommonArgs->nCamCnt = 1; + pCam = &pCamList[0]; + pCam->nPipeId = 0; + CUSTOM_COMMON_VIN_GetSnsConfig(eSnsType, &pCam->tMipiAttr, &pCam->tSnsAttr, &pCam->tSnsClkAttr, &pCam->tDevAttr, + &pCam->tPipeAttr[pCam->nPipeId], pCam->tChnAttr); + pCam->nDevId = 0; + pCam->nRxDev = 0; + pCam->tSnsClkAttr.nSnsClkIdx = 0; + pCam->tDevBindPipe.nNum = 1; + pCam->tDevBindPipe.nPipeId[0] = pCam->nPipeId; + pCam->ptSnsHdl[pCam->nPipeId] = COMMON_ISP_GetSnsObj(eSnsType); + pCam->eBusType = COMMON_ISP_GetSnsBusType(eSnsType); + pCam->eInputMode = AX_INPUT_MODE_DVP; + __set_pipe_hdr_mode(&pCam->tDevBindPipe.nHDRSel[0], eHdrMode); + __set_vin_attr(pCam, eSnsType, eHdrMode, eSysMode, pVinParam->bAiispEnable); + for (AX_S32 j = 0; j < AX_VIN_MAX_PIPE_NUM; j++) { + pCam->tPipeInfo[j].ePipeMode = SAMPLE_PIPE_MODE_VIDEO; + pCam->tPipeInfo[j].bAiispEnable = pVinParam->bAiispEnable; + strncpy(pCam->tPipeInfo[j].szBinPath, "null.bin", sizeof(pCam->tPipeInfo[j].szBinPath)); + } + + return 0; +} + +static AX_U32 __sample_case_single_bt656(AX_CAMERA_T *pCamList, SAMPLE_SNS_TYPE_E eSnsType, + SAMPLE_VIN_PARAM_T *pVinParam, COMMON_SYS_ARGS_T *pCommonArgs) +{ + AX_CAMERA_T *pCam = NULL; + COMMON_VIN_MODE_E eSysMode = pVinParam->eSysMode; + AX_SNS_HDR_MODE_E eHdrMode = pVinParam->eHdrMode; + pCommonArgs->nCamCnt = 1; + pCam = &pCamList[0]; + pCam->nPipeId = 2; + CUSTOM_COMMON_VIN_GetSnsConfig(eSnsType, &pCam->tMipiAttr, &pCam->tSnsAttr, &pCam->tSnsClkAttr, &pCam->tDevAttr, + &pCam->tPipeAttr[pCam->nPipeId], pCam->tChnAttr); + pCam->nDevId = 2; + pCam->nRxDev = 2; + pCam->tSnsClkAttr.nSnsClkIdx = 0; + pCam->tDevBindPipe.nNum = 1; + pCam->tDevBindPipe.nPipeId[0] = pCam->nPipeId; + pCam->ptSnsHdl[pCam->nPipeId] = COMMON_ISP_GetSnsObj(eSnsType); + pCam->eBusType = COMMON_ISP_GetSnsBusType(eSnsType); + pCam->eInputMode = AX_INPUT_MODE_BT656; + pCam->tPipeAttr[pCam->nPipeId].ePipeWorkMode = AX_VIN_PIPE_ISP_BYPASS_MODE; + pCam->tPipeAttr[pCam->nPipeId].ePixelFmt = AX_FORMAT_YUV420_SEMIPLANAR; + __set_pipe_hdr_mode(&pCam->tDevBindPipe.nHDRSel[0], eHdrMode); + __set_vin_attr(pCam, eSnsType, eHdrMode, eSysMode, pVinParam->bAiispEnable); + pCam->bRegisterSns = AX_FALSE; + + return 0; +} + +static AX_U32 __sample_case_single_bt1120(AX_CAMERA_T *pCamList, SAMPLE_SNS_TYPE_E eSnsType, + SAMPLE_VIN_PARAM_T *pVinParam, COMMON_SYS_ARGS_T *pCommonArgs) +{ + AX_CAMERA_T *pCam = NULL; + COMMON_VIN_MODE_E eSysMode = pVinParam->eSysMode; + AX_SNS_HDR_MODE_E eHdrMode = pVinParam->eHdrMode; + pCommonArgs->nCamCnt = 1; + pCam = &pCamList[0]; + pCam->nPipeId = 0; + CUSTOM_COMMON_VIN_GetSnsConfig(eSnsType, &pCam->tMipiAttr, &pCam->tSnsAttr, &pCam->tSnsClkAttr, &pCam->tDevAttr, + &pCam->tPipeAttr[pCam->nPipeId], pCam->tChnAttr); + pCam->nDevId = 2; + pCam->nRxDev = 2; + pCam->tSnsClkAttr.nSnsClkIdx = 0; + pCam->tDevBindPipe.nNum = 1; + pCam->tDevBindPipe.nPipeId[0] = pCam->nPipeId; + pCam->ptSnsHdl[pCam->nPipeId] = COMMON_ISP_GetSnsObj(eSnsType); + pCam->eBusType = COMMON_ISP_GetSnsBusType(eSnsType); + pCam->eInputMode = AX_INPUT_MODE_BT1120; + pCam->tPipeAttr[pCam->nPipeId].ePipeWorkMode = AX_VIN_PIPE_ISP_BYPASS_MODE; + pCam->tPipeAttr[pCam->nPipeId].ePixelFmt = AX_FORMAT_YUV420_SEMIPLANAR; + __set_pipe_hdr_mode(&pCam->tDevBindPipe.nHDRSel[0], eHdrMode); + __set_vin_attr(pCam, eSnsType, eHdrMode, eSysMode, pVinParam->bAiispEnable); + pCam->bRegisterSns = AX_FALSE; + + return 0; +} + +static AX_U32 __sample_case_single_lvds(AX_CAMERA_T *pCamList, SAMPLE_SNS_TYPE_E eSnsType, + SAMPLE_VIN_PARAM_T *pVinParam, COMMON_SYS_ARGS_T *pCommonArgs) +{ + AX_CAMERA_T *pCam = NULL; + COMMON_VIN_MODE_E eSysMode = pVinParam->eSysMode; + AX_SNS_HDR_MODE_E eHdrMode = pVinParam->eHdrMode; + pCommonArgs->nCamCnt = 1; + pCam = &pCamList[0]; + pCam->nPipeId = 0; + CUSTOM_COMMON_VIN_GetSnsConfig(eSnsType, &pCam->tMipiAttr, &pCam->tSnsAttr, &pCam->tSnsClkAttr, &pCam->tDevAttr, + &pCam->tPipeAttr[pCam->nPipeId], pCam->tChnAttr); + pCam->nDevId = 0; + pCam->nRxDev = 0; + pCam->tSnsClkAttr.nSnsClkIdx = 0; + pCam->tDevBindPipe.nNum = 1; + pCam->tDevBindPipe.nPipeId[0] = pCam->nPipeId; + pCam->ptSnsHdl[pCam->nPipeId] = COMMON_ISP_GetSnsObj(eSnsType); + pCam->eBusType = COMMON_ISP_GetSnsBusType(eSnsType); + pCam->eInputMode = AX_INPUT_MODE_LVDS; + __set_pipe_hdr_mode(&pCam->tDevBindPipe.nHDRSel[0], eHdrMode); + __set_vin_attr(pCam, eSnsType, eHdrMode, eSysMode, pVinParam->bAiispEnable); + for (AX_S32 j = 0; j < AX_VIN_MAX_PIPE_NUM; j++) { + pCam->tPipeInfo[j].ePipeMode = SAMPLE_PIPE_MODE_VIDEO; + pCam->tPipeInfo[j].bAiispEnable = pVinParam->bAiispEnable; + strncpy(pCam->tPipeInfo[j].szBinPath, "null.bin", sizeof(pCam->tPipeInfo[j].szBinPath)); + } + + return 0; +} + +static AX_U32 __sample_case_single_os04a10(AX_CAMERA_T *pCamList, SAMPLE_SNS_TYPE_E eSnsType, + SAMPLE_VIN_PARAM_T *pVinParam, COMMON_SYS_ARGS_T *pCommonArgs) +{ + AX_CAMERA_T *pCam = NULL; + COMMON_VIN_MODE_E eSysMode = pVinParam->eSysMode; + AX_SNS_HDR_MODE_E eHdrMode = pVinParam->eHdrMode; + AX_S32 j = 0; + SAMPLE_LOAD_RAW_NODE_E eLoadRawNode = pVinParam->eLoadRawNode; + pCommonArgs->nCamCnt = 1; + pCam = &pCamList[0]; + pCam->nPipeId = 0; + CUSTOM_COMMON_VIN_GetSnsConfig(eSnsType, &pCam->tMipiAttr, &pCam->tSnsAttr, &pCam->tSnsClkAttr, &pCam->tDevAttr, + &pCam->tPipeAttr[pCam->nPipeId], pCam->tChnAttr); + pCam->nDevId = 0; + pCam->nRxDev = 0; + pCam->tSnsClkAttr.nSnsClkIdx = 0; + pCam->tDevBindPipe.nNum = 1; + pCam->tDevBindPipe.nPipeId[0] = pCam->nPipeId; + pCam->eLoadRawNode = eLoadRawNode; + pCam->ptSnsHdl[pCam->nPipeId] = COMMON_ISP_GetSnsObj(eSnsType); + pCam->eBusType = COMMON_ISP_GetSnsBusType(eSnsType); + pCam->eInputMode = AX_INPUT_MODE_MIPI; + __set_pipe_hdr_mode(&pCam->tDevBindPipe.nHDRSel[0], eHdrMode); + __set_vin_attr(pCam, eSnsType, eHdrMode, eSysMode, pVinParam->bAiispEnable); + for (j = 0; j < pCam->tDevBindPipe.nNum; j++) { + pCam->tPipeInfo[j].ePipeMode = SAMPLE_PIPE_MODE_VIDEO; + pCam->tPipeInfo[j].bAiispEnable = pVinParam->bAiispEnable; + strncpy(pCam->tPipeInfo[j].szBinPath, "null.bin", sizeof(pCam->tPipeInfo[j].szBinPath)); + } + return 0; +} + +static AX_U32 __sample_case_single_sc850sl(AX_CAMERA_T *pCamList, SAMPLE_SNS_TYPE_E eSnsType, + SAMPLE_VIN_PARAM_T *pVinParam, COMMON_SYS_ARGS_T *pCommonArgs) +{ + AX_CAMERA_T *pCam = NULL; + COMMON_VIN_MODE_E eSysMode = pVinParam->eSysMode; + AX_SNS_HDR_MODE_E eHdrMode = pVinParam->eHdrMode; + AX_S32 j = 0; + SAMPLE_LOAD_RAW_NODE_E eLoadRawNode = pVinParam->eLoadRawNode; + pCommonArgs->nCamCnt = 1; + pCam = &pCamList[0]; + pCam->nPipeId = 0; + CUSTOM_COMMON_VIN_GetSnsConfig(eSnsType, &pCam->tMipiAttr, &pCam->tSnsAttr, &pCam->tSnsClkAttr, &pCam->tDevAttr, + &pCam->tPipeAttr[pCam->nPipeId], pCam->tChnAttr); + pCam->nDevId = 0; + pCam->nRxDev = 0; + pCam->tSnsClkAttr.nSnsClkIdx = 0; + pCam->tDevBindPipe.nNum = 1; + pCam->tDevBindPipe.nPipeId[0] = pCam->nPipeId; + pCam->eLoadRawNode = eLoadRawNode; + pCam->ptSnsHdl[pCam->nPipeId] = COMMON_ISP_GetSnsObj(eSnsType); + pCam->eBusType = COMMON_ISP_GetSnsBusType(eSnsType); + pCam->eInputMode = AX_INPUT_MODE_MIPI; + __set_pipe_hdr_mode(&pCam->tDevBindPipe.nHDRSel[0], eHdrMode); + __set_vin_attr(pCam, eSnsType, eHdrMode, eSysMode, pVinParam->bAiispEnable); + for (j = 0; j < pCam->tDevBindPipe.nNum; j++) { + pCam->tPipeInfo[j].ePipeMode = SAMPLE_PIPE_MODE_VIDEO; + pCam->tPipeInfo[j].bAiispEnable = pVinParam->bAiispEnable; + if (pCam->tPipeInfo[j].bAiispEnable) { + if (eHdrMode <= AX_SNS_LINEAR_MODE) { + strncpy(pCam->tPipeInfo[j].szBinPath, "/opt/etc/sc850sl_sdr.bin", + sizeof(pCam->tPipeInfo[j].szBinPath)); + } else { + strncpy(pCam->tPipeInfo[j].szBinPath, "/opt/etc/sc850sl_hdr_2x.bin", + sizeof(pCam->tPipeInfo[j].szBinPath)); + } + } else { + strncpy(pCam->tPipeInfo[j].szBinPath, "null.bin", sizeof(pCam->tPipeInfo[j].szBinPath)); + } + } + return 0; +} + +static AX_U32 __sample_case_double_os04a10(AX_CAMERA_T *pCamList, SAMPLE_SNS_TYPE_E eSnsType, + SAMPLE_VIN_PARAM_T *pVinParam, COMMON_SYS_ARGS_T *pCommonArgs) +{ + AX_CAMERA_T *pCam = NULL; + COMMON_VIN_MODE_E eSysMode = pVinParam->eSysMode; + AX_SNS_HDR_MODE_E eHdrMode = pVinParam->eHdrMode; + AX_S32 j = 0, i = 0; + pCommonArgs->nCamCnt = 2; + + for (i = 0; i < pCommonArgs->nCamCnt; i++) { + pCam = &pCamList[i]; + pCam->nNumber = i; + pCam->nPipeId = i; + CUSTOM_COMMON_VIN_GetSnsConfig(eSnsType, &pCam->tMipiAttr, &pCam->tSnsAttr, &pCam->tSnsClkAttr, &pCam->tDevAttr, + &pCam->tPipeAttr[pCam->nPipeId], pCam->tChnAttr); + + pCam->nDevId = i; + if (i == 0) { + pCam->nRxDev = 0; + pCam->nI2cAddr = 0x36; + } else { + pCam->nRxDev = 1; + pCam->nI2cAddr = 0x36; + } + pCam->tSnsClkAttr.nSnsClkIdx = 0; + pCam->tDevBindPipe.nNum = 1; + pCam->tDevBindPipe.nPipeId[0] = pCam->nPipeId; + pCam->ptSnsHdl[pCam->nPipeId] = COMMON_ISP_GetSnsObj(eSnsType); + pCam->eBusType = COMMON_ISP_GetSnsBusType(eSnsType); + if (eHdrMode == AX_SNS_LINEAR_MODE) + pCam->tSnsAttr.nSettingIndex = 33; + else + pCam->tSnsAttr.nSettingIndex = 34; + pCam->tMipiAttr.eLaneNum = AX_MIPI_DATA_LANE_2; + pCam->eInputMode = AX_INPUT_MODE_MIPI; + __set_pipe_hdr_mode(&pCam->tDevBindPipe.nHDRSel[0], eHdrMode); + __set_vin_attr(pCam, eSnsType, eHdrMode, eSysMode, pVinParam->bAiispEnable); + if (pCam->nPipeId != 0 && eHdrMode == AX_SNS_HDR_2X_MODE) { + pCam->tPipeAttr[pCam->nPipeId].tCompressInfo.enCompressMode = AX_COMPRESS_MODE_NONE; + } + for (j = 0; j < pCam->tDevBindPipe.nNum; j++) { + pCam->tPipeInfo[j].ePipeMode = SAMPLE_PIPE_MODE_VIDEO; + pCam->tPipeInfo[j].bAiispEnable = pVinParam->bAiispEnable; + strncpy(pCam->tPipeInfo[j].szBinPath, "null.bin", sizeof(pCam->tPipeInfo[j].szBinPath)); + } + } + return 0; +} + +static AX_U32 __sample_case_single_sc450ai(AX_CAMERA_T *pCamList, SAMPLE_SNS_TYPE_E eSnsType, + SAMPLE_VIN_PARAM_T *pVinParam, COMMON_SYS_ARGS_T *pCommonArgs) +{ + AX_CAMERA_T *pCam = NULL; + COMMON_VIN_MODE_E eSysMode = pVinParam->eSysMode; + AX_SNS_HDR_MODE_E eHdrMode = pVinParam->eHdrMode; + AX_S32 j = 0; + SAMPLE_LOAD_RAW_NODE_E eLoadRawNode = pVinParam->eLoadRawNode; + pCommonArgs->nCamCnt = 1; + + pCam = &pCamList[0]; + pCam->nPipeId = 0; + CUSTOM_COMMON_VIN_GetSnsConfig(eSnsType, &pCam->tMipiAttr, &pCam->tSnsAttr, &pCam->tSnsClkAttr, &pCam->tDevAttr, + &pCam->tPipeAttr[pCam->nPipeId], pCam->tChnAttr); + pCam->nDevId = 0; + pCam->nRxDev = 0; + pCam->tSnsClkAttr.nSnsClkIdx = 0; + pCam->tDevBindPipe.nNum = 1; + pCam->eLoadRawNode = eLoadRawNode; + pCam->tDevBindPipe.nPipeId[0] = pCam->nPipeId; + pCam->ptSnsHdl[pCam->nPipeId] = COMMON_ISP_GetSnsObj(eSnsType); + pCam->eBusType = COMMON_ISP_GetSnsBusType(eSnsType); + pCam->eInputMode = AX_INPUT_MODE_MIPI; + __set_pipe_hdr_mode(&pCam->tDevBindPipe.nHDRSel[0], eHdrMode); + __set_vin_attr(pCam, eSnsType, eHdrMode, eSysMode, pVinParam->bAiispEnable); + for (j = 0; j < pCam->tDevBindPipe.nNum; j++) { + pCam->tPipeInfo[j].ePipeMode = SAMPLE_PIPE_MODE_VIDEO; + pCam->tPipeInfo[j].bAiispEnable = pVinParam->bAiispEnable; + if (pCam->tPipeInfo[j].bAiispEnable) { + if (eHdrMode <= AX_SNS_LINEAR_MODE) { + strncpy(pCam->tPipeInfo[j].szBinPath, "/opt/etc/sc450ai_sdr_dual3dnr.bin", + sizeof(pCam->tPipeInfo[j].szBinPath)); + } else { + strncpy(pCam->tPipeInfo[j].szBinPath, "/opt/etc/sc450ai_hdr_2x_ainr.bin", + sizeof(pCam->tPipeInfo[j].szBinPath)); + } + } else { + strncpy(pCam->tPipeInfo[j].szBinPath, "null.bin", sizeof(pCam->tPipeInfo[j].szBinPath)); + } + } + return 0; +} + +static AX_U32 __sample_case_double_sc450ai(AX_CAMERA_T *pCamList, SAMPLE_SNS_TYPE_E eSnsType, + SAMPLE_VIN_PARAM_T *pVinParam, COMMON_SYS_ARGS_T *pCommonArgs) +{ + AX_CAMERA_T *pCam = NULL; + COMMON_VIN_MODE_E eSysMode = pVinParam->eSysMode; + AX_SNS_HDR_MODE_E eHdrMode = pVinParam->eHdrMode; + AX_S32 j = 0, i = 0; + pCommonArgs->nCamCnt = 2; + + for (i = 0; i < pCommonArgs->nCamCnt; i++) { + pCam = &pCamList[i]; + pCam->nNumber = i; + pCam->nPipeId = i; + CUSTOM_COMMON_VIN_GetSnsConfig(eSnsType, &pCam->tMipiAttr, &pCam->tSnsAttr, &pCam->tSnsClkAttr, &pCam->tDevAttr, + &pCam->tPipeAttr[pCam->nPipeId], pCam->tChnAttr); + + pCam->nDevId = i; + if (i == 0) { + pCam->nRxDev = 0; + pCam->nI2cAddr = 0x30; + } else { + pCam->nRxDev = 1; + pCam->nI2cAddr = 0x30; + } + pCam->tSnsClkAttr.nSnsClkIdx = 0; + pCam->tDevBindPipe.nNum = 1; + pCam->tDevBindPipe.nPipeId[0] = pCam->nPipeId; + pCam->ptSnsHdl[pCam->nPipeId] = COMMON_ISP_GetSnsObj(eSnsType); + pCam->eBusType = COMMON_ISP_GetSnsBusType(eSnsType); + if (eHdrMode == AX_SNS_LINEAR_MODE) + pCam->tSnsAttr.nSettingIndex = 33; + else + pCam->tSnsAttr.nSettingIndex = 35; + pCam->tMipiAttr.eLaneNum = AX_MIPI_DATA_LANE_2; + pCam->eInputMode = AX_INPUT_MODE_MIPI; + __set_pipe_hdr_mode(&pCam->tDevBindPipe.nHDRSel[0], eHdrMode); + __set_vin_attr(pCam, eSnsType, eHdrMode, eSysMode, pVinParam->bAiispEnable); + if (pCam->nPipeId != 0 && eHdrMode == AX_SNS_HDR_2X_MODE) { + pCam->tPipeAttr[pCam->nPipeId].tCompressInfo.enCompressMode = AX_COMPRESS_MODE_NONE; + } + for (j = 0; j < pCam->tDevBindPipe.nNum; j++) { + pCam->tPipeInfo[j].ePipeMode = SAMPLE_PIPE_MODE_VIDEO; + pCam->tPipeInfo[j].bAiispEnable = pVinParam->bAiispEnable; + if (pCam->tPipeInfo[j].bAiispEnable) { + if (eHdrMode <= AX_SNS_LINEAR_MODE) { + strncpy(pCam->tPipeInfo[j].szBinPath, "/opt/etc/sc450ai_sdr_dual3dnr.bin", + sizeof(pCam->tPipeInfo[j].szBinPath)); + } else { + strncpy(pCam->tPipeInfo[j].szBinPath, "/opt/etc/sc450ai_hdr_2x_ainr.bin", + sizeof(pCam->tPipeInfo[j].szBinPath)); + } + } else { + strncpy(pCam->tPipeInfo[j].szBinPath, "null.bin", sizeof(pCam->tPipeInfo[j].szBinPath)); + } + } + } + return 0; +} + +static AX_U32 __sample_case_double_os04a10_and_bt656(AX_CAMERA_T *pCamList, SAMPLE_VIN_PARAM_T *pVinParam, + COMMON_SYS_ARGS_T *pCommonArgs) +{ + AX_CAMERA_T *pCam = NULL; + COMMON_VIN_MODE_E eSysMode = pVinParam->eSysMode; + AX_SNS_HDR_MODE_E eHdrMode = pVinParam->eHdrMode; + SAMPLE_SNS_TYPE_E eSnsType; + AX_S32 j = 0, i = 0; + pCommonArgs->nCamCnt = 3; + + for (i = 0; i < pCommonArgs->nCamCnt; i++) { + if (i < 2) + eSnsType = OMNIVISION_OS04A10; + else { + eSnsType = SAMPLE_SNS_BT656; + eHdrMode = AX_SNS_LINEAR_MODE; + } + pCam = &pCamList[i]; + pCam->nNumber = i; + pCam->nPipeId = i; + CUSTOM_COMMON_VIN_GetSnsConfig(eSnsType, &pCam->tMipiAttr, &pCam->tSnsAttr, &pCam->tSnsClkAttr, &pCam->tDevAttr, + &pCam->tPipeAttr[pCam->nPipeId], pCam->tChnAttr); + + pCam->nDevId = i; + pCam->nRxDev = i; + if (i == 0) { + pCam->nI2cAddr = 0x36; + } else if (i == 1) { + pCam->nI2cAddr = 0x36; + } + pCam->tSnsClkAttr.nSnsClkIdx = 0; + pCam->tDevBindPipe.nNum = 1; + pCam->tDevBindPipe.nPipeId[0] = pCam->nPipeId; + pCam->ptSnsHdl[pCam->nPipeId] = COMMON_ISP_GetSnsObj(eSnsType); + pCam->eBusType = COMMON_ISP_GetSnsBusType(eSnsType); + if (eHdrMode == AX_SNS_LINEAR_MODE) + pCam->tSnsAttr.nSettingIndex = 33; + else + pCam->tSnsAttr.nSettingIndex = 34; + pCam->tMipiAttr.eLaneNum = AX_MIPI_DATA_LANE_2; + pCam->eInputMode = AX_INPUT_MODE_MIPI; + if (i == 2) { + pCam->eInputMode = AX_INPUT_MODE_BT656; + pCam->bRegisterSns = AX_FALSE; + } + __set_pipe_hdr_mode(&pCam->tDevBindPipe.nHDRSel[0], eHdrMode); + __set_vin_attr(pCam, eSnsType, eHdrMode, eSysMode, pVinParam->bAiispEnable); + for (j = 0; j < pCam->tDevBindPipe.nNum; j++) { + pCam->tPipeInfo[j].ePipeMode = SAMPLE_PIPE_MODE_VIDEO; + pCam->tPipeInfo[j].bAiispEnable = pVinParam->bAiispEnable; + if (pCam->tPipeInfo[j].bAiispEnable && i < 2) { + if (eHdrMode <= AX_SNS_LINEAR_MODE) { + strncpy(pCam->tPipeInfo[j].szBinPath, "/opt/etc/os04a10_sdr_dual3dnr.bin", + sizeof(pCam->tPipeInfo[j].szBinPath)); + } else { + strncpy(pCam->tPipeInfo[j].szBinPath, "/opt/etc/os04a10_hdr_2x_ainr.bin", + sizeof(pCam->tPipeInfo[j].szBinPath)); + } + } else { + strncpy(pCam->tPipeInfo[j].szBinPath, "null.bin", sizeof(pCam->tPipeInfo[j].szBinPath)); + } + } + } + return 0; +} + +static AX_U32 __sample_case_single_s5kjn1sq03(AX_CAMERA_T *pCamList, SAMPLE_SNS_TYPE_E eSnsType, + SAMPLE_VIN_PARAM_T *pVinParam, COMMON_SYS_ARGS_T *pCommonArgs) +{ + AX_CAMERA_T *pCam = NULL; + COMMON_VIN_MODE_E eSysMode = pVinParam->eSysMode; + AX_SNS_HDR_MODE_E eHdrMode = pVinParam->eHdrMode; + AX_S32 j = 0; + SAMPLE_LOAD_RAW_NODE_E eLoadRawNode = pVinParam->eLoadRawNode; + pCommonArgs->nCamCnt = 1; + pCam = &pCamList[0]; + pCam->nPipeId = 0; + CUSTOM_COMMON_VIN_GetSnsConfig(eSnsType, &pCam->tMipiAttr, &pCam->tSnsAttr, &pCam->tSnsClkAttr, &pCam->tDevAttr, + &pCam->tPipeAttr[pCam->nPipeId], pCam->tChnAttr); + pCam->nDevId = 0; + pCam->nRxDev = 0; + pCam->tSnsClkAttr.nSnsClkIdx = 0; + pCam->tDevBindPipe.nNum = 1; + pCam->tDevBindPipe.nPipeId[0] = pCam->nPipeId; + pCam->eLoadRawNode = eLoadRawNode; + pCam->ptSnsHdl[pCam->nPipeId] = COMMON_ISP_GetSnsObj(eSnsType); + pCam->eBusType = COMMON_ISP_GetSnsBusType(eSnsType); + pCam->eInputMode = AX_INPUT_MODE_MIPI; + __set_pipe_hdr_mode(&pCam->tDevBindPipe.nHDRSel[0], eHdrMode); + __set_vin_attr(pCam, eSnsType, eHdrMode, eSysMode, pVinParam->bAiispEnable); + for (j = 0; j < pCam->tDevBindPipe.nNum; j++) { + pCam->tPipeInfo[j].ePipeMode = SAMPLE_PIPE_MODE_VIDEO; + pCam->tPipeInfo[j].bAiispEnable = pVinParam->bAiispEnable; + strncpy(pCam->tPipeInfo[j].szBinPath, "null.bin", sizeof(pCam->tPipeInfo[j].szBinPath)); + } + return 0; +} + + + + + +static AX_U32 __sample_case_config(AX_CAMERA_T *gCams, SAMPLE_VIN_PARAM_T *pVinParam, + COMMON_SYS_ARGS_T *pCommonArgs, COMMON_SYS_ARGS_T *pPrivArgs) +{ + AX_CAMERA_T *pCamList = gCams; + SAMPLE_SNS_TYPE_E eSnsType = OMNIVISION_OS04A10; + + COMM_ISP_PRT("eSysCase %d, eSysMode %d, eHdrMode %d, bAiispEnable %d\n", pVinParam->eSysCase, pVinParam->eSysMode, + pVinParam->eHdrMode, pVinParam->bAiispEnable); + + switch (pVinParam->eSysCase) { + case SYS_CASE_SINGLE_DVP: + eSnsType = SAMPLE_SNS_DVP; + /* comm pool config */ + __cal_dump_pool(gtSysCommPoolSingleDVPSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pCommonArgs->nPoolCfgCnt = sizeof(gtSysCommPoolSingleDVPSdr) / sizeof(gtSysCommPoolSingleDVPSdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolSingleDVPSdr; + + /* private pool config */ + __cal_dump_pool(gtSysPrivatePoolSingleDVPSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = sizeof(gtSysPrivatePoolSingleDVPSdr) / sizeof(gtSysPrivatePoolSingleDVPSdr[0]); + pPrivArgs->pPoolCfg = gtSysPrivatePoolSingleDVPSdr; + + /* cams config */ + __sample_case_single_dvp(pCamList, eSnsType, pVinParam, pCommonArgs); + break; + case SYS_CASE_SINGLE_BT601: + eSnsType = SAMPLE_SNS_BT601; + /* comm pool config */ + __cal_dump_pool(gtSysCommPoolSingleBTSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pCommonArgs->nPoolCfgCnt = sizeof(gtSysCommPoolSingleBTSdr) / sizeof(gtSysCommPoolSingleBTSdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolSingleBTSdr; + + /* private pool config */ + __cal_dump_pool(gtSysPrivatePoolSingleBTSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = sizeof(gtSysPrivatePoolSingleBTSdr) / sizeof(gtSysPrivatePoolSingleBTSdr[0]); + pPrivArgs->pPoolCfg = gtSysPrivatePoolSingleBTSdr; + + /* cams config */ + __sample_case_single_bt656(pCamList, eSnsType, pVinParam, pCommonArgs); + break; + case SYS_CASE_SINGLE_BT656: + eSnsType = SAMPLE_SNS_BT656; + /* comm pool config */ + __cal_dump_pool(gtSysCommPoolSingleBTSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pCommonArgs->nPoolCfgCnt = sizeof(gtSysCommPoolSingleBTSdr) / sizeof(gtSysCommPoolSingleBTSdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolSingleBTSdr; + + /* private pool config */ + __cal_dump_pool(gtSysPrivatePoolSingleBTSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = sizeof(gtSysPrivatePoolSingleBTSdr) / sizeof(gtSysPrivatePoolSingleBTSdr[0]); + pPrivArgs->pPoolCfg = gtSysPrivatePoolSingleBTSdr; + + /* cams config */ + __sample_case_single_bt656(pCamList, eSnsType, pVinParam, pCommonArgs); + break; + case SYS_CASE_SINGLE_BT1120: + eSnsType = SAMPLE_SNS_BT1120; + /* comm pool config */ + __cal_dump_pool(gtSysCommPoolSingleBTSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pCommonArgs->nPoolCfgCnt = sizeof(gtSysCommPoolSingleBTSdr) / sizeof(gtSysCommPoolSingleBTSdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolSingleBTSdr; + + /* private pool config */ + __cal_dump_pool(gtSysPrivatePoolSingleBTSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = sizeof(gtSysPrivatePoolSingleBTSdr) / sizeof(gtSysPrivatePoolSingleBTSdr[0]); + pPrivArgs->pPoolCfg = gtSysPrivatePoolSingleBTSdr; + + /* cams config */ + __sample_case_single_bt1120(pCamList, eSnsType, pVinParam, pCommonArgs); + break; + case SYS_CASE_SINGLE_LVDS: + eSnsType = SAMPLE_SNS_LVDS; + /* comm pool config */ + __cal_dump_pool(gtSysCommPoolSingleLVDSSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pCommonArgs->nPoolCfgCnt = sizeof(gtSysCommPoolSingleLVDSSdr) / sizeof(gtSysCommPoolSingleLVDSSdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolSingleLVDSSdr; + + /* private pool config */ + __cal_dump_pool(gtSysPrivatePoolSingleLVDSSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = sizeof(gtSysPrivatePoolSingleLVDSSdr) / sizeof(gtSysPrivatePoolSingleLVDSSdr[0]); + pPrivArgs->pPoolCfg = gtSysPrivatePoolSingleLVDSSdr; + + /* cams config */ + __sample_case_single_lvds(pCamList, eSnsType, pVinParam, pCommonArgs); + break; + case SAMPLE_VIN_SINGLE_OS04A10: + eSnsType = OMNIVISION_OS04A10; + /* comm pool config */ + __cal_dump_pool(gtSysCommPoolSingleOs04a10Sdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pCommonArgs->nPoolCfgCnt = sizeof(gtSysCommPoolSingleOs04a10Sdr) / sizeof(gtSysCommPoolSingleOs04a10Sdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolSingleOs04a10Sdr; + + /* private pool config */ + __cal_dump_pool(gtPrivatePoolSingleOs04a10Sdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = sizeof(gtPrivatePoolSingleOs04a10Sdr) / sizeof(gtPrivatePoolSingleOs04a10Sdr[0]); + pPrivArgs->pPoolCfg = gtPrivatePoolSingleOs04a10Sdr; + + /* cams config */ + __sample_case_single_os04a10(pCamList, eSnsType, pVinParam, pCommonArgs); + break; + case SAMPLE_VIN_DOUBLE_OS04A10: + eSnsType = OMNIVISION_OS04A10; + /* comm pool config */ + if (AX_SNS_LINEAR_MODE == pVinParam->eHdrMode) { + __cal_dump_pool(gtSysCommPoolDoubleOs04a10Sdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pCommonArgs->nPoolCfgCnt = + sizeof(gtSysCommPoolDoubleOs04a10Sdr) / sizeof(gtSysCommPoolDoubleOs04a10Sdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolDoubleOs04a10Sdr; + } else { + __cal_dump_pool(gtSysCommPoolDoubleOs04a10Hdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pCommonArgs->nPoolCfgCnt = + sizeof(gtSysCommPoolDoubleOs04a10Hdr) / sizeof(gtSysCommPoolDoubleOs04a10Hdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolDoubleOs04a10Hdr; + } + + /* private pool config */ + if (AX_SNS_LINEAR_MODE == pVinParam->eHdrMode) { + __cal_dump_pool(gtPrivatePoolDoubleOs04a10Sdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = + sizeof(gtPrivatePoolDoubleOs04a10Sdr) / sizeof(gtPrivatePoolDoubleOs04a10Sdr[0]); + pPrivArgs->pPoolCfg = gtPrivatePoolDoubleOs04a10Sdr; + } else if (AX_SNS_LINEAR_ONLY_MODE == pVinParam->eHdrMode) { + __cal_dump_pool(gtPrivatePoolDoubleOs04a10SdrOnly, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = + sizeof(gtPrivatePoolDoubleOs04a10SdrOnly) / sizeof(gtPrivatePoolDoubleOs04a10SdrOnly[0]); + pPrivArgs->pPoolCfg = gtPrivatePoolDoubleOs04a10SdrOnly; + } else { + __cal_dump_pool(gtPrivatePoolDoubleOs04a10Hdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = + sizeof(gtPrivatePoolDoubleOs04a10Hdr) / sizeof(gtPrivatePoolDoubleOs04a10Hdr[0]); + pPrivArgs->pPoolCfg = gtPrivatePoolDoubleOs04a10Hdr; + } + + /* cams config */ + __sample_case_double_os04a10(pCamList, eSnsType, pVinParam, pCommonArgs); + break; + case SAMPLE_VIN_DOUBLE_SC450AI: + eSnsType = SMARTSENS_SC450AI; + /* comm pool config */ + if (AX_SNS_LINEAR_MODE == pVinParam->eHdrMode) { + __cal_dump_pool(gtSysCommPoolDoubleSc450aiSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pCommonArgs->nPoolCfgCnt = + sizeof(gtSysCommPoolDoubleSc450aiSdr) / sizeof(gtSysCommPoolDoubleSc450aiSdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolDoubleSc450aiSdr; + } else { + __cal_dump_pool(gtSysCommPoolDoubleSc450aiHdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pCommonArgs->nPoolCfgCnt = + sizeof(gtSysCommPoolDoubleSc450aiHdr) / sizeof(gtSysCommPoolDoubleSc450aiHdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolDoubleSc450aiHdr; + } + + /* private pool config */ + if (AX_SNS_LINEAR_MODE == pVinParam->eHdrMode) { + __cal_dump_pool(gtPrivatePoolDoubleSc450aiSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = + sizeof(gtPrivatePoolDoubleSc450aiSdr) / sizeof(gtPrivatePoolDoubleSc450aiSdr[0]); + pPrivArgs->pPoolCfg = gtPrivatePoolDoubleSc450aiSdr; + } else { + __cal_dump_pool(gtPrivatePoolDoubleSc450aiHdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = + sizeof(gtPrivatePoolDoubleSc450aiHdr) / sizeof(gtPrivatePoolDoubleSc450aiHdr[0]); + pPrivArgs->pPoolCfg = gtPrivatePoolDoubleSc450aiHdr; + } + + /* cams config */ + __sample_case_double_sc450ai(pCamList, eSnsType, pVinParam, pCommonArgs); + break; + case SAMPLE_VIN_SINGLE_SC450AI: + eSnsType = SMARTSENS_SC450AI; + /* comm pool config */ + __cal_dump_pool(gtSysCommPoolSingleOs450aiSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pCommonArgs->nPoolCfgCnt = sizeof(gtSysCommPoolSingleOs450aiSdr) / sizeof(gtSysCommPoolSingleOs450aiSdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolSingleOs450aiSdr; + + /* private pool config */ + __cal_dump_pool(gtPrivatePoolSingleOs450aiSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = sizeof(gtPrivatePoolSingleOs450aiSdr) / sizeof(gtPrivatePoolSingleOs450aiSdr[0]); + pPrivArgs->pPoolCfg = gtPrivatePoolSingleOs450aiSdr; + + /* cams config */ + __sample_case_single_sc450ai(pCamList, eSnsType, pVinParam, pCommonArgs); + break; + case SAMPLE_VIN_SINGLE_SC850SL: + eSnsType = SMARTSENS_SC850SL; + /* comm pool config */ + __cal_dump_pool(gtSysCommPoolSingleSc850SlSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pCommonArgs->nPoolCfgCnt = sizeof(gtSysCommPoolSingleSc850SlSdr) / sizeof(gtSysCommPoolSingleSc850SlSdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolSingleSc850SlSdr; + + /* private pool config */ + __cal_dump_pool(gtPrivatePoolSingleSc850SlSdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = sizeof(gtPrivatePoolSingleSc850SlSdr) / sizeof(gtPrivatePoolSingleSc850SlSdr[0]); + pPrivArgs->pPoolCfg = gtPrivatePoolSingleSc850SlSdr; + + /* cams config */ + __sample_case_single_sc850sl(pCamList, eSnsType, pVinParam, pCommonArgs); + break; + case SAMPLE_VIN_DOUBLE_OS04A10_AND_BT656: + /* comm pool config */ + if (AX_SNS_LINEAR_MODE == pVinParam->eHdrMode) { + __cal_dump_pool(gtSysCommPoolDoubleOs04a10Bt656Sdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pCommonArgs->nPoolCfgCnt = + sizeof(gtSysCommPoolDoubleOs04a10Bt656Sdr) / sizeof(gtSysCommPoolDoubleOs04a10Bt656Sdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolDoubleOs04a10Bt656Sdr; + } else { + __cal_dump_pool(gtSysCommPoolDoubleOs04a10Bt656Hdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pCommonArgs->nPoolCfgCnt = + sizeof(gtSysCommPoolDoubleOs04a10Bt656Hdr) / sizeof(gtSysCommPoolDoubleOs04a10Bt656Hdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolDoubleOs04a10Bt656Hdr; + } + + /* private pool config */ + if (AX_SNS_LINEAR_MODE == pVinParam->eHdrMode) { + __cal_dump_pool(gtPrivatePoolDoubleOs04a10Bt656Sdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = + sizeof(gtPrivatePoolDoubleOs04a10Bt656Sdr) / sizeof(gtPrivatePoolDoubleOs04a10Bt656Sdr[0]); + pPrivArgs->pPoolCfg = gtPrivatePoolDoubleOs04a10Bt656Sdr; + } else { + __cal_dump_pool(gtPrivatePoolDoubleOs04a10Bt656Hdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = + sizeof(gtPrivatePoolDoubleOs04a10Bt656Hdr) / sizeof(gtPrivatePoolDoubleOs04a10Bt656Hdr[0]); + pPrivArgs->pPoolCfg = gtPrivatePoolDoubleOs04a10Bt656Hdr; + } + + /* cams config */ + __sample_case_double_os04a10_and_bt656(pCamList, pVinParam, pCommonArgs); + break; + case SAMPLE_VIN_SINGLE_S5KJN1SQ03: + eSnsType = SAMSUNG_S5KJN1SQ03; + /* comm pool config */ + __cal_dump_pool(gtSysCommPoolSingles5kjn1sq03Sdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pCommonArgs->nPoolCfgCnt = + sizeof(gtSysCommPoolSingles5kjn1sq03Sdr) / sizeof(gtSysCommPoolSingles5kjn1sq03Sdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolSingles5kjn1sq03Sdr; + + /* private pool config */ + __cal_dump_pool(gtPrivatePoolSingles5kjn1sq03Sdr, pVinParam->eHdrMode, pVinParam->nDumpFrameNum); + pPrivArgs->nPoolCfgCnt = + sizeof(gtPrivatePoolSingles5kjn1sq03Sdr) / sizeof(gtPrivatePoolSingles5kjn1sq03Sdr[0]); + pPrivArgs->pPoolCfg = gtPrivatePoolSingles5kjn1sq03Sdr; + + /* cams config */ + __sample_case_single_s5kjn1sq03(pCamList, eSnsType, pVinParam, pCommonArgs); + break; + case SAMPLE_VIN_SINGLE_DUMMY: + default: + eSnsType = SAMPLE_SNS_DUMMY; + /* pool config */ + pCommonArgs->nPoolCfgCnt = sizeof(gtSysCommPoolSingleDummySdr) / sizeof(gtSysCommPoolSingleDummySdr[0]); + pCommonArgs->pPoolCfg = gtSysCommPoolSingleDummySdr; + + /* private pool config */ + pPrivArgs->nPoolCfgCnt = sizeof(gtPrivatePoolSingleDummySdr) / sizeof(gtPrivatePoolSingleDummySdr[0]); + pPrivArgs->pPoolCfg = gtPrivatePoolSingleDummySdr; + + /* cams config */ + __sample_case_single_dummy(pCamList, eSnsType, pVinParam, pCommonArgs); + break; + } + + return 0; +} + +typedef enum { + AX_SENSOR_NONT = 0b00000, + AX_SENSOR_NPU_ENABLE = 0b00001, + AX_SENSOR_CAM_ENABLE = 0b00010, + AX_SENSOR_CAM_POOL_ENABLE = 0b00100, + AX_SENSOR_CAM_OPEN = 0b01000, + AX_SENSOR_GET_FRAME_THREAD = 0b10000, +} AX_SENSOR_STATUS; + +struct axera_camera_t { + COMMON_SYS_ARGS_T tPrivArgs; + COMMON_SYS_ARGS_T tCommonArgs; + AX_CAMERA_T gCams; + SAMPLE_VIN_PARAM_T VinParam; + AX_IMG_INFO_T ax_img; + AX_VIDEO_FRAME_T out_img; + int Chn; +} axera_obj; + +static int camera_capture_callback_set(struct camera_t* camera, vcamera_frame_get pcallback) +{ + if (camera->state_ == CAMERA_SATTE_CAP) { + SLOGW("Set capture callback failed"); + return -1; + } + camera->pcallback_ = pcallback; + return 0; +} + +static void* camera_capture_thread(void* param) +{ + int Ret = -1; + camera_t* camera = (camera_t*)param; + struct v4l2_buffer EnQueueBuf; + struct v4l2_buffer DeQueueBuf; + + SLOGI("Start capture"); + + while (camera->state_ & AX_SENSOR_GET_FRAME_THREAD) { + AX_S32 axRet = AX_VIN_GetYuvFrame(axera_obj.gCams.nPipeId, axera_obj.Chn, &axera_obj.ax_img, 500); + if (axRet == 0) + { + // axera_obj.ax_img.tFrameInfo.stVFrame.u64VirAddr[0] = (AX_U64)AX_POOL_GetBlockVirAddr(axera_obj.ax_img.tFrameInfo.stVFrame.u32BlkId[0]); + // axera_obj.ax_img.tFrameInfo.stVFrame.u64PhyAddr[0] = AX_POOL_Handle2PhysAddr(axera_obj.ax_img.tFrameInfo.stVFrame.u32BlkId[0]); + // AX_S32 AX_IVPS_CropResizeTdp(const AX_VIDEO_FRAME_T *ptSrc, AX_VIDEO_FRAME_T *ptDst, + // const AX_IVPS_CROP_RESIZE_ATTR_T *ptAttr); + AX_IVPS_CROP_RESIZE_ATTR_T tAttr = {0}; + AX_IVPS_CropResizeTdp(&axera_obj.ax_img.tFrameInfo.stVFrame, &axera_obj.out_img, &tAttr); + AX_VIN_ReleaseYuvFrame(axera_obj.gCams.nPipeId, axera_obj.Chn, &axera_obj.ax_img); + camera->pcallback_((void*)axera_obj.out_img.u64VirAddr[0], axera_obj.out_img.u32Width, axera_obj.out_img.u32Height, + axera_obj.out_img.u32FrameSize, camera->ctx_); + } + else + { + // ALOGD("get ax img error! code:0x%x", axRet); + usleep(10 * 1000); + } + } + + SLOGI("Stop capture"); + + return NULL; +} + +static int camera_capture_start(struct camera_t* camera) +{ + SLOGI("Start capture thread"); + if (!camera->pcallback_) { + SLOGW("Capture callback not set, start faild"); + return -1; + } + if (!(camera->state_ & AX_SENSOR_CAM_OPEN)) { + SLOGW("Camera not open, start faild"); + return -1; + } + camera->state_ |= AX_SENSOR_GET_FRAME_THREAD; + pthread_create(&camera->capture_thread_id_, NULL, camera_capture_thread, camera); + + return 0; +} + +static int camera_capture_stop(struct camera_t* camera) +{ + SLOGI("Stop capture thread"); + camera->state_ &= ~((int)AX_SENSOR_GET_FRAME_THREAD); + pthread_join(camera->capture_thread_id_, NULL); + SLOGI("Capture thread stop"); + return 0; +} + +static void camera_set_ctx(struct camera_t* camera, void* ctx) +{ + camera->ctx_ = ctx; +} + +int axera_camera_open_from(camera_t* camera) +{ + int Ret = -1; + AX_S32 axRet; + if (camera == NULL) return -1; + /* Check whether the camera is already open or in an error state */ + SLOGI("Open camera %s...", camera->dev_name_); + if (camera->state_ & AX_SENSOR_CAM_OPEN) { + SLOGE("Error: camera was open or meet error, now state is: %d", camera->state_); + goto ErrorHandle; + } + axera_obj.VinParam.eSysCase = SAMPLE_VIN_BUTT; + for (int i = 0; i < sizeof(axera_camera_index) / sizeof(axera_camera_index[0]); i++) + { + if(strcmp(axera_camera_index[i].name, camera->dev_name_) == 0) + { + axera_obj.VinParam.eSysCase = axera_camera_index[i].index; + break; + } + } + if(axera_obj.VinParam.eSysCase == SAMPLE_VIN_BUTT) + { + SLOGE("Error: camera not support %s", camera->dev_name_); + return -10; + } + + axera_obj.VinParam.eSysMode = COMMON_VIN_SENSOR; + axera_obj.VinParam.eHdrMode = AX_SNS_LINEAR_MODE; + axera_obj.VinParam.bAiispEnable = AX_TRUE; + // axera_obj.gCams.tChnAttr + __sample_case_config(&axera_obj.gCams, &axera_obj.VinParam, &axera_obj.tCommonArgs, &axera_obj.tPrivArgs); + COMMON_SYS_Init(&axera_obj.tCommonArgs); + COMMON_NPU_Init(); + AX_IVPS_Init(); + axRet = COMMON_CAM_Init(); + if (axRet) { + COMM_ISP_PRT("COMMON_CAM_Init fail, ret:0x%x", axRet); + return -1; + } + camera->state_ |= AX_SENSOR_CAM_ENABLE; + axRet = COMMON_CAM_PrivPoolInit(&axera_obj.tPrivArgs); + if (axRet) { + COMM_ISP_PRT("COMMON_CAM_PrivPoolInit fail, ret:0x%x", axRet); + return -2; + } + camera->state_ |= AX_SENSOR_CAM_POOL_ENABLE; + /* Step5: Cam Open */ + axRet = COMMON_CAM_Open(&axera_obj.gCams, axera_obj.tCommonArgs.nCamCnt); + if (axRet) { + COMM_ISP_PRT("COMMON_CAM_Open fail, ret:0x%x", axRet); + return -3; + } + axera_obj.Chn = AX_VIN_CHN_ID_MAIN; + camera->state_ |= AX_SENSOR_CAM_OPEN; + + axera_obj.out_img.u32Width = camera->width_; + axera_obj.out_img.u32Height = camera->height_; + axera_obj.out_img.u32PicStride[0] = ALIGN_UP(camera->width_, 16); + axera_obj.out_img.enImgFormat = AX_FORMAT_YUV420_SEMIPLANAR; + axera_obj.out_img.u32FrameSize = camera->width_ * camera->height_ * 3 / 2; + AX_SYS_MemAlloc(&axera_obj.out_img.u64PhyAddr[0], (AX_VOID **)&axera_obj.out_img.u64VirAddr[0], ALIGN_UP(axera_obj.out_img.u32FrameSize, 0x100), 0x100, (AX_S8 *)"StackFlow_camera_output_buff"); + + camera->camera_capture_callback_set = camera_capture_callback_set; + camera->camera_capture_start = camera_capture_start; + camera->camera_capture_stop = camera_capture_stop; + camera->camera_set_ctx = camera_set_ctx; + camera->is_alloc_ = 0; + return 0; + +ErrorHandle: + SLOGE("Camera open meet error, now handle it"); + return -1; +} + +camera_t* axera_camera_open(const char* pdev_name, int width, int height, int fps) +{ + int Ret = -1; + camera_t* camera = (camera_t*)malloc(sizeof(camera_t)); + if (camera == NULL) return NULL; + memset(camera, 0, sizeof(camera_t)); + camera->buffer_cnt_ = CONFIG_CAPTURE_BUF_CNT; + + int CopyLen = strlen(pdev_name); + if (CopyLen > CONFIG_DEVNAME_LEN - 1) { + SLOGE("Error: device name length over limit: %d", CopyLen); + goto ErrorHandle; + } + memset(camera->dev_name_, 0, CONFIG_DEVNAME_LEN); + memcpy(camera->dev_name_, pdev_name, CopyLen); + + camera->width_ = width; + camera->height_ = height; + camera->capture_fps_ = fps; + + Ret = axera_camera_open_from(camera); + if (Ret) { + goto ErrorHandle; + } + camera->is_alloc_ = 1; + return camera; + +ErrorHandle: + SLOGE("Camera open meet error, now handle it"); + free(camera); + return NULL; +} + +int axera_camera_close(camera_t* camera) +{ + if (camera == NULL) return -1; + if (camera->state_ & AX_SENSOR_CAM_OPEN) { + COMMON_CAM_Close(&axera_obj.gCams, axera_obj.tCommonArgs.nCamCnt); + camera->state_ &= ~((int)AX_SENSOR_CAM_OPEN); + } + + if (camera->state_ & AX_SENSOR_CAM_ENABLE) { + COMMON_CAM_Deinit(); + camera->state_ &= ~((int)AX_SENSOR_CAM_ENABLE); + } + camera->state_ = AX_SENSOR_NONT; + AX_IVPS_Deinit(); + COMMON_SYS_DeInit(); + if (camera->is_alloc_) free(camera); + + SLOGI("camera closed"); + + return 0; +} \ No newline at end of file diff --git a/projects/llm_framework/main_camera/src/axera_camera.h b/projects/llm_framework/main_camera/src/axera_camera.h new file mode 100644 index 0000000..6035c8c --- /dev/null +++ b/projects/llm_framework/main_camera/src/axera_camera.h @@ -0,0 +1,35 @@ +/* + * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD + * + * SPDX-License-Identifier: MIT + */ +#ifndef AXERA_CAMERA_H +#define AXERA_CAMERA_H + +#if __cplusplus +extern "C" { +#endif +/** + * Open the axera_camera + * @pdev_name Device node + * Return value: NULL for failure + */ +camera_t* axera_camera_open(const char* pdev_name, int width, int height, int fps); + +/** + * Open the axera_camera from config + * @pDevName Device node + * Return value: 0 for success, -1 for failure + */ +int axera_camera_open_from(camera_t* camera); + +/** + * Close the axera_camera + * Return value: 0 for success, -1 for failure + */ +int axera_camera_close(camera_t* camera); + +#if __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/projects/llm_framework/main_camera/src/camera.h b/projects/llm_framework/main_camera/src/camera.h index 71df980..8aab531 100644 --- a/projects/llm_framework/main_camera/src/camera.h +++ b/projects/llm_framework/main_camera/src/camera.h @@ -14,7 +14,7 @@ #if __cplusplus extern "C" { #endif -typedef void (*vcamera_frame_get)(uint8_t* pdata, uint32_t width, uint32_t height, uint32_t length, void* ctx); +typedef void (*vcamera_frame_get)(void* pdata, uint32_t width, uint32_t height, uint32_t length, void* ctx); typedef enum { CAMERA_STATE_CLOSE, CAMERA_SATTE_OPEN, CAMERA_SATTE_CAP, CAMERA_STATE_ERR } CAMERA_STATE_t; typedef struct { @@ -32,7 +32,7 @@ typedef struct camera_t { uint32_t height_; CAMERA_Buffer_t* pcamera_buffer_; vcamera_frame_get pcallback_; - CAMERA_STATE_t state_; /* 0 Not open, 1 Turn on the camera, 2 Start capturing, + int state_; /* 0 Not open, 1 Turn on the camera, 2 Start capturing, 3 Error */ pthread_t capture_thread_id_; void* ctx_; diff --git a/projects/llm_framework/main_camera/src/main.cpp b/projects/llm_framework/main_camera/src/main.cpp index 07545b3..ceefc15 100644 --- a/projects/llm_framework/main_camera/src/main.cpp +++ b/projects/llm_framework/main_camera/src/main.cpp @@ -13,6 +13,7 @@ #include #include "../../../../SDK/components/utilities/include/sample_log.h" #include "camera.h" +#include "axera_camera.h" #include #include @@ -25,6 +26,10 @@ static void __sigint(int iSigNo) typedef std::function task_callback_t; +typedef camera_t* (*hal_camera_open_fun)(const char* pdev_name, int width, int height, int fps); +typedef int (*hal_camera_close_fun)(camera_t* camera); + + #define CONFIG_AUTO_SET(obj, key) \ if (config_body.contains(#key)) \ mode_config_.key = config_body[#key]; \ @@ -34,7 +39,8 @@ typedef std::function task_callback_t; class llm_task { private: camera_t *cam; - + hal_camera_open_fun hal_camera_open; + hal_camera_close_fun hal_camera_close; public: std::string response_format_; task_callback_t out_callback_; @@ -49,7 +55,7 @@ public: int frame_height_; cv::Mat yuv_dist_; - static void on_cap_fream(uint8_t *pData, uint32_t width, uint32_t height, uint32_t Length, void *ctx) + static void on_cap_fream(void *pData, uint32_t width, uint32_t height, uint32_t Length, void *ctx) { llm_task *self = static_cast(ctx); int src_offsetX; @@ -127,6 +133,13 @@ public: } enstream_ = (response_format_.find("stream") != std::string::npos); yuv_dist_ = cv::Mat(frame_height_, frame_width_, CV_8UC2); + if(devname_.find("/dev/video") != std::string::npos){ + hal_camera_open = camera_open; + hal_camera_close = camera_close; + }else if(devname_.find("axera_") != std::string::npos){ + hal_camera_open = axera_camera_open; + hal_camera_close = axera_camera_close; + } return false; } @@ -136,7 +149,7 @@ public: return -1; } try { - cam = camera_open(devname_.c_str(), frame_width_, frame_height_, 30); + cam = hal_camera_open(devname_.c_str(), frame_width_, frame_height_, 30); if (cam == NULL) { printf("Camera open failed \n"); return -1; @@ -166,7 +179,7 @@ public: { if (cam) { cam->camera_capture_stop(cam); - camera_close(cam); + hal_camera_close(cam); cam = NULL; } } diff --git a/projects/llm_framework/main_camera/src/camera.c b/projects/llm_framework/main_camera/src/v4l2_camera.c similarity index 100% rename from projects/llm_framework/main_camera/src/camera.c rename to projects/llm_framework/main_camera/src/v4l2_camera.c