Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions components/artnet/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ menu "qmsk-artnet"
config ARTNET_OUTPUTS_MAX
int "Maximum Art-NET output universes"

range 0 20
default 16
range 0 24
default 4
help
Must be less than CONFIG_LWIP_UDP_RECVMBOX_SIZE and CONFIG_LWIP_TCPIP_RECVMBOX_SIZE to avoid dropped packets.

endmenu
15 changes: 15 additions & 0 deletions components/artnet/artnet.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ int artnet_init(struct artnet *artnet, struct artnet_options options)
LOG_ERROR("calloc(input_dmx)");
return -1;
}

if (!(artnet->input_events = xEventGroupCreate())) {
LOG_ERROR("xEventGroupCreate");
return -1;
}
}

if (options.outputs) {
Expand Down Expand Up @@ -155,3 +160,13 @@ void artnet_get_stats(struct artnet *artnet, struct artnet_stats *stats)
stats->errors = stats_counter_copy(&artnet->stats.errors);
stats->dmx_discard = stats_counter_copy(&artnet->stats.dmx_discard);
}

// node in synchronous DMX mode?
bool artnet_sync_state (struct artnet *artnet)
{
if (artnet->sync_tick) {
return xTaskGetTickCount() - artnet->sync_tick < ARTNET_SYNC_TICKS;
} else {
return false;
}
}
6 changes: 5 additions & 1 deletion components/artnet/artnet.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ void artnet_reset_inputs_stats(struct artnet *artnet);

