Hi Pete > The main one was in getting the write function to work. The midi > driver > seems to cleanly pass an event at a time, which nicely fits in a USB > midi packet -- *unless* it is a SysEx sequence, which can take many > packets to transmit. So I thought I'd be efficient, and set up a > rotating pool of packet-sized buffers that I'd fill and pass on to > the USB driver with queue_bulk(...) as fast as they were filled. > (A semaphore primed with the number of buffers is used to prevent > overflow.) You do not need to split up anything. In fact you shouldn't. The packet size of the endpoint is purely informational for you. The stack (or the host controller depending on the model) will do the splitting up. You hand in the whole buffer with all the payload data you need to send. > I've made it work by changing the semaphore to only allow one packet > to get sent until the callback is invoked, but this seems wrong from > the concept of a 'queue'. [And SLOW!] Or, as I say, am I > misunderstanding? It is not actually a queue. It simply means that the function is async. Transmission is queued and the function returns. You must only queue one transfer at a time. For receiving this cannot work differently due to the data toggle that you only know after an incoming transfer has passed. For sending it would be possible to calculate the toggle up front and allow multiple transfers. This is not currently supported however. This means one buffer at the time for now. Since you do not need to split up your buffer and can pass in the whole payload data you want, this is in practice usually not a problem. Regards Michael