回答編集履歴

7

I2Cダンプ関数追加

2019/09/06 10:43

投稿

nomuken
nomuken

スコア1627

test CHANGED
@@ -226,6 +226,44 @@
226
226
 
227
227
  }
228
228
 
229
+
230
+
231
+ int i2c_dump16(u8 slave_addr, u16 reg, u32 in_len)
232
+
233
+ {
234
+
235
+ u8 out[2] = { (u8)(reg >> 8), (u8)reg};
236
+
237
+ u8 in[256];
238
+
239
+ u32 i;
240
+
241
+ int retval;
242
+
243
+ if(in_len > sizeof(in)) { in_len = sizeof(in); }
244
+
245
+ for(i = 0;i < in_len;i++) { in[i] = 0xaa; }
246
+
247
+ retval = i2c_rw(slave_addr, out, sizeof(out), in , in_len);
248
+
249
+ if(retval >= 0){
250
+
251
+ for(i = 0;i < in_len;i++){
252
+
253
+ if ((i & 0xf) ==0) { printf("%04x:", reg + i); }
254
+
255
+ printf("%02x%c", in[i], ((i & 0xf) == 0xf) ? '\n' : ' ');
256
+
257
+ }
258
+
259
+ if ((i & 0xf) !=0) { printf("\n"); }
260
+
261
+ }
262
+
263
+ return retval;
264
+
265
+ }
266
+
229
267
  ```
230
268
 
231
269
 

6

使用例の誤り修正

2019/09/06 10:42

投稿

nomuken
nomuken

スコア1627

test CHANGED
@@ -274,7 +274,7 @@
274
274
 
275
275
  u16 data16;
276
276
 
277
- retval = i2c_read16_8(BH1750_ADDRESS, /*RESULT__ALS_VAL*/0x50, &data16);
277
+ retval = i2c_read16_16(BH1750_ADDRESS, /*RESULT__ALS_VAL*/0x50, &data16);
278
278
 
279
279
  if(retval < 0){
280
280
 

5

使用例を追加

2019/09/05 18:34

投稿

nomuken
nomuken

スコア1627

test CHANGED
@@ -231,3 +231,65 @@
231
231
 
232
232
 
233
233
  好きに使ってください。
234
+
235
+
236
+
237
+ 使用例
238
+
239
+ ```C
240
+
241
+ // For 8bit registers
242
+
243
+ {
244
+
245
+ int retval;
246
+
247
+ u8 data8;
248
+
249
+ retval = i2c_read16_8(BH1750_ADDRESS, /*RESULT__INTERRUPT_STATUS_GPIO*/0x4f, &data8);
250
+
251
+ if(retval < 0){
252
+
253
+ /* エラー処理:適切な処理を入れてください */
254
+
255
+ }
256
+
257
+ else {
258
+
259
+ /* 正常時処理 */
260
+
261
+ printf("register value = %02x\n", data8);
262
+
263
+ }
264
+
265
+ }
266
+
267
+
268
+
269
+ // for 16bit registers
270
+
271
+ {
272
+
273
+ int retval;
274
+
275
+ u16 data16;
276
+
277
+ retval = i2c_read16_8(BH1750_ADDRESS, /*RESULT__ALS_VAL*/0x50, &data16);
278
+
279
+ if(retval < 0){
280
+
281
+ /* エラー処理:適切な処理を入れてください */
282
+
283
+ }
284
+
285
+ else {
286
+
287
+ /* 正常時処理 */
288
+
289
+ printf("register value = %04x\n", data16);
290
+
291
+ }
292
+
293
+ }
294
+
295
+ ```

4

不具合修正

2019/09/05 17:24

投稿

nomuken
nomuken

スコア1627

test CHANGED
@@ -148,7 +148,7 @@
148
148
 
149
149
 
150
150
 
151
- msgset.nmsgs = 1;
151
+ msgset.nmsgs = 2;
152
152
 
153
153
  }
154
154
 

3

ソースコードを更新。レジスタ幅16bit、データ幅8bit/16bit両対応

2019/09/04 22:08

投稿

nomuken
nomuken

スコア1627

test CHANGED
@@ -26,7 +26,7 @@
26
26
 
27
27
 
28
28
 
29
- [これ](https://gist.github.com/JamesDunne/9b7fbedb74c22ccc833059623f47beb7)をベース
29
+ [これ](https://gist.github.com/JamesDunne/9b7fbedb74c22ccc833059623f47beb7)を参考実装します。
30
30
 
31
31
 
32
32
 
@@ -34,130 +34,200 @@
34
34
 
35
35
 
36
36
 
37
+ ```C
38
+
39
+ #include <stdio.h>
40
+
41
+ #include <string.h>
42
+
43
+ #include <fcntl.h>
44
+
45
+ #include <unistd.h>
46
+
47
+ #include <sys/ioctl.h>
48
+
49
+
50
+
51
+ #include <linux/i2c-dev.h>
52
+
53
+ #ifndef I2C_M_RD
54
+
55
+ #include <linux/i2c.h>
56
+
57
+ #endif
58
+
59
+
60
+
61
+ typedef unsigned char u8;
62
+
63
+ typedef unsigned short u16;
64
+
65
+ typedef unsigned int u32;
66
+
67
+
68
+
69
+ int i2c_fd = -1;
70
+
71
+ const char *i2c_fname = "/dev/i2c-1";
72
+
73
+
74
+
75
+ int i2c_init(void)
76
+
77
+ {
78
+
79
+ if ((i2c_fd = open(i2c_fname, O_RDWR)) < 0) {
80
+
81
+ char err[200];
82
+
83
+ sprintf(err, "open('%s') in i2c_init", i2c_fname);
84
+
85
+ perror(err);
86
+
87
+ return -1;
88
+
89
+ }
90
+
91
+
92
+
93
+ return i2c_fd;
94
+
95
+ }
96
+
97
+
98
+
99
+ void i2c_close(void)
100
+
101
+ {
102
+
103
+ close(i2c_fd);
104
+
105
+ i2c_fd = -1;
106
+
107
+ }
108
+
109
+
110
+
111
+ int i2c_rw(u8 slave_addr, u8 *out, u32 out_len, u8 *in, u32 in_len)
112
+
113
+ {
114
+
115
+ int retval;
116
+
117
+ struct i2c_msg msgs[2];
118
+
119
+ struct i2c_rdwr_ioctl_data msgset;
120
+
121
+
122
+
123
+ msgset.msgs = msgs;
124
+
125
+ msgset.nmsgs = 1;
126
+
127
+
128
+
129
+ msgs[0].addr = slave_addr;
130
+
131
+ msgs[0].flags = 0;
132
+
133
+ msgs[0].len = out_len;
134
+
135
+ msgs[0].buf = out;
136
+
137
+
138
+
139
+ if(in_len > 0U){
140
+
141
+ msgs[1].addr = slave_addr;
142
+
143
+ msgs[1].flags = I2C_M_RD | I2C_M_NOSTART;
144
+
145
+ msgs[1].len = in_len;
146
+
147
+ msgs[1].buf = in;
148
+
149
+
150
+
151
+ msgset.nmsgs = 1;
152
+
153
+ }
154
+
155
+
156
+
157
+ if (ioctl(i2c_fd, I2C_RDWR, &msgset) < 0) {
158
+
159
+ perror("ioctl(I2C_RDWR) in i2c_rw");
160
+
161
+ return -1;
162
+
163
+ }
164
+
165
+
166
+
167
+ return 0;
168
+
169
+ }
170
+
171
+
172
+
173
+ int i2c_write16_8(u8 slave_addr, u16 reg, u8 data)
174
+
175
+ {
176
+
177
+ u8 out[3] = { (u8)(reg >> 8), (u8)reg, data };
178
+
179
+ return i2c_rw(slave_addr, out, sizeof(out), NULL, 0);
180
+
181
+ }
182
+
183
+
184
+
185
+ int i2c_write16_16(u8 slave_addr, u16 reg, u16 data)
186
+
187
+ {
188
+
189
+ u8 out[4] = { (u8)(reg >> 8), (u8)reg, (u8)(data >> 8), (u8)data };
190
+
191
+ return i2c_rw(slave_addr, out, sizeof(out), NULL, 0);
192
+
193
+ }
194
+
195
+
196
+
197
+ int i2c_read16_8(u8 slave_addr, u16 reg, u8 *data)
198
+
199
+ {
200
+
201
+ u8 out[2] = { (u8)(reg >> 8), (u8)reg};
202
+
203
+ return i2c_rw(slave_addr, out, sizeof(out), data, 1);
204
+
205
+ }
206
+
207
+
208
+
209
+ int i2c_read16_16(u8 slave_addr, u16 reg, u16 *data)
210
+
211
+ {
212
+
213
+ u8 out[2] = { (u8)(reg >> 8), (u8)reg};
214
+
215
+ u8 in[2];
216
+
217
+ int retval = i2c_rw(slave_addr, out, sizeof(out), in, sizeof(in));
218
+
219
+ if(retval >= 0){
220
+
221
+ *data = (((u16)in[0]) << 8) | in[1];
222
+
223
+ }
224
+
225
+ return retval;
226
+
227
+ }
228
+
37
229
  ```
38
230
 
39
- // Write to an I2C slave device's register:
231
+
40
-
41
- int i2c_write(u8 slave_addr, u16 reg, u8 data) {
232
+
42
-
43
- int retval;
233
+ 好きに使ってください。
44
-
45
- u8 outbuf[3];
46
-
47
-
48
-
49
- struct i2c_msg msgs[1];
50
-
51
- struct i2c_rdwr_ioctl_data msgset[1];
52
-
53
-
54
-
55
- outbuf[0] = (reg >> 8) & 0xffU;
56
-
57
- outbuf[1] = (reg >> 0) & 0xffU;
58
-
59
- outbuf[2] = data;
60
-
61
-
62
-
63
- msgs[0].addr = slave_addr;
64
-
65
- msgs[0].flags = 0;
66
-
67
- msgs[0].len = 3;
68
-
69
- msgs[0].buf = outbuf;
70
-
71
-
72
-
73
- msgset[0].msgs = msgs;
74
-
75
- msgset[0].nmsgs = 1;
76
-
77
-
78
-
79
- if (ioctl(i2c_fd, I2C_RDWR, &msgset) < 0) {
80
-
81
- perror("ioctl(I2C_RDWR) in i2c_write");
82
-
83
- return -1;
84
-
85
- }
86
-
87
-
88
-
89
- return 0;
90
-
91
- }
92
-
93
-
94
-
95
- // Read the given I2C slave device's register and return the read value in `*result`:
96
-
97
- int i2c_read(u8 slave_addr, u16 reg, u8 *result) {
98
-
99
- int retval;
100
-
101
- u8 outbuf[2], inbuf[1];
102
-
103
- struct i2c_msg msgs[2];
104
-
105
- struct i2c_rdwr_ioctl_data msgset[1];
106
-
107
-
108
-
109
- msgs[0].addr = slave_addr;
110
-
111
- msgs[0].flags = 0;
112
-
113
- msgs[0].len = 1;
114
-
115
- msgs[0].buf = outbuf;
116
-
117
-
118
-
119
- msgs[1].addr = slave_addr;
120
-
121
- msgs[1].flags = I2C_M_RD | I2C_M_NOSTART;
122
-
123
- msgs[1].len = 1;
124
-
125
- msgs[1].buf = inbuf;
126
-
127
-
128
-
129
- msgset[0].msgs = msgs;
130
-
131
- msgset[0].nmsgs = 2;
132
-
133
-
134
-
135
- outbuf[0] = (reg >> 8) & 0xffU;
136
-
137
- outbuf[1] = (reg >> 0) & 0xffU;
138
-
139
-
140
-
141
- inbuf[0] = 0;
142
-
143
-
144
-
145
- *result = 0;
146
-
147
- if (ioctl(i2c_fd, I2C_RDWR, &msgset) < 0) {
148
-
149
- perror("ioctl(I2C_RDWR) in i2c_read");
150
-
151
- return -1;
152
-
153
- }
154
-
155
-
156
-
157
- *result = inbuf[0];
158
-
159
- return 0;
160
-
161
- }
162
-
163
- ```

2

修正漏れ対応

2019/09/04 22:00

投稿

nomuken
nomuken

スコア1627

test CHANGED
@@ -94,7 +94,7 @@
94
94
 
95
95
  // Read the given I2C slave device's register and return the read value in `*result`:
96
96
 
97
- int i2c_read(u8 slave_addr, u8 reg, u8 *result) {
97
+ int i2c_read(u8 slave_addr, u16 reg, u8 *result) {
98
98
 
99
99
  int retval;
100
100
 

1

リンクの書き方を修正

2019/09/04 13:30

投稿

nomuken
nomuken

スコア1627

test CHANGED
@@ -12,7 +12,7 @@
12
12
 
13
13
 
14
14
 
15
- そして(wiringPiI2C*の実装)[https://github.com/WiringPi/WiringPi/blob/master/wiringPi/wiringPiI2C.c]を見たのですがLinux KernelのSMBusインタフェースを使用して実装されています。
15
+ そして[wiringPiI2C*の実装](https://github.com/WiringPi/WiringPi/blob/master/wiringPi/wiringPiI2C.c)を見たのですがLinux KernelのSMBusインタフェースを使用して実装されています。
16
16
 
17
17
 
18
18