#ifndef _MRBC_PWM_H #define _MRBC_PWM_H #include "mrbc_api.h" #include "mrubyc.h" typedef struct PWM_HANDLE { uint8_t pin_num; uint16_t duty_num; // unit 1/10000 uint32_t freq_num; } PWM_HANDLE; void c_pwm_sub(mrb_vm *vm, mrb_value *v){ PWM_HANDLE *handle = (PWM_HANDLE *)v[0].instance->data; mrbcPwmWrite(handle->pin_num, handle->freq_num, handle->duty_num); } void c_pwm_new(mrb_vm *vm, mrb_value *v, int argc){ v[0] = mrbc_instance_new(vm, v[0].cls, sizeof(PWM_HANDLE)); PWM_HANDLE *handle = (PWM_HANDLE *)v[0].instance->data; handle->pin_num = GET_INT_ARG(1); MRBC_KW_ARG(frequency, freq, duty); if( MRBC_ISNUMERIC(duty) ){ #if MRBC_USE_FLOAT handle->duty_num = (uint16_t) MRBC_TO_FLOAT(duty)*100; #else handle->duty_num = MRBC_TO_INT(duty)*100; #endif }else{ handle->duty_num = 5000; } if( MRBC_ISNUMERIC(frequency) ){ handle->freq_num = MRBC_TO_INT(frequency); }else if( MRBC_ISNUMERIC(freq) ){ handle->freq_num = MRBC_TO_INT(freq); }else{ handle->freq_num = 1000; } MRBC_KW_DELETE(frequency, freq, duty); c_pwm_sub(vm,v); } static void c_pwm_duty(mrbc_vm *vm, mrbc_value *v, int argc){ PWM_HANDLE *handle = (PWM_HANDLE *)v[0].instance->data; #if MRBC_USE_FLOAT handle->duty_num = (uint16_t) MRBC_ARG_F(1)*100; #else handle->duty_num = MRBC_ARG_I(1)*100; #endif c_pwm_sub(vm,v); } static void c_pwm_frequency(mrbc_vm *vm, mrbc_value *v, int argc){ PWM_HANDLE *handle = (PWM_HANDLE *)v[0].instance->data; handle->freq_num = MRBC_ARG_I(1); c_pwm_sub(vm,v); } #if MRBC_USE_FLOAT || MRBC_USE_STRING static void c_pwm_period_us(mrbc_vm *vm, mrbc_value *v, int argc){ PWM_HANDLE *handle = (PWM_HANDLE *)v[0].instance->data; uint16_t us = MRBC_ARG_I(1); uint32_t freq = ( us==0 ? 0 : 1000000 / us ); handle->freq_num = freq; c_pwm_sub(vm,v); } static void c_pwm_pulse_width_us(mrbc_vm *vm, mrbc_value *v, int argc){ PWM_HANDLE *handle = (PWM_HANDLE *)v[0].instance->data; handle->duty_num = MRBC_ARG_I(1)*(handle->freq_num)/100; //1e6/1e4 c_pwm_sub(vm,v); } #endif void mrbc_init_class_pwm(void){ mrbc_class *pwm = mrbc_define_class(0, "PWM", mrbc_class_object); mrbc_define_method(0, pwm, "new", c_pwm_new); mrbc_define_method(0, pwm, "duty", c_pwm_duty); mrbc_define_method(0, pwm, "frequency", c_pwm_frequency); #if MRBC_USE_FLOAT || MRBC_USE_STRING mrbc_define_method(0, pwm, "period_us", c_pwm_period_us); mrbc_define_method(0, pwm, "pulse_width_us", c_pwm_pulse_width_us); #endif } #endif