Changed GPIO and ADC API.

Signed-off-by: Yilin Sun <imi415@imi.moe>
This commit is contained in:
Yilin Sun 2023-03-16 18:40:54 +08:00
parent 7f0aca015e
commit 6be5185d38
3 changed files with 72 additions and 46 deletions

View File

@ -7,7 +7,8 @@
#include "adc.h"
typedef struct {
uint32_t pin;
uint32_t channel;
uint32_t avg;
} mrb_adc_t;
static void mrb_adc_free(mrb_state *mrb, void *ptr);
@ -22,42 +23,65 @@ static void mrb_adc_free(mrb_state *mrb, void *ptr) {
}
static mrb_value mrb_adc_initialize(mrb_state *mrb, mrb_value self) {
mrb_value init_cfg = mrb_get_arg1(mrb);
mrb_ensure_hash_type(mrb, init_cfg);
mrb_int channel_id;
mrb_value init_cfg;
mrb_value pin_num = mrb_hash_get(mrb, init_cfg, mrb_symbol_value(mrb_intern_static(mrb, "pin", 3)));
mrb_ensure_integer_type(mrb, pin_num);
uint32_t avg = 1;
mrb_adc_t *analog_pin = mrb_malloc(mrb, sizeof(mrb_adc_t));
mrb_int nargs = mrb_get_args(mrb, "i|H", &channel_id, &init_cfg);
analog_pin->pin = mrb_integer(pin_num);
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_machine_adc_impl_config(analog_pin->pin);
mrb_adc_t *adc_ch = mrb_malloc(mrb, sizeof(mrb_adc_t));
DATA_PTR(self) = analog_pin;
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 *analog_pin = mrb_data_get_ptr(mrb, self, &mrb_adc_type);
if (analog_pin == NULL) {
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 = mrb_machine_adc_impl_read(analog_pin->pin);
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, 0));
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());
}

View File

@ -3,7 +3,7 @@
#include <stdint.h>
int mrb_machine_adc_impl_config(uint32_t pin);
int mrb_machine_adc_impl_read(uint32_t pin);
int mrb_machine_adc_impl_config(uint32_t channel);
int mrb_machine_adc_impl_read(uint32_t channel);
#endif // MRBGEMS_MACHINE_ADC_ADC_H

View File

