/* * シリアル通信関連 * * Copyright (c) 2016 Wakayama.rb Ruby Board developers * * This software is released under the MIT License. * https://github.com/wakayamarb/wrbb-v2lib-firm/blob/master/MITL * */ #include #include #include #include #include #include #include "../llbruby.h" #define SERIAL_MAX 6 #define SERIAL_BUFFER_SIZE 1024 serial_t *RbSerial[SERIAL_MAX]; /*0:Serial(USB), 1:Serial1, 2:Serial3, 3:Serial2, 4:Serial6 5:Serial7*/ /******************************************************/ /* メモリの開放時に走る*/ /******************************************************/ static void mrb_serial_free(mrb_state *mrb, void *ptr) { serial_t* serial = (serial_t *)(ptr); mrb_free(mrb, serial); } /******************************************************/ /* この構造体の意味はよくわかっていない*/ /******************************************************/ static struct mrb_data_type serial_type = {"Serial", mrb_serial_free}; /******************************************************/ /* シリアル通信を初期化します: Serial.new*/ /* Serial.new(num[, bps]) */ /* num: 通信番号(0:USB, 1:TX-0/RX-1, 2:TX-5/RX-6, 3:TX-7/RX-8, 4:TX-12/RX-11, 5:TX-9(26)/RX-3)*/ /* bps: ボーレート*/ /**/ /* 戻り値*/ /* Serialのインスタンス*/ /******************************************************/ static mrb_value mrb_serial_initialize(mrb_state *mrb, mrb_value self) { /* Initialize data type first, otherwise segmentation fault occurs.*/ DATA_TYPE(self) = &serial_type; DATA_PTR(self) = NULL; mrb_int num; mrb_int bps; PinName txpin, rxpin; int n = mrb_get_args(mrb, "i|i", &num, &bps); if (num < 0 && num >= SERIAL_MAX) { return mrb_nil_value(); /*戻り値は無しですよ。*/ } if(!portToPins(num, &txpin, &rxpin)) return mrb_nil_value(); /*戻り値は無しですよ。*/ serial_t* serialc = mrb_malloc(mrb, sizeof(serial_t)); serial_init(serialc, txpin, rxpin); if (n >= 2) { serial_baud(serialc, bps); } DATA_PTR(self) = serialc; return self; } /******************************************************/ /* ボーレートを設定します: Serial.bps*/ /* Serial.bps(bps)*/ /* bps: ボーレート */ /******************************************************/ mrb_value mrb_serial_bps(mrb_state *mrb, mrb_value self) { int bps; serial_t* serialc = (serial_t *)(mrb_get_datatype(mrb, self, &serial_type)); mrb_get_args(mrb, "i", &bps); serial_baud(serialc, bps); return mrb_nil_value(); /*戻り値は無しですよ。*/ } /******************************************************/ /* シリアルに出力します: Serial.print*/ /* Serial.print([str])*/ /* str: 文字列*/ /* 省略時は何も出力しません*/ /******************************************************/ mrb_value mrb_serial_print(mrb_state *mrb, mrb_value self) { mrb_value text; serial_t* serialc = (serial_t *)(mrb_get_datatype(mrb, self, &serial_type)); int n = mrb_get_args(mrb, "|S", &text); if (n > 0) { serial_print(serialc, RSTRING_PTR(text)); } return mrb_nil_value(); /*戻り値は無しですよ。*/ } /******************************************************/ /* シリアルに\r\n付きで出力します: Serial.println*/ /* Serial.println([str])*/ /* str: 文字列*/ /* 省略時は改行のみ*/ /******************************************************/ mrb_value mrb_serial_println(mrb_state *mrb, mrb_value self) { mrb_value text; serial_t* serialc = (serial_t *)(mrb_get_datatype(mrb, self, &serial_type)); int n = mrb_get_args(mrb, "|S", &text); if (n > 0) { serial_println(serialc, RSTRING_PTR(text)); } else { serial_println(serialc, ""); } return mrb_nil_value(); /*戻り値は無しですよ。*/ } /******************************************************/ /* シリアルデータがあるかどうか調べます: Serial.available*/ /* Serial.available()*/ /* 戻り値 シリアルバッファにあるデータのバイト数。0の場合はデータなし*/ /******************************************************/ mrb_value mrb_serial_available(mrb_state *mrb, mrb_value self) { serial_t* serialc = (serial_t *)(mrb_get_datatype(mrb, self, &serial_type)); return mrb_fixnum_value(serial_readable(serialc)); } /******************************************************/ /* シリアルからデータを取得します: Serial.read*/ /* Serial.read()*/ /* 戻り値*/ /* データ配列*/ /******************************************************/ mrb_value mrb_serial_read(mrb_state *mrb, mrb_value self) { serial_t* serialc = (serial_t *)(mrb_get_datatype(mrb, self, &serial_type)); int len = serial_readable(serialc); mrb_value ret; char *buf; ret = mrb_str_buf_new(mrb, len); buf = RSTRING_PTR(ret); for (int i = 0; i < len; i++) { buf[i] = serial_getc(serialc); } RSTR_SET_LEN(RSTRING(ret), len); return ret; } /******************************************************/ /* シリアルにデータを出力します: Serial.write*/ /* Serial.write(buf,len)*/ /* buf: 出力データ*/ /* len: 出力データサイズ*/ /* 戻り値*/ /* 出力したバイト数*/ /******************************************************/ mrb_value mrb_serial_write(mrb_state *mrb, mrb_value self) { mrb_value value; int len; char *buf; serial_t* serialc = (serial_t *)(mrb_get_datatype(mrb, self, &serial_type)); mrb_get_args(mrb, "Si", &value, &len); buf = RSTRING_PTR(value); for (int i = 0; i < len; i++) { serial_putc(serialc, buf[i]); } return mrb_fixnum_value(len); } /******************************************************/ /* シリアルデータをフラッシュします: Serial.flash*/ /* Serial.flash()*/ /******************************************************/ mrb_value mrb_serial_flash(mrb_state *mrb, mrb_value self) { serial_t* serialc = (serial_t *)(mrb_get_datatype(mrb, self, &serial_type)); //serial_flush(serialc); return mrb_nil_value(); /*戻り値は無しですよ。*/ } #if 0 unsigned char WiFiData[256]; /***************************************************/ /* USBポートとESP8266をシリアルで直結します: WiFi.bypass*/ /* WiFi.bypass()*/ /* リセットするまで、処理は戻りません。*/ //**************************************************/ mrb_value mrb_wifi_bypass(mrb_state *mrb, mrb_value self) { int len0, len1,len; //serial_begin(RbSerial[0], 115200); //serial_begin(RbSerial[3], 115200); int retCnt = 0; while(true){ len0 = serial_readable(RbSerial[0]); len1 = serial_readable(RbSerial[3]); if(len0 > 0){ len = len0<256 ? len0 : 256; for(int i=0; i 20){ return mrb_nil_value(); /*戻り値は無しですよ。*/ } } else{ retCnt = 0; } } serial_write(RbSerial[3], WiFiData, len ); } if(len1 > 0){ len = len1<256 ? len1 : 256; for(int i=0; iobject_class); MRB_SET_INSTANCE_TT(serialModule, MRB_TT_DATA); mrb_define_method(mrb, serialModule, "initialize", mrb_serial_initialize, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1)); mrb_define_method(mrb, serialModule, "bps", mrb_serial_bps, MRB_ARGS_REQ(1)); mrb_define_method(mrb, serialModule, "print", mrb_serial_print, MRB_ARGS_OPT(1)); mrb_define_method(mrb, serialModule, "println", mrb_serial_println, MRB_ARGS_OPT(1)); mrb_define_method(mrb, serialModule, "read", mrb_serial_read, MRB_ARGS_NONE()); mrb_define_method(mrb, serialModule, "write", mrb_serial_write, MRB_ARGS_REQ(2)); mrb_define_method(mrb, serialModule, "flash", mrb_serial_flash, MRB_ARGS_NONE()); mrb_define_method(mrb, serialModule, "available", mrb_serial_available, MRB_ARGS_NONE()); /*struct RClass *wifiModule = mrb_define_module(mrb, "WiFi");*/ /*mrb_define_module_function(mrb, wifiModule, "bypass", mrb_wifi_bypass, MRB_ARGS_NONE());*/ }