diff --git a/libtock-sync/peripherals/gpio_async.c b/libtock-sync/peripherals/gpio_async.c index b51f7eed3..963a4412f 100644 --- a/libtock-sync/peripherals/gpio_async.c +++ b/libtock-sync/peripherals/gpio_async.c @@ -1,92 +1,68 @@ #include "gpio_async.h" -struct gpio_async_data { - bool fired; - bool value; - returncode_t ret; -}; - -static struct gpio_async_data result = { .fired = false }; +#include "syscalls/gpio_async_syscalls.h" -static void gpio_async_callback_command(returncode_t ret, bool value) { - result.fired = true; - result.value = value; - result.ret = ret; -} - -static returncode_t gpio_async_op(uint32_t port, uint8_t pin, returncode_t (*op)(uint32_t, uint8_t, - libtock_gpio_async_callback_command)) { - returncode_t err; - result.fired = false; +static returncode_t gpio_async_command(uint32_t port, uint8_t pin, returncode_t (*command_fn)(uint32_t, uint8_t)) { + returncode_t ret; - err = op(port, pin, gpio_async_callback_command); - if (err != RETURNCODE_SUCCESS) return err; + ret = command_fn(port, pin); + if (ret != RETURNCODE_SUCCESS) return ret; - // Wait for the callback. - yield_for(&result.fired); - return result.ret; + ret = libtocksync_gpio_async_yield_wait_for_generic_command(); + return ret; } returncode_t libtocksync_gpio_async_make_output(uint32_t port, uint8_t pin) { - return gpio_async_op(port, pin, libtock_gpio_async_make_output); + return gpio_async_command(port, pin, libtock_gpio_async_command_make_output); } returncode_t libtocksync_gpio_async_set(uint32_t port, uint8_t pin) { - return gpio_async_op(port, pin, libtock_gpio_async_set); + return gpio_async_command(port, pin, libtock_gpio_async_command_set); } returncode_t libtocksync_gpio_async_clear(uint32_t port, uint8_t pin) { - return gpio_async_op(port, pin, libtock_gpio_async_clear); + return gpio_async_command(port, pin, libtock_gpio_async_command_clear); } returncode_t libtocksync_gpio_async_toggle(uint32_t port, uint8_t pin) { - return gpio_async_op(port, pin, libtock_gpio_async_toggle); + return gpio_async_command(port, pin, libtock_gpio_async_command_toggle); } returncode_t libtocksync_gpio_async_make_input(uint32_t port, uint8_t pin, libtock_gpio_input_mode_t pin_config) { - returncode_t err; - result.fired = false; + returncode_t ret; - err = libtock_gpio_async_make_input(port, pin, pin_config, gpio_async_callback_command); - if (err != RETURNCODE_SUCCESS) return err; + ret = libtock_gpio_async_command_make_input(port, pin, pin_config); + if (ret != RETURNCODE_SUCCESS) return ret; - // Wait for the callback. - yield_for(&result.fired); - return result.ret; + ret = libtocksync_gpio_async_yield_wait_for_generic_command(); + return ret; } returncode_t libtocksync_gpio_async_read(uint32_t port, uint8_t pin, bool* value) { - returncode_t err; - result.fired = false; - - err = libtock_gpio_async_read(port, pin, gpio_async_callback_command); - if (err != RETURNCODE_SUCCESS) return err; + returncode_t ret; - // Wait for the callback. - yield_for(&result.fired); - if (result.ret != RETURNCODE_SUCCESS) return result.ret; + ret = libtock_gpio_async_command_read(port, pin); + if (ret != RETURNCODE_SUCCESS) return ret; - *value = result.value; - return RETURNCODE_SUCCESS; + ret = libtocksync_gpio_async_yield_wait_for_read(value); + return ret; } returncode_t libtocksync_gpio_async_enable_interrupt(uint32_t port, uint8_t pin, libtock_gpio_interrupt_mode_t irq_config) { - returncode_t err; - result.fired = false; + returncode_t ret; - err = libtock_gpio_async_enable_interrupt(port, pin, irq_config, gpio_async_callback_command); - if (err != RETURNCODE_SUCCESS) return err; + ret = libtock_gpio_async_command_enable_interrupt(port, pin, irq_config); + if (ret != RETURNCODE_SUCCESS) return ret; - // Wait for the callback. - yield_for(&result.fired); - return result.ret; + ret = libtocksync_gpio_async_yield_wait_for_generic_command(); + return ret; } returncode_t libtocksync_gpio_async_disable_interrupt(uint32_t port, uint8_t pin) { - return gpio_async_op(port, pin, libtock_gpio_async_disable_interrupt); + return gpio_async_command(port, pin, libtock_gpio_async_command_disable_interrupt); } returncode_t libtocksync_gpio_async_disable_sync(uint32_t port, uint8_t pin) { - return gpio_async_op(port, pin, libtock_gpio_async_disable); + return gpio_async_command(port, pin, libtock_gpio_async_command_disable); } diff --git a/libtock-sync/peripherals/syscalls/gpio_async_syscalls.c b/libtock-sync/peripherals/syscalls/gpio_async_syscalls.c new file mode 100644 index 000000000..292e1228b --- /dev/null +++ b/libtock-sync/peripherals/syscalls/gpio_async_syscalls.c @@ -0,0 +1,21 @@ +#include "gpio_async_syscalls.h" + +returncode_t libtocksync_gpio_async_yield_wait_for_generic_command(void) { + yield_waitfor_return_t ret; + ret = yield_wait_for(DRIVER_NUM_GPIO_ASYNC, 0); + + return (returncode_t) ret.data0; +} + +returncode_t libtocksync_gpio_async_yield_wait_for_read(bool* value) { + yield_waitfor_return_t ywf; + returncode_t ret; + + ywf = yield_wait_for(DRIVER_NUM_GPIO_ASYNC, 0); + + ret = (returncode_t) ywf.data0; + if (ret != RETURNCODE_SUCCESS) return ret; + + *value = (bool) ywf.data1; + return ret; +} diff --git a/libtock-sync/peripherals/syscalls/gpio_async_syscalls.h b/libtock-sync/peripherals/syscalls/gpio_async_syscalls.h new file mode 100644 index 000000000..bb2c8fd76 --- /dev/null +++ b/libtock-sync/peripherals/syscalls/gpio_async_syscalls.h @@ -0,0 +1,20 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Wait for a GPIO-Async operation with no values to finish. +// +// In lieu of redundant `wait_for_[set|clear|...]`, generic_command can be used +// for any operation that only reports success or failure, expecting no values. +returncode_t libtocksync_gpio_async_yield_wait_for_generic_command(void); + +returncode_t libtocksync_gpio_async_yield_wait_for_read(bool* value); + +#ifdef __cplusplus +} +#endif