API GUIDE / ADC / OVERVIEW

G32S10 ADC API 概述

模块概述:本文档定义 G32S10 SDK ADC 模块的正式接口,覆盖以下两层:

1. 文档范围

本文档定义 G32S10 SDK ADC 模块的正式接口,覆盖以下两层:

  • HAL ADC:面向应用、BSP和驱动上层的功能级接口

  • LL ADC:面向寄存器与位操作的低层接口

补充说明:

  • LL层不返回状态码;需要返回寄存器值或数据时返回 uint32_t。

  • HAL层负责参数校验、状态管理、中断/DMA编排和超时处理。

本文档以当前 SDK 源码为准,主要核对文件如下:

类型路径
HAL 公开接口code/include/drivers/g32s10/adc/hal_adc.h
HAL 实现code/drivers/g32s10/adc/hal_adc.c
LL 公开接口code/include/drivers/g32s10/adc/ll_adc.h
寄存器定义code/include/drivers/g32s10/adc/adc_regs.h
构建配置code/drivers/g32s10/adc/Kconfig
HAL 示例code/examples/hal/
LL 示例code/examples/ll/adc_seq_example.c

当文档描述与头文件、实现或 Kconfig 不一致时,以当前源码为准;硬件能力中未能在 SDK 源码内直接确认的数值,应结合芯片 SPEC 阅读。

2. 分层关系

APPLICATION  Application / BSP / Example  业务代码、板级支持与示例入口
↓
HAL  HAL ADC  模块级配置、状态管理与硬件访问
↓
LL  LL ADC  寄存器访问与字段级控制
↓
HARDWARE REGISTERS  ADC Registers  实例地址、寄存器布局与位域定义

分层职责如下:

  • HAL ADC

    • 封装初始化、序列配置、启动停止、轮询、中断、DMA侧控制、AWD和寄存器dump

    • 维护参数合法性、模块级状态、活跃序列mask和统一返回码

    • 提供便于上层使用的解包数据结构、回调注册和错误查询接口

  • LL ADC

    • 提供寄存器位级访问入口

    • 不维护软件状态,不做复杂业务语义判断

    • 公开接口均为 static inline,首参数为 adc_regs_t *adcx

  • adc_regs.h

    • 定义ADC基地址、寄存器结构体布局、通道数量、序列长度和位域mask

2.1 编译与运行前置条件

ADC HAL/LL 不负责板级时钟、引脚复用和 SoC 中断资源。直接使用本模块前,应用、BSP 或板级代码需要完成以下准备:

项目责任方说明
CONFIG_DRIVER_ADC应用配置编译 ADC 驱动;该选项会自动选择 CONFIG_DRIVER_DMA。
ADC 模块时钟与门控CPM/板级访问寄存器前使能对应 SADC0/SADC1 时钟和门控。HAL 初始化不会配置 CPM。
模拟输入引脚GPIO/板级将所选通道对应的引脚配置为 ADC 模拟输入功能;具体引脚和功能号由板级设计决定。
SoC IRQPLIC/中断框架使用 *_it() 或 DMA 完成中断时,应用必须注册并使能 IRQ_SADC0 或 IRQ_SADC1,中断服务程序调用 hal_adc_irq_handler()。
systick 时间基准应用/OShal_adc_poll_for_conversion() 以及使用微秒/毫秒超时的应用代码依赖 SDK systick。
DMA 控制器CPM/DMA HALDMA 模式需要 DMA 控制器时钟、合法 descriptor 存储和调用方持有的目标缓冲区。HAL 负责 ADC 侧 cache 维护。
Debug helper应用配置hal_adc_regs_dump() 需要同时开启 CONFIG_SDK_ENABLE_DEBUG_HELPERS 和 CONFIG_ADC_ENABLE_DEBUG_HELPERS,否则保留符号但返回 IM_ERR_UNSUPPORTED。

轮询模式下可不使用 ADC IRQ;DMA 模式是否使用完成中断取决于应用选择普通 start 还是 *_it() 接口。

3. 资源模型与公开类型

3.1 ADC 硬件能力摘要

项目说明
分辨率12 bit,转换结果有效位为 [11:0]。
采样率最大 2 Msps。
ADC工作时钟最大 30 MHz
通道SPEC描述模拟输入通道为 ADC_IN0 ~ ADC_IN7。寄存器存在部分预留扩展位,HAL默认只开放 0~7。
转换序列支持 SEQ0、SEQ1、SEQ2 三个用户自定义转换序列。
SEQ0最多 4 次转换,仅支持寄存器触发,不支持DMA和连续模式,结果存储在 seq0_dr[2]。
SEQ1LL层当前开放最多 8 次转换,支持寄存器/TCU/PWM0/PWM1触发,支持FIFO、DMA、延时扫描、连续转换、组连续转换;寄存器高8次转换暂隐藏。
SEQ2最多 8 次转换,支持寄存器/TCU/PWM0/PWM1触发,支持FIFO、DMA、延时扫描,不支持连续模式。
模拟看门狗支持每个通道高/低阈值检测,支持中断和PWM急停FAIL输出屏蔽控制。
冲突处理支持序列优先级和 BREAK_MD,用于处理高/低优先级序列触发冲突。

