MIDI recieve overrun?

Hey guys. I am using the MIDI handler routine from the Pod examples for my clonewheel organ project. It works perfectly when I use my Korg TR workstation MIDI Out as a keyboard.

Now the odd part: This workstation has an “audition” function that plays a few bars of a song so you can hear any of its built-in patches. Their MIDI sequences are played out as well - nice for me since I can’t play a lick on a keyboard! Some of them play fine, but a few leave one or more “stuck-on” notes. I can turn them off if I hit the key of the stuck note again, as the code will correctly process it and turn the note off. I have seen as many as 8 notes stuck on by a particularly “dense” MIDI sequence. So it seems like some Note-Off messages are not being handled.

I am only looking at Note-On and Note-Off messages, ignoring anything else. I keep a 32-entry note table, add to it with the On’s note value, and search and delete them when I get the Off’s. I process at the 1ms callback rate. With 32-way polyphony, I can literally lean my arm on the keyboard and all the notes turn on and off as expected.

So the question is, is the MIDI handler routine in the HID library robust, i.e. can it handle incoming messages at the maximum rate, and ignore all the messages that it is supposed to ignore? Looking through the “maze of twisty passages” that are the libraries, I see that the handler uses a 256-entry event FIFO. I can’t imagine that it is overrun.

Any ideas? This isn’t a show-stopper for me, but I assume that others might want to drive their Daisy synths with MIDI sequencer apps that could could overwhelm the handler in this way.

Thanks for bringing this up. We’re going to be going into implement the unimplemented MIDI messages (i.e. Program Change, etc.) in the next few weeks. So we can dig into this a bit while we’re doing that.

Is your libdaisy up to date? We did merge an update the fixed the handling of the Channel Pressure messages that could trip up the whole MIDI bus (since they’re only two bytes). I don’t think it would cause only a few hung notes, but if you’re on an earlier version of the library, and there are channel pressure messages in the MIDI files being played there’s a chance it’s related.

Otherwise, it does sound like an overrun issue, but as you’ve said it’s pretty easy to just slam the keyboard or send a bunch of CCs and still see everything chug away.

Once we get in there and poke around a bit, I can report back with a bit more detail.

@shensley it looks like you might get overrun with current UART code in some cases, because of check in line 449:

Seems like transfer callback would only get called if IDLE flag is set. It probably won’t be the case if you’ve ended a DMA transfer while there’s more data being sent. Won’t that lead to buffer data between last IDLE interrupt and end of DMA transfer getting discarded?

For OWL we do things a bit different and stop DMA transfer on IDLE interrupt which allows us to complete the transaction earlier. So we can setup multiple transactions of variable length this way rather than a single transaction with intermediate reads.

Ah, you might be right. The intention was to have the RxCpltCallback still fire if the buffer completely filled (which it will, but will be ignored because of the conditional you linked), while having the IDLE flag prematurely trigger the callback if necessary.

In the actual UART_IRQHandler, we are already checking if the IDLE flag is set. So the check in the RxCpltCallback is a bit redundant either way.

I’ve opened an issue on github. So that we’re aware, and can spend some time revisiting this a bit to avoid the current possible pit fall.