API GUIDE / IPU / HAL

G32S10 IPU HAL 接口

HAL 层接口:背景(大图)输入描述:

1. 资源模型与公开类型

1.1 IPU 硬件能力摘要

能力说明
输入(背景)格式ARGB8888、NV12、YUV422(HAL_IPU_FORMAT_*)。
输出格式ARGB8888、RGB888、NV12、NV21、HSV。
输出路由PSRAM(HAL_IPU_OUTPUT_PSRAM)或 DPU 直通(HAL_IPU_OUTPUT_DPU,IPU_TRIGGER.DPU_EN 0x074)。
帧模式单帧(HAL_IPU_REFRESH_SINGLE)和连续帧(HAL_IPU_REFRESH_CONTINUOUS,乒乓)。
处理能力CSC(YUV↔RGB)、OSD 叠图(background + channel0)、2-bit OSD。
图像尺寸HAL_IPU_DIMENSION_MIN=4,HAL_IPU_DIMENSION_MAX=1280。
对齐地址/stride 需满足 IPU_ALIGNMENT_BYTES(8 字节)。

1.2 公开枚举与常量

宏/枚举说明
HAL_IPU_IRQ_OUT_END / HAL_IPU_STATUS_SIZE_ERR语义化事件位(由 IPU_STATUS 0x004 捕获;非寄存器掩码)。
HAL_IPU_OUTPUT_PSRAM / HAL_IPU_OUTPUT_DPU输出路由编码(IPU_TRIGGER.DPU_EN 0x074)。
HAL_IPU_REFRESH_SINGLE / HAL_IPU_REFRESH_CONTINUOUS帧刷新模式编码(IPU_TRIGGER.REFRESH_MODE 0x074)。
HAL_IPU_FORMAT_*像素格式词汇(IPU_D_FMT 0x008),HAL 全部图像路径共用。
HAL_IPU_ORDER_*12 种 ARGB/RGB 字节序(IPU_D_FMT.OUT_ARGB_ORDER 0x008)。
HAL_IPU_CSC_NONE / YUV_TO_RGB / RGB_TO_YUVOSD 通道 CSC 方向(IPU_OSD_CH0_PARA.CSC_CTL 0x11C)。
HAL_IPU_ALPHA_SELECT_PIXEL / GLOBAL / PIXEL_X_GLOBALalpha 选择(IPU_OSD_CH0_PARA.ALPHA_SEL 0x11C)。
HAL_IPU_ARB_MODE_FIXED_PRIORITY / ROUND_ROBIN读仲裁模式(IPU_RD_ARB_CTL.ARB_MODE 0x1A8)。
HAL_IPU_ARB_PRIORITY_HIGH / LOW读仲裁通道优先级(IPU_RD_ARB_CTL.CH0/CH1_PRIO 0x1A8)。
HAL_IPU_BUFFER_BK0 / BK1 / CH0_0 / CH0_1乒乓 buffer ready 位(IPU_BUFF_STATE 0x1D0)。
HAL_IPU_BUFFER_ALL全部乒乓 buffer ready 位组合。
HAL_IPU_DIMENSION_MIN / HAL_IPU_DIMENSION_MAX图像尺寸范围 4~1280。
IPU_IRQ_IDPLIC 中断号。
CONFIG_IPU_ENABLE_DEBUG_HELPERShal_ipu_dump_regs() 编译开关。

1.3 公开结构体

1.3.1 hal_ipu_input_t

背景(大图)输入描述:

字段类型说明
formathal_ipu_format_t输入格式。
argb_orderhal_ipu_argb_order_tpacked 格式字节序。
y_addruint32_tY 或 packed 像素地址,8 字节对齐。
uv_addruint32_tUV 地址(NV 格式),8 字节对齐。
width / heightuint16_t输入宽高,4~1280。
y_strideuint32_tY 或 packed 跨距,8 字节对齐。
uv_strideuint32_tUV 跨距(NV 格式),8 字节对齐。

1.3.2 hal_ipu_output_t

输出图像描述(格式与目的 buffer):

