RISCV_ADCMP使用参考
REVISION HISTORY¶
Revision No. | Description |
Date |
---|---|---|
1.0 | 09/06/2024 | |
1.1 | 04/10/2025 | |
1.2 | 05/15/2025 |
1. 概述¶
逐次逼近型模数转换器(Successive Approximation ADC)采用的是一种反馈比较型电路结构。实现方式简要概述为:取一个数字量加到DAC上,可得到一个对应的输出模拟电压,将这个模拟电压和输入的模拟电压信号相比较,如果两者不相等,则调整所取的数字量,直到两个模拟电压相等为止,最后所取的这个数字量就是所求的转换结果。
2. 关键字说明¶
-
ADCLP
Analog-to-digital converter Low Precision,低精度(10bit)模数转换器
-
ADCMP
Analog-to-digital converter Medium Precision,中精度(12bit)模数转换器
-
regular/inject
不同的adc通道可以选择按不同的采样顺序加入regular序列或者inject序列,inject序列采样优先级高于regular序列
-
基准电压
用于模数转换计算时使用的参考电压,也是最大量程,若基准电压设定为1.8v,当外部输入电压>=1.8v时,数字量达到最大值4095
3. 功能描述¶
SAR ADCMP采样精度为12bit,硬件设计为2组,下文使用group0和group1区分,其中group0属于pm domain,group1属于nonpm domain
3.1. group0功能描述¶
-
支持22个adc通道采样,可同时使用regular序列及inject序列
-
regular序列最多配置23个adc通道(group0共计22个通道,富余的1个通道可以选择不配置,也可以选择配置为重复的通道),inject序列最多配置12个adc通道(采样优先级大于regular序列,但非dma模式下不建议与regular序列的通道重合)
-
regular序列支持15种采样触发方式,inject序列支持14种采样触发方式
-
采样频率 = 时钟源 / 16,可选时钟源为24M和12M(采样频率的倒数为硬件上采集一个数据点的时间)
-
支持1.5V、1.8V共计2个档位基准电压
3.2. group1功能描述¶
-
支持2个adc通道采样,且不可同时使用regular序列及inject序列,只能二选一
-
regular序列最多配置23个adc通道(group1共计2个通道,富余的21个通道可以选择不配置,也可以选择配置为重复的通道),inject序列最多配置12个adc通道(富余的10个通道可以选择不配置,也可以选择配置为重复的通道,但不支持与regular序列同时使用)
-
regular序列支持3种采样触发方式,inject序列支持2种采样触发方式
-
采样频率 = 时钟源 / N,可选时钟源为80M、24M、12M、6M;当采样模式为conversion时, N=15;当采样模式为sequence时, N=16(采样频率的倒数为硬件上采集一个数据点的时间)
-
支持1.8V的基准电压
3.3. 触发方式说明¶
adcmp支持的触发方式汇总:
NO. | 触发方式 | group0-regular | group0-inject | group1-regular | group1-inject |
---|---|---|---|---|---|
0 | pwm12_out_p | ||||
1 | pwm12_out_n | ||||
2 | pwm13_out_p | ||||
3 | pwm13_out_n | ||||
4 | pwm14_out_p | ||||
5 | pwm14_out_n | ||||
6 | pwm15_out_p | ||||
7 | pwm15_out_n | ||||
8 | pwm16_out_p | ||||
9 | pwm16_out_n | ||||
10 | pwm17_out_p | ||||
11 | pwm17_out_n | ||||
12 | sw trigger | ||||
13 | external trigger | ||||
14 | freerun |
pwm_out_p:基于dead time设定后生成的正向PWM波,regular序列的采样时机是pwm_out_p波形的上升沿,inject序列的采样时机是pwm周期的起点,如图所示:
pwm_out_n:基于dead time设定后生成的反向PWM波,regular序列的采样时机是pwm_out_n波形的上升沿,inject序列的采样时机是pwm周期的起点,如图所示:
sw trigger:通知指令下达至寄存器,一次指令trigger后硬件执行一次采样
external trigger:指定PIN脚,拉低拉高后触发上升沿脉冲后硬件执行一次采样
freerun:不间断采样,采样方法如果是conversion,那么支持采样多个数据并输出平均值,同时可设定采样间隔
3.4. 采样方法说明¶
adcmp采样可选择conversion和sequence两种不同的方法
conversion:每次触发源会触发硬件采样一个通道
- conversion + pwm_out_p触发源:每个pwm周期的上升沿触发一次采样并采集一个通道的数据
- conversion + sw trigger触发源:每执行一次sw trigger,触发一次采样并采集一个通道的数据
- conversion + external trigger触发源:每执行一次external trigger,触发一次采样并采集一个通道的数据
- conversion + freerun触发源:触发一次后进行不间断采样,支持平均采样和设定每个通道的硬件采样间隔
sequence:每次触发源会触发硬件采样一整个序列的所有通道
- sequence + pwm_out_p触发源:每个pwm周期的上升沿触发一次采样并采集一整个序列所有通道的数据
- sequence + sw trigger触发源:每执行一次sw trigger,触发一次采样并采集一整个序列所有通道的数据
- sequence + external trigger触发源:每执行一次external trigger,触发一次采样并采集一整个序列所有通道的数据
- sequence + freerun触发源:触发一次后进行不间断采样,不支持平均采样,也不支持设定每个通道的硬件采样间隔
3.5. 计算说明¶
SAR ADCMP的主要功能是将模拟信号转换为相应的数字信号,即可以将输入电压转换为数字量存储于寄存器中,通过公式计算出输入电压,
计算公式:电压 = ( 寄存器数值 / 采样精度12bit )* 基准电压
即如果读到的数值是0x4B0,可得电压为0x4B0/0xFFF *1.8=0.53v左右
4. 硬件连接介绍¶
SAR ADCMP不同group下的不同通道与PAD的对应关系:
Group0 Channel Index | Pad Name |
---|---|
0 | PAD_SAR_ADC0_00 |
1 | PAD_SAR_ADC0_01 |
2 | PAD_SAR_ADC0_02 |
3 | PAD_SAR_ADC0_03 |
4 | PAD_SAR_ADC0_04 |
5 | PAD_SAR_ADC0_05 |
6 | PAD_SAR_ADC0_06 |
7 | PAD_SAR_ADC0_07 |
8 | PAD_SAR_ADC0_08 |
9 | PAD_SAR_ADC0_09 |
10 | PAD_SAR_ADC0_10 |
11 | PAD_SAR_ADC0_11 |
12 | PAD_SAR_ADC0_12 |
13 | PAD_SAR_ADC0_13 |
14 | PAD_SAR_ADC0_14 |
15 | PAD_SAR_ADC0_11 |
16 | PAD_PM_GPIO0 |
17 | PAD_PM_GPIO1 |
18 | PAD_PM_GPIO3 |
19 | PAD_PM_GPIO6 |
20 | PAD_PM_ADC00_IN |
21 | PAD_PM_GPIO7 |
Group1 Channel Index | Pad Name |
---|---|
0 | PAD_PWM_OUT00 |
1 | PAD_PWM_OUT01 |
以PAD_SAR_ADC0_00为例,硬件连接时,查看原理图定位引脚位置,将外部电压接入引脚PAD_SAR_ADC0_00,如下图所示:
5. RISCV用法介绍¶
5.1. DRIVER PATH¶
sc/driver/sysdriver/saradc/os/adcmp_os.h sc/driver/sysdriver/saradc/drv/pub/drv_adcmp.h sc/driver/sysdriver/saradc/drv/src/drv_adcmp.c sc/driver/sysdriver/saradc/drv/src/drv_adcmp_test.c sc/driver/sysdriver/saradc/hal/chipname/src/hal_adcmp.c sc/driver/sysdriver/saradc/hal/chipname/inc/hal_adcmp.h sc/driver/sysdriver/saradc/hal/chipname/inc/hal_adcmp_cfg.h
5.2. CONFIG配置¶
config文件位于mak/options_chipname_riscv_isw.mak
,使能CONFIG_SARADC_SUPPORT
# Feature_Name = [DRV] SARADC driver support # Description = SARADC driver support # Option_Selection = TRUE, FALSE CONFIG_SARADC_SUPPORT = TRUE
5.3. SYSDESC配置¶
chipname_xxx.sys
文件是用于描述外设硬件属性的文件,外设节点中包含的属性值可用于外设的配置,类似Linux的设备树,该文件位于sc/driver/sysdriver/sysdesc/hal/chipname/pub
<adcmp0> [reg_u32] 0x200AC00, 0x200AE00, 0x2003C00, 0x2204600, 0x2203E00; [interrupts_u32] INT_PM_FIQ_ADCMP; [camclk_u16] CAMCLK_pm_pwm_adc; [interrupts_en_u8] 0; [dma_en_u8] 0; [dma_count_u32] 50; [clk_level_u8] 0; [ref_vol_u32] 1800; [regular_method_u8] 0; [inject_method_u8] 0; [regular_ch_u8] 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11; [inject_ch_u8] 12, 13, 14, 15, 16, 17, 18, 19, 20, 21; [upper_bound_u16] 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,0xFFFF, 0xFFFF; [lower_bound_u16] 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; [status_u8] 0; <adcmp1> [reg_u32] 0x2203600, 0x2203A00, 0x2200E00, 0x2204600, 0x2203E00; [interrupts_u32] INT_FIQ_ADCMP; [camclk_u16] CAMCLK_pwm_adc; [interrupts_en_u8] 0; [dma_en_u8] 0; [dma_count_u32] 50; [clk_level_u8] 3; [ref_vol_u32] 1800; [regular_method_u8] 0; [inject_method_u8] 0; [regular_ch_u8] 0, 1; [upper_bound_u16] 0xFFFF, 0xFFFF; [lower_bound_u16] 0, 0; [status_u8] 0;
属性 | 描述 | 设定值 | 备注 |
---|---|---|---|
reg_u32 | 设定寄存器bank地址 | 禁止修改 | |
interrupts_u32 | 绑定中断号 | INT_PM_FIQ_ADCMP & INT_FIQ_ADCMP | 禁止修改 |
camclk_u16 | 设定时钟源 | CAMCLK_pm_pwm_adc & CAMCLK_pwm_adc | 禁止修改 |
interrupts_en_u8 | 使能中断 | 1:enable,0:disable | 可根据需要修改 |
dma_en_u8 | 使能dma | 1:enable,0:disable, 使用dma需要先使能中断 | 可根据需要修改 |
dma_count_u32 | dma采样数量 | 必须是偶数 | 可根据需要修改 |
ref_vol_u32 | 设定基准电压挡位 | 以mv为单位,group0可选1500、1800,group1只能设定1800 | 可根据需要修改 |
clk_level_u8 | 设定时钟源 | 可切换时钟源变更采样时间,group0可选0->24M、1->12M,group1可选0->24M、1->12M、2->6M、3->80M | 可根据需要修改 |
regular_method_u8 | 设定regular序列的采样模式 | 0:conversion, 1:sequence | 可根据需要修改 |
inject_method_u8 | 设定inject序列的采样模式 | 0:conversion, 1:sequence | 可根据需要修改 |
regular_ch_u8 | 设定regular序列的adc采样通道 | 最多设定23个adc通道,按照采样顺序从左至右排列 | 可根据需要修改 |
inject_ch_u8 | 设定inject序列的adc采样通道 | 最多设定12个adc通道,按照采样顺序从左至右排列 | 可根据需要修改 |
upper_bound_u16 | 设定阈值上限电压 | 0~0xFFFF | 可根据需要修改 |
lower_bound_u16 | 设定阈值下限电压 | 0~0xFFFF | 可根据需要修改 |
status | 是否使能驱动 | 1:enable,0:disable | 可根据需要修改 |
以DMA采样功能举例,若按照如下DTS配置:
<adcmp0> ...... [interrupts_u32] INT_PM_FIQ_ADCMP; [camclk_u16] CAMCLK_pm_pwm_adc; [interrupts_en_u8] 1; //DMA功能必须使能中断 [dma_en_u8] 1; //使能DMA [dma_count_u32] 200; //每次触发采样,会连续采集200个ADC数据 [clk_level_u8] 0; [ref_vol_u32] 1800; [regular_method_u8] 0; [inject_method_u8] 0; [regular_ch_u8] 0, 1, 2, 3, 4, 5; [inject_ch_u8] 12, 13, 14, 15; ......
影响DMA采样结果的配置如下:
[clk_level_u8] 0
:采样频率 = 24M / 16 = 1.5M hz,因此每个ADC数据的采样间隔 = 1000000000 / 1.5M = 667ns
[dma_count_u32] 200
:每次DMA触发后采集200个ADC数据,因此每次DMA触发后硬件采样的总时间为667ns * 200 = 133400ns
[regular_ch_u8] 0, 1, 2, 3, 4, 5; [inject_ch_u8] 12, 13, 14, 15;
:采集的200个数据中包含了channel0、1、2、3、4、5、12、13、14、15的ADC数据,
由于inject序列优先级更高,因此采样结果按照channel 12 -> channel 13 -> channel 14 -> channel 15 -> channel 0 -> channel 1 -> channel 2 -> channel 3 -> channel 4 -> channel 5....
顺序排列
<adcmp1> ...... [interrupts_u32] INT_FIQ_ADCMP; [camclk_u16] CAMCLK_pwm_adc; [interrupts_en_u8] 1; //DMA功能必须使能中断 [dma_en_u8] 1; //使能DMA [dma_count_u32] 400; //每次触发采样,会连续采集400个ADC数据 [clk_level_u8] 3; [ref_vol_u32] 1800; [regular_method_u8] 1; [regular_ch_u8] 0, 1; ......
影响DMA采样结果的配置如下:
[clk_level_u8] 3; [regular_method_u8] 1;
:采样频率 = 80M / 16 = 5M hz (如果regular-method = <0>, 那么采样频率 = 80M / 15 = 5.33M hz) ,因此每个ADC数据的采样间隔 = 1000000000 / 5M = 200ns
[dma_count_u32] 400
:每次DMA触发后采集400个ADC数据,因此每次DMA触发后硬件采样的总时间为200ns * 400 = 80000ns
[regular_ch_u8] 0, 1
:采集的400个数据中包含了channel0和channle1的ADC数值,按照channel 0 -> channel 1 -> channel 0 -> channel 1 -> ....
顺序排列
5.4. PADMUX配置¶
CONFIG配置:CONFIG_PADMUX_SUPPORT=TRUE
如果chipname_xxx.sys
文件配置了属性<padmux>
,那么PADMUX的设定直接在此配置:
<padmux> [schematic_u32_u32_u32] //pm adc 22ch PAD_SAR_ADC0_00 PINMUX_FOR_PMADC0_MODE_1 MDRV_PUSE_PWMADC0, PAD_SAR_ADC0_01 PINMUX_FOR_PMADC1_MODE_1 MDRV_PUSE_PWMADC1, PAD_SAR_ADC0_02 PINMUX_FOR_PMADC2_MODE_1 MDRV_PUSE_PWMADC2, PAD_SAR_ADC0_03 PINMUX_FOR_PMADC3_MODE_1 MDRV_PUSE_PWMADC3, PAD_SAR_ADC0_04 PINMUX_FOR_PMADC4_MODE_1 MDRV_PUSE_PWMADC4, PAD_SAR_ADC0_05 PINMUX_FOR_PMADC5_MODE_1 MDRV_PUSE_PWMADC5, PAD_SAR_ADC0_06 PINMUX_FOR_PMADC6_MODE_1 MDRV_PUSE_PWMADC6, PAD_SAR_ADC0_07 PINMUX_FOR_PMADC7_MODE_1 MDRV_PUSE_PWMADC7, PAD_SAR_ADC0_08 PINMUX_FOR_PMADC8_MODE_1 MDRV_PUSE_PWMADC8, PAD_SAR_ADC0_09 PINMUX_FOR_PMADC9_MODE_1 MDRV_PUSE_PWMADC9, PAD_SAR_ADC0_10 PINMUX_FOR_PMADC10_MODE_1 MDRV_PUSE_PWMADC10, PAD_SAR_ADC0_11 PINMUX_FOR_PMADC11_MODE_1 MDRV_PUSE_PWMADC11, PAD_SAR_ADC0_12 PINMUX_FOR_PMADC12_MODE_1 MDRV_PUSE_PWMADC12, PAD_SAR_ADC0_13 PINMUX_FOR_PMADC13_MODE_1 MDRV_PUSE_PWMADC13, PAD_SAR_ADC0_14 PINMUX_FOR_PMADC14_MODE_1 MDRV_PUSE_PWMADC14, PAD_PM_GPIO0 PINMUX_FOR_PMADC15_MODE_1 MDRV_PUSE_PWMADC15, PAD_PM_GPIO1 PINMUX_FOR_PMADC16_MODE_1 MDRV_PUSE_PWMADC16, PAD_PM_GPIO2 PINMUX_FOR_PMADC17_MODE_1 MDRV_PUSE_PWMADC17, PAD_PM_GPIO3 PINMUX_FOR_PMADC18_MODE_1 MDRV_PUSE_PWMADC18, PAD_PM_GPIO6 PINMUX_FOR_PMADC19_MODE_1 MDRV_PUSE_PWMADC19, PAD_PM_ADC00_IN PINMUX_FOR_PMADC20_MODE_1 MDRV_PUSE_PWMADC20, PAD_PM_GPIO7 PINMUX_FOR_PMADC21_MODE_1 MDRV_PUSE_PWMADC21, PAD_PM_PWM0_OUT PINMUX_FOR_PM_ADC_INT_MODE_2 MDRV_PUSE_PMPWMADC_INT, //non pm adc 2ch PAD_PWM_OUT00 PINMUX_FOR_ADC0_MODE_1 MDRV_PUSE_PWMADC22, PAD_PWM_OUT01 PINMUX_FOR_ADC1_MODE_1 MDRV_PUSE_PWMADC23, PAD_GPIOA_12 PINMUX_FOR_PWM_INT_MODE_1 MDRV_PUSE_PWMADC_INT, PAD_GPIOA_13 PINMUX_FOR_PWM_INT_MODE_1 MDRV_PUSE_PWMOUT_INT; [status_u8] 1;
否则通过使能PADMUX驱动,在chipname-xxx-padmux.c
文件配置引脚复用功能,该文件位于sc/driver/sysdriver/padmux/hal/chipname/src
,只需要在对应的schematic
属性添加如下内容中设定:
pad_info_t schematic[] = { //pm adc 22ch {PAD_SAR_ADC0_00 PINMUX_FOR_PMADC0_MODE_1 MDRV_PUSE_PWMADC0}, {PAD_SAR_ADC0_01 PINMUX_FOR_PMADC1_MODE_1 MDRV_PUSE_PWMADC1}, {PAD_SAR_ADC0_02 PINMUX_FOR_PMADC2_MODE_1 MDRV_PUSE_PWMADC2}, {PAD_SAR_ADC0_03 PINMUX_FOR_PMADC3_MODE_1 MDRV_PUSE_PWMADC3}, {PAD_SAR_ADC0_04 PINMUX_FOR_PMADC4_MODE_1 MDRV_PUSE_PWMADC4}, {PAD_SAR_ADC0_05 PINMUX_FOR_PMADC5_MODE_1 MDRV_PUSE_PWMADC5}, {PAD_SAR_ADC0_06 PINMUX_FOR_PMADC6_MODE_1 MDRV_PUSE_PWMADC6}, {PAD_SAR_ADC0_07 PINMUX_FOR_PMADC7_MODE_1 MDRV_PUSE_PWMADC7}, {PAD_SAR_ADC0_08 PINMUX_FOR_PMADC8_MODE_1 MDRV_PUSE_PWMADC8}, {PAD_SAR_ADC0_09 PINMUX_FOR_PMADC9_MODE_1 MDRV_PUSE_PWMADC9}, {PAD_SAR_ADC0_10 PINMUX_FOR_PMADC10_MODE_1 MDRV_PUSE_PWMADC10}, {PAD_SAR_ADC0_11 PINMUX_FOR_PMADC11_MODE_1 MDRV_PUSE_PWMADC11}, {PAD_SAR_ADC0_12 PINMUX_FOR_PMADC12_MODE_1 MDRV_PUSE_PWMADC12}, {PAD_SAR_ADC0_13 PINMUX_FOR_PMADC13_MODE_1 MDRV_PUSE_PWMADC13}, {PAD_SAR_ADC0_14 PINMUX_FOR_PMADC14_MODE_1 MDRV_PUSE_PWMADC14}, {PAD_PM_GPIO0 PINMUX_FOR_PMADC15_MODE_1 MDRV_PUSE_PWMADC15}, {PAD_PM_GPIO1 PINMUX_FOR_PMADC16_MODE_1 MDRV_PUSE_PWMADC16}, {PAD_PM_GPIO2 PINMUX_FOR_PMADC17_MODE_1 MDRV_PUSE_PWMADC17}, {PAD_PM_GPIO3 PINMUX_FOR_PMADC18_MODE_1 MDRV_PUSE_PWMADC18}, {PAD_PM_GPIO6 PINMUX_FOR_PMADC19_MODE_1 MDRV_PUSE_PWMADC19}, {PAD_PM_ADC00_IN PINMUX_FOR_PMADC20_MODE_1 MDRV_PUSE_PWMADC20}, {PAD_PM_GPIO7 PINMUX_FOR_PMADC21_MODE_1 MDRV_PUSE_PWMADC21}, {PAD_PM_PWM0_OUT PINMUX_FOR_PM_ADC_INT_MODE_2 MDRV_PUSE_PMPWMADC_INT}, //non pm adc 2ch {PAD_PWM_OUT00 PINMUX_FOR_ADC0_MODE_1 MDRV_PUSE_PWMADC22}, {PAD_PWM_OUT01 PINMUX_FOR_ADC1_MODE_1 MDRV_PUSE_PWMADC23}, {PAD_GPIOA_12 PINMUX_FOR_PWM_INT_MODE_1 MDRV_PUSE_PWMADC_INT}, {PAD_GPIOA_13 PINMUX_FOR_PWM_INT_MODE_1 MDRV_PUSE_PWMOUT_INT}, };
第一列为引脚索引号,可以在sc/drivers/sysdriver/gpio/hal/chipname/pub/gpio.h
中查询;
第二列为模式定义,可以在sc/drivers/sysdriver/gpio/hal/chipname/pub/padmux.h
中查询;
第三列为引脚及搭配模式的索引名称,可以在sc/drivers/sysdriver/padmux/drv/pub/drv_puse.h
中查询;
5.5. Sample Code¶
demo源码位于sc/driver/sysdriver/saradc/drv/src/drv_adcmp_test.c
其中需要注意dma采样时的调用顺序:drv_adcmp_set_config()->drv_adcmp_register_callback()->drv_adcmp_dma_sample_trigger()->回调函数中调用drv_adcmp_dma_sample_data()
6. API参考¶
头文件位于sc/driver/sysdriver/saradc/drv/pub/drv_adcmp.h
struct adcmp_bound { u8 channel; //指定adc通道 u8 bound_en; //使能阈值监测功能 u16 lower_bd; //阈值下限 u16 upper_bd; //阈值上限 }; struct adcmp_config { u8 inje_en; //使能inject序列采样功能 u8 inje_mod; //inject序列采样触发方式 u8 regu_en; //使能regular序列采样功能 u8 regu_mod; //regular序列采样触发方式 u8 avg_cnt; //freerun时获取平均值的采样数量 u32 p_delay; //inject采样时pwm out p trigger的delay时间 u32 n_delay; //inject采样时pwm out n trigger的delay时间 u16 sample_time; //freerun延长的采样间隔(仅支持coversion下使用),若sample time = N,最终的采样间隔时间 = 基础采样时间 + 延长采样时间 = (1 / (时钟源 / 16)) + ( N / (时钟源 / 4)) }; typedef s32 (*adcmp_cb_t)(u8 group); int drv_adcmp_get_ref_vol(u8 group, u32 *voltage); int drv_adcmp_set_bound(struct adcmp_bound *adcmp_bd, u8 group); int drv_adcmp_set_config(struct adcmp_config *adcmp_cfg, u8 group); int drv_adcmp_get_config(struct adcmp_config *adcmp_cfg, u8 group); int int drv_adcmp_direct_read_ch(u8 group, u8 channel, u16 *value)(u8 group, u8 channel, u16 *value); int drv_adcmp_direct_read_seq(u8 group, u8 linear_map, u16 *value); int drv_adcmp_sample_channel(u8 group, u8 channel, u16 *value); int drv_adcmp_sample_sequence(u8 group, u16 *value); int drv_adcmp_sample_seq_linear_map(u8 group, u16 *value); int drv_adcmp_dma_sample_trigger(u8 group); int drv_adcmp_dma_sample_stop(u8 group); int drv_adcmp_dma_sample_data(u8 group, u16 *value); int drv_adcmp_register_callback(u8 group, adcmp_cb_t cb_t); int drv_adcmp_unregister_callback(u8 group, adcmp_cb_t cb_t);
API名称 | 功能 |
---|---|
drv_adcmp_get_ref_vol | 获取当前使用的基准电压 |
drv_adcmp_set_bound | 设定指定通道的阈值 |
drv_adcmp_set_config | 设定采样属性 |
drv_adcmp_get_config | 获取采样属性 |
drv_adcmp_direct_read_ch | 直接获取指定单个通道的外部输入电压数字量,不保证实时性 |
drv_adcmp_direct_read_seq | 在不使能dma时,直接获取regular序列所有通道的外部输入电压数字量,不保证实时性 |
drv_adcmp_sample_channel | 实时获取指定单个通道的外部输入电压数字量 |
drv_adcmp_sample_sequence | 在不使能dma时,实时获取sysdesc指定所有通道的外部输入电压数字量 |
drv_adcmp_sample_seq_linear_map | 在不使能dma时,实时获取sysdesc指定所有通道的外部输入电压数字量,并将通道和数据做线性映射 |
drv_adcmp_dma_sample_trigger | 触发dma模式下的采样功能 |
drv_adcmp_dma_sample_stop | 停止dma模式下的采样功能 |
drv_adcmp_dma_sample_data | 获取dma模式下的采样结果 |
drv_adcmp_register_callback | 注册指定group的回调函数 |
drv_adcmp_unregister_callback | 释放指定group的回调函数和注册时申请的内存 |
6.1. drv_adcmp_set_bound¶
-
目的
设定adcmp指定通道的阈值范围
-
语法
int drv_adcmp_set_bound(struct adcmp_bound *adcmp_bd, u8 group)
-
参数
参数名称 描述 adcmp_bd 用于使能及配置adcmp指定通道的阈值上下限 group 指定adcmp group -
返回值
结果 描述 成功 返回0 失败 返回负数
6.2. drv_adcmp_set_config¶
-
目的
设定adcmp的采样属性
-
语法
int drv_adcmp_set_config(struct adcmp_config *adcmp_cfg, u8 group)
-
参数
参数名称 描述 adcmp_cfg 配置adcmp的采样属性 group 指定adcmp group -
返回值
结果 描述 成功 返回0 失败 返回负数
6.3. drv_adcmp_get_config¶
-
目的
获取adcmp的采样属性,防止更新参数时其他属性被改变
-
语法
drv_adcmp_get_config(struct adcmp_config *adcmp_cfg, u8 group)
-
参数
参数名称 描述 adcmp_cfg 获取当前adcmp的采样属性 group 指定adcmp group -
返回值
结果 描述 成功 返回0 失败 返回负数
6.4. drv_adcmp_sample_channel¶
-
目的
获取指定单个通道的外部输入电压数字量
-
语法
int drv_adcmp_sample_channel(u8 group, u8 channel, u16 *value)
-
参数
参数名称 描述 group 指定adcmp group channel 指定通道,注意需要是sysdesc中属性 regular_ch_u8
和inject_ch_u8
的成员value 获取采样结果的指针 -
返回值
结果 描述 成功 返回0 失败 返回负数
6.5. drv_adcmp_sample_sequence¶
-
目的
在不使能dma时,获取sysdesc指定所有通道的外部输入电压数字量
-
语法
int drv_adcmp_sample_sequence(u8 group, u16 *value)
-
参数
参数名称 描述 group 指定adcmp group value 获取采样结果的指针, 先获取 inject_ch_u8
指定通道的采样值,后获取regular_ch_u8
指定通道的采样值 -
返回值
结果 描述 成功 返回0 失败 返回负数
6.6. drv_adcmp_dma_sample_trigger¶
-
目的
触发dma模式下的采样功能
-
语法
int drv_adcmp_dma_sample_trigger(u8 group)
-
参数
参数名称 描述 group 指定adcmp group -
返回值
结果 描述 成功 返回0 失败 返回负数
6.7. drv_adcmp_dma_sample_stop¶
-
目的
停止dma模式下的采样功能
-
语法
int drv_adcmp_dma_sample_stop(u8 group)
-
参数
参数名称 描述 group 指定adcmp group -
返回值
结果 描述 成功 返回0 失败 返回负数
6.8. drv_adcmp_dma_sample_data¶
-
目的
获取dma模式下的采样结果,注意每次刷新采样结果都需要先调用
drv_adcmp_dma_sample_trigger
-
语法
int drv_adcmp_dma_sample_data(u8 group, u16 *value)
-
参数
参数名称 描述 group 指定adcmp group value 获取dma采样结果的指针,先获取 inject-ch
指定通道的采样值,后获取regular-ch
指定通道的采样值 -
返回值
结果 描述 成功 返回0 失败 返回负数
6.9. drv_adcmp_register_callback¶
-
目的
注册指定group的回调函数,当dma采样完成后可在回调函数里调用
drv_adcmp_dma_sample_data
获取采样结果 -
语法
int drv_adcmp_register_callback(u8 group, adcmp_cb_t cb_t)
-
参数
参数名称 描述 group 指定adcmp group cb_t 函数指针 -
返回值
结果 描述 成功 返回0 失败 返回负数
6.10. drv_adcmp_unregister_callback¶
-
目的
释放指定group的回调函数和注册时申请的内存
-
语法
int drv_adcmp_unregister_callback(u8 group, adcmp_cb_t cb_t)
-
参数
参数名称 描述 group 指定adcmp group cb_t 函数指针 -
返回值
结果 描述 成功 返回0 失败 返回负数
6.11. drv_adcmp_get_ref_vol¶
-
目的
获取当前使用的基准电压
-
语法
int drv_adcmp_get_ref_vol(u8 group, u32 *voltage)
-
参数
参数名称 描述 group 指定adcmp group voltage 基准电压,以mv为单位 -
返回值
结果 描述 成功 返回0 失败 返回负数
6.12. drv_adcmp_direct_read_ch¶
-
目的
直接获取指定单个通道的外部输入电压数字量,与
drv_adcmp_sample_channel
区别在于direct read获取的结果不保证实时性,仅支持对regular序列的通道使用,且触发源不支持sw trigger和external trigger;硬件方面,regular序列的通道会按照既定顺序轮询采样,使用
drv_adcmp_sample_channel
会确保是当前周期的采样结果,drv_adcmp_direct_read_ch
可能是上一个周期,当前周期,或者下一周期的采样结果(一个采样周期=regular序列通道数量*(1 / 采样频率),不包括inject序列抢占所需的采样时间)常用场景一般为使用DMA采集大量数据时,可在DMA采样结束前先获取某个通道的数据
-
语法
int drv_adcmp_direct_read_ch(u8 group, u8 channel, u16 *value)
-
参数
参数名称 描述 group 指定adcmp group channel 指定通道,必须是sysdesc中属性 regular_ch_u8
的成员value 获取采样结果的指针 -
返回值
结果 描述 成功 返回0 失败 返回负数 -
注意事项
第一次使用之前或者每次调用
drv_adcmp_set_config
之后,都需要先调用一次drv_adcmp_sample_channel
ordrv_adcmp_dma_sample_trigger
触发采样;如果使用了
drv_adcmp_dma_sample_trigger
,drv_adcmp_direct_read_ch
只能获取DMA采样过程中的通道数据,当DMA采样结束后,drv_adcmp_direct_read_ch
拿到的数据不会更新,此时再调用drv_adcmp_sample_channel
即可恢复
6.13. drv_adcmp_direct_read_seq¶
-
目的
在不使能dma时,直接获取regular序列所有通道的外部输入电压数字量,与
drv_adcmp_sample_sequence
区别在于direct read获取的结果不保证实时性,仅支持对regular序列的通道使用,且触发源不支持sw trigger和external trigger;硬件方面,regular序列的通道会按照既定顺序轮询采样,使用
drv_adcmp_sample_sequence
会确保是当前周期的采样结果,drv_adcmp_direct_read_seq
可能是上一个周期,当前周期,或者下一周期的采样结果(一个采样周期=regular序列通道数量*(1 / 采样频率),不包括inject序列抢占所需的采样时间)常用场景一般为使用DMA采集大量数据时,可在DMA采样结束前先获取整个序列所有通道的数据
-
语法
int drv_adcmp_direct_read_seq(u8 group, u8 linear_map, u16 *value)
-
参数
参数名称 描述 group 指定adcmp group linear_map 0:value的数据排序根据sysdesc中 regular_ch_u8
定义的顺序,1:value的数据按照通道index从小到大排序,比如value[0]=channel 0 adc datavalue 获取采样结果的指针, 获取 regular_ch_u8
中所有通道的采样值 -
返回值
结果 描述 成功 返回0 失败 返回负数 -
注意事项
第一次使用之前或者每次调用
drv_adcmp_set_config
之后,都需要先调用一次drv_adcmp_sample_sequence
ordrv_adcmp_dma_sample_trigger
触发采样;如果使用了
drv_adcmp_dma_sample_trigger
,drv_adcmp_direct_read_seq
只能获取DMA采样过程中的通道数据,当DMA采样结束后,drv_adcmp_direct_read_seq
拿到的数据不会更新,此时再调用drv_adcmp_sample_sequence
即可恢复
6.14. drv_adcmp_sample_seq_linear_map¶
-
目的
在不使能dma时,实时获取sysdesc指定所有通道的外部输入电压数字量,并将通道和数据做线性映射
-
语法
int drv_adcmp_sample_seq_linear_map(u8 group, u16 *value)
-
参数
参数名称 描述 group 指定adcmp group value 获取采样结果的指针, value的数据按照通道index从小到大排序,比如value[0] = channel 0 adc data, value[1] = channel 1 adc data -
返回值
结果 描述 成功 返回0 失败 返回负数
7. FAQ¶
Q1:SAR ADCMP接口不存在
-
检查sysdes adcmp节点的
status_u8
是否为1
-
检查config是否配置,详见[5.2. Config配置]
Q2:SAR ADCMP采样结果没有与外部电压同步变化
-
引脚设为GPIO mode进行output high/low的试验,如果无法拉高拉低则有可能是硬件问题
-
检查采样触发方式是否ready,比如pwm out p需要配置pwm dead time并使能,external trigger需要电平产生变化触发上升沿,尤其是inject序列的触发方式未启动,那么regular序列也无法采样
Q3:SAR ADCMP采样结果以256的倍数变化
当某一ADC通道对应的PIN脚输入电压大于参考电压时,前一个通道的采样会受到干扰,采样结果只能是256的倍数
<adcmp0> [reg_u32] 0x200AC00, 0x200AE00, 0x2003C00, 0x2204600, 0x2203E00; [interrupts_u32] INT_PM_FIQ_ADCMP; [camclk_u16] CAMCLK_pm_pwm_adc; [interrupts_en_u8] 0; [dma_en_u8] 0; [dma_count_u32] 50; [clk_level_u8] 0; [ref_vol_u32] 1800; [regular_method_u8] 0; [inject_method_u8] 0; [regular_ch_u8] 0 1 2 8 3 9 4 5 6 7 10 11 12 13 14 15 16 17 18 19 20 21; [upper_bound_u16] 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,0xFFFF, 0xFFFF; [lower_bound_u16] 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0; [status_u8] 1;
例如上述配置中,[ref_vol_u32]为1.8V,若通道8、通道9的输入电压大于1.8V,则通道2、通道3的采样结果会受到干扰,且只能是256的倍数。
Q4:SAR ADCMP 在超声波场景下DMA采样时获取不到有效数据"
此场景需求输出PWM波形(蓝色)后,电压(黄色)才产生变化;
如果没有报错,仅是采样数据不符合预期,需要查看DMA采样时机与电压变化时机是否匹配;
如果此时使用adcmp0,可以选择pwm_out的触发方式(0~11),采样起点在第一个PWM波形的上升沿,可以保证同步采完所有ADC数据;
如果此时使用adcmp1,由于没有pwm_out的触发方式,可以选择先trigger采样,然后在控制输出PWM波形,根据采样count控制采样总时长,也可采完所有ADC数据