SAR使用参考


1. 概述

1.1. 概述

SAR口一共四个,10bit 精度,获取到的值范围在0~0x3ff之间,参考电压为1.8V,即如果你读到的值是0x1D2,得到的电压就是0x1D2/0x3FF *1.8=0.82v左右。

1.2. kernel中添加sar的支持

  1. 确保dtsi里面有打开sar的支持

    1.  sar: sar {  
    2.      compatible = "sstar,infinity-sar";  
    3.      clocks = <&CLK_sar>;  
    4.      reg = <0x1F002800 0x200>;  
    5.      status = "ok";  
    6.  };
    
  2. make menuconfig,确认sar的驱动有编译到kernel

    Device Drivers  --->
        [*] SStar SoC platform drivers  --->
            <*> sar driver
    

2. 内核使用SAR

2.1. 初始化为SAR口

先申明一下extern void ms_sar_hw_init (void)函数,再通过这个函数初始化SAR。

  • 目的

    初始化SAR

  • 语法

    void ms_sar_hw_init ();
    

2.2. 取SAR值

先申明一下extern int ms_sar_get (int ch)函数,再通过这个函数读取sar口电平。

  • 目的

    获取SAR口电平

  • 语法

    int ms_sar_get (int ch)
    
  • 参数

    参数名称 描述
    Ch SAR 通道,值范围为0~3
  • 返回值

    返回值 描述
    Int 当前SAR口AD值

2.3. Example

1.  #include <linux/module.h>  
2.  #include <linux/moduleparam.h>  
3.  #include <linux/types.h>  
4.  #include <linux/kernel.h>  
5.  #include <linux/slab.h>  
6.  #include <linux/fs.h>  
7.  #include <linux/miscdevice.h>  
8.  #include <linux/watchdog.h>  
9.  #include <linux/init.h>  
10. #include <linux/version.h>  
11. #include <linux/interrupt.h>  
12. #include <linux/ioport.h>  
13. #include <linux/delay.h>  
14. #include <linux/kthread.h>  
15. #include <linux/semaphore.h>  
16. #include <linux/init.h>  
17. #include <linux/mutex.h>   
18. #include <asm/io.h>  
19. #include <asm/uaccess.h>  
20. #include <linux/random.h>  
21. #include <linux/spi/spi.h>  
22. #include <linux/spi/flash.h>  
23. #include <linux/proc_fs.h>  
24.   
25. static int chn = 0;  
26.   
27. module_param(chn, int, S_IRUGO|S_IWUSR);  
28. MODULE_PARM_DESC(chn, "sar chn num");  
29.   
30. extern void ms_sar_hw_init(void);  
31. extern int ms_sar_get(int ch);  
32.   
33. static int __init sar_test_init(void)  
34. {  
35.     int value = 0;  
36.   
37.     ms_sar_hw_init();  
38.   
39.     value = ms_sar_get(chn);  
40.   
41.     printk("chn=%d, value=%d\n", chn, value);  
42.       
43.     return 0;  
44. }  
45.   
46. static void __exit sar_test_exit(void)  
47. {  
48.     printk("sar_test driver exit success\n");  
49. }  
50.   
51. module_init(sar_test_init);  
52. module_exit(sar_test_exit);  
53.   
54. MODULE_DESCRIPTION("SAR_TEST driver");  
55. MODULE_AUTHOR("SigmaStar");  
56. MODULE_LICENSE("GPL");

3. 用户空间使用SAR

3.1. 概述

用户空间访问sar,通过IOCTL 的方式,首先open /dev/sar,通过IOCTL初始化SAR 和读取电平。

3.2. IOCTL初始化SAR

1.  #define MS_SAR_INIT_IO(SARADC_IOC_MAGIC, 0)  
2.  sar_fd= open("/dev/sar", /*O_RDONLY*/O_RDWR);  
3.  ioctl(sar_fd, MS_SAR_INIT, 0);

3.3. IOCTL读取SAR值

1.  #define SARADC_IOC_MAGIC               'a'  
2.  #define MS_SAR_SET_CHANNEL_READ_VALUE  _IO(SARADC_IOC_MAGIC, 1)  
3.    
4.  typedef struct   
5.  {  
6.      int channel_value;  ////0~3  
7.      int adc_value;  ///读取到的值  
8.  }ADC_CONFIG_READ_ADC;   
9.    
10. stCfg.channel_value=0;  ///SAR0  
11. ioctl(sar_fd, MS_SAR_SET_CHANNEL_READ_VALUE, &stCfg);  
12. printf("0: read stCfg.adc_value=:%x\n", stCfg.adc_value);

3.4. Example

1.  #include <fcntl.h>  
2.  #include <stdio.h>  
3.  #include <ctype.h>  
4.  #include <sys/ioctl.h>  
5.  #include <unistd.h>  
6.  #include <errno.h>  
7.  #include <string.h>  
8.  #include <stdlib.h>  
9.    
10. #define SARADC_IOC_MAGIC 'a'  
11. #define MDRV_SARADC_SET_CHANNEL_MODE_READ_ADC _IO(SARADC_IOC_MAGIC, 1)  
12. #define MS_SAR_INIT                         _IO(SARADC_IOC_MAGIC, 0)  
13.   
14. #define SAR_MAX_CHN_NUM         4  
15. #define SAR_DEV_NAME            "/dev/sar"  
16.   
17. /// mdrv_sar_io.h  
18. typedef struct  
19. {  
20.     int channel_value;  
21.     int adc_value;  
22. } ADC_CONFIG_READ_ADC;  
23.   
24. int main(int argc, char **argv)  
25. {  
26.     ADC_CONFIG_READ_ADC stCfg;  
27.     int sar_fd = -1;  
28.     int chn = 0;  
29.     int ret = 0;  
30.       
31.     if (argc < 2)  
32.     {  
33.         printf("%s %d, such as: %s 1\n", __func__, __LINE__, argv[0]);  
34.         return -1;  
35.     }  
36.       
37.     chn = atoi(argv[1]);  
38.     if (chn < 0 || chn > SAR_MAX_CHN_NUM)  
39.     {  
40.         printf("%s %d, chn range is %d~%d\n", __func__, __LINE__, 0, SAR_MAX_CHN_NUM);  
41.         return -1;  
42.     }  
43.       
44.     sar_fd = open(SAR_DEV_NAME, O_RDWR);  
45.     if (sar_fd < 0)  
46.     {  
47.         perror("open error");  
48.         return -1;  
49.     }  
50.       
51.     if (0 > ioctl(sar_fd, MS_SAR_INIT))  
52.     {  
53.         perror("ioctl MS_SAR_INIT error");  
54.         close(sar_fd);  
55.         return -1;  
56.     }  
57.       
58.     memset(&stCfg, 0, sizeof(ADC_CONFIG_READ_ADC));  
59.       
60.     stCfg.channel_value = chn;  
61.     if (0 > ioctl(sar_fd,MDRV_SARADC_SET_CHANNEL_MODE_READ_ADC, &stCfg))  
62.     {  
63.         perror("ioctl MDRV_SARADC_SET_CHANNEL_MODE_READ_ADC error");  
64.         close(sar_fd);  
65.         return -1;  
66.     }  
67.       
68.     printf("get success, chn=%d, value=%d\n", stCfg.channel_value, stCfg.adc_value);  
69.     close(sar_fd);  
70.   
71.     return 0;  
72. }