字段类型说明
formathal_ipu_format_t输出格式。
argb_orderhal_ipu_argb_order_tpacked 输出字节序。
out_addruint32_t输出 Y、S 或 packed 地址,8 字节对齐。
out_strideuint32_t输出 Y、S 或 packed 跨距,8 字节对齐。
out_v_addr / out_v_strideuint32_tHSV 输出 V 平面地址/跨距。
uv_out_addr / uv_out_strideuint32_t输出 UV(NV)或 H(HSV)地址/跨距。

1.3.3 hal_ipu_osd_channel0_t

OSD 通道 0(小图)描述:

字段类型说明
enablebool通道使能。
formathal_ipu_format_t小图格式。
argb_orderhal_ipu_argb_order_tpacked 小图字节序。
csc_controlhal_ipu_csc_control_t小图 CSC 方向。
alpha_selecthal_ipu_alpha_select_talpha 选择方式。
global_alphauint8_t全局 alpha 值。
prembool输入像素是否已预乘 alpha(PREM=1 时硬件不再预乘)。
osdmuint8_tPorter-Duff 混合模式。
mask_enbool通道 mask 使能。
pad_sel / osd_selbool重叠/非重叠区层选择。
width / heightuint16_t小图宽高。
xpos / yposuint16_t小图在背景中的位置。
y_addr / y_strideuint32_t小图 Y 或 packed 地址/跨距。
uv_addr / uv_strideuint32_t小图 UV 地址/跨距。
bak_argbuint32_t通道 mask ARGB/AYUV 值。

1.3.4 hal_ipu_osd_background_t

OSD 背景通道描述:

字段类型说明
formathal_ipu_format_t背景格式。
argb_orderhal_ipu_argb_order_tpacked 背景字节序。
alpha_selecthal_ipu_alpha_select_talpha 选择方式。
global_alphauint8_t全局 alpha 值。
prembool输入像素是否已预乘 alpha(PREM=1 时硬件不再预乘)。
mask_enbool背景 mask 使能。
bak_argbuint32_t背景 mask ARGB/AYUV 值。

1.3.5 hal_ipu_csc_t

通道 0 CSC 系数与偏移(语义化 12/8-bit 值,寄存器编码由 HAL 完成):

字段类型说明
c00~`c22`uint16_t9 个 12-bit CSC 系数。
luma_offsetuint8_t亮度偏移,8-bit。
chroma_offsetuint8_t色度偏移,8-bit。

1.3.6 hal_ipu_pingpong_t

连续帧乒乓地址寄存器:

字段类型说明
y_addr_ppuint32_t乒乓 Y 或 packed 源地址。
uv_addr_ppuint32_t乒乓 UV 源地址。
ch0_y_addr_ppuint32_t乒乓通道 0 Y 地址。
ch0_uv_addr_ppuint32_t乒乓通道 0 UV 地址。

1.3.7 hal_ipu_2bit_t

2-bit 模式 alpha/color 控制:

字段类型说明
bit_1uint32_t数据位为 1 时使用的值(IPU_2BIT_BIT_1 0x1F4)。
bit_0uint32_t数据位为 0 时使用的值(IPU_2BIT_BIT_0 0x1F8)。
maskuint32_t2-bit mask(IPU_2BIT_MASK 0x1FC)。

1.3.8 hal_ipu_control_t

控制器控制字段:

字段类型说明
continuous_modebooltrue 为连续刷新模式。
output_to_dpubooltrue 为 DPU 直通。
arb_modehal_ipu_arb_mode_t读仲裁模式。
ch0_priority / ch1_priorityhal_ipu_arb_priority_t通道 0/1 仲裁优先级。
osd_lay_padding_argbuint32_tOSD 层 padding 颜色(IPU_OSD_LAY_PADDING_ARGB 0x1B0)。

1.3.9 hal_ipu_frame_addr_t

连续模式单帧源地址组:

字段类型说明
y_addruint32_t背景 Y 或 packed 地址。
uv_addruint32_t背景 UV 地址。
ch0_y_addruint32_t通道 0 Y 或 packed 地址。
ch0_uv_addruint32_t通道 0 UV 地址。

