API GUIDE / VIC / HAL

G32S10 VIC HAL 接口

HAL 层接口:对应到寄存器与字段:

1. 分层关系与依赖

1.1 硬件数据通路

DVP / BT656 ──> CIM0 / CIM1 ─┐
                             ├──> VIC 前端 ──> TOP ──> DMSC ──> IPC ──> GPL_WDMA ──> DDR
MIPI CSI ────> CSI0 (D-PHY) ─┘                    │        │
                                                  │        └──> AE 统计(ISP0)
                                                  └──> RESP 事件(WDMA_DONE、帧开始/结束、错误)

对应到寄存器与字段:

环节由谁配置关键寄存器
输入前端hal_vic_configure_dvp/mipi/bt656()VIC.CTRL/IN_INTF/IN_DVP/IN_HOR_PARA0..
帧尺寸与数据类型hal_isp_top_configure()TOP.FRM_SIZE/BAYER_TYPE/LINE_SPACE_0
DMSC 是否在通路上TOP.BYPASS.DMSC_BYPASS由 hal_isp_top_configure() 的 bypass_dmsc 决定
RAW → YUVhal_isp_dmsc_configure()DMSC.PAR_0..2/OFFSET/CLIP_MINMAX
输出映射与偏移hal_isp_ipc_configure()IPC.OUT_NUM/OUT_MAP/TRIGE_SEL/OFFSET
写 DDRhal_isp_wdma_configure()/start_frame()WDMA.MUX_SEL/STRIDE/START_ADDR
事件与中断hal_isp_resp_configure()RESP.COMMON0/UNUSUAL0/BACKUP0_*
曝光统计hal_isp_ae_configure() + TOP.STATIC_ENAE.ZONE_*/LUM_TH_FREQ/DMA_*

两条容易混淆的“旁路”:

  • DMSC 旁路只能在 TOP 里改(bypass_dmsc)。DMSC 自己的配置不会改变旁路位。

  • WDMA 数据源由 mux_sel 选择:3 取 DMSC 的 YUV,1 取 RAW 通路,2 取 YUV422 通路。旁路 DMSC 时不能再选 mux_sel = 3。

1.2 实例、中断与共享资源

资源ISP0ISP1说明
基地址0x133500000x13360000code/soc/g32s10/include/base.h
中断IRQ_ISP0 = IRQ_PLIC0_START + 19IRQ_ISP1 = IRQ_PLIC0_START + 18VIC 与 RESP 共用同一条 IRQ 线
模块时钟CGU_ISPM同一个 CGU_ISPM无独立门控位,两个实例共享
传感器 MCLK由 CIM0/CIM1 提供同左hal_vic_camera_enable_sensor_mclk(index, hz),index 0/1
AE / DMSC有没有ISP1 上没有 AE 和 DMSC 寄存器块

两个直接后果:

  1. 中断服务程序里必须先读 VIC 的 INT_STA 并写 INT_CLR,再处理 RESP 的挂起事件。 只处理其中一个,另一个会一直把 CPU 叫回来(VIC 的中断是电平型,见第 11.3 节)。

  2. 打开/关闭 ISP 时钟会影响两路相机。hal_isp_clock_enable/disable() 由 CPM 引用计数, 只要还有一路持有引用,时钟就不会真正关闭。

2. 资源模型

2.1 公共宏

宏说明取值/约束
HAL_VIC_MAX_IMAGE_WIDTHVIC HAL 接受的最大图像宽度2048
HAL_VIC_MAX_IMAGE_HEIGHTVIC HAL 接受的最大图像高度2048
HAL_VIC_DEFAULT_OUTPUT_DELAY输出延迟默认值0
HAL_VIC_DEFAULT_TIMEOUT_MS复位等待默认超时1000 ms
HAL_VIC_OUTPUT_DELAY_MIN/MAX输出延迟字段范围0 / 0xFFFF
HAL_VIC_DVP_BUS_SELECT_MAXDVP 总线选择字段上限8
HAL_VIC_DVP_HORIZONTAL_BLANK_MAXDVP 水平消隐字段上限0xFFFF
HAL_VIC_DVP_VERTICAL_BLANK_MAXDVP 垂直消隐字段上限0xFFFFFFFF
HAL_VIC_DVP_LINE_CODE_MAXSAV/EAV 行码字段上限0xFFFFFF
HAL_VIC_MIPI_START_DELAY_MAXMIPI 启动延迟字段上限0xF
HAL_VIC_MIPI_VCROP_START_LINE_MAXMIPI 垂直裁剪起始行上限0xFFFF
HAL_VIC_MIPI_TOTAL_WIDTH_MAXMIPI 总行宽上限0xFFFF
HAL_VIC_MIPI_HCROP_START_PIXEL_MAXMIPI 水平裁剪起始像素上限0xFFFF
HAL_VIC_MIPI_WIDTH_4BYTE_MAXMIPI 4 字节字宽字段上限0xFFFF
HAL_VIC_COLORBAR_FRAME_COUNT_MAX彩条有限帧数上限0x7FFF
HAL_VIC_COLORBAR_BLANK_MAX彩条消隐字段上限0xFFFF
HAL_VIC_COLORBAR_COLOR_COUNT彩条颜色数量8(VIC_COLOR_BAR_COUNT)
HAL_ISP_TOP_MIN_FRAME_WIDTHTOP 最小帧宽640
HAL_ISP_TOP_MIN_FRAME_HEIGHTTOP 最小帧高360
HAL_ISP_TOP_FRAME_ALIGNMENTTOP 帧尺寸对齐4
HAL_ISP_TOP_MAX_FRAME_WIDTHTOP 最大帧宽1920
HAL_ISP_TOP_MAX_FRAME_HEIGHTTOP 最大帧高1080
HAL_ISP_TOP_BAYER_TYPE_MAXBayer 类型字段上限0x1F
HAL_ISP_TOP_STATISTICS_POSITION_MAX统计位置字段上限7
HAL_ISP_TOP_LINE_SPACE_MAX行间距字段上限0xFFFF
HAL_ISP_TOP_SHADOW_WRITE_SELECT_MAXDMSC 影子写选择上限1
HAL_ISP_IPC_OUTPUT_NUMBER_MAXIPC 输出映射计数上限0x1F
HAL_ISP_IPC_TRIGGER_MODE_MAXIPC 触发模式上限1
HAL_ISP_IPC_CH0_TRIGGER_SELECT_MAX通道 0 触发源上限7
HAL_ISP_IPC_OFFSET_MAXIPC Y/UV 偏移上限0x1FF
HAL_ISP_RESP_POS_COUNTRESP 断点位置组数3
HAL_ISP_WDMA_ADDRESS_ALIGNMENTWDMA 地址对齐8 字节
HAL_ISP_WDMA_ADDRESS_MAXWDMA 地址上限0x1FFFFFF8
HAL_ISP_WDMA_STRIDE_ALIGNMENTWDMA 步长对齐8 字节
HAL_ISP_WDMA_STRIDE_MAXWDMA 步长上限0xFFF8
HAL_ISP_WDMA_ADDRESS_FIFO_DEPTHWDMA 地址 FIFO 深度4
HAL_ISP_DMSC_OUTPUT_OPTION_MAXDMSC 输出选项上限3
HAL_ISP_DMSC_INPUT_MODE_MAXDMSC 输入模式上限1
HAL_ISP_DMSC_UV_RESOLUTION_MODE_MAXDMSC UV 分辨率模式上限7
HAL_ISP_DMSC_RGB_OFFSET_MAXDMSC RGB 偏移上限0x1FF
HAL_ISP_DMSC_OFFSET_MAXDMSC Y/UV 偏移上限0xFF
HAL_ISP_DMSC_CLIP_MAXDMSC 裁剪值上限0xFF
HAL_ISP_AE_MAX_ZONE_COUNTAE 每方向最大分区数15
HAL_ISP_AE_ZONE_SIZE_COUNTAE 每方向尺寸表项数15
HAL_ISP_AE_DMA_BASE_COUNTAE DMA 基址表项数4
HAL_ISP_AE_DMA_BUFFER_COUNT_MINAE DMA 缓冲数下限1
HAL_ISP_AE_DMA_BASE_ALIGNMENTAE DMA 基址对齐8 字节
HAL_ISP_AE_ZONE_START_MAXAE 分区起点上限0xFFF
HAL_ISP_AE_THRESHOLD_MAXAE 阈值上限0xFF
HAL_ISP_AE_FREQUENCY_MAXAE 频率上限0xF
HAL_ISP_AE_DMA_PRIORITY_MAXAE DMA 优先级上限3
HAL_ISP_AE_SPECIFIC_POSITION_MAXAE 特定窗口坐标上限0xFFF
HAL_ISP_AE_SPECIFIC_FRAME_NUMBER_MAXAE 特定帧号上限0xFF
HAL_ISP_CLOCK_DEFAULT_HZISP 模块时钟默认频率100000000

3. 配置对象与默认值

3.1 VIC 枚举

3.1.1 hal_vic_dvp_data_format_t

枚举值说明
HAL_VIC_DVP_DATA_FORMAT_RAW80DVP RAW8
HAL_VIC_DVP_DATA_FORMAT_RAW101DVP RAW10
HAL_VIC_DVP_DATA_FORMAT_RAW122DVP RAW12
HAL_VIC_DVP_DATA_FORMAT_YUV422_16BIT3DVP YUV422 16-bit
HAL_VIC_DVP_DATA_FORMAT_YUV422_8BIT6DVP YUV422 8-bit

3.1.2 hal_vic_yuv_order_t

枚举值说明
HAL_VIC_YUV_ORDER_Y1_V0_Y0_U00Y1 V0 Y0 U0
HAL_VIC_YUV_ORDER_Y1_U0_Y0_V01Y1 U0 Y0 V0
HAL_VIC_YUV_ORDER_V0_Y1_U0_Y02V0 Y1 U0 Y0
HAL_VIC_YUV_ORDER_U0_Y1_V0_Y03U0 Y1 V0 Y0

3.1.3 hal_vic_dvp_timing_mode_t

枚举值说明
HAL_VIC_DVP_TIMING_MODE_HREF0HREF 时序
HAL_VIC_DVP_TIMING_MODE_HSYNC1HSYNC 时序
HAL_VIC_DVP_TIMING_MODE_SONY2Sony 时序(带 SAV/EAV 行码)

3.1.4 hal_vic_polarity_t

枚举值说明
HAL_VIC_POLARITY_ACTIVE_HIGH0高有效
HAL_VIC_POLARITY_ACTIVE_LOW1低有效

3.1.5 hal_vic_raw_align_t

枚举值说明
HAL_VIC_RAW_ALIGN_LOW0RAW 数据对齐到低位
HAL_VIC_RAW_ALIGN_HIGH1RAW 数据对齐到高位

3.1.6 hal_vic_dvp_sample_edge_t

枚举值说明
HAL_VIC_DVP_SAMPLE_FALLING_EDGE0PCLK 下降沿采样
HAL_VIC_DVP_SAMPLE_RISING_EDGE1PCLK 上升沿采样

3.1.7 hal_vic_bt656_bus_width_t

枚举值说明
HAL_VIC_BT656_BUS_WIDTH_8BIT08-bit 总线
HAL_VIC_BT656_BUS_WIDTH_16BIT116-bit 总线

3.1.8 hal_vic_bt656_sync_order_t

枚举值说明
HAL_VIC_BT656_SYNC_EAV_BEFORE_SAV0EAV 在 SAV 之前
HAL_VIC_BT656_SYNC_SAV_BEFORE_EAV1SAV 在 EAV 之前

3.1.9 hal_vic_field_t

枚举值说明
HAL_VIC_FIELD_ODD0奇数场
HAL_VIC_FIELD_EVEN1偶数场

3.1.10 hal_vic_mipi_pixel_format_t

枚举值说明
HAL_VIC_MIPI_PIXEL_FORMAT_RAW80MIPI RAW8
HAL_VIC_MIPI_PIXEL_FORMAT_RAW101MIPI RAW10
HAL_VIC_MIPI_PIXEL_FORMAT_RAW122MIPI RAW12
HAL_VIC_MIPI_PIXEL_FORMAT_YUV4227MIPI YUV422

3.1.11 hal_vic_mipi_data_type_t

枚举值说明
HAL_VIC_MIPI_DATA_TYPE_YUV422_8BIT0x1ECSI-2 YUV422 8-bit
HAL_VIC_MIPI_DATA_TYPE_RAW80x2ACSI-2 RAW8
HAL_VIC_MIPI_DATA_TYPE_RAW100x2BCSI-2 RAW10
HAL_VIC_MIPI_DATA_TYPE_RAW120x2CCSI-2 RAW12

