API GUIDE / JPEGE / HAL

G32S10 JPEGE HAL 接口

HAL 层接口:推荐调用顺序:

1. HAL JPEGE 接口

1.1 生命周期和基础流程

void hal_jpege_struct_init(hal_jpege_param_t *param,
                           hal_jpege_config_t *config,
                           hal_jpege_frame_t *frame);

error_code_t hal_jpege_init(const hal_jpege_config_t *config);
error_code_t hal_jpege_callback_register(hal_jpege_callback_t callback);
error_code_t hal_jpege_sequence_configure(const hal_jpege_param_t *param,
                                          const hal_jpege_config_t *config);
error_code_t hal_jpege_start_frame(const hal_jpege_frame_t *frame);
void hal_jpege_irq_handler(void);
error_code_t hal_jpege_get_result(hal_jpege_frame_t *frame);
error_code_t hal_jpege_deinit(void);
error_code_t hal_jpege_regs_dump(void);

推荐调用顺序:

STEP 1  hal_jpege_struct_init
↓
STEP 2  hal_jpege_init
↓
STEP 3  hal_jpege_callback_register
↓
STEP 4  hal_jpege_sequence_configure
↓
STEP 5  hal_jpege_start_frame
↓
STEP 6  SoC IRQ → hal_jpege_irq_handler
↓
STEP 7  hal_jpege_get_result
↓
STEP 8  hal_jpege_deinit

1.2 默认值

hal_jpege_struct_init() 会清零 param/config/frame,然后设置以下默认值:

字段默认值
param.pix_formatHAL_JPEGE_PIX_FMT_NV12
param.bayer_formatHAL_JPEGE_BAYER_FMT_RGGB
param.qk_tableHAL_JPEGE_QK_TABLE_HIGH_COMPRESSION
config.codec.qt_modeHAL_JPEGE_QT_MODE_HARD
config.codec.qt_tableHAL_JPEGE_QT_TABLE_1
config.wrap4
config.ar_outstanding1
config.awlen0
config.timeout_ms1000
config.reset_cycle10
config.hw_timeout.thrd0xffffffff

width、height、src_addr、dst_addr、dst_buf_size 等外部关心字段仍需由调用方填写。

1.3 初始化和复位

error_code_t hal_jpege_reset(const hal_jpege_config_t *config);
error_code_t hal_jpege_init(const hal_jpege_config_t *config);
error_code_t hal_jpege_deinit(void);

hal_jpege_reset 内部流程:

  1. 校验 config != NULL 和 reset_cycle <= 15

  2. 写 SW_RESET_CYCLE

  3. 使能 sequence reset 覆盖 sequence registers 和 slave registers

  4. 触发 SW_SEQ_RESET

  5. 轮询 RESET_FSM_DONE,超时返回 IM_ERR_TIMEOUT

hal_jpege_init 内部流程:

  1. 保存 runtime config 到 HAL 内部 context

  2. 执行 hal_jpege_reset

  3. 检查 systick 是否初始化

  4. 使能 JPEGE 硬件状态中断位并清 pending

  5. 配置 frame-end hold cycles

  6. 设置内部 initialized 状态

hal_jpege_deinit 会关闭所有中断、清 pending、执行 reset,并清除 HAL 内部 configured/initialized 状态。

1.4 序列配置

error_code_t hal_jpege_sequence_configure(const hal_jpege_param_t *param,
                                          const hal_jpege_config_t *config);

该函数用于配置一组编码序列的固定参数,包括图像尺寸、像素格式、stride、MCU 数、量化模式、restart marker 和 trigger/reset 模式。

参数校验:

参数条件
param/config不能为 NULL
width256-1920,且必须是 4 的倍数
height256-1440,且必须是 4 的倍数
pix_format必须为 NV12/YUV420、YUYV/YUV422、单 Y 或 Bayer 之一
bayer_format必须为 RGGB/BGGR/GBRG/GRBG 之一
config.codec.qt_mode必须为 SOFT 或 HARD
config.codec.qt_table必须为 table preset 1 或 2
ar_outstanding1-16
awlen0-3
reset_cycle0-15
qp硬件 QP 模式下必须 0-98
qk_table软件表模式下必须为高/中/低压缩表组之一
wrapJPEG_WRAP 寄存器值;NV12/YUV420 至少 4,YUYV/YUV422 和单 Y 至少 2,最大 0xff;Bayer 不配置

几何参数计算:

输入格式MCU 对齐宽MCU 对齐高stride
HAL_JPEGE_PIX_FMT_Y88width
HAL_JPEGE_PIX_FMT_NV121616width
HAL_JPEGE_PIX_FMT_YUYV168width * 2
HAL_JPEGE_PIX_FMT_BAYER1616width