1.3.10 hal_ipu_config_t

语义化管线配置,在 start 请求前一次性应用:

字段类型说明
inputhal_ipu_input_t背景(大图)输入。
outputhal_ipu_output_t输出格式与目的 buffer。
osd_channel0hal_ipu_osd_channel0_tOSD 通道 0。
osd_backgroundhal_ipu_osd_background_tOSD 背景通道。
cschal_ipu_csc_t通道 0 CSC 系数。
pingponghal_ipu_pingpong_t乒乓地址(连续模式)。
two_bithal_ipu_2bit_t2-bit 模式控制。
controlhal_ipu_control_t控制器控制字段。

RUN/STOP/RESET 与 BUFF_STATE ready 位由 HAL 运行期接口(IPU_BUFF_STATE0x1D0)管理,不属于本结构体。

1.3.11 hal_ipu_irq_callback_t

typedef void (*hal_ipu_irq_callback_t)(const ipu_regs_t *ipux, uint32_t irq_status, void *user_ctx);

ISR 上下文调用的锁存中断通知回调;必须保持简短,不得回调 HAL。

2. HAL 接口规范

2.1 初始化与生命周期

2.1.1 hal_ipu_get_instance

ipu_regs_t *hal_ipu_get_instance(void);

功能说明: 返回 SoC IPU 寄存器块指针,供其他 HAL 调用使用。

参数表:

参数类型方向说明
无---

返回值表:

返回值说明
非空指针IPU 寄存器块基地址

2.1.2 hal_ipu_init

error_code_t hal_ipu_init(ipu_regs_t *ipux);

功能说明: 绑定并初始化唯一 IPU 硬件实例:使能时钟门控(HAL_CPM_ID_GATE_IPU)、关闭并 清除外设中断与 BUFF_STATE、把可能残留的扫描流关掉。HAL 不注册 PLIC 中断。

参数表:

参数 类型 方向 说明
ipux ipu_regs_t * 输入 IPU 寄存器基地址,必须为 IPU 实例。

返回值表:

返回值 说明
IM_OK 初始化成功
IM_ERR_INVALID_PARAM ipux 非 IPU 实例
IM_ERR_BUSY 已有调用方持有唯一硬件实例
IM_ERR_TIMEOUT 残留扫描流未在默认超时内停下来
其他 时钟使能失败

补充说明:

  • 初始化过程会清除先前硬件状态(中断、OUT_END、BUFF_STATE)。
  • IRQ_IPU 由 MID 或平台层管理。推荐先完成 hal_ipu_init() 和 hal_ipu_irq_set_callback(),再调用 sys_irq_request() / sys_irq_enable(), 避免 CPU IRQ 在 HAL 尚未初始化或无 callback 时进入。
  • hal_ipu_init() 会关闭外设级 IPU_GLB_CTRL.IRQ_EN;hal_ipu_start() 在 启动帧前再打开,hal_ipu_stop() / hal_ipu_deinit() 会关闭。
  • 上一次运行(本应用的软重启、上一个测试、其它固件镜像)可能把 IPU 留在扫描 状态。hal_ipu_config() 要求硬件 idle,所以 init 会先判断 IPU_STATUS.MSTATUS,非 idle 时写 TRIGGER.STOP 并等待 idle 后再返回;因此 调用方不需要在 init 之前手动 stop。等待超时则回滚时钟与内部状态并返回 IM_ERR_TIMEOUT。
  • 失败时内部状态清零,时钟门控回滚。

2.1.3 hal_ipu_deinit

error_code_t hal_ipu_deinit(ipu_regs_t *ipux);

功能说明: 停止 IPU(如非 idle)、关闭并注销中断、释放时钟门控并解绑实例。

参数表:

参数类型方向说明
ipuxipu_regs_t *输入传给 hal_ipu_init() 的寄存器基地址。

返回值表:

返回值说明
IM_OK释放成功
IM_ERR_INVALID_PARAMipux 非法
IM_ERR_TIMEOUT停止时等待 idle 超时