3.2 HAL 返回状态约定

HAL层普通可失败接口统一返回SDK公共错误码类型:

error_code_t

常用返回值如下:

返回值说明
IM_OK操作成功。
IM_ERR_INVALID_PARAM参数为空、实例非法、越界或模式组合非法。
IM_ERR_BUSY指定序列或ADC资源忙。
IM_ERR_TIMEOUT轮询等待超时。
IM_ERR_NOT_READY轮询检测到硬件错误、数据未就绪或内部流程未完成。
IM_ERR_UNSUPPORTED当前配置不支持该操作,例如非软件触发序列调用软件start接口。

3.3 数据准备条件

typedef enum {
    HAL_ADC_DRT_SEQUENCE_END = 0,
    HAL_ADC_DRT_GROUP_END = 1,
    HAL_ADC_DRT_FIFO_GE_1 = 2,
    HAL_ADC_DRT_FIFO_GE_4 = 3,
    HAL_ADC_DRT_FIFO_GE_8 = 4,
    HAL_ADC_DRT_FIFO_GE_16 = 5,
    HAL_ADC_DRT_CUSTOM = 7,
} hal_adc_drt_t;

说明:

  • SEQ0 只支持 HAL_ADC_DRT_SEQUENCE_END 和 HAL_ADC_DRT_CUSTOM。

  • HAL_ADC_DRT_GROUP_END 仅对 SEQ1 连续组模式有效。

  • FIFO阈值触发仅对 SEQ1、SEQ2 有效。

HAL 枚举值与 LL 写寄存器时使用的编码并不完全相同,调用 LL 接口时不要直接套用 HAL 数值:

HAL类型HAL_ADC_DRT_* 值ll_adc_seq0_data_ready_type_set()ll_adc_seq1/2_data_ready_type_set()
HAL_ADC_DRT_SEQUENCE_END000
HAL_ADC_DRT_GROUP_END1不支持1
HAL_ADC_DRT_FIFO_GE_1/4/8/162/3/4/5不支持2/3/4/5
HAL_ADC_DRT_CUSTOM717

LL函数只负责写入编码,不校验sequence与模式的组合是否有效;例如编码值1可由SEQ2的LL接口写入,但HAL不支持SEQ2组结束模式。

3.4 HAL 错误标志

typedef enum {
    HAL_ADC_ERROR_NONE = 0U,
    HAL_ADC_ERROR_INVALID_PARAM = (1UL << 0U),
    HAL_ADC_ERROR_EOC_TIMEOUT = (1UL << 1U),
    HAL_ADC_ERROR_DATA_OVERRUN = (1UL << 2U),
    HAL_ADC_ERROR_EVENT_OVERRUN = (1UL << 3U),
    HAL_ADC_ERROR_PHY_EOC = (1UL << 4U),
    HAL_ADC_ERROR_DMA = (1UL << 5U),
} hal_adc_error_t;

说明:

  • 错误枚举值是bit flag,可按位或写入 hal_adc_handle_t.error_code。

  • 统一start路径中的DMA handle打开或传输启动失败时,HAL会记录 HAL_ADC_ERROR_DMA。

  • 普通HAL参数检查失败时直接返回 IM_ERR_INVALID_PARAM,当前实现不会因该次调用把 HAL_ADC_ERROR_INVALID_PARAM 锁存到 error_code。

  • hal_adc_error_get() 在 hadc 或其 instance 无效时返回 HAL_ADC_ERROR_INVALID_PARAM,这一返回值是无效handle的结果,不代表发生了已锁存的参数错误。

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

4.1 通道和序列长度

序列最大转换次数通道范围说明
SEQ040~7软件触发,数据在 seq0_dr[2]。
SEQ180~7LL层当前开放rank 0~7,支持FIFO/DMA/连续/组连续。
SEQ280~7支持FIFO/DMA/延时扫描。

4.2 模式组合

配置项SEQ0SEQ1SEQ2
软件触发支持支持支持
TCU触发不支持支持支持
PWM0触发不支持支持支持
PWM1触发不支持支持支持
延时扫描不支持支持支持
连续转换不支持支持不支持
组连续转换不支持支持不支持
DMA不支持支持支持
FIFO不支持深度16深度16

4.3 AWD 阈值

