Skip to content

Commit

Permalink
fixup! feat(split): Add full-duplex wired split support
Browse files Browse the repository at this point in the history
  • Loading branch information
petejohanson committed Jan 21, 2025
1 parent 47b7001 commit 45d95af
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 37 deletions.
32 changes: 14 additions & 18 deletions app/src/split/wired/central.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,8 @@ static int split_central_bt_send_command(uint8_t source,
return -ENOSPC;
}

struct command_envelope env = {.source = source, .cmd = cmd};
struct command_envelope env = {
.magic_prefix = ZMK_SPLIT_WIRED_ENVELOPE_MAGIC_PREFIX, .source = source, .cmd = cmd};

env.crc = crc32_ieee((void *)&env, sizeof(env) - 4);
LOG_DBG("calculated a CRC for %d", env.crc);
Expand Down Expand Up @@ -205,23 +206,18 @@ static void publish_events_work(struct k_work *work) {

while (ring_buf_size_get(&state->rx_buf) >= sizeof(struct event_envelope)) {
struct event_envelope env;
size_t bytes_left = sizeof(struct event_envelope);

while (bytes_left > 0) {
size_t read = ring_buf_get(&state->rx_buf, (uint8_t *)&env + (sizeof(env) - bytes_left),
bytes_left);
bytes_left -= read;
int item_err = zmk_split_wired_get_item(&state->rx_buf, (uint8_t *)&env,
sizeof(struct event_envelope));
switch (item_err) {
case 0:
zmk_split_transport_central_peripheral_event_handler(&wired_central, env.source,
env.event);
break;
case -EAGAIN:
break;
default:
LOG_WRN("Issue fetching an item from the RX buffer: %d", item_err);
break;
}

LOG_HEXDUMP_DBG(&env, sizeof(env), "Env data");

// Exclude the trailing 4 bytes that contain the received CRC
uint32_t crc = crc32_ieee((uint8_t *)&env, sizeof(env) - 4);
if (crc != env.crc) {
LOG_WRN("Data corruption in received peripheral event, ignoring");
return;
}

zmk_split_transport_central_peripheral_event_handler(&wired_central, env.source, env.event);
}
}
27 changes: 12 additions & 15 deletions app/src/split/wired/peripheral.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ split_peripheral_wired_report_event(const struct zmk_split_transport_peripheral_
size_t added = 0;

struct event_envelope env = {
.magic_prefix = ZMK_SPLIT_WIRED_ENVELOPE_MAGIC_PREFIX,
.source = peripheral_id,
.event = *event,
};
Expand Down Expand Up @@ -218,21 +219,17 @@ ZMK_SPLIT_TRANSPORT_PERIPHERAL_REGISTER(wired_peripheral, &peripheral_api);
static void publish_commands_work(struct k_work *work) {
while (ring_buf_size_get(&chosen_rx_buf) >= sizeof(struct command_envelope)) {
struct command_envelope env;
size_t bytes_left = sizeof(struct command_envelope);

while (bytes_left > 0) {
size_t read = ring_buf_get(&chosen_rx_buf, (uint8_t *)&env + (sizeof(env) - bytes_left),
bytes_left);
bytes_left -= read;
}

// Exclude the trailing 4 bytes that contain the received CRC
uint32_t crc = crc32_ieee((uint8_t *)&env, sizeof(env) - 4);
if (crc != env.crc) {
LOG_WRN("Data corruption in received peripheral event, ignoring");
return;
int item_err = zmk_split_wired_get_item(&chosen_rx_buf, (uint8_t *)&env,
sizeof(struct command_envelope));
switch (item_err) {
case 0:
zmk_split_transport_peripheral_command_handler(&wired_peripheral, env.cmd);
break;
case -EAGAIN:
break;
default:
LOG_WRN("Issue fetching an item from the RX buffer: %d", item_err);
break;
}

zmk_split_transport_peripheral_command_handler(&wired_peripheral, env.cmd);
}
}
49 changes: 46 additions & 3 deletions app/src/split/wired/wired.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "wired.h"

#include <zephyr/sys/crc.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/logging/log.h>

Expand Down Expand Up @@ -57,6 +58,7 @@ void zmk_split_wired_poll_in(struct ring_buf *rx_buf, const struct device *uart,

void zmk_split_wired_fifo_read(const struct device *dev, struct ring_buf *buf,
struct k_work *process_work) {
// TODO: Add error checking on platforms that support it
uint32_t last_read = 0, len = 0;
do {
uint8_t *buffer;
Expand Down Expand Up @@ -88,8 +90,6 @@ void zmk_split_wired_fifo_fill(const struct device *dev, struct ring_buf *tx_buf

int sent = uart_fifo_fill(dev, buf, claim_len);

LOG_DBG("Sent %d to the UART", sent);

ring_buf_get_finish(tx_buf, MAX(sent, 0));

if (sent <= 0) {
Expand All @@ -102,4 +102,47 @@ void zmk_split_wired_fifo_fill(const struct device *dev, struct ring_buf *tx_buf
}
}

#endif // IS_ENABLED(CONFIG_ZMK_SPLIT_WIRED_UART_MODE_DEFAULT_INTERRUPT)
#endif // IS_ENABLED(CONFIG_ZMK_SPLIT_WIRED_UART_MODE_DEFAULT_INTERRUPT)

int zmk_split_wired_get_item(struct ring_buf *rx_buf, uint8_t *env, size_t env_size) {
while (ring_buf_size_get(rx_buf) >= env_size) {
size_t bytes_left = env_size;

uint8_t prefix[5] = {0};

uint32_t peek_read = ring_buf_peek(rx_buf, prefix, 4);
__ASSERT(peek_read == 4, "Somehow read less than we expect from the RX buffer");

if (strcmp(prefix, ZMK_SPLIT_WIRED_ENVELOPE_MAGIC_PREFIX) != 0) {
uint8_t discarded_byte;
ring_buf_get(rx_buf, &discarded_byte, 1);

LOG_WRN("Prefix mismatch, discarding byte %0x", discarded_byte);

continue;
}

while (bytes_left > 0) {
size_t read = ring_buf_get(rx_buf, env + (env_size - bytes_left), bytes_left);
bytes_left -= read;
}

LOG_HEXDUMP_DBG(env, env_size, "Env data");

// Avoid unaligned access by copying into our 32-bit integer on the stack
uint32_t env_crc;
memcpy(&env_crc, env + (env_size - 4), 4);

// Exclude the trailing 4 bytes that contain the received CRC
uint32_t crc = crc32_ieee(env, env_size - 4);
if (crc != env_crc) {
LOG_WRN("Data corruption in received peripheral event, ignoring %d vs %d", crc,
env_crc);
return -EINVAL;
}

return 0;
}

return -EAGAIN;
}
8 changes: 7 additions & 1 deletion app/src/split/wired/wired.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,17 @@

#include <zmk/split/transport/types.h>

#define ZMK_SPLIT_WIRED_ENVELOPE_MAGIC_PREFIX "ZmKw"

struct event_envelope {
uint8_t magic_prefix[4];
uint8_t source;
struct zmk_split_transport_peripheral_event event;
uint32_t crc;
} __packed;

struct command_envelope {
uint8_t magic_prefix[4];
uint8_t source;
struct zmk_split_transport_central_command cmd;
uint32_t crc;
Expand All @@ -38,4 +42,6 @@ void zmk_split_wired_fifo_read(const struct device *dev, struct ring_buf *buf,
struct k_work *process_work);
void zmk_split_wired_fifo_fill(const struct device *dev, struct ring_buf *tx_buf);

#endif
#endif

int zmk_split_wired_get_item(struct ring_buf *rx_buf, uint8_t *env, size_t env_size);

0 comments on commit 45d95af

Please sign in to comment.