source: EcnlProtoTool/trunk/mrbgems/mruby-arduino/src/sI2c.c

Last change on this file was 321, checked in by coas-nagasima, 7 years ago

文字コードを設定

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 8.4 KB
Line 
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
22i2c_t *RbWire[WIRE_MAX]; /*0:Wire1, 1:Wire3, 2:Wire2, 3:Wire6 4:Wire7*/
23
24/******************************************************/
25/* メモリの開放時に走る*/
26/******************************************************/
27static 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/******************************************************/
36static 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/******************************************************/
46static 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/******************************************************/
78mrb_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/******************************************************/
98mrb_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/******************************************************/
120mrb_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/******************************************************/
142mrb_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/******************************************************/
162mrb_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/******************************************************/
178mrb_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/******************************************************/
198mrb_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/******************************************************/
210mrb_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/******************************************************/
222mrb_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/******************************************************/
236void 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}
Note: See TracBrowser for help on using the repository browser.