2.2 配置与运行控制

2.2.1 hal_ipu_config

error_code_t hal_ipu_config(ipu_regs_t *ipux, const hal_ipu_config_t *config);

功能说明: 在 IPU idle 时应用完整语义配置,编码进全部相关寄存器。

参数表:

参数类型方向说明
ipuxipu_regs_t *输入IPU 寄存器块指针。
configconst hal_ipu_config_t *输入语义化管线配置。

返回值表:

返回值说明
IM_OK配置成功
IM_ERR_INVALID_PARAM参数或组合非法
IM_ERR_UNSUPPORTED格式无法编码(见 7.3)
IM_ERR_BUSYIPU 非 idle

补充说明:

  • 校验规则见 7.3;config 中 RUN/STOP/RESET 与 ready 位不由此接口管理。

  • 连续帧运行中不要调用本接口;换帧使用 hal_ipu_update_frame()。

2.2.2 hal_ipu_start

error_code_t hal_ipu_start(ipu_regs_t *ipux);

功能说明: 置位 IPU_TRIGGER.RUN(0x074)启动帧处理。

参数表:

参数类型方向说明
ipuxipu_regs_t *输入IPU 寄存器块指针。

返回值表:

返回值说明
IM_OK启动成功
IM_ERR_INVALID_PARAMipux 非法
IM_ERR_BUSYIPU 非 idle

补充说明:

  • 单帧模式按 spec 要求,RUN 前 BUFF_STATE.BK_BUFF0_STATE 必须为 1 (IPU_BUFF_STATE 0x1D0)。

2.2.3 hal_ipu_stop

error_code_t hal_ipu_stop(ipu_regs_t *ipux, uint32_t timeout_ms);

功能说明: 请求安全停止(置 IPU_TRIGGER.STOP),并等待 IPU_STATUS.MSTATUS(0x004)为 idle。

参数表:

参数类型方向说明
ipuxipu_regs_t *输入IPU 寄存器块指针。
timeout_msuint32_t输入idle 等待超时;0 表示只检查一次、不额外等待。

返回值表:

返回值说明
IM_OK停止成功或本就 idle
IM_ERR_INVALID_PARAMipux 非法
IM_ERR_TIMEOUT等待 idle 超时

2.2.4 hal_ipu_wait_idle

error_code_t hal_ipu_wait_idle(ipu_regs_t *ipux, uint32_t timeout_ms);

功能说明: 轮询 IPU_STATUS.MSTATUS(0x004)直到 IPU idle。

参数表:

参数 类型 方向 说明
ipux ipu_regs_t * 输入 IPU 寄存器块指针。
timeout_ms uint32_t 输入 idle 等待超时;0 表示只检查一次、不额外等待。

返回值表:

返回值 说明
IM_OK IPU 已 idle
IM_ERR_INVALID_PARAM ipux 非法
IM_ERR_TIMEOUT 等待 idle 超时

2.2.5 hal_ipu_reset

error_code_t hal_ipu_reset(ipu_regs_t *ipux, uint32_t timeout_ms);

功能说明: 等待 idle 后执行控制器复位(IPU_TRIGGER.RESET),并清除 OUT_END 与pending_irq 锁存。

参数表:

参数类型方向说明
ipuxipu_regs_t *输入IPU 寄存器块指针。
timeout_msuint32_t输入idle 等待超时;0 表示只检查一次、不额外等待。

返回值表:

返回值说明
IM_OK复位成功
IM_ERR_INVALID_PARAMipux 非法
IM_ERR_TIMEOUT等待 idle 超时

2.3 状态读取与连续帧接口

2.3.1 hal_ipu_get_status

error_code_t hal_ipu_get_status(const ipu_regs_t *ipux, uint32_t *status_out);

功能说明: 读取原始 IPU_STATUS 寄存器(0x004)。

参数表:

参数类型方向说明
ipuxconst ipu_regs_t *输入IPU 寄存器块指针。
status_outuint32_t *输出STATUS 原始值。

返回值表:

返回值说明
IM_OK读取成功
IM_ERR_INVALID_PARAMipux 或 status_out 非法

2.3.2 hal_ipu_get_trigger

error_code_t hal_ipu_get_trigger(const ipu_regs_t *ipux, uint32_t *trigger_out);

功能说明: 读取原始 IPU_TRIGGER 寄存器(0x074)。

参数表:

参数类型方向说明
ipuxconst ipu_regs_t *输入IPU 寄存器块指针。
trigger_outuint32_t *输出TRIGGER 原始值。

返回值表:

返回值说明
IM_OK读取成功
IM_ERR_INVALID_PARAMipux 或 trigger_out 非法

2.3.3 hal_ipu_get_buffer_state

error_code_t hal_ipu_get_buffer_state(const ipu_regs_t *ipux, uint32_t *buffer_state_out);

功能说明: 读取原始 IPU_BUFF_STATE 寄存器(0x1D0)ready 位。

参数表:

参数类型方向说明
ipuxconst ipu_regs_t *输入IPU 寄存器块指针。
buffer_state_outuint32_t *输出BUFF_STATE ready 位。

返回值表:

返回值说明
IM_OK读取成功
IM_ERR_INVALID_PARAMipux 或 buffer_state_out 非法

2.3.4 hal_ipu_update_frame

error_code_t hal_ipu_update_frame(ipu_regs_t *ipux, uint32_t buf_index,
                                  const hal_ipu_frame_addr_t *addr);

功能说明: 更新一组连续帧源地址,并置位对应 IPU_REG_CTRL(0x064)ready 位,使新地址在 当前帧结束后生效。

参数表:

参数类型方向说明
ipuxipu_regs_t *输入IPU 寄存器块指针。
buf_indexuint32_t输入乒乓组序号,0 或 1。
addrconst hal_ipu_frame_addr_t *输入新源地址组。

返回值表:

返回值说明
IM_OK更新成功
IM_ERR_INVALID_PARAMipux/addr 非法、buf_index 越界,或当前非连续刷新模式

补充说明:

  • 仅连续模式(IPU_TRIGGER.REFRESH_MODE=1)可用。

  • 不修改 RUN 位与 BUFF_STATE。

2.3.5 hal_ipu_buffer_ready_set

error_code_t hal_ipu_buffer_ready_set(ipu_regs_t *ipux, uint32_t buffers);

功能说明: 置位选定乒乓 buffer 的 ready 位(IPU_BUFF_STATE 0x1D0)。

参数表:

参数类型方向说明
ipuxipu_regs_t *输入IPU 寄存器块指针。
buffersuint32_t输入HAL_IPU_BUFFER_* 位组合。

返回值表:

返回值说明
IM_OK置位成功
IM_ERR_INVALID_PARAMipux 非法,或 buffers 为空/含无效位

2.3.6 hal_ipu_buffer_ready_clear

error_code_t hal_ipu_buffer_ready_clear(ipu_regs_t *ipux, uint32_t buffers);

功能说明: 清除选定乒乓 buffer 的 ready 位(IPU_BUFF_STATE 0x1D0)。

参数表:

参数类型方向说明
ipuxipu_regs_t *输入IPU 寄存器块指针。
buffersuint32_t输入HAL_IPU_BUFFER_* 位组合。

返回值表:

返回值说明
IM_OK清除成功
IM_ERR_INVALID_PARAMipux 非法,或 buffers 为空/含无效位

2.4 中断接口

2.4.1 hal_ipu_irq_handler

void hal_ipu_irq_handler(void);

功能说明: 处理一次 IPU 硬件中断。函数读取 IPU_STATUS,把 OUT_END 和 SIZE_ERR 转换为 HAL_IPU_IRQ_* 语义位并锁存,清除本次已处理的硬件 OUT_END,最后调用 通过 hal_ipu_irq_set_callback() 注册的业务回调。

该函数由 MID 的 IRQ 入口调用:

IRQ_IPU
    -> im_ipu_irq_entry()
    -> hal_ipu_irq_handler()
    -> im_ipu_irq_callback()
    -> os_thread_waiter_wakeup()

