iram void gpios_periodic(void) { gpio_t *gpio; const gpio_config_entry_t *cfg; unsigned int current; unsigned int duty; bool_t pwm_changed = false; for(current = 0; current < gpio_size; current++) { gpio = &gpios[current]; cfg = get_config(gpio); if((cfg->mode == gpio_counter) && (gpio->counter.debounce != 0)) { if(gpio->counter.debounce >= 10) gpio->counter.debounce -= 10; // 10 ms per tick else gpio->counter.debounce = 0; if(gpio->counter.debounce == 0) arm_counter(gpio); } if((cfg->mode == gpio_timer) && (gpio->timer.delay > 0)) { if(gpio->timer.delay >= 10) gpio->timer.delay -= 10; // 10 ms per tick else gpio->timer.delay = 0; if(gpio->timer.delay == 0) { set_output(gpio, !get_input(gpio)); if(cfg->timer.repeat) gpio->timer.delay = cfg->timer.delay; } } if((cfg->mode == gpio_pwm) && (gpio->pwm.delay_top > 0)) { if(++gpio->pwm.delay_current > gpio->pwm.delay_top) { gpio->pwm.delay_current = 0; duty = pwm_get_duty(gpio->pwm.channel); if(gpio->pwm.direction == gpio_up) { if(duty < gpio->pwm.min_duty) duty = gpio->pwm.min_duty; if(duty < 16) duty = 16; duty *= 115; duty /= 100; if(duty >= gpio->pwm.max_duty) { duty = gpio->pwm.max_duty; gpio->pwm.direction = gpio_down; } } else { if(duty > gpio->pwm.max_duty) duty = gpio->pwm.max_duty; duty *= 100; duty /= 115; if(duty <= gpio->pwm.min_duty) { duty = gpio->pwm.min_duty; gpio->pwm.direction = gpio_up; } if(duty < 16) { duty = 16; gpio->pwm.direction = gpio_up; } } pwm_changed = true; pwm_set_duty(duty, gpio->pwm.channel); } } } if(pwm_changed) pwm_start(); }
irom static void dump(const gpio_config_t *cfgs, const gpio_t *gpio_in, uint16_t size, char *str) { uint8_t current; uint16_t length; const gpio_t *gpio; const gpio_config_entry_t *cfg; for(current = 0; current < gpio_size; current++) { gpio = &gpios[current]; cfg = &cfgs->entry[current]; if(!gpio_in || (gpio_in->id == gpio->id)) { length = snprintf(str, size, "> gpio: %u, name: %s, mode: ", gpio->index, gpio->name); size -= length; str += length; length = 0; switch(cfg->mode) { case(gpio_disabled): { length = snprintf(str, size, "disabled"); break; } case(gpio_input): { length = snprintf(str, size, "input, state: %s", onoff(get_input(gpio))); break; } case(gpio_counter): { length = snprintf(str, size, "counter, state: %s, counter: %u, debounce: %u/%u, reset on get: %s", onoff(get_input(gpio)), gpio->counter.count, cfg->counter.debounce, gpio->counter.debounce, onoff(cfg->counter.reset_on_get)); break; } case(gpio_output): { length = snprintf(str, size, "output, state: %s, startup: %s", onoff(get_input(gpio)), onoff(cfg->output.startup_state)); break; } case(gpio_timer): { length = snprintf(str, size, "timer, direction: %s, delay: %u ms, repeat: %s, autotrigger: %s, active: %s, current state: %s", cfg->timer.direction == gpio_up ? "up" : "down", cfg->timer.delay, onoff(cfg->timer.repeat), onoff(cfg->timer.autotrigger), onoff(gpio->timer.delay > 0), onoff(get_input(gpio))); break; } case(gpio_pwm): { length = snprintf(str, size, "pwm, "); str += length; size -= length; if(gpio_flags.pwm_subsystem_active) length = snprintf(str, size, "active, current frequency: %u Hz, current duty: %u", 1000000 / pwm_get_period(), pwm_get_duty(gpio->pwm.channel)); else length = snprintf(str, size, "inactive"); str += length; size -= length; length = snprintf(str, size, "\ndefault min duty: %u, max duty: %u, speed: %u", cfg->pwm.min_duty, cfg->pwm.max_duty, cfg->pwm.speed); str += length; size -= length; length = snprintf(str, size, "\nactive min duty: %u, max duty %u, speed: %u", gpio->pwm.min_duty, gpio->pwm.max_duty, gpio->pwm.speed); break; } case(gpio_i2c): { length = snprintf(str, size, "i2c, pin: %s", cfg->i2c.pin == gpio_i2c_sda ? "sda" : "scl"); break; } default: { length = snprintf(str, size, "unknown mode"); break; } } str += length; size =- length; length = snprintf(str, size, "\n"); str += length; size -= length; } } }