3.1.12 hal_vic_mipi_sync_mode_t

枚举值说明
HAL_VIC_MIPI_SYNC_MODE_HEADER0包头部同步
HAL_VIC_MIPI_SYNC_MODE_PACKET1包同步

3.1.13 hal_vic_mipi_start_channel_t

取值 0~3,对应 HAL_VIC_MIPI_START_CHANNEL_0 ~ _3。

3.1.14 hal_vic_mipi_sensor_frame_mode_t

枚举值说明
HAL_VIC_MIPI_SENSOR_FRAME_MODE_LINEAR0线性帧
HAL_VIC_MIPI_SENSOR_FRAME_MODE_11字段值 1
HAL_VIC_MIPI_SENSOR_FRAME_MODE_22字段值 2
HAL_VIC_MIPI_SENSOR_FRAME_MODE_33字段值 3

3.1.15 hal_vic_output_route_t

枚举值说明
HAL_VIC_OUTPUT_ROUTE_TIZIANO0路由到 Tiziano ISP 通路
HAL_VIC_OUTPUT_ROUTE_NONE4关闭输出路由

3.1.16 hal_vic_irq_t

枚举位说明
HAL_VIC_IRQ_FRAME_DONE0帧完成
HAL_VIC_IRQ_FRAME_START4帧开始
HAL_VIC_IRQ_FRAME_RESET8帧复位
HAL_VIC_IRQ_ASFIFO_OVERFLOW9ASFIFO 溢出
HAL_VIC_IRQ_HORIZONTAL_ERROR10水平尺寸错误
HAL_VIC_IRQ_VERTICAL_ERROR14垂直尺寸错误
HAL_VIC_IRQ_HVF_ERROR18水平/垂直场错误
HAL_VIC_IRQ_DVP_HCOMP_ERROR19DVP 水平比较错误
HAL_VIC_IRQ_IMAGE_FIFO_OVERFLOW22图像 FIFO 溢出
HAL_VIC_IRQ_MIPI_HCOMP_ERROR24MIPI 水平比较错误
HAL_VIC_IRQ_MIPI_VCOMP_ERROR28MIPI 垂直比较错误
HAL_VIC_IRQ_ALL以上全部所有已定义中断位

补充说明:

  • INT_STA、INT_MASK、INT_CLR 使用同一套位定义。

  • 硬件语义为 1 = 屏蔽、0 = 放行,与常见外设相反。

  • 寄存器复位值是 INT_MASK = 0,即全部放行。HAL 的 *_struct_init() 默认值另有一套: DVP/BT656 默认掩码为 FRAME_START | FRAME_RESET。

  • HAL 的 MIPI 默认掩码为 0xFFFFF & ~(FRAME_DONE | 各错误位):bit0 与各错误位放行, bit4/bit8(帧开始/帧复位)在默认值下是屏蔽的。做 MIPI 帧计数时不要指望 “默认就有帧中断”,要显式改掩码。

3.2 VIC 结构体

3.2.1 hal_vic_common_config_t

字段类型说明
routehal_vic_output_route_tVIC 输出路由
vertical_delayuint32_t有效数据前延迟,单位时钟周期
horizontal_delayuint32_t行尾延迟,单位时钟周期
frame_end_delayuint32_t帧尾延迟,单位时钟周期
interrupt_maskuint32_t写入 VIC_INT_MASK 的掩码,1 = 屏蔽
timeout_msuint32_t复位等待超时,0 使用默认 1000 ms

默认初始化宏:HAL_VIC_DEFAULT_COMMON_CONFIG_INIT(DVP 掩码)、HAL_VIC_DEFAULT_MIPI_COMMON_CONFIG_INIT、HAL_VIC_DEFAULT_BT656_COMMON_CONFIG_INIT。

3.2.2 hal_vic_dvp_config_t

字段类型说明
ispxisp_regs_t *ISP0 / ISP1
widthuint32_t输出宽度
heightuint32_t输出高度
data_formathal_vic_dvp_data_format_tDVP 输入格式
yuv_orderhal_vic_yuv_order_tYUV 字节序
timing_modehal_vic_dvp_timing_mode_t时序模式
hsync_polarityhal_vic_polarity_tHSYNC 极性
vsync_polarityhal_vic_polarity_tVSYNC 极性
sample_edgehal_vic_dvp_sample_edge_t采样边沿
raw_alignhal_vic_raw_align_tRAW 对齐方式
bus_selectuint32_tYUV422 8-bit 总线选择,0~8
horizontal_front_blankuint32_t水平前消隐,HSYNC/Sony 模式有效
horizontal_back_blankuint32_t水平后消隐,HSYNC/Sony 模式有效
vertical_blankuint32_t垂直消隐,HSYNC/Sony 模式有效
line_sav_codeuint32_tSony 模式行 SAV 码,24 位
line_eav_codeuint32_tSony 模式行 EAV 码,24 位
enable_image_checkbool打开 DVP 图像尺寸检查
enable_hcompbool打开 DVP 水平比较
commonhal_vic_common_config_t公共配置

默认值(HAL_VIC_DEFAULT_DVP_CONFIG_INIT):ISP0、640×480、YUV422_8BIT、Y1_U0_Y0_V0、HREF、HSYNC/VSYNC 高有效、上升沿、RAW 低位对齐、总线 0、消隐全 0、 SAV 0x800800、EAV 0x9D09D0、检查全关。

3.2.3 hal_vic_mipi_config_t

字段类型说明
ispxisp_regs_t *ISP0 / ISP1
output_widthuint32_t裁剪后输出宽度
output_heightuint32_t裁剪后输出高度
total_widthuint32_t裁剪前总行宽,0 表示等于 output_width
hcrop_start_pixeluint32_t水平裁剪起始像素
vcrop_start_lineuint32_t垂直裁剪起始行
pixel_formathal_vic_mipi_pixel_format_tMIPI 像素格式
data_typehal_vic_mipi_data_type_tCSI-2 数据类型
sync_modehal_vic_mipi_sync_mode_t同步模式
start_delayuint32_t启动延迟,0~0xF
start_channelhal_vic_mipi_start_channel_t启动通道
sensor_frame_modehal_vic_mipi_sensor_frame_mode_t传感器帧模式
enable_data_type_checkbool打开数据类型检查
enable_horizontal_comparebool打开水平比较
enable_vertical_comparebool打开垂直比较
commonhal_vic_common_config_t公共配置

默认值(HAL_VIC_DEFAULT_MIPI_CONFIG_INIT):ISP0、640×480、total_width=640、 裁剪 0、RAW10、DT 0x2B、HEADER 同步、延迟 0、通道 0、线性帧、DT 检查开、 水平比较开、垂直比较关。

3.2.4 hal_vic_bt656_config_t

字段类型说明
ispxisp_regs_t *ISP0 / ISP1
widthuint32_t输出宽度
heightuint32_t输出高度
bus_widthhal_vic_bt656_bus_width_t总线宽度
sync_orderhal_vic_bt656_sync_order_tSAV/EAV 顺序
yuv_orderhal_vic_yuv_order_tYUV 字节序
start_fieldhal_vic_field_t起始场
enable_hcompbool打开水平比较
commonhal_vic_common_config_t公共配置

默认值(HAL_VIC_DEFAULT_BT656_CONFIG_INIT):ISP0、640×480、8-bit、 EAV 先于 SAV、Y1_U0_Y0_V0、奇数场、水平比较关。

3.2.5 hal_vic_colorbar_color_t

字段类型说明
yuint8_tY 分量
cbuint8_tCb 分量
cruint8_tCr 分量

3.2.6 hal_vic_colorbar_config_t

字段类型说明
ispxisp_regs_t *ISP0 / ISP1
frame_infinitebool无限帧
frame_countuint32_t有限帧数
horizontal_blankuint32_t行间隔
vertical_blankuint32_t帧间隔
colors[8]hal_vic_colorbar_color_t第一组颜色
colors2[8]hal_vic_colorbar_color_t第二组颜色
program_colorsbool是否写两组颜色表
replace_data_onlybool仅替换数据(保留同步)

默认值(HAL_VIC_DEFAULT_COLORBAR_CONFIG_INIT):无限帧、帧数 0、消隐 0、 两组颜色均为白/黄/青/绿/品红/红/蓝/黑标准表、写颜色、替换同步与数据。

3.3 ISP 子模块枚举与结构体

3.3.1 hal_isp_top_data_type_t

枚举值说明
HAL_ISP_TOP_DATA_TYPE_RAW80RAW8 输入
HAL_ISP_TOP_DATA_TYPE_RAW101RAW10 输入
HAL_ISP_TOP_DATA_TYPE_RAW122RAW12 输入
HAL_ISP_TOP_DATA_TYPE_YUV3YUV 输入

3.3.2 hal_isp_top_shadow_select_t

枚举值说明
HAL_ISP_TOP_SHADOW_SELECT_ACTIVE0写活动寄存器组
HAL_ISP_TOP_SHADOW_SELECT_SHADOW1写影子寄存器组

3.3.3 hal_isp_top_config_t

字段类型说明
ispxisp_regs_t *ISP0 / ISP1
widthuint32_t帧宽,640~1920,4 对齐
heightuint32_t帧高,360~1080,4 对齐
data_typehal_isp_top_data_type_t输入数据类型
bayer_typeuint32_tBayer 类型,0~0x1F
bypass_dmscbool旁路 DMSC
enable_raw_test_patternbool打开 RAW 测试图
enable_rgb_test_patternbool打开 RGB 测试图
enable_yuv_test_patternbool打开 YUV 测试图
statistics_positionuint32_t统计位置,0~7
ipc_line_spaceuint32_tIPC 行间距
normal_line_spaceuint32_t普通行间距
shadow_selecthal_isp_top_shadow_select_t影子寄存器选择
shadow_write_selectuint32_tDMSC 影子写选择,0~1
enable_overflow_stopbool溢出时停止流水线
trigger_shadowbool配置后触发影子更新

默认值(HAL_ISP_TOP_DEFAULT_CONFIG_INIT):ISP0、640×480、YUV、Bayer 1、 旁路 DMSC、测试图全关、统计位置 0、行间距 0、活动寄存器组、写选择 0、 溢出停止关、影子触发关。

3.3.4 hal_isp_ipc_config_t

字段类型说明
ispxisp_regs_t *ISP0 / ISP1
output_numberuint32_t输出映射计数上限,0~0x1F;0 表示只用映射项 0(单路输出)
output_mapuint32_t输出映射原始值,单路常用 0
overflow_restartbool溢出后是否进入停流序列(不是自愈,见 8.5)
size_error_restartbool尺寸错误后是否进入停流序列
trigger_modeuint32_t触发模式,0 正常 / 1 一帧后停止
channel0_trigger_selectuint32_t通道 0 触发源,0 表示不启动
y_offsetuint32_tY 输出偏移,0~0x1FF
uv_offsetuint32_tUV 输出偏移,0~0x1FF
trigger_after_configbool配置完成后立即触发

默认值(HAL_ISP_IPC_DEFAULT_CONFIG_INIT):输出数 0、映射 0、两种重启关、 触发模式 0、通道 0 触发源 4、偏移 0、配置后触发。

3.3.5 hal_isp_resp_event_masks_t

字段类型说明
common0uint32_tCOMMON_0 事件掩码
unusual0uint32_tUNUSUAL_0 事件掩码
backup0uint32_tBACKUP_0 事件掩码

3.3.6 hal_isp_resp_config_t

字段类型说明
ispxisp_regs_t *ISP0 / ISP1
enable_eventshal_isp_resp_event_masks_t事件源使能
cpu_eventshal_isp_resp_event_masks_t上报 CPU 的事件
clear_all_before_enablebool使能前清空所有挂起事件

默认值(HAL_ISP_RESP_DEFAULT_CONFIG_INIT):只使能 COMMON_0 的GPL_WDMA_DONE,CPU 掩码相同,使能前清空。

3.3.7 hal_isp_resp_position_t

字段类型说明
hcountuint32_t水平计数
vcountuint32_t垂直计数

3.3.8 hal_isp_resp_common0_pending_t

字段类型说明
eventsuint32_t原始挂起事件
has_pendingbool是否有挂起事件
ae_static_doneboolAE 统计完成
ae_hist_doneboolAE 直方图完成
stopbool停止事件
gpl_wdma_doneboolWDMA 完成
ipc_frame_startboolIPC 帧开始
ipc_frame_doneboolIPC 帧完成
ipc_ch0_startboolIPC 通道 0 开始
ipc_ch0_endboolIPC 通道 0 结束

