1 | /*
|
---|
2 | * I2C通信関連
|
---|
3 | *
|
---|
4 | * Copyright (c) 2016 Wakayama.rb Ruby Board developers
|
---|
5 | *
|
---|
6 | * This software is released under the MIT License.
|
---|
7 | * https://github.com/wakayamarb/wrbb-v2lib-firm/blob/master/MITL
|
---|
8 | *
|
---|
9 | */
|
---|
10 | #include <arduino.h>
|
---|
11 | /*#include <wire.h>*/
|
---|
12 |
|
---|
13 | #include <mruby.h>
|
---|
14 | #include <mruby/data.h>
|
---|
15 | #include <mruby/class.h>
|
---|
16 |
|
---|
17 | #include "../llbruby.h"
|
---|
18 | #include "sKernel.h"
|
---|
19 |
|
---|
20 | #define WIRE_MAX 6
|
---|
21 |
|
---|
22 | i2c_t *RbWire[WIRE_MAX]; /*0:Wire1, 1:Wire3, 2:Wire2, 3:Wire6 4:Wire7*/
|
---|
23 |
|
---|
24 | /******************************************************/
|
---|
25 | /* メモリの開放時に走る*/
|
---|
26 | /******************************************************/
|
---|
27 | static void i2c_free(mrb_state *mrb, void *ptr)
|
---|
28 | {
|
---|
29 | i2c_t* i2c = (i2c_t*)(ptr);
|
---|
30 | mrb_free(mrb, i2c);
|
---|
31 | }
|
---|
32 |
|
---|
33 | /******************************************************/
|
---|
34 | /* この構造体の意味はよくわかっていない*/
|
---|
35 | /******************************************************/
|
---|
36 | static struct mrb_data_type i2c_type = {"I2c", i2c_free};
|
---|
37 |
|
---|
38 | /******************************************************/
|
---|
39 | /* I2Cを初期化します: I2c.new*/
|
---|
40 | /* I2c.new(num) */
|
---|
41 | /* num: 通信番号(0:SDA-0/SCL-1, 1:SDA-5/SCL-6, 2:SDA-7/SCL-8, 3:SDA-12/SCL-11, 4:SDA-9(26)/SCL-3)*/
|
---|
42 | /**/
|
---|
43 | /* 戻り値*/
|
---|
44 | /* I2cのインスタンス*/
|
---|
45 | /******************************************************/
|
---|
46 | static mrb_value mrb_i2c_initialize(mrb_state *mrb, mrb_value self)
|
---|
47 | {
|
---|
48 | /* Initialize data type first, otherwise segmentation fault occurs.*/
|
---|
49 | DATA_TYPE(self) = &i2c_type;
|
---|
50 | DATA_PTR(self) = NULL;
|
---|
51 |
|
---|
52 | mrb_int num;
|
---|
53 |
|
---|
54 | mrb_get_args(mrb, "i", &num);
|
---|
55 |
|
---|
56 | if (num <= 0 && num >= WIRE_MAX) {
|
---|
57 | return mrb_nil_value(); /*戻り値は無しですよ。*/
|
---|
58 | }
|
---|
59 |
|
---|
60 | i2c_t* i2c = mrb_malloc(mrb, sizeof(i2c_t));
|
---|
61 | i2c_init(i2c, num, num);
|
---|
62 |
|
---|
63 | DATA_PTR(self) = i2c;
|
---|
64 | return self;
|
---|
65 | }
|
---|
66 |
|
---|
67 | /******************************************************/
|
---|
68 | /* アドレスにデータを書き込みます: I2c.write*/
|
---|
69 | /* I2c.write( deviceID, address, data )*/
|
---|
70 | /* deviceID: デバイスID*/
|
---|
71 | /* address: 書き込みアドレス*/
|
---|
72 | /* data: データ*/
|
---|
73 | /**/
|
---|
74 | /* 戻り値は以下のとおり*/
|
---|
75 | /* 0: 成功*/
|
---|
76 | /* 4: その他のエラー*/
|
---|
77 | /******************************************************/
|
---|
78 | mrb_value mrb_i2c_write(mrb_state *mrb, mrb_value self)
|
---|
79 | {
|
---|
80 | int deviceID, addr, dat;
|
---|
81 |
|
---|
82 | mrb_get_args(mrb, "iii", &deviceID, &addr, &dat);
|
---|
83 |
|
---|
84 | i2c_t* i2c = (i2c_t *)(mrb_get_datatype(mrb, self, &i2c_type));
|
---|
85 |
|
---|
86 | return mrb_fixnum_value(i2c_write(i2c, addr, (char *)&dat, sizeof(dat), 1));
|
---|
87 | }
|
---|
88 |
|
---|
89 | /******************************************************/
|
---|
90 | /* アドレスからデータを読み込み: I2c.read*/
|
---|
91 | /* I2c.read( deviceID, addressL[, addressH] )*/
|
---|
92 | /* deviceID: デバイスID*/
|
---|
93 | /* addressL: 読み込み下位アドレス*/
|
---|
94 | /* addressH: 読み込み上位アドレス*/
|
---|
95 | /**/
|
---|
96 | /* 戻り値は読み込んだ値*/
|
---|
97 | /******************************************************/
|
---|
98 | mrb_value mrb_i2c_read(mrb_state *mrb, mrb_value self)
|
---|
99 | {
|
---|
100 | int deviceID, addrL;
|
---|
101 | int addrH = 0;
|
---|
102 | int dat = 0;
|
---|
103 | /*byte datH;*/
|
---|
104 |
|
---|
105 | int n = mrb_get_args(mrb, "ii|i", &deviceID, &addrL, &addrH);
|
---|
106 |
|
---|
107 | i2c_t* i2c = (i2c_t *)(mrb_get_datatype(mrb, self, &i2c_type));
|
---|
108 |
|
---|
109 | i2c_read(i2c, addrL | (addrH << 8), (char *)&dat, sizeof(dat), 1);
|
---|
110 |
|
---|
111 | return mrb_fixnum_value(dat);
|
---|
112 | }
|
---|
113 |
|
---|
114 | /******************************************************/
|
---|
115 | /* I2Cデバイスに対して送信を開始するための準備をする: I2c.begin*/
|
---|
116 | /* I2c.begin( deviceID )*/
|
---|
117 | /* この関数は送信バッファを初期化するだけで、実際の動作は行わない。繰り返し呼ぶと、送信バッファが先頭に戻る。*/
|
---|
118 | /* deviceID: デバイスID 0~0x7Fまでの純粋なアドレス*/
|
---|
119 | /******************************************************/
|
---|
120 | mrb_value mrb_i2c_beginTransmission(mrb_state *mrb, mrb_value self)
|
---|
121 | {
|
---|
122 | int deviceID;
|
---|
123 |
|
---|
124 | mrb_get_args(mrb, "i", &deviceID);
|
---|
125 |
|
---|
126 | i2c_t* i2c = (i2c_t *)(mrb_get_datatype(mrb, self, &i2c_type));
|
---|
127 |
|
---|
128 | i2c_start(i2c);
|
---|
129 | i2c_byte_write(i2c, deviceID);
|
---|
130 |
|
---|
131 | return mrb_nil_value(); /*戻り値は無しですよ。*/
|
---|
132 | }
|
---|
133 |
|
---|
134 | /******************************************************/
|
---|
135 | /* 送信バッファの末尾に数値を追加する: I2c.lwrite*/
|
---|
136 | /* I2c.lwrite( data )*/
|
---|
137 | /* data: セットする値*/
|
---|
138 | /**/
|
---|
139 | /* 戻り値は、送信したバイト数(バッファに溜めたバイト数)を返す。*/
|
---|
140 | /* 送信バッファ(260バイト)に空き容量が無ければ失敗して0を返す*/
|
---|
141 | /******************************************************/
|
---|
142 | mrb_value mrb_i2c_lwrite(mrb_state *mrb, mrb_value self)
|
---|
143 | {
|
---|
144 | int dat;
|
---|
145 |
|
---|
146 | mrb_get_args(mrb, "i", &dat);
|
---|
147 |
|
---|
148 | i2c_t* i2c = (i2c_t *)(mrb_get_datatype(mrb, self, &i2c_type));
|
---|
149 |
|
---|
150 | return mrb_fixnum_value(i2c_byte_write(i2c, dat));
|
---|
151 | }
|
---|
152 |
|
---|
153 | /******************************************************/
|
---|
154 | /* デバイスに対してI2Cの送信シーケンスを発行する: I2c.end*/
|
---|
155 | /* I2c.end()*/
|
---|
156 | /* I2Cの送信はこの関数を実行して初めて実際に行われる。*/
|
---|
157 | /**/
|
---|
158 | /* 戻り値は以下のとおり*/
|
---|
159 | /* 0: 成功*/
|
---|
160 | /* 4: その他のエラー*/
|
---|
161 | /******************************************************/
|
---|
162 | mrb_value mrb_i2c_endTransmission(mrb_state *mrb, mrb_value self)
|
---|
163 | {
|
---|
164 | i2c_t* i2c = (i2c_t *)(mrb_get_datatype(mrb, self, &i2c_type));
|
---|
165 |
|
---|
166 | return mrb_fixnum_value(i2c_stop(i2c));
|
---|
167 | }
|
---|
168 |
|
---|
169 | /******************************************************/
|
---|
170 | /* デバイスに対して受信シーケンスを発行しデータを読み出す: I2c.request*/
|
---|
171 | /* I2c.request( address, count )*/
|
---|
172 | /* num: 通信番号(0:SDA-0/SCL-1, 1:SDA-5/SCL-6, 2:SDA-7/SCL-8, 3:SDA-12/SCL-11, 4:SDA-9(26)/SCL-3)*/
|
---|
173 | /* address: 読み込み開始アドレス*/
|
---|
174 | /* count: 読み出す数*/
|
---|
175 | /**/
|
---|
176 | /* 戻り値は、実際に受信したバイト数。*/
|
---|
177 | /******************************************************/
|
---|
178 | mrb_value mrb_i2c_requestFrom(mrb_state *mrb, mrb_value self)
|
---|
179 | {
|
---|
180 | int addr, cnt, ret;
|
---|
181 | char rxdata[16];
|
---|
182 |
|
---|
183 | mrb_get_args(mrb, "ii", &addr, &cnt);
|
---|
184 |
|
---|
185 | i2c_t* i2c = (i2c_t *)(mrb_get_datatype(mrb, self, &i2c_type));
|
---|
186 |
|
---|
187 | ret = i2c_read(i2c, addr, rxdata, cnt, 1);
|
---|
188 |
|
---|
189 | return mrb_fixnum_value(ret);
|
---|
190 | }
|
---|
191 |
|
---|
192 | /******************************************************/
|
---|
193 | /* デバイスに対して受信シーケンスを発行しデータを読み出す: I2c.lread*/
|
---|
194 | /* I2c.lread()*/
|
---|
195 | /**/
|
---|
196 | /* 戻り値は読み込んだ値*/
|
---|
197 | /******************************************************/
|
---|
198 | mrb_value mrb_i2c_lread(mrb_state *mrb, mrb_value self)
|
---|
199 | {
|
---|
200 | i2c_t* i2c = (i2c_t *)(mrb_get_datatype(mrb, self, &i2c_type));
|
---|
201 | return mrb_fixnum_value(i2c_byte_read(i2c, 1));
|
---|
202 | }
|
---|
203 |
|
---|
204 | /******************************************************/
|
---|
205 | /* デバイスに対して受信バッファ内にあるデータ数を調べる: I2c.available*/
|
---|
206 | /* I2c.available()*/
|
---|
207 | /**/
|
---|
208 | /* 戻り値はデータ数*/
|
---|
209 | /******************************************************/
|
---|
210 | mrb_value mrb_i2c_available(mrb_state *mrb, mrb_value self)
|
---|
211 | {
|
---|
212 | i2c_t* i2c = (i2c_t *)(mrb_get_datatype(mrb, self, &i2c_type));
|
---|
213 | return mrb_fixnum_value(1/*i2c_available(i2c)*/);
|
---|
214 | }
|
---|
215 | #if 0
|
---|
216 | /******************************************************/
|
---|
217 | /* 周波数を変更する: I2c.freq*/
|
---|
218 | /* I2c.freq( Hz )*/
|
---|
219 | /* Hz: クロックの周波数をHz単位で指定する。*/
|
---|
220 | /* 有効な値は1~200000程度。基本的にソフトでやっているので400kHzは出ない。*/
|
---|
221 | /******************************************************/
|
---|
222 | mrb_value mrb_i2c_freq(mrb_state *mrb, mrb_value self)
|
---|
223 | {
|
---|
224 | int fq;
|
---|
225 |
|
---|
226 | mrb_get_args(mrb, "i", &fq);
|
---|
227 |
|
---|
228 | i2c_frequency(i2c, fq);
|
---|
229 |
|
---|
230 | return mrb_nil_value(); /* 戻り値は無しですよ。 */
|
---|
231 | }
|
---|
232 | #endif
|
---|
233 | /******************************************************/
|
---|
234 | /* ライブラリを定義します*/
|
---|
235 | /******************************************************/
|
---|
236 | void i2c_Init(mrb_state *mrb)
|
---|
237 | {
|
---|
238 | /*0:Wire1, 1:Wire3, 2:Wire2, 3:Wire6 4:Wire7*/
|
---|
239 | RbWire[0] = NULL;
|
---|
240 | RbWire[1] = &Wire1;
|
---|
241 | RbWire[2] = &Wire2;
|
---|
242 | RbWire[3] = &Wire3;
|
---|
243 | RbWire[4] = &Wire4;
|
---|
244 | RbWire[5] = &Wire5;
|
---|
245 |
|
---|
246 | struct RClass *i2cModule = mrb_define_class(mrb, "I2c", mrb->object_class);
|
---|
247 | MRB_SET_INSTANCE_TT(i2cModule, MRB_TT_DATA);
|
---|
248 |
|
---|
249 | mrb_define_method(mrb, i2cModule, "initialize", mrb_i2c_initialize, MRB_ARGS_REQ(1));
|
---|
250 | mrb_define_method(mrb, i2cModule, "write", mrb_i2c_write, MRB_ARGS_REQ(3));
|
---|
251 | mrb_define_method(mrb, i2cModule, "read", mrb_i2c_read, MRB_ARGS_REQ(2) | MRB_ARGS_OPT(1));
|
---|
252 | mrb_define_method(mrb, i2cModule, "begin", mrb_i2c_beginTransmission, MRB_ARGS_REQ(1));
|
---|
253 | mrb_define_method(mrb, i2cModule, "lwrite", mrb_i2c_lwrite, MRB_ARGS_REQ(1));
|
---|
254 | mrb_define_method(mrb, i2cModule, "end", mrb_i2c_endTransmission, MRB_ARGS_NONE());
|
---|
255 | mrb_define_method(mrb, i2cModule, "request", mrb_i2c_requestFrom, MRB_ARGS_REQ(2));
|
---|
256 | mrb_define_method(mrb, i2cModule, "lread", mrb_i2c_lread, MRB_ARGS_NONE());
|
---|
257 | mrb_define_method(mrb, i2cModule, "available", mrb_i2c_available, MRB_ARGS_NONE());
|
---|
258 | }
|
---|