参数表:

参数 类型 方向 说明
无 - - 固定服务当前唯一的 IPU 实例。

返回值表:

返回值 说明
无 -

补充说明:

  • HAL 不调用 sys_irq_request()、sys_irq_enable()、sys_irq_disable() 或 sys_irq_release()。
  • MID 负责 IRQ_IPU 的完整生命周期,平台层直接使用 HAL 时也必须自行管理该 IRQ,并在中断入口调用本函数。
  • 回调在 IRQ 上下文执行,必须简短,不得阻塞或等待。

2.4.2 hal_ipu_irq_enable

error_code_t hal_ipu_irq_enable(ipu_regs_t *ipux, bool enable);

功能说明: 使能或关闭 IPU OUT_END 中断产生与 PLIC 投递。

参数表:

参数类型方向说明
ipuxipu_regs_t *输入IPU 寄存器块指针。
enablebool输入true 使能,false 关闭。

返回值表:

返回值说明
IM_OK操作成功
IM_ERR_INVALID_PARAMipux 非法

2.4.3 hal_ipu_irq_status_get

error_code_t hal_ipu_irq_status_get(const ipu_regs_t *ipux, uint32_t *irq_status_out);

功能说明: 读取核心 ISR 锁存的 IRQ 位(HAL_IPU_IRQ_*)。

参数表:

参数类型方向说明
ipuxconst ipu_regs_t *输入IPU 寄存器块指针。
irq_status_outuint32_t *输出锁存的 IRQ 位。

返回值表:

返回值说明
IM_OK读取成功
IM_ERR_INVALID_PARAMipux 或 irq_status_out 非法

2.4.4 hal_ipu_irq_status_clear

error_code_t hal_ipu_irq_status_clear(ipu_regs_t *ipux, uint32_t irq_mask);

功能说明: 清除锁存 IRQ 位中选定位。

参数表:

参数类型方向说明
ipuxipu_regs_t *输入IPU 寄存器块指针。
irq_maskuint32_t输入待清除的 HAL_IPU_IRQ_* 位。

返回值表:

返回值说明
IM_OK清除成功
IM_ERR_INVALID_PARAMipux 非法

2.4.5 hal_ipu_irq_set_callback

error_code_t hal_ipu_irq_set_callback(ipu_regs_t *ipux, hal_ipu_irq_callback_t callback,
                                      void *user_ctx);

功能说明: 安装或清除 ISR 锁存中断通知回调。

参数表:

参数类型方向说明
ipuxipu_regs_t *输入IPU 寄存器块指针。
callbackhal_ipu_irq_callback_t输入ISR 中调用的回调,NULL 清除。
user_ctxvoid *输入回传给回调的不透明上下文。

返回值表:

返回值说明
IM_OK安装成功
IM_ERR_INVALID_PARAMipux 非法

补充说明:

  • 回调在 ISR 上下文执行,必须保持简短,不得回调 HAL。

2.4.6 hal_ipu_output_end_clear

error_code_t hal_ipu_output_end_clear(ipu_regs_t *ipux);

功能说明: 清除硬件 OUT_END 条件(IPU_STATUS 0x004,W1C)。

参数表:

参数类型方向说明
ipuxipu_regs_t *输入IPU 寄存器块指针。

返回值表:

返回值说明
IM_OK清除成功
IM_ERR_INVALID_PARAMipux 非法

2.5 诊断与系数辅助

2.5.1 hal_ipu_get_cycle_count

error_code_t hal_ipu_get_cycle_count(const ipu_regs_t *ipux, uint32_t *cycle_count_out);

功能说明: 读取最近一帧 cycle count(IPU_CYC_NUM_ONE_FRA 0x1AC)。

参数表:

参数类型方向说明
ipuxconst ipu_regs_t *输入IPU 寄存器块指针。
cycle_count_outuint32_t *输出上一帧 cycle count。

返回值表:

返回值说明
IM_OK读取成功
IM_ERR_INVALID_PARAMipux 或 cycle_count_out 非法

