Pisound: MIDI communication fixes for scaled down CPU.

* Increased maximum SPI communication speed to avoid running too slow
  when the CPU is scaled down and losing MIDI data.

* Keep track of buffer usage in millibytes for higher precision.

Signed-off-by: Giedrius Trainavičius <giedrius@blokas.io>
This commit is contained in:
Giedrius
2020-01-07 11:04:21 +02:00
committed by popcornmix
parent 76f2adafd6
commit d10c7d7946

View File

@@ -1,6 +1,6 @@
/* /*
* Pisound Linux kernel module. * Pisound Linux kernel module.
* Copyright (C) 2016-2019 Vilniaus Blokas UAB, https://blokas.io/pisound * Copyright (C) 2016-2020 Vilniaus Blokas UAB, https://blokas.io/pisound
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@@ -326,7 +326,7 @@ static void spi_transfer(const uint8_t *txbuf, uint8_t *rxbuf, int len)
transfer.tx_buf = txbuf; transfer.tx_buf = txbuf;
transfer.rx_buf = rxbuf; transfer.rx_buf = rxbuf;
transfer.len = len; transfer.len = len;
transfer.speed_hz = 100000; transfer.speed_hz = 150000;
transfer.delay_usecs = 10; transfer.delay_usecs = 10;
spi_message_add_tail(&transfer, &msg); spi_message_add_tail(&transfer, &msg);
@@ -403,9 +403,9 @@ static struct spi_device *pisnd_spi_find_device(void)
static void pisnd_work_handler(struct work_struct *work) static void pisnd_work_handler(struct work_struct *work)
{ {
enum { TRANSFER_SIZE = 4 }; enum { TRANSFER_SIZE = 4 };
enum { PISOUND_OUTPUT_BUFFER_SIZE = 128 }; enum { PISOUND_OUTPUT_BUFFER_SIZE_MILLIBYTES = 127 * 1000 };
enum { MIDI_BYTES_PER_SECOND = 3125 }; enum { MIDI_MILLIBYTES_PER_JIFFIE = (3125 * 1000) / HZ };
int out_buffer_used = 0; int out_buffer_used_millibytes = 0;
unsigned long now; unsigned long now;
uint8_t val; uint8_t val;
uint8_t txbuf[TRANSFER_SIZE]; uint8_t txbuf[TRANSFER_SIZE];
@@ -445,7 +445,9 @@ static void pisnd_work_handler(struct work_struct *work)
had_data = false; had_data = false;
memset(txbuf, 0, sizeof(txbuf)); memset(txbuf, 0, sizeof(txbuf));
for (i = 0; i < sizeof(txbuf) && for (i = 0; i < sizeof(txbuf) &&
out_buffer_used < PISOUND_OUTPUT_BUFFER_SIZE; ((out_buffer_used_millibytes+1000 <
PISOUND_OUTPUT_BUFFER_SIZE_MILLIBYTES) ||
g_ledFlashDurationChanged);
i += 2) { i += 2) {
val = 0; val = 0;
@@ -458,7 +460,7 @@ static void pisnd_work_handler(struct work_struct *work)
} else if (kfifo_get(&spi_fifo_out, &val)) { } else if (kfifo_get(&spi_fifo_out, &val)) {
txbuf[i+0] = 0x0f; txbuf[i+0] = 0x0f;
txbuf[i+1] = val; txbuf[i+1] = val;
++out_buffer_used; out_buffer_used_millibytes += 1000;
} }
} }
@@ -469,12 +471,14 @@ static void pisnd_work_handler(struct work_struct *work)
* rate. * rate.
*/ */
now = jiffies; now = jiffies;
out_buffer_used -= if (now != last_transfer_at) {
(MIDI_BYTES_PER_SECOND / HZ) / out_buffer_used_millibytes -=
(now - last_transfer_at); (now - last_transfer_at) *
if (out_buffer_used < 0) MIDI_MILLIBYTES_PER_JIFFIE;
out_buffer_used = 0; if (out_buffer_used_millibytes < 0)
out_buffer_used_millibytes = 0;
last_transfer_at = now; last_transfer_at = now;
}
for (i = 0; i < sizeof(rxbuf); i += 2) { for (i = 0; i < sizeof(rxbuf); i += 2) {
if (rxbuf[i]) { if (rxbuf[i]) {
@@ -489,6 +493,7 @@ static void pisnd_work_handler(struct work_struct *work)
|| !kfifo_is_empty(&spi_fifo_out) || !kfifo_is_empty(&spi_fifo_out)
|| pisnd_spi_has_more() || pisnd_spi_has_more()
|| g_ledFlashDurationChanged || g_ledFlashDurationChanged
|| out_buffer_used_millibytes != 0
); );
if (!kfifo_is_empty(&spi_fifo_in) && g_recvCallback) if (!kfifo_is_empty(&spi_fifo_in) && g_recvCallback)