ADCLP使用参考
REVISION HISTORY¶
Revision No. | Description |
Date |
---|---|---|
1.0 | 04/25/2024 | |
1.1 | 07/22/2024 |
1. 概述¶
逐次逼近型模数转换器(Successive Approximation ADC)采用的是一种反馈比较型电路结构。实现方式简要概述为:取一个数字量加到DAC上,可得到一个对应的输出模拟电压,将这个模拟电压和输入的模拟电压信号相比较,如果两者不相等,则调整所取的数字量,直到两个模拟电压相等为止,最后所取的这个数字量就是所求的转换结果。
2. 关键字说明¶
-
ADCLP
Analog-to-digital converter Low Precision,低精度(10bit)模数转换器
-
upper/lower bound
ADCLP可设置外部输入电压数字量的上下限,超出范围则触发中断
-
基准电压
用于模数转换计算时使用的参考电压,也是最大量程
3. 功能描述¶
-
SAR ADCLP共计4个Channel可支持外部输入电压的模数转换
-
采样精度为10bit,因此获取到的寄存器数值范围在0~0x3ff之间
-
支持两个档位的基准电压(即满量程)切换,分别为3.3V和2.0V
-
支持外部输入电压的阈值设定
-
采样时间为8667ns
4. 硬件连接介绍¶
如下图,可将外部电压接入引脚PAD_SAR_GPIO0~PAD_SAR_GPIO3
5. 计算说明¶
SAR ADCLP的主要功能是将模拟信号转换为相应的数字信号,即可以将输入电压转换为数字量存储于寄存器中,通过公式计算出输入电压,
计算公式:电压 = ( 寄存器数值 / 满量程 )* 基准电压
即如果读到的数值是0x1D2,可得电压为0x1D2/0x3FF *3.3=1.50v左右
6. Uboot用法介绍¶
6.1. Uboot Config配置¶
查看Kconfig可以看到支持ADCLP需要配置CONFIG_SSTAR_ADCLP、CONFIG_ADC、CONFIG_CMD_ADC,其中开启CONFIG_CMD_ADC需要先配置DM_REGULATOR
-
配置CONFIG_SSTAR_ADCLP
-
配置CONFIG_ADC
-
配置DM_REGULATOR
-
配置CONFIG_CMD_ADC
6.2. DTS配置¶
SAR ADCLP的DTS配置只需要在chipname.dtsi中配置如下信息:
adclp: adclp { compatible = "sstar,adclp"; reg = <0x1F002800 0x200>; chan-num = <5>; ref-voltage = <3300>; status = "okay"; };
SAR ADCLP DTS配置说明:
属性 | 描述 | 设定值 | 备注 |
---|---|---|---|
compatible | 匹配驱动进行驱动注册 | "sstar,sar" | 禁止修改 |
reg | 设定寄存器bank地址 | <0x1F002800 0x200> | 禁止修改 |
chan-num | 设定支持的通道数量 | 5 | 禁止修改 |
ref-voltage | 设定基准电压档位 | 以mv为单位,可选3300和2000 | 可根据需要修改 |
status | 选择是否使能驱动 | "okay" or "disable" | 可根据需要修改 |
6.3. Uboot cmd参数说明及使用实例¶
命令行输入adc:
①adc list → 可查看sar adclp是否有绑定
②adc info adclp → 可查看sar adclp支持的channel数量及data精度
如下图,目前支持的channel数量为5(注意区分mask为0x1f),最大data值为0x3ff
③adc single adclp [channel] → 可查看具体某个channel的data
如下图,channel 0的数值为605
根据公式:电压 = ( data / 0x3ff)* 基准电压
此时电压为605 / 1023 * 3.3 V = 1.95V
④adc scan adclp [channel mask] → 可查看多个channel的data
adc scan adclp :查看所有channel的data
adc scan adclp 0x3:查看channel 0和channel 1的data
7. Kernel用法介绍¶
7.1. Kernel Config配置¶
Device Drivers ---> [*] Sstar SoC platform drivers ---> <*> Sstar ADCLP driver
7.2. DTS配置¶
SAR ADCLP的DTS配置只需要在chipname.dtsi中配置如下信息:
adclp0: adclp0@1f002800 { compatible = "sstar,adclp"; interrupt-parent = <&sstar_pm_main_intc>; interrupts = <INT_PMSLEEP_IRQ_SAR_KP>; reg = <0x0 0x1F002800 0x0 0x200>; clocks = <&CLK_sar>; interrupt-enable; channel = <0>; ref-voltage = <3300>; upper-bound = <0x3FF>; lower-bound = <0>; status = "ok"; };
属性 | 描述 | 设定值 | 备注 |
---|---|---|---|
compatible | 匹配驱动进行驱动注册 | "sstar,adclp" | 禁止修改 |
interrupt-parent | 绑定中断控制器 | &sstar_pm_main_intc | 禁止修改 |
interrupts | 绑定中断号 | INT_PMSLEEP_IRQ_SAR_KP | 禁止修改 |
reg | 设定寄存器bank地址 | 0x1F002800 | 禁止修改 |
clocks | 设定时钟源 | &CLK_sar | 不需要更改 |
interrupt-enable | 使能中断 | bool类型,注释即disable | 可根据需要修改 |
channel | 设定通道 | 0~4 | 不需要更改 |
ref-voltage | 设定基准电压档位 | 以mv为单位,可选3300和2000 | 可根据需要修改 |
upper-bound | 设定阈值上限电压 | 0~0x3FF,使能中断有效 | 可根据需要修改 |
lower-bound | 设定阈值下限电压 | 0~0x3FF,使能中断有效 | 可根据需要修改 |
status | 是否使能驱动 | "ok" or "disable" | 可根据需要修改 |
7.3. Padmux配置¶
SAR-ADCLP无需进行padmux的配置,原理图上的PIN脚会默认配置为ADC采样功能
7.4. 模块使用介绍¶
7.4.1. SYSFS接口¶
-
进入SAR ADCLP采样的通道Channel 0
cd /sys/class/sstar/adclp0/
-
设定SAR ADCLP0的阈值(不设定阈值则使用默认值1023)
echo 800 400 > /sys/class/sstar/adclp0/threshold
-
使能SAR ADCLP0
echo 1 > enable
-
获取SAR ADCLP0采样后的数字量
cat /sys/class/sstar/adclp0/value
7.4.2. IOCTL使用方法¶
头文件<drv_adclp.h>
位于kernel/driver/sstar/sar目录下,
-
IOCTL_ADCLP_SET_BOUND
设定采样电压阈值
-
IOCTL_ADCLP_READ_VALUE
获取电压转换后的数字量
... struct adclp_bound { unsigned short upper_bound; unsigned short lower_bound; }; #define ADCLP_IOC_MAXNR 2 #define ADCLP_IOC_MAGIC 'a' #define IOCTL_ADCLP_SET_BOUND _IO(ADCLP_IOC_MAGIC, 0) #define IOCTL_ADCLP_READ_VALUE _IO(ADCLP_IOC_MAGIC, 1) ...
Sample code
源码位于kernel/driver/sstar/sar/ut/ut_adclp.c
#include <fcntl.h> #include <stdio.h> #include <errno.h> #include <signal.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <sys/types.h> #include <drv_adclp.h> void sample_warn(int num) { printf("adclp data exceeding the threshold\n"); } int main(int argc, char **argv) { int fd; char cmd; int flags; unsigned short value; unsigned int channel; char path[64]; struct adclp_bound adclp_bd; if (argc == 2) { channel = atoi(argv[1]); } else if (argc == 4) { channel = atoi(argv[1]); adclp_bd.upper_bound = atoi(argv[2]); adclp_bd.lower_bound = atoi(argv[3]); } else { printf("format: ut_adclp [channel] <upper> <lower>\n"); return -1; } snprintf(path, sizeof(path), "/dev/adclp%u", channel); fd = open((const char *)(char *)path, O_RDWR); if (fd < 0) { printf("open device fail\n"); return -1; } if (argc == 4) { ioctl(fd, IOCTL_ADCLP_SET_BOUND, &adclp_bd); } signal(SIGIO, sample_warn); fcntl(fd, F_SETOWN, getpid()); flags = fcntl(fd, F_GETFL); fcntl(fd, F_SETFL, flags | FASYNC); while (1) { cmd = getchar(); if (cmd == 'q' || cmd == 'Q') { break; } ioctl(fd, IOCTL_ADCLP_READ_VALUE, &value); printf("adclp%u data[%hu]\n", channel, value); } close(fd); return 0; }
7.4.3. 内核态API使用方法¶
头文件<drv_adclp.h>
位于kernel/driver/sstar/sar目录下,
... #ifdef __KERNEL__ #include <linux/list.h> enum adclp_vdd_type { ADCLP_VDD_CPU = 0, ADCLP_VDD_IPU, }; typedef int (*adclp_cb_t)(void *); struct adclp_cb { u32 chan; adclp_cb_t cb_t; struct list_head cb_node; }; int sstar_adclp_get_data(u8 channel); int sstar_adclp_enable(u8 channel, u8 enable); int sstar_adclp_vdd_power(enum adclp_vdd_type type); int sstar_adclp_set_bound(u8 channel, u16 max, u16 min); int sstar_adclp_register_callback(struct adclp_cb *para); int sstar_adclp_unregister_callback(struct adclp_cb *para); #endif ...
sstar_adclp_enable
-
目的
使能指定通道的采样功能
-
语法
int sstar_adclp_enable(u8 channel, u8 enable);
-
参数
参数名称 描述 channel 采样通道 enable 使能与否 -
返回值
返回值 描述 0 成功 非0 失败
sstar_adclp_get_data
-
目的
获取指定通道的外部输入电压数字量
-
语法
int sstar_adclp_get_data(u8 channel)
-
参数
参数名称 描述 channel 采样通道 -
返回值
返回值 描述 value 电压数字量
sstar_adclp_set_bound
-
目的
设定指定通道的阈值
-
语法
int sstar_adclp_set_bound(u8 channel, u16 max, u16 min)
-
参数
参数名称 描述 channel 采样通道 max 阈值上限 min 阈值下限 -
返回值
返回值 描述 0 成功 EINVAL 失败
sstar_adclp_register_callback
-
目的
注册指定通道的回调函数,可用于超出阈值后的中断处理
-
语法
sstar_adclp_register_callback(u8 channel, const adclp_cb_t cb)
-
参数
参数名称 描述 channel 采样通道 cb 函数指针 -
返回值
返回值 描述 0 成功 EINVAL 失败
sstar_adclp_unregister_callback
-
目的
释放指定通道的回调函数
-
语法
int sstar_adclp_unregister_callback(u8 channel, const adclp_cb_t cb)
-
参数
参数名称 描述 channel 采样通道 cb 函数指针 -
返回值
返回值 描述 0 成功 EINVAL 失败
7.5. Debug方法¶
7.5.1 SAR ADCLP接口不存在¶
-
检查DTS ADCLP节点的
status
是否为ok
-
检查kernel config是否配置,详见7.1. Kernel Config配置
7.5.2 SAR ADCLP采样结果为0¶
引脚设为GPIO mode进行output high/low的试验,如果无法拉高拉低则有可能是硬件问题