From 2788b27a6f51f19e658621fcb1ed148b8c56fb32 Mon Sep 17 00:00:00 2001 From: Will Xyen Date: Sat, 21 Sep 2019 14:15:50 -0400 Subject: [PATCH] aciodrv: Add KFCA support --- src/main/aciodrv/Module.mk | 1 + src/main/aciodrv/kfca.c | 100 +++++++++++++++++++++++++++++++++++++ src/main/aciodrv/kfca.h | 30 +++++++++++ 3 files changed, 131 insertions(+) create mode 100644 src/main/aciodrv/kfca.c create mode 100644 src/main/aciodrv/kfca.h diff --git a/src/main/aciodrv/Module.mk b/src/main/aciodrv/Module.mk index c7b822a..bb30a47 100644 --- a/src/main/aciodrv/Module.mk +++ b/src/main/aciodrv/Module.mk @@ -5,5 +5,6 @@ libs_aciodrv := \ src_aciodrv := \ device.c \ icca.c \ + kfca.c \ port.c \ diff --git a/src/main/aciodrv/kfca.c b/src/main/aciodrv/kfca.c new file mode 100644 index 0000000..ef0599d --- /dev/null +++ b/src/main/aciodrv/kfca.c @@ -0,0 +1,100 @@ +#define LOG_MODULE "aciodrv-kfca" + +#include +#include + +#include "aciodrv/device.h" + +#include "util/log.h" + +static bool aciodrv_kfca_watchdog_start(uint8_t node_id) +{ + + // exit early and don't actually call watchdog + // the watchdog call actually returns different sized packets depending on the state + // this results in an issue during packet processing (see: #68) + return true; + + /* + struct ac_io_message msg; + + msg.addr = node_id + 1; + msg.cmd.code = ac_io_u16(AC_IO_CMD_KFCA_WATCHDOG); + msg.cmd.nbytes = 2; + msg.cmd.nbytes = 2; + + // uint16_t: 6000 + msg.cmd.raw[0] = 23; + msg.cmd.raw[1] = 112; + + if (!aciodrv_send_and_recv(&msg, offsetof(struct ac_io_message, cmd.raw) + 2)) { + log_warning("Starting watchdog failed"); + return false; + } + + log_warning("Started watchdog of node %d, status: %d", + node_id, msg.cmd.status); + + return true; + */ +} + +static bool aciodrv_kfca_amp(uint8_t node_id) +{ + struct ac_io_message msg; + + msg.addr = node_id + 1; + msg.cmd.code = ac_io_u16(AC_IO_CMD_KFCA_AMP_CONTROL); + msg.cmd.nbytes = 4; + + // yes this sets the amp to 100% volume + // TODO: expose this to sdvxio instead at some point + msg.cmd.raw[0] = 0; + msg.cmd.raw[1] = 0; + msg.cmd.raw[2] = 0; + msg.cmd.raw[3] = 0; + + if (!aciodrv_send_and_recv(&msg, offsetof(struct ac_io_message, cmd.raw) + 1)) { + log_warning("Setting AMP failed"); + return false; + } + + log_warning("Started AMP node %d", node_id); + + return true; +} + +bool aciodrv_kfca_init(uint8_t node_id) +{ + if (!aciodrv_kfca_watchdog_start(node_id)) { + return false; + } + + if (!aciodrv_kfca_amp(node_id)) { + return false; + } + + return true; +} + +bool aciodrv_kfca_poll(uint8_t node_id, const struct ac_io_kfca_poll_out* pout, struct ac_io_kfca_poll_in* pin) +{ + struct ac_io_message msg; + + msg.addr = node_id + 1; + msg.cmd.code = ac_io_u16(AC_IO_CMD_KFCA_POLL); + msg.cmd.nbytes = sizeof(*pout); + /* buffer size of data we expect */ + msg.cmd.kfca_poll_out = *pout; + + if (!aciodrv_send_and_recv(&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.kfca_poll_in, sizeof(*pin)); + } + + return true; +} diff --git a/src/main/aciodrv/kfca.h b/src/main/aciodrv/kfca.h new file mode 100644 index 0000000..b2d7319 --- /dev/null +++ b/src/main/aciodrv/kfca.h @@ -0,0 +1,30 @@ +#ifndef ACIODRV_KFCA_H +#define ACIODRV_KFCA_H + +#include "acio/kfca.h" + +/** + * Initialize an KFCA node. + * + * @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_kfca_init(uint8_t node_id); + +/** + * Poll the KFCA io board + * + * @param node_id Id of the node to query (0 based). + * @param state Pointer to a state struct to return the current state to + * (optional, NULL for none). + * @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_kfca_poll(uint8_t node_id, const struct ac_io_kfca_poll_out* pout, struct ac_io_kfca_poll_in* pin); + +#endif