3.3.9 hal_isp_resp_unusual0_pending_t

字段类型说明
eventsuint32_t原始挂起事件
has_pendingbool是否有挂起事件
ipc_size_errorboolIPC 尺寸错误
ipc_overflowboolIPC 溢出
ae_errorboolAE 错误
ae_hist_errorboolAE 直方图错误

3.3.10 hal_isp_resp_backup0_pending_t

字段类型说明
eventsuint32_t原始挂起事件
has_pendingbool是否有挂起事件
dmsc_frame_doneboolDMSC 帧完成
ae_frame_doneboolAE 帧完成

3.3.11 hal_isp_resp_pending_t

字段类型说明
common0hal_isp_resp_common0_pending_tCOMMON_0 解码结果
unusual0hal_isp_resp_unusual0_pending_tUNUSUAL_0 解码结果
backup0hal_isp_resp_backup0_pending_tBACKUP_0 解码结果
has_pendingbool三组中任意一组有事件

3.3.12 hal_isp_wdma_dump_data_type_t

枚举值说明
HAL_ISP_WDMA_DUMP_DATA_TYPE_RAW8_OR_Y0RAW8 或 Y
HAL_ISP_WDMA_DUMP_DATA_TYPE_RAW10_12_16_OR_UV1RAW10/12/16 或 UV
HAL_ISP_WDMA_DUMP_DATA_TYPE_RAW32_OR_RGB8882RAW32 或 RGB888
HAL_ISP_WDMA_DUMP_DATA_TYPE_YUV420_DUAL4YUV420 双平面
HAL_ISP_WDMA_DUMP_DATA_TYPE_DOL_RAW16_DUAL5DOL RAW16 双平面
HAL_ISP_WDMA_DUMP_DATA_TYPE_YUV422_DUAL6YUV422 双平面

3.3.13 hal_isp_wdma_mux_sel_t

枚举值说明
HAL_ISP_WDMA_MUX_SEL_RAW_PATH1RAW 通路
HAL_ISP_WDMA_MUX_SEL_YUV422_PATH2YUV422 通路
HAL_ISP_WDMA_MUX_SEL_DMSC_YUV_PATH3DMSC YUV 通路

3.3.14 hal_isp_wdma_static_config_t

字段类型说明
mux_selhal_isp_wdma_mux_sel_t数据源
dump_data_typehal_isp_wdma_dump_data_type_t数据排布
dump_data_orderuint32_t字节序,0~7
strideuint32_tY/单平面步长,8 对齐,最大 0xFFF8
chroma_strideuint32_tUV 步长,8 对齐,最大 0xFFF8
y_priority_leveluint32_tY DMA 优先级等级,0~3
y_priority_limituint32_tY DMA 优先级限制,0~0x1FF
chroma_priority_leveluint32_tUV DMA 优先级等级,0~3
chroma_priority_limituint32_tUV DMA 优先级限制,0~0x1FF

默认值(HAL_ISP_WDMA_DEFAULT_STATIC_CONFIG_INIT):DMSC YUV 通路、YUV420 双平面、 字节序 0、步长 0、优先级 0。

3.3.15 hal_isp_wdma_config_t

字段类型说明
ispxisp_regs_t *ISP0 / ISP1
static_confighal_isp_wdma_static_config_t静态配置

3.3.16 hal_isp_wdma_frame_config_t

字段类型说明
ispxisp_regs_t *ISP0 / ISP1
start_addressuint32_tY/单平面物理地址,8 对齐
chroma_start_addressuint32_tUV 物理地址,8 对齐
enable_chromabool是否先写 C_START_ADDR

3.3.17 hal_isp_wdma_done_info_t

字段类型说明
done_addressuint32_tY/单平面完成地址
chroma_done_addressuint32_tUV 完成地址
dump_enabledboolDUMP_EN 状态

3.3.18 hal_isp_wdma_address_fifo_state_t

字段类型说明
rawuint32_t原始调试寄存器值
data_countuint32_t已用项数,0~4
free_countuint32_t空闲项数,0~4
fullbool满标志
emptybool空标志
validbool计数与标志自洽

3.3.19 hal_isp_wdma_address_fifo_t

字段类型说明
y_starthal_isp_wdma_address_fifo_state_tY 地址 FIFO
chroma_starthal_isp_wdma_address_fifo_state_tUV 地址 FIFO

3.3.20 hal_isp_dmsc_config_t

字段类型说明
ispxisp_regs_t *ISP0 / ISP1
output_optionuint32_t输出选项,0~3
input_modeuint32_t输入模式,0~1
uv_resolution_modeuint32_tUV 分辨率模式,0~7
r_offset / g_offset / b_offsetuint32_tRGB 偏移,0~0x1FF
matrix_00~matrix_22uint32_t3×3 颜色矩阵系数
y_offset / uv_offsetuint32_t输出偏移,0~0xFF
y_clip_min / y_clip_maxuint32_tY 裁剪范围,0~0xFF
uv_clip_min / uv_clip_maxuint32_tUV 裁剪范围,0~0xFF

矩阵位宽:m00/m10/m11/m21/m22 9 位,m01/m12/m20 10 位,m02 8 位。

默认值(HAL_ISP_DMSC_DEFAULT_CONFIG_INIT):3×3 输出、其余全 0、裁剪0~0xFF。

3.3.21 hal_isp_dmsc_debug0_t

字段类型说明
fifo_data_countuint32_t输出 FIFO 已用项数,0~3
fifo_free_countuint32_t输出 FIFO 空闲项数,0~3

3.3.22 hal_isp_dmsc_debug1_t

字段类型说明
transfer_stateuint32_t输出状态机,0~0x3F
fifo_underflowboolFIFO 下溢
fifo_overflowboolFIFO 上溢
fifo_emptyboolFIFO 空
fifo_fullboolFIFO 满
input_backpressurebool输入反压

3.3.23 hal_isp_ae_config_t

字段类型说明
ispxisp_regs_t *ISP0 / ISP1
zone_h_start / zone_v_startuint32_t分区网格起点,0~0xFFF
zone_h_number / zone_v_numberuint32_t每方向分区数,1~15
horizontal_zone_size[15]uint8_t水平分区尺寸
vertical_zone_size[15]uint8_t垂直分区尺寸
dark_thresholduint32_t暗点阈值,0~0xFF
saturation_thresholduint32_t饱和阈值,0~0xFF
histogram_frequencyuint32_t直方图频率,0~0xF
statistics_frequencyuint32_t统计频率,0~0xF
enable_histogram_read_modebool直方图读模式
enable_histogram_trigger_modebool直方图触发模式
statistics_dma_base[4]uint32_t统计 DMA 基址,8 对齐或 0
histogram_dma_base[4]uint32_t直方图 DMA 基址,8 对齐或 0
statistics_buffer_countuint32_t统计缓冲数,1~4
histogram_buffer_countuint32_t直方图缓冲数,1~4
enable_statistics_dma_monitorbool统计 DMA 监视
enable_histogram_dma_monitorbool直方图 DMA 监视
enable_interrupt_improve_dropbool中断期间丢帧
statistics_dma_priorityuint32_t统计 DMA 优先级,0~3
histogram_dma_priorityuint32_t直方图 DMA 优先级,0~3
enable_drop_frame_backpressurebool丢帧反压模式
specific_horizontal_start/enduint32_t特定窗口水平范围,0~0xFFF
specific_vertical_start/enduint32_t特定窗口垂直范围,0~0xFFF
specific_frame_number_inuint32_t特定窗口输入帧号,0~0xFF
enable_ram_busy_backpressureboolRAM 忙反压
enable_shadowbool配置末尾触发一次 AE 影子更新(SHD_CTRL,一次性)

默认值(HAL_ISP_AE_DEFAULT_CONFIG_INIT):15×15 分区、水平尺寸全 20、垂直尺寸全 16、 暗阈值 30、饱和阈值 230、频率 1、DMA 基址全 0、缓冲数 4、监视/丢帧/反压关、 优先级 0、特定窗口 0、特定帧号 8、写一次影子触发。

3.3.24 hal_isp_ae_dma_info_t

字段类型说明
hist_current_baseuint32_t当前直方图缓冲索引
ae_current_baseuint32_t当前统计缓冲索引
ae_frame_numberuint32_tAE 内部帧计数
ae_dma_stop_ackuint32_tDMA 停止应答,1/0
ae_dma_mismatchuint32_t统计 DMA 尺寸错误,1/0
hist_dma_mismatchuint32_t直方图 DMA 尺寸错误,1/0

3.3.25 hal_isp_ae_specific_statistics_t

字段类型说明
frame_number_outuint32_t输出帧号,8 位
sum_darkuint32_t暗像素和,28 位
sum_miduint32_t中间像素和,28 位
sum_satuint32_t饱和像素和,28 位
count_darkuint32_t暗像素计数,20 位
count_satuint32_t饱和像素计数,20 位

3.4 默认值与必须覆盖的字段

*_struct_init() 返回的是“能编译、能下载、但通常不能直接出图”的默认值。下表列出 真实采集路径上必须覆盖的字段:

结构体默认值必须覆盖原因
hal_vic_dvp_config_tISP0、640×480、YUV422_8BITispx、width/height、data_format、raw_align、common.interrupt_mask实例与板级接线相关;RAW sensor 必须改成 RAW 格式;HAL 默认掩码屏蔽帧开始/复位,通常需要重算
hal_vic_mipi_config_tRAW10、通道 0、线性ispx、output_width/height、total_width、pixel_format、data_type、start_channel行宽与 DT 必须与 sensor 实际输出一致
hal_isp_top_config_tYUV、旁路 DMSC、640×480ispx、width/height、data_type、bypass_dmsc、statistics_position尺寸必须 640×360~1920×1080;是否走 DMSC 决定 WDMA 源
hal_isp_ipc_config_t单路、触发源 4、配置后触发一般不需要改;多路输出时改 output_number/output_map单摄线性通路默认值即可
hal_isp_resp_config_t只开 GPL_WDMA_DONE需要 AE 时把 AE_STATIC_DONE 一起打开否则 AE 完成不进中断
hal_isp_wdma_static_config_tmux_sel=3、YUV420 双平面、步长 0mux_sel、dump_data_type、stride、chroma_stride步长 0 不会写出正确图像;源必须与 TOP 旁路一致
hal_isp_dmsc_config_t全 0 矩阵走 DMSC 时必须填完整矩阵与偏移全 0 矩阵会把 Y 打成常数 0
hal_isp_ae_config_t15×15、H20/V16、4 个空 DMA 基址ispx、statistics_dma_base[]、statistics_buffer_count(及直方图对应项)基址为 0 时 AE 统计数据不会写入 DDR

4. HAL 接口规范

本节按子模块列出全部 HAL 接口。每个接口的写法统一为:

  1. 函数原型;

  2. 功能说明;

  3. 参数表(类型 / 方向 / 说明);

  4. 返回值表;

  5. 补充说明(编程顺序、默认值、边界条件、踩坑点)。

约定:

  • 所有 *_struct_init() 都是 void,指针为空时直接返回;

  • 所有配置/读接口返回 error_code_t,参数检查见 3.3 与 5.9;

  • 标 “调试辅助” 的接口受两个 Kconfig 同时控制;

  • 结构体字段与默认值见第 4 章,这里只讲接口行为。

4.1 VIC 前端

4.1.1 hal_vic_common_struct_init

void hal_vic_common_struct_init(hal_vic_common_config_t *config);

功能说明:把公共配置填充为 SDK 默认值(Tiziano 路由、延迟 0、DVP 掩码、超时 1000 ms)。

参数类型方向说明
confighal_vic_common_config_t *输出待填充的公共配置

返回值:无。config 为 NULL 时直接返回。

4.1.2 hal_vic_dvp_struct_init

void hal_vic_dvp_struct_init(hal_vic_dvp_config_t *config);

功能说明:把 DVP 配置填充为默认值(ISP0、640×480、YUV422_8BIT、HREF)。

参数类型方向说明
confighal_vic_dvp_config_t *输出待填充的 DVP 配置

返回值:无。config 为 NULL 时直接返回。

4.1.3 hal_vic_mipi_struct_init

void hal_vic_mipi_struct_init(hal_vic_mipi_config_t *config);

功能说明:把 MIPI 配置填充为默认值(ISP0、640×480、RAW10、通道 0、线性帧)。

参数类型方向说明
confighal_vic_mipi_config_t *输出待填充的 MIPI 配置

返回值:无。config 为 NULL 时直接返回。

