ADCLP使用参考


REVISION HISTORY

Revision No.
Description
Date
1.0
  • Initial release
  • 04/25/2024
    1.1
  • Corrected reference voltage
  • 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

    1. 配置CONFIG_SSTAR_ADCLP

    2. 配置CONFIG_ADC

    3. 配置DM_REGULATOR

    4. 配置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接口

    1. 进入SAR ADCLP采样的通道Channel 0

      cd /sys/class/sstar/adclp0/
      
    2. 设定SAR ADCLP0的阈值(不设定阈值则使用默认值1023)

      echo 800 400 > /sys/class/sstar/adclp0/threshold
      
    3. 使能SAR ADCLP0

      echo 1 > enable
      
    4. 获取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接口不存在

    7.5.2 SAR ADCLP采样结果为0

    引脚设为GPIO mode进行output high/low的试验,如果无法拉高拉低则有可能是硬件问题