Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix send/receive #91

Merged
merged 5 commits into from
Aug 19, 2023
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
22 changes: 13 additions & 9 deletions src/dmx/hal.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ static bool DMX_ISR_ATTR dmx_timer_isr(
driver->flags &= ~DMX_FLAGS_DRIVER_IS_IN_BREAK;

// Reset the alarm for the end of the DMX mark-after-break
dmx_timer_set_alarm(timer, driver->break_len + driver->mab_len);
dmx_timer_set_alarm(timer, driver->mab_len, false);
} else {
// Write data to the UART
size_t write_size = driver->tx_size;
Expand Down Expand Up @@ -882,7 +882,8 @@ size_t dmx_receive(dmx_port_t dmx_num, dmx_packet_t *packet,
// Set an early timeout with the hardware timer
taskENTER_CRITICAL(DMX_SPINLOCK(dmx_num));
dmx_timer_set_counter(timer, elapsed);
dmx_timer_set_alarm(timer, RDM_PACKET_SPACING_CONTROLLER_NO_RESPONSE);
dmx_timer_set_alarm(timer, RDM_PACKET_SPACING_CONTROLLER_NO_RESPONSE,
false);
dmx_timer_start(timer);
taskEXIT_CRITICAL(DMX_SPINLOCK(dmx_num));
}
Expand All @@ -893,23 +894,25 @@ size_t dmx_receive(dmx_port_t dmx_num, dmx_packet_t *packet,
dmx_timer_stop(timer);
driver->task_waiting = NULL;
taskEXIT_CRITICAL(DMX_SPINLOCK(dmx_num));

if (!notified) {
xTaskNotifyStateClear(xTaskGetCurrentTaskHandle());
xSemaphoreGiveRecursive(driver->mux);
return packet_size;
}
taskENTER_CRITICAL(DMX_SPINLOCK(dmx_num));
driver->flags &= ~DMX_FLAGS_DRIVER_HAS_DATA;
packet_size = driver->head;
taskEXIT_CRITICAL(DMX_SPINLOCK(dmx_num));
} else if (!(driver_flags & DMX_FLAGS_DRIVER_HAS_DATA)) {
// Fail early if there is no data available and this function cannot block
xSemaphoreGiveRecursive(driver->mux);
return packet_size;
}

// Parse DMX data packet
taskENTER_CRITICAL(DMX_SPINLOCK(dmx_num));
driver->flags &= ~DMX_FLAGS_DRIVER_HAS_DATA;
packet_size = driver->head;
taskEXIT_CRITICAL(DMX_SPINLOCK(dmx_num));
if (packet_size == -1) {
packet_size = 0;
}
if (packet != NULL) {
taskENTER_CRITICAL(DMX_SPINLOCK(dmx_num));
packet->sc = packet_size > 0 ? driver->data[0] : -1;
Expand Down Expand Up @@ -1158,14 +1161,15 @@ size_t dmx_send(dmx_port_t dmx_num, size_t size) {
elapsed = dmx_timer_get_micros_since_boot() - driver->last_slot_ts;
if (elapsed < timeout) {
dmx_timer_set_counter(timer, elapsed);
dmx_timer_set_alarm(timer, timeout);
dmx_timer_set_alarm(timer, timeout, false);
dmx_timer_start(timer);
driver->task_waiting = xTaskGetCurrentTaskHandle();
}
taskEXIT_CRITICAL(DMX_SPINLOCK(dmx_num));

// Block if an alarm was set
if (elapsed < timeout) {
// FIXME: clean up this section
bool notified = xTaskNotifyWait(0, ULONG_MAX, NULL, pdDMX_MS_TO_TICKS(23));
if (!notified) {
dmx_timer_stop(timer);
Expand Down Expand Up @@ -1249,7 +1253,7 @@ size_t dmx_send(dmx_port_t dmx_num, size_t size) {
driver->flags |=
(DMX_FLAGS_DRIVER_IS_IN_BREAK | DMX_FLAGS_DRIVER_IS_SENDING);
dmx_timer_set_counter(timer, 0);
dmx_timer_set_alarm(timer, driver->break_len);
dmx_timer_set_alarm(timer, driver->break_len, true);
dmx_timer_start(timer);

dmx_uart_invert_tx(uart, 1);
Expand Down
8 changes: 4 additions & 4 deletions src/dmx/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ dmx_timer_handle_t dmx_timer_init(dmx_port_t dmx_num, void *isr_handle,
.counter_dir = TIMER_COUNT_UP,
.counter_en = false,
.alarm_en = true,
.auto_reload = false,
.auto_reload = true,
};
esp_err_t err = timer_init(timer->group, timer->idx, &timer_config);
if (err) {
Expand Down Expand Up @@ -95,15 +95,15 @@ void DMX_ISR_ATTR dmx_timer_set_counter(dmx_timer_handle_t timer,
}

void DMX_ISR_ATTR dmx_timer_set_alarm(dmx_timer_handle_t timer,
uint64_t alarm) {
uint64_t alarm, bool auto_reload) {
#if ESP_IDF_VERSION_MAJOR >= 5
const gptimer_alarm_config_t alarm_config = {
.alarm_count = alarm,
.reload_count = 0,
.flags.auto_reload_on_alarm = false};
.flags.auto_reload_on_alarm = auto_reload};
gptimer_set_alarm_action(timer->gptimer_handle, &alarm_config);
#else
timer_set_alarm_value(timer->group, timer->idx, alarm);
timer_group_set_alarm_value_in_isr(timer->group, timer->idx, alarm);
#endif
}

Expand Down
5 changes: 4 additions & 1 deletion src/dmx/timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,11 @@ void dmx_timer_set_counter(dmx_timer_handle_t timer, uint64_t counter);
*
* @param timer A handle to the DMX timer.
* @param alarm The alarm value to which to set the DMX timer.
* @param auto_reload Set to true to automatically reload the alarm when the
* alarm is triggered.
*/
void dmx_timer_set_alarm(dmx_timer_handle_t timer, uint64_t alarm);
void dmx_timer_set_alarm(dmx_timer_handle_t timer, uint64_t alarm,
bool auto_reload);

/**
* @brief Starts the DMX timer.
Expand Down