wrap 直接对应 SPEC 中的 JPEG_WRAP 字段,单位是 OCM 中 ISP/JPEG 可用的 8 行像素空间数量。HAL 不把它当 AXI wrap 或总线属性使用,也不再对 NV12/YUV420 做隐式单位换算;调用方应直接填最终写入寄存器的值。

Trigger 归一化:

  • Bayer 输入不支持自动 start,若 start_auto=true,HAL 会在内部 context 中转为手动 start 并打印 warning

  • Bayer 输入不支持 ISP linkage,若 isp_en=true,HAL 会在内部 context 中关闭 ISP 并打印 warning

  • Bayer 输入无需配置 JPEG_WRAP,HAL 不会写 WRAP 寄存器

  • isp_en=false 时不支持自动 start,若 start_auto=true,HAL 会转为手动 start 并打印 warning

  • 上述归一化只修改 HAL 内部 context,不回写用户传入的 config

量化表配置:

模式配置动作
HAL_JPEGE_QT_MODE_HARD写 qt_base1/qt_base2 到 qt_base_tab[],再写 QP
HAL_JPEGE_QT_MODE_SOFT写 qt_tab1/qt_tab2 到 qt_tab[],再写 QK_TAB_SEL

内部寄存器配置顺序:

  1. 计算 stride、MCU 数、对齐尺寸和输入平面大小

  2. 写量化相关寄存器和量化表 RAM/base table

  3. 写 trigger/reset/ISP/timeout/AW/QT 选择等控制寄存器

  4. 写帧尺寸、stride、MCU 数、输入格式、restart marker、编码像素总数和 wrap

hal_jpege_sequence_configure() 只负责写入序列级配置寄存器,不触发 SHADOW_CUR_EN。第 0 帧的 shadow 生效动作在 hal_jpege_start_frame() 中完成,以保证源/目的地址和 cache 维护已经准备好后再让当前帧配置生效。

1.5 单帧启动、IRQ 分发和取结果

error_code_t hal_jpege_start_frame(const hal_jpege_frame_t *frame);
error_code_t hal_jpege_callback_register(hal_jpege_callback_t callback);
void hal_jpege_irq_handler(void);
error_code_t hal_jpege_get_result(hal_jpege_frame_t *frame);

hal_jpege_start_frame:

  1. 校验 HAL 已初始化、sequence config 已配置

  2. 保存 frame 到 HAL 内部 context

  3. 清除历史中断状态

  4. 校验 src_addr、dst_addr 256 字节对齐

  5. 写 RAWY_ADDR、BS_ADDR

  6. 对源 Y/RAWY 范围执行 cache clean

  7. 对目的 buffer 执行 clean+invalidate

  8. NV12/YUV420 格式下配置 UV 地址,若 src_uv_addr == NULL,按 src_addr + stride * height 推导;YUV422/Bayer 不配置该寄存器

  9. 标记当前帧为 started,确保紧随其后的硬件事件可被 IRQ handler 接收

  10. 若当前 JPEG frame counter 为 0,设置 SHADOW_FLAG 并触发 SHADOW_CUR_EN,让 sequence 配置对第 0 帧生效;后续手动帧触发 START

hal_jpege_irq_handler:

  1. 要求 HAL 已 initialized、sequence 已 configured,且当前帧处于 started;不满足时直接返回

  2. 读取 INTR_STAT & JPEGE_ALL_INTR_MASK;无命中 status 时直接返回

  3. 清除本次读取到的全部 pending status

  4. 按 overflow -> frame-start abnormal -> timeout -> frame-end 的优先级归一为一个 hal_jpege_irq_event_t

  5. 清除 started;只有 frame-end 将结果标记为 ready

  6. 在 IRQ 上下文调用已注册的 callback

HAL 不注册 IRQ_JPEG_ENC,也不执行等待。平台 IRQ entry 必须调用 hal_jpege_irq_handler()。

hal_jpege_get_result:

  1. 校验 HAL 已初始化、sequence 已配置,且 HAL 已接收到有效 frame-end

  2. 读取 GLB_STAT.BS_LEN

  3. 若输出大小超过 dst_buf_size,在返回 IM_ERR_NO_SPACE 前执行帧级复位并清理结果状态

  4. 回填 frame->output_size

  5. 对输出 JPEG 范围执行 cache invalidate

  6. 若 reset_auto=false,触发 SW_FRM_RESET;正常结果和 IM_ERR_NO_SPACE 错误路径均执行

异常 IRQ(overflow、frame-start abnormal、hardware timeout)在回调前同样执行帧级复位;reset_auto=true 时由硬件 AUTO_RESET 完成,reset_auto=false 时由 HAL 触发 SW_FRM_RESET。