参数约束
channel0~7。
low_threshold0~0x0FFF。
high_threshold0~0x0FFF。
阈值关系必须 low_threshold <= high_threshold,HAL参数校验不满足时返回 IM_ERR_INVALID_PARAM。
low_flagsbit07对应通道07低阈值触发;建议使用 HAL_ADC_AWD_CHANNEL_FLAG()。
high_flagsbit07对应通道07高阈值触发;建议使用 HAL_ADC_AWD_CHANNEL_FLAG()。

4.4 配置修改时机与资源所有权

HAL 不会在所有配置接口中统一检查“所有序列均已停止”。调用方必须根据下表保证时序:

接口或资源HAL 当前检查调用方责任
hal_adc_sequence_config()检查目标sequence的HAL active、DMA active和硬件busy状态仅在该sequence空闲时重新配置。
hal_adc_start() / hal_adc_start_multi()检查目标sequence active、硬件busy、软件触发和DMA状态不应重复启动仍在活动的sequence。
hal_adc_clock_config()只校验分频范围,不检查序列忙状态在修改ADC转换/延时时钟前停止所有相关序列。
hal_adc_priority_config()只校验优先级和break参数,不检查序列忙状态在修改抢占配置前停止所有相关序列。
hal_adc_soc_extra_cycle_config()校验离散编码,不检查序列忙状态SPEC要求任一序列运行期间不得修改 SOC_EXT_CYCLE。
ll_adc_soc_extra_cycle_set()不校验编码和序列忙状态调用方只能传入合法离散编码,并保证所有序列已停止。
hal_adc_sequence_unstorage_config()不检查目标sequence是否活动先停止目标SEQ1/SEQ2,再修改storage mask。
dma_buffer / dma_desc配置阶段校验地址、长度、对齐和descriptor约束存储始终由调用方持有,生命周期必须覆盖DMA配置、运行和停止阶段。
IRQ_SADC0 / IRQ_SADC1HAL只处理ADC寄存器中断PLIC、CPU中断入口/退出和IRQ生命周期由BSP或中断框架负责。

5. 示例程序与使用方式

5.1 示例程序索引与接入方式

ADC示例只位于 code/examples。这些文件不会自动编译进主固件,应用需要将选定的 .c 文件显式加入自身构建目标;示例用于说明调用方式,不属于与HAL/LL同等级的稳定二进制接口。

示例层级调用入口覆盖内容
adc_polling_example.cHALexample_adc_sample_run()、example_adc_sample_run_on()单通道采样、SEQ0/SEQ1/SEQ2轮询、多序列启动。
hal_adc_dma_example.cHALexample_hal_adc_dma_run()SEQ1/SEQ2循环DMA、ADC DMA完成中断和回调。
hal_adc_dma_loop_example.cHALexample_hal_adc_dma_loop_run()、example_hal_adc_dma_loop_soak_get_default_config()、example_hal_adc_dma_loop_soak_run()多轮DMA、停止后重启和长时间运行观察;SADC时钟由调用方配置。
tcu_trig_adc_example.cHALexample_tcu_trig_adc0_run()、example_tcu_trig_adc1_run()SEQ1 TCU外部触发,TCU channel 0 HALF/FULL输出分别触发ADC0/ADC1。
adc_seq_example.cLLexample_adc_seq_sample_run()直接配置寄存器,完成SEQ0/SEQ1/SEQ2软件触发轮询和寄存器dump。

接入方式:

  1. HAL示例需要包含 hal_adc.h 并启用 CONFIG_DRIVER_ADC;再按示例实际使用的功能启用GPIO、TCU、IRQ等驱动。CONFIG_DRIVER_ADC 会自动选择 CONFIG_DRIVER_DMA;示例本身不调用CPM HAL,SADC时钟由调用方准备。

  2. LL示例需要包含 ll_adc.h,不需要链接ADC HAL。

  3. 示例未提供独立公共头文件时,应用应显式把示例 .c 加入构建目标,并在应用侧声明需要调用的入口函数;不要同时编译和包含同一个 .c 文件,避免重复定义。

  4. 调用示例前完成2.1节中的时钟、引脚、IRQ、systick和模拟信号准备。不同示例覆盖的前置条件不同,以各文件头部说明为准。

本文列出的 ADC HAL/LL 示例都不配置CPM,SADC源时钟和门控由板级代码或调用方预先建立;示例中的GPIO配置只负责把目标GPIOC引脚切到function 0。

5.2 单通道轮询采样

hal_adc_handle_t hadc0;
uint32_t value;
error_code_t ret;

ret = hal_adc_handle_init(&hadc0, ADC0);
if (ret != IM_OK) {
    return ret;
}

hadc0.init.adc_clk_div = 2U;
hadc0.init.soc_extra_cycle = (uint8_t)HAL_ADC_SOC_EXTRA_CYCLE_0;
ret = hal_adc_init(&hadc0);
if (ret != IM_OK) {
    return ret;
}

ret = hal_adc_channel_value_get(&hadc0, 0U, &value, 1000000U);