diff --git a/src/main/aciodrv/device.c b/src/main/aciodrv/device.c index 1765a18..8d47616 100644 --- a/src/main/aciodrv/device.c +++ b/src/main/aciodrv/device.c @@ -12,11 +12,14 @@ /* Enable to dump all data to the logger */ //#define AC_IO_MSG_LOG -static uint8_t aciodrv_device_msg_counter = 1; -static uint8_t aciodrv_device_node_count; -static char aviodrv_device_node_products[16][4]; +struct aciodrv_device_ctx { + HANDLE fd; + char node_products[16][4]; // 16 devices max + uint8_t msg_counter; + uint8_t node_count; +}; -static bool aciodrv_device_init(void) +static bool aciodrv_device_init(struct aciodrv_device_ctx* device) { uint8_t init_seq[1] = {AC_IO_SOF}; uint8_t read_buff[1] = {0x00}; @@ -24,18 +27,18 @@ static bool aciodrv_device_init(void) /* init/reset the device by sending 0xAA until 0xAA is returned */ int read = 0; do { - if (aciodrv_port_write(init_seq, sizeof(init_seq)) <= 0) { + if (aciodrv_port_write(device->fd, init_seq, sizeof(init_seq)) <= 0) { return false; } - read = aciodrv_port_read(read_buff, sizeof(read_buff)); + read = aciodrv_port_read(device->fd, read_buff, sizeof(read_buff)); } while ((read <= 0) || (read_buff[0] != init_seq[0])); if (read > 0) { log_warning("Obtained SOF, clearing out buffer now"); /* empty buffer by reading all data */ while (read > 0) { - read = aciodrv_port_read(init_seq, sizeof(init_seq)); + read = aciodrv_port_read(device->fd, init_seq, sizeof(init_seq)); } log_warning("Cleared buffer, init done"); @@ -57,7 +60,7 @@ aciodrv_device_log_buffer(const char *msg, const uint8_t *buffer, int length) } #endif -static bool aciodrv_device_send(const uint8_t *buffer, int length) +static bool aciodrv_device_send(struct aciodrv_device_ctx* device, const uint8_t *buffer, int length) { uint8_t send_buf[512]; int send_buf_pos = 0; @@ -98,7 +101,7 @@ static bool aciodrv_device_send(const uint8_t *buffer, int length) aciodrv_device_log_buffer("Send (2)", send_buf, send_buf_pos); #endif - if (aciodrv_port_write(send_buf, send_buf_pos) != send_buf_pos) { + if (aciodrv_port_write(device->fd, send_buf, send_buf_pos) != send_buf_pos) { log_warning("Sending data with length %d failed", send_buf_pos); return false; } @@ -106,7 +109,7 @@ static bool aciodrv_device_send(const uint8_t *buffer, int length) return true; } -static int aciodrv_device_receive(uint8_t *buffer, int size) +static int aciodrv_device_receive(struct aciodrv_device_ctx* device, uint8_t *buffer, int size) { uint8_t recv_buf[512]; int recv_size = 0; @@ -118,7 +121,7 @@ static int aciodrv_device_receive(uint8_t *buffer, int size) of 0xAAs before we get a valid message. */ recv_buf[0] = AC_IO_SOF; do { - read = aciodrv_port_read(recv_buf, 1); + read = aciodrv_port_read(device->fd, recv_buf, 1); } while (recv_buf[0] == AC_IO_SOF); if (read > 0) { @@ -137,7 +140,7 @@ static int aciodrv_device_receive(uint8_t *buffer, int size) non-zero read. */ while (size > 0) { do { - read = aciodrv_port_read(recv_buf + recv_size, 1); + read = aciodrv_port_read(device->fd, recv_buf + recv_size, 1); } while (read == 0); if (read < 0) { @@ -150,7 +153,8 @@ static int aciodrv_device_receive(uint8_t *buffer, int size) /* next byte is our real data overwrite escape byte */ do { - read = aciodrv_port_read(recv_buf + recv_size, 1); + read = aciodrv_port_read( + device->fd, recv_buf + recv_size, 1); } while (read == 0); if (read < 0) { @@ -195,7 +199,7 @@ static int aciodrv_device_receive(uint8_t *buffer, int size) return -1; } -static uint8_t aciodrv_device_enum_nodes(void) +static uint8_t aciodrv_device_enum_nodes(struct aciodrv_device_ctx* device) { struct ac_io_message msg; @@ -205,7 +209,9 @@ static uint8_t aciodrv_device_enum_nodes(void) msg.cmd.count = 0; if (!aciodrv_send_and_recv( - &msg, offsetof(struct ac_io_message, cmd.raw) + 1)) { + device, + &msg, + offsetof(struct ac_io_message, cmd.raw) + 1)) { log_warning("Enumerating nodes failed"); return 0; } @@ -215,7 +221,7 @@ static uint8_t aciodrv_device_enum_nodes(void) return msg.cmd.count; } -static bool aciodrv_device_get_version(uint8_t node_id, char product[4]) +static bool aciodrv_device_get_version(struct aciodrv_device_ctx* device, uint8_t node_id, char product[4]) { struct ac_io_message msg; @@ -224,6 +230,7 @@ static bool aciodrv_device_get_version(uint8_t node_id, char product[4]) msg.cmd.nbytes = 0; if (!aciodrv_send_and_recv( + device, &msg, offsetof(struct ac_io_message, cmd.raw) + sizeof(struct ac_io_version))) { @@ -252,7 +259,7 @@ static bool aciodrv_device_get_version(uint8_t node_id, char product[4]) return true; } -static bool aciodrv_device_start_node(uint8_t node_id) +static bool aciodrv_device_start_node(struct aciodrv_device_ctx* device, uint8_t node_id) { struct ac_io_message msg; @@ -261,7 +268,9 @@ static bool aciodrv_device_start_node(uint8_t node_id) msg.cmd.nbytes = 0; if (!aciodrv_send_and_recv( - &msg, offsetof(struct ac_io_message, cmd.raw) + 1)) { + device, + &msg, + offsetof(struct ac_io_message, cmd.raw) + 1)) { log_warning("Starting node %d failed", node_id); return false; } @@ -270,55 +279,64 @@ static bool aciodrv_device_start_node(uint8_t node_id) return true; } -bool aciodrv_device_open(const char *port, int baud) +struct aciodrv_device_ctx* aciodrv_device_open(const char *port_path, int baud) { - if (!aciodrv_port_open(port, baud)) { + HANDLE port = aciodrv_port_open(port_path, baud); + if (!port) { + return NULL; + } + + struct aciodrv_device_ctx* device = malloc(sizeof(struct aciodrv_device_ctx)); + + device->fd = port; + + if (!aciodrv_device_init(device)) { + aciodrv_device_close(device); + return NULL; + } + + device->node_count = aciodrv_device_enum_nodes(device); + if (device->node_count == 0) { + aciodrv_device_close(device); return false; } - if (!aciodrv_device_init()) { - return false; - } - - aciodrv_device_node_count = aciodrv_device_enum_nodes(); - if (aciodrv_device_node_count == 0) { - return false; - } - - for (uint8_t i = 0; i < aciodrv_device_node_count; i++) { + for (uint8_t i = 0; i < device->node_count; i++) { if (!aciodrv_device_get_version( - i + 1, aviodrv_device_node_products[i])) { - return false; + device, i + 1, device->node_products[i])) { + aciodrv_device_close(device); + return NULL; } } - for (uint8_t i = 0; i < aciodrv_device_node_count; i++) { - if (!aciodrv_device_start_node(i + 1)) { - return false; + for (uint8_t i = 0; i < device->node_count; i++) { + if (!aciodrv_device_start_node(device, i + 1)) { + aciodrv_device_close(device); + return NULL; } } - return true; + return device; } -uint8_t aciodrv_device_get_node_count(void) +uint8_t aciodrv_device_get_node_count(struct aciodrv_device_ctx* device) { - return aciodrv_device_node_count; + return device->node_count; } -bool aciodrv_device_get_node_product_ident(uint8_t node_id, char product[4]) +bool aciodrv_device_get_node_product_ident(struct aciodrv_device_ctx* device, uint8_t node_id, char product[4]) { - if (aciodrv_device_node_count == 0 || node_id > aciodrv_device_node_count) { + if (device->node_count == 0 || node_id > device->node_count) { return false; } - memcpy(product, aviodrv_device_node_products[node_id], 4); + memcpy(product, device->node_products[node_id], 4); return true; } -bool aciodrv_send_and_recv(struct ac_io_message *msg, int resp_size) +bool aciodrv_send_and_recv(struct aciodrv_device_ctx* device, struct ac_io_message *msg, int resp_size) { - msg->cmd.seq_no = aciodrv_device_msg_counter++; + msg->cmd.seq_no = device->msg_counter++; int send_size = offsetof(struct ac_io_message, cmd.raw) + msg->cmd.nbytes; #ifdef AC_IO_MSG_LOG @@ -328,7 +346,7 @@ bool aciodrv_send_and_recv(struct ac_io_message *msg, int resp_size) msg->cmd.code, send_size); #endif - if (aciodrv_device_send((uint8_t *) msg, send_size) <= 0) { + if (aciodrv_device_send(device, (uint8_t *) msg, send_size) <= 0) { return false; } @@ -337,7 +355,7 @@ bool aciodrv_send_and_recv(struct ac_io_message *msg, int resp_size) #ifdef AC_IO_MSG_LOG log_info("Beginning recv: (%d b)", resp_size); #endif - if (aciodrv_device_receive((uint8_t *) msg, resp_size) <= 0) { + if (aciodrv_device_receive(device, (uint8_t *) msg, resp_size) <= 0) { return false; } @@ -352,7 +370,9 @@ bool aciodrv_send_and_recv(struct ac_io_message *msg, int resp_size) return true; } -void aciodrv_device_close(void) +void aciodrv_device_close(struct aciodrv_device_ctx* device) { - aciodrv_port_close(); + aciodrv_port_close(device->fd); + + free(device); } diff --git a/src/main/aciodrv/device.h b/src/main/aciodrv/device.h index 62f544b..b976d50 100644 --- a/src/main/aciodrv/device.h +++ b/src/main/aciodrv/device.h @@ -5,48 +5,56 @@ #include "acio/acio.h" +#include "windows.h" + +struct aciodrv_device_ctx; + /** * Open an ACIO device connected to a serial port. * * @param port Port the device is connected to (e.g. "COM1") * @param baud Baud rate for communication (e.g. 57600 for ICCA) - * @return True if opening the port and resetting the device was successful, - * false on error. + * @return opened device context, NULL on error */ -bool aciodrv_device_open(const char *port, int baud); +struct aciodrv_device_ctx* aciodrv_device_open(const char *port_path, int baud); /** * Get the node count on the opened device. * + * @param device Context of opened device * @return Total num of nodes enumerated on the ACIO device. */ -uint8_t aciodrv_device_get_node_count(void); +uint8_t aciodrv_device_get_node_count(struct aciodrv_device_ctx* device); /** * Get the product identifier of an enumerated node. * + * @param device Context of opened device * @param node_id Id of the node. Needs to be in range of the total node count. * @param product Buffer to return the product id to. * @return True on success, false on error. If True the variable product * contains the identifier of the queried node. */ -bool aciodrv_device_get_node_product_ident(uint8_t node_id, char product[4]); +bool aciodrv_device_get_node_product_ident(struct aciodrv_device_ctx* device, uint8_t node_id, char product[4]); /** * Send a message to the ACIO bus and receive an answer. * Use this to implement the protocol for each type of device that can be * part of the bus. * + * @param device Context of opened device * @param msg Msg to send to the bus. Make sure that the buffer backing * this message is big enough to receive the response as well. * @param resp_size Size of the expecting response. * @return True on success, false on error. */ -bool aciodrv_send_and_recv(struct ac_io_message *msg, int resp_size); +bool aciodrv_send_and_recv(struct aciodrv_device_ctx* device, struct ac_io_message *msg, int resp_size); /** * Close the previously opened ACIO device. + * + * @param device Context of opened device */ -void aciodrv_device_close(void); +void aciodrv_device_close(struct aciodrv_device_ctx* device); #endif \ No newline at end of file diff --git a/src/main/aciodrv/icca.c b/src/main/aciodrv/icca.c index 52a63a0..a3902a0 100644 --- a/src/main/aciodrv/icca.c +++ b/src/main/aciodrv/icca.c @@ -6,7 +6,9 @@ #include "util/log.h" -static bool aciodrv_icca_queue_loop_start(uint8_t node_id) +static bool aciodrv_icca_queue_loop_start( + struct aciodrv_device_ctx *device, + uint8_t node_id) { struct ac_io_message msg; @@ -16,7 +18,9 @@ static bool aciodrv_icca_queue_loop_start(uint8_t node_id) msg.cmd.status = 0; if (!aciodrv_send_and_recv( - &msg, offsetof(struct ac_io_message, cmd.raw) + 1)) { + device, + &msg, + offsetof(struct ac_io_message, cmd.raw) + 1)) { log_warning("Starting queue loop failed"); return false; } @@ -27,9 +31,9 @@ static bool aciodrv_icca_queue_loop_start(uint8_t node_id) return true; } -bool aciodrv_icca_init(uint8_t node_id) +bool aciodrv_icca_init(struct aciodrv_device_ctx *device, uint8_t node_id) { - if (!aciodrv_icca_queue_loop_start(node_id + 1)) { + if (!aciodrv_icca_queue_loop_start(device, node_id + 1)) { return false; } @@ -37,7 +41,10 @@ bool aciodrv_icca_init(uint8_t node_id) } bool aciodrv_icca_set_state( - uint8_t node_id, int slot_state, struct ac_io_icca_state *state) + struct aciodrv_device_ctx *device, + uint8_t node_id, + int slot_state, + struct ac_io_icca_state *state) { struct ac_io_message msg; @@ -49,7 +56,9 @@ bool aciodrv_icca_set_state( msg.cmd.raw[1] = slot_state; if (!aciodrv_send_and_recv( - &msg, offsetof(struct ac_io_message, cmd.raw) + msg.cmd.raw[0])) { + device, + &msg, + offsetof(struct ac_io_message, cmd.raw) + msg.cmd.raw[0])) { log_warning("Setting state of node %d failed", node_id + 1); return false; } @@ -61,7 +70,10 @@ bool aciodrv_icca_set_state( return true; } -bool aciodrv_icca_get_state(uint8_t node_id, struct ac_io_icca_state *state) +bool aciodrv_icca_get_state( + struct aciodrv_device_ctx *device, + uint8_t node_id, + struct ac_io_icca_state *state) { struct ac_io_message msg; @@ -72,7 +84,9 @@ bool aciodrv_icca_get_state(uint8_t node_id, struct ac_io_icca_state *state) msg.cmd.count = sizeof(struct ac_io_icca_state); if (!aciodrv_send_and_recv( - &msg, offsetof(struct ac_io_message, cmd.raw) + msg.cmd.count)) { + device, + &msg, + offsetof(struct ac_io_message, cmd.raw) + msg.cmd.count)) { log_warning("Getting state of node %d failed", node_id + 1); return false; } @@ -84,7 +98,10 @@ bool aciodrv_icca_get_state(uint8_t node_id, struct ac_io_icca_state *state) return true; } -bool aciodrv_icca_read_card(uint8_t node_id, struct ac_io_icca_state *state) +bool aciodrv_icca_read_card( + struct aciodrv_device_ctx *device, + uint8_t node_id, + struct ac_io_icca_state *state) { struct ac_io_message msg; @@ -95,7 +112,9 @@ bool aciodrv_icca_read_card(uint8_t node_id, struct ac_io_icca_state *state) msg.cmd.count = sizeof(struct ac_io_icca_state); if (!aciodrv_send_and_recv( - &msg, offsetof(struct ac_io_message, cmd.raw) + msg.cmd.count)) { + device, + &msg, + offsetof(struct ac_io_message, cmd.raw) + msg.cmd.count)) { log_warning("Reading card of node %d failed", node_id + 1); return false; } diff --git a/src/main/aciodrv/icca.h b/src/main/aciodrv/icca.h index ddae29e..44424d9 100644 --- a/src/main/aciodrv/icca.h +++ b/src/main/aciodrv/icca.h @@ -6,17 +6,19 @@ /** * Initialize an ICCA node. * + * @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_icca_init(uint8_t node_id); +bool aciodrv_icca_init(struct aciodrv_device_ctx *device, uint8_t node_id); /** * Set the state of on ICCA node. * + * @param device Context of opened device * @param node_id Id of the node to set the state for (0 based). * @param slot_state State of the slot (refer to corresponding enum). * @param state Pointer to a state struct to return the current state to @@ -27,11 +29,14 @@ bool aciodrv_icca_init(uint8_t node_id); * @see driver.h */ bool aciodrv_icca_set_state( - uint8_t node_id, int slot_state, struct ac_io_icca_state *state); + struct aciodrv_device_ctx *device, + uint8_t node_id, int slot_state, + struct ac_io_icca_state *state); /** * Get the current state of an ICCA node. * + * @param device Context of opened device * @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). @@ -40,7 +45,10 @@ bool aciodrv_icca_set_state( * device driver foundation. * @see driver.h */ -bool aciodrv_icca_get_state(uint8_t node_id, struct ac_io_icca_state *state); +bool aciodrv_icca_get_state( + struct aciodrv_device_ctx *device, + uint8_t node_id, + struct ac_io_icca_state *state); /** * Trigger a card read action on the ICCA reader. Make sure to call this @@ -48,6 +56,7 @@ bool aciodrv_icca_get_state(uint8_t node_id, struct ac_io_icca_state *state); * to get the most recent card data. Make sure to re-get the state after * a read call. The state returned here might not be up to date for some reason. * + * @param device Context of opened device * @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). @@ -56,6 +65,9 @@ bool aciodrv_icca_get_state(uint8_t node_id, struct ac_io_icca_state *state); * device driver foundation. * @see driver.h */ -bool aciodrv_icca_read_card(uint8_t node_id, struct ac_io_icca_state *state); +bool aciodrv_icca_read_card( + struct aciodrv_device_ctx *device, + uint8_t node_id, + struct ac_io_icca_state *state); #endif \ No newline at end of file diff --git a/src/main/aciodrv/kfca.c b/src/main/aciodrv/kfca.c index 000656f..9a3a93f 100644 --- a/src/main/aciodrv/kfca.c +++ b/src/main/aciodrv/kfca.c @@ -7,7 +7,9 @@ #include "util/log.h" -static bool aciodrv_kfca_watchdog_start(uint8_t node_id) +static bool aciodrv_kfca_watchdog_start( + struct aciodrv_device_ctx *device, + uint8_t node_id) { // exit early and don't actually call watchdog // the watchdog call actually returns different sized packets depending on @@ -26,8 +28,9 @@ static bool aciodrv_kfca_watchdog_start(uint8_t node_id) 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; + if (!aciodrv_send_and_recv( + device, &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", @@ -38,6 +41,7 @@ static bool aciodrv_kfca_watchdog_start(uint8_t node_id) } bool aciodrv_kfca_amp( + struct aciodrv_device_ctx *device, uint8_t node_id, uint8_t primary, uint8_t headphone, @@ -56,7 +60,9 @@ bool aciodrv_kfca_amp( msg.cmd.raw[3] = subwoofer; if (!aciodrv_send_and_recv( - &msg, offsetof(struct ac_io_message, cmd.raw) + 1)) { + device, + &msg, + offsetof(struct ac_io_message, cmd.raw) + 1)) { log_warning("Setting AMP failed"); return false; } @@ -66,13 +72,15 @@ bool aciodrv_kfca_amp( return true; } -bool aciodrv_kfca_init(uint8_t node_id) +bool aciodrv_kfca_init( + struct aciodrv_device_ctx *device, + uint8_t node_id) { - if (!aciodrv_kfca_watchdog_start(node_id)) { + if (!aciodrv_kfca_watchdog_start(device, node_id)) { return false; } - if (!aciodrv_kfca_amp(node_id, 0, 0, 0, 0)) { + if (!aciodrv_kfca_amp(device, node_id, 0, 0, 0, 0)) { return false; } @@ -80,6 +88,7 @@ bool aciodrv_kfca_init(uint8_t node_id) } bool aciodrv_kfca_poll( + struct aciodrv_device_ctx *device, uint8_t node_id, const struct ac_io_kfca_poll_out *pout, struct ac_io_kfca_poll_in *pin) @@ -93,7 +102,9 @@ bool aciodrv_kfca_poll( msg.cmd.kfca_poll_out = *pout; if (!aciodrv_send_and_recv( - &msg, offsetof(struct ac_io_message, cmd.raw) + sizeof(*pin))) { + device, + &msg, + offsetof(struct ac_io_message, cmd.raw) + sizeof(*pin))) { log_warning("Polling of node %d failed", node_id + 1); return false; } diff --git a/src/main/aciodrv/kfca.h b/src/main/aciodrv/kfca.h index 9f146bd..d73f259 100644 --- a/src/main/aciodrv/kfca.h +++ b/src/main/aciodrv/kfca.h @@ -6,17 +6,19 @@ /** * Initialize an KFCA node. * + * @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_kfca_init(uint8_t node_id); +bool aciodrv_kfca_init(struct aciodrv_device_ctx *device, uint8_t node_id); /** * Poll the KFCA io board * + * @param device Context of opened device * @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). @@ -26,6 +28,7 @@ bool aciodrv_kfca_init(uint8_t node_id); * @see driver.h */ bool aciodrv_kfca_poll( + struct aciodrv_device_ctx *device, uint8_t node_id, const struct ac_io_kfca_poll_out *pout, struct ac_io_kfca_poll_in *pin); @@ -33,6 +36,7 @@ bool aciodrv_kfca_poll( /** * Set the KFCA digital amp level * + * @param device Context of opened device * @param node_id Id of the node to query (0 based). * @param primary primary volume (96-0) * @param headphone headphone volume (96-0) @@ -42,6 +46,7 @@ bool aciodrv_kfca_poll( * @note Note 96 (or 100?) is lowest volume level, 0 is highest */ bool aciodrv_kfca_amp( + struct aciodrv_device_ctx *device, uint8_t node_id, uint8_t primary, uint8_t headphone, diff --git a/src/main/aciodrv/port.c b/src/main/aciodrv/port.c index 29c28b5..415cc4f 100644 --- a/src/main/aciodrv/port.c +++ b/src/main/aciodrv/port.c @@ -7,17 +7,15 @@ #include "util/log.h" -static HANDLE aciodrv_port_fd; - -bool aciodrv_port_open(const char *port, int baud) +HANDLE aciodrv_port_open(const char *port_path, int baud) { COMMTIMEOUTS ct; DCB dcb; - log_info("Opening ACIO on %s at %d baud", port, baud); + log_info("Opening ACIO on %s at %d baud", port_path, baud); - aciodrv_port_fd = CreateFile( - port, + HANDLE port_fd = CreateFile( + port_path, GENERIC_READ | GENERIC_WRITE, 0, NULL, @@ -25,26 +23,26 @@ bool aciodrv_port_open(const char *port, int baud) FILE_FLAG_WRITE_THROUGH | FILE_ATTRIBUTE_NORMAL, NULL); - if (aciodrv_port_fd == INVALID_HANDLE_VALUE) { - log_warning("Failed to open %s", port); + if (port_fd == INVALID_HANDLE_VALUE) { + log_warning("Failed to open %s", port_path); goto early_fail; } - if (!SetCommMask(aciodrv_port_fd, EV_RXCHAR)) { + if (!SetCommMask(port_fd, EV_RXCHAR)) { log_warning("SetCommMask failed"); goto fail; } - if (!SetupComm(aciodrv_port_fd, 0x1000, 0x1000)) { + if (!SetupComm(port_fd, 0x1000, 0x1000)) { log_warning("SetupComm failed"); goto fail; } if (!PurgeComm( - aciodrv_port_fd, + port_fd, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR)) { log_warning("PurgeComm failed"); @@ -57,7 +55,7 @@ bool aciodrv_port_open(const char *port, int baud) ct.ReadTotalTimeoutMultiplier = 0; ct.WriteTotalTimeoutMultiplier = 0; - if (!SetCommTimeouts(aciodrv_port_fd, &ct)) { + if (!SetCommTimeouts(port_fd, &ct)) { log_warning("SetCommTimeouts failed"); goto fail; @@ -65,7 +63,7 @@ bool aciodrv_port_open(const char *port, int baud) dcb.DCBlength = sizeof(dcb); - if (!GetCommState(aciodrv_port_fd, &dcb)) { + if (!GetCommState(port_fd, &dcb)) { log_warning("GetCommState failed"); goto fail; @@ -90,45 +88,44 @@ bool aciodrv_port_open(const char *port, int baud) dcb.XonLim = 100; dcb.XoffLim = 100; - if (!SetCommState(aciodrv_port_fd, &dcb)) { + if (!SetCommState(port_fd, &dcb)) { log_warning("SetCommState failed"); goto fail; } - if (!EscapeCommFunction(aciodrv_port_fd, SETDTR)) { + if (!EscapeCommFunction(port_fd, SETDTR)) { log_warning("SETDTR failed: err = %lu", GetLastError()); goto fail; } - log_info("Opened ACIO device on %s", port); + log_info("Opened ACIO device on %s", port_path); - return true; + return port_fd; fail: - CloseHandle(aciodrv_port_fd); + CloseHandle(port_fd); early_fail: - aciodrv_port_fd = NULL; - return false; + return NULL; } -int aciodrv_port_read(void *bytes, int nbytes) +int aciodrv_port_read(HANDLE port_fd, void *bytes, int nbytes) { DWORD nread; - if (aciodrv_port_fd == NULL) { + if (port_fd == NULL) { return -1; } - if (!ClearCommError(aciodrv_port_fd, NULL, NULL)) { + if (!ClearCommError(port_fd, NULL, NULL)) { log_warning("ClearCommError failed"); return -1; } - if (!ReadFile(aciodrv_port_fd, bytes, nbytes, &nread, NULL)) { + if (!ReadFile(port_fd, bytes, nbytes, &nread, NULL)) { log_warning("ReadFile failed: err = %lu", GetLastError()); return -1; @@ -137,15 +134,15 @@ int aciodrv_port_read(void *bytes, int nbytes) return nread; } -int aciodrv_port_write(const void *bytes, int nbytes) +int aciodrv_port_write(HANDLE port_fd, const void *bytes, int nbytes) { DWORD nwrit; - if (aciodrv_port_fd == NULL) { + if (port_fd == NULL) { return -1; } - if (!WriteFile(aciodrv_port_fd, bytes, nbytes, &nwrit, NULL)) { + if (!WriteFile(port_fd, bytes, nbytes, &nwrit, NULL)) { log_warning("WriteFile failed: err = %lu", GetLastError()); return -1; @@ -154,9 +151,9 @@ int aciodrv_port_write(const void *bytes, int nbytes) return nwrit; } -void aciodrv_port_close(void) +void aciodrv_port_close(HANDLE port_fd) { - if (aciodrv_port_fd != NULL) { - CloseHandle(aciodrv_port_fd); + if (port_fd != NULL) { + CloseHandle(port_fd); } } diff --git a/src/main/aciodrv/port.h b/src/main/aciodrv/port.h index f9a423f..29c3417 100644 --- a/src/main/aciodrv/port.h +++ b/src/main/aciodrv/port.h @@ -4,39 +4,45 @@ #include #include +#include + /** * Open a serial port for communication with a ACIO device. * * @param port Port the device is connected to (e.g. "COM1") * @param baud Baud rate for communication (e.g. 57600 for ICCA) - * @return True if opening the com port was successful, false on error. + * @return HANDLE of the port, NULL on error * @note This will open and setup the com port, only. */ -bool aciodrv_port_open(const char *port, int baud); +HANDLE aciodrv_port_open(const char *port_path, int baud); /** * Read data from the opened com port. * + * @param port_fd HANDLE of opened serial port * @param bytes Pointer to an allocated buffer to read the data into. * @param nbytes Number of bytes to read. Has to be less or equal the allocated * buffer size. * @return Number of bytes read on success or -1 on error. */ -int aciodrv_port_read(void *bytes, int nbytes); +int aciodrv_port_read(HANDLE port_fd, void *bytes, int nbytes); /** * Write data to the opened com port. * + * @param port_fd HANDLE of opened serial port * @param bytes Pointer to an allocated buffer with data to write. * @param nbytes Number of bytes to write. Has to be equal or less the size * of the allocated buffer. * @return Number of bytes written on success or -1 on error. */ -int aciodrv_port_write(const void *bytes, int nbytes); +int aciodrv_port_write(HANDLE port_fd, const void *bytes, int nbytes); /** * Close the previously opened com port. + * + * @param port_fd HANDLE of opened serial port */ -void aciodrv_port_close(void); +void aciodrv_port_close(HANDLE port_fd); #endif \ No newline at end of file diff --git a/src/main/acioemu/emu.c b/src/main/acioemu/emu.c index 9603279..11cf35a 100644 --- a/src/main/acioemu/emu.c +++ b/src/main/acioemu/emu.c @@ -134,6 +134,7 @@ static HRESULT ac_io_emu_write(struct ac_io_emu *emu, struct irp *irp) break; } + // this supplies a single SOF byte per byte read ac_io_in_supply(&emu->in, NULL, 0); ac_io_out_consume_message(&emu->out); } diff --git a/src/main/aciotest/bi2a-sdvx.c b/src/main/aciotest/bi2a-sdvx.c index 8c7b9f2..1ac6f68 100644 --- a/src/main/aciotest/bi2a-sdvx.c +++ b/src/main/aciotest/bi2a-sdvx.c @@ -8,22 +8,24 @@ #include "bio2drv/bi2a-sdvx.h" -bool aciotest_bi2a_sdvx_handler_init(uint8_t node_id, void **ctx) +bool aciotest_bi2a_sdvx_handler_init( + struct aciodrv_device_ctx *device, uint8_t node_id, void **ctx) { *ctx = malloc(sizeof(uint32_t)); *((uint32_t *) *ctx) = 0; - return bio2drv_bi2a_sdvx_init(node_id); + return bio2drv_bi2a_sdvx_init(device, node_id); } -bool aciotest_bi2a_sdvx_handler_update(uint8_t node_id, void *ctx) +bool aciotest_bi2a_sdvx_handler_update( + struct aciodrv_device_ctx *device, uint8_t node_id, void *ctx) { struct bi2a_sdvx_state_in pin; struct bi2a_sdvx_state_out pout; memset(&pout, 0, sizeof(pout)); - if (!bio2drv_bi2a_sdvx_poll(node_id, &pout, &pin)) { + if (!bio2drv_bi2a_sdvx_poll(device, node_id, &pout, &pin)) { return false; } diff --git a/src/main/aciotest/bi2a-sdvx.h b/src/main/aciotest/bi2a-sdvx.h index 59d4a2d..a52bda3 100644 --- a/src/main/aciotest/bi2a-sdvx.h +++ b/src/main/aciotest/bi2a-sdvx.h @@ -4,7 +4,11 @@ #include #include -bool aciotest_bi2a_sdvx_handler_init(uint8_t node_id, void **ctx); -bool aciotest_bi2a_sdvx_handler_update(uint8_t node_id, void *ctx); +#include "aciodrv/device.h" + +bool aciotest_bi2a_sdvx_handler_init( + struct aciodrv_device_ctx *device, uint8_t node_id, void **ctx); +bool aciotest_bi2a_sdvx_handler_update( + struct aciodrv_device_ctx *device, uint8_t node_id, void *ctx); #endif diff --git a/src/main/aciotest/handler.h b/src/main/aciotest/handler.h index b4e46cf..98f2e4c 100644 --- a/src/main/aciotest/handler.h +++ b/src/main/aciotest/handler.h @@ -1,6 +1,8 @@ #ifndef ACIOTEST_HANDLER_H #define ACIOTEST_HANDLER_H +#include "aciodrv/device.h" + static const uint8_t aciotest_handler_max = 16; /** @@ -8,8 +10,10 @@ static const uint8_t aciotest_handler_max = 16; */ struct aciotest_handler_node_handler { void *ctx; - bool (*init)(uint8_t node_id, void **ctx); - bool (*update)(uint8_t node_id, void *ctx); + bool (*init)( + struct aciodrv_device_ctx *device, uint8_t node_id, void **ctx); + bool (*update)( + struct aciodrv_device_ctx *device, uint8_t node_id, void *ctx); }; #endif \ No newline at end of file diff --git a/src/main/aciotest/icca.c b/src/main/aciotest/icca.c index ad00359..41fbbbf 100644 --- a/src/main/aciotest/icca.c +++ b/src/main/aciotest/icca.c @@ -5,29 +5,31 @@ #include "aciodrv/icca.h" -bool aciotest_icca_handler_init(uint8_t node_id, void **ctx) +bool aciotest_icca_handler_init( + struct aciodrv_device_ctx *device, uint8_t node_id, void **ctx) { *ctx = malloc(sizeof(uint32_t)); *((uint32_t *) *ctx) = 0; - return aciodrv_icca_init(node_id); + return aciodrv_icca_init(device, node_id); } -bool aciotest_icca_handler_update(uint8_t node_id, void *ctx) +bool aciotest_icca_handler_update( + struct aciodrv_device_ctx *device, uint8_t node_id, void *ctx) { if (*((uint32_t *) ctx) == 0) { *((uint32_t *) ctx) = 1; /* eject cards that were left in the reader */ if (!aciodrv_icca_set_state( - node_id, AC_IO_ICCA_SLOT_STATE_EJECT, NULL)) { + device, node_id, AC_IO_ICCA_SLOT_STATE_EJECT, NULL)) { return false; } } struct ac_io_icca_state state; - if (!aciodrv_icca_get_state(node_id, &state)) { + if (!aciodrv_icca_get_state(device, node_id, &state)) { return false; } @@ -61,7 +63,7 @@ bool aciotest_icca_handler_update(uint8_t node_id, void *ctx) /* eject card with "empty" key */ if (state.key_state & AC_IO_ICCA_KEYPAD_MASK_EMPTY) { if (!aciodrv_icca_set_state( - node_id, AC_IO_ICCA_SLOT_STATE_EJECT, NULL)) { + device, node_id, AC_IO_ICCA_SLOT_STATE_EJECT, NULL)) { return false; } } @@ -70,7 +72,7 @@ bool aciotest_icca_handler_update(uint8_t node_id, void *ctx) if (!(state.sensor_state & AC_IO_ICCA_SENSOR_MASK_BACK_ON) && !(state.sensor_state & AC_IO_ICCA_SENSOR_MASK_FRONT_ON)) { if (!aciodrv_icca_set_state( - node_id, AC_IO_ICCA_SLOT_STATE_OPEN, NULL)) { + device, node_id, AC_IO_ICCA_SLOT_STATE_OPEN, NULL)) { return false; } } @@ -79,11 +81,11 @@ bool aciotest_icca_handler_update(uint8_t node_id, void *ctx) if ((state.sensor_state & AC_IO_ICCA_SENSOR_MASK_BACK_ON) && (state.sensor_state & AC_IO_ICCA_SENSOR_MASK_FRONT_ON)) { if (!aciodrv_icca_set_state( - node_id, AC_IO_ICCA_SLOT_STATE_CLOSE, NULL)) { + device, node_id, AC_IO_ICCA_SLOT_STATE_CLOSE, NULL)) { return false; } - if (!aciodrv_icca_read_card(node_id, NULL)) { + if (!aciodrv_icca_read_card(device, node_id, NULL)) { return false; } } diff --git a/src/main/aciotest/icca.h b/src/main/aciotest/icca.h index f91fae5..0e05fd2 100644 --- a/src/main/aciotest/icca.h +++ b/src/main/aciotest/icca.h @@ -4,7 +4,11 @@ #include #include -bool aciotest_icca_handler_init(uint8_t node_id, void **ctx); -bool aciotest_icca_handler_update(uint8_t node_id, void *ctx); +#include "aciodrv/device.h" + +bool aciotest_icca_handler_init( + struct aciodrv_device_ctx *device, uint8_t node_id, void **ctx); +bool aciotest_icca_handler_update( + struct aciodrv_device_ctx *device, uint8_t node_id, void *ctx); #endif \ No newline at end of file diff --git a/src/main/aciotest/kfca.c b/src/main/aciotest/kfca.c index e9f0ba9..aec20c2 100644 --- a/src/main/aciotest/kfca.c +++ b/src/main/aciotest/kfca.c @@ -8,15 +8,17 @@ #include "aciodrv/kfca.h" -bool aciotest_kfca_handler_init(uint8_t node_id, void **ctx) +bool aciotest_kfca_handler_init( + struct aciodrv_device_ctx *device, uint8_t node_id, void **ctx) { *ctx = malloc(sizeof(uint32_t)); *((uint32_t *) *ctx) = 0; - return aciodrv_kfca_init(node_id); + return aciodrv_kfca_init(device, node_id); } -bool aciotest_kfca_handler_update(uint8_t node_id, void *ctx) +bool aciotest_kfca_handler_update( + struct aciodrv_device_ctx *device, uint8_t node_id, void *ctx) { struct ac_io_kfca_poll_in pin; struct ac_io_kfca_poll_out pout; @@ -28,7 +30,7 @@ bool aciotest_kfca_handler_update(uint8_t node_id, void *ctx) pout.gpio |= 1 << gpio_test_pin; pout.gpio = ac_io_u32(pout.gpio); - if (!aciodrv_kfca_poll(node_id, &pout, &pin)) { + if (!aciodrv_kfca_poll(device, node_id, &pout, &pin)) { return false; } diff --git a/src/main/aciotest/kfca.h b/src/main/aciotest/kfca.h index 30c3d73..95e9d2b 100644 --- a/src/main/aciotest/kfca.h +++ b/src/main/aciotest/kfca.h @@ -4,7 +4,11 @@ #include #include -bool aciotest_kfca_handler_init(uint8_t node_id, void **ctx); -bool aciotest_kfca_handler_update(uint8_t node_id, void *ctx); +#include "aciodrv/device.h" + +bool aciotest_kfca_handler_init( + struct aciodrv_device_ctx *device, uint8_t node_id, void **ctx); +bool aciotest_kfca_handler_update( + struct aciodrv_device_ctx *device, uint8_t node_id, void *ctx); #endif diff --git a/src/main/aciotest/main.c b/src/main/aciotest/main.c index bea7eba..4cddca8 100644 --- a/src/main/aciotest/main.c +++ b/src/main/aciotest/main.c @@ -70,14 +70,16 @@ int main(int argc, char **argv) log_to_writer(log_writer_stdout, NULL); - if (!aciodrv_device_open(argv[1], atoi(argv[2]))) { + + struct aciodrv_device_ctx *device = aciodrv_device_open(argv[1], atoi(argv[2])); + if (!device) { printf("Opening acio device failed\n"); return -1; } printf("Opening acio device successful\n"); - uint8_t node_count = aciodrv_device_get_node_count(); + uint8_t node_count = aciodrv_device_get_node_count(device); printf("Enumerated %d nodes\n", node_count); struct aciotest_handler_node_handler handler[aciotest_handler_max]; @@ -88,7 +90,7 @@ int main(int argc, char **argv) for (uint8_t i = 0; i < node_count; i++) { char product[4]; - aciodrv_device_get_node_product_ident(i, product); + aciodrv_device_get_node_product_ident(device, i, product); printf( "> %d: %c%c%c%c\n", i + 1, @@ -110,7 +112,7 @@ int main(int argc, char **argv) for (uint8_t i = 0; i < aciotest_handler_max; i++) { if (handler[i].init != NULL) { - if (!handler[i].init(i, &handler[i].ctx)) { + if (!handler[i].init(device, i, &handler[i].ctx)) { printf("ERROR: Initializing node %d failed\n", i); handler[i].update = NULL; } @@ -129,7 +131,7 @@ int main(int argc, char **argv) for (uint8_t i = 0; i < aciotest_handler_max; i++) { if (handler[i].update != NULL) { - if (!handler[i].update(i, handler[i].ctx)) { + if (!handler[i].update(device, i, handler[i].ctx)) { printf("ERROR: Updating node %d, removed from loop\n", i); handler[i].update = NULL; Sleep(5000); diff --git a/src/main/bio2drv/bi2a-iidx.c b/src/main/bio2drv/bi2a-iidx.c index 2f7a6e3..666f9d2 100644 --- a/src/main/bio2drv/bi2a-iidx.c +++ b/src/main/bio2drv/bi2a-iidx.c @@ -14,7 +14,9 @@ // in all inputs and outputs (over sub IO) other than 14 keys to not work. static const uint8_t _BIO2DR_BI2A_IIDX_INIT_DATA = 0x2D; -static bool bio2drv_bi2a_iidx_init_io(uint8_t node_id) +static bool bio2drv_bi2a_iidx_init_io( + struct aciodrv_device_ctx *device, + uint8_t node_id) { struct ac_io_message msg; @@ -24,7 +26,9 @@ static bool bio2drv_bi2a_iidx_init_io(uint8_t node_id) msg.cmd.param = _BIO2DR_BI2A_IIDX_INIT_DATA; if (!aciodrv_send_and_recv( - &msg, offsetof(struct ac_io_message, cmd.raw) + 1)) { + device, + &msg, + offsetof(struct ac_io_message, cmd.raw) + 1)) { log_warning("Init node failed"); return 0; } @@ -34,7 +38,9 @@ static bool bio2drv_bi2a_iidx_init_io(uint8_t node_id) return 1; } -static bool bio2drv_bi2a_iidx_watchdog_start(uint8_t node_id) +static bool bio2drv_bi2a_iidx_watchdog_start( + struct aciodrv_device_ctx *device, + uint8_t node_id) { // exit early and don't actually call watchdog // the watchdog call actually returns different sized packets depending on @@ -54,7 +60,7 @@ static bool bio2drv_bi2a_iidx_watchdog_start(uint8_t node_id) msg.cmd.raw[1] = 112; if (!aciodrv_send_and_recv( - &msg, offsetof(struct ac_io_message, cmd.raw) + 2 + device, &msg, offsetof(struct ac_io_message, cmd.raw) + 2 )) { log_warning("Starting watchdog failed"); return false; } @@ -66,13 +72,13 @@ static bool bio2drv_bi2a_iidx_watchdog_start(uint8_t node_id) */ } -bool bio2drv_bi2a_iidx_init(uint8_t node_id) +bool bio2drv_bi2a_iidx_init(struct aciodrv_device_ctx *device, uint8_t node_id) { - if (!bio2drv_bi2a_iidx_init_io(node_id)) { + if (!bio2drv_bi2a_iidx_init_io(device, node_id)) { return false; } - if (!bio2drv_bi2a_iidx_watchdog_start(node_id)) { + if (!bio2drv_bi2a_iidx_watchdog_start(device, node_id)) { return false; } @@ -80,6 +86,7 @@ bool bio2drv_bi2a_iidx_init(uint8_t node_id) } bool bio2drv_bi2a_iidx_poll( + struct aciodrv_device_ctx *device, uint8_t node_id, const struct bi2a_iidx_state_out *pout, struct bi2a_iidx_state_in *pin) @@ -93,7 +100,9 @@ bool bio2drv_bi2a_iidx_poll( *(struct bi2a_iidx_state_out *) msg.cmd.raw = *pout; if (!aciodrv_send_and_recv( - &msg, offsetof(struct ac_io_message, cmd.raw) + sizeof(*pin))) { + device, + &msg, + offsetof(struct ac_io_message, cmd.raw) + sizeof(*pin))) { log_warning("Polling of node %d failed", node_id + 1); return false; } diff --git a/src/main/bio2drv/bi2a-iidx.h b/src/main/bio2drv/bi2a-iidx.h index 6ec62e0..f90ce78 100644 --- a/src/main/bio2drv/bi2a-iidx.h +++ b/src/main/bio2drv/bi2a-iidx.h @@ -1,22 +1,28 @@ #ifndef BIO2DRV_BI2A_IIDX_H #define BIO2DRV_BI2A_IIDX_H +#include "aciodrv/device.h" + #include "bio2/bi2a-iidx.h" /** * Initialize a BI2A node. * + * @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 bio2drv_bi2a_iidx_init(uint8_t node_id); +bool bio2drv_bi2a_iidx_init( + struct aciodrv_device_ctx *device, + uint8_t node_id); /** * Poll the BI2A board * + * @param device Context of opened device * @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). @@ -26,6 +32,7 @@ bool bio2drv_bi2a_iidx_init(uint8_t node_id); * @see driver.h */ bool bio2drv_bi2a_iidx_poll( + struct aciodrv_device_ctx *device, uint8_t node_id, const struct bi2a_iidx_state_out *pout, struct bi2a_iidx_state_in *pin); diff --git a/src/main/bio2drv/bi2a-sdvx.c b/src/main/bio2drv/bi2a-sdvx.c index 0d1fc6d..f8b6b25 100644 --- a/src/main/bio2drv/bi2a-sdvx.c +++ b/src/main/bio2drv/bi2a-sdvx.c @@ -12,7 +12,7 @@ static const uint8_t _BIO2DR_BI2A_SDVX_INIT_DATA = 0x3B; // this is probably InitIO -static bool bio2drv_bi2a_sdvx_init_io(uint8_t node_id) +static bool bio2drv_bi2a_sdvx_init_io(struct aciodrv_device_ctx *device, uint8_t node_id) { struct ac_io_message msg; @@ -22,7 +22,9 @@ static bool bio2drv_bi2a_sdvx_init_io(uint8_t node_id) msg.cmd.param = _BIO2DR_BI2A_SDVX_INIT_DATA; if (!aciodrv_send_and_recv( - &msg, offsetof(struct ac_io_message, cmd.raw) + 1)) { + device, + &msg, + offsetof(struct ac_io_message, cmd.raw) + 1)) { log_warning("Init node failed"); return 0; } @@ -32,7 +34,7 @@ static bool bio2drv_bi2a_sdvx_init_io(uint8_t node_id) return 1; } -static bool bio2drv_bi2a_sdvx_watchdog_start(uint8_t node_id) +static bool bio2drv_bi2a_sdvx_watchdog_start(struct aciodrv_device_ctx *device, uint8_t node_id) { // exit early and don't actually call watchdog // the watchdog call actually returns different sized packets depending on @@ -65,6 +67,7 @@ static bool bio2drv_bi2a_sdvx_watchdog_start(uint8_t node_id) } bool bio2drv_bi2a_sdvx_amp( + struct aciodrv_device_ctx *device, uint8_t node_id, uint8_t unused_1, uint8_t unused_2, @@ -86,7 +89,9 @@ bool bio2drv_bi2a_sdvx_amp( msg.cmd.raw[3] = right; if (!aciodrv_send_and_recv( - &msg, offsetof(struct ac_io_message, cmd.raw) + 1)) { + device, + &msg, + offsetof(struct ac_io_message, cmd.raw) + 1)) { log_warning("Setting AMP failed"); return false; } @@ -96,17 +101,17 @@ bool bio2drv_bi2a_sdvx_amp( return true; } -bool bio2drv_bi2a_sdvx_init(uint8_t node_id) +bool bio2drv_bi2a_sdvx_init(struct aciodrv_device_ctx *device, uint8_t node_id) { - if (!bio2drv_bi2a_sdvx_init_io(node_id)) { + if (!bio2drv_bi2a_sdvx_init_io(device, node_id)) { return false; } - if (!bio2drv_bi2a_sdvx_watchdog_start(node_id)) { + if (!bio2drv_bi2a_sdvx_watchdog_start(device, node_id)) { return false; } - if (!bio2drv_bi2a_sdvx_amp(node_id, 0, 0, 0, 0)) { + if (!bio2drv_bi2a_sdvx_amp(device, node_id, 0, 0, 0, 0)) { return false; } @@ -114,6 +119,7 @@ bool bio2drv_bi2a_sdvx_init(uint8_t node_id) } bool bio2drv_bi2a_sdvx_poll( + struct aciodrv_device_ctx *device, uint8_t node_id, const struct bi2a_sdvx_state_out *pout, struct bi2a_sdvx_state_in *pin) @@ -127,7 +133,9 @@ bool bio2drv_bi2a_sdvx_poll( *(struct bi2a_sdvx_state_out *) msg.cmd.raw = *pout; if (!aciodrv_send_and_recv( - &msg, offsetof(struct ac_io_message, cmd.raw) + sizeof(*pin))) { + device, + &msg, + offsetof(struct ac_io_message, cmd.raw) + sizeof(*pin))) { log_warning("Polling of node %d failed", node_id + 1); return false; } diff --git a/src/main/bio2drv/bi2a-sdvx.h b/src/main/bio2drv/bi2a-sdvx.h index a68aa78..6186dec 100644 --- a/src/main/bio2drv/bi2a-sdvx.h +++ b/src/main/bio2drv/bi2a-sdvx.h @@ -1,22 +1,28 @@ -#ifndef BIO2DRV_BI2A_H -#define BIO2DRV_BI2A_H +#ifndef BIO2DRV_BI2A_SDVX_H +#define BIO2DRV_BI2A_SDVX_H + +#include "aciodrv/device.h" #include "bio2/bi2a-sdvx.h" /** * Initialize a BI2A node. * + * @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 bio2drv_bi2a_sdvx_init(uint8_t node_id); +bool bio2drv_bi2a_sdvx_init( + struct aciodrv_device_ctx *device, + uint8_t node_id); /** * Poll the board * + * @param device Context of opened device * @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). @@ -26,6 +32,7 @@ bool bio2drv_bi2a_sdvx_init(uint8_t node_id); * @see driver.h */ bool bio2drv_bi2a_sdvx_poll( + struct aciodrv_device_ctx *device, uint8_t node_id, const struct bi2a_sdvx_state_out *pout, struct bi2a_sdvx_state_in *pin); @@ -33,6 +40,7 @@ bool bio2drv_bi2a_sdvx_poll( /** * Set the BIO2 BI2A SDVX digital amp level * + * @param device Context of opened device * @param node_id Id of the node to query (0 based). * @param primary primary volume (96-0) * @param headphone headphone volume (96-0) @@ -42,6 +50,7 @@ bool bio2drv_bi2a_sdvx_poll( * @note Note 96 is lowest volume level, 0 is highest */ bool bio2drv_bi2a_sdvx_amp( + struct aciodrv_device_ctx *device, uint8_t node_id, uint8_t unused_1, uint8_t unused_2, diff --git a/src/main/eamio-icca/eamio-icca.c b/src/main/eamio-icca/eamio-icca.c index 00478a6..7fe6080 100644 --- a/src/main/eamio-icca/eamio-icca.c +++ b/src/main/eamio-icca/eamio-icca.c @@ -34,6 +34,8 @@ static const uint8_t eam_io_keypad_mappings[16] = {EAM_IO_KEYPAD_DECIMAL, static struct ac_io_icca_state eam_io_icca_state[2]; +static struct aciodrv_device_ctx *acio_device_ctx; + void eam_io_set_loggers( log_formatter_t misc, log_formatter_t info, @@ -46,13 +48,14 @@ void eam_io_set_loggers( bool eam_io_init( thread_create_t create, thread_join_t join, thread_destroy_t destroy) { - if (!aciodrv_device_open("COM1", 57600)) { + acio_device_ctx = aciodrv_device_open("COM1", 57600); + if (acio_device_ctx == NULL) { log_warning("Opening acio device on COM1 failed"); return false; } for (uint8_t i = 0; i < 2; i++) { - if (!aciodrv_icca_init(i)) { + if (!aciodrv_icca_init(acio_device_ctx, i)) { log_warning("Initializing icca %d failed", i); return false; } @@ -63,7 +66,7 @@ bool eam_io_init( void eam_io_fini(void) { - aciodrv_device_close(); + aciodrv_device_close(acio_device_ctx); } uint16_t eam_io_get_keypad_state(uint8_t unit_no) @@ -112,19 +115,20 @@ bool eam_io_card_slot_cmd(uint8_t unit_no, uint8_t cmd) switch (cmd) { case EAM_IO_CARD_SLOT_CMD_CLOSE: return aciodrv_icca_set_state( - unit_no, AC_IO_ICCA_SLOT_STATE_CLOSE, NULL); + acio_device_ctx, unit_no, AC_IO_ICCA_SLOT_STATE_CLOSE, NULL); case EAM_IO_CARD_SLOT_CMD_OPEN: return aciodrv_icca_set_state( - unit_no, AC_IO_ICCA_SLOT_STATE_OPEN, NULL); + acio_device_ctx, unit_no, AC_IO_ICCA_SLOT_STATE_OPEN, NULL); case EAM_IO_CARD_SLOT_CMD_EJECT: return aciodrv_icca_set_state( - unit_no, AC_IO_ICCA_SLOT_STATE_EJECT, NULL); + acio_device_ctx, unit_no, AC_IO_ICCA_SLOT_STATE_EJECT, NULL); case EAM_IO_CARD_SLOT_CMD_READ: - return aciodrv_icca_read_card(unit_no, NULL) && - aciodrv_icca_get_state(unit_no, &eam_io_icca_state[unit_no]); + return aciodrv_icca_read_card(acio_device_ctx, unit_no, NULL) && + aciodrv_icca_get_state( + acio_device_ctx, unit_no, &eam_io_icca_state[unit_no]); default: break; @@ -135,7 +139,8 @@ bool eam_io_card_slot_cmd(uint8_t unit_no, uint8_t cmd) bool eam_io_poll(uint8_t unit_no) { - return aciodrv_icca_get_state(unit_no, &eam_io_icca_state[unit_no]); + return aciodrv_icca_get_state( + acio_device_ctx, unit_no, &eam_io_icca_state[unit_no]); } const struct eam_io_config_api *eam_io_get_config_api(void) diff --git a/src/main/iidxio-bio2/iidxio.c b/src/main/iidxio-bio2/iidxio.c index e005b45..f2762cd 100644 --- a/src/main/iidxio-bio2/iidxio.c +++ b/src/main/iidxio-bio2/iidxio.c @@ -38,6 +38,8 @@ static struct bi2a_iidx_state_in pin_cur; static struct bi2a_iidx_state_out pout_staging; static struct bi2a_iidx_state_out pout_ready; +static struct aciodrv_device_ctx *bio2_device_ctx; + static bool _bio2_iidx_io_poll( const struct bi2a_iidx_state_out *pout, struct bi2a_iidx_state_in *pin) { @@ -47,7 +49,7 @@ static bool _bio2_iidx_io_poll( processing_io = true; - if (!bio2drv_bi2a_iidx_poll(bio2_node_id, pout, pin)) { + if (!bio2drv_bi2a_iidx_poll(bio2_device_ctx, bio2_node_id, pout, pin)) { processing_io = false; return false; } @@ -114,14 +116,15 @@ bool iidx_io_init( } } - if (!aciodrv_device_open(selected_port, config_bio2.baud)) { + bio2_device_ctx = aciodrv_device_open(selected_port, config_bio2.baud); + if (bio2_device_ctx == NULL) { log_info("Opening BIO2 device on [%s] failed", selected_port); return 0; } log_info("Opening BIO2 device on [%s] successful", selected_port); - uint8_t node_count = aciodrv_device_get_node_count(); + uint8_t node_count = aciodrv_device_get_node_count(bio2_device_ctx); log_info("Enumerated %d nodes", node_count); bio2_node_id = -1; @@ -129,7 +132,7 @@ bool iidx_io_init( for (uint8_t i = 0; i < node_count; i++) { char product[4]; - aciodrv_device_get_node_product_ident(i, product); + aciodrv_device_get_node_product_ident(bio2_device_ctx, i, product); log_info( "> %d: %c%c%c%c\n", @@ -150,7 +153,7 @@ bool iidx_io_init( if (bio2_node_id != -1) { log_warning("Using BI2A on node: %d", bio2_node_id); - if (!bio2drv_bi2a_iidx_init(bio2_node_id)) { + if (!bio2drv_bi2a_iidx_init(bio2_device_ctx, bio2_node_id)) { log_warning("Unable to start BI2A on node: %d", bio2_node_id); return false; } diff --git a/src/main/sdvxio-bio2/sdvxio.c b/src/main/sdvxio-bio2/sdvxio.c index 0405682..3174180 100644 --- a/src/main/sdvxio-bio2/sdvxio.c +++ b/src/main/sdvxio-bio2/sdvxio.c @@ -40,6 +40,8 @@ uint8_t wing_staging[12]; struct bi2a_sdvx_state_out pout_staging; struct bi2a_sdvx_state_out pout_ready; +static struct aciodrv_device_ctx *bio2_device_ctx; + void sdvx_io_set_loggers( log_formatter_t misc, log_formatter_t info, @@ -99,21 +101,22 @@ bool sdvx_io_init( } } - if (!aciodrv_device_open(selected_port, config_bio2.baud)) { + bio2_device_ctx = aciodrv_device_open(selected_port, config_bio2.baud); + if (bio2_device_ctx == NULL) { log_info("Opening BIO2 device on [%s] failed", selected_port); return 0; } log_info("Opening BIO2 device on [%s] successful", selected_port); - uint8_t node_count = aciodrv_device_get_node_count(); + uint8_t node_count = aciodrv_device_get_node_count(bio2_device_ctx); log_info("Enumerated %d nodes", node_count); bio2_node_id = -1; for (uint8_t i = 0; i < node_count; i++) { char product[4]; - aciodrv_device_get_node_product_ident(i, product); + aciodrv_device_get_node_product_ident(bio2_device_ctx, i, product); log_info( "> %d: %c%c%c%c\n", i, @@ -133,7 +136,7 @@ bool sdvx_io_init( if (bio2_node_id != -1) { log_warning("Using BI2A on node: %d", bio2_node_id); - if (!bio2drv_bi2a_sdvx_init(bio2_node_id)) { + if (!bio2drv_bi2a_sdvx_init(bio2_device_ctx, bio2_node_id)) { log_warning("Unable to start BI2A on node: %d", bio2_node_id); return false; } @@ -240,7 +243,7 @@ bool _bio2_sdvx_io_poll( processing_io = true; - if (!bio2drv_bi2a_sdvx_poll(bio2_node_id, pout, pin)) { + if (!bio2drv_bi2a_sdvx_poll(bio2_device_ctx, bio2_node_id, pout, pin)) { processing_io = false; return false; } @@ -319,7 +322,7 @@ bool sdvx_io_set_amp_volume( // yes, the BIO2 doesn't allow control of the amps individually // so let's just set it so that people's ear's don't blow out - if (!bio2drv_bi2a_sdvx_amp(bio2_node_id, 0, 0, primary, primary)) { + if (!bio2drv_bi2a_sdvx_amp(bio2_device_ctx, bio2_node_id, 0, 0, primary, primary)) { return false; } diff --git a/src/main/sdvxio-kfca/sdvxio.c b/src/main/sdvxio-kfca/sdvxio.c index 41708e6..21f8709 100644 --- a/src/main/sdvxio-kfca/sdvxio.c +++ b/src/main/sdvxio-kfca/sdvxio.c @@ -37,6 +37,8 @@ static int16_t kfca_node_id; struct ac_io_kfca_poll_out pout_staging; struct ac_io_kfca_poll_out pout_ready; +static struct aciodrv_device_ctx *acio_device_ctx; + void sdvx_io_set_loggers( log_formatter_t misc, log_formatter_t info, @@ -78,21 +80,22 @@ bool sdvx_io_init( cconfig_finit(config); - if (!aciodrv_device_open(config_kfca.port, config_kfca.baud)) { + acio_device_ctx = aciodrv_device_open(config_kfca.port, config_kfca.baud); + if (acio_device_ctx == NULL) { log_info("Opening acio device on [%s] failed", config_kfca.port); return 0; } log_info("Opening acio device successful"); - uint8_t node_count = aciodrv_device_get_node_count(); + uint8_t node_count = aciodrv_device_get_node_count(acio_device_ctx); log_info("Enumerated %d nodes", node_count); kfca_node_id = -1; for (uint8_t i = 0; i < node_count; i++) { char product[4]; - aciodrv_device_get_node_product_ident(i, product); + aciodrv_device_get_node_product_ident(acio_device_ctx, i, product); log_info( "> %d: %c%c%c%c\n", i, @@ -112,7 +115,7 @@ bool sdvx_io_init( if (kfca_node_id != -1) { log_warning("Using KFCA on node: %d", kfca_node_id); - if (!aciodrv_kfca_init(kfca_node_id)) { + if (!aciodrv_kfca_init(acio_device_ctx, kfca_node_id)) { log_warning("Unable to start KFCA on node: %d", kfca_node_id); return false; } @@ -163,7 +166,7 @@ bool sdvx_io_read_input(void) } processing_io = true; - if (!aciodrv_kfca_poll(kfca_node_id, &pout_ready, &pin)) { + if (!aciodrv_kfca_poll(acio_device_ctx, kfca_node_id, &pout_ready, &pin)) { return false; } @@ -217,7 +220,10 @@ bool sdvx_io_set_amp_volume( return false; } - if (!aciodrv_kfca_amp(kfca_node_id, primary, 96, headphone, subwoofer)) { + if (!aciodrv_kfca_amp( + acio_device_ctx, + kfca_node_id, + primary, 96, headphone, subwoofer)) { return false; }