4.1.4 hal_vic_bt656_struct_init

void hal_vic_bt656_struct_init(hal_vic_bt656_config_t *config);

功能说明:把 BT656 配置填充为默认值(ISP0、640×480、8-bit、EAV 先于 SAV)。

参数类型方向说明
confighal_vic_bt656_config_t *输出待填充的 BT656 配置

返回值:无。config 为 NULL 时直接返回。

4.1.5 hal_vic_colorbar_struct_init

void hal_vic_colorbar_struct_init(hal_vic_colorbar_config_t *config);

功能说明:把彩条配置填充为默认值(无限帧、标准 8 色两组、替换同步与数据)。

参数类型方向说明
confighal_vic_colorbar_config_t *输出待填充的彩条配置

返回值:无。config 为 NULL 时直接返回。

4.1.6 hal_vic_reset

error_code_t hal_vic_reset(isp_regs_t *ispx, uint32_t timeout_ms);

功能说明:对指定 VIC 实例发起软件复位并等待完成。复位通过 CTRL.RST(bit2)触发, 硬件在完成后自清;函数轮询 CTRL 直到为 0。

参数类型方向说明
ispxisp_regs_t *输入ISP0 / ISP1
timeout_msuint32_t输入超时毫秒数,0 使用 HAL_VIC_DEFAULT_TIMEOUT_MS
返回值说明
IM_OK复位完成
IM_ERR_INVALID_PARAMispx 不是 ISP0/ISP1
IM_ERR_TIMEOUT超时未完成,日志打印超时时的 CTRL 值

补充说明:

  • 复位会清除该实例 VIC 前端的配置,之后必须重新编程。

  • timeout_ms = 0 不是无限等待,而是回退到 1000 ms。

  • ISP0 与 ISP1 的复位互不影响。

4.1.7 hal_vic_apply_register_update

error_code_t hal_vic_apply_register_update(isp_regs_t *ispx);

功能说明:置位 CTRL.REG_EN(bit1),提交已写入的 VIC 配置。

参数类型方向说明
ispxisp_regs_t *输入ISP0 / ISP1
返回值说明
IM_OK已置位
IM_ERR_INVALID_PARAMispx 非法

补充说明:

  • 本函数不轮询完成状态,写后立即返回。

  • 各 hal_vic_configure_* 在末尾自动调用本函数,通常不需要单独调用。

4.1.8 hal_vic_configure_dvp

error_code_t hal_vic_configure_dvp(const hal_vic_dvp_config_t *config);

功能说明:配置 DVP 输入通路。函数先复位 VIC,再依次写帧几何、DVP 格式/时序/极性、 RAW 对齐与采样沿、可选总线和消隐、检查使能、公共配置,最后提交寄存器更新。

参数类型方向说明
configconst hal_vic_dvp_config_t *输入DVP 配置
返回值说明
IM_OK配置成功
IM_ERR_INVALID_PARAM指针为空、实例非法或字段越界
IM_ERR_TIMEOUT复位等待超时

补充说明:

  • HACT 计算:YUV422_8BIT 为 width×2,其余格式为 width。

  • 帧配置同时写 VLD_FRM_SAV = height、VLD_FRM_EAV = width、PCK_MASK = 0xFFFF。

  • bus_select 仅在 YUV422_8BIT 时写入。

  • 水平/垂直消隐仅在 HSYNC 或 Sony 模式写入;SAV/EAV 行码仅在 Sony 模式写入。

  • 扫描方式固定为逐行,DVP 场固定为奇数场。

  • common.interrupt_mask 会先用于清中断,再写入 INT_MASK。

4.1.9 hal_vic_configure_mipi

error_code_t hal_vic_configure_mipi(const hal_vic_mipi_config_t *config);

功能说明:配置 MIPI CSI 输入通路。函数计算每像素位宽、总行宽与 4 字节字宽, 复位 VIC 后依次写帧几何、MIPI 格式与裁剪、数据类型与检查、同步/延迟/通道/帧模式, 最后写公共配置并提交。

参数类型方向说明
configconst hal_vic_mipi_config_t *输入MIPI 配置
返回值说明
IM_OK配置成功
IM_ERR_INVALID_PARAM指针为空、实例非法、裁剪关系不成立或字段越界
IM_ERR_TIMEOUT复位等待超时

补充说明:

  • total_width = 0 时按 output_width 处理。

  • 每像素位宽:RAW8 = 8、RAW10 = 10、RAW12 = 12、YUV422 = 16。

  • MIPI_WIDTH4 = ceil(total_width × bpp / 32),上限 0xFFFF。

  • 裁剪约束:hcrop_start_pixel ≤ total_width 且total_width - hcrop_start_pixel ≥ output_width。

  • HACT 固定为 output_width×2。

  • MIPI_HCROP_CH0 的总宽字段写 total_width,起始像素写 hcrop_start_pixel。

  • 本 HAL 只配置 VIC 侧寄存器;CSI/PHY 必须由调用方在开流前初始化。

4.1.10 hal_vic_configure_bt656

error_code_t hal_vic_configure_bt656(const hal_vic_bt656_config_t *config);

功能说明:配置 BT656 输入通路。函数复位 VIC 后写帧几何、总线宽度、SAV/EAV 顺序、 YUV 字节序、逐行扫描、起始场、可选水平比较,最后写公共配置并提交。

参数类型方向说明
configconst hal_vic_bt656_config_t *输入BT656 配置
返回值说明
IM_OK配置成功
IM_ERR_INVALID_PARAM指针为空、实例非法或字段越界
IM_ERR_TIMEOUT复位等待超时

补充说明:

  • HACT 计算:16-bit 总线为 width,8-bit 总线为 width×2。

  • 输入接口选择值为 0(BT656)。

4.1.11 hal_vic_configure_colorbar

error_code_t hal_vic_configure_colorbar(const hal_vic_colorbar_config_t *config);

功能说明:配置 BF 彩条发生器。函数先关闭彩条与仅替换数据使能,再写消隐、帧模式与 帧数;program_colors 为真时写两组各 8 个 YCbCr 值;最后按 replace_data_only选择只替换数据或替换同步与数据,并提交。

参数类型方向说明
configconst hal_vic_colorbar_config_t *输入彩条配置
返回值说明
IM_OK配置成功
IM_ERR_INVALID_PARAM指针为空、实例非法或字段越界

补充说明:

  • 彩条只对 DVP/BT656 输入有效。

  • 颜色按 Y[23:16] | Cb[15:8] | Cr[7:0] 打包。

  • replace_data_only = true 时保留输入同步信号,只替换数据。

4.1.12 hal_vic_disable_colorbar

error_code_t hal_vic_disable_colorbar(isp_regs_t *ispx);

功能说明:同时关闭彩条使能和仅替换数据使能,并提交寄存器更新。

参数类型方向说明
ispxisp_regs_t *输入ISP0 / ISP1
返回值说明
IM_OK已关闭
IM_ERR_INVALID_PARAMispx 非法

4.1.13 hal_vic_start

error_code_t hal_vic_start(isp_regs_t *ispx);

功能说明:置位 CTRL.START,启动 VIC 采集。

参数类型方向说明
ispxisp_regs_t *输入ISP0 / ISP1
返回值说明
IM_OK已启动
IM_ERR_INVALID_PARAMispx 非法

补充说明:调用前 VIC、TOP、IPC、WDMA 的配置必须已经提交。

4.1.14 hal_vic_stop

error_code_t hal_vic_stop(isp_regs_t *ispx);

功能说明:清除 CTRL.START,停止 VIC 采集。

参数类型方向说明
ispxisp_regs_t *输入ISP0 / ISP1
返回值说明
IM_OK已停止
IM_ERR_INVALID_PARAMispx 非法

4.1.15 hal_vic_camera_enable_sensor_mclk

error_code_t hal_vic_camera_enable_sensor_mclk(uint32_t index, uint32_t clk_rate_hz);

功能说明:使能指定 CIM 通道的传感器 MCLK。index 0 对应 CGU_CIM0,index 1 对应CGU_CIM1。函数读取当前频率,若读取失败或与请求值不同则重编程,然后打开 MCLK 时钟和 共享的 CIM 门控。

参数类型方向说明
indexuint32_t输入0 = CIM0,1 = CIM1
clk_rate_hzuint32_t输入目标 MCLK 频率,0 非法
返回值说明
IM_OK使能成功
IM_ERR_INVALID_PARAMindex ≥ 2 或 clk_rate_hz == 0
CPM 错误码读频率、设频率、开时钟或开门控失败

补充说明:

  • 频率读取失败只告警,随后仍会尝试重编程。

  • 频率设置失败只告警,函数继续尝试开时钟。

  • HAL_CPM_ID_GATE_CIM 是 CIM0/CIM1 共享门控;开门控失败时会关闭 MCLK 并返回错误。

4.1.16 hal_vic_camera_disable_sensor_mclk

error_code_t hal_vic_camera_disable_sensor_mclk(uint32_t index);

功能说明:关闭指定通道的 MCLK;当 CIM0 与 CIM1 都已关闭时,再关闭共享 CIM 门控。

参数类型方向说明
indexuint32_t输入0 = CIM0,1 = CIM1
返回值说明
IM_OK已关闭(共享门控可能仍开)
IM_ERR_INVALID_PARAMindex ≥ 2
CPM 错误码关时钟或查询状态失败

补充说明:只关自己的 MCLK;另一路仍在运行时共享门控保持开启。

4.1.17 hal_vic_read_interrupt_status

error_code_t hal_vic_read_interrupt_status(const isp_regs_t *ispx, uint32_t *status_out);

功能说明:读取 INT_STA 原始状态。

参数类型方向说明
ispxconst isp_regs_t *输入ISP0 / ISP1
status_outuint32_t *输出中断状态位图
返回值说明
IM_OK读取成功
IM_ERR_INVALID_PARAM指针为空或实例非法

4.1.18 hal_vic_clear_interrupt_status

error_code_t hal_vic_clear_interrupt_status(isp_regs_t *ispx, uint32_t mask);

功能说明:向 INT_CLR 写 1 清除指定位。

参数类型方向说明
ispxisp_regs_t *输入ISP0 / ISP1
maskuint32_t输入HAL_VIC_IRQ_* 位组合
返回值说明
IM_OK已写入
IM_ERR_INVALID_PARAMispx 非法

4.1.19 hal_vic_read_work_state

error_code_t hal_vic_read_work_state(const isp_regs_t *ispx, uint32_t *state_out);

功能说明:读取 W_STATE 状态机的 7 位状态值。

参数类型方向说明
ispxconst isp_regs_t *输入ISP0 / ISP1
state_outuint32_t *输出状态值,0~0x7F
返回值说明
IM_OK读取成功
IM_ERR_INVALID_PARAM指针为空或实例非法

4.1.20 hal_vic_regs_dump

error_code_t hal_vic_regs_dump(const isp_regs_t *ispx);

功能说明:打印 VIC 前端主要寄存器。

参数类型方向说明
ispxconst isp_regs_t *输入ISP0 / ISP1
返回值说明
IM_OK打印完成
IM_ERR_UNSUPPORTED调试辅助未编译
IM_ERR_INVALID_PARAM实例非法(仅调试辅助开启时检查)

补充说明:只有 CONFIG_SDK_ENABLE_DEBUG_HELPERS 与 CONFIG_VIC_ENABLE_DEBUG_HELPERS同时为真时才有效。

4.2 ISP 模块时钟

4.2.1 hal_isp_clock_enable

error_code_t hal_isp_clock_enable(void);

功能说明:把 CGU_ISPM 的父时钟设为 SCLK_A,频率设为HAL_ISP_CLOCK_DEFAULT_HZ(100 MHz),然后使能该时钟。

参数类型方向说明
无———
返回值说明
IM_OK使能成功
CPM 错误码设置父时钟、设置频率或使能失败

补充说明:

  • 访问任何 ISP 寄存器前必须先使能该时钟,否则读回常数、写入被丢弃。

  • 两个 ISP 实例共用本时钟,引用计数由 CPM 维护。

  • ISP 没有独立门控位,分频器就是全部使能路径。

4.2.2 hal_isp_clock_disable

error_code_t hal_isp_clock_disable(void);

功能说明:释放一次 hal_isp_clock_enable() 取得的引用。

参数类型方向说明
无———
返回值说明
IM_OK成功
CPM 错误码关闭失败

补充说明:仍有相机持有引用时时钟保持运行。

4.2.3 hal_isp_clock_set_rate_hz

error_code_t hal_isp_clock_set_rate_hz(uint32_t rate_hz);

