#ifndef _MRBC_UART_H #define _MRBC_UART_H #include "mrbc_api.h" #include "mrubyc.h" #ifdef __cplusplus extern "C" { #endif 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 #ifdef __cplusplus } #endif void c_uart_setmode(mrbc_vm *vm, mrbc_value v[], int argc){ #if defined(NO_UART_HANDLE) void* handle = NULL; #else UART_HANDLE *handle = (UART_HANDLE *)v[0].instance->data; #endif 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 = MRBC_UART_NONE; 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); mrbcUartSetMode(handle,baud_rate,datb,stpb,prty); 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){ #if defined(NO_UART_HANDLE) void* handle = NULL; #else v[0] = mrbc_instance_new(vm, v[0].cls, sizeof(UART_HANDLE)); 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; handle->unit_num = unit_num; #endif mrbcUartInit(handle); c_uart_setmode( vm, v, argc ); } void c_uart_write(mrb_vm *vm, mrb_value *v, int argc){ #if defined(NO_UART_HANDLE) void* handle = NULL; #else UART_HANDLE *handle = (UART_HANDLE *)v[0].instance->data; #endif int size = 0; if(argc>0){ char *buf = (char*) make_output_buffer( vm, v, argc, 1, &size ); size=mrbcUartWrite(handle,buf,size); } SET_RETURN( mrbc_integer_value(size) ); } static void c_uart_puts(mrbc_vm *vm, mrbc_value v[], int argc){ #if defined(NO_UART_HANDLE) void* handle = NULL; #else UART_HANDLE *handle = (UART_HANDLE *)v[0].instance->data; #endif char zero[]="\n"; int size = 1; if(argc>0){ char *buf = (char*) make_output_buffer( vm, v, argc, 1, &size ); size=mrbcUartWrite(handle,buf,size); if( size == 0 || buf[size-1] != '\n' ){ size=1; }else{ size=0; } } if(size) mrbcUartWrite(handle,zero,1); SET_NIL_RETURN(); } void c_uart_read(mrb_vm *vm, mrb_value *v, int argc){ #if defined(NO_UART_HANDLE) void* handle = NULL; #else UART_HANDLE *handle = (UART_HANDLE *)v[0].instance->data; #endif mrbc_value ret = mrbc_nil_value(); if(argc>0){ int size = GET_INT_ARG(1); char *buf = (char*) mrbc_alloc(vm, size); size = mrbcUartRead( handle, 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){ #if defined(NO_UART_HANDLE) void* handle = NULL; #else UART_HANDLE *handle = (UART_HANDLE *)v[0].instance->data; #endif mrbc_value ret = mrbc_nil_value(); int size=0; while( !size ) size = mrbcUartCanReadLine(handle); char *buf = (char*) mrbc_alloc(vm, size); size = mrbcUartRead( handle, 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_bytes_available(mrbc_vm *vm, mrbc_value v[], int argc){ #if defined(NO_UART_HANDLE) void* handle = NULL; #else UART_HANDLE *handle = (UART_HANDLE *)v[0].instance->data; #endif int value=mrbcUartAvailable( handle ); SET_INT_RETURN( value ); } static void c_uart_bytes_to_write(mrbc_vm *vm, mrbc_value v[], int argc){ #if defined(NO_UART_HANDLE) void* handle = NULL; #else UART_HANDLE *handle = (UART_HANDLE *)v[0].instance->data; #endif int value=mrbcUartByteToWrite(handle); SET_INT_RETURN( value ); } static void c_uart_can_read_line(mrbc_vm *vm, mrbc_value v[], int argc){ #if defined(NO_UART_HANDLE) void* handle = NULL; #else UART_HANDLE *handle = (UART_HANDLE *)v[0].instance->data; #endif int pos=mrbcUartCanReadLine(handle); SET_INT_RETURN( pos ); } static void c_uart_flush(mrbc_vm *vm, mrbc_value v[], int argc){ #if defined(NO_UART_HANDLE) void* handle = NULL; #else UART_HANDLE *handle = (UART_HANDLE *)v[0].instance->data; #endif mrbcUartFlush(handle); } static void c_uart_clear_rx_buffer(mrbc_vm *vm, mrbc_value v[], int argc){ #if defined(NO_UART_HANDLE) void* handle = NULL; #else UART_HANDLE *handle = (UART_HANDLE *)v[0].instance->data; #endif mrbcUartClearRx(handle); } static void c_uart_clear_tx_buffer(mrbc_vm *vm, mrbc_value v[], int argc){ #if defined(NO_UART_HANDLE) void* handle = NULL; #else UART_HANDLE *handle = (UART_HANDLE *)v[0].instance->data; #endif mrbcUartClearTx(handle); } 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_clear_rx_buffer); mrbc_define_method(0, uart, "clear_tx_buffer", c_uart_clear_tx_buffer); mrbc_define_method(0, uart, "send_break", c_uart_nop); mrb_value mrbc_uart_none=mrbc_integer_value(MRBC_UART_NONE); mrb_value mrbc_uart_even=mrbc_integer_value(MRBC_UART_EVEN); mrb_value mrbc_uart_odd=mrbc_integer_value(MRBC_UART_ODD); mrbc_set_class_const(uart, mrbc_str_to_symid("NONE"), &mrbc_uart_none); mrbc_set_class_const(uart, mrbc_str_to_symid("EVEN"), &mrbc_uart_even); mrbc_set_class_const(uart, mrbc_str_to_symid("ODD") , &mrbc_uart_odd); } #endif