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_YUV | OSD 通道 CSC 方向(IPU_OSD_CH0_PARA.CSC_CTL 0x11C)。 |
HAL_IPU_ALPHA_SELECT_PIXEL / GLOBAL / PIXEL_X_GLOBAL | alpha 选择(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_ID | PLIC 中断号。 |
CONFIG_IPU_ENABLE_DEBUG_HELPERS | hal_ipu_dump_regs() 编译开关。 |
1.3 公开结构体
1.3.1 hal_ipu_input_t
背景(大图)输入描述:
| 字段 | 类型 | 说明 |
|---|---|---|
format | hal_ipu_format_t | 输入格式。 |
argb_order | hal_ipu_argb_order_t | packed 格式字节序。 |
y_addr | uint32_t | Y 或 packed 像素地址,8 字节对齐。 |
uv_addr | uint32_t | UV 地址(NV 格式),8 字节对齐。 |
width / height | uint16_t | 输入宽高,4~1280。 |
y_stride | uint32_t | Y 或 packed 跨距,8 字节对齐。 |
uv_stride | uint32_t | UV 跨距(NV 格式),8 字节对齐。 |
1.3.2 hal_ipu_output_t
输出图像描述(格式与目的 buffer):
| 字段 | 类型 | 说明 |
|---|---|---|
format | hal_ipu_format_t | 输出格式。 |
argb_order | hal_ipu_argb_order_t | packed 输出字节序。 |
out_addr | uint32_t | 输出 Y、S 或 packed 地址,8 字节对齐。 |
out_stride | uint32_t | 输出 Y、S 或 packed 跨距,8 字节对齐。 |
out_v_addr / out_v_stride | uint32_t | HSV 输出 V 平面地址/跨距。 |
uv_out_addr / uv_out_stride | uint32_t | 输出 UV(NV)或 H(HSV)地址/跨距。 |
1.3.3 hal_ipu_osd_channel0_t
OSD 通道 0(小图)描述:
| 字段 | 类型 | 说明 |
|---|---|---|
enable | bool | 通道使能。 |
format | hal_ipu_format_t | 小图格式。 |
argb_order | hal_ipu_argb_order_t | packed 小图字节序。 |
csc_control | hal_ipu_csc_control_t | 小图 CSC 方向。 |
alpha_select | hal_ipu_alpha_select_t | alpha 选择方式。 |
global_alpha | uint8_t | 全局 alpha 值。 |
prem | bool | 输入像素是否已预乘 alpha(PREM=1 时硬件不再预乘)。 |
osdm | uint8_t | Porter-Duff 混合模式。 |
mask_en | bool | 通道 mask 使能。 |
pad_sel / osd_sel | bool | 重叠/非重叠区层选择。 |
width / height | uint16_t | 小图宽高。 |
xpos / ypos | uint16_t | 小图在背景中的位置。 |
y_addr / y_stride | uint32_t | 小图 Y 或 packed 地址/跨距。 |
uv_addr / uv_stride | uint32_t | 小图 UV 地址/跨距。 |
bak_argb | uint32_t | 通道 mask ARGB/AYUV 值。 |
1.3.4 hal_ipu_osd_background_t
OSD 背景通道描述:
| 字段 | 类型 | 说明 |
|---|---|---|
format | hal_ipu_format_t | 背景格式。 |
argb_order | hal_ipu_argb_order_t | packed 背景字节序。 |
alpha_select | hal_ipu_alpha_select_t | alpha 选择方式。 |
global_alpha | uint8_t | 全局 alpha 值。 |
prem | bool | 输入像素是否已预乘 alpha(PREM=1 时硬件不再预乘)。 |
mask_en | bool | 背景 mask 使能。 |
bak_argb | uint32_t | 背景 mask ARGB/AYUV 值。 |
1.3.5 hal_ipu_csc_t
通道 0 CSC 系数与偏移(语义化 12/8-bit 值,寄存器编码由 HAL 完成):
| 字段 | 类型 | 说明 |
|---|---|---|
c00~`c22` | uint16_t | 9 个 12-bit CSC 系数。 |
luma_offset | uint8_t | 亮度偏移,8-bit。 |
chroma_offset | uint8_t | 色度偏移,8-bit。 |
1.3.6 hal_ipu_pingpong_t
连续帧乒乓地址寄存器:
| 字段 | 类型 | 说明 |
|---|---|---|
y_addr_pp | uint32_t | 乒乓 Y 或 packed 源地址。 |
uv_addr_pp | uint32_t | 乒乓 UV 源地址。 |
ch0_y_addr_pp | uint32_t | 乒乓通道 0 Y 地址。 |
ch0_uv_addr_pp | uint32_t | 乒乓通道 0 UV 地址。 |
1.3.7 hal_ipu_2bit_t
2-bit 模式 alpha/color 控制:
| 字段 | 类型 | 说明 |
|---|---|---|
bit_1 | uint32_t | 数据位为 1 时使用的值(IPU_2BIT_BIT_1 0x1F4)。 |
bit_0 | uint32_t | 数据位为 0 时使用的值(IPU_2BIT_BIT_0 0x1F8)。 |
mask | uint32_t | 2-bit mask(IPU_2BIT_MASK 0x1FC)。 |
1.3.8 hal_ipu_control_t
控制器控制字段:
| 字段 | 类型 | 说明 |
|---|---|---|
continuous_mode | bool | true 为连续刷新模式。 |
output_to_dpu | bool | true 为 DPU 直通。 |
arb_mode | hal_ipu_arb_mode_t | 读仲裁模式。 |
ch0_priority / ch1_priority | hal_ipu_arb_priority_t | 通道 0/1 仲裁优先级。 |
osd_lay_padding_argb | uint32_t | OSD 层 padding 颜色(IPU_OSD_LAY_PADDING_ARGB 0x1B0)。 |
1.3.9 hal_ipu_frame_addr_t
连续模式单帧源地址组:
| 字段 | 类型 | 说明 |
|---|---|---|
y_addr | uint32_t | 背景 Y 或 packed 地址。 |
uv_addr | uint32_t | 背景 UV 地址。 |
ch0_y_addr | uint32_t | 通道 0 Y 或 packed 地址。 |
ch0_uv_addr | uint32_t | 通道 0 UV 地址。 |
1.3.10 hal_ipu_config_t
语义化管线配置,在 start 请求前一次性应用:
| 字段 | 类型 | 说明 |
|---|---|---|
input | hal_ipu_input_t | 背景(大图)输入。 |
output | hal_ipu_output_t | 输出格式与目的 buffer。 |
osd_channel0 | hal_ipu_osd_channel0_t | OSD 通道 0。 |
osd_background | hal_ipu_osd_background_t | OSD 背景通道。 |
csc | hal_ipu_csc_t | 通道 0 CSC 系数。 |
pingpong | hal_ipu_pingpong_t | 乒乓地址(连续模式)。 |
two_bit | hal_ipu_2bit_t | 2-bit 模式控制。 |
control | hal_ipu_control_t | 控制器控制字段。 |
RUN/STOP/RESET 与
BUFF_STATEready 位由 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)、关闭并注销中断、释放时钟门控并解绑实例。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ipux | ipu_regs_t * | 输入 | 传给 hal_ipu_init() 的寄存器基地址。 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 释放成功 |
IM_ERR_INVALID_PARAM | ipux 非法 |
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 时应用完整语义配置,编码进全部相关寄存器。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ipux | ipu_regs_t * | 输入 | IPU 寄存器块指针。 |
config | const hal_ipu_config_t * | 输入 | 语义化管线配置。 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 配置成功 |
IM_ERR_INVALID_PARAM | 参数或组合非法 |
IM_ERR_UNSUPPORTED | 格式无法编码(见 7.3) |
IM_ERR_BUSY | IPU 非 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)启动帧处理。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ipux | ipu_regs_t * | 输入 | IPU 寄存器块指针。 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 启动成功 |
IM_ERR_INVALID_PARAM | ipux 非法 |
IM_ERR_BUSY | IPU 非 idle |
补充说明:
单帧模式按 spec 要求,RUN 前
BUFF_STATE.BK_BUFF0_STATE必须为 1 (IPU_BUFF_STATE0x1D0)。
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。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ipux | ipu_regs_t * | 输入 | IPU 寄存器块指针。 |
timeout_ms | uint32_t | 输入 | idle 等待超时;0 表示只检查一次、不额外等待。 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 停止成功或本就 idle |
IM_ERR_INVALID_PARAM | ipux 非法 |
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 锁存。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ipux | ipu_regs_t * | 输入 | IPU 寄存器块指针。 |
timeout_ms | uint32_t | 输入 | idle 等待超时;0 表示只检查一次、不额外等待。 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 复位成功 |
IM_ERR_INVALID_PARAM | ipux 非法 |
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)。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ipux | const ipu_regs_t * | 输入 | IPU 寄存器块指针。 |
status_out | uint32_t * | 输出 | STATUS 原始值。 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 读取成功 |
IM_ERR_INVALID_PARAM | ipux 或 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)。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ipux | const ipu_regs_t * | 输入 | IPU 寄存器块指针。 |
trigger_out | uint32_t * | 输出 | TRIGGER 原始值。 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 读取成功 |
IM_ERR_INVALID_PARAM | ipux 或 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 位。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ipux | const ipu_regs_t * | 输入 | IPU 寄存器块指针。 |
buffer_state_out | uint32_t * | 输出 | BUFF_STATE ready 位。 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 读取成功 |
IM_ERR_INVALID_PARAM | ipux 或 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 位,使新地址在
当前帧结束后生效。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ipux | ipu_regs_t * | 输入 | IPU 寄存器块指针。 |
buf_index | uint32_t | 输入 | 乒乓组序号,0 或 1。 |
addr | const hal_ipu_frame_addr_t * | 输入 | 新源地址组。 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 更新成功 |
IM_ERR_INVALID_PARAM | ipux/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)。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ipux | ipu_regs_t * | 输入 | IPU 寄存器块指针。 |
buffers | uint32_t | 输入 | HAL_IPU_BUFFER_* 位组合。 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 置位成功 |
IM_ERR_INVALID_PARAM | ipux 非法,或 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)。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ipux | ipu_regs_t * | 输入 | IPU 寄存器块指针。 |
buffers | uint32_t | 输入 | HAL_IPU_BUFFER_* 位组合。 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 清除成功 |
IM_ERR_INVALID_PARAM | ipux 非法,或 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 投递。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ipux | ipu_regs_t * | 输入 | IPU 寄存器块指针。 |
enable | bool | 输入 | true 使能,false 关闭。 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 操作成功 |
IM_ERR_INVALID_PARAM | ipux 非法 |
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_*)。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ipux | const ipu_regs_t * | 输入 | IPU 寄存器块指针。 |
irq_status_out | uint32_t * | 输出 | 锁存的 IRQ 位。 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 读取成功 |
IM_ERR_INVALID_PARAM | ipux 或 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 位中选定位。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ipux | ipu_regs_t * | 输入 | IPU 寄存器块指针。 |
irq_mask | uint32_t | 输入 | 待清除的 HAL_IPU_IRQ_* 位。 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 清除成功 |
IM_ERR_INVALID_PARAM | ipux 非法 |
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 锁存中断通知回调。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ipux | ipu_regs_t * | 输入 | IPU 寄存器块指针。 |
callback | hal_ipu_irq_callback_t | 输入 | ISR 中调用的回调,NULL 清除。 |
user_ctx | void * | 输入 | 回传给回调的不透明上下文。 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 安装成功 |
IM_ERR_INVALID_PARAM | ipux 非法 |
补充说明:
回调在 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)。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ipux | ipu_regs_t * | 输入 | IPU 寄存器块指针。 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 清除成功 |
IM_ERR_INVALID_PARAM | ipux 非法 |
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)。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ipux | const ipu_regs_t * | 输入 | IPU 寄存器块指针。 |
cycle_count_out | uint32_t * | 输出 | 上一帧 cycle count。 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 读取成功 |
IM_ERR_INVALID_PARAM | ipux 或 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)。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ipux | const ipu_regs_t * | 输入 | IPU 寄存器块指针。 |
debug_info_out | uint32_t * | 输出 | debug 信号原始值。 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 读取成功 |
IM_ERR_INVALID_PARAM | ipux 或 debug_info_out 非法 |
2.5.3 hal_ipu_dump_regs
error_code_t hal_ipu_dump_regs(const ipu_regs_t *ipux);
功能说明: 以 INFO 级别打印全部具名 IPU 寄存器。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
ipux | const ipu_regs_t * | 输入 | IPU 寄存器块指针。 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 打印成功 |
IM_ERR_INVALID_PARAM | ipux 非法 |
IM_ERR_UNSUPPORTED | CONFIG_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_out | hal_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_out | hal_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);