From 85c9c444f12c39992691fb0d4b4d7961c9ffb16b Mon Sep 17 00:00:00 2001 From: Will Xyen Date: Sun, 12 Sep 2021 19:13:45 -0700 Subject: [PATCH] aciotest: add RVOL test, and change to use product types instead of names --- src/main/aciodrv/Module.mk | 1 + src/main/aciodrv/rvol.c | 79 +++++++++++++++++++++++++++++++++++++ src/main/aciodrv/rvol.h | 36 +++++++++++++++++ src/main/aciotest/Module.mk | 3 +- src/main/aciotest/main.c | 35 +++++++++------- src/main/aciotest/rvol.c | 73 ++++++++++++++++++++++++++++++++++ src/main/aciotest/rvol.h | 14 +++++++ 7 files changed, 226 insertions(+), 15 deletions(-) create mode 100644 src/main/aciodrv/rvol.c create mode 100644 src/main/aciodrv/rvol.h create mode 100644 src/main/aciotest/rvol.c create mode 100644 src/main/aciotest/rvol.h diff --git a/src/main/aciodrv/Module.mk b/src/main/aciodrv/Module.mk index 154eabb..0aad3e3 100644 --- a/src/main/aciodrv/Module.mk +++ b/src/main/aciodrv/Module.mk @@ -8,5 +8,6 @@ src_aciodrv := \ icca.c \ kfca.c \ panb.c \ + rvol.c \ port.c \ diff --git a/src/main/aciodrv/rvol.c b/src/main/aciodrv/rvol.c new file mode 100644 index 0000000..375d0cc --- /dev/null +++ b/src/main/aciodrv/rvol.c @@ -0,0 +1,79 @@ +#define LOG_MODULE "aciodrv-rvol" + +#include +#include + +#include "aciodrv/device.h" + +#include "util/log.h" + +static bool aciodrv_rvol_change_expand_mode( + struct aciodrv_device_ctx *device, + uint8_t node_id, + uint8_t mode) +{ + struct ac_io_message msg; + + log_assert(device); + + msg.addr = node_id + 1; + msg.cmd.code = ac_io_u16(AC_IO_CMD_RVOL_SET_EXPAND_MODE); + msg.cmd.nbytes = 1; + + msg.cmd.raw[0] = (mode | (2 * mode)) << 6; + + if (!aciodrv_send_and_recv( + device, &msg, offsetof(struct ac_io_message, cmd.raw) + 1)) { + log_warning("RVOL change expand mode failed %d", node_id); + return false; + } + + log_info("I/O expand mode set %d, mode: %d", + node_id, mode); + + return true; +} + +bool aciodrv_rvol_init( + struct aciodrv_device_ctx *device, + uint8_t node_id) +{ + log_assert(device); + + if (!aciodrv_rvol_change_expand_mode(device, node_id, 1)) { + return false; + } + + return true; +} + +bool aciodrv_rvol_poll( + struct aciodrv_device_ctx *device, + uint8_t node_id, + const struct ac_io_rvol_poll_out *pout, + struct ac_io_rvol_poll_in *pin) +{ + struct ac_io_message msg; + + log_assert(device); + + msg.addr = node_id + 1; + msg.cmd.code = ac_io_u16(AC_IO_CMD_RVOL_POLL); + msg.cmd.nbytes = sizeof(*pout); + /* buffer size of data we expect */ + msg.cmd.rvol_poll_out = *pout; + + if (!aciodrv_send_and_recv( + device, + &msg, + offsetof(struct ac_io_message, cmd.raw) + sizeof(*pin))) { + log_warning("Polling of node %d failed", node_id + 1); + return false; + } + + if (pin != NULL) { + memcpy(pin, &msg.cmd.rvol_poll_in, sizeof(*pin)); + } + + return true; +} diff --git a/src/main/aciodrv/rvol.h b/src/main/aciodrv/rvol.h new file mode 100644 index 0000000..875164b --- /dev/null +++ b/src/main/aciodrv/rvol.h @@ -0,0 +1,36 @@ +#ifndef ACIODRV_RVOL_H +#define ACIODRV_RVOL_H + +#include "acio/rvol.h" + +/** + * Initialize a Revolte (KFCA 1.5) IO board + * + * @param device Context of opened device + * @param node_id Id of the node to initialize (0 based). + * @return True if successful, false on error. + * @note This module is supposed to be used in combination with the common + * device driver foundation. + * @see driver.h + */ +bool aciodrv_rvol_init(struct aciodrv_device_ctx *device, uint8_t node_id); + +/** + * Poll a Revolte (KFCA 1.5) IO board + * + * @param device Context of opened device + * @param node_id Id of the node to query (0 based). + * @param pout Pointer to a state struct to write to device + * @param pin Pointer to a state struct to return the current state to + * @return True on success, false on error. + * @note This module is supposed to be used in combination with the common + * device driver foundation. + * @see driver.h + */ +bool aciodrv_rvol_poll( + struct aciodrv_device_ctx *device, + uint8_t node_id, + const struct ac_io_rvol_poll_out *pout, + struct ac_io_rvol_poll_in *pin); + +#endif diff --git a/src/main/aciotest/Module.mk b/src/main/aciotest/Module.mk index 1c66387..7ec2634 100644 --- a/src/main/aciotest/Module.mk +++ b/src/main/aciotest/Module.mk @@ -9,6 +9,7 @@ libs_aciotest := \ src_aciotest := \ icca.c \ kfca.c \ - bi2a-sdvx.c \ panb.c \ + rvol.c \ + bi2a-sdvx.c \ main.c \ diff --git a/src/main/aciotest/main.c b/src/main/aciotest/main.c index e773db7..842c2c1 100644 --- a/src/main/aciotest/main.c +++ b/src/main/aciotest/main.c @@ -11,6 +11,7 @@ #include "aciotest/icca.h" #include "aciotest/kfca.h" #include "aciotest/panb.h" +#include "aciotest/rvol.h" #include "util/log.h" @@ -21,31 +22,37 @@ static uint8_t bi2a_mode = 0; * Enumerate supported ACIO nodes based on their product id. */ static bool aciotest_assign_handler( - char product[4], struct aciotest_handler_node_handler *handler) + uint32_t product_type, struct aciotest_handler_node_handler *handler) { - if (!memcmp(product, "ICCA", 4) || !memcmp(product, "ICCB", 4) || - !memcmp(product, "ICCC", 4)) { + if (product_type == AC_IO_NODE_TYPE_ICCA) { handler->init = aciotest_icca_handler_init; handler->update = aciotest_icca_handler_update; return true; } - if (!memcmp(product, "KFCA", 4)) { + if (product_type == AC_IO_NODE_TYPE_KFCA) { handler->init = aciotest_kfca_handler_init; handler->update = aciotest_kfca_handler_update; return true; } - if (!memcmp(product, "PANB", 4)) { + if (product_type == AC_IO_NODE_TYPE_PANB) { handler->init = aciotest_panb_handler_init; handler->update = aciotest_panb_handler_update; return true; } - if (!memcmp(product, "BI2A", 4)) { + if (product_type == AC_IO_NODE_TYPE_RVOL) { + handler->init = aciotest_rvol_handler_init; + handler->update = aciotest_rvol_handler_update; + + return true; + } + + if (product_type == AC_IO_NODE_TYPE_BI2A) { if (bi2a_mode == 0) { handler->init = aciotest_bi2a_sdvx_handler_init; handler->update = aciotest_bi2a_sdvx_handler_update; @@ -99,22 +106,22 @@ int main(int argc, char **argv) for (uint8_t i = 0; i < node_count; i++) { char product[4]; + uint32_t product_type = aciodrv_device_get_node_product_type(device, i); aciodrv_device_get_node_product_ident(device, i, product); + printf( - "> %d: %c%c%c%c\n", + "> %d: %c%c%c%c (%08x)\n", i + 1, product[0], product[1], product[2], - product[3]); + product[3], + product_type); - if (!aciotest_assign_handler(product, &handler[i])) { + if (!aciotest_assign_handler(product_type, &handler[i])) { printf( - "ERROR: Unsupported acio node product %c%c%c%c on node %d\n", - product[0], - product[1], - product[2], - product[3], + "ERROR: Unsupported acio node product %08x on node %d\n", + product_type, i); } } diff --git a/src/main/aciotest/rvol.c b/src/main/aciotest/rvol.c new file mode 100644 index 0000000..3240f4c --- /dev/null +++ b/src/main/aciotest/rvol.c @@ -0,0 +1,73 @@ +#include "aciotest/rvol.h" + +#include "acio/acio.h" + +#include +#include +#include + +#include "aciodrv/rvol.h" + +static struct ac_io_rvol_poll_out pout; + +bool aciotest_rvol_handler_init( + struct aciodrv_device_ctx *device, uint8_t node_id, void **ctx) +{ + memset(&pout, 0, sizeof(pout)); + return aciodrv_rvol_init(device, node_id); +} + +bool aciotest_rvol_handler_update( + struct aciodrv_device_ctx *device, uint8_t node_id, void *ctx) +{ + struct ac_io_rvol_poll_in pin; + + if (!aciodrv_rvol_poll(device, node_id, &pout, &pin)) { + return false; + } + uint8_t selected_light = pin.spinners[0] / 43; + + printf( + ">>> RVOL %d\n" + "Press: %3d %3d %3d\n" + " %3d %3d\n" + "\n" + "Spin: %3d %3d %3d\n" + " %3d %3d\n" + "\n" + "Pedal: %3d\n" + "\n" + "Editing light #%d R: %d G: %d B: %d\n" + "(Change light with Spinner 1, values with 3-5)\n", + node_id, + pin.buttons_2.spinner_1, + pin.buttons_3.spinner_3, + pin.buttons_1.spinner_5, + pin.buttons_2.spinner_2, + pin.buttons_1.spinner_4, + pin.spinners[0], + pin.spinners[2], + pin.spinners[4], + pin.spinners[1], + pin.spinners[3], + !pin.buttons_1.pedal, + selected_light, + pin.spinners[2] / 2, + pin.spinners[3] / 2, + pin.spinners[4] / 2 + ); + + memset(&pout, 0, sizeof(pout)); + + if (selected_light == 5) { + pout.title.r = pin.spinners[2] / 2; + pout.title.g = pin.spinners[3] / 2; + pout.title.b = pin.spinners[4] / 2; + } else { + pout.spinner[selected_light].r = pin.spinners[2] / 2; + pout.spinner[selected_light].g = pin.spinners[3] / 2; + pout.spinner[selected_light].b = pin.spinners[4] / 2; + } + + return true; +} diff --git a/src/main/aciotest/rvol.h b/src/main/aciotest/rvol.h new file mode 100644 index 0000000..705a338 --- /dev/null +++ b/src/main/aciotest/rvol.h @@ -0,0 +1,14 @@ +#ifndef ACIOTEST_RVOL_H +#define ACIOTEST_RVOL_H + +#include +#include + +#include "aciodrv/device.h" + +bool aciotest_rvol_handler_init( + struct aciodrv_device_ctx *device, uint8_t node_id, void **ctx); +bool aciotest_rvol_handler_update( + struct aciodrv_device_ctx *device, uint8_t node_id, void *ctx); + +#endif