Maestro
Steve Pampling (1551) 8172 posts |
When I referred to a master timer in the "generic timer thread, what you have said matches what I was thinking of so
I’m thinking it’s a good idea. Druck did a module that did that so he thought it was a good idea. Other people are now free to join in thinking it’s a good idea. |
Steve Pampling (1551) 8172 posts |
I’d disagree when the alternate is to “hijack” everything as low as possible and offer replacements at super intervals that are multiples of 0.001s. |
John Williams (567) 768 posts |
“alternative”? = Other option? |
Rick Murray (539) 13850 posts |
I was thinking about this while I was at work, and sorry, I just can’t justify MIDI needing to claim an entire timer (which might be the only available one in the system) for itself. So back to my earlier proposal:
This would provide RISC OS with the long known mechanisms for scheduling events and timing/delaying, only running to an accuracy of 1kHz rather than 100Hz. More than all of that, it would be a system wide resource available for suitable software (in the same way as now with the existing setup) which is infinitely better than the entirely bad idea of “let’s create a protocol to claim a limited resource to solve just one problem”. MIDI? Solved:
Want to time very specific delays in BASIC, maybe for poking hardware, maybe better than 100Hz? The ReadFastTime SWI, just like ReadMonotonicTime. I bet you could do reasonable work in a millisecond on a Pi, even in BASIC! Don’t steal a hardware timer for a specific use, make a system-wide resource and everything can benefit. |
Steve Pampling (1551) 8172 posts |
So back to my earlier proposal: and Don’t steal a hardware timer for a specific use, make a system-wide resource and everything can benefit. Which in various different words seems to be what most people are saying. One fast timer (can we go faster than 1kHz?) and slower sub-timer facilities for any event requiring vaguely precise regular action. I suspect any such facility would: |
Chris (121) 472 posts |
I’ve probably misunderstood, but isn’t that exactly what Jeffrey is proposing in the ARM generic timer thread? |
Steve Pampling (1551) 8172 posts |
Yes, but everyone is following the standard management principle: |
Ron (2686) 63 posts |
Rick’s comment: Can you not run it 2KHz? and get 0.5mS ticks? |
Rick Murray (539) 13850 posts |
The CallEvery time would be R0+1, meaning the minimum would be 2ms. Millisecond is available. To quote CallEvery: |
Dave Higton (1515) 3534 posts |
Rick, would you care to make the source code of your USB MIDI module available, either to the public at large, or just to me? |
Rick Murray (539) 13850 posts |
Dave – since you asked nicely and I’m not planning on working on it at this time… http://heyrick.ddns.net/files/usbmidi_005_source.zip It has been licenced as EUPL v1.1 (only). PDF file included gives you the blurb, but it’s basically “Like GPL but without the s**t”. ;-) |
Dave Higton (1515) 3534 posts |
Got it, thanks, Rick. |
Rick Murray (539) 13850 posts |
It’s my birthday tomorrow (though I celebrate on June 16th), so no pointing at the code and laughing, okay? ;-) |
Dave Higton (1515) 3534 posts |
Okay! Actually you’ve set it all out very neatly, clearly with maintainability in mind. I’m still not getting anything coming through from my MIDI keyboard (I can send to it from Maestro, but I can’t get any app or any debug in the module to see incoming stuff). My own test app, which just opens the bulk in endpoint and reads from it stupidly, does get input. So far I can’t work out what’s wrong. I was surprised to see the way you open endpoints: by telling RO whether to open for input or output, and letting RO work out which endpoint to use. However, I’ve tried a more conventional approach, tied to my particular device, for testing purposes, and it makes no difference: nothing comes in. Work continues… |
Dave Higton (1515) 3534 posts |
The input-from-USB process of the USB MIDI module calls OS_GBPB 4, but it always returns with R3 on exit = R3 on entry, showing no bytes available. I notice that the regs on exit from OS_GBPB 4 are the same as the regs on entry, if no bytes are transferred. So how would I know if OS_GBPB is really being called? As I said above, my simple and stupid test app does receive data from the input endpoint of the USB device – even if no keys are being pressed on the instrument, it’s sending Active Sensing frequently. So the hardware works; the problem, whatever it is, is in software. |
Dave Higton (1515) 3534 posts |
To answer my own question: call _kernel_swi_c and see if the carry flag is altered. It is. Does the OS modify the operation of OS_GBPB in a ticker handler? ‘Cos that’s where this call is made from. |
Richard Walker (2090) 431 posts |
The GBPB isn’t returning an error, is it? Sorry, just thought I would ask! Does your simple test app use GBPB in the same way? And open the USB endpoint in the same way? If you can stand the clutter, you could take a look at my USBJoystick source. It uses Buffer Manager (rather than GBPB) so if you have some fundamental issue with using it, then you can always not use it! |
Rick Murray (539) 13850 posts |
Thank you. That’s how I write code now. Let’s just say I learn from my mistakes. :-)
I had this big messy bit of code that parsed the descriptors and worked out which endpoint was which. I threw that away when I realised (by mistake in a BASIC test program) that if you don’t specify the endpoint, RISC OS will open the appropriate one automatically.
Check the logic in usb.c for opening the handles and setting up the options. If nothing else, it would be good to be certain that both programs are opening the handles in the same way.
Which may or may not ever be passed on to the client. The MIDI module may use/ignore/suppress these messages – read to user guide (either mine or the original Acorn one). I think the debug command says whether or not the module has received active sensing messages, if it is handling them. If you have DADebug, there ought to be some code in place to enable some debugging info. Don’t be afraid to add more if you need it.
Which sort of ticker? It ought to be a CallAfter which schedules a CallBack which does the read. FileCore reentrancy and all that… |
Dave Higton (1515) 3534 posts |
My apologies, I got rather disheartened. I restarted tests last night.
No. I addd debug code to test for that. No error, but no bytes either.
I must have deleted it (or it was in RAM disc). Opening was via OPENIN, where Rick’s module uses OS_Find, but I believe that they amount to the same. I’ll have to do some more tests tonight. The module’s opening code tests for and reports errors, but there aren’t any errors to report.
They do seem to be, with the obvious and correct exception that only the input stream is set non-padding. Two endpoints are opened up on the device. It isn’t possible to open an endpoint twice, and the other endpoint outputs correctly to MIDI, so the one I’m looking at must be the input. Active sensing:
I’m looking at the point of the OS_GBPB 4, before any filtering can take place.
I do. Makes no difference. Rick, can you confirm that your module does generate input from a MIDI keyboard? |
Colin (478) 2433 posts |
Don’t use OS_GBPB from the upcall handler use the buffer functions directly – obtained with Buffer_InternalInfo. bsd.riscos.sources.networking.Ethernet.etherusb.c.usb in CVS shows how to use the functions. At UpCall_DeviceRxDataPresent you can read if data is present with one of thes functions and process it if it is. Always remove all of the data from the buffer otherwise you will not get an UpCall_DeviceRxDataPresent event again. Also at UpCall_DeviceRxDataPresent you need to call
This ensures that the streaming process continues. It specifies that you want to fetch a large number of bytes but you will actually get only bytes that are available. Also use this same call to start the streaming process outside of the upcall vector maybe after you open the endpoint. Open and close the endpoint in the usual way I use nonblocking endpoints – probably out of habit not sure it matters if not using os_gbpb. |
Dave Higton (1515) 3534 posts |
Colin: thank you for your information. It’s clear that I’m getting well out of my depth here. I need to work towards getting data, and putting data, potentially every millisecond. Let’s shelve the output for the moment and look at the input. The incoming data MUST be accurately time stamped. I can see two possibilities: 1) The module’s UpCall_DeviceRxDataPresent handler will be called within the same millisecond that the data appeared, in which case I can use it. 2) It won’t be called until some upredictable time later, in which case I have to look at the buffer every millisecond from the timer handler. The timer handler is AFAIK in IRQ mode. So, does the upcall handler always get called very promptly, or can the buffer routines be called in IRQ mode? |
Colin (478) 2433 posts |
The UpCall_DeviceRxDataPresent event in the upcall handler is called from IRQ mode as soon as data is transferred from the USB DMA buffer to the DeviceFS buffer (and the deviceFS buffer was previously empty) so you won’t get to the data any quicker. You don’t need a large USB buffer I’d expect packet size would do – depends if the device is likely to send multiple packet chunks You can use the buffer functions to read the number of bytes in the buffer and to transfer the bytes out. |
Rick Murray (539) 13850 posts |
Of course. Not a lot of point if it can’t manage that. ;-)
It’s a ticker event, not an upcall. I never managed to get that to work reliably.
Hmm…? I thought I was, but… |
Colin (478) 2433 posts |
Is bufman.zip any use to you. I made it for SerialUSB. You create a bufman object with bufman_new from the buffer handle delete it with bufman_delete and there are various functions for manipulating the buffer. |
Dave Higton (1515) 3534 posts |
Well, a little bit of news. I’ve got an UpCall handler that outputs a debug string on UpCall 8 from our input endpoint. But here’s the curious bit: there’s no debug message until I’ve played something to the ME50 from Maestro! Whereupon I get a continuous stream of them, at a rate that suggests each is from Active Sensing messages. This must be a bug in the crappy adapter that I have. Still no data coming in from the endpoint via OS_GBPB 4, but I haven’t implemented Colin’s ideas yet. It’s been enough of a struggle to get all the right parameters for some of the DeviceFS calls. Plus I’ve actually watched some TV this evening… a real rarity for me. |