@ -24,47 +24,50 @@ static void mrb_gpio_free(mrb_state *mrb, void *ptr) {
}
static mrb_value mrb_gpio_initialize(mrb_state *mrb, mrb_value self) {
mrb_value init_cfg = mrb_get_arg1(mrb);
mrb_ensure_hash_type(mrb, init_cfg);
mrb_int pin_num;
mrb_value init_cfg;
mrb_int nargs = mrb_get_args(mrb, "i|H", &pin_num, &init_cfg);
machine_gpio_mode_t init_mode = MACHINE_GPIO_MODE_INPUT;
machine_gpio_value_t init_value = MACHINE_GPIO_LOW;
machine_gpio_pull_t init_pull = MACHINE_GPIO_PULL_NONE;
mrb_value pin_num = mrb_hash_get(mrb, init_cfg, mrb_symbol_value(mrb_intern_static(mrb, "pin", 3)));
mrb_ensure_integer_type(mrb, pin_num);
/* Optional parameters, use default if not received from hash */
mrb_value pin_mode = mrb_hash_get(mrb, init_cfg, mrb_symbol_value(mrb_intern_static(mrb, "mode", 4)));
if (!mrb_nil_p(pin_mode)) {
mrb_ensure_integer_type(mrb, pin_mode);
init_mode = mrb_integer(pin_mode);
if (init_mode >= MACHINE_GPIO_MODE_END) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "Invalid GPIO mode");
}
}
if (nargs == 2) {
mrb_ensure_hash_type(mrb, init_cfg);
mrb_value pin_pull = mrb_hash_get(mrb, init_cfg, mrb_symbol_value(mrb_intern_static(mrb, "pull", 4)));
if (!mrb_nil_p(pin_pull)) {
mrb_ensure_integer_type(mrb, pin_pull);
init_pull = mrb_integer(pin_pull);
if (init_pull >= MACHINE_GPIO_PULL_END) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "Invalid GPIO pull");
mrb_value pin_mode = mrb_hash_get(mrb, init_cfg, mrb_symbol_value(mrb_intern_static(mrb, "mode", 4)));
if (!mrb_nil_p(pin_mode)) {
mrb_ensure_integer_type(mrb, pin_mode);
init_mode = mrb_integer(pin_mode);
if (init_mode >= MACHINE_GPIO_MODE_END) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "Invalid GPIO mode");
}
}
}
mrb_value pin_initial_value = mrb_hash_get(mrb, init_cfg, mrb_symbol_value(mrb_intern_static(mrb, "init", 4)));
if (!mrb_nil_p(pin_initial_value)) {
mrb_ensure_integer_type(mrb, pin_initial_value);
init_value = mrb_integer(pin_initial_value);
if (init_value >= MACHINE_GPIO_END) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "Invalid GPIO initial value");
mrb_value pin_pull = mrb_hash_get(mrb, init_cfg, mrb_symbol_value(mrb_intern_static(mrb, "pull", 4)));
if (!mrb_nil_p(pin_pull)) {
mrb_ensure_integer_type(mrb, pin_pull);
init_pull = mrb_integer(pin_pull);
if (init_pull >= MACHINE_GPIO_PULL_END) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "Invalid GPIO pull");
}
}
mrb_value pin_initial_value = mrb_hash_get(mrb, init_cfg, mrb_symbol_value(mrb_intern_static(mrb, "init", 4)));
if (!mrb_nil_p(pin_initial_value)) {
mrb_ensure_integer_type(mrb, pin_initial_value);
init_value = mrb_integer(pin_initial_value);
if (init_value >= MACHINE_GPIO_END) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "Invalid GPIO initial value");
}
}
}
mrb_gpio_t *pin = mrb_malloc(mrb, sizeof(mrb_gpio_t));
pin->pin = mrb_integer(pin_num);
pin->pin = pin_num;
pin->cfg.initial_value = init_value;
pin->cfg.mode = init_mode;
pin->cfg.pull = init_pull;
@ -173,13 +176,12 @@ static mrb_value mrb_gpio_config(mrb_state *mrb, mrb_value self) {
void mrb_machine_gpio_gem_init(mrb_state *mrb) {
/**
* Example:
* pin_led = led = Machine::GPIO.new({
* pin: 10,
* pin_led = led = Machine::GPIO.new(10, {
* mode: Machine::GPIO::OUTPUT_OD,
* pull: Machine::GPIO::PULL_NONE,
* init: Machine::GPIO::ON
* })
* pin_btn = Machine::GPIO.new({pin: 2}) # Default mode is Machine::GPIO::INPUT
* pin_btn = Machine::GPIO.new(2) # Default mode is Machine::GPIO::INPUT
* pin_led.on # Set to logical high
* pin_led.off # Set to logical low
* pin_led.toggle # Toggle.
@ -205,7 +207,7 @@ void mrb_machine_gpio_gem_init(mrb_state *mrb) {
mrb_define_const(mrb, class_gpio, "OUTPUT_OD", mrb_fixnum_value(MACHINE_GPIO_MODE_OUTPUT_OPENDRAIN));
/* Instance methods */
mrb_define_method(mrb, class_gpio, "initialize", mrb_gpio_initialize, MRB_ARGS_ARG(1, 0));
mrb_define_method(mrb, class_gpio, "initialize", mrb_gpio_initialize, MRB_ARGS_ARG(1, 1));
mrb_define_method(mrb, class_gpio, "on", mrb_gpio_on, MRB_ARGS_NONE());
mrb_define_method(mrb, class_gpio, "off", mrb_gpio_off, MRB_ARGS_NONE());
mrb_define_method(mrb, class_gpio, "toggle", mrb_gpio_toggle, MRB_ARGS_NONE());