/* output.c */
struct artnet_output {
struct artnet *artnet;

enum artnet_port_type type;
struct artnet_output_options options;
struct artnet_output_state state;
Expand Down Expand Up @@ -79,11 +81,13 @@ struct artnet {
struct artnet_dmx dmx;

/* inputs */
xTaskHandle input_task;
EventGroupHandle_t input_events;
struct artnet_dmx *input_dmx;

// last sync received at
TickType_t sync_tick;

struct artnet_stats stats;
};

bool artnet_sync_state (struct artnet *artnet);
30 changes: 16 additions & 14 deletions components/artnet/include/artnet.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,16 @@
#define ARTNET_INPUT_NAME_MAX 16
#define ARTNET_OUTPUT_NAME_MAX 16

// limited to 20 by the available FreeRTOS event group bits
// hard-limited to 24 by the available FreeRTOS event group bits
#define ARTNET_OUTPUTS_MAX (CONFIG_ARTNET_OUTPUTS_MAX)

// up to 20 task notification bits for indexed outputs
// NOTE: FreeRTOS event groups only support 24 bits...
#define ARTNET_OUTPUT_EVENT_INDEX_BITS 0x000fffff
#define ARTNET_OUTPUT_EVENT_FLAG_BITS 0x00f00000

// flag bit to force output sync
#define ARTNET_OUTPUT_EVENT_SYNC_BIT 20
// up to 24 task notification bits for indexed outputs
// NOTE: FreeRTOS event groups only support 24 bits
#define ARTNET_OUTPUT_EVENT_BITS 0x00ffffff

// limited by ARTNET_INPUT_TASK_INDEX_BITS
#define ARTNET_INPUTS_MAX 16
#define ARTNET_INPUT_TASK_INDEX_BITS 0xffff
#define ARTNET_INPUT_EVENT_BITS 0x00ffffff

struct artnet;
struct artnet_input;
Expand All @@ -59,9 +55,6 @@ struct artnet_options {
};

struct artnet_dmx {
// flags
uint8_t sync_mode : 1; // receiver is in sync mode, wait for sync event before refreshing output

// received sequence number
uint8_t seq : 8;

Expand Down Expand Up @@ -90,8 +83,17 @@ struct artnet_output_options {
/* Set event group bits on DMX updates */
EventGroupHandle_t event_group;

/* Only bits matching ARTNET_OUTPUT_EVENT_INDEX_BITS are supported */
EventBits_t event_bits;
/* Only bits matching ARTNET_OUTPUTS_EVENT_BITS are supported */
EventBits_t dmx_event_bit;

/* Only bits matching ARTNET_OUTPUTS_EVENT_BITS are supported */
EventBits_t sync_event_bit;

/* Set event group bits on DMX sync/update */
EventGroupHandle_t output_events;

/* Only bits matching ARTNET_OUTPUTS_EVENT_BITS are supported */
EventBits_t output_event_bit;
};

struct artnet_input_state {
Expand Down
18 changes: 7 additions & 11 deletions components/artnet/input.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,27 +64,23 @@ void artnet_input_dmx(struct artnet_input *input, const struct artnet_dmx *dmx)
xQueueOverwrite(input->queue, dmx);
}

if (input->artnet->input_task) {
xTaskNotify(input->artnet->input_task, (1 << input->index) & ARTNET_INPUT_TASK_INDEX_BITS, eSetBits);
if (input->artnet->input_events) {
xEventGroupSetBits(input->artnet->input_events, (1 << input->index) & ARTNET_INPUT_EVENT_BITS);
}
}

int artnet_inputs_main(struct artnet *artnet)
{
uint32_t notify_bits;

artnet->input_task = xTaskGetCurrentTaskHandle();

for (;;) {
if (!xTaskNotifyWait(0, ARTNET_INPUT_TASK_INDEX_BITS, &notify_bits, portMAX_DELAY)) {
LOG_ERROR("xTaskNotifyWait");
continue;
}
BaseType_t xClearOnExit = true;
BaseType_t xWaitForAllBits = false;

EventBits_t event_bits = xEventGroupWaitBits(artnet->input_events, ARTNET_INPUT_EVENT_BITS, xClearOnExit, xWaitForAllBits, portMAX_DELAY);

for (unsigned index = 0; index < artnet->input_count; index++) {
struct artnet_input *input = &artnet->input_ports[index];

if (!(notify_bits & (1 << index))) {
if (!(event_bits & (1 << index))) {
continue;
}

Expand Down
33 changes: 19 additions & 14 deletions components/artnet/output.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,16 @@ int artnet_add_output(struct artnet *artnet, struct artnet_output **outputp, str
return -1;
}

if (!options.event_group) {
LOG_DEBUG("event_bits unused");
} else if (!options.event_bits) {
LOG_ERROR("event_bits=%08x empty", options.event_bits);
if (!options.output_events) {
LOG_DEBUG("output_events unused");
} else if (!options.output_event_bit) {
LOG_ERROR("output_event_bit=%08x empty", options.output_event_bit);
return -1;
} else if ((options.event_bits & ~ARTNET_OUTPUT_EVENT_INDEX_BITS)) {
LOG_ERROR("event_bits=%08x overflow", options.event_bits);
} else if ((options.output_event_bit & ~ARTNET_OUTPUT_EVENT_BITS)) {
LOG_ERROR("output_event_bit=%08x overflow", options.output_event_bit);
return -1;
} else {
LOG_DEBUG("event_bits=%08x", options.event_bits);
LOG_DEBUG("output_event_bit=%08x", options.output_event_bit);
}

LOG_DEBUG("output=%d address=%04x", artnet->output_count, options.address);
Expand All @@ -43,6 +43,7 @@ int artnet_add_output(struct artnet *artnet, struct artnet_output **outputp, str

struct artnet_output *output = &artnet->output_ports[artnet->output_count++];

output->artnet = artnet;
output->type = ARTNET_PORT_TYPE_DMX;
output->options = options;
output->queue = queue;
Expand Down Expand Up @@ -208,19 +209,23 @@ void artnet_output_dmx(struct artnet_output *output, struct artnet_dmx *dmx)

output->state.tick = tick;

if (dmx->sync_mode) {
stats_counter_increment(&output->stats.dmx_sync);
}

// attempt normal send first, before overwriting for overflow stats
if (xQueueSend(output->queue, dmx, 0) == errQUEUE_FULL) {
stats_counter_increment(&output->stats.queue_overwrite);

xQueueOverwrite(output->queue, dmx);
}

if (output->options.event_group) {
xEventGroupSetBits(output->options.event_group, output->options.event_bits);
if (output->options.output_events) {
xEventGroupSetBits(output->options.output_events, output->options.output_event_bit);
}

if (artnet_sync_state(output->artnet)) {
// wait for hard sync
stats_counter_increment(&output->stats.dmx_sync);
} else if (output->options.event_group && output->options.dmx_event_bit) {
// sync each update
xEventGroupSetBits(output->options.event_group, output->options.dmx_event_bit);
}
}

Expand Down Expand Up @@ -262,7 +267,7 @@ int artnet_sync_outputs(struct artnet *artnet)
stats_counter_increment(&output->stats.sync_recv);

if (output->options.event_group != event_group) {
xEventGroupSetBits(output->options.event_group, (1 << ARTNET_OUTPUT_EVENT_SYNC_BIT));
xEventGroupSetBits(output->options.event_group, output->options.sync_event_bit);

// only notify each event_group once
event_group = output->options.event_group;
Expand Down
11 changes: 0 additions & 11 deletions components/artnet/protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,16 +151,6 @@ int artnet_sendrecv_poll(struct artnet *artnet, struct artnet_sendrecv *sendrecv
return artnet_send_poll_reply(artnet, sendrecv);
}

// node in synchronous DMX mode?
static bool artnet_sync_state (struct artnet *artnet)
{
if (artnet->sync_tick) {
return xTaskGetTickCount() - artnet->sync_tick < ARTNET_SYNC_TICKS;
} else {
return false;
}
}

int artnet_recv_dmx(struct artnet *artnet, const struct artnet_sendrecv *recv)
{
struct artnet_packet_dmx *dmx = &recv->packet->dmx;
Expand Down Expand Up @@ -198,7 +188,6 @@ int artnet_recv_dmx(struct artnet *artnet, const struct artnet_sendrecv *recv)
#endif

// copy
artnet->dmx.sync_mode = artnet_sync_state(artnet);
artnet->dmx.seq = seq;
artnet->dmx.len = len;

Expand Down
4 changes: 2 additions & 2 deletions main/artnet_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ int artnet_cmd_info(int argc, char **argv, void *ctx)
}

printf("\n");
printf("Inputs: count=%u\n", input_count);
printf("Inputs: count=%u / max=%d\n", input_count, ARTNET_INPUTS_MAX);

for (int i = 0; i < inputs_size && i < ARTNET_INPUTS_MAX; i++) {
struct artnet_input_options *options = &artnet_input_options[i];
Expand All @@ -76,7 +76,7 @@ int artnet_cmd_info(int argc, char **argv, void *ctx)
}

printf("\n");
printf("Outputs: count=%u\n", output_count);
printf("Outputs: count=%u / max=%d\n", output_count, ARTNET_OUTPUTS_MAX);

for (int i = 0; i < outputs_size && i < ARTNET_OUTPUTS_MAX; i++) {
struct artnet_output_options *options = &artnet_output_options[i];
Expand Down
Loading
Loading