【TINY4412】LINUX移植笔记:(26)设备树ADC驱动

环境

宿主机 : 虚拟机 Ubuntu 16.04 LTS / X64
目标板[底板]: Tiny4412SDK - 1506
目标板[核心板]: Tiny4412 - 1412
LINUX内核: 4.12.0
交叉编译器: arm-none-linux-gnueabi-gcc(gcc version 4.8.3 20140320)
日期: 2017-9-9 20:30:09
作者: SY

简介

开发板自带 4ADC

1

1

开发板将 ADC0 连接一个滑动变阻器。 ADC12 位,最大码值为:4095

移植

设备树

参考设备树文件:

1
2
3
4
5
6
7
8
9
10
11
12
adc: adc@126C0000 {
compatible = "samsung,exynos-adc-v1";
reg = <0x126C0000 0x100>;
interrupt-parent = <&combiner>;
interrupts = <10 3>;
clocks = <&clock CLK_TSADC>;
clock-names = "adc";
#io-channel-cells = <1>;
io-channel-ranges;
samsung,syscon-phandle = <&pmu_system_controller>;
status = "disabled";
};

写自己的设备树:

1
2
3
&adc {
status = "okay";
};
1
2
3
4
Device Drivers --->
<*> Industrial I/O support --->
Analog to digital converters --->
<*> Exynos ADC driver support

烧录

1
[ 4.002206] exynos-adc 126c0000.adc: 126c0000.adc supply vdd not found, using dummy regulator

查看设备节点

1
2
[root@TINY4412:~]# ls /dev/iio\:device0
/dev/iio:device0

APP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/*
* adc driver for tiny4412
*
* Copyright (c) 2017
* Author: SY <1530454315@qq.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <stdbool.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/epoll.h>
#define DEVICE_NAME "/sys/bus/iio/devices/iio\:device0/"
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
struct adc_dev {
uint8_t chn;
const char *dev;
};
const struct adc_dev adc_dev_table[] = {
{0, "in_voltage0_raw"},
{1, "in_voltage1_raw"},
{2, "in_voltage2_raw"},
{3, "in_voltage3_raw"},
};
#if 1
static void help(void)
{
printf("Usage: ./adc <chn>\n");
}
#endif
int adc_chn;
bool esc = false;
static void sigint_handler(int dunno)
{
switch (dunno) {
case SIGINT:
esc = true;
printf("< Ctrl+C > Press.\n");
break;
default:
break;
}
}
const char* match_adc_dev(uint8_t chn)
{
for (uint8_t i=0; i<ARRAY_SIZE(adc_dev_table); ++i) {
if (chn == adc_dev_table[i].chn) {
return adc_dev_table[i].dev;
}
}
return NULL;
}
static bool read_adc(char *dev, int32_t *code)
{
int fd = open(dev, O_RDONLY);
if (fd < 0) {
perror("open error");
return false;
}
char value[32];
int ret = read(fd, value, sizeof(value));
if (ret < 0) {
perror("read error");
return false;
}
int32_t adc = 0;
sscanf(value, "%d", &adc);
close(fd);
*code = adc;
return true;
}
static void* read_handler(void* data)
{
printf("thread run.\n");
char dev_name[64];
strcpy(dev_name, DEVICE_NAME);
const char *dev = match_adc_dev(adc_chn);
if (!dev) {
printf("it can't find device!\n");
return NULL;
}
strcat(dev_name, dev);
while (esc == false) {
int32_t code = 0;
if (read_adc(dev_name, &code) == false) {
printf("read_adc error!\n");
return NULL;
}
printf("[%d] %d\n", adc_chn, code);
usleep(20*1000);
}
pthread_exit(NULL);
return NULL;
}
int main(int argc, char **argv)
{
if (argc != 2) {
help();
exit(0);
}
adc_chn = atoi(argv[1]);
pthread_t thread_read;
int ret = pthread_create(&thread_read, NULL, read_handler, NULL);
if (ret) {
perror("[thread_create]");
return 1;
}
/* Register signal */
signal(SIGINT, sigint_handler);
pthread_join(thread_read, NULL);
printf("done!\n");
return 0;
}

使用 dev/iio\:device0 读取数据有问题,因此使用 sysfs 读数据。

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
[root@TINY4412:~]# ./tmp/adc 0
thread run.
[0] 0
[0] 0
[0] 0
[0] 5
[0] 20
[0] 38
[0] 81
[0] 135
[0] 181
[0] 225
[0] 263
[0] 284
[0] 311
[0] 347
[0] 362
[0] 396
[0] 433
[0] 453
[0] 484
[0] 513
[0] 531
[0] 543
[0] 567
[0] 606
[0] 621
[0] 640
[0] 662
[0] 696
[0] 724
[0] 748
[0] 798
[0] 820
[0] 845
[0] 875
[0] 893
[0] 925
[0] 946
[0] 997
[0] 1057
[0] 1097
[0] 1142
[0] 1232
[0] 1289
[0] 1368
[0] 1421
[0] 1478
[0] 1541
[0] 1601
[0] 1653
[0] 1724
[0] 1771
[0] 1800
[0] 1841
[0] 1875
[0] 1894
[0] 1942
[0] 1962
[0] 1986
[0] 2033
[0] 2062
[0] 2095
[0] 2120
[0] 2141
[0] 2162
[0] 2180
[0] 2213
[0] 2239
[0] 2273
[0] 2313
[0] 2342
[0] 2366
[0] 2391
[0] 2419
[0] 2448
[0] 2467
[0] 2496
[0] 2505
[0] 2554
[0] 2604
[0] 2623
[0] 2668
[0] 2723
[0] 2777
[0] 2836
[0] 2879
[0] 2951
[0] 3021
[0] 3046
[0] 3087
[0] 3113
[0] 3163
[0] 3211
[0] 3251
[0] 3296
[0] 3332
[0] 3377
[0] 3404
[0] 3457
[0] 3504
[0] 3561
[0] 3639
[0] 3691
[0] 3780
[0] 3854
[0] 3917
[0] 3968
[0] 4009
[0] 4064
[0] 4095
[0] 4095
[0] 4095
[0] 4095
^C< Ctrl+C > Press.
done!
SY wechat
扫一扫,用手机访问本站