/* This file is part of MutekH. MutekH is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; version 2.1 of the License. MutekH is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . Copyright Julien Peeters (c) 2016 */ #include #include #include #include #include #include #include #include #include #include #include #include #define FIRST STM32_PE8 #define LAST STM32_PE15 static struct device_gpio_s gpio; static struct device_timer_s timer; static dev_timer_delay_t msec; static uint8_t brain_gpio_init_mask[] = { 0x55, 0x55 }; void otoroshi_startup(void) { printk("bmaaa: brain firmware started!\n"); ensure(!device_get_accessor_by_path(&gpio.base, NULL, "/gpio", DRIVER_CLASS_GPIO)); ensure(!device_get_accessor_by_path(&timer.base, NULL, "/timer4", DRIVER_CLASS_TIMER)); ensure(!dev_timer_init_sec(&timer, &msec, 0, 1, 1000)); DEVICE_OP(&gpio, set_output, FIRST, LAST, brain_gpio_init_mask, dev_gpio_mask0); DEVICE_OP(&gpio, set_mode, FIRST, LAST, dev_gpio_mask1, DEV_PIN_PUSHPULL); dev_timer_busy_wait_delay(&timer, msec * 100); DEVICE_OP(&gpio, set_output, FIRST, LAST, dev_gpio_mask0, dev_gpio_mask0); } enum shell_otoroshi_opts_e { OTOROSHI_OPT_RELAY = 0x1, OTOROSHI_OPT_STATE = 0x2, OTOROSHI_OPT_CLOSED = 0x4, OTOROSHI_OPT_OPEN = 0x8, OTOROSHI_OPT_PULSE = 0x10, OTOROSHI_OPT_DELAY = 0x20, }; struct termui_optctx_otoroshi_opts { uint8_t relay; bool_t state; size_t delay; }; static TERMUI_CON_COMMAND_PROTOTYPE(shell_otoroshi_relay) { struct termui_optctx_otoroshi_opts * c = ctx; struct device_timer_s timer; dev_timer_delay_t msec; struct device_gpio_s gpio; error_t err = 0; err = device_get_accessor_by_path(&gpio.base, NULL, "/gpio", DRIVER_CLASS_GPIO); if (err) return err; err = device_get_accessor_by_path(&timer.base, NULL, "/timer*", DRIVER_CLASS_TIMER); if (err) goto gpio_cleanup; err = dev_timer_init_sec(&timer, &msec, 0, 1, 1000); if (err) goto timer_cleanup; DEVICE_OP(&gpio, set_output, STM32_PE8, STM32_PE15, dev_gpio_mask0, dev_gpio_mask0); DEVICE_OP(&gpio, set_mode, STM32_PE8, STM32_PE15, dev_gpio_mask1, DEV_PIN_PUSHPULL); if (used & OTOROSHI_OPT_PULSE) { uint8_t id = STM32_PE8 + c->relay * 2; static uint8_t door_open_mask[1] = { 0x2 }; static uint8_t door_close_mask[1] = { 0x1 }; DEVICE_OP(&gpio, set_output, id, id + 1, door_open_mask, door_open_mask); dev_timer_wait_delay(&timer, msec * 100, 0); DEVICE_OP(&gpio, set_output, id, id, dev_gpio_mask0, dev_gpio_mask0); dev_timer_wait_delay(&timer, msec * c->delay, 0); DEVICE_OP(&gpio, set_output, id, id + 1, door_close_mask, door_close_mask); dev_timer_wait_delay(&timer, msec * 100, 0); DEVICE_OP(&gpio, set_output, id, id, dev_gpio_mask0, dev_gpio_mask0); } else { bool_t state = 0; if (used & OTOROSHI_OPT_STATE) state = c->state; else if (used & OTOROSHI_OPT_CLOSED) state = 0; else if (used & OTOROSHI_OPT_OPEN) state = 1; uint8_t id = STM32_PE8 + c->relay * 2 + state; DEVICE_OP(&gpio, set_output, id, id, dev_gpio_mask1, dev_gpio_mask1); dev_timer_wait_delay(&timer, msec * 100, 0); DEVICE_OP(&gpio, set_output, id, id, dev_gpio_mask0, dev_gpio_mask0); } timer_cleanup: device_put_accessor(&timer.base); gpio_cleanup: device_put_accessor(&gpio.base); return err; } static TERMUI_CON_OPT_DECL(otoroshi_opts) = { TERMUI_CON_OPT_INTEGER_RANGE_ENTRY("-r", "--relay", OTOROSHI_OPT_RELAY, struct termui_optctx_otoroshi_opts, relay, 1, 0, 3, TERMUI_CON_OPT_CONSTRAINTS(OTOROSHI_OPT_RELAY, 0)) TERMUI_CON_OPT_INTEGER_RANGE_ENTRY("-s", "--state", OTOROSHI_OPT_STATE, struct termui_optctx_otoroshi_opts, state, 1, 0, 1, TERMUI_CON_OPT_CONSTRAINTS(OTOROSHI_OPT_STATE, OTOROSHI_OPT_RELAY)) TERMUI_CON_OPT_ENTRY("-c", "--closed", OTOROSHI_OPT_CLOSED, TERMUI_CON_OPT_CONSTRAINTS(OTOROSHI_OPT_CLOSED | OTOROSHI_OPT_OPEN | OTOROSHI_OPT_STATE, OTOROSHI_OPT_RELAY)) TERMUI_CON_OPT_ENTRY("-o", "--open", OTOROSHI_OPT_OPEN, TERMUI_CON_OPT_CONSTRAINTS(OTOROSHI_OPT_CLOSED | OTOROSHI_OPT_OPEN | OTOROSHI_OPT_STATE, OTOROSHI_OPT_RELAY)) TERMUI_CON_OPT_ENTRY("-p", "--pulse", OTOROSHI_OPT_PULSE, TERMUI_CON_OPT_CONSTRAINTS(OTOROSHI_OPT_CLOSED | OTOROSHI_OPT_OPEN | OTOROSHI_OPT_STATE | OTOROSHI_OPT_PULSE, OTOROSHI_OPT_RELAY)) TERMUI_CON_OPT_INTEGER_ENTRY("-d", "--delay", OTOROSHI_OPT_DELAY, struct termui_optctx_otoroshi_opts, delay, 1, TERMUI_CON_OPT_CONSTRAINTS(OTOROSHI_OPT_CLOSED | OTOROSHI_OPT_OPEN | OTOROSHI_OPT_STATE | OTOROSHI_OPT_DELAY, OTOROSHI_OPT_RELAY | OTOROSHI_OPT_PULSE)) TERMUI_CON_LIST_END }; static TERMUI_CON_GROUP_DECL(shell_otoroshi_subgroup) = { TERMUI_CON_ENTRY(shell_otoroshi_relay, "relay", TERMUI_CON_OPTS_CTX(otoroshi_opts, OTOROSHI_OPT_RELAY, OTOROSHI_OPT_STATE | OTOROSHI_OPT_CLOSED | OTOROSHI_OPT_OPEN | OTOROSHI_OPT_PULSE | OTOROSHI_OPT_DELAY, NULL)) TERMUI_CON_LIST_END }; MUTEK_SHELL_ROOT_GROUP(shell_otoroshi_subgroup, "otoroshi");