2.5.2 hal_ipu_get_debug_info

error_code_t hal_ipu_get_debug_info(const ipu_regs_t *ipux, uint32_t *debug_info_out);

功能说明: 读取 debug 信号快照(IPU_DEBUG_INFO_SIGNALS 0x1B4)。

参数表:

参数类型方向说明
ipuxconst ipu_regs_t *输入IPU 寄存器块指针。
debug_info_outuint32_t *输出debug 信号原始值。

返回值表:

返回值说明
IM_OK读取成功
IM_ERR_INVALID_PARAMipux 或 debug_info_out 非法

2.5.3 hal_ipu_dump_regs

error_code_t hal_ipu_dump_regs(const ipu_regs_t *ipux);

功能说明: 以 INFO 级别打印全部具名 IPU 寄存器。

参数表:

参数类型方向说明
ipuxconst ipu_regs_t *输入IPU 寄存器块指针。

返回值表:

返回值说明
IM_OK打印成功
IM_ERR_INVALID_PARAMipux 非法
IM_ERR_UNSUPPORTEDCONFIG_IPU_ENABLE_DEBUG_HELPERS 未启用

2.5.4 hal_ipu_csc_set_default_yuv2rgb

void hal_ipu_csc_set_default_yuv2rgb(hal_ipu_csc_t *csc_out);

功能说明: 填充 spec 推荐的 YUV-to-RGB 系数。

参数表:

参数类型方向说明
csc_outhal_ipu_csc_t *输出待填充的 CSC 结构体,必须非空。

返回值表:

返回值说明
无接口不返回状态码;csc 必须非空

2.5.5 hal_ipu_csc_set_default_rgb2yuv

void hal_ipu_csc_set_default_rgb2yuv(hal_ipu_csc_t *csc_out);

功能说明: 填充旧 SDK 沿用的 RGB-to-YUV 系数集。

参数表:

参数类型方向说明
csc_outhal_ipu_csc_t *输出待填充的 CSC 结构体,必须非空。

返回值表:

返回值说明
无接口不返回状态码;csc_out 必须非空

3. 当前实现约束与行为说明

3.1 ISR 与 pending_irq 锁存

  • ISR 读 IPU_STATUS,将 OUT_END/SIZE_ERR 映射为语义位 (HAL_IPU_IRQ_OUT_END/HAL_IPU_STATUS_SIZE_ERR)锁存到 pending_irq, 调用回调,然后 W1C 清除硬件 OUT_END。

  • 调用方通过 hal_ipu_irq_status_get() 读锁存、hal_ipu_irq_status_clear()清除;hal_ipu_irq_status_clear() 通过临时关闭 IPU 中断使读改写与 ISR 串行化。硬件位已被 ISR 清除,因此提交前清除锁存即可隔离新旧帧事件。

  • SIZE_ERR 是只读状态位,不触发中断,只能轮询锁存发现。

  • IPU_STATUS 复位值含 OUT_END=1,首次使用前需清除。

3.2 连续帧 ready 位语义

  • HAL_IPU_BUFFER_BK0|CH0_0 与基地址寄存器组对应,BK1|CH0_1 与乒乓寄存器 组对应;两组必须成对维护。

  • 换帧前应清除另一组 ready 位,否则 IPU 会继续循环旧 buffer。

4. 典型用法

4.1 单帧 CSC 到 PSRAM

static const uint32_t y_addr = 0x20000000U;      /* NV12 输入,8 字节对齐 */
static const uint32_t uv_addr = 0x20010000U;
static const uint32_t out_addr = 0x20020000U;    /* ARGB8888 输出 */
hal_ipu_config_t cfg;
uint32_t status;

hal_ipu_init(hal_ipu_get_instance());
hal_ipu_irq_enable(hal_ipu_get_instance(), true);
memset(&cfg, 0, sizeof(cfg));