功能说明:设置 ISP 模块时钟频率。

参数类型方向说明
rate_hzuint32_t输入目标频率,0 非法
返回值说明
IM_OK设置成功
IM_ERR_INVALID_PARAMrate_hz == 0
CPM 错误码分频计算或写入失败

补充说明:硬件分频器按不高于请求值的档位取整,精确值不必等于请求值。

4.2.4 hal_isp_clock_get_rate_hz

error_code_t hal_isp_clock_get_rate_hz(uint32_t *rate_hz_out);

功能说明:读取 ISP 模块时钟当前频率。

参数类型方向说明
rate_hz_outuint32_t *输出当前频率
返回值说明
IM_OK读取成功
IM_ERR_INVALID_PARAM输出指针为空
CPM 错误码读取失败

4.3 TOP

4.3.1 hal_isp_top_struct_init

void hal_isp_top_struct_init(hal_isp_top_config_t *config);

功能说明:填充 TOP 默认配置(ISP0、640×480、YUV、旁路 DMSC)。

参数类型方向说明
confighal_isp_top_config_t *输出待填充配置

返回值:无。config 为 NULL 时直接返回。

4.3.2 hal_isp_top_reset

error_code_t hal_isp_top_reset(isp_regs_t *ispx);

功能说明:置位 RST.FUN_RST(bit2),请求 TOP 功能复位。

参数类型方向说明
ispxisp_regs_t *输入ISP0 / ISP1
返回值说明
IM_OK已请求
IM_ERR_INVALID_PARAM实例非法

补充说明:本函数不轮询完成状态。

4.3.3 hal_isp_top_configure

error_code_t hal_isp_top_configure(const hal_isp_top_config_t *config);

功能说明:配置 TOP 帧几何、输入类型、Bayer 类型、统计位置、行间距、DMSC 影子写选择、 DMSC 旁路、测试图和溢出停止,并按需触发影子更新。

参数类型方向说明
configconst hal_isp_top_config_t *输入TOP 配置
返回值说明
IM_OK配置成功
IM_ERR_INVALID_PARAM指针为空、实例非法或字段越界

补充说明:

  • 尺寸校验:宽/高分别在 640~1920、360~1080,且均为 4 的倍数。

  • 编程顺序:触发复位 → 影子选择 → 帧宽 → 帧高 → 数据类型 → Bayer → 统计位置 → IPC 行间距 → 普通行间距 → DMSC 影子写选择 → 旁路 → RAW/RGB/YUV 测试图 → 溢出停止 → 可选影子触发。

  • 测试图寄存器位是反相的:硬件位为 0 表示启用测试图,HAL 的enable_*_test_pattern 取反后写入。

  • 影子写选择非 0 时走 pre-shadow 写,否则走普通 shadow 写。

  • enable_overflow_stop 写 OVERFLOW_STOP_EN bit0。在已验证的硬件上该位看不出可观测 效果:把它置 1 并不能抑制溢出后的停流,也不能阻止 stop_int。 不要靠它做溢出保护;溢出后的恢复要看 IPC.RESTART 的档位(见 8.5),或者直接停流重来(见 8.11)。

  • FUN_RST 只复位各模块的计算部分,不复位配置参数,也不会清 STATIC_EN 的回读值。

4.3.4 hal_isp_top_enable_ae_statistics

error_code_t hal_isp_top_enable_ae_statistics(isp_regs_t *ispx);

功能说明:置位 STATIC_EN bit0,使能 AE 分区统计。

参数类型方向说明
ispxisp_regs_t *输入ISP0 / ISP1
返回值说明
IM_OK已使能
IM_ERR_INVALID_PARAM实例非法

4.3.5 hal_isp_top_disable_ae_statistics

error_code_t hal_isp_top_disable_ae_statistics(isp_regs_t *ispx);

功能说明:清除 STATIC_EN bit0。

参数类型方向说明
ispxisp_regs_t *输入ISP0 / ISP1
返回值说明
IM_OK已关闭
IM_ERR_INVALID_PARAM实例非法

4.3.6 hal_isp_top_enable_histogram

error_code_t hal_isp_top_enable_histogram(isp_regs_t *ispx);

功能说明:置位 STATIC_EN bit1,使能直方图统计。

参数类型方向说明
ispxisp_regs_t *输入ISP0 / ISP1
返回值说明
IM_OK已使能
IM_ERR_INVALID_PARAM实例非法

4.3.7 hal_isp_top_disable_histogram

error_code_t hal_isp_top_disable_histogram(isp_regs_t *ispx);

功能说明:清除 STATIC_EN bit1。

参数类型方向说明
ispxisp_regs_t *输入ISP0 / ISP1
返回值说明
IM_OK已关闭
IM_ERR_INVALID_PARAM实例非法

4.3.8 hal_isp_top_stop

error_code_t hal_isp_top_stop(isp_regs_t *ispx);

功能说明:置位 STOP_CON bit0,请求 TOP 停止。

参数类型方向说明
ispxisp_regs_t *输入ISP0 / ISP1
返回值说明
IM_OK已请求
IM_ERR_INVALID_PARAM实例非法

补充说明:

  • 写 STOP_CON 是触发位,写入后自清;效果是只停当前实例这一路(另一路不受影响)。 写入后该路 done 冻结、avail=0,RESP 报一次 stop_int。

  • 不要用 hal_isp_top_read_stop_state() 判断“停没停”。健康出流的那一路 读回与已停流的那一路相同(STOP_CON=0、STOP_STATE=1),这两个读数没有判别力。 判停流请看行为(done 是否冻结、avail 是否为 0)和 RESP 的 stop_int。

  • stop_int 的语义是“TOP 停流机器走了一遭”的通知位,不等于“出流确实停了”,也不 说明是谁请求的。

4.3.9 hal_isp_top_trigger_shadow

error_code_t hal_isp_top_trigger_shadow(isp_regs_t *ispx);

功能说明:置位 SHD_TEST_CTRL bit0,触发一次影子寄存器更新。

参数类型方向说明
ispxisp_regs_t *输入ISP0 / ISP1
返回值说明
IM_OK已触发
IM_ERR_INVALID_PARAM实例非法

4.3.10 hal_isp_top_read_stop_state

error_code_t hal_isp_top_read_stop_state(const isp_regs_t *ispx, uint32_t *state_out);

功能说明:读取 STOP_STATE。实现连续读两次并返回第二次的值。

参数类型方向说明
ispxconst isp_regs_t *输入ISP0 / ISP1
state_outuint32_t *输出停止状态
返回值说明
IM_OK读取成功
IM_ERR_INVALID_PARAM指针为空或实例非法

补充说明:

  • 实现上第一次读的结果被丢弃,返回第二次读的值(寄存器手册建议,单次读不算稳定值)。

  • 但这个读数不能用来判断停流:健康出流的一路与已停流的一路读回相同 (常见 0/1),零判别力。判停流看 done 是否冻结、avail 是否为 0。

4.3.11 hal_isp_top_regs_dump

error_code_t hal_isp_top_regs_dump(const isp_regs_t *ispx);

功能说明:打印 TOP 主要寄存器。

参数类型方向说明
ispxconst isp_regs_t *输入ISP0 / ISP1
返回值说明
IM_OK打印完成
IM_ERR_UNSUPPORTED调试辅助未编译

4.4 IPC

4.4.1 hal_isp_ipc_struct_init

void hal_isp_ipc_struct_init(hal_isp_ipc_config_t *config);

功能说明:填充 IPC 默认配置(输出映射计数 0、通道 0 触发源 4、配置后触发)。

参数类型方向说明
confighal_isp_ipc_config_t *输出待填充配置

返回值:无。config 为 NULL 时直接返回。

4.4.2 hal_isp_ipc_configure

error_code_t hal_isp_ipc_configure(const hal_isp_ipc_config_t *config);

功能说明:配置 IPC 输出映射计数、映射值、溢出/尺寸错误重启、触发模式、通道 0 触发源和 Y/UV 偏移;trigger_after_config 为真时最后触发一次。

参数类型方向说明
configconst hal_isp_ipc_config_t *输入IPC 配置
返回值说明
IM_OK配置成功
IM_ERR_INVALID_PARAM指针为空、实例非法或字段越界

补充说明:

  • 编程顺序:输出映射计数 → 输出映射 → 溢出重启 → 尺寸错误重启 → 触发模式 → 通道 0 触发源 → Y 偏移 → UV 偏移 → 可选触发。

  • output_number 写的是 OUT_NUM,语义是输出映射计数器上限,不是“通道数”:0 表示只用映射项 0,也就是常见的单摄线性输出;写 N 表示循环使用映射项 0~N。 单摄场景保持 0、output_map = 0 即可,不要因为“只有一路”而困惑。

  • overflow_restart / size_error_restart 决定的是异常后这一路要不要走停流序列, 不是“自动恢复”。两档都需要外部动作才能恢复,且恢复手段不同,详见 8.5 的对照表。

  • channel0_trigger_select = 0 表示通道 0 不由触发源启动;默认值 4 是正常运行所需。

  • 硬件对 Y/UV 偏移执行加法后饱和到 0~255。

  • 中间件对 NV12 输出刻意把 uv_offset 留 0:非 0 会让 UV 平面整体偏移,画面偏色。

4.4.3 hal_isp_ipc_trigger

error_code_t hal_isp_ipc_trigger(isp_regs_t *ispx);

功能说明:置位 TRIGE bit0,触发 IPC 开始一帧输出。

参数类型方向说明
ispxisp_regs_t *输入ISP0 / ISP1
返回值说明
IM_OK已触发
IM_ERR_INVALID_PARAM实例非法

4.4.4 hal_isp_ipc_read_version

error_code_t hal_isp_ipc_read_version(const isp_regs_t *ispx,
                                      uint32_t *soft_version_out,
                                      uint32_t *hard_version_out);

功能说明:读取 IPC 软件版本号与硬件版本号。

参数类型方向说明
ispxconst isp_regs_t *输入ISP0 / ISP1
soft_version_outuint32_t *输出软件版本
hard_version_outuint32_t *输出硬件版本
返回值说明
IM_OK读取成功
IM_ERR_INVALID_PARAM任一指针为空或实例非法

4.4.5 hal_isp_ipc_regs_dump

error_code_t hal_isp_ipc_regs_dump(const isp_regs_t *ispx);

功能说明:打印 IPC 主要寄存器。

参数类型方向说明
ispxconst isp_regs_t *输入ISP0 / ISP1
返回值说明
IM_OK打印完成
IM_ERR_UNSUPPORTED调试辅助未编译

4.5 RESP

4.5.1 hal_isp_resp_struct_init

void hal_isp_resp_struct_init(hal_isp_resp_config_t *config);

功能说明:填充 RESP 默认配置(只使能 GPL_WDMA_DONE,使能前清空)。

参数类型方向说明
confighal_isp_resp_config_t *输出待填充配置

返回值:无。config 为 NULL 时直接返回。

4.5.2 hal_isp_resp_configure

error_code_t hal_isp_resp_configure(const hal_isp_resp_config_t *config);

功能说明:按需清空所有挂起事件,然后写三组事件源使能和 CPU 上报掩码。

参数类型方向说明
configconst hal_isp_resp_config_t *输入RESP 配置
返回值说明
IM_OK配置成功
IM_ERR_INVALID_PARAM指针为空、实例非法或事件位超出该组定义

补充说明:

  • 事件源使能寄存器中 1 = 使能该事件源。

  • CPU 上报掩码中 1 = 允许上报 CPU、0 = 阻止,与 VIC 的 INT_MASK 相反。

  • 事件掩码不允许包含该组 EVENT_ALL 之外的位。

4.5.3 hal_isp_resp_clear_all

error_code_t hal_isp_resp_clear_all(isp_regs_t *ispx);

功能说明:置位 INT_CTRL bit16,清空所有挂起事件。

参数类型方向说明
ispxisp_regs_t *输入ISP0 / ISP1
返回值说明
IM_OK已清空
IM_ERR_INVALID_PARAM实例非法

4.5.4 hal_isp_resp_read_common0_events

error_code_t hal_isp_resp_read_common0_events(const isp_regs_t *ispx,
                                              uint32_t *events_out);

功能说明:读取 COMMON_0 挂起事件,并按该组 EVENT_ALL 掩码裁剪。

参数类型方向说明
ispxconst isp_regs_t *输入ISP0 / ISP1
events_outuint32_t *输出HAL_ISP_RESP_COMMON0_* 位组合
返回值说明
IM_OK读取成功
IM_ERR_INVALID_PARAM指针为空或实例非法

