[270] | 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 | }
|
---|