#include "arduino_uart.h" extern "C" { extern uint8_t * make_output_buffer(mrb_vm *vm, mrb_value v[], int argc, int start_idx, int *ret_bufsiz); #if !MRBC_USE_STRING extern mrbc_value mrbc_array_new_alloc(mrbc_vm *vm, const uint8_t *c_array, int size); #endif typedef struct UART_HANDLE { decltype(Serial) *unit_serial; //uint8_t delimiter; } UART_HANDLE; void c_uart_setmode(mrbc_vm *vm, mrbc_value v[], int argc){ UART_HANDLE *handle = (UART_HANDLE *)v[0].instance->data; decltype(SERIAL_8N1) myUARTSettings=SERIAL_8N1; MRBC_KW_ARG( baudrate, baud, data_bits, stop_bits, parity, flow_control, txd_pin, rxd_pin, rts_pin, cts_pin ); int32_t baud_rate = 9600; int datb = 8; int stpb = 1; int prty = 0; if( MRBC_KW_ISVALID(baudrate) ) baud_rate = mrbc_integer(baudrate); if( MRBC_KW_ISVALID(baud) ) baud_rate = mrbc_integer(baud); if( MRBC_KW_ISVALID(data_bits) ) datb = mrbc_integer(data_bits); if( MRBC_KW_ISVALID(stop_bits) ) stpb = mrbc_integer(stop_bits); if( MRBC_KW_ISVALID(parity) ) prty = mrbc_integer(parity); switch(prty){ case 0: myUARTSettings=(stpb<2)? SERIAL_8N1 : SERIAL_8N2; break; case 1: myUARTSettings=(stpb<2)? SERIAL_8O1 : SERIAL_8O2; break; case 2: myUARTSettings=(stpb<2)? SERIAL_8E1 : SERIAL_8E2; break; } decltype(Serial) *unit_serial = handle->unit_serial; unit_serial->end(); unit_serial->begin(baud_rate,myUARTSettings); while (!(*unit_serial)); unit_serial->setTimeout(1000); MRBC_KW_DELETE( baudrate, baud, data_bits, stop_bits, parity, flow_control, txd_pin, rxd_pin, rts_pin, cts_pin ); } void c_uart_new(mrb_vm *vm, mrb_value *v, int argc){ v[0] = mrbc_instance_new(vm, v[0].cls, 0); int unit_num = 0; if( argc > 0 ) unit_num = GET_INT_ARG(1); MRBC_KW_ARG( unit ); if( MRBC_KW_ISVALID(unit) ) unit_num = mrbc_integer(unit); MRBC_KW_DELETE( unit ); UART_HANDLE *handle = (UART_HANDLE *)v[0].instance->data; decltype(Serial) *unit_serial; unit_serial=&Serial; switch(unit_num){ case 0: unit_serial=&Serial; break; case 1: unit_serial=&Serial1; break; #if defined(Serial2) case 2: unit_serial=&Serial2; break; #endif #if defined(Serial3) case 3: unit_serial=&Serial3; break; #endif #if defined(Serial4) case 4: unit_serial=&Serial4; break; #endif } handle->unit_serial = unit_serial; c_uart_setmode( vm, v, argc ); } void c_uart_write(mrb_vm *vm, mrb_value *v, int argc){ UART_HANDLE *handle = (UART_HANDLE *)v[0].instance->data; int bufsiz = 0; if(argc>0){ char *buf = (char*) make_output_buffer( vm, v, argc, 1, &bufsiz ); bufsiz=(int) handle->unit_serial->write(buf,bufsiz); } SET_RETURN( mrbc_integer_value(bufsiz) ); } static void c_uart_puts(mrbc_vm *vm, mrbc_value v[], int argc){ UART_HANDLE *handle = (UART_HANDLE *)v[0].instance->data; char zero[]="\n"; char *buf=zero; int len=1; if(argc>0){ buf = (char*) make_output_buffer( vm, v, argc, 1, &len ); len=(int) handle->unit_serial->write(buf,len); if( len == 0 || buf[len-1] != '\n' ){ len=1; }else{ len=0; } } handle->unit_serial->write(buf,len); SET_NIL_RETURN(); } void c_uart_read(mrb_vm *vm, mrb_value *v, int argc){ UART_HANDLE *handle = (UART_HANDLE *)v[0].instance->data; mrbc_value ret = mrbc_nil_value(); if(argc>0){ int size = GET_INT_ARG(1); char *buf = (char*) mrbc_alloc(vm, size); size=(int) handle->unit_serial->readBytes(buf,size); #if MRBC_USE_STRING ret = mrbc_string_new_alloc(vm, buf, size); #else ret = mrbc_array_new_alloc( vm, (uint8_t*) buf, size); mrbc_free( vm, buf ); #endif } SET_RETURN(ret); } static void c_uart_gets(mrbc_vm *vm, mrbc_value v[], int argc){ UART_HANDLE *handle = (UART_HANDLE *)v[0].instance->data; mrbc_value ret = mrbc_nil_value(); int size=0; char *buf = (char*) mrbc_alloc(vm, UART_GETS_MAX); decltype(Serial) *unit_serial = handle->unit_serial; while(size==0) size=(int) unit_serial->available(); size=(int) unit_serial->readBytesUntil('\n', buf, UART_GETS_MAX); #if MRBC_USE_STRING ret = mrbc_string_new_alloc(vm, buf, size); #else ret = mrbc_array_new_alloc( vm, (uint8_t *) buf, size); mrbc_free( vm, buf ); #endif SET_RETURN(ret); } static void c_uart_bytes_available(mrbc_vm *vm, mrbc_value v[], int argc){ UART_HANDLE *handle = (UART_HANDLE *)v[0].instance->data; int n=0; n=handle->unit_serial->available(); SET_INT_RETURN(n); } static void c_uart_bytes_to_write(mrbc_vm *vm, mrbc_value v[], int argc){ SET_INT_RETURN( 0 ); } static void c_uart_can_read_line(mrbc_vm *vm, mrbc_value v[], int argc){ SET_INT_RETURN( 0 ); } static void c_uart_flush(mrbc_vm *vm, mrbc_value v[], int argc){ UART_HANDLE *handle = (UART_HANDLE *)v[0].instance->data; handle->unit_serial->flush(); } static void c_uart_nop(mrbc_vm *vm, mrbc_value v[], int argc){ } void mrbc_init_class_uart(void){ mrb_class *uart = mrbc_define_class(0, "UART", mrbc_class_object); mrbc_define_method(0, uart, "new", c_uart_new); mrbc_define_method(0, uart, "setmode", c_uart_setmode); mrbc_define_method(0, uart, "read", c_uart_read); mrbc_define_method(0, uart, "write", c_uart_write); mrbc_define_method(0, uart, "gets", c_uart_gets); mrbc_define_method(0, uart, "puts", c_uart_puts); mrbc_define_method(0, uart, "bytes_available", c_uart_bytes_available); mrbc_define_method(0, uart, "bytes_to_write", c_uart_bytes_to_write); mrbc_define_method(0, uart, "can_read_line", c_uart_can_read_line); mrbc_define_method(0, uart, "flush", c_uart_flush); mrbc_define_method(0, uart, "clear_rx_buffer", c_uart_nop); mrbc_define_method(0, uart, "clear_tx_buffer", c_uart_nop); mrbc_define_method(0, uart, "send_break", c_uart_nop); mrb_value none=mrbc_integer_value(0); mrb_value odd=mrbc_integer_value(1); mrb_value even=mrbc_integer_value(2); mrbc_set_class_const(uart, mrbc_str_to_symid("NONE"), &none); mrbc_set_class_const(uart, mrbc_str_to_symid("ODD"), &odd); mrbc_set_class_const(uart, mrbc_str_to_symid("EVEN"), &even); } } //extern