补充说明:若该组处于读清除模式,读取会顺带清除返回的位。

4.5.5 hal_isp_resp_read_unusual0_events

error_code_t hal_isp_resp_read_unusual0_events(const isp_regs_t *ispx,
                                               uint32_t *events_out);

功能说明:读取 UNUSUAL_0 挂起事件并裁剪。

参数类型方向说明
ispxconst isp_regs_t *输入ISP0 / ISP1
events_outuint32_t *输出HAL_ISP_RESP_UNUSUAL0_* 位组合
返回值说明
IM_OK读取成功
IM_ERR_INVALID_PARAM指针为空或实例非法

4.5.6 hal_isp_resp_read_backup0_events

error_code_t hal_isp_resp_read_backup0_events(const isp_regs_t *ispx,
                                              uint32_t *events_out);

功能说明:读取 BACKUP_0 挂起事件并裁剪。

参数类型方向说明
ispxconst isp_regs_t *输入ISP0 / ISP1
events_outuint32_t *输出HAL_ISP_RESP_BACKUP0_* 位组合
返回值说明
IM_OK读取成功
IM_ERR_INVALID_PARAM指针为空或实例非法

4.5.7 hal_isp_resp_clear_common0_events

error_code_t hal_isp_resp_clear_common0_events(isp_regs_t *ispx, uint32_t events);

功能说明:清除 COMMON_0 指定事件。

参数类型方向说明
ispxisp_regs_t *输入ISP0 / ISP1
eventsuint32_t输入要清除的事件位
返回值说明
IM_OK已处理
IM_ERR_INVALID_PARAM实例非法或事件位越界

补充说明:events == 0 时不写寄存器,直接返回 IM_OK。

4.5.8 hal_isp_resp_clear_unusual0_events

error_code_t hal_isp_resp_clear_unusual0_events(isp_regs_t *ispx, uint32_t events);

功能说明:清除 UNUSUAL_0 指定事件。

参数类型方向说明
ispxisp_regs_t *输入ISP0 / ISP1
eventsuint32_t输入要清除的事件位
返回值说明
IM_OK已处理
IM_ERR_INVALID_PARAM实例非法或事件位越界

4.5.9 hal_isp_resp_clear_backup0_events

error_code_t hal_isp_resp_clear_backup0_events(isp_regs_t *ispx, uint32_t events);

功能说明:清除 BACKUP_0 指定事件。

参数类型方向说明
ispxisp_regs_t *输入ISP0 / ISP1
eventsuint32_t输入要清除的事件位
返回值说明
IM_OK已处理
IM_ERR_INVALID_PARAM实例非法或事件位越界

4.5.10 hal_isp_resp_read_position

error_code_t hal_isp_resp_read_position(const isp_regs_t *ispx, uint8_t index,
                                        hal_isp_resp_position_t *position_out);

功能说明:读取指定断点位置的像素坐标。

参数类型方向说明
ispxconst isp_regs_t *输入ISP0 / ISP1
indexuint8_t输入位置索引,0~2
position_outhal_isp_resp_position_t *输出水平/垂直计数
返回值说明
IM_OK读取成功
IM_ERR_INVALID_PARAM指针为空、实例非法或 index ≥ 3

补充说明:索引 0 对应 IPC,1 对应 DMSC Y,2 对应 DMSC C。

4.5.11 hal_isp_resp_read_pending

error_code_t hal_isp_resp_read_pending(const isp_regs_t *ispx,
                                       hal_isp_resp_pending_t *pending_out);

功能说明:一次读取三组挂起事件并按位解码为具名布尔字段。

参数类型方向说明
ispxconst isp_regs_t *输入ISP0 / ISP1
pending_outhal_isp_resp_pending_t *输出解码结果
返回值说明
IM_OK读取成功
IM_ERR_INVALID_PARAM指针为空或实例非法

补充说明:本函数不会主动清除事件;需要时再调用 hal_isp_resp_clear_pending()。

4.5.12 hal_isp_resp_clear_pending

error_code_t hal_isp_resp_clear_pending(isp_regs_t *ispx,
                                        const hal_isp_resp_pending_t *pending);

功能说明:按 pending 中三组 events 字段清除对应事件。

参数类型方向说明
ispxisp_regs_t *输入ISP0 / ISP1
pendingconst hal_isp_resp_pending_t *输入待清除事件
返回值说明
IM_OK已处理
IM_ERR_INVALID_PARAM指针为空、实例非法或事件位越界

补充说明:三组事件均为 0 时不写寄存器。

4.5.13 hal_isp_resp_regs_dump

error_code_t hal_isp_resp_regs_dump(const isp_regs_t *ispx);

功能说明:打印 RESP 主要寄存器。

参数类型方向说明
ispxconst isp_regs_t *输入ISP0 / ISP1
返回值说明
IM_OK打印完成
IM_ERR_UNSUPPORTED调试辅助未编译

4.6 GPL_WDMA

4.6.1 hal_isp_wdma_struct_init

void hal_isp_wdma_struct_init(hal_isp_wdma_config_t *config);

功能说明:填充 WDMA 静态配置默认值(DMSC YUV 通路、YUV420 双平面、步长 0)。

参数类型方向说明
confighal_isp_wdma_config_t *输出待填充配置

返回值:无。config 为 NULL 时直接返回。

4.6.2 hal_isp_wdma_frame_struct_init

void hal_isp_wdma_frame_struct_init(hal_isp_wdma_frame_config_t *frame_config);

功能说明:填充单帧配置默认值(地址 0、不写 UV 地址)。

参数类型方向说明
frame_confighal_isp_wdma_frame_config_t *输出待填充帧配置

返回值:无。frame_config 为 NULL 时直接返回。

4.6.3 hal_isp_wdma_configure

error_code_t hal_isp_wdma_configure(const hal_isp_wdma_config_t *config);

功能说明:写 WDMA 数据源、数据排布、字节序、Y/UV 步长和两路 DMA 优先级。

参数类型方向说明
configconst hal_isp_wdma_config_t *输入WDMA 配置
返回值说明
IM_OK配置成功
IM_ERR_INVALID_PARAM指针为空、实例非法或字段越界

补充说明:步长 0 是合法值;非 0 时必须 8 字节对齐且不超过 0xFFF8。

4.6.4 hal_isp_wdma_start_frame

error_code_t hal_isp_wdma_start_frame(const hal_isp_wdma_frame_config_t *frame_config,
                                      const hal_isp_wdma_static_config_t *static_config);

功能说明:为下一帧写起始地址。函数先检查地址 FIFO;若满则复位 WDMA 并重新应用static_config,然后按需写 C_START_ADDR,最后写 START_ADDR。

参数类型方向说明
frame_configconst hal_isp_wdma_frame_config_t *输入单帧地址配置
static_configconst hal_isp_wdma_static_config_t *输入用于 FIFO 恢复后重配的静态参数
返回值说明
IM_OK已写入
IM_ERR_INVALID_PARAM指针为空、实例非法、地址未对齐或越界
其他恢复流程中 hal_isp_wdma_reset() 或重配失败

补充说明:

  • 地址必须 8 字节对齐,且不超过 0x1FFFFFF8。

  • FIFO 状态解码不自洽时只告警一次,并跳过满检查。

  • FIFO 满时执行:告警 → 软件复位(请求、延时 10 µs、清除)→ 重新初始化配置结构 → 重写静态配置 → 再写本帧地址。

  • START_ADDR 会推动地址 FIFO 并可能启动搬运,因此必须最后写。

  • 本函数不等待帧完成,完成状态通过 RESP 事件或 hal_isp_wdma_read_done() 获取。

4.6.5 hal_isp_wdma_read_address_fifo

error_code_t hal_isp_wdma_read_address_fifo(const isp_regs_t *ispx,
                                            hal_isp_wdma_address_fifo_t *fifo_out);

功能说明:读取 Y 与 UV 两个地址 FIFO 的调试值并解码。

参数类型方向说明
ispxconst isp_regs_t *输入ISP0 / ISP1
fifo_outhal_isp_wdma_address_fifo_t *输出解码结果
返回值说明
IM_OK读取成功
IM_ERR_INVALID_PARAM指针为空或实例非法

补充说明:valid 要求 data + free == 4、full == (free == 0)、empty == (data == 0) 同时成立。

4.6.6 hal_isp_wdma_request_reset

error_code_t hal_isp_wdma_request_reset(isp_regs_t *ispx);

功能说明:置位 SOFT_RESET bit0,请求 WDMA 软件复位。

参数类型方向说明
ispxisp_regs_t *输入ISP0 / ISP1
返回值说明
IM_OK已请求
IM_ERR_INVALID_PARAM实例非法

4.6.7 hal_isp_wdma_clear_reset

error_code_t hal_isp_wdma_clear_reset(isp_regs_t *ispx);

功能说明:清除 SOFT_RESET bit0。

参数类型方向说明
ispxisp_regs_t *输入ISP0 / ISP1
返回值说明
IM_OK已清除
IM_ERR_INVALID_PARAM实例非法

4.6.8 hal_isp_wdma_reset

error_code_t hal_isp_wdma_reset(isp_regs_t *ispx);

功能说明:请求复位、延时 10 µs、再清除复位。

参数类型方向说明
ispxisp_regs_t *输入ISP0 / ISP1
返回值说明
IM_OK完成
IM_ERR_INVALID_PARAM实例非法

补充说明:软件复位会清掉静态配置,复位后必须重新调用 hal_isp_wdma_configure()。

4.6.9 hal_isp_wdma_is_busy

error_code_t hal_isp_wdma_is_busy(const isp_regs_t *ispx, bool *busy_out);

功能说明:读取 DUMP_EN 判断 WDMA 是否已开始工作。

参数类型方向说明
ispxconst isp_regs_t *输入ISP0 / ISP1
busy_outbool *输出true 表示 DUMP_EN 置位
返回值说明
IM_OK读取成功
IM_ERR_INVALID_PARAM指针为空或实例非法

4.6.10 hal_isp_wdma_read_done

error_code_t hal_isp_wdma_read_done(const isp_regs_t *ispx,
                                    hal_isp_wdma_done_info_t *done_out);

功能说明:读取 Y/UV 完成地址和 DUMP_EN 状态。

参数类型方向说明
ispxconst isp_regs_t *输入ISP0 / ISP1
done_outhal_isp_wdma_done_info_t *输出完成信息
返回值说明
IM_OK读取成功
IM_ERR_INVALID_PARAM指针为空或实例非法

补充说明:完成地址寄存器不复位,可能保留上一次运行的值,不能仅凭非 0 判断本帧完成。

4.6.11 hal_isp_wdma_regs_dump

error_code_t hal_isp_wdma_regs_dump(const isp_regs_t *ispx);

功能说明:打印 WDMA 主要寄存器。

参数类型方向说明
ispxconst isp_regs_t *输入ISP0 / ISP1
返回值说明
IM_OK打印完成
IM_ERR_UNSUPPORTED调试辅助未编译

4.7 DMSC

4.7.1 hal_isp_dmsc_struct_init

void hal_isp_dmsc_struct_init(hal_isp_dmsc_config_t *config_out);

功能说明:填充 DMSC 默认配置(3×3 输出、系数与偏移全 0、裁剪 0~0xFF)。

参数类型方向说明
config_outhal_isp_dmsc_config_t *输出待填充配置

返回值:无。config_out 为 NULL 时直接返回。

4.7.2 hal_isp_dmsc_configure

error_code_t hal_isp_dmsc_configure(const hal_isp_dmsc_config_t *config);

功能说明:配置 DMSC 输出选项、输入模式、UV 分辨率模式、RGB 偏移、3×3 矩阵、 Y/UV 偏移与裁剪范围。

参数类型方向说明
configconst hal_isp_dmsc_config_t *输入DMSC 配置
返回值说明
IM_OK配置成功
IM_ERR_INVALID_PARAM指针为空、实例非法、字段越界或裁剪最小值大于最大值

补充说明:

  • 矩阵系数并非统一的 9 位字段:m02 为 8 位,m01/m12/m20 为 10 位, 其余为 9 位。

  • output_option = 1 选择 2×2 插值,其余值选择 3×3 插值。

  • 本 HAL 不写 TOP 的 DMSC 旁路位;是否经过 DMSC 由 hal_isp_top_configure() 的bypass_dmsc 决定。

4.7.3 hal_isp_dmsc_read_debug0

error_code_t hal_isp_dmsc_read_debug0(const isp_regs_t *ispx,
                                      hal_isp_dmsc_debug0_t *debug_out);

功能说明:读取输出 FIFO 已用/空闲项数。