cfg.input.format    = HAL_IPU_FORMAT_NV12;
cfg.input.y_addr    = y_addr;
cfg.input.uv_addr   = uv_addr;
cfg.input.width     = 64U;
cfg.input.height    = 64U;
cfg.input.y_stride  = 64U;
cfg.input.uv_stride = 64U;
/* YUV422 输入同路径:input.format = HAL_IPU_FORMAT_YUV422、y_stride = width * 2。 */
cfg.output.format   = HAL_IPU_FORMAT_ARGB8888;
cfg.output.order    = HAL_IPU_ORDER_ARGB;
cfg.output.y_addr   = out_addr;
cfg.output.y_stride = 64U * 4U;
hal_ipu_csc_set_default_yuv2rgb(&cfg.csc);
cfg.control.arb_mode     = HAL_IPU_ARB_MODE_ROUND_ROBIN;
cfg.control.ch0_priority = HAL_IPU_ARB_PRIORITY_HIGH;
cfg.control.ch1_priority = HAL_IPU_ARB_PRIORITY_LOW;

hal_ipu_config(hal_ipu_get_instance(), &cfg);
hal_ipu_buffer_ready_set(hal_ipu_get_instance(), HAL_IPU_BUFFER_BK0 | HAL_IPU_BUFFER_CH0_0);
hal_ipu_start(hal_ipu_get_instance());

/* 轮询锁存等待帧结束(或注册回调) */
do {
    (void)hal_ipu_irq_status_get(hal_ipu_get_instance(), &status);
} while ((status & HAL_IPU_IRQ_OUT_END) == 0U);

hal_ipu_stop(hal_ipu_get_instance(), 1000U);
hal_ipu_deinit(hal_ipu_get_instance());

4.2 连续帧乒乓(OSD)

/* 首帧:全量配置(含 pingpong 地址),RUN 前置第 0 组 ready */
hal_ipu_config(hal_ipu_get_instance(), &cfg);
hal_ipu_buffer_ready_set(hal_ipu_get_instance(), HAL_IPU_BUFFER_BK0 | HAL_IPU_BUFFER_CH0_0);
hal_ipu_start(hal_ipu_get_instance());

/* 每帧 OUT_END 后提交下一帧到另一组:先撤旧组,再更新地址,最后置新组 ready */
uint32_t next_buf = 1U;
hal_ipu_frame_addr_t addr = {
    .y_addr      = next_y,
    .uv_addr     = next_uv,
    .ch0_y_addr  = next_ch0_y,
    .ch0_uv_addr = next_ch0_uv,
};
(void)hal_ipu_buffer_ready_clear(hal_ipu_get_instance(),
                                 (next_buf == 0U) ? (HAL_IPU_BUFFER_BK0 | HAL_IPU_BUFFER_CH0_0)
                                                  : (HAL_IPU_BUFFER_BK1 | HAL_IPU_BUFFER_CH0_1));
hal_ipu_update_frame(hal_ipu_get_instance(), next_buf, &addr);
hal_ipu_buffer_ready_set(hal_ipu_get_instance(),
                         (next_buf == 0U) ? (HAL_IPU_BUFFER_BK0 | HAL_IPU_BUFFER_CH0_0)
                                          : (HAL_IPU_BUFFER_BK1 | HAL_IPU_BUFFER_CH0_1));
next_buf ^= 1U;

/* 停止:等当前帧结束后 STOP */
hal_ipu_stop(hal_ipu_get_instance(), 1000U);

4.3 DPU 直通

cfg.control.continuous_mode = true;
cfg.control.output_to_dpu   = true;   /* IPU_TRIGGER.DPU_EN 置位 */

/* IPU 输出直通 DPU,不写 PSRAM;DPU 侧先启动,IPU 后启动 */
hal_ipu_config(hal_ipu_get_instance(), &cfg);
hal_ipu_buffer_ready_set(hal_ipu_get_instance(), HAL_IPU_BUFFER_BK0 | HAL_IPU_BUFFER_CH0_0);
hal_ipu_start(hal_ipu_get_instance());

/* OUT_END 后 IPU 保持输出,DPU 按自己的刷新节奏取数 */
hal_ipu_stop(hal_ipu_get_instance(), 1000U);