#include "arduino_spi.h" #include extern "C" { static SPISettings mySPISettings = SPISettings(1000000, MSBFIRST, SPI_MODE0); 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 void c_spi_setmode(mrbc_vm *vm, mrbc_value v[], int argc){ MRBC_KW_ARG( unit, frequency, mode, first_bit ); int32_t spi_freq = 1000000; int spi_mode = SPI_MODE0; int spi_first_bit = MSBFIRST; if( MRBC_KW_ISVALID(frequency) ) spi_freq = mrbc_integer(frequency); if( MRBC_KW_ISVALID(first_bit) ) spi_first_bit = mrbc_integer(first_bit); if( MRBC_KW_ISVALID(mode) ){ switch(mrbc_integer(mode)){ case 1: spi_mode = SPI_MODE1; break; case 2: spi_mode = SPI_MODE2; break; case 3: spi_mode = SPI_MODE3; break; } } mySPISettings = SPISettings(spi_freq, spi_first_bit, spi_mode); MRBC_KW_DELETE( unit, frequency, mode, first_bit ); } void c_spi_new(mrb_vm *vm, mrb_value *v, int argc){ v[0] = mrbc_instance_new(vm, v[0].cls, 0); c_spi_setmode( vm, v, argc ); SPI.begin(); } void c_spi_write(mrb_vm *vm, mrb_value *v, int argc){ uint8_t *buf = 0; int bufsiz = 0; if(argc>1){ buf = make_output_buffer( vm, v, argc, 1, &bufsiz ); SPI.beginTransaction(mySPISettings); SPI.transfer(buf, bufsiz); SPI.endTransaction(); mrbc_free( vm, buf ); } SET_RETURN( mrbc_integer_value(bufsiz) ); } void c_spi_read(mrb_vm *vm, mrb_value *v, int argc){ mrbc_value ret = mrbc_nil_value(); if(argc>0){ int size = GET_INT_ARG(1); uint8_t *buf = (uint8_t*) mrbc_alloc(vm, size); memset(buf, 0, size); SPI.beginTransaction(mySPISettings); SPI.transfer(buf, size); SPI.endTransaction(); #if MRBC_USE_STRING ret = mrbc_string_new_alloc(vm, buf, size); #else ret = mrbc_array_new_alloc( vm, buf, size); mrbc_free( vm, buf ); #endif } SET_RETURN(ret); } void c_spi_transfer(mrb_vm *vm, mrb_value *v, int argc){ mrbc_value ret = mrbc_nil_value(); uint8_t *buf = 0; int bufsiz = 0; if(argc>0){ buf = make_output_buffer( vm, v, 1, 1, &bufsiz ); if(argc>1){ int additional_read_bytes = GET_INT_ARG(2); uint8_t *buf2 = (uint8_t *) mrbc_realloc(vm, buf, bufsiz + additional_read_bytes); buf = buf2; memset(buf + bufsiz, 0, additional_read_bytes); bufsiz += additional_read_bytes; } SPI.beginTransaction(mySPISettings); SPI.transfer(buf, bufsiz); SPI.endTransaction(); #if MRBC_USE_STRING ret = mrbc_string_new_alloc(vm, buf, bufsiz); #else ret = mrbc_array_new_alloc( vm, buf, bufsiz); mrbc_free( vm, buf ); #endif } SET_RETURN(ret); } void mrbc_init_class_spi(void){ mrb_class *spi = mrbc_define_class(0, "SPI", mrbc_class_object); mrbc_define_method(0, spi, "new", c_spi_new); mrbc_define_method(0, spi, "setmode", c_spi_setmode); mrbc_define_method(0, spi, "read", c_spi_read); mrbc_define_method(0, spi, "write", c_spi_write); mrbc_define_method(0, spi, "transfer", c_spi_transfer); mrb_value lsb=mrbc_integer_value(LSBFIRST); mrb_value msb=mrbc_integer_value(MSBFIRST); mrbc_set_class_const(spi, mrbc_str_to_symid("LSB_FIRST"), &lsb); mrbc_set_class_const(spi, mrbc_str_to_symid("MSB_FIRST"), &msb); } } //extern