参数类型方向说明
ispxconst isp_regs_t *输入ISP0 / ISP1
debug_outhal_isp_dmsc_debug0_t *输出解码结果
返回值说明
IM_OK读取成功
IM_ERR_INVALID_PARAM指针为空或实例非法

4.7.4 hal_isp_dmsc_read_debug1

error_code_t hal_isp_dmsc_read_debug1(const isp_regs_t *ispx,
                                      hal_isp_dmsc_debug1_t *debug_out);

功能说明:读取输出状态机、FIFO 标志和输入反压。

参数类型方向说明
ispxconst isp_regs_t *输入ISP0 / ISP1
debug_outhal_isp_dmsc_debug1_t *输出解码结果
返回值说明
IM_OK读取成功
IM_ERR_INVALID_PARAM指针为空或实例非法

4.7.5 hal_isp_dmsc_regs_dump

error_code_t hal_isp_dmsc_regs_dump(const isp_regs_t *ispx);

功能说明:打印 DMSC 主要寄存器。

参数类型方向说明
ispxconst isp_regs_t *输入ISP0 / ISP1
返回值说明
IM_OK打印完成
IM_ERR_UNSUPPORTED调试辅助未编译

4.8 AE

4.8.1 hal_isp_ae_struct_init

void hal_isp_ae_struct_init(hal_isp_ae_config_t *config_out);

功能说明:填充 AE 默认配置(15×15 分区、水平尺寸 20、垂直尺寸 16、4 缓冲、影子使能)。

参数类型方向说明
config_outhal_isp_ae_config_t *输出待填充配置

返回值:无。config_out 为 NULL 时直接返回。

4.8.2 hal_isp_ae_configure

error_code_t hal_isp_ae_configure(const hal_isp_ae_config_t *config);

功能说明:配置 AE 分区网格、分区尺寸、亮度阈值、统计/直方图频率、工作模式、DMA 基址与 缓冲数、监视与优先级、特定窗口、反压和影子更新。

参数类型方向说明
configconst hal_isp_ae_config_t *输入AE 配置
返回值说明
IM_OK配置成功
IM_ERR_INVALID_PARAM指针为空、实例非法或字段越界

补充说明:

  • 只校验 statistics_buffer_count / histogram_buffer_count 之内的 DMA 基址; 未使用的表项由 HAL 写 0。

  • DMA 缓冲数写入硬件字段时使用 count - 1。

  • 分区尺寸只把前 zone_h_number / zone_v_number 个有效表项拷贝到零填充的局部数组, 其余表项写 0。

  • 分区尺寸寄存器每 4 项打包为一个 32 位寄存器:1–4 在 HOR_ZONE_SIZE_14, 5–8 在 _58,9–12 在 _912,13–15 在 _1315;垂直方向同理。

  • enable_shadow 由 HAL 在配置末尾直接写 SHD_CTRL bit0:这是一次一次性触发, 硬件在下一个帧边界完成影子更新后自动清零。也就是说,每次改完 AE 配置都要重新写 一次 SHD_CTRL,不需要(也无法)把它当作常开使能位来轮询。

  • AE 的配置值是写进影子寄存器组的,帧边界才生效。写 SHD_CTRL 后下一帧即按新配置 统计;不写则新配置一直停在影子组里。

  • AE 的分区尺寸寄存器复位值是每格 64×36,15×15 格覆盖 960×540,比 640×480 的帧还大。 只改 DMA 基址、其它字段保持复位值时,统计窗口会跑出帧外,拿不到有效数据。正确做法 是用 hal_isp_ae_struct_init() 的默认值(每格 20×16) 整套下下去,或按实际分辨率自己算网格尺寸。

4.8.3 hal_isp_ae_read_dma_info

error_code_t hal_isp_ae_read_dma_info(const isp_regs_t *ispx,
                                      hal_isp_ae_dma_info_t *info_out);

功能说明:读取当前 DMA 缓冲索引、AE 帧计数、停止应答与两路尺寸错误标志。

参数类型方向说明
ispxconst isp_regs_t *输入ISP0 / ISP1
info_outhal_isp_ae_dma_info_t *输出DMA 状态
返回值说明
IM_OK读取成功
IM_ERR_INVALID_PARAM指针为空或实例非法

补充说明:三个布尔状态在结构体中表示为 1/0 的 uint32_t。

4.8.4 hal_isp_ae_read_specific_statistics

error_code_t hal_isp_ae_read_specific_statistics(const isp_regs_t *ispx,
                                                 hal_isp_ae_specific_statistics_t *statistics_out);

功能说明:读取特定窗口的帧号、暗/中/饱和像素和与暗/饱和像素计数。

参数类型方向说明
ispxconst isp_regs_t *输入ISP0 / ISP1
statistics_outhal_isp_ae_specific_statistics_t *输出统计结果
返回值说明
IM_OK读取成功
IM_ERR_INVALID_PARAM指针为空或实例非法

4.8.5 hal_isp_ae_regs_dump

error_code_t hal_isp_ae_regs_dump(const isp_regs_t *ispx);

功能说明:打印 AE 主要寄存器。

参数类型方向说明
ispxconst isp_regs_t *输入ISP0 / ISP1
返回值说明
IM_OK打印完成
IM_ERR_UNSUPPORTED调试辅助未编译

5. 典型用法:从零开始

本章按“从一块刚上电的板子到第一帧数据落进 DDR”的顺序,把 HAL 调用串起来。每一步都 给出目标、代码和容易踩的坑。如果你只是想改中间件的行为,可以只读 8.1 和 8.12。

5.1 开始之前:先想清楚五件事

问题影响对应配置
用哪个实例?决定 ispx、IRQ 号、有没有 AE/DMSCISP0 / ISP1
输入是 DVP 还是 MIPI?决定调用 hal_vic_configure_dvp 还是 configure_mipi,以及 MCLK 走 CIM 还是 CSI板级接线
分辨率与格式?TOP 只接受 640×360~1920×1080;格式决定 data_type / pixel_format / data_type(CSI)sensor 输出
输出要什么?要 NV12 就必须走 DMSC(且输入是 RAW);直写 RAW/YUV 就旁路 DMSCbypass_dmsc + mux_sel
谁来收帧?中断(RESP)还是轮询;缓冲有几块、每块多大WDMA 地址 FIFO + RESP

先写一张纸:

        instance : ISP0
        input    : MIPI CSI, 2 lanes, 640x480 RAW10
        output   : NV12 640x480 (DMSC on)
        buffers  : 4 frames, Y 640x480 + UV 320x240
        events   : WDMA_DONE -> IRQ -> dequeue

后面所有代码都从这张纸推出来。

5.2 第一步:打开 ISP 时钟

目标:让 ISP 寄存器窗口可访问。

#include "drivers/g32s10/vic/hal_isp_clock.h"

error_code_t isp_clock_up(void)
{
    return hal_isp_clock_enable();
}

补充说明:

  • hal_isp_clock_enable() 做三件事:把父时钟设为 SCLK_A、把频率设为 100 MHz (HAL_ISP_CLOCK_DEFAULT_HZ)、打开 CGU_ISPM。CPM 内部有引用计数, 两个实例共用同一个时钟。

  • 没有单独的“ISP0 时钟门控位”,也没有办法只给 ISP1 开时钟。

  • 时钟没开时,读寄存器会返回常数,而且不会报错。验证方法:读 VIC.CTRL两次(中间加一点延时),两次值应当稳定;如果读回 0xFFFFFFFF 或全 0 且对写 没反应,先怀疑时钟。

  • 还有第二个门:DVP 的寄存器窗口需要 CIM/MCLK 门控打开。中间件是在camera_open() 里先开 ISP 时钟、再由 sensor 的 power_on() 打开 CIM 门控并 给 MCLK。在 camera_open() 之前读 VIC 寄存器,读到的可能是常数。 自己的工程如果不用中间件,至少要先用 hal_vic_camera_enable_sensor_mclk()打开对应 CIM 的 MCLK,再访问 VIC 窗口。

  • 释放时调用 hal_isp_clock_disable();两个实例都释放后时钟才真正关闭。

5.3 第四步:配置 IPC

目标:把 TOP 的输出按默认单路映射送到 WDMA。

#include "drivers/g32s10/vic/hal_isp_ipc.h"

error_code_t ipc_setup(void)
{
    hal_isp_ipc_config_t ipc;

    hal_isp_ipc_struct_init(&ipc);
    ipc.ispx = ISP0;

    /* output_number = 0 selects mapping entry 0 only: single linear output. */
    ipc.output_number = 0U;
    ipc.output_map = 0U;
    ipc.channel0_trigger_select = 4U;
    ipc.trigger_after_config = true;

    return hal_isp_ipc_configure(&ipc);
}

补充说明:

  • 单摄场景用默认值就够了,唯一需要确认的是 ispx。

  • output_number 是“映射计数上限”,不是通道数。写 0 表示只用映射项 0。

  • trigger_after_config = true 会在配置末尾写 TRIGE,让 IPC 从下一帧开始输出。 如果希望自己控制启动时刻,把它置 false,之后调用 hal_isp_ipc_trigger()。

  • y_offset / uv_offset 保持 0。非 0 会让整个平面偏移,NV12 下表现为偏色。

  • 溢出/尺寸错误重启位(overflow_restart、size_error_restart)默认关。这两个位不提供 自动恢复,决定的是溢出后这一路走哪条失败路径,两条路径的恢复手段互不通用:

    overflow_restart溢出后现象stop_int恢复动作
    true该路停止输出,done 冻结,画面停在最后一帧有写该路的 TRIGE(hal_isp_ipc_trigger() / ISP+0x3020)
    false继续出流,done 照涨,但前端失步,画面行/列错位、卷动无该路 func_reset(hal_isp_top_reset() / ISP+0x0024 ← 0x4)

    两档都不自愈:TRIGE 修不了失步档,func_reset 也不是停流档的解;等一段时间 不会恢复,err/avail 也判断不出属于哪一档。要一次修好,最稳妥的做法仍是停流重来 (见 8.11)。HAL 的默认配置把两位都置关,中间件沿用默认值,TRIGE / func_reset都是每路独立的,写错实例无法恢复。不要把这两个位理解成“自动恢复”。

5.4 第六步:配置 DMSC(可选)

目标:把 RAW 变成 YUV,供 NV12 输出使用。

#include "drivers/g32s10/vic/hal_isp_dmsc.h"

error_code_t dmsc_setup_bt601(void)
{
    hal_isp_dmsc_config_t dmsc;

    hal_isp_dmsc_struct_init(&dmsc);
    dmsc.ispx = ISP0;

    /* Fill a real color matrix; the all-zero default turns Y into constant 0. */
    dmsc.matrix_00 = 0x12AU;
    dmsc.matrix_01 = 0x24AU;
    dmsc.matrix_02 = 0x074U;
    dmsc.matrix_10 = 0x3D0U;
    dmsc.matrix_11 = 0x350U;
    dmsc.matrix_12 = 0x0E0U;
    dmsc.matrix_20 = 0x3D0U;
    dmsc.matrix_21 = 0x3B0U;
    dmsc.matrix_22 = 0x080U;

    return hal_isp_dmsc_configure(&dmsc);
}

(上面的系数只是 BT.601 量级示意,不要直接当产品参数用;请按自己的颜色矩阵 和位宽填。)

补充说明:

  • 只有 ISP0 有 DMSC。ISP1 上没有这个寄存器块。

  • 默认配置是 3×3 输出 + 全 0 矩阵。全 0 矩阵不是“直通”,而是把 Y 打成常数 0, 画面全黑(或只剩 UV)。所以走 DMSC 就必须填完整矩阵。

  • 复位默认值本身就是一条 BT.601 Q10 链路:什么都不写也能出彩色。现在的相机 中间件从不调用 hal_isp_dmsc_configure(),依赖的正是这条复位通路。你自己写 DMSC 配置时,等于把这条通路替换掉,矩阵、偏移、裁剪都要一起填。

  • 矩阵字段位宽不统一:matrix_02 是 8 位,matrix_01/matrix_12/matrix_20是 10 位,其余是 9 位。超范围会被 HAL 拒绝。

  • uv_offset 保持 0。非 0 会让 UV 平面整体偏移,NV12 表现为偏色。

  • 是否走 DMSC 只由 TOP 的 bypass_dmsc 决定;DMSC 自己无法“打开/关闭旁路”。

  • 输入按 RAW10 设计。RAW8 输入没有完整的软件通路(见第 13 章)。

5.5 第八步:使能 RESP 事件与 CPU 中断

目标:让 WDMA_DONE(以及需要的 AE 事件)产生 CPU 中断。

#include "drivers/g32s10/vic/hal_isp_resp.h"

error_code_t resp_setup(bool with_ae)
{
    hal_isp_resp_config_t resp;
    uint32_t common = (uint32_t)HAL_ISP_RESP_COMMON0_GPL_WDMA_DONE;

    if (with_ae) {
        common |= (uint32_t)HAL_ISP_RESP_COMMON0_AE_STATIC_DONE;
    }

    hal_isp_resp_struct_init(&resp);
    resp.ispx = ISP0;
    resp.enable_events.common0 = common;   /* 1 = enabled */
    resp.cpu_events.common0 = common;      /* 1 = allowed to reach the CPU */
    resp.clear_all_before_enable = true;

    return hal_isp_resp_configure(&resp);
}

补充说明:

  • 两套极性很容易搞混:事件使能 INT_EN 是 1 = 使能;上报 CPU 的 INT_MASK是 1 = 放行、0 = 屏蔽,与 VIC 的掩码正好相反。

  • clear_all_before_enable = true 会先写 INT_CTRL.ALL_CLR(bit16),把上电/上次 运行留下的挂起事件清掉,避免一开中断就进 ISR。

  • VIC 与 RESP 共用一条 IRQ。ISR 里先读 hal_vic_read_interrupt_status() 并hal_vic_clear_interrupt_status(),再 hal_isp_resp_read_pending() /hal_isp_resp_clear_pending()。只处理一边会导致中断风暴。

  • 默认只使能 GPL_WDMA_DONE。要用 AE 就同时打开 AE_STATIC_DONE,否则统计完成 不会通知到你。

  • 读清模式(read-clear)默认关闭;不要假设“读一次就清了”,清除要走hal_isp_resp_clear_pending()。

5.6 第九步:AE 统计(可选,仅 ISP0)

目标:让 AE 每帧把 15×15 分区统计和直方图写进 DDR。

#include "drivers/g32s10/vic/hal_isp_ae.h"
#include "drivers/g32s10/vic/hal_isp_top.h"

static uint8_t s_ae_stats[2][4096] __attribute__((aligned(8)));
static uint8_t s_ae_hist[2][2048] __attribute__((aligned(8)));

error_code_t ae_setup(void)
{
    hal_isp_ae_config_t ae;

    hal_isp_ae_struct_init(&ae);
    ae.ispx = ISP0;

    ae.statistics_buffer_count = 2U;
    ae.statistics_dma_base[0] = (uint32_t)(uintptr_t)s_ae_stats[0];
    ae.statistics_dma_base[1] = (uint32_t)(uintptr_t)s_ae_stats[1];

    ae.histogram_buffer_count = 2U;
    ae.histogram_dma_base[0] = (uint32_t)(uintptr_t)s_ae_hist[0];
    ae.histogram_dma_base[1] = (uint32_t)(uintptr_t)s_ae_hist[1];

    return hal_isp_ae_configure(&ae);
}

/* Recommended after the stream is running: the order used by the middleware. */
error_code_t ae_start(void)
{
    return hal_isp_top_enable_ae_statistics(ISP0);
}

补充说明:

  • 只有 ISP0 有 AE。ISP1 上没有这个寄存器块。

  • 使能顺序:hal_isp_top_configure() → VIC 配置 → 启动 → hal_isp_top_enable_ae_statistics()。 这是中间件采用的顺序。TOP 的 FUN_RST 会复位计算部分(不清 STATIC_EN 的回读值), 把使能放在启动之后是最稳妥的写法。

  • enable_shadow 在 hal_isp_ae_configure() 末尾写一次 SHD_CTRL,是一次性触发, 帧边界自清。改完配置要重新触发,不能当常开位用。

  • 分区尺寸的复位值是每格 64×36(15×15 格覆盖 960×540),比 640×480 还大。只填 DMA 基址、不写网格时会采不到有效统计;用 hal_isp_ae_struct_init() 的默认整套下下去 最省事(每格 20×16)。

  • DMA 基址必须 8 字节对齐;缓冲数写进硬件时是 count - 1,HAL 负责换算。

  • 缓冲大小按用途给:测试用例里统计缓冲用 4 KiB、直方图缓冲用 2 KiB,每个 2 块。

  • 直方图另有读模式/触发模式两个开关,默认都关,先不要动。

6. 示例程序解读

6.1 用例二:tiziano_int_ae

它回答什么问题:AE 的 15×15 分区统计与直方图能不能真正落进 DDR,以及STATIC_EN / SHD_CTRL 的正确时序。

核心函数

static error_code_t tz_ae_apply_config(isp_regs_t *isp)
{
    hal_isp_ae_config_t config;
    uint32_t index;

    hal_isp_ae_struct_init(&config);
    config.ispx = isp;
    config.statistics_buffer_count = TZ_AE_BUF_COUNT;
    config.histogram_buffer_count = TZ_AE_BUF_COUNT;

    for (index = 0U; index < HAL_ISP_AE_DMA_BASE_COUNT; ++index) {
        bool used = (index < TZ_AE_BUF_COUNT);
        config.statistics_dma_base[index] = used ? s_ae_stats_base[index] : 0U;
        config.histogram_dma_base[index] = used ? s_ae_hist_base[index] : 0U;
    }

    /* The FAULT case needs the monitors to report AE_ERR / AE_HIST_ERR. */
    config.enable_statistics_dma_monitor = true;
    config.enable_histogram_dma_monitor = true;

    return hal_isp_ae_configure(&config);
}

三个必须记住的结论

  1. 不能只写 DMA 基址。分区尺寸寄存器复位值是 64×36,15×15 格要覆盖 960×540, 比 640×480 整帧还大,扫描完不成,统计一次都不产生(表现为帧号在涨、统计头 全是 0)。hal_isp_ae_struct_init() 的默认值(20×16)对应帧宽/2/15、帧高/2/15,与中间件使用的配置一致。

  2. SHD_CTRL 是一次性触发。写完立刻读是 1,过了一个帧边界读回 0。所以 “读到 0”不能当“配置没生效”;每次改 AE 寄存器都要重新写一次(HAL 的enable_shadow 就是干这个的)。

  3. STATIC_EN 建议在 camera_start() 之后写。这是中间件采用的顺序。 注意 FUN_RST 并不会清 STATIC_EN,所以不要拿 STATIC_EN 是否被清零来判断FUN_RST 是否发生;把使能放在启动之后仍然是无害且推荐的做法。

用例还给出了干净的回读期望:

ZONE_NUM_START : 0xf000f000   (start 0, 15 x 15)
H zone sizes   : 0x14141414   (20, 20, 20, 20)
V zone sizes   : 0x10101010   (16, 16, 16, 16)

复位值是 0xf001f001(起点 1),不能拿它当期望值。

判读陷阱:cur(当前写入的缓冲序号)只采一个瞬间,恒为 0 不能否定 DMA;要看hdr(统计缓冲前 4 个字是否非 0)以及帧号增量。fnum 只在说明 AE 收到了帧边界,不说明统计在算——网格越界时它也照样每帧 +1。

7. 集成到你自己的工程

7.1 CMake

驱动的 CMake 已经按组件注册,应用侧不需要手动添加源文件:

# code/drivers/g32s10/vic/CMakeLists.txt
if(CONFIG_DRIVER_VIC)
    imde_component_register(NAME g32s10_vic SRCS
        "${CMAKE_CURRENT_LIST_DIR}/hal_vic.c"
        "${CMAKE_CURRENT_LIST_DIR}/hal_isp_top.c"
        ...)
endif()

应用只需要:

  1. 在 defconfig 里打开 CONFIG_DRIVER_VIC;

  2. 在源文件里包含对应 HAL 头文件(drivers/g32s10/vic/...)。

MIPI 输入还需要 CSI/D-PHY 驱动(CONFIG_DRIVER_CSI);只做 DVP 时不需要。

8. 调试与验证

8.1 VIC 状态与中断

uint32_t status;
uint32_t state;

(void)hal_vic_read_interrupt_status(ISP0, &status);
(void)hal_vic_clear_interrupt_status(ISP0, status);
(void)hal_vic_read_work_state(ISP0, &state);

排查顺序:

  1. 先读 INT_MASK,确认要的位是 0(放行)。写 HAL_VIC_IRQ_ALL 是全部屏蔽, 这是最常见的错误。

  2. 确认 INT_STA 里目标位真的置起来了;没有置说明链路事件没发生(或窗口没开)。

  3. 位置了但 CPU 没进 ISR:检查 PLIC 使能、优先级、irq_enable()。

  4. CPU 反复进 ISR:INT_STA 清不掉,或 RESP 那边还有事件没清。VIC 与 RESP 共用 一条 IRQ,两边都要处理。

  5. MIPI 下 FRAME_RESET 可能常置,不要把它一起放行。

hal_vic_read_work_state() 返回 W_STATE[6:0],用于确认 VIC 是否处在“等待帧/接收 数据/输出”的某个状态;把它和 INT_STA 一起看,可以区分“没数据”和“数据来了但 下游堵住”。

8.2 WDMA 完成与地址 FIFO

hal_isp_wdma_done_info_t done;
hal_isp_wdma_address_fifo_t fifo;

(void)hal_isp_wdma_read_done(ISP0, &done);
(void)hal_isp_wdma_read_address_fifo(ISP0, &fifo);
观测含义
done.done_address最近一次完成地址;非 0 不代表本帧刚写完,要看是否在帧环内
done.dump_enabledDUMP_EN 状态
fifo.y_start.full地址 FIFO 满——不会再接受新地址
fifo.y_start.emptyFIFO 空——WDMA 下一帧没地址可写
fifo.*.valid计数与标志自洽;为假时该读数不可用

起流前必须 hal_isp_wdma_reset() 并确认四套 FIFO 全空。用例 A3 的做法是:写 2 个 地址 → 软复位 → 回读 empty=1 / data=0 / free=4。

9. 约束与注意事项

9.1 时钟与访问前提

  • 访问任何 ISP 寄存器前必须先调用 hal_isp_clock_enable()。时钟关闭时读回固定常数、 写入被丢弃,表现为“寄存器完全不动”。

  • CGU_ISPM 由 ISP0/ISP1 共用,没有独立门控位;关闭时钟会影响另一路。

  • hal_isp_clock_enable() 会把频率设为 100 MHz(HAL_ISP_CLOCK_DEFAULT_HZ), 这是当前验证过的配置;hal_isp_clock_set_rate_hz() 可以改,但改完要重新验证。

  • 只开 ISP 时钟还不够:VIC 寄存器窗口还压在一层共享的 CIM/MCLK 门控后面,那层由 sensor 的 power_on()(中间件里是 camera_open())打开。窗口没开时读回常数。

9.2 复位语义

  • VIC 复位通过 CTRL.RST(bit2)触发,硬件自清;hal_vic_reset() 轮询 CTRL == 0。

  • timeout_ms = 0 回退为 1000 ms,不是无限等待。

  • TOP 的 RST.FUN_RST(bit2)只置位请求,HAL 不轮询完成;它只复位计算部分,不清配置参数。STATIC_EN 回读不会被它清零,别用它当复位证据。

  • 尽管如此,仍建议把 AE/直方图使能安排在 TOP 配置与启动之后(中间件验证过的顺序)。

  • WDMA 软件复位会清除静态配置,复位后必须重新写 mux_sel、数据排布、步长等。

  • 重启 VIC 只能走 hal_vic_stop() → hal_vic_start()。只写一次 START 会破坏 几何配置。

9.3 TOP 约束

  • 帧尺寸范围 640×360 ~ 1920×1080,宽高必须 4 对齐;小于下限会被 HAL 直接拒绝。

  • 测试图控制位是反相的:硬件位 0 = 启用测试图。

  • hal_isp_top_read_stop_state() 连续读两次、返回第二次值,但该读数没有判别力: 健康出流与已停流的一路读回相同。判停流看 done 是否冻结、avail 是否为 0。

  • 统计位置 0 = IPC、1 = DMSC,2~7 保留。

  • DMSC 是否在通路上只由 bypass_dmsc 决定;DMSC 自身的配置不会改变旁路位。

9.4 RESP 约束

  • 三组事件必须按组使用各自的事件位定义,跨组位会被判为参数错误。

  • 读清除模式会改变读操作的副作用;默认不启用,读取不会清除状态。

  • hal_isp_resp_read_pending() 本身不清除事件,必须显式调用hal_isp_resp_clear_pending()。

  • clear_all_before_enable 默认打开,避免把上一次运行留下的事件当成本次事件。