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 → YUV | hal_isp_dmsc_configure() | DMSC.PAR_0..2/OFFSET/CLIP_MINMAX |
| 输出映射与偏移 | hal_isp_ipc_configure() | IPC.OUT_NUM/OUT_MAP/TRIGE_SEL/OFFSET |
| 写 DDR | hal_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_EN | AE.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 实例、中断与共享资源
| 资源 | ISP0 | ISP1 | 说明 |
|---|---|---|---|
| 基地址 | 0x13350000 | 0x13360000 | code/soc/g32s10/include/base.h |
| 中断 | IRQ_ISP0 = IRQ_PLIC0_START + 19 | IRQ_ISP1 = IRQ_PLIC0_START + 18 | VIC 与 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 寄存器块 |
两个直接后果:
中断服务程序里必须先读 VIC 的
INT_STA并写INT_CLR,再处理 RESP 的挂起事件。 只处理其中一个,另一个会一直把 CPU 叫回来(VIC 的中断是电平型,见第 11.3 节)。打开/关闭 ISP 时钟会影响两路相机。
hal_isp_clock_enable/disable()由 CPM 引用计数, 只要还有一路持有引用,时钟就不会真正关闭。
2. 资源模型
2.1 公共宏
| 宏 | 说明 | 取值/约束 |
|---|---|---|
HAL_VIC_MAX_IMAGE_WIDTH | VIC HAL 接受的最大图像宽度 | 2048 |
HAL_VIC_MAX_IMAGE_HEIGHT | VIC 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_MAX | DVP 总线选择字段上限 | 8 |
HAL_VIC_DVP_HORIZONTAL_BLANK_MAX | DVP 水平消隐字段上限 | 0xFFFF |
HAL_VIC_DVP_VERTICAL_BLANK_MAX | DVP 垂直消隐字段上限 | 0xFFFFFFFF |
HAL_VIC_DVP_LINE_CODE_MAX | SAV/EAV 行码字段上限 | 0xFFFFFF |
HAL_VIC_MIPI_START_DELAY_MAX | MIPI 启动延迟字段上限 | 0xF |
HAL_VIC_MIPI_VCROP_START_LINE_MAX | MIPI 垂直裁剪起始行上限 | 0xFFFF |
HAL_VIC_MIPI_TOTAL_WIDTH_MAX | MIPI 总行宽上限 | 0xFFFF |
HAL_VIC_MIPI_HCROP_START_PIXEL_MAX | MIPI 水平裁剪起始像素上限 | 0xFFFF |
HAL_VIC_MIPI_WIDTH_4BYTE_MAX | MIPI 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_WIDTH | TOP 最小帧宽 | 640 |
HAL_ISP_TOP_MIN_FRAME_HEIGHT | TOP 最小帧高 | 360 |
HAL_ISP_TOP_FRAME_ALIGNMENT | TOP 帧尺寸对齐 | 4 |
HAL_ISP_TOP_MAX_FRAME_WIDTH | TOP 最大帧宽 | 1920 |
HAL_ISP_TOP_MAX_FRAME_HEIGHT | TOP 最大帧高 | 1080 |
HAL_ISP_TOP_BAYER_TYPE_MAX | Bayer 类型字段上限 | 0x1F |
HAL_ISP_TOP_STATISTICS_POSITION_MAX | 统计位置字段上限 | 7 |
HAL_ISP_TOP_LINE_SPACE_MAX | 行间距字段上限 | 0xFFFF |
HAL_ISP_TOP_SHADOW_WRITE_SELECT_MAX | DMSC 影子写选择上限 | 1 |
HAL_ISP_IPC_OUTPUT_NUMBER_MAX | IPC 输出映射计数上限 | 0x1F |
HAL_ISP_IPC_TRIGGER_MODE_MAX | IPC 触发模式上限 | 1 |
HAL_ISP_IPC_CH0_TRIGGER_SELECT_MAX | 通道 0 触发源上限 | 7 |
HAL_ISP_IPC_OFFSET_MAX | IPC Y/UV 偏移上限 | 0x1FF |
HAL_ISP_RESP_POS_COUNT | RESP 断点位置组数 | 3 |
HAL_ISP_WDMA_ADDRESS_ALIGNMENT | WDMA 地址对齐 | 8 字节 |
HAL_ISP_WDMA_ADDRESS_MAX | WDMA 地址上限 | 0x1FFFFFF8 |
HAL_ISP_WDMA_STRIDE_ALIGNMENT | WDMA 步长对齐 | 8 字节 |
HAL_ISP_WDMA_STRIDE_MAX | WDMA 步长上限 | 0xFFF8 |
HAL_ISP_WDMA_ADDRESS_FIFO_DEPTH | WDMA 地址 FIFO 深度 | 4 |
HAL_ISP_DMSC_OUTPUT_OPTION_MAX | DMSC 输出选项上限 | 3 |
HAL_ISP_DMSC_INPUT_MODE_MAX | DMSC 输入模式上限 | 1 |
HAL_ISP_DMSC_UV_RESOLUTION_MODE_MAX | DMSC UV 分辨率模式上限 | 7 |
HAL_ISP_DMSC_RGB_OFFSET_MAX | DMSC RGB 偏移上限 | 0x1FF |
HAL_ISP_DMSC_OFFSET_MAX | DMSC Y/UV 偏移上限 | 0xFF |
HAL_ISP_DMSC_CLIP_MAX | DMSC 裁剪值上限 | 0xFF |
HAL_ISP_AE_MAX_ZONE_COUNT | AE 每方向最大分区数 | 15 |
HAL_ISP_AE_ZONE_SIZE_COUNT | AE 每方向尺寸表项数 | 15 |
HAL_ISP_AE_DMA_BASE_COUNT | AE DMA 基址表项数 | 4 |
HAL_ISP_AE_DMA_BUFFER_COUNT_MIN | AE DMA 缓冲数下限 | 1 |
HAL_ISP_AE_DMA_BASE_ALIGNMENT | AE DMA 基址对齐 | 8 字节 |
HAL_ISP_AE_ZONE_START_MAX | AE 分区起点上限 | 0xFFF |
HAL_ISP_AE_THRESHOLD_MAX | AE 阈值上限 | 0xFF |
HAL_ISP_AE_FREQUENCY_MAX | AE 频率上限 | 0xF |
HAL_ISP_AE_DMA_PRIORITY_MAX | AE DMA 优先级上限 | 3 |
HAL_ISP_AE_SPECIFIC_POSITION_MAX | AE 特定窗口坐标上限 | 0xFFF |
HAL_ISP_AE_SPECIFIC_FRAME_NUMBER_MAX | AE 特定帧号上限 | 0xFF |
HAL_ISP_CLOCK_DEFAULT_HZ | ISP 模块时钟默认频率 | 100000000 |
3. 配置对象与默认值
3.1 VIC 枚举
3.1.1 hal_vic_dvp_data_format_t
| 枚举 | 值 | 说明 |
|---|---|---|
HAL_VIC_DVP_DATA_FORMAT_RAW8 | 0 | DVP RAW8 |
HAL_VIC_DVP_DATA_FORMAT_RAW10 | 1 | DVP RAW10 |
HAL_VIC_DVP_DATA_FORMAT_RAW12 | 2 | DVP RAW12 |
HAL_VIC_DVP_DATA_FORMAT_YUV422_16BIT | 3 | DVP YUV422 16-bit |
HAL_VIC_DVP_DATA_FORMAT_YUV422_8BIT | 6 | DVP YUV422 8-bit |
3.1.2 hal_vic_yuv_order_t
| 枚举 | 值 | 说明 |
|---|---|---|
HAL_VIC_YUV_ORDER_Y1_V0_Y0_U0 | 0 | Y1 V0 Y0 U0 |
HAL_VIC_YUV_ORDER_Y1_U0_Y0_V0 | 1 | Y1 U0 Y0 V0 |
HAL_VIC_YUV_ORDER_V0_Y1_U0_Y0 | 2 | V0 Y1 U0 Y0 |
HAL_VIC_YUV_ORDER_U0_Y1_V0_Y0 | 3 | U0 Y1 V0 Y0 |
3.1.3 hal_vic_dvp_timing_mode_t
| 枚举 | 值 | 说明 |
|---|---|---|
HAL_VIC_DVP_TIMING_MODE_HREF | 0 | HREF 时序 |
HAL_VIC_DVP_TIMING_MODE_HSYNC | 1 | HSYNC 时序 |
HAL_VIC_DVP_TIMING_MODE_SONY | 2 | Sony 时序(带 SAV/EAV 行码) |
3.1.4 hal_vic_polarity_t
| 枚举 | 值 | 说明 |
|---|---|---|
HAL_VIC_POLARITY_ACTIVE_HIGH | 0 | 高有效 |
HAL_VIC_POLARITY_ACTIVE_LOW | 1 | 低有效 |
3.1.5 hal_vic_raw_align_t
| 枚举 | 值 | 说明 |
|---|---|---|
HAL_VIC_RAW_ALIGN_LOW | 0 | RAW 数据对齐到低位 |
HAL_VIC_RAW_ALIGN_HIGH | 1 | RAW 数据对齐到高位 |
3.1.6 hal_vic_dvp_sample_edge_t
| 枚举 | 值 | 说明 |
|---|---|---|
HAL_VIC_DVP_SAMPLE_FALLING_EDGE | 0 | PCLK 下降沿采样 |
HAL_VIC_DVP_SAMPLE_RISING_EDGE | 1 | PCLK 上升沿采样 |
3.1.7 hal_vic_bt656_bus_width_t
| 枚举 | 值 | 说明 |
|---|---|---|
HAL_VIC_BT656_BUS_WIDTH_8BIT | 0 | 8-bit 总线 |
HAL_VIC_BT656_BUS_WIDTH_16BIT | 1 | 16-bit 总线 |
3.1.8 hal_vic_bt656_sync_order_t
| 枚举 | 值 | 说明 |
|---|---|---|
HAL_VIC_BT656_SYNC_EAV_BEFORE_SAV | 0 | EAV 在 SAV 之前 |
HAL_VIC_BT656_SYNC_SAV_BEFORE_EAV | 1 | SAV 在 EAV 之前 |
3.1.9 hal_vic_field_t
| 枚举 | 值 | 说明 |
|---|---|---|
HAL_VIC_FIELD_ODD | 0 | 奇数场 |
HAL_VIC_FIELD_EVEN | 1 | 偶数场 |
3.1.10 hal_vic_mipi_pixel_format_t
| 枚举 | 值 | 说明 |
|---|---|---|
HAL_VIC_MIPI_PIXEL_FORMAT_RAW8 | 0 | MIPI RAW8 |
HAL_VIC_MIPI_PIXEL_FORMAT_RAW10 | 1 | MIPI RAW10 |
HAL_VIC_MIPI_PIXEL_FORMAT_RAW12 | 2 | MIPI RAW12 |
HAL_VIC_MIPI_PIXEL_FORMAT_YUV422 | 7 | MIPI YUV422 |
3.1.11 hal_vic_mipi_data_type_t
| 枚举 | 值 | 说明 |
|---|---|---|
HAL_VIC_MIPI_DATA_TYPE_YUV422_8BIT | 0x1E | CSI-2 YUV422 8-bit |
HAL_VIC_MIPI_DATA_TYPE_RAW8 | 0x2A | CSI-2 RAW8 |
HAL_VIC_MIPI_DATA_TYPE_RAW10 | 0x2B | CSI-2 RAW10 |
HAL_VIC_MIPI_DATA_TYPE_RAW12 | 0x2C | CSI-2 RAW12 |
3.1.12 hal_vic_mipi_sync_mode_t
| 枚举 | 值 | 说明 |
|---|---|---|
HAL_VIC_MIPI_SYNC_MODE_HEADER | 0 | 包头部同步 |
HAL_VIC_MIPI_SYNC_MODE_PACKET | 1 | 包同步 |
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_LINEAR | 0 | 线性帧 |
HAL_VIC_MIPI_SENSOR_FRAME_MODE_1 | 1 | 字段值 1 |
HAL_VIC_MIPI_SENSOR_FRAME_MODE_2 | 2 | 字段值 2 |
HAL_VIC_MIPI_SENSOR_FRAME_MODE_3 | 3 | 字段值 3 |
3.1.15 hal_vic_output_route_t
| 枚举 | 值 | 说明 |
|---|---|---|
HAL_VIC_OUTPUT_ROUTE_TIZIANO | 0 | 路由到 Tiziano ISP 通路 |
HAL_VIC_OUTPUT_ROUTE_NONE | 4 | 关闭输出路由 |
3.1.16 hal_vic_irq_t
| 枚举 | 位 | 说明 |
|---|---|---|
HAL_VIC_IRQ_FRAME_DONE | 0 | 帧完成 |
HAL_VIC_IRQ_FRAME_START | 4 | 帧开始 |
HAL_VIC_IRQ_FRAME_RESET | 8 | 帧复位 |
HAL_VIC_IRQ_ASFIFO_OVERFLOW | 9 | ASFIFO 溢出 |
HAL_VIC_IRQ_HORIZONTAL_ERROR | 10 | 水平尺寸错误 |
HAL_VIC_IRQ_VERTICAL_ERROR | 14 | 垂直尺寸错误 |
HAL_VIC_IRQ_HVF_ERROR | 18 | 水平/垂直场错误 |
HAL_VIC_IRQ_DVP_HCOMP_ERROR | 19 | DVP 水平比较错误 |
HAL_VIC_IRQ_IMAGE_FIFO_OVERFLOW | 22 | 图像 FIFO 溢出 |
HAL_VIC_IRQ_MIPI_HCOMP_ERROR | 24 | MIPI 水平比较错误 |
HAL_VIC_IRQ_MIPI_VCOMP_ERROR | 28 | MIPI 垂直比较错误 |
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
| 字段 | 类型 | 说明 |
|---|---|---|
route | hal_vic_output_route_t | VIC 输出路由 |
vertical_delay | uint32_t | 有效数据前延迟,单位时钟周期 |
horizontal_delay | uint32_t | 行尾延迟,单位时钟周期 |
frame_end_delay | uint32_t | 帧尾延迟,单位时钟周期 |
interrupt_mask | uint32_t | 写入 VIC_INT_MASK 的掩码,1 = 屏蔽 |
timeout_ms | uint32_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
| 字段 | 类型 | 说明 |
|---|---|---|
ispx | isp_regs_t * | ISP0 / ISP1 |
width | uint32_t | 输出宽度 |
height | uint32_t | 输出高度 |
data_format | hal_vic_dvp_data_format_t | DVP 输入格式 |
yuv_order | hal_vic_yuv_order_t | YUV 字节序 |
timing_mode | hal_vic_dvp_timing_mode_t | 时序模式 |
hsync_polarity | hal_vic_polarity_t | HSYNC 极性 |
vsync_polarity | hal_vic_polarity_t | VSYNC 极性 |
sample_edge | hal_vic_dvp_sample_edge_t | 采样边沿 |
raw_align | hal_vic_raw_align_t | RAW 对齐方式 |
bus_select | uint32_t | YUV422 8-bit 总线选择,0~8 |
horizontal_front_blank | uint32_t | 水平前消隐,HSYNC/Sony 模式有效 |
horizontal_back_blank | uint32_t | 水平后消隐,HSYNC/Sony 模式有效 |
vertical_blank | uint32_t | 垂直消隐,HSYNC/Sony 模式有效 |
line_sav_code | uint32_t | Sony 模式行 SAV 码,24 位 |
line_eav_code | uint32_t | Sony 模式行 EAV 码,24 位 |
enable_image_check | bool | 打开 DVP 图像尺寸检查 |
enable_hcomp | bool | 打开 DVP 水平比较 |
common | hal_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
| 字段 | 类型 | 说明 |
|---|---|---|
ispx | isp_regs_t * | ISP0 / ISP1 |
output_width | uint32_t | 裁剪后输出宽度 |
output_height | uint32_t | 裁剪后输出高度 |
total_width | uint32_t | 裁剪前总行宽,0 表示等于 output_width |
hcrop_start_pixel | uint32_t | 水平裁剪起始像素 |
vcrop_start_line | uint32_t | 垂直裁剪起始行 |
pixel_format | hal_vic_mipi_pixel_format_t | MIPI 像素格式 |
data_type | hal_vic_mipi_data_type_t | CSI-2 数据类型 |
sync_mode | hal_vic_mipi_sync_mode_t | 同步模式 |
start_delay | uint32_t | 启动延迟,0~0xF |
start_channel | hal_vic_mipi_start_channel_t | 启动通道 |
sensor_frame_mode | hal_vic_mipi_sensor_frame_mode_t | 传感器帧模式 |
enable_data_type_check | bool | 打开数据类型检查 |
enable_horizontal_compare | bool | 打开水平比较 |
enable_vertical_compare | bool | 打开垂直比较 |
common | hal_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
| 字段 | 类型 | 说明 |
|---|---|---|
ispx | isp_regs_t * | ISP0 / ISP1 |
width | uint32_t | 输出宽度 |
height | uint32_t | 输出高度 |
bus_width | hal_vic_bt656_bus_width_t | 总线宽度 |
sync_order | hal_vic_bt656_sync_order_t | SAV/EAV 顺序 |
yuv_order | hal_vic_yuv_order_t | YUV 字节序 |
start_field | hal_vic_field_t | 起始场 |
enable_hcomp | bool | 打开水平比较 |
common | hal_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
| 字段 | 类型 | 说明 |
|---|---|---|
y | uint8_t | Y 分量 |
cb | uint8_t | Cb 分量 |
cr | uint8_t | Cr 分量 |
3.2.6 hal_vic_colorbar_config_t
| 字段 | 类型 | 说明 |
|---|---|---|
ispx | isp_regs_t * | ISP0 / ISP1 |
frame_infinite | bool | 无限帧 |
frame_count | uint32_t | 有限帧数 |
horizontal_blank | uint32_t | 行间隔 |
vertical_blank | uint32_t | 帧间隔 |
colors[8] | hal_vic_colorbar_color_t | 第一组颜色 |
colors2[8] | hal_vic_colorbar_color_t | 第二组颜色 |
program_colors | bool | 是否写两组颜色表 |
replace_data_only | bool | 仅替换数据(保留同步) |
默认值(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_RAW8 | 0 | RAW8 输入 |
HAL_ISP_TOP_DATA_TYPE_RAW10 | 1 | RAW10 输入 |
HAL_ISP_TOP_DATA_TYPE_RAW12 | 2 | RAW12 输入 |
HAL_ISP_TOP_DATA_TYPE_YUV | 3 | YUV 输入 |
3.3.2 hal_isp_top_shadow_select_t
| 枚举 | 值 | 说明 |
|---|---|---|
HAL_ISP_TOP_SHADOW_SELECT_ACTIVE | 0 | 写活动寄存器组 |
HAL_ISP_TOP_SHADOW_SELECT_SHADOW | 1 | 写影子寄存器组 |
3.3.3 hal_isp_top_config_t
| 字段 | 类型 | 说明 |
|---|---|---|
ispx | isp_regs_t * | ISP0 / ISP1 |
width | uint32_t | 帧宽,640~1920,4 对齐 |
height | uint32_t | 帧高,360~1080,4 对齐 |
data_type | hal_isp_top_data_type_t | 输入数据类型 |
bayer_type | uint32_t | Bayer 类型,0~0x1F |
bypass_dmsc | bool | 旁路 DMSC |
enable_raw_test_pattern | bool | 打开 RAW 测试图 |
enable_rgb_test_pattern | bool | 打开 RGB 测试图 |
enable_yuv_test_pattern | bool | 打开 YUV 测试图 |
statistics_position | uint32_t | 统计位置,0~7 |
ipc_line_space | uint32_t | IPC 行间距 |
normal_line_space | uint32_t | 普通行间距 |
shadow_select | hal_isp_top_shadow_select_t | 影子寄存器选择 |
shadow_write_select | uint32_t | DMSC 影子写选择,0~1 |
enable_overflow_stop | bool | 溢出时停止流水线 |
trigger_shadow | bool | 配置后触发影子更新 |
默认值(HAL_ISP_TOP_DEFAULT_CONFIG_INIT):ISP0、640×480、YUV、Bayer 1、
旁路 DMSC、测试图全关、统计位置 0、行间距 0、活动寄存器组、写选择 0、
溢出停止关、影子触发关。
3.3.4 hal_isp_ipc_config_t
| 字段 | 类型 | 说明 |
|---|---|---|
ispx | isp_regs_t * | ISP0 / ISP1 |
output_number | uint32_t | 输出映射计数上限,0~0x1F;0 表示只用映射项 0(单路输出) |
output_map | uint32_t | 输出映射原始值,单路常用 0 |
overflow_restart | bool | 溢出后是否进入停流序列(不是自愈,见 8.5) |
size_error_restart | bool | 尺寸错误后是否进入停流序列 |
trigger_mode | uint32_t | 触发模式,0 正常 / 1 一帧后停止 |
channel0_trigger_select | uint32_t | 通道 0 触发源,0 表示不启动 |
y_offset | uint32_t | Y 输出偏移,0~0x1FF |
uv_offset | uint32_t | UV 输出偏移,0~0x1FF |
trigger_after_config | bool | 配置完成后立即触发 |
默认值(HAL_ISP_IPC_DEFAULT_CONFIG_INIT):输出数 0、映射 0、两种重启关、
触发模式 0、通道 0 触发源 4、偏移 0、配置后触发。
3.3.5 hal_isp_resp_event_masks_t
| 字段 | 类型 | 说明 |
|---|---|---|
common0 | uint32_t | COMMON_0 事件掩码 |
unusual0 | uint32_t | UNUSUAL_0 事件掩码 |
backup0 | uint32_t | BACKUP_0 事件掩码 |
3.3.6 hal_isp_resp_config_t
| 字段 | 类型 | 说明 |
|---|---|---|
ispx | isp_regs_t * | ISP0 / ISP1 |
enable_events | hal_isp_resp_event_masks_t | 事件源使能 |
cpu_events | hal_isp_resp_event_masks_t | 上报 CPU 的事件 |
clear_all_before_enable | bool | 使能前清空所有挂起事件 |
默认值(HAL_ISP_RESP_DEFAULT_CONFIG_INIT):只使能 COMMON_0 的GPL_WDMA_DONE,CPU 掩码相同,使能前清空。
3.3.7 hal_isp_resp_position_t
| 字段 | 类型 | 说明 |
|---|---|---|
hcount | uint32_t | 水平计数 |
vcount | uint32_t | 垂直计数 |
3.3.8 hal_isp_resp_common0_pending_t
| 字段 | 类型 | 说明 |
|---|---|---|
events | uint32_t | 原始挂起事件 |
has_pending | bool | 是否有挂起事件 |
ae_static_done | bool | AE 统计完成 |
ae_hist_done | bool | AE 直方图完成 |
stop | bool | 停止事件 |
gpl_wdma_done | bool | WDMA 完成 |
ipc_frame_start | bool | IPC 帧开始 |
ipc_frame_done | bool | IPC 帧完成 |
ipc_ch0_start | bool | IPC 通道 0 开始 |
ipc_ch0_end | bool | IPC 通道 0 结束 |
3.3.9 hal_isp_resp_unusual0_pending_t
| 字段 | 类型 | 说明 |
|---|---|---|
events | uint32_t | 原始挂起事件 |
has_pending | bool | 是否有挂起事件 |
ipc_size_error | bool | IPC 尺寸错误 |
ipc_overflow | bool | IPC 溢出 |
ae_error | bool | AE 错误 |
ae_hist_error | bool | AE 直方图错误 |
3.3.10 hal_isp_resp_backup0_pending_t
| 字段 | 类型 | 说明 |
|---|---|---|
events | uint32_t | 原始挂起事件 |
has_pending | bool | 是否有挂起事件 |
dmsc_frame_done | bool | DMSC 帧完成 |
ae_frame_done | bool | AE 帧完成 |
3.3.11 hal_isp_resp_pending_t
| 字段 | 类型 | 说明 |
|---|---|---|
common0 | hal_isp_resp_common0_pending_t | COMMON_0 解码结果 |
unusual0 | hal_isp_resp_unusual0_pending_t | UNUSUAL_0 解码结果 |
backup0 | hal_isp_resp_backup0_pending_t | BACKUP_0 解码结果 |
has_pending | bool | 三组中任意一组有事件 |
3.3.12 hal_isp_wdma_dump_data_type_t
| 枚举 | 值 | 说明 |
|---|---|---|
HAL_ISP_WDMA_DUMP_DATA_TYPE_RAW8_OR_Y | 0 | RAW8 或 Y |
HAL_ISP_WDMA_DUMP_DATA_TYPE_RAW10_12_16_OR_UV | 1 | RAW10/12/16 或 UV |
HAL_ISP_WDMA_DUMP_DATA_TYPE_RAW32_OR_RGB888 | 2 | RAW32 或 RGB888 |
HAL_ISP_WDMA_DUMP_DATA_TYPE_YUV420_DUAL | 4 | YUV420 双平面 |
HAL_ISP_WDMA_DUMP_DATA_TYPE_DOL_RAW16_DUAL | 5 | DOL RAW16 双平面 |
HAL_ISP_WDMA_DUMP_DATA_TYPE_YUV422_DUAL | 6 | YUV422 双平面 |
3.3.13 hal_isp_wdma_mux_sel_t
| 枚举 | 值 | 说明 |
|---|---|---|
HAL_ISP_WDMA_MUX_SEL_RAW_PATH | 1 | RAW 通路 |
HAL_ISP_WDMA_MUX_SEL_YUV422_PATH | 2 | YUV422 通路 |
HAL_ISP_WDMA_MUX_SEL_DMSC_YUV_PATH | 3 | DMSC YUV 通路 |
3.3.14 hal_isp_wdma_static_config_t
| 字段 | 类型 | 说明 |
|---|---|---|
mux_sel | hal_isp_wdma_mux_sel_t | 数据源 |
dump_data_type | hal_isp_wdma_dump_data_type_t | 数据排布 |
dump_data_order | uint32_t | 字节序,0~7 |
stride | uint32_t | Y/单平面步长,8 对齐,最大 0xFFF8 |
chroma_stride | uint32_t | UV 步长,8 对齐,最大 0xFFF8 |
y_priority_level | uint32_t | Y DMA 优先级等级,0~3 |
y_priority_limit | uint32_t | Y DMA 优先级限制,0~0x1FF |
chroma_priority_level | uint32_t | UV DMA 优先级等级,0~3 |
chroma_priority_limit | uint32_t | UV DMA 优先级限制,0~0x1FF |
默认值(HAL_ISP_WDMA_DEFAULT_STATIC_CONFIG_INIT):DMSC YUV 通路、YUV420 双平面、
字节序 0、步长 0、优先级 0。
3.3.15 hal_isp_wdma_config_t
| 字段 | 类型 | 说明 |
|---|---|---|
ispx | isp_regs_t * | ISP0 / ISP1 |
static_config | hal_isp_wdma_static_config_t | 静态配置 |
3.3.16 hal_isp_wdma_frame_config_t
| 字段 | 类型 | 说明 |
|---|---|---|
ispx | isp_regs_t * | ISP0 / ISP1 |
start_address | uint32_t | Y/单平面物理地址,8 对齐 |
chroma_start_address | uint32_t | UV 物理地址,8 对齐 |
enable_chroma | bool | 是否先写 C_START_ADDR |
3.3.17 hal_isp_wdma_done_info_t
| 字段 | 类型 | 说明 |
|---|---|---|
done_address | uint32_t | Y/单平面完成地址 |
chroma_done_address | uint32_t | UV 完成地址 |
dump_enabled | bool | DUMP_EN 状态 |
3.3.18 hal_isp_wdma_address_fifo_state_t
| 字段 | 类型 | 说明 |
|---|---|---|
raw | uint32_t | 原始调试寄存器值 |
data_count | uint32_t | 已用项数,0~4 |
free_count | uint32_t | 空闲项数,0~4 |
full | bool | 满标志 |
empty | bool | 空标志 |
valid | bool | 计数与标志自洽 |
3.3.19 hal_isp_wdma_address_fifo_t
| 字段 | 类型 | 说明 |
|---|---|---|
y_start | hal_isp_wdma_address_fifo_state_t | Y 地址 FIFO |
chroma_start | hal_isp_wdma_address_fifo_state_t | UV 地址 FIFO |
3.3.20 hal_isp_dmsc_config_t
| 字段 | 类型 | 说明 |
|---|---|---|
ispx | isp_regs_t * | ISP0 / ISP1 |
output_option | uint32_t | 输出选项,0~3 |
input_mode | uint32_t | 输入模式,0~1 |
uv_resolution_mode | uint32_t | UV 分辨率模式,0~7 |
r_offset / g_offset / b_offset | uint32_t | RGB 偏移,0~0x1FF |
matrix_00~matrix_22 | uint32_t | 3×3 颜色矩阵系数 |
y_offset / uv_offset | uint32_t | 输出偏移,0~0xFF |
y_clip_min / y_clip_max | uint32_t | Y 裁剪范围,0~0xFF |
uv_clip_min / uv_clip_max | uint32_t | UV 裁剪范围,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_count | uint32_t | 输出 FIFO 已用项数,0~3 |
fifo_free_count | uint32_t | 输出 FIFO 空闲项数,0~3 |
3.3.22 hal_isp_dmsc_debug1_t
| 字段 | 类型 | 说明 |
|---|---|---|
transfer_state | uint32_t | 输出状态机,0~0x3F |
fifo_underflow | bool | FIFO 下溢 |
fifo_overflow | bool | FIFO 上溢 |
fifo_empty | bool | FIFO 空 |
fifo_full | bool | FIFO 满 |
input_backpressure | bool | 输入反压 |
3.3.23 hal_isp_ae_config_t
| 字段 | 类型 | 说明 |
|---|---|---|
ispx | isp_regs_t * | ISP0 / ISP1 |
zone_h_start / zone_v_start | uint32_t | 分区网格起点,0~0xFFF |
zone_h_number / zone_v_number | uint32_t | 每方向分区数,1~15 |
horizontal_zone_size[15] | uint8_t | 水平分区尺寸 |
vertical_zone_size[15] | uint8_t | 垂直分区尺寸 |
dark_threshold | uint32_t | 暗点阈值,0~0xFF |
saturation_threshold | uint32_t | 饱和阈值,0~0xFF |
histogram_frequency | uint32_t | 直方图频率,0~0xF |
statistics_frequency | uint32_t | 统计频率,0~0xF |
enable_histogram_read_mode | bool | 直方图读模式 |
enable_histogram_trigger_mode | bool | 直方图触发模式 |
statistics_dma_base[4] | uint32_t | 统计 DMA 基址,8 对齐或 0 |
histogram_dma_base[4] | uint32_t | 直方图 DMA 基址,8 对齐或 0 |
statistics_buffer_count | uint32_t | 统计缓冲数,1~4 |
histogram_buffer_count | uint32_t | 直方图缓冲数,1~4 |
enable_statistics_dma_monitor | bool | 统计 DMA 监视 |
enable_histogram_dma_monitor | bool | 直方图 DMA 监视 |
enable_interrupt_improve_drop | bool | 中断期间丢帧 |
statistics_dma_priority | uint32_t | 统计 DMA 优先级,0~3 |
histogram_dma_priority | uint32_t | 直方图 DMA 优先级,0~3 |
enable_drop_frame_backpressure | bool | 丢帧反压模式 |
specific_horizontal_start/end | uint32_t | 特定窗口水平范围,0~0xFFF |
specific_vertical_start/end | uint32_t | 特定窗口垂直范围,0~0xFFF |
specific_frame_number_in | uint32_t | 特定窗口输入帧号,0~0xFF |
enable_ram_busy_backpressure | bool | RAM 忙反压 |
enable_shadow | bool | 配置末尾触发一次 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_base | uint32_t | 当前直方图缓冲索引 |
ae_current_base | uint32_t | 当前统计缓冲索引 |
ae_frame_number | uint32_t | AE 内部帧计数 |
ae_dma_stop_ack | uint32_t | DMA 停止应答,1/0 |
ae_dma_mismatch | uint32_t | 统计 DMA 尺寸错误,1/0 |
hist_dma_mismatch | uint32_t | 直方图 DMA 尺寸错误,1/0 |
3.3.25 hal_isp_ae_specific_statistics_t
| 字段 | 类型 | 说明 |
|---|---|---|
frame_number_out | uint32_t | 输出帧号,8 位 |
sum_dark | uint32_t | 暗像素和,28 位 |
sum_mid | uint32_t | 中间像素和,28 位 |
sum_sat | uint32_t | 饱和像素和,28 位 |
count_dark | uint32_t | 暗像素计数,20 位 |
count_sat | uint32_t | 饱和像素计数,20 位 |
3.4 默认值与必须覆盖的字段
*_struct_init() 返回的是“能编译、能下载、但通常不能直接出图”的默认值。下表列出
真实采集路径上必须覆盖的字段:
| 结构体 | 默认值 | 必须覆盖 | 原因 |
|---|---|---|---|
hal_vic_dvp_config_t | ISP0、640×480、YUV422_8BIT | ispx、width/height、data_format、raw_align、common.interrupt_mask | 实例与板级接线相关;RAW sensor 必须改成 RAW 格式;HAL 默认掩码屏蔽帧开始/复位,通常需要重算 |
hal_vic_mipi_config_t | RAW10、通道 0、线性 | ispx、output_width/height、total_width、pixel_format、data_type、start_channel | 行宽与 DT 必须与 sensor 实际输出一致 |
hal_isp_top_config_t | YUV、旁路 DMSC、640×480 | ispx、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_t | mux_sel=3、YUV420 双平面、步长 0 | mux_sel、dump_data_type、stride、chroma_stride | 步长 0 不会写出正确图像;源必须与 TOP 旁路一致 |
hal_isp_dmsc_config_t | 全 0 矩阵 | 走 DMSC 时必须填完整矩阵与偏移 | 全 0 矩阵会把 Y 打成常数 0 |
hal_isp_ae_config_t | 15×15、H20/V16、4 个空 DMA 基址 | ispx、statistics_dma_base[]、statistics_buffer_count(及直方图对应项) | 基址为 0 时 AE 统计数据不会写入 DDR |
4. HAL 接口规范
本节按子模块列出全部 HAL 接口。每个接口的写法统一为:
函数原型;
功能说明;
参数表(类型 / 方向 / 说明);
返回值表;
补充说明(编程顺序、默认值、边界条件、踩坑点)。
约定:
所有
*_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)。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
config | hal_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)。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
config | hal_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、线性帧)。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
config | hal_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)。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
config | hal_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 色两组、替换同步与数据)。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
config | hal_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。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | isp_regs_t * | 输入 | ISP0 / ISP1 |
timeout_ms | uint32_t | 输入 | 超时毫秒数,0 使用 HAL_VIC_DEFAULT_TIMEOUT_MS |
| 返回值 | 说明 |
|---|---|
IM_OK | 复位完成 |
IM_ERR_INVALID_PARAM | ispx 不是 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 配置。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | isp_regs_t * | 输入 | ISP0 / ISP1 |
| 返回值 | 说明 |
|---|---|
IM_OK | 已置位 |
IM_ERR_INVALID_PARAM | ispx 非法 |
补充说明:
本函数不轮询完成状态,写后立即返回。
各
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 对齐与采样沿、可选总线和消隐、检查使能、公共配置,最后提交寄存器更新。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
config | const 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 格式与裁剪、数据类型与检查、同步/延迟/通道/帧模式, 最后写公共配置并提交。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
config | const 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 字节序、逐行扫描、起始场、可选水平比较,最后写公共配置并提交。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
config | const 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选择只替换数据或替换同步与数据,并提交。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
config | const 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);
功能说明:同时关闭彩条使能和仅替换数据使能,并提交寄存器更新。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | isp_regs_t * | 输入 | ISP0 / ISP1 |
| 返回值 | 说明 |
|---|---|
IM_OK | 已关闭 |
IM_ERR_INVALID_PARAM | ispx 非法 |
4.1.13 hal_vic_start
error_code_t hal_vic_start(isp_regs_t *ispx);
功能说明:置位 CTRL.START,启动 VIC 采集。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | isp_regs_t * | 输入 | ISP0 / ISP1 |
| 返回值 | 说明 |
|---|---|
IM_OK | 已启动 |
IM_ERR_INVALID_PARAM | ispx 非法 |
补充说明:调用前 VIC、TOP、IPC、WDMA 的配置必须已经提交。
4.1.14 hal_vic_stop
error_code_t hal_vic_stop(isp_regs_t *ispx);
功能说明:清除 CTRL.START,停止 VIC 采集。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | isp_regs_t * | 输入 | ISP0 / ISP1 |
| 返回值 | 说明 |
|---|---|
IM_OK | 已停止 |
IM_ERR_INVALID_PARAM | ispx 非法 |
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 门控。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
index | uint32_t | 输入 | 0 = CIM0,1 = CIM1 |
clk_rate_hz | uint32_t | 输入 | 目标 MCLK 频率,0 非法 |
| 返回值 | 说明 |
|---|---|
IM_OK | 使能成功 |
IM_ERR_INVALID_PARAM | index ≥ 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 门控。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
index | uint32_t | 输入 | 0 = CIM0,1 = CIM1 |
| 返回值 | 说明 |
|---|---|
IM_OK | 已关闭(共享门控可能仍开) |
IM_ERR_INVALID_PARAM | index ≥ 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 原始状态。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | const isp_regs_t * | 输入 | ISP0 / ISP1 |
status_out | uint32_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 清除指定位。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | isp_regs_t * | 输入 | ISP0 / ISP1 |
mask | uint32_t | 输入 | HAL_VIC_IRQ_* 位组合 |
| 返回值 | 说明 |
|---|---|
IM_OK | 已写入 |
IM_ERR_INVALID_PARAM | ispx 非法 |
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 位状态值。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | const isp_regs_t * | 输入 | ISP0 / ISP1 |
state_out | uint32_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 前端主要寄存器。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | const 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_hz | uint32_t | 输入 | 目标频率,0 非法 |
| 返回值 | 说明 |
|---|---|
IM_OK | 设置成功 |
IM_ERR_INVALID_PARAM | rate_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_out | uint32_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)。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
config | hal_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 功能复位。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | isp_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 旁路、测试图和溢出停止,并按需触发影子更新。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
config | const 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_ENbit0。在已验证的硬件上该位看不出可观测 效果:把它置 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 分区统计。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | isp_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。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | isp_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,使能直方图统计。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | isp_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。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | isp_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 停止。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | isp_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,触发一次影子寄存器更新。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | isp_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。实现连续读两次并返回第二次的值。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | const isp_regs_t * | 输入 | ISP0 / ISP1 |
state_out | uint32_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 主要寄存器。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | const 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、配置后触发)。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
config | hal_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 为真时最后触发一次。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
config | const 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 开始一帧输出。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | isp_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 软件版本号与硬件版本号。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | const isp_regs_t * | 输入 | ISP0 / ISP1 |
soft_version_out | uint32_t * | 输出 | 软件版本 |
hard_version_out | uint32_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 主要寄存器。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | const 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,使能前清空)。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
config | hal_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 上报掩码。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
config | const 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,清空所有挂起事件。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | isp_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 掩码裁剪。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | const isp_regs_t * | 输入 | ISP0 / ISP1 |
events_out | uint32_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 挂起事件并裁剪。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | const isp_regs_t * | 输入 | ISP0 / ISP1 |
events_out | uint32_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 挂起事件并裁剪。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | const isp_regs_t * | 输入 | ISP0 / ISP1 |
events_out | uint32_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 指定事件。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | isp_regs_t * | 输入 | ISP0 / ISP1 |
events | uint32_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 指定事件。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | isp_regs_t * | 输入 | ISP0 / ISP1 |
events | uint32_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 指定事件。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | isp_regs_t * | 输入 | ISP0 / ISP1 |
events | uint32_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);
功能说明:读取指定断点位置的像素坐标。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | const isp_regs_t * | 输入 | ISP0 / ISP1 |
index | uint8_t | 输入 | 位置索引,0~2 |
position_out | hal_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);
功能说明:一次读取三组挂起事件并按位解码为具名布尔字段。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | const isp_regs_t * | 输入 | ISP0 / ISP1 |
pending_out | hal_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 字段清除对应事件。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | isp_regs_t * | 输入 | ISP0 / ISP1 |
pending | const 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 主要寄存器。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | const 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)。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
config | hal_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_config | hal_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 优先级。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
config | const 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_config | const hal_isp_wdma_frame_config_t * | 输入 | 单帧地址配置 |
static_config | const 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 的调试值并解码。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | const isp_regs_t * | 输入 | ISP0 / ISP1 |
fifo_out | hal_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 软件复位。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | isp_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。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | isp_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、再清除复位。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | isp_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 是否已开始工作。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | const isp_regs_t * | 输入 | ISP0 / ISP1 |
busy_out | bool * | 输出 | 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 状态。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | const isp_regs_t * | 输入 | ISP0 / ISP1 |
done_out | hal_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 主要寄存器。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | const 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_out | hal_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 偏移与裁剪范围。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
config | const 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 已用/空闲项数。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | const isp_regs_t * | 输入 | ISP0 / ISP1 |
debug_out | hal_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 标志和输入反压。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | const isp_regs_t * | 输入 | ISP0 / ISP1 |
debug_out | hal_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 主要寄存器。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | const 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_out | hal_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 基址与 缓冲数、监视与优先级、特定窗口、反压和影子更新。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
config | const 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_CTRLbit0:这是一次一次性触发, 硬件在下一个帧边界完成影子更新后自动清零。也就是说,每次改完 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 帧计数、停止应答与两路尺寸错误标志。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | const isp_regs_t * | 输入 | ISP0 / ISP1 |
info_out | hal_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);
功能说明:读取特定窗口的帧号、暗/中/饱和像素和与暗/饱和像素计数。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | const isp_regs_t * | 输入 | ISP0 / ISP1 |
statistics_out | hal_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 主要寄存器。
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ispx | const isp_regs_t * | 输入 | ISP0 / ISP1 |
| 返回值 | 说明 |
|---|---|
IM_OK | 打印完成 |
IM_ERR_UNSUPPORTED | 调试辅助未编译 |
5. 典型用法:从零开始
本章按“从一块刚上电的板子到第一帧数据落进 DDR”的顺序,把 HAL 调用串起来。每一步都 给出目标、代码和容易踩的坑。如果你只是想改中间件的行为,可以只读 8.1 和 8.12。
5.1 开始之前:先想清楚五件事
| 问题 | 影响 | 对应配置 |
|---|---|---|
| 用哪个实例? | 决定 ispx、IRQ 号、有没有 AE/DMSC | ISP0 / 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 就旁路 DMSC | bypass_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);
}三个必须记住的结论
不能只写 DMA 基址。分区尺寸寄存器复位值是 64×36,15×15 格要覆盖 960×540, 比 640×480 整帧还大,扫描完不成,统计一次都不产生(表现为帧号在涨、统计头 全是 0)。
hal_isp_ae_struct_init()的默认值(20×16)对应帧宽/2/15、帧高/2/15,与中间件使用的配置一致。SHD_CTRL是一次性触发。写完立刻读是 1,过了一个帧边界读回 0。所以 “读到 0”不能当“配置没生效”;每次改 AE 寄存器都要重新写一次(HAL 的enable_shadow就是干这个的)。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()应用只需要:
在 defconfig 里打开
CONFIG_DRIVER_VIC;在源文件里包含对应 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);
排查顺序:
先读
INT_MASK,确认要的位是 0(放行)。写HAL_VIC_IRQ_ALL是全部屏蔽, 这是最常见的错误。确认
INT_STA里目标位真的置起来了;没有置说明链路事件没发生(或窗口没开)。位置了但 CPU 没进 ISR:检查 PLIC 使能、优先级、
irq_enable()。CPU 反复进 ISR:
INT_STA清不掉,或 RESP 那边还有事件没清。VIC 与 RESP 共用 一条 IRQ,两边都要处理。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_enabled | DUMP_EN 状态 |
fifo.y_start.full | 地址 FIFO 满——不会再接受新地址 |
fifo.y_start.empty | FIFO 空——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默认打开,避免把上一次运行留下的事件当成本次事件。