hal_jpege_callback_register() 在 hal_jpege_init() 成功后、首次 hal_jpege_start_frame() 前调用。传入 NULL 恢复默认无操作 callback。JPEGE callback 运行于 IRQ 上下文,不得阻塞、做 cache 操作或启动下一帧。

1.6 Shadow 更新接口

error_code_t hal_jpege_update_qp_with_shadow(hal_jpege_shadow_timing_t shadow_timing,
                                             uint32_t qp);
error_code_t hal_jpege_update_qk_table_with_shadow(hal_jpege_shadow_timing_t shadow_timing,
                                                   hal_jpege_qk_table_t qk_table);
接口适用模式校验
hal_jpege_update_qp_with_shadowHAL_JPEGE_QT_MODE_HARDHAL 已 init、sequence 已 configured、qp <= 98、shadow_timing 合法、当前模式为 hard
hal_jpege_update_qk_table_with_shadowHAL_JPEGE_QT_MODE_SOFTHAL 已 init、sequence 已 configured、qk_table 合法、shadow_timing 合法、当前模式为 soft

shadow_timing 可选值:

值说明
HAL_JPEGE_SHADOW_NEXT_START修改在下一帧开始生效
HAL_JPEGE_SHADOW_NEXT_END修改在下一帧结束生效

SHADOW_CUR_EN、SHADOW_NEXT_START_EN 和 SHADOW_NEXT_END_EN 是一次性触发位,所选 shadow 更新生效后由硬件自动清零,软件不需要额外清除这些位。

1.7 调试寄存器 dump

error_code_t hal_jpege_regs_dump(void);

hal_jpege_regs_dump() 用 INFO log 输出 JPEGE 可读寄存器,便于和 spec 或异常现场对照。该接口由两个 Kconfig 开关控制:

开关说明
CONFIG_SDK_ENABLE_DEBUG_HELPERSSDK 全局 debug helper 开关
CONFIG_JPEGE_ENABLE_DEBUG_HELPERSJPEGE driver debug helper 开关

两个开关均打开时,接口返回 IM_OK 并输出寄存器;否则返回 IM_ERR_UNSUPPORTED。INTR_CLR 是 write-only 寄存器,dump 时只打印 <skip>,不会读取。qt_base_tab[32] 和 qt_tab[384] 默认也只打印 <skip>,避免普通寄存器 dump 输出过长;需要查看量化表内容时,可定义:

#define HAL_JPEGE_DUMP_READ_TABLES 1U

1.8 Cache 管理

HAL 当前在以下位置进行 cache 维护:

阶段地址操作目的
start_framesrc_addr,长度 rawy_sizeclean确保硬件读到 CPU 已写入的源 Y/RAWY 数据
start_framesrc_uv_addr 或推导 UV 地址,长度 rawc_sizecleanNV12/YUV420 下确保硬件读到 CPU 已写入的 UV 数据
start_framedst_addr,长度 dst_buf_sizeclean+invalidate避免 CPU 脏 cache line 在硬件写结果后覆盖 JPEG bitstream
get_resultdst_addr,长度 output_sizeinvalidate让 CPU 读取硬件写入后的 JPEG bitstream

调用方在 hal_jpege_start_frame() 到 hal_jpege_get_result() 之间不应修改源/目的 buffer。

源图像与 JPEG bitstream buffer 的 cache 所有权切换见 JPEGE buffer cache 生命周期图。

1.9 线程安全与中断策略

1.9.1 IRQ 模型

JPEGE 采用与 MSCALER 一致的 interrupt-driven 分层:

JPEGE hardware
    -> IRQ_JPEG_ENC
    -> im_irq dispatch
    -> hal_jpege_irq_handler()
    -> hal_jpege_callback_t(event)
职责归属层实现
平台 IRQ 申请、使能和释放应用/平台由平台 IRQ 层负责
转交 SoC IRQ应用/平台在 ISR 中调用 hal_jpege_irq_handler()
读取/清除 JPEGE status,按优先级选择 event,调用 callbackHALhal_jpege_irq_handler()
buffer 分配和 256 字节对齐应用层HAL 只校验,不分配/搬运

2. 典型用法

2.1 软件量化表模式

hal_jpege_struct_init(&param, &config, &frame);

param.width = 640U;
param.height = 480U;
param.pix_format = HAL_JPEGE_PIX_FMT_NV12;
param.qk_table = HAL_JPEGE_QK_TABLE_MEDIUM_COMPRESSION;

config.codec.qt_mode = HAL_JPEGE_QT_MODE_SOFT;
config.codec.qt_table = HAL_JPEGE_QT_TABLE_1;

软件表模式下,param.qp 不参与 QP 配置,HAL 使用 param.qk_table 写 QK_TAB_SEL。