Jump to content

Sauraen

Programmer
  • Posts

    460
  • Joined

  • Last visited

  • Days Won

    26

Everything posted by Sauraen

  1. I know you know your applications better than I do (obviously), so I'll take your word for it. But in my application, it would be likely that a new block would have to be transferred from the SD card every 10 ms or so, so blocking for up to 1 ms (and then losing another up to 1 ms when the task switches back) is wasting an average of 10% of the CPU time. I really don't know anything about low-level filesystem stuff, and I don't feel like I should have to rewrite the entire driver just to avoid adding 3 lines of FreeRTOS code to MIOS32. I'm not going to make any changes to the public MIOS32 source unless TK approves them, but there's got to be a better solution than a whole new driver that's application-specific. The reason this is a "mid-priority task" is because there's another task, with a new priority level I defined called "insane", which has to run every few microseconds to push new DAC data to the YM2612s (there's four of them). This could take half the CPU time itself, depending on how much the user is playing. This function (it's not even a task, just an ISR) is what uses up the buffer data and flags buffers as needing to be filled. Whether those flags are in a small number of places to check or on a queue somewhere is besides the point. Clearly, some task with lower priority than this, but higher priority than things like DIN/DOUT, has to check these things and start transfers from the SD card. Problem is, if the user is trying to play too much, there will be no time other than during the SD card DMA transfers when the CPU can be free to do all other tasks! What you described above with mutexes is fine as a solution for waking up the SD card thread immediately after the audio thread signals there's new data to be read. But the question here is how to put the SD card thread itself to sleep when the DMA transfer has started and wake it up again when it is complete. I have the answer--the FreeRTOS functions discussed earlier--the question is how to integrate them into MIOS32 without breaking its platform independence.
  2. Let me say a few words about the application. There will be a number of buffers containing data which is being streamed from the SD card. A mid-priority task comes around every so often and checks if any queues need to be filled (they're double-buffered). If so, I want it to start the DMA transfer and then let the CPU do other things while that completes, and then continue. I would think this kind of thing is a pretty common use case. I'd be happy to write a new SD card driver that uses the FreeRTOS wait -> notify mechanism I'm talking about (not least because it would avoid introducing new bugs into MIOS32). But I do need the functionality of the FILE and FatFS drivers, and the files I'm streaming from may be arbitrarily large (bigger than a sector), so I can't just get a pointer to the first sector and read from there. The reason I was talking about adding this to the generic MIOS32 SD card functions is that other than the portability issue, I would think that most applications would want the behavior of the CPU being freed while a SD card DMA transfer was in progress. Of course there might be some applications where you want it to block during the transfer, but that would seem to be the exception. As you pointed out TK, DIN/DOUT gets around this by using callbacks, and implementing basically the entire functionality of the DIO system in those callbacks. I can't do this because I need the data to trickle back up through FatFS and FILE to my routine. I have little to no idea what FatFS is doing with the data it gets back from the SD card, but I'm under the impression it's nontrivial. (My application can't guarantee that an entire transfer would be from one sector, for instance--it might overlap two.) I think TK's idea of implementing something like the Mutexes is the best so far, but I'll have to take a closer look before I can get anywhere with it.
  3. Hi TK, I understand about mios32/ being platform-independent, and I'd prefer not to modify critical mios32 components anyway. As far as committing, all my changes do have to eventually go up, so that people who buy the MBHP_Genesis board can get the software. So you're saying have the SPI code call generic-looking functions that I create (e.g. MIOS32_TaskSuspend or something) and then define these in some file that's included in the FreeRTOS folder? What and where should I define those functions for other platforms? I'll take a look at your implementation of Mutexes, maybe that'll help.
  4. Thanks for the tip! After a bit of research it looks like vPortYieldFromISR() is what I was looking for. Evidently, this sets up a "pending interrupt" that's ignored when in kernel mode (including in the ISR) but happens as soon as the CPU goes back to user mode (starting to execute the low-priority task again). Then the kernel will task-switch to the suspended medium-priority task. I hope it works! Also, is there any reason that this is not implemented in the existing MIOS32? That all MIDIboxes busy-wait during SD card and DIN/DOUT SPI transfers?
  5. Hi TK, Right now I'm in a course on real-time operating systems, and I'd like to lay the foundation for a more stable and higher-performance MIDIbox Quad Genesis, so I want to start doing some fancy things. This is a simplified version of the picture, but if I can figure this part out I should be able to do the whole thing. I have a task that checks whether certain buffers need to be filled, and if so, reads into them from a file on the SD card. This task needs to run every so often at medium priority, and there are other low-priority tasks running. I see that currently the SPI transfer from the SD card is accomplished via DMA, but the CPU still busy-waits during the transfer. Instead, once the DMA has started, I want the task to be suspended; and then once the DMA Complete interrupt happens, I want the task to resume from the next line of code (go back to the FATFS driver and process the data, etc.). Two questions: Looking at FreeRTOS, I can call vTaskSuspend after the DMA has started, and then from the DMA Complete ISR call xTaskResumeFromISR. The problem with this is that it simply marks the task as ready, it doesn't actually context-switch back to it. So for instance, if a low-priority task was running, this would still make the SD card task wait for up to a whole ms before a tick interrupt gave it control again. I want the OS to reevaluate the priorities after the ISR--in effect, force a virtual "tick" right after returning from the DMA Complete ISR. Do you know if this is possible? Maybe somehow overriding the tick timer to expire very soon (but it'd have to get put back to its normal length immediately by the OS)? To implement any of this, I'd have to at least modify mios32_spi.c, and possibly other MIOS32 components as well. I can put my changes in #ifdef SAURAEN_DMA_TEST or something like this so they're guaranteed not to mess up everyone else's use of MIOS32 even if they're buggy--but I'm not sure if you want me touching those files anyway. Is there any better way? Thanks, Sauraen
  6. Thanks everyone! As I said before, more information and first versions of complete code for the simple applications should be coming out in about a month. Nah, that award goes to Ander's Station controller. I won't ever be able to top that.
  7. MAGFest has come and gone, and the first unit of MIDIbox Quad Genesis has been hand-delivered to Josh Whelchel and featured in our panel at the event. (To be clear, the hardware was finished, the software is only about 10% done.) Here is the video I recorded before leaving:
  8. I live in the US as well, and I've heard many "reverse" expressions like that, but never that one. I thought about that, but there's two reasons I didn't do that. There's no room on the board for larger tact switches--they'd intersect with the LEDs. In order for the tact switches to work properly with the LEDs and the 3D printed button caps, they have to be 5mm high and positioned right where they are. Fortunately this is a very standard type of tact switches. The LEDs are a bigger concern in terms of availability. Ultra-high brightness LEDs are required to illuminate the transparent button caps and LED pipes. The board contains about $150 worth of LEDs.
  9. What's a-matter, you... chicken...? Not sure if this will make you feel any better, but it only took me about 20 hours to assemble and bring up the front panel board. If (when?) I sell these boards, I will also offer a matching aluminum front panel for about $300 and a matching set of 3D printed transparent buttons and LED pipes for about $30. But I will not sell them until the MIDIbox Quad Genesis firmware is significantly usable (won't say "done"), which won't be for a few months. Due to my schedule of having to get this hardware done by next week, the only software I've been writing is test programs for various functions (though this also includes ironing out the last of the bugs in the MBHP_Genesis module driver and the VGM-streaming-from-SD-card engine). I will be gone for a couple weeks (next week I'm presenting this hardware, as well as MIDIbox FM V2.1, at a panel at MAGFest with Josh Whelchel, my client; and then the week after that I have a graduate school event). After that, I expect it to take me a week or so to get my copy of MIDIbox Quad Genesis up to the same state as this one (this one's for Josh Whelchel). And then, finally, I will modify and clean up my code into the two apps I promised: MIDIbox Genesis Tracker and MIDIbox VGM Player. The former will have no synth engine and just control sound chip parameters directly via MIDI, and the second will have the VGM player and a small LCD+DIN+DOUT interface. So this means code that anyone can use with the MBHP_Genesis module should be going up in about a month from now (middle of March). Sorry it can't be sooner, the client comes first! It's much more impressive when the lights are off--it lights up the room quite nicely. This was taken in a bright room (midday while it was snowy outside).
  10. I apologize for my quietness recently, I've been spending basically all my free time on this synth, and I haven't gotten a chance to do much documentation. The hardware is due in less than a week, so I've been under a lot of pressure! Here is the front panel PCB with all 600+ LEDs on. (Actually, they're not quite all on, due to another part of the software I forgot to disable while running this test--but the other red and green LEDs in the central matrix do work).
  11. I guess it might not have been clear: the hardware is already (mostly) done, the encoders are already in that configuration, and they couldn't have really been put in a separate DIN block due to the density of the front panel. Now I'm just trying to write software to support what I built. I know I could write a custom BLM driver that would support my front panel, but there's no use reinventing the wheel if I can just overlap the BLM-X driver and regular encoder driver.
  12. Hi TK, I just wanted your quick opinion on which BLM driver I should use for the front panel of MIDIbox Quad Genesis. The panel is compatible with the standard MIDIbox DIN/DOUT/matrix system, and I would just use BLM-X, except there's one difference. There's encoders directly connected to DIN pins (common pin grounded, not in the matrix), but due to front panel layout considerations they're sprinkled in arbitrarily throughout the DIN chain, not on dedicated shift registers at the end. Is it possible for me to use BLM-X for the buttons and LEDs, and then also attach additional code to the raw DIN handler to read the encoder values? I think I could simply leave those pins unconfigured in the DIN matrix, I don't think that should be a problem. Or can I use the standard encoder handler? Is there any issue with overlapping the encoder handler with the BLM-X handler to read from different pins on the same shift registers? Thanks, Sauraen
  13. As promised, a video of VGM playback on a MBHP_Genesis module! There is still one issue with the frequency correction, which occasionally leads to wrong notes in certain VGM files, but I understand what the issue is and will fix it when I get a chance. Also, there's an inherent incompatibilty between the noise channel in the SN76489 and the one in the SN76489-clone used in the actual Mega Drive / Genesis (shift register length and therefore pitch, and also what happens with zero frequency). I may be able to have the software correct for it in certain cases, but it's not a huge deal overall.
  14. I am excited to announce that the MBHP_Genesis boards are finally available for sale on the MIDIbox Shop! http://midiboxshop.bigcartel.com/product/midibox-quad-genesis-board Special thanks to SmashTV for helping make this happen!
  15. Thanks TK. In previous projects I used all static allocation, but this one involves users editing these VGM files on the synth, and this requires arrays to change size and other dynamic stuff. I deleted the cpp_issues directory as per your request. I would have made it in playground in the first place, but I didn't know if I would be able to get the project to build, due to it not being in a valid position in the mios32 directory tree.
  16. Don't really want to get into this, but no, it was not my arrangement, it was a verbatim playback of the VGM file of "A Whole New World" from Aladdin on Sega Genesis / Mega Drive. (Well, verbatim, except with timing issues.) I knew there might be an issue, but for two reasons I decided to put it up: (1) I wasn't the first person to upload a copy of that song, and (2) I didn't think Youtube's Content ID system would be smart enough to match a Genesis tune against its original. But I was wrong. No issue for my account, just Disney got to put ads on the video, so I deleted it.
  17. SmashTV has the boards and the photos needed to put up the listing. I emailed him about it a few days ago and he said he's been very busy but they're coming soon.
  18. I may do that, as the core object-oriented part which really needed that had to be changed anyway. We'll see. The one thing is that I don't think I can use malloc and free. I looked at the OS source and there's a pvPortMalloc function, but I'm not sure if I can use that. And in the documentation of those functions, it mentions not being able to free memory after allocating it. But new and delete work fine (if less quickly). I would think they would actually call the C functions malloc and free, but there's a lot about low-level embedded stuff I don't know. Maybe TK can weigh in on this? Has anyone else done a big MIDIbox project in C++?
  19. Umm... so let's just say that maybe it wasn't the wisest choice to use a song from a game owned by Disney as a demo. The video will not be put back up. However it's sort of for the best, as I've significantly improved the software since then, I hope to have a new video up with "flawless" playback in the next week.
  20. Never mind, it's me not understanding polymorphism and virtual functions. Still a dumb error message to get in response to those kind of issues.
  21. I committed this code so you can take a look if you want. I also created a test project in apps/troubleshooting that has the same overall structure as my project, but which doesn't have the linker issues. This leads me to believe that my code is at fault (of course it is!), but I still don't know what I could have messed up that would lead to this kind of linker issue.
  22. The application code for MIDIbox Quad Genesis absolutely needs C++: pieces of VGM files have to be edited, which means dynamic memory allocation (and freeing). Even the playback engine, where one VGM file can be played by multiple "play heads" at different positions corresponding to different channels, is inherently object-oriented. So I started making the core VGM player in MIOS32 in a new C++ application. Just testing the MBHP_Genesis driver with a C++ project (app.cpp) works fine, no compilation issues, and I was able to get the driver mostly working. But I then added some more complicated object-oriented source files, and after they compile, they fail to link: /usr/local/etc/mios32_toolchain/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7e-m/libc_s.a(lib_a-abort.o): In function `abort': abort.c:(.text.abort+0xa): undefined reference to `_exit' /usr/local/etc/mios32_toolchain/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7e-m/libc_s.a(lib_a-sbrkr.o): In function `_sbrk_r': sbrkr.c:(.text._sbrk_r+0xc): undefined reference to `_sbrk' /usr/local/etc/mios32_toolchain/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7e-m/libc_s.a(lib_a-signalr.o): In function `_kill_r': signalr.c:(.text._kill_r+0xe): undefined reference to `_kill' and so on. Do you have any idea what could be going on? The application includes a number of C++ source files, one C source file, and of course a number of drivers and MIOS32 components in C. Does this have to do with the 'extern "C"' thing? Not exactly sure where I need that, but all my code compiled, so the C and C++ source files seemed to have found each other's headers. The only reason I needed a C source file in the first place was to manipulate the timers (higher resolution than those provided in MIOS32_Timer), and putting things like TIM5->CNT in a C++ source file didn't work. So I wrapped all the timer accesses in C functions and then had the original C++ source file call them. Again, this compiles, and this part doesn't seem to fail to link, just those OS things above.
  23. From the album: MIDIbox Quad Genesis

    See http://wiki.midibox.org/doku.php?id=mbhp_genesis
×
×
  • Create New...