93 lines
2.4 KiB
C
93 lines
2.4 KiB
C
#include <mruby.h>
|
|
#include <mruby/class.h>
|
|
#include <mruby/data.h>
|
|
#include <mruby/hash.h>
|
|
|
|
/* Private */
|
|
#include "adc.h"
|
|
|
|
typedef struct {
|
|
uint32_t channel;
|
|
uint32_t avg;
|
|
} mrb_adc_t;
|
|
|
|
static void mrb_adc_free(mrb_state *mrb, void *ptr);
|
|
|
|
const struct mrb_data_type mrb_adc_type = {
|
|
.struct_name = "ADC",
|
|
.dfree = mrb_adc_free,
|
|
};
|
|
|
|
static void mrb_adc_free(mrb_state *mrb, void *ptr) {
|
|
mrb_free(mrb, ptr);
|
|
}
|
|
|
|
static mrb_value mrb_adc_initialize(mrb_state *mrb, mrb_value self) {
|
|
mrb_int channel_id;
|
|
mrb_value init_cfg;
|
|
|
|
uint32_t avg = 1;
|
|
|
|
mrb_int nargs = mrb_get_args(mrb, "i|H", &channel_id, &init_cfg);
|
|
|
|
if (nargs == 2) {
|
|
mrb_ensure_hash_type(mrb, init_cfg);
|
|
mrb_value ch_average = mrb_hash_get(mrb, init_cfg, mrb_symbol_value(mrb_intern_static(mrb, "average", 7)));
|
|
if (!mrb_nil_p(ch_average)) {
|
|
mrb_ensure_integer_type(mrb, ch_average);
|
|
avg = mrb_integer(ch_average);
|
|
}
|
|
}
|
|
|
|
mrb_adc_t *adc_ch = mrb_malloc(mrb, sizeof(mrb_adc_t));
|
|
if (adc_ch == NULL) {
|
|
mrb_raise(mrb, E_RUNTIME_ERROR, "Failed to allocate ADC struct");
|
|
}
|
|
|
|
adc_ch->channel = channel_id;
|
|
adc_ch->avg = avg;
|
|
|
|
mrb_machine_adc_impl_config(adc_ch->channel);
|
|
|
|
DATA_PTR(self) = adc_ch;
|
|
DATA_TYPE(self) = &mrb_adc_type;
|
|
|
|
return self;
|
|
}
|
|
|
|
static mrb_value mrb_adc_value(mrb_state *mrb, mrb_value self) {
|
|
mrb_adc_t *adc_ch = mrb_data_get_ptr(mrb, self, &mrb_adc_type);
|
|
if (adc_ch == NULL) {
|
|
mrb_raise(mrb, E_RUNTIME_ERROR, "Uninitialized ADC struct");
|
|
}
|
|
|
|
uint32_t adc_uv = 0;
|
|
|
|
for (uint32_t i = 0; i < adc_ch->avg; i++) {
|
|
adc_uv += mrb_machine_adc_impl_read(adc_ch->channel);
|
|
}
|
|
|
|
adc_uv = adc_uv / adc_ch->avg;
|
|
|
|
return mrb_int_value(mrb, adc_uv);
|
|
}
|
|
|
|
void mrb_machine_adc_gem_init(mrb_state *mrb) {
|
|
/**
|
|
* Example:
|
|
* analog_ch = Machine::ADC.new(0, {average: 4})
|
|
* analog_ch.value
|
|
*/
|
|
|
|
struct RClass *module_machine = mrb_define_module(mrb, "Machine");
|
|
struct RClass *class_adc = mrb_define_class_under(mrb, module_machine, "ADC", mrb->object_class);
|
|
|
|
MRB_SET_INSTANCE_TT(class_adc, MRB_TT_CDATA);
|
|
|
|
mrb_define_method(mrb, class_adc, "initialize", mrb_adc_initialize, MRB_ARGS_ARG(1, 1));
|
|
mrb_define_method(mrb, class_adc, "value", mrb_adc_value, MRB_ARGS_NONE());
|
|
}
|
|
|
|
void mrb_machine_adc_gem_final(mrb_state *mrb) {
|
|
/* Unused */
|
|
} |