#include static mrb_value mrb_read32(mrb_state *mrb, mrb_value self) { mrb_value addr = mrb_get_arg1(mrb); uint32_t addr_int = mrb_integer(addr); if (addr_int % 4 != 0) { mrb_raise(mrb, E_ARGUMENT_ERROR, "Address must be 32bits aligned"); } uint32_t val = *(volatile uint32_t *)(addr_int); return mrb_int_value(mrb, val); } static mrb_value mrb_read16(mrb_state *mrb, mrb_value self) { mrb_value addr = mrb_get_arg1(mrb); uint32_t addr_int = mrb_integer(addr); if (addr_int % 2 != 0) { mrb_raise(mrb, E_ARGUMENT_ERROR, "Address must be 16bits aligned"); } uint16_t val = *(volatile uint16_t *)(addr_int); return mrb_int_value(mrb, val); } static mrb_value mrb_read8(mrb_state *mrb, mrb_value self) { mrb_value addr = mrb_get_arg1(mrb); uint32_t addr_int = mrb_integer(addr); uint8_t val = *(volatile uint8_t *)(addr_int); return mrb_int_value(mrb, val); } static mrb_value mrb_write32(mrb_state *mrb, mrb_value self) { mrb_int addr, value; mrb_get_args(mrb, "ii", &addr, &value); uint32_t addr_int = (uint32_t)addr; uint32_t value_int = (uint32_t)value; if (addr_int % 4 != 0) { mrb_raise(mrb, E_ARGUMENT_ERROR, "Address must be 32bits aligned"); } *(volatile uint16_t *)(addr_int) = value_int; return mrb_nil_value(); } static mrb_value mrb_write16(mrb_state *mrb, mrb_value self) { mrb_int addr, value; mrb_get_args(mrb, "ii", &addr, &value); uint32_t addr_int = (uint32_t)addr; uint16_t value_int = (uint16_t)value; if (addr_int % 2 != 0) { mrb_raise(mrb, E_ARGUMENT_ERROR, "Address must be 16bits aligned"); } *(volatile uint16_t *)(addr_int) = value_int; return mrb_nil_value(); } static mrb_value mrb_write8(mrb_state *mrb, mrb_value self) { mrb_int addr, value; mrb_get_args(mrb, "ii", &addr, &value); uint32_t addr_int = (uint32_t)addr; uint8_t value_int = (uint8_t)value; *(volatile uint8_t *)(addr_int) = value_int; return mrb_nil_value(); } void mrb_machine_devmem_gem_init(mrb_state *mrb) { struct RClass *module_machine = mrb_define_module(mrb, "Machine"); struct RClass *class_devmem = mrb_define_class_under(mrb, module_machine, "DevMem", mrb->object_class); mrb_define_class_method(mrb, class_devmem, "read32", mrb_read32, MRB_ARGS_ARG(1, 0)); mrb_define_class_method(mrb, class_devmem, "read16", mrb_read16, MRB_ARGS_ARG(1, 0)); mrb_define_class_method(mrb, class_devmem, "read8", mrb_read8, MRB_ARGS_ARG(1, 0)); mrb_define_class_method(mrb, class_devmem, "write32", mrb_write32, MRB_ARGS_ARG(2, 0)); mrb_define_class_method(mrb, class_devmem, "write16", mrb_write16, MRB_ARGS_ARG(2, 0)); mrb_define_class_method(mrb, class_devmem, "write8", mrb_write8, MRB_ARGS_ARG(2, 0)); } void mrb_machine_devmem_gem_final(mrb_state *mrb) { /* Not used */ }