Skip to content

Commit

Permalink
SUKU trs midi rx hanging note fixed, latency introduced
Browse files Browse the repository at this point in the history
  • Loading branch information
SukuWc committed Mar 13, 2024
1 parent 9022bd8 commit fe1c520
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 109 deletions.
6 changes: 5 additions & 1 deletion Firmware/.vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@
"grid_ui.h": "c",
"grid_led.h": "c",
"knot_midi_translator.h": "c",
"knot_midi_uart.h": "c"
"knot_midi_uart.h": "c",
"*.ipp": "c",
"bitset": "c",
"initializer_list": "c",
"utility": "c"
},
"actionButtons": {
"defaultColor": "#ff0034",
Expand Down
117 changes: 33 additions & 84 deletions Firmware/components/knot_midi_uart/knot_midi_uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,105 +111,54 @@ void knot_midi_uart_rx_task(void* arg) {

for (;;) {

vTaskDelay(1); // at least one tick however many ms that is
bzero(dtmp, RD_BUF_SIZE);
int length = 0;

uart_get_buffered_data_len(EX_UART_NUM, (size_t*)&length);
// Waiting for UART event.
if (xQueueReceive(knot_midi_uart_state.uart0_queue, (void*)&event, (TickType_t)portMAX_DELAY)) {
bzero(dtmp, RD_BUF_SIZE);
// ESP_LOGI(TAG, "uart[%d] event:", EX_UART_NUM);
switch (event.type) {
// Event of UART receiving data
/*We'd better handler data event fast, there would be much more data events than
other types of events. If we take too much time on data event, the queue might
be full.*/
case UART_DATA:
if (uart_read_bytes(EX_UART_NUM, dtmp, length, portMAX_DELAY)) {
// led_rx_effect_start();

grid_alert_one_set(&grid_led_state, 0, 200, 200, 200, 30);

// led_rx_effect_start();
ESP_LOGD(TAG, "[UART DATA]: %d", length);

grid_alert_one_set(&grid_led_state, 0, 200, 200, 200, 30);
for (int i = 0; i < length; i++) {

// ESP_LOGI(TAG, "[UART DATA]: %d", event.size);
uart_read_bytes(EX_UART_NUM, dtmp, event.size, portMAX_DELAY);
struct uart_midi_event_packet uart_ev = uart_midi_process_byte(dtmp[i]);

if (uart_ev.length) {
struct usb_midi_event_packet usb_ev = midi_uart_to_usb(uart_ev);
while (knot_midi_usb_out_isready() == 0) {
ESP_LOGD(TAG, "waiting\n");
vTaskDelay(1); // at least one tick however many ms that is
}

for (uint8_t i = 0; i < event.size; i++) {
portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED;
portENTER_CRITICAL(&spinlock);

struct uart_midi_event_packet uart_ev = uart_midi_process_byte(dtmp[i]);
int status = knot_midi_usb_send_packet(usb_ev);
portEXIT_CRITICAL(&spinlock);

if (uart_ev.length) {
struct usb_midi_event_packet usb_ev = midi_uart_to_usb(uart_ev);
knot_midi_usb_send_packet(usb_ev);
if (status == 0) {

// transfer was ok
if (knot_midi_uart_state.midi_through_state) {
knot_midi_uart_send_packet(uart_ev);
ets_printf("USB + MIDI: %d %d %d %d\n", usb_ev.byte0, usb_ev.byte1, usb_ev.byte2, usb_ev.byte3);
ESP_LOGD(TAG, "USB + MIDI: %d %d %d %d", usb_ev.byte0, usb_ev.byte1, usb_ev.byte2, usb_ev.byte3);
} else {
ets_printf("USB: %d %d %d %d\n", usb_ev.byte0, usb_ev.byte1, usb_ev.byte2, usb_ev.byte3);
ESP_LOGD(TAG, "USB: %d %d %d %d", usb_ev.byte0, usb_ev.byte1, usb_ev.byte2, usb_ev.byte3);
}
} else if (status == 1) {
ESP_LOGW(TAG, "USB not connected");
} else {
ESP_LOGW(TAG, "USB error: %d", status);
}
}

// ESP_LOGI(TAG, "[DATA EVT]: %d %d %d %d", dtmp[0], dtmp[1], dtmp[2], dtmp[3]);
break;
// Event of HW FIFO overflow detected
case UART_FIFO_OVF:

grid_alert_one_set(&grid_led_state, 1, 200, 0, 0, 30); // ERROR
ESP_LOGI(TAG, "hw fifo overflow");
// If fifo overflow happened, you should consider adding flow control for your application.
// The ISR has already reset the rx FIFO,
// As an example, we directly flush the rx buffer here in order to read more data.
uart_flush_input(EX_UART_NUM);
xQueueReset(knot_midi_uart_state.uart0_queue);
break;
// Event of UART ring buffer full
case UART_BUFFER_FULL:

grid_alert_one_set(&grid_led_state, 2, 200, 0, 0, 30); // ERROR
ESP_LOGI(TAG, "ring buffer full");
// If buffer full happened, you should consider encreasing your buffer size
// As an example, we directly flush the rx buffer here in order to read more data.
uart_flush_input(EX_UART_NUM);
xQueueReset(knot_midi_uart_state.uart0_queue);
break;
// Event of UART RX break detected
case UART_BREAK:
grid_alert_one_set(&grid_led_state, 0, 200, 0, 0, 30); // ERROR
ESP_LOGI(TAG, "uart rx break");
break;
// Event of UART parity check error
case UART_PARITY_ERR:
grid_alert_one_set(&grid_led_state, 0, 200, 0, 0, 30); // ERROR
ESP_LOGI(TAG, "uart parity error");
break;
// Event of UART frame error
case UART_FRAME_ERR:
grid_alert_one_set(&grid_led_state, 0, 200, 0, 0, 30); // ERROR
ESP_LOGI(TAG, "uart frame error");
break;
// UART_PATTERN_DET
case UART_PATTERN_DET:
grid_alert_one_set(&grid_led_state, 0, 200, 0, 0, 30); // ERROR
uart_get_buffered_data_len(EX_UART_NUM, &buffered_size);
int pos = uart_pattern_pop_pos(EX_UART_NUM);
ESP_LOGI(TAG, "[UART PATTERN DETECTED] pos: %d, buffered size: %d", pos, buffered_size);
if (pos == -1) {
// There used to be a UART_PATTERN_DET event, but the pattern position queue is full so that it can not
// record the position. We should set a larger queue size.
// As an example, we directly flush the rx buffer here.
uart_flush_input(EX_UART_NUM);
} else {
uart_read_bytes(EX_UART_NUM, dtmp, pos, 100 / portTICK_PERIOD_MS);
uint8_t pat[PATTERN_CHR_NUM + 1];
memset(pat, 0, sizeof(pat));
uart_read_bytes(EX_UART_NUM, pat, PATTERN_CHR_NUM, 100 / portTICK_PERIOD_MS);
ESP_LOGI(TAG, "read data: %s", dtmp);
ESP_LOGI(TAG, "read pat : %s", pat);
}
break;
// Others
default:
grid_alert_one_set(&grid_led_state, 0, 0, 0, 200, 30); // ERROR
ESP_LOGI(TAG, "uart event type: %d", event.type);
break;
}

// ESP_LOGI(TAG, "[DATA EVT]: %d %d %d %d", dtmp[0], dtmp[1], dtmp[2], dtmp[3]);
}

// ESP_LOGI(TAG, "UART RX loop");
Expand Down
43 changes: 21 additions & 22 deletions Firmware/components/knot_midi_usb/knot_midi_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,13 +208,6 @@ static esp_err_t midi_find_intf_and_ep_desc(class_driver_t* driver_obj, const us

static usb_transfer_t* out_transfer;

static void out_transfer_cb(usb_transfer_t* transfer) {
// This is function is called from within usb_host_client_handle_events(). Don't block and try to keep it short
struct class_driver_t* class_driver_obj = (struct class_driver_t*)transfer->context;

// ets_printf("OUT: Transfer status %d, actual number of bytes transferred %d\n", transfer->status, transfer->actual_num_bytes);
}

static usb_transfer_t* in_transfer;

static void in_transfer_cb(usb_transfer_t* in_transfer) {
Expand All @@ -234,27 +227,33 @@ static void in_transfer_cb(usb_transfer_t* in_transfer) {
usb_host_transfer_submit(in_transfer);
}

void knot_midi_usb_send_packet(struct usb_midi_event_packet ev) {
volatile uint8_t DRAM_ATTR usb_out_ready = 1;

if (out_transfer != NULL) {
static void IRAM_ATTR out_transfer_cb(usb_transfer_t* in_transfer) {
// ets_printf("Ready\n");
usb_out_ready = 1;
}

out_transfer->num_bytes = 4;
ets_printf("OUT: %d %d %d %d\r\n", ev.byte0, ev.byte1, ev.byte2, ev.byte3);
uint8_t knot_midi_usb_out_isready(void) { return usb_out_ready; }

out_transfer->data_buffer[0] = ev.byte0;
out_transfer->data_buffer[1] = ev.byte1;
out_transfer->data_buffer[2] = ev.byte2;
out_transfer->data_buffer[3] = ev.byte3;
int knot_midi_usb_send_packet(struct usb_midi_event_packet ev) {

usb_host_transfer_submit(out_transfer);
} else {
ets_printf("USB not connected\r\n");
if (out_transfer == NULL) {
return 1;
}

// memset(out_transfer->data_buffer, 0xAA, 4);
// out_transfer->num_bytes = 4;
// ets_printf("OUT: %d %d %d %d\r\n", ev.byte0, ev.byte1, ev.byte2, ev.byte3 );
// usb_host_transfer_submit(out_transfer);
out_transfer->num_bytes = 4;

out_transfer->data_buffer[0] = ev.byte0;
out_transfer->data_buffer[1] = ev.byte1;
out_transfer->data_buffer[2] = ev.byte2;
out_transfer->data_buffer[3] = ev.byte3;
out_transfer->callback = out_transfer_cb;

usb_out_ready = 0;
esp_err_t err = usb_host_transfer_submit(out_transfer);

return err;
}

static void action_get_dev_desc(class_driver_t* driver_obj) {
Expand Down
3 changes: 2 additions & 1 deletion Firmware/components/knot_midi_usb/knot_midi_usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ typedef struct {
int claimed_interface;
} class_driver_t;

void knot_midi_usb_send_packet(struct usb_midi_event_packet ev);
uint8_t knot_midi_usb_out_isready(void);
int knot_midi_usb_send_packet(struct usb_midi_event_packet ev);

void class_driver_task(void* arg);
2 changes: 1 addition & 1 deletion Firmware/main/midi_host_fw.c
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ void app_main(void) {
grid_led_set_layer_color(&grid_led_state, 2, GRID_LED_LAYER_UI_A, 0, 255, 0); // green
}

xTaskCreatePinnedToCore(knot_midi_uart_rx_task, "uart_rx", 2048, (void*)signaling_sem, UART_RX_TASK_PRIORITY, &uart_rx_task_hdl, 0);
xTaskCreatePinnedToCore(knot_midi_uart_rx_task, "uart_rx", 4096, (void*)signaling_sem, UART_RX_TASK_PRIORITY, &uart_rx_task_hdl, 0);

uint8_t last_button_state = 1;

Expand Down

0 comments on commit fe